diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000..8c1f46f6ff --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,200 @@ +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 + needs: test + 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" + - "circuitplayground_express_displayio" + - "cp32-m4" + - "datalore_ip_m4" + - "datum_distance" + - "datum_imu" + - "datum_light" + - "datum_weather" + - "electronut_labs_blip" + - "electronut_labs_papyr" + - "escornabot_makech" + - "feather_f405" + - "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" + - "pewpew_m4" + - "pirkey_m0" + - "pybadge" + - "pybadge_airlift" + - "pyboard_v11" + - "pygamer" + - "pygamer_advance" + - "pyportal" + - "pyportal_titano" + - "pyruler" + - "robohatmm1_m0" + - "robohatmm1_m4" + - "sam32" + - "serpente" + - "snekboard" + - "sparkfun_lumidrive" + - "sparkfun_nrf52840_mini" + - "sparkfun_redboard_turbo" + - "sparkfun_samd21_dev" + - "sparkfun_samd21_mini" + - "stm32f411ve_discovery" + - "stm32f412zg_discovery" + - "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.BLINKA_GITHUB_ACCESS_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 0000000000..ce93237021 --- /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.BLINKA_GITHUB_ACCESS_TOKEN }} + if: github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested') diff --git a/.gitmodules b/.gitmodules index 163d45fcd1..7b57cab547 100644 --- a/.gitmodules +++ b/.gitmodules @@ -95,3 +95,6 @@ [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/.travis.yml b/.travis.yml deleted file mode 100755 index d75b4e7d4a..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,145 +0,0 @@ -sudo: required -dist: xenial -language: c -compiler: - - gcc -git: - depth: 6 - -# Each item under 'env' is a separate Travis job to execute. -# They run in separate environments, so each one must take the time -# to clone the repository and submodules; to download and install SDKs, -# pip packages, and so forth. By gathering activities together in optimal -# ways, the "run time" and "total time" of the travis jobs can be minimized. -# -# Since at the time of writing Travis generally starts 5 or 6 jobs, the -# builds have been organized into 5 groups of *approximately* equal durations. -# Additionally, the jobs that need extra SDKs are also organized together. -# -# When adding new boards, take a look on the travis CI page -# https://travis-ci.org/adafruit/circuitpython to which build that installs -# that SDK is shortest and add it there. In the case of major re-organizations, -# just try to make the builds "about equal in run time" -env: - - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="circuitplayground_express mini_sam_m4 grandcentral_m4_express capablerobot_usbhub pygamer pca10056 pca10059 feather_nrf52840_express makerdiary_nrf52840_mdk makerdiary_nrf52840_mdk_usb_dongle particle_boron particle_argon particle_xenon sparkfun_nrf52840_mini electronut_labs_papyr electronut_labs_blip" TRAVIS_SDK=arm:nrf - - TRAVIS_BOARDS="metro_m0_express metro_m4_express metro_m4_airlift_lite pirkey_m0 trellis_m4_express trinket_m0 sparkfun_lumidrive sparkfun_redboard_turbo bast_pro_mini_m0 datum_distance pyruler" TRAVIS_SDK=arm - - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow sam32 uchip escornabot_makech pygamer_advance datum_imu" TRAVIS_SDK=arm - - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300 arduino_mkrzero pewpew10 kicksat-sprite ugame10 robohatmm1 datum_light" TRAVIS_SDK=arm - - TRAVIS_BOARDS="circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express catwan_usbstick pyportal sparkfun_samd21_mini sparkfun_samd21_dev pybadge pybadge_airlift datum_weather" TRAVIS_SDK=arm - -addons: - artifacts: - paths: - - $(ls -d1 bin/*/*/* | tr "\n" ":") - target_paths: / - -# Some deploy jobs take over 10 minutes so use this keep alive hack to make sure Travis doesn't kill us. -before_deploy: | - function keep_alive() { - while true; do - echo -en "\a" - sleep 5 - done - } - keep_alive & - -deploy: - provider: releases - api_key: - secure: "jdqVFw6itRY4qwQF4ReXo0uaymT+Mob6RhYX0lw8KWFNqBgHnLVuKmKKcGMEuRvBVMPkvxF7bMuOQzSBOunqwlHFse3oMzdWvQODv1zwV7pSRXGwTdIvTPbBjKWxnBG9uSNRf2R5AMflJFUxy2CbtBpgvNzr+4VLREZDrrjEu8C1iTtXGpSm5AQ5iIp2fkMAWD85FP7CQPpkqRoxhSIFZmTdurfYRmenq1OZ/4SeD5TESKcyvqJNzVT9z210B3cg3eAkP6ukvelW4qE2zgIANqUkGqvDEnAvEII9M89kuwhCMAekdfwnUSPrry+g77i1dUZHoRN1+MFj+waYtPaqxdYo2G1sysa6enxlu4jHMR5MfMk9eKHgaNgL3PiyANusYSS44amh8QIiVaX5nw82myZDCpQOZW7YqJKE6WX70Lbs4mS+wIs+ig4KIXO1B0p9kMb0OeVjHRl+KcXsWGRu/ECG/ExpqlVIssSPU407LohMXT2cJ37CY/R/EeK2XSDsQ2M3L3EAGUjCJdBGuwsOJ+2lG+HQpAVu9vAB4kq5jy9Ye+MG+8Xlkly3XZZ5+FkXyYxKnXb26/QVv0e5sIG5OmdJCPYFaH2J1QdKo7CdhEcBtrf6DMPWaimGMldShFqzLjOz3b3qLysRxFF0aGb7ipKPa57vawNzYHoPAViOcXQ=" - file_glob: true - file: "$TRAVIS_BUILD_DIR/bin/*/*/*" - skip_cleanup: true - on: - tags: true - -notifications: - webhooks: - urls: - - https://rosie-ci.ngrok.io/travis - on_success: always - on_failure: always - on_start: always - on_cancel: always - on_error: always - -before_script: - # Expand the git tree back to 4.0.0-alpha.1 and then fetch the latest tag. - - LAST_TAG=`git ls-remote --quiet --tags --sort=version:refname | egrep -o "refs/tags/[0-9]+.*\$" | tail -n 1` - - git fetch --depth 1 origin $LAST_TAG:$LAST_TAG - - git describe --dirty --always --tags - - function var_search () { case "$1" in *$2*) true;; *) false;; esac; } - - sudo dpkg --add-architecture i386 - - - - (! var_search "${TRAVIS_SDK-}" arm || (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)) - - # For huzzah builds - - (! var_search "${TRAVIS_SDK-}" esp8266 || (wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz && tar -C .. -xaf xtensa-lx106-elf-standalone.tar.gz)) - - if var_search "${TRAVIS_SDK-}" esp8266 ; then PATH=$(readlink -f ../xtensa-lx106-elf/bin):$PATH; fi - - # For coverage testing (upgrade is used to get latest urllib3 version) - - sudo apt-get install -y python3-pip - - pip3 install --user sh click - - ([[ -z "$TRAVIS_TESTS" ]] || sudo pip install --upgrade cpp-coveralls) - - (! var_search "${TRAVIS_TESTS-}" docs || sudo apt-get install -y librsvg2-bin) - - (! var_search "${TRAVIS_TESTS-}" docs || pip install --user Sphinx sphinx-rtd-theme recommonmark sphinxcontrib-svg2pdfconverter) - - (! var_search "${TRAVIS_TESTS-}" translations || pip3 install --user polib) - - # report some good version numbers to the build - - gcc --version - - (! var_search "${TRAVIS_SDK-}" arm || arm-none-eabi-gcc --version) - - (! var_search "${TRAVIS_SDK-}" esp8266 || xtensa-lx106-elf-gcc --version) - - python3 --version - -script: - # Build mpy-cross first because other builds depend on it. - - echo 'Building mpy-cross' && echo 'travis_fold:start:mpy-cross' - - make -C mpy-cross -j2 ; S=$? ; echo $S > status ; (exit $S) - - echo 'travis_fold:end:mpy-cross' && tools/print_status.py status - - # Use unbuffered output because building all the releases can take a long time. - # Travis will cancel the job if it sees no output for >10 minutes. - - cd tools && python3 -u build_release_files.py - - cd .. - - - echo 'Building unix' && echo 'travis_fold:start:unix' - - (! var_search "${TRAVIS_TESTS-}" unix || (make -C ports/unix deplibs -j2 && make -C ports/unix -j2 && make -C ports/unix coverage -j2)) ; S=$? ; echo $S > status ; (exit $S) - - echo 'travis_fold:end:unix' && tools/print_status.py status - - # run tests without coverage info - #- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests -j1) - #- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests -j1 --emit native) - - # run tests with coverage info - - echo 'Test all' && echo 'travis_fold:start:test_all' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1)) ; S=$? ; echo $S > status ; (exit $S) - - echo 'travis_fold:end:test_all' && tools/print_status.py status - - - echo 'Test threads' && echo 'travis_fold:start:test_threads' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread)) ; S=$? ; echo $S > status ; (exit $S) - - echo 'travis_fold:end:test_threads' && tools/print_status.py status - - - echo 'Testing with native' && echo 'travis_fold:start:test_native' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native)) ; S=$? ; echo $S > status ; (exit $S) - - echo 'travis_fold:end:test_native' && tools/print_status.py status - - - (echo 'Testing with mpy' && echo 'travis_fold:start:test_mpy') - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float)) ; S=$? ; echo $S > status ; (exit $S) - - echo 'travis_fold:end:test_mpy' && tools/print_status.py status - - - (echo 'Building docs' && echo 'travis_fold:start:build_docs') - - (! var_search "${TRAVIS_TESTS-}" docs || sphinx-build -E -W -b html . _build/html) ; S=$? ; echo $S > status ; (exit $S) - - echo 'travis_fold:end:build_docs' && tools/print_status.py status - - - (echo 'Building translations' && echo 'travis_fold:start:build_translations') - - (! var_search "${TRAVIS_TESTS-}" translations || make check-translate) ; S=$? ; echo $S > status ; (exit $S) - - echo 'travis_fold:end:build_translations' && tools/print_status.py status - - # 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) - - - (! var_search "${TRAVIS_TESTS-}" website || (cd tools && python3 build_board_info.py && cd ..)) - -after_failure: - - (cd tests && for exp in *.exp; do testbase=$(basename $exp .exp); echo -e "\nFAILURE $testbase"; diff -u $testbase.exp $testbase.out; done) diff --git a/README.rst b/README.rst index f5f9cccea2..03116be88e 100644 --- a/README.rst +++ b/README.rst @@ -78,7 +78,7 @@ If you'd like to use the term "CircuitPython" and Blinka for your product here i * 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 +* 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. diff --git a/conf.py b/conf.py index 6b0f40da6b..3df958fe1f 100644 --- a/conf.py +++ b/conf.py @@ -13,6 +13,7 @@ # All configuration values have a default; values that are commented out # serve to show the default. +import json import sys import os @@ -24,8 +25,20 @@ from recommonmark.parser import CommonMarkParser 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. @@ -40,7 +53,9 @@ extensions = [ 'sphinxcontrib.rsvgconverter', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', - 'sphinx.ext.coverage' + 'sphinx.ext.coverage', + 'rstjinja', + 'c2rst' ] # Add any paths that contain templates here, relative to this directory. @@ -49,8 +64,7 @@ templates_path = ['templates'] # The suffix of source filenames. source_suffix = ['.rst', '.md', '.c', '.h'] -source_parsers = {'.md': CommonMarkParser, - '.c': "c2rst.CStrip", '.h': "c2rst.CStrip"} +source_parsers = {'.md': CommonMarkParser} # The encoding of source files. #source_encoding = 'utf-8-sig' @@ -122,6 +136,10 @@ exclude_patterns = ["**/build*", "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", @@ -351,3 +369,6 @@ texinfo_documents = [ 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/c2rst.py b/docs/c2rst.py index 904fb74084..76489dca30 100644 --- a/docs/c2rst.py +++ b/docs/c2rst.py @@ -1,19 +1,31 @@ -import sphinx.parsers +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 -class CStrip(sphinx.parsers.Parser): - def __init__(self): - self.rst_parser = sphinx.parsers.RSTParser() + fname = app.env.doc2path(docname) + if (not fname.endswith(".c") and + not fname.endswith(".h")): + #print("skipping:", fname) + return - def parse(self, inputstring, document): - # This setting is missing starting with Sphinx 1.7.1 so we set it ourself. - document.settings.tab_width = 4 - document.settings.character_level_inline_markup = False - stripped = [] - for line in inputstring.split("\n"): - line = line.strip() - if line == "//|": - stripped.append("") - elif line.startswith("//| "): - stripped.append(line[len("//| "):]) - stripped = "\r\n".join(stripped) - self.rst_parser.parse(stripped, document) + 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/library/network.rst b/docs/library/network.rst index d25f9f3884..cdcc5f3232 100644 --- a/docs/library/network.rst +++ b/docs/library/network.rst @@ -5,6 +5,7 @@ .. include:: ../templates/unsupported_in_circuitpython.inc .. module:: network + :noindex: :synopsis: network configuration This module provides network drivers and routing configuration. To use this diff --git a/docs/rstjinja.py b/docs/rstjinja.py new file mode 100644 index 0000000000..3a08b25997 --- /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 0000000000..ba0ec0e4f9 --- /dev/null +++ b/docs/shared_bindings_matrix.py @@ -0,0 +1,289 @@ +# 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, or a list of + modules that determine default [see audiocore, audiomixer, etc.]). + + """ + 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.findall(re_pattern, configs) + if not find_config: + continue + find_config = ", ".join([x.strip("$()") for x in find_config]) + + full_build = int("CIRCUITPY_FULL_BUILD" in find_config) + if not full_build: + default_val = find_config + else: + default_val = "None" + + base[search_name] = { + "name": full_name, + "full_build": str(full_build), + "default_value": default_val, + "excluded": {} + } + + #print(base) + 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]) + + check_dependent_modules = dict() + 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 board uses `MINIMAL_BUILD`. if yes, and current + # module is marked as `DEFAULT_BUILD`, board is excluded + min_build = re.search("CIRCUITPY_MINIMAL_BUILD = 1", contents) + if min_build and base[module]["default_value"] == "CIRCUITPY_DEFAULT_BUILD": + 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: + if base[module]["default_value"].isdigit(): + # 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: + # this module is dependent on another module. add it + # to the list to check after processing all other modules. + # only need to check exclusion if it isn't already excluded. + if (not board_is_excluded and + base[module]["default_value"] not in [ + "None", + "CIRCUITPY_DEFAULT_BUILD" + ]): + check_dependent_modules[module] = base[module]["default_value"] + 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] + + for module in check_dependent_modules: + depend_results = set() + + parents = check_dependent_modules[module].split("CIRCUITPY_") + parents = [item.strip(", ").lower() for item in parents if item] + + for parent in parents: + if parent in base: + if (board_chip in base[parent]["excluded"] and + entry.name in base[parent]["excluded"][board_chip]): + depend_results.add(False) + else: + depend_results.add(True) + + # only exclude the module if there were zero parents enabled + # as determined by the 'depend_results' set. + if not any(depend_results): + 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/frozen/Adafruit_CircuitPython_BusDevice b/frozen/Adafruit_CircuitPython_BusDevice index b9280af514..52d87bd7e5 160000 --- a/frozen/Adafruit_CircuitPython_BusDevice +++ b/frozen/Adafruit_CircuitPython_BusDevice @@ -1 +1 @@ -Subproject commit b9280af5142fc41639229544678e23b5cca07c3a +Subproject commit 52d87bd7e571af66ecb57ee32b5af92531134150 diff --git a/frozen/Adafruit_CircuitPython_CircuitPlayground b/frozen/Adafruit_CircuitPython_CircuitPlayground index 154b74de02..d87ea261c4 160000 --- a/frozen/Adafruit_CircuitPython_CircuitPlayground +++ b/frozen/Adafruit_CircuitPython_CircuitPlayground @@ -1 +1 @@ -Subproject commit 154b74de020764597ba49f0d1e8cc18d55b3643b +Subproject commit d87ea261c40ecbc6d893d72d337beefbea1cf932 diff --git a/frozen/Adafruit_CircuitPython_Crickit b/frozen/Adafruit_CircuitPython_Crickit index 617bb0787f..a6100fb5d8 160000 --- a/frozen/Adafruit_CircuitPython_Crickit +++ b/frozen/Adafruit_CircuitPython_Crickit @@ -1 +1 @@ -Subproject commit 617bb0787f2c61283d248632a62b27be80f64b29 +Subproject commit a6100fb5d867c7f4980f071119bfa7e0a76e1d47 diff --git a/frozen/Adafruit_CircuitPython_IRRemote b/frozen/Adafruit_CircuitPython_IRRemote index 70865ac6e0..8b7611a2cc 160000 --- a/frozen/Adafruit_CircuitPython_IRRemote +++ b/frozen/Adafruit_CircuitPython_IRRemote @@ -1 +1 @@ -Subproject commit 70865ac6e09f821b26ec727e2df300a6d9ebf6b3 +Subproject commit 8b7611a2cc076a2ac1b368c70227519f69f1e3e9 diff --git a/frozen/Adafruit_CircuitPython_LIS3DH b/frozen/Adafruit_CircuitPython_LIS3DH index bd7ddc67dc..53146ab2e8 160000 --- a/frozen/Adafruit_CircuitPython_LIS3DH +++ b/frozen/Adafruit_CircuitPython_LIS3DH @@ -1 +1 @@ -Subproject commit bd7ddc67dc86f7ad0115f58ab80d5605739c6482 +Subproject commit 53146ab2e82c318c3c37bd76bac34035a597b311 diff --git a/frozen/Adafruit_CircuitPython_Thermistor b/frozen/Adafruit_CircuitPython_Thermistor index 893c5ec6a9..2e5aedf18e 160000 --- a/frozen/Adafruit_CircuitPython_Thermistor +++ b/frozen/Adafruit_CircuitPython_Thermistor @@ -1 +1 @@ -Subproject commit 893c5ec6a9aeef38284985074c2058e87754ad3d +Subproject commit 2e5aedf18eb417a4120d4998ac1f387a4f600730 diff --git a/frozen/Adafruit_CircuitPython_seesaw b/frozen/Adafruit_CircuitPython_seesaw index f1171f9408..ea5e445edd 160000 --- a/frozen/Adafruit_CircuitPython_seesaw +++ b/frozen/Adafruit_CircuitPython_seesaw @@ -1 +1 @@ -Subproject commit f1171f94083ba64d153ff3f90eeb07500331d6e1 +Subproject commit ea5e445edd4441cacd207aa2d2bfd724b813a253 diff --git a/frozen/circuitpython-stage b/frozen/circuitpython-stage index 6d1ae72916..c1d8e1d645 160000 --- a/frozen/circuitpython-stage +++ b/frozen/circuitpython-stage @@ -1 +1 @@ -Subproject commit 6d1ae72916cf240ea86185c45f844d59f56d8ec3 +Subproject commit c1d8e1d645cbc83d857e12cf4ba67549b988a4e7 diff --git a/lib/tinyusb b/lib/tinyusb index 0848c462b3..d3e48da5a1 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 0848c462b3e431a9da42e96537d2b597a4579636 +Subproject commit d3e48da5a1266a88f5f0fdfe28818c8599b09844 diff --git a/lib/utils/buffer_helper.c b/lib/utils/buffer_helper.c index f6eb8bf1e7..694952e3d2 100644 --- a/lib/utils/buffer_helper.c +++ b/lib/utils/buffer_helper.c @@ -26,10 +26,10 @@ #include "lib/utils/buffer_helper.h" -void normalize_buffer_bounds(int32_t* start, int32_t end, uint32_t* length) { +void normalize_buffer_bounds(int32_t* start, int32_t end, size_t* length) { if (end < 0) { end += *length; - } else if (((uint32_t) end) > *length) { + } else if (((size_t) end) > *length) { end = *length; } if (*start < 0) { diff --git a/lib/utils/buffer_helper.h b/lib/utils/buffer_helper.h index 47042e7ef1..7487b9df53 100644 --- a/lib/utils/buffer_helper.h +++ b/lib/utils/buffer_helper.h @@ -28,7 +28,8 @@ #define MICROPY_INCLUDED_LIB_UTILS_BUFFER_HELPER_H #include +#include -void normalize_buffer_bounds(int32_t* start, int32_t end, uint32_t* length); +void normalize_buffer_bounds(int32_t* start, int32_t end, size_t* length); #endif // MICROPY_INCLUDED_LIB_UTILS_BUFFER_HELPER_H diff --git a/locale/ID.po b/locale/ID.po index 33e63bd2ce..63e3466b6e 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-09 09:06-0400\n" +"POT-Creation-Date: 2019-09-08 17:30-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -52,7 +52,7 @@ msgstr "" msgid "%q indices must be integers, not %s" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c #, fuzzy msgid "%q must be >= 1" @@ -218,12 +218,12 @@ msgstr "" msgid "A hardware interrupt channel is already in use" msgstr "Sebuah channel hardware interrupt sedang digunakan" -#: shared-bindings/bleio/Address.c +#: 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 +#: shared-bindings/_bleio/Address.c msgid "Address type out of range" msgstr "" @@ -255,6 +255,7 @@ 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" @@ -300,6 +301,10 @@ 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" @@ -312,6 +317,10 @@ msgstr "" 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 "" @@ -325,6 +334,19 @@ msgstr "" 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 "" @@ -335,7 +357,7 @@ msgstr "" msgid "Bus pin %d is already in use" msgstr "DAC sudah digunakan" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c #, fuzzy msgid "Byte buffer must be 16 bytes." msgstr "buffers harus mempunyai panjang yang sama" @@ -353,8 +375,8 @@ msgstr "" msgid "Can not use dotstar with %s" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +#: 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 @@ -415,15 +437,7 @@ msgstr "tidak dapat mendapatkan ukuran scalar secara tidak ambigu" msgid "Cannot write without MOSI pin." msgstr "" -#: shared-bindings/bleio/Service.c -msgid "Characteristic UUID doesn't match Service UUID" -msgstr "" - -#: ports/nrf/common-hal/bleio/Service.c -msgid "Characteristic already in use by another Service." -msgstr "" - -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "" @@ -443,6 +457,10 @@ msgstr "Clock unit sedang digunakan" 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 "" @@ -455,7 +473,7 @@ msgstr "" msgid "Corrupt raw code" msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c #, c-format msgid "Could not decode ble_uuid, err 0x%04x" msgstr "" @@ -464,11 +482,11 @@ msgstr "" msgid "Could not initialize UART" msgstr "Tidak dapat menginisialisasi UART" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "" @@ -485,11 +503,11 @@ msgstr "DAC sudah digunakan" msgid "Data 0 pin must be byte aligned" msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Data chunk must follow fmt chunk" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: ports/nrf/common-hal/_bleio/Peripheral.c #, fuzzy msgid "Data too large for advertisement packet" msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment" @@ -498,7 +516,16 @@ msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment" msgid "Destination capacity is smaller than destination_length." msgstr "" +#: ports/nrf/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +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 "" @@ -522,16 +549,25 @@ msgstr "Error pada regex" msgid "Expected a %q" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c msgid "Expected a Characteristic" msgstr "" -#: shared-bindings/bleio/Characteristic.c shared-bindings/bleio/Descriptor.c -#: shared-bindings/bleio/Service.c +#: 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 +#: shared-bindings/_bleio/Central.c msgid "Expected an Address" msgstr "" @@ -549,12 +585,17 @@ msgstr "" msgid "Failed to acquire mutex, err 0x%04x" msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Service.c +#: 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/Peripheral.c +#: 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" @@ -569,61 +610,66 @@ msgstr "Gagal untuk mengalokasikan buffer RX" 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 +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c msgid "Failed to connect: timeout" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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/Central.c +#: 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 +#: 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 +#: 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 +#: 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/Characteristic.c +#: 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/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/Characteristic.c +#: 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 +#: 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" @@ -633,42 +679,47 @@ msgstr "Gagal untuk menambahkan Vendor Spesific UUID, status: 0x%08lX" msgid "Failed to release mutex, err 0x%04x" msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c #, c-format msgid "Failed to start connecting, error 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Characteristic.c #, c-format msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: 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/Characteristic.c +#: 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" @@ -704,6 +755,11 @@ msgstr "" 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 "" @@ -760,7 +816,7 @@ msgstr "Ukuran buffer tidak valid" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "" @@ -768,11 +824,11 @@ msgstr "" msgid "Invalid direction." msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid file" msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" msgstr "" @@ -810,15 +866,27 @@ msgstr "Pin-pin tidak valid" msgid "Invalid polarity" msgstr "" +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid wave file" msgstr "" @@ -878,7 +946,7 @@ msgstr "" msgid "Must be a %q subclass." msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Characteristic.c msgid "No CCCD for this Characteristic" msgstr "" @@ -924,6 +992,10 @@ msgstr "" 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 "" @@ -932,13 +1004,15 @@ msgstr "" msgid "No such file/directory" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -#: shared-bindings/bleio/CharacteristicBuffer.c +#: 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 "" @@ -964,8 +1038,8 @@ msgstr "" #: shared-module/displayio/OnDiskBitmap.c #, c-format msgid "" -"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " -"given" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" msgstr "" #: shared-bindings/_pixelbuf/PixelBuf.c @@ -1042,6 +1116,10 @@ msgstr "sistem file (filesystem) bersifat Read-only" 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" @@ -1063,11 +1141,12 @@ msgstr "" msgid "SDA or SCL needs a pull up" msgstr "SDA atau SCL membutuhkan pull up" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/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" @@ -1086,8 +1165,8 @@ msgstr "" msgid "Slices not supported" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c -#, c-format +#: 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" @@ -1135,19 +1214,19 @@ msgid "" "exit safe mode.\n" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "" @@ -1155,8 +1234,12 @@ msgstr "" 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 indices must be 0 - 255" +msgid "Tile value out of bounds" msgstr "" #: shared-bindings/displayio/TileGrid.c @@ -1171,11 +1254,13 @@ msgstr "Untuk keluar, silahkan reset board tanpa " msgid "Too many channels in sample." msgstr "Terlalu banyak channel dalam sampel" -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +#: 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 "" @@ -1195,15 +1280,15 @@ msgstr "" msgid "USB Error" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID integer value must be 0-0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID value is not str, int or byte buffer" msgstr "" @@ -1212,6 +1297,11 @@ msgstr "" 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" @@ -1229,7 +1319,7 @@ msgstr "" msgid "Unable to write to nvm." msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c msgid "Unexpected nrfx uuid type" msgstr "" @@ -1242,12 +1332,12 @@ msgstr "" msgid "Unsupported baudrate" msgstr "Baudrate tidak didukung" -#: shared-module/displayio/Display.c +#: shared-module/displayio/display_core.c #, fuzzy msgid "Unsupported display bus type" msgstr "Baudrate tidak didukung" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Unsupported format" msgstr "" @@ -1259,12 +1349,18 @@ msgstr "" msgid "Unsupported pull value." msgstr "" -#: py/emitnative.c -msgid "Viper functions don't currently support more than 4 arguments" +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" msgstr "" -#: shared-module/audioio/Mixer.c -msgid "Voice index too high" +#: 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 "" #: main.c @@ -1358,10 +1454,6 @@ msgstr "" msgid "attributes not supported yet" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "" - #: py/builtinevex.c msgid "bad compile mode" msgstr "mode compile buruk" @@ -1390,7 +1482,7 @@ msgstr "" msgid "bits must be 8" msgstr "bits harus memilki nilai 8" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "" @@ -1403,7 +1495,7 @@ msgstr "" msgid "buf is too small. need %d bytes" msgstr "" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "buffer must be a bytes-like object" msgstr "" @@ -1615,10 +1707,6 @@ msgstr "tidak dapat melakukan relative import" msgid "casting" msgstr "" -#: shared-bindings/bleio/Service.c -msgid "characteristics includes an object that is not a Characteristic" -msgstr "" - #: shared-bindings/_stage/Text.c msgid "chars buffer too small" msgstr "" @@ -1766,7 +1854,8 @@ msgstr "argumen keyword ekstra telah diberikan" msgid "extra positional arguments given" msgstr "argumen posisi ekstra telah diberikan" -#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c msgid "file must be a file opened in byte mode" msgstr "" @@ -1895,7 +1984,7 @@ msgstr "" msgid "integer required" msgstr "" -#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c #, c-format msgid "interval must be in range %s-%s" msgstr "" @@ -1989,6 +2078,10 @@ msgstr "label didefinis ulang" msgid "length argument not allowed for this type" msgstr "" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "" @@ -2017,6 +2110,12 @@ msgstr "" 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 "" @@ -2062,7 +2161,7 @@ msgstr "" msgid "name '%q' is not defined" msgstr "" -#: shared-bindings/bleio/Peripheral.c +#: shared-bindings/_bleio/Peripheral.c #, fuzzy msgid "name must be a string" msgstr "keyword harus berupa string" @@ -2108,16 +2207,17 @@ msgstr "tidak ada ikatan/bind pada temuan nonlocal" 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 "" -#: shared-bindings/bleio/Peripheral.c -msgid "non-Service found in services" -msgstr "" - -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c @@ -2136,7 +2236,7 @@ msgstr "non-keyword arg setelah */**" msgid "non-keyword arg after keyword arg" msgstr "non-keyword arg setelah keyword arg" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "not a 128-bit UUID" msgstr "" @@ -2203,6 +2303,14 @@ msgstr "panjang data string memiliki keganjilan (odd-length)" 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" @@ -2311,7 +2419,7 @@ msgstr "" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" @@ -2426,10 +2534,6 @@ msgstr "sintaksis error pada pendeskripsi uctypes" msgid "threshold must be in the range 0-65536" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "tile index out of bounds" -msgstr "" - #: shared-bindings/time/__init__.c msgid "time.struct_time() takes a 9-sequence" msgstr "" @@ -2442,7 +2546,7 @@ msgstr "" msgid "timeout >100 (units are now seconds, not msecs)" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c #, fuzzy msgid "timeout must be >= 0.0" msgstr "bits harus memilki nilai 8" @@ -2596,7 +2700,7 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Scanner.c msgid "window must be <= interval" msgstr "" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 2ad3316c7f..d709a69cc9 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-11 18:42-0400\n" +"POT-Creation-Date: 2019-09-08 17:30-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -52,7 +52,7 @@ msgstr "" msgid "%q indices must be integers, not %s" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c msgid "%q must be >= 1" msgstr "" @@ -217,12 +217,12 @@ msgstr "" msgid "A hardware interrupt channel is already in use" msgstr "" -#: shared-bindings/bleio/Address.c +#: shared-bindings/_bleio/Address.c #, c-format msgid "Address must be %d bytes long" msgstr "" -#: shared-bindings/bleio/Address.c +#: shared-bindings/_bleio/Address.c msgid "Address type out of range" msgstr "" @@ -253,6 +253,7 @@ 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" @@ -296,6 +297,10 @@ msgid "" "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 "" @@ -308,6 +313,10 @@ msgstr "" 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 "" @@ -321,6 +330,19 @@ msgstr "" 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 "" @@ -331,7 +353,7 @@ msgstr "" msgid "Bus pin %d is already in use" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "" @@ -348,8 +370,8 @@ msgstr "" msgid "Can not use dotstar with %s" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +#: 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 @@ -405,15 +427,7 @@ msgstr "" msgid "Cannot write without MOSI pin." msgstr "" -#: shared-bindings/bleio/Service.c -msgid "Characteristic UUID doesn't match Service UUID" -msgstr "" - -#: ports/nrf/common-hal/bleio/Service.c -msgid "Characteristic already in use by another Service." -msgstr "" - -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "" @@ -433,6 +447,10 @@ msgstr "" 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 "" @@ -445,7 +463,7 @@ msgstr "" msgid "Corrupt raw code" msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c #, c-format msgid "Could not decode ble_uuid, err 0x%04x" msgstr "" @@ -454,11 +472,11 @@ msgstr "" msgid "Could not initialize UART" msgstr "" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "" @@ -475,11 +493,11 @@ msgstr "" msgid "Data 0 pin must be byte aligned" msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Data chunk must follow fmt chunk" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: ports/nrf/common-hal/_bleio/Peripheral.c msgid "Data too large for advertisement packet" msgstr "" @@ -487,7 +505,16 @@ msgstr "" msgid "Destination capacity is smaller than destination_length." msgstr "" +#: ports/nrf/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +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 "" @@ -511,16 +538,25 @@ msgstr "" msgid "Expected a %q" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c msgid "Expected a Characteristic" msgstr "" -#: shared-bindings/bleio/Characteristic.c shared-bindings/bleio/Descriptor.c -#: shared-bindings/bleio/Service.c +#: 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 +#: shared-bindings/_bleio/Central.c msgid "Expected an Address" msgstr "" @@ -538,12 +574,17 @@ msgstr "" msgid "Failed to acquire mutex, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Service.c +#: ports/nrf/common-hal/_bleio/Service.c #, c-format msgid "Failed to add characteristic, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: 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 "" @@ -558,57 +599,62 @@ msgstr "" msgid "Failed to allocate RX buffer of %d bytes" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c +#: ports/nrf/common-hal/_bleio/Adapter.c msgid "Failed to change softdevice state" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c msgid "Failed to connect: timeout" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: ports/nrf/common-hal/_bleio/Scanner.c #, c-format msgid "Failed to continue scanning, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c +#: ports/nrf/common-hal/_bleio/__init__.c msgid "Failed to discover services" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c +#: ports/nrf/common-hal/_bleio/Adapter.c msgid "Failed to get local address" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c +#: ports/nrf/common-hal/_bleio/Adapter.c msgid "Failed to get softdevice state" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: 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/Characteristic.c +#: 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/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/Characteristic.c +#: 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 +#: ports/nrf/common-hal/_bleio/UUID.c #, c-format msgid "Failed to register Vendor-Specific UUID, err 0x%04x" msgstr "" @@ -618,42 +664,47 @@ msgstr "" msgid "Failed to release mutex, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c #, c-format msgid "Failed to start connecting, error 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Characteristic.c #, c-format msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Failed to write attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Failed to write gatts value, err 0x%04x" msgstr "" @@ -689,6 +740,11 @@ msgstr "" 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 "" @@ -745,7 +801,7 @@ msgstr "" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "" @@ -753,11 +809,11 @@ msgstr "" msgid "Invalid direction." msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid file" msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" msgstr "" @@ -795,15 +851,27 @@ msgstr "" msgid "Invalid polarity" msgstr "" +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid wave file" msgstr "" @@ -863,7 +931,7 @@ msgstr "" msgid "Must be a %q subclass." msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Characteristic.c msgid "No CCCD for this Characteristic" msgstr "" @@ -909,6 +977,10 @@ msgstr "" 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 "" @@ -917,12 +989,14 @@ msgstr "" msgid "No such file/directory" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -#: shared-bindings/bleio/CharacteristicBuffer.c +#: 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 "" @@ -948,8 +1022,8 @@ msgstr "" #: shared-module/displayio/OnDiskBitmap.c #, c-format msgid "" -"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " -"given" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" msgstr "" #: shared-bindings/_pixelbuf/PixelBuf.c @@ -1023,6 +1097,10 @@ msgstr "" 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 "" @@ -1043,11 +1121,12 @@ msgstr "" msgid "SDA or SCL needs a pull up" msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/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 "" @@ -1066,7 +1145,7 @@ msgstr "" msgid "Slices not supported" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c +#: ports/nrf/common-hal/_bleio/Adapter.c #, c-format msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" @@ -1112,19 +1191,19 @@ msgid "" "exit safe mode.\n" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "" @@ -1132,8 +1211,12 @@ msgstr "" 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 indices must be 0 - 255" +msgid "Tile value out of bounds" msgstr "" #: shared-bindings/displayio/TileGrid.c @@ -1148,11 +1231,13 @@ msgstr "" msgid "Too many channels in sample." msgstr "" -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +#: 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 "" @@ -1172,15 +1257,15 @@ msgstr "" msgid "USB Error" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID integer value must be 0-0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID value is not str, int or byte buffer" msgstr "" @@ -1189,6 +1274,11 @@ msgstr "" 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" @@ -1206,7 +1296,7 @@ msgstr "" msgid "Unable to write to nvm." msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c msgid "Unexpected nrfx uuid type" msgstr "" @@ -1219,11 +1309,11 @@ msgstr "" msgid "Unsupported baudrate" msgstr "" -#: shared-module/displayio/Display.c +#: shared-module/displayio/display_core.c msgid "Unsupported display bus type" msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Unsupported format" msgstr "" @@ -1235,12 +1325,18 @@ msgstr "" msgid "Unsupported pull value." msgstr "" -#: py/emitnative.c -msgid "Viper functions don't currently support more than 4 arguments" +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" msgstr "" -#: shared-module/audioio/Mixer.c -msgid "Voice index too high" +#: 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 "" #: main.c @@ -1325,10 +1421,6 @@ msgstr "" msgid "attributes not supported yet" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "" - #: py/builtinevex.c msgid "bad compile mode" msgstr "" @@ -1357,7 +1449,7 @@ msgstr "" msgid "bits must be 8" msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "" @@ -1370,7 +1462,7 @@ msgstr "" msgid "buf is too small. need %d bytes" msgstr "" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "buffer must be a bytes-like object" msgstr "" @@ -1581,10 +1673,6 @@ msgstr "" msgid "casting" msgstr "" -#: shared-bindings/bleio/Service.c -msgid "characteristics includes an object that is not a Characteristic" -msgstr "" - #: shared-bindings/_stage/Text.c msgid "chars buffer too small" msgstr "" @@ -1732,7 +1820,8 @@ msgstr "" msgid "extra positional arguments given" msgstr "" -#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c msgid "file must be a file opened in byte mode" msgstr "" @@ -1861,7 +1950,7 @@ msgstr "" msgid "integer required" msgstr "" -#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c #, c-format msgid "interval must be in range %s-%s" msgstr "" @@ -1955,6 +2044,10 @@ msgstr "" msgid "length argument not allowed for this type" msgstr "" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "" @@ -1983,6 +2076,12 @@ msgstr "" 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 "" @@ -2028,7 +2127,7 @@ msgstr "" msgid "name '%q' is not defined" msgstr "" -#: shared-bindings/bleio/Peripheral.c +#: shared-bindings/_bleio/Peripheral.c msgid "name must be a string" msgstr "" @@ -2073,16 +2172,17 @@ msgstr "" 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 "" -#: shared-bindings/bleio/Peripheral.c -msgid "non-Service found in services" -msgstr "" - -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c @@ -2101,7 +2201,7 @@ msgstr "" msgid "non-keyword arg after keyword arg" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "not a 128-bit UUID" msgstr "" @@ -2167,6 +2267,14 @@ msgstr "" 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" @@ -2275,7 +2383,7 @@ msgstr "" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" @@ -2390,10 +2498,6 @@ msgstr "" msgid "threshold must be in the range 0-65536" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "tile index out of bounds" -msgstr "" - #: shared-bindings/time/__init__.c msgid "time.struct_time() takes a 9-sequence" msgstr "" @@ -2406,7 +2510,7 @@ msgstr "" msgid "timeout >100 (units are now seconds, not msecs)" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "timeout must be >= 0.0" msgstr "" @@ -2559,7 +2663,7 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Scanner.c msgid "window must be <= interval" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index cf115716fb..c846b646b7 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-09 09:06-0400\n" +"POT-Creation-Date: 2019-09-08 17:30-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Pascal Deneaux\n" "Language-Team: Sebastian Plamauer, Pascal Deneaux\n" @@ -54,7 +54,7 @@ msgstr "Der Index %q befindet sich außerhalb der Reihung" 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/_bleio/CharacteristicBuffer.c #: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c msgid "%q must be >= 1" msgstr "%q muss >= 1 sein" @@ -219,12 +219,12 @@ msgstr "3-arg pow() wird nicht unterstützt" msgid "A hardware interrupt channel is already in use" msgstr "Ein Hardware Interrupt Kanal wird schon benutzt" -#: shared-bindings/bleio/Address.c +#: 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 +#: shared-bindings/_bleio/Address.c msgid "Address type out of range" msgstr "" @@ -255,6 +255,7 @@ 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" @@ -300,6 +301,10 @@ 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" @@ -312,6 +317,10 @@ msgstr "Bit depth muss ein Vielfaches von 8 sein." 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" @@ -325,6 +334,19 @@ msgstr "Die Helligkeit ist nicht einstellbar" 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" @@ -335,7 +357,7 @@ msgstr "Der Puffer muss eine Mindestenslänge von 1 haben" msgid "Bus pin %d is already in use" msgstr "Bus pin %d wird schon benutzt" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "Der Puffer muss 16 Bytes lang sein" @@ -352,8 +374,8 @@ msgstr "" 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 for local Characteristic" +#: 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 @@ -409,15 +431,7 @@ msgstr "sizeof scalar kann nicht eindeutig bestimmt werden" msgid "Cannot write without MOSI pin." msgstr "Kann nicht ohne MOSI-Pin schreiben." -#: shared-bindings/bleio/Service.c -msgid "Characteristic UUID doesn't match Service UUID" -msgstr "Characteristic UUID stimmt nicht mit der Service-UUID überein" - -#: ports/nrf/common-hal/bleio/Service.c -msgid "Characteristic already in use by another Service." -msgstr "Characteristic wird bereits von einem anderen Dienst verwendet." - -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "Schreiben von CharacteristicBuffer ist nicht vorgesehen" @@ -437,6 +451,10 @@ msgstr "Clock unit wird benutzt" 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" @@ -449,7 +467,7 @@ msgstr "" msgid "Corrupt raw code" msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c +#: 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" @@ -458,11 +476,11 @@ msgstr "Konnte ble_uuid nicht decodieren. Status: 0x%04x" msgid "Could not initialize UART" msgstr "Konnte UART nicht initialisieren" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "Konnte first buffer nicht zuteilen" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "Konnte second buffer nicht zuteilen" @@ -479,11 +497,11 @@ msgstr "DAC wird schon benutzt" msgid "Data 0 pin must be byte aligned" msgstr "Data 0 pin muss am Byte ausgerichtet sein" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Data chunk must follow fmt chunk" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: ports/nrf/common-hal/_bleio/Peripheral.c msgid "Data too large for advertisement packet" msgstr "Zu vielen Daten für das advertisement packet" @@ -491,7 +509,16 @@ msgstr "Zu vielen Daten für das advertisement packet" msgid "Destination capacity is smaller than destination_length." msgstr "Die Zielkapazität ist kleiner als destination_length." +#: ports/nrf/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +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 "Die Rotation der Anzeige muss in 90-Grad-Schritten erfolgen" @@ -515,16 +542,25 @@ msgstr "Fehler in regex" msgid "Expected a %q" msgstr "Erwartet ein(e) %q" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c msgid "Expected a Characteristic" msgstr "Characteristic wird erwartet" -#: shared-bindings/bleio/Characteristic.c shared-bindings/bleio/Descriptor.c -#: shared-bindings/bleio/Service.c +#: 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 +#: shared-bindings/_bleio/Central.c msgid "Expected an Address" msgstr "" @@ -542,12 +578,17 @@ msgstr "" msgid "Failed to acquire mutex, err 0x%04x" msgstr "Mutex konnte nicht akquiriert werden. Status: 0x%04x" -#: ports/nrf/common-hal/bleio/Service.c +#: 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/Peripheral.c +#: 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" @@ -562,57 +603,62 @@ msgstr "Konnte keinen RX Buffer allozieren" msgid "Failed to allocate RX buffer of %d bytes" msgstr "Konnte keine RX Buffer mit %d allozieren" -#: ports/nrf/common-hal/bleio/Adapter.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c msgid "Failed to connect: timeout" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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/Central.c +#: 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 +#: 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 +#: 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 +#: 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/Characteristic.c +#: 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/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/Characteristic.c +#: 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 +#: 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" @@ -622,42 +668,47 @@ msgstr "Kann keine herstellerspezifische UUID hinzufügen. Status: 0x%04x" msgid "Failed to release mutex, err 0x%04x" msgstr "Mutex konnte nicht freigegeben werden. Status: 0x%04x" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c #, c-format msgid "Failed to start connecting, error 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Characteristic.c #, c-format msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: 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/Characteristic.c +#: 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" @@ -693,6 +744,11 @@ msgstr "" 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" @@ -751,7 +807,7 @@ msgstr "Ungültige Puffergröße" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "Ungültige Anzahl von Kanälen" @@ -759,11 +815,11 @@ msgstr "Ungültige Anzahl von Kanälen" msgid "Invalid direction." msgstr "Ungültige Richtung" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid file" msgstr "Ungültige Datei" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" msgstr "Ungültige format chunk size" @@ -801,15 +857,27 @@ msgstr "Ungültige Pins" 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-bindings/audioio/Mixer.c +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "Ungültige Anzahl von Stimmen" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid wave file" msgstr "Ungültige wave Datei" @@ -876,7 +944,7 @@ msgstr "" msgid "Must be a %q subclass." msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Characteristic.c msgid "No CCCD for this Characteristic" msgstr "" @@ -922,6 +990,10 @@ msgstr "" 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" @@ -930,12 +1002,14 @@ msgstr "Kein Speicherplatz auf Gerät" msgid "No such file/directory" msgstr "Keine solche Datei/Verzeichnis" -#: ports/nrf/common-hal/bleio/Characteristic.c -#: shared-bindings/bleio/CharacteristicBuffer.c +#: 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" @@ -963,8 +1037,8 @@ msgstr "" #: shared-module/displayio/OnDiskBitmap.c #, c-format msgid "" -"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " -"given" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" msgstr "" #: shared-bindings/_pixelbuf/PixelBuf.c @@ -1040,6 +1114,10 @@ msgstr "Schreibgeschützte Dateisystem" 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" @@ -1060,11 +1138,12 @@ msgstr "Sicherheitsmodus aktiv! Gespeicherter Code wird nicht ausgeführt\n" msgid "SDA or SCL needs a pull up" msgstr "SDA oder SCL brauchen pull up" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/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" @@ -1083,7 +1162,7 @@ msgstr "Slice und Wert (value) haben unterschiedliche Längen." msgid "Slices not supported" msgstr "Slices werden nicht unterstützt" -#: ports/nrf/common-hal/bleio/Adapter.c +#: ports/nrf/common-hal/_bleio/Adapter.c #, c-format msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" @@ -1141,19 +1220,19 @@ msgstr "" "Die Reset-Taste wurde beim Booten von CircuitPython gedrückt. Drücke sie " "erneut um den abgesicherten Modus zu verlassen. \n" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "" @@ -1161,8 +1240,12 @@ msgstr "" 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 indices must be 0 - 255" +msgid "Tile value out of bounds" msgstr "" #: shared-bindings/displayio/TileGrid.c @@ -1177,11 +1260,13 @@ msgstr "Zum beenden, resette bitte das board ohne " msgid "Too many channels in sample." msgstr "Zu viele Kanäle im sample" -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +#: 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" @@ -1201,15 +1286,15 @@ msgstr "USB beschäftigt" msgid "USB Error" msgstr "USB Fehler" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID integer value must be 0-0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c +#: 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 +#: 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" @@ -1218,6 +1303,11 @@ msgstr "Der UUID-Wert ist kein str-, int- oder Byte-Puffer" 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" @@ -1235,7 +1325,7 @@ msgstr "" msgid "Unable to write to nvm." msgstr "Schreiben in nvm nicht möglich." -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c msgid "Unexpected nrfx uuid type" msgstr "Unerwarteter nrfx uuid-Typ" @@ -1250,11 +1340,11 @@ msgstr "" msgid "Unsupported baudrate" msgstr "Baudrate wird nicht unterstützt" -#: shared-module/displayio/Display.c +#: shared-module/displayio/display_core.c msgid "Unsupported display bus type" msgstr "Nicht unterstützter display bus type" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Unsupported format" msgstr "Nicht unterstütztes Format" @@ -1266,14 +1356,20 @@ msgstr "Nicht unterstützte Operation" 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/audioio/Mixer.c -msgid "Voice index too high" -msgstr "Voice index zu hoch" - #: main.c msgid "WARNING: Your code filename has two extensions\n" msgstr "" @@ -1365,10 +1461,6 @@ msgstr "Array/Bytes auf der rechten Seite erforderlich" msgid "attributes not supported yet" msgstr "Attribute werden noch nicht unterstützt" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "" - #: py/builtinevex.c msgid "bad compile mode" msgstr "" @@ -1397,7 +1489,7 @@ msgstr "bits muss 7, 8 oder 9 sein" msgid "bits must be 8" msgstr "bits müssen 8 sein" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "Es müssen 8 oder 16 bits_per_sample sein" @@ -1410,7 +1502,7 @@ msgstr "Zweig ist außerhalb der Reichweite" msgid "buf is too small. need %d bytes" msgstr "buf ist zu klein. brauche %d Bytes" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "buffer must be a bytes-like object" msgstr "Puffer muss ein bytes-artiges Objekt sein" @@ -1621,10 +1713,6 @@ msgstr "kann keinen relativen Import durchführen" msgid "casting" msgstr "" -#: shared-bindings/bleio/Service.c -msgid "characteristics includes an object that is not a Characteristic" -msgstr "" - #: shared-bindings/_stage/Text.c msgid "chars buffer too small" msgstr "" @@ -1772,7 +1860,8 @@ msgstr "Es wurden zusätzliche Keyword-Argumente angegeben" msgid "extra positional arguments given" msgstr "Es wurden zusätzliche Argumente ohne Keyword angegeben" -#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c +#: 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" @@ -1902,7 +1991,7 @@ msgstr "int() arg 2 muss >= 2 und <= 36 sein" msgid "integer required" msgstr "integer erforderlich" -#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c #, c-format msgid "interval must be in range %s-%s" msgstr "" @@ -2000,6 +2089,10 @@ msgstr "Label neu definiert" msgid "length argument not allowed for this type" msgstr "Für diesen Typ ist length nicht zulässig" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs und rhs sollten kompatibel sein" @@ -2030,6 +2123,12 @@ msgstr "map buffer zu klein" 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" @@ -2075,7 +2174,7 @@ msgstr "muss Schlüsselwortargument für key function verwenden" msgid "name '%q' is not defined" msgstr "Name '%q' ist nirgends definiert worden (Schreibweise kontrollieren)" -#: shared-bindings/bleio/Peripheral.c +#: shared-bindings/_bleio/Peripheral.c msgid "name must be a string" msgstr "name muss ein String sein" @@ -2120,16 +2219,17 @@ msgstr "" 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 "" -#: shared-bindings/bleio/Peripheral.c -msgid "non-Service found in services" -msgstr "" - -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c @@ -2148,7 +2248,7 @@ msgstr "" msgid "non-keyword arg after keyword arg" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "not a 128-bit UUID" msgstr "keine 128-bit UUID" @@ -2214,6 +2314,14 @@ msgstr "String mit ungerader Länge" 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" @@ -2324,7 +2432,7 @@ msgstr "" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" @@ -2442,10 +2550,6 @@ msgstr "Syntaxfehler in uctypes Deskriptor" msgid "threshold must be in the range 0-65536" msgstr "threshold muss im Intervall 0-65536 liegen" -#: shared-bindings/displayio/TileGrid.c -msgid "tile index out of bounds" -msgstr "" - #: shared-bindings/time/__init__.c msgid "time.struct_time() takes a 9-sequence" msgstr "" @@ -2458,7 +2562,7 @@ msgstr "" msgid "timeout >100 (units are now seconds, not msecs)" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "timeout must be >= 0.0" msgstr "timeout muss >= 0.0 sein" @@ -2615,7 +2719,7 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Scanner.c msgid "window must be <= interval" msgstr "" @@ -2680,6 +2784,12 @@ msgstr "" #~ 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" @@ -2813,6 +2923,9 @@ msgstr "" #~ msgstr "" #~ "Benutze das esptool um den flash zu löschen und Python erneut hochzuladen" +#~ msgid "Voice index too high" +#~ msgstr "Voice index zu hoch" + #~ msgid "buffer too long" #~ msgstr "Buffer zu lang" diff --git a/locale/en_US.po b/locale/en_US.po index ab1776aa24..652053ee99 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-09 09:06-0400\n" +"POT-Creation-Date: 2019-09-08 17:30-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -52,7 +52,7 @@ msgstr "" msgid "%q indices must be integers, not %s" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c msgid "%q must be >= 1" msgstr "" @@ -217,12 +217,12 @@ msgstr "" msgid "A hardware interrupt channel is already in use" msgstr "" -#: shared-bindings/bleio/Address.c +#: shared-bindings/_bleio/Address.c #, c-format msgid "Address must be %d bytes long" msgstr "" -#: shared-bindings/bleio/Address.c +#: shared-bindings/_bleio/Address.c msgid "Address type out of range" msgstr "" @@ -253,6 +253,7 @@ 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" @@ -296,6 +297,10 @@ msgid "" "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 "" @@ -308,6 +313,10 @@ msgstr "" 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 "" @@ -321,6 +330,19 @@ msgstr "" 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 "" @@ -331,7 +353,7 @@ msgstr "" msgid "Bus pin %d is already in use" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "" @@ -348,8 +370,8 @@ msgstr "" msgid "Can not use dotstar with %s" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +#: 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 @@ -405,15 +427,7 @@ msgstr "" msgid "Cannot write without MOSI pin." msgstr "" -#: shared-bindings/bleio/Service.c -msgid "Characteristic UUID doesn't match Service UUID" -msgstr "" - -#: ports/nrf/common-hal/bleio/Service.c -msgid "Characteristic already in use by another Service." -msgstr "" - -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "" @@ -433,6 +447,10 @@ msgstr "" 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 "" @@ -445,7 +463,7 @@ msgstr "" msgid "Corrupt raw code" msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c #, c-format msgid "Could not decode ble_uuid, err 0x%04x" msgstr "" @@ -454,11 +472,11 @@ msgstr "" msgid "Could not initialize UART" msgstr "" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "" @@ -475,11 +493,11 @@ msgstr "" msgid "Data 0 pin must be byte aligned" msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Data chunk must follow fmt chunk" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: ports/nrf/common-hal/_bleio/Peripheral.c msgid "Data too large for advertisement packet" msgstr "" @@ -487,7 +505,16 @@ msgstr "" msgid "Destination capacity is smaller than destination_length." msgstr "" +#: ports/nrf/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +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 "" @@ -511,16 +538,25 @@ msgstr "" msgid "Expected a %q" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c msgid "Expected a Characteristic" msgstr "" -#: shared-bindings/bleio/Characteristic.c shared-bindings/bleio/Descriptor.c -#: shared-bindings/bleio/Service.c +#: 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 +#: shared-bindings/_bleio/Central.c msgid "Expected an Address" msgstr "" @@ -538,12 +574,17 @@ msgstr "" msgid "Failed to acquire mutex, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Service.c +#: ports/nrf/common-hal/_bleio/Service.c #, c-format msgid "Failed to add characteristic, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: 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 "" @@ -558,57 +599,62 @@ msgstr "" msgid "Failed to allocate RX buffer of %d bytes" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c +#: ports/nrf/common-hal/_bleio/Adapter.c msgid "Failed to change softdevice state" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c msgid "Failed to connect: timeout" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: ports/nrf/common-hal/_bleio/Scanner.c #, c-format msgid "Failed to continue scanning, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c +#: ports/nrf/common-hal/_bleio/__init__.c msgid "Failed to discover services" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c +#: ports/nrf/common-hal/_bleio/Adapter.c msgid "Failed to get local address" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c +#: ports/nrf/common-hal/_bleio/Adapter.c msgid "Failed to get softdevice state" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: 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/Characteristic.c +#: 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/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/Characteristic.c +#: 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 +#: ports/nrf/common-hal/_bleio/UUID.c #, c-format msgid "Failed to register Vendor-Specific UUID, err 0x%04x" msgstr "" @@ -618,42 +664,47 @@ msgstr "" msgid "Failed to release mutex, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c #, c-format msgid "Failed to start connecting, error 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Characteristic.c #, c-format msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Failed to write attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Failed to write gatts value, err 0x%04x" msgstr "" @@ -689,6 +740,11 @@ msgstr "" 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 "" @@ -745,7 +801,7 @@ msgstr "" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "" @@ -753,11 +809,11 @@ msgstr "" msgid "Invalid direction." msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid file" msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" msgstr "" @@ -795,15 +851,27 @@ msgstr "" msgid "Invalid polarity" msgstr "" +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid wave file" msgstr "" @@ -863,7 +931,7 @@ msgstr "" msgid "Must be a %q subclass." msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Characteristic.c msgid "No CCCD for this Characteristic" msgstr "" @@ -909,6 +977,10 @@ msgstr "" 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 "" @@ -917,12 +989,14 @@ msgstr "" msgid "No such file/directory" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -#: shared-bindings/bleio/CharacteristicBuffer.c +#: 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 "" @@ -948,8 +1022,8 @@ msgstr "" #: shared-module/displayio/OnDiskBitmap.c #, c-format msgid "" -"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " -"given" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" msgstr "" #: shared-bindings/_pixelbuf/PixelBuf.c @@ -1023,6 +1097,10 @@ msgstr "" 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 "" @@ -1043,11 +1121,12 @@ msgstr "" msgid "SDA or SCL needs a pull up" msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/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 "" @@ -1066,7 +1145,7 @@ msgstr "" msgid "Slices not supported" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c +#: ports/nrf/common-hal/_bleio/Adapter.c #, c-format msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" @@ -1112,19 +1191,19 @@ msgid "" "exit safe mode.\n" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "" @@ -1132,8 +1211,12 @@ msgstr "" 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 indices must be 0 - 255" +msgid "Tile value out of bounds" msgstr "" #: shared-bindings/displayio/TileGrid.c @@ -1148,11 +1231,13 @@ msgstr "" msgid "Too many channels in sample." msgstr "" -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +#: 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 "" @@ -1172,15 +1257,15 @@ msgstr "" msgid "USB Error" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID integer value must be 0-0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID value is not str, int or byte buffer" msgstr "" @@ -1189,6 +1274,11 @@ msgstr "" 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" @@ -1206,7 +1296,7 @@ msgstr "" msgid "Unable to write to nvm." msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c msgid "Unexpected nrfx uuid type" msgstr "" @@ -1219,11 +1309,11 @@ msgstr "" msgid "Unsupported baudrate" msgstr "" -#: shared-module/displayio/Display.c +#: shared-module/displayio/display_core.c msgid "Unsupported display bus type" msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Unsupported format" msgstr "" @@ -1235,12 +1325,18 @@ msgstr "" msgid "Unsupported pull value." msgstr "" -#: py/emitnative.c -msgid "Viper functions don't currently support more than 4 arguments" +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" msgstr "" -#: shared-module/audioio/Mixer.c -msgid "Voice index too high" +#: 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 "" #: main.c @@ -1325,10 +1421,6 @@ msgstr "" msgid "attributes not supported yet" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "" - #: py/builtinevex.c msgid "bad compile mode" msgstr "" @@ -1357,7 +1449,7 @@ msgstr "" msgid "bits must be 8" msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "" @@ -1370,7 +1462,7 @@ msgstr "" msgid "buf is too small. need %d bytes" msgstr "" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "buffer must be a bytes-like object" msgstr "" @@ -1581,10 +1673,6 @@ msgstr "" msgid "casting" msgstr "" -#: shared-bindings/bleio/Service.c -msgid "characteristics includes an object that is not a Characteristic" -msgstr "" - #: shared-bindings/_stage/Text.c msgid "chars buffer too small" msgstr "" @@ -1732,7 +1820,8 @@ msgstr "" msgid "extra positional arguments given" msgstr "" -#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c msgid "file must be a file opened in byte mode" msgstr "" @@ -1861,7 +1950,7 @@ msgstr "" msgid "integer required" msgstr "" -#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c #, c-format msgid "interval must be in range %s-%s" msgstr "" @@ -1955,6 +2044,10 @@ msgstr "" msgid "length argument not allowed for this type" msgstr "" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "" @@ -1983,6 +2076,12 @@ msgstr "" 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 "" @@ -2028,7 +2127,7 @@ msgstr "" msgid "name '%q' is not defined" msgstr "" -#: shared-bindings/bleio/Peripheral.c +#: shared-bindings/_bleio/Peripheral.c msgid "name must be a string" msgstr "" @@ -2073,16 +2172,17 @@ msgstr "" 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 "" -#: shared-bindings/bleio/Peripheral.c -msgid "non-Service found in services" -msgstr "" - -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c @@ -2101,7 +2201,7 @@ msgstr "" msgid "non-keyword arg after keyword arg" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "not a 128-bit UUID" msgstr "" @@ -2167,6 +2267,14 @@ msgstr "" 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" @@ -2275,7 +2383,7 @@ msgstr "" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" @@ -2390,10 +2498,6 @@ msgstr "" msgid "threshold must be in the range 0-65536" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "tile index out of bounds" -msgstr "" - #: shared-bindings/time/__init__.c msgid "time.struct_time() takes a 9-sequence" msgstr "" @@ -2406,7 +2510,7 @@ msgstr "" msgid "timeout >100 (units are now seconds, not msecs)" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "timeout must be >= 0.0" msgstr "" @@ -2559,7 +2663,7 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Scanner.c msgid "window must be <= interval" msgstr "" diff --git a/locale/en_x_pirate.po b/locale/en_x_pirate.po index 550966a943..1d2fcb659c 100644 --- a/locale/en_x_pirate.po +++ b/locale/en_x_pirate.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-09 09:06-0400\n" +"POT-Creation-Date: 2019-09-08 17:30-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: @sommersoft, @MrCertainly\n" @@ -54,7 +54,7 @@ msgstr "" msgid "%q indices must be integers, not %s" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c msgid "%q must be >= 1" msgstr "" @@ -219,12 +219,12 @@ msgstr "" msgid "A hardware interrupt channel is already in use" msgstr "Avast! A hardware interrupt channel be used already" -#: shared-bindings/bleio/Address.c +#: shared-bindings/_bleio/Address.c #, c-format msgid "Address must be %d bytes long" msgstr "" -#: shared-bindings/bleio/Address.c +#: shared-bindings/_bleio/Address.c msgid "Address type out of range" msgstr "" @@ -255,6 +255,7 @@ 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" @@ -300,6 +301,10 @@ 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 "" @@ -312,6 +317,10 @@ msgstr "" 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 "" @@ -325,6 +334,19 @@ msgstr "" 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 "" @@ -335,7 +357,7 @@ msgstr "" msgid "Bus pin %d is already in use" msgstr "Belay that! Bus pin %d already be in use" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "" @@ -352,8 +374,8 @@ msgstr "" msgid "Can not use dotstar with %s" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +#: 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 @@ -409,15 +431,7 @@ msgstr "" msgid "Cannot write without MOSI pin." msgstr "" -#: shared-bindings/bleio/Service.c -msgid "Characteristic UUID doesn't match Service UUID" -msgstr "" - -#: ports/nrf/common-hal/bleio/Service.c -msgid "Characteristic already in use by another Service." -msgstr "" - -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "" @@ -437,6 +451,10 @@ msgstr "" 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 "" @@ -449,7 +467,7 @@ msgstr "" msgid "Corrupt raw code" msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c #, c-format msgid "Could not decode ble_uuid, err 0x%04x" msgstr "" @@ -458,11 +476,11 @@ msgstr "" msgid "Could not initialize UART" msgstr "" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "" @@ -479,11 +497,11 @@ msgstr "" msgid "Data 0 pin must be byte aligned" msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Data chunk must follow fmt chunk" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: ports/nrf/common-hal/_bleio/Peripheral.c msgid "Data too large for advertisement packet" msgstr "" @@ -491,7 +509,16 @@ msgstr "" msgid "Destination capacity is smaller than destination_length." msgstr "" +#: ports/nrf/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +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 "" @@ -515,16 +542,25 @@ msgstr "" msgid "Expected a %q" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c msgid "Expected a Characteristic" msgstr "" -#: shared-bindings/bleio/Characteristic.c shared-bindings/bleio/Descriptor.c -#: shared-bindings/bleio/Service.c +#: 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 +#: shared-bindings/_bleio/Central.c msgid "Expected an Address" msgstr "" @@ -542,12 +578,17 @@ msgstr "" msgid "Failed to acquire mutex, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Service.c +#: ports/nrf/common-hal/_bleio/Service.c #, c-format msgid "Failed to add characteristic, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: 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 "" @@ -562,57 +603,62 @@ msgstr "" msgid "Failed to allocate RX buffer of %d bytes" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c +#: ports/nrf/common-hal/_bleio/Adapter.c msgid "Failed to change softdevice state" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c msgid "Failed to connect: timeout" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: ports/nrf/common-hal/_bleio/Scanner.c #, c-format msgid "Failed to continue scanning, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Central.c +#: ports/nrf/common-hal/_bleio/__init__.c msgid "Failed to discover services" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c +#: ports/nrf/common-hal/_bleio/Adapter.c msgid "Failed to get local address" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c +#: ports/nrf/common-hal/_bleio/Adapter.c msgid "Failed to get softdevice state" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: 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/Characteristic.c +#: 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/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/Characteristic.c +#: 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 +#: ports/nrf/common-hal/_bleio/UUID.c #, c-format msgid "Failed to register Vendor-Specific UUID, err 0x%04x" msgstr "" @@ -622,42 +668,47 @@ msgstr "" msgid "Failed to release mutex, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c #, c-format msgid "Failed to start connecting, error 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Characteristic.c #, c-format msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Failed to write attribute value, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Failed to write gatts value, err 0x%04x" msgstr "" @@ -693,6 +744,11 @@ msgstr "" 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 "" @@ -749,7 +805,7 @@ msgstr "" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "" @@ -757,11 +813,11 @@ msgstr "" msgid "Invalid direction." msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid file" msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" msgstr "" @@ -799,15 +855,27 @@ msgstr "" msgid "Invalid polarity" msgstr "" +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid wave file" msgstr "" @@ -867,7 +935,7 @@ msgstr "" msgid "Must be a %q subclass." msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Characteristic.c msgid "No CCCD for this Characteristic" msgstr "" @@ -913,6 +981,10 @@ msgstr "" 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 "" @@ -921,12 +993,14 @@ msgstr "" msgid "No such file/directory" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -#: shared-bindings/bleio/CharacteristicBuffer.c +#: 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 "" @@ -952,8 +1026,8 @@ msgstr "" #: shared-module/displayio/OnDiskBitmap.c #, c-format msgid "" -"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " -"given" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" msgstr "" #: shared-bindings/_pixelbuf/PixelBuf.c @@ -1027,6 +1101,10 @@ msgstr "" 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 "" @@ -1047,11 +1125,12 @@ msgstr "Runnin' in safe mode! Nay runnin' saved code.\n" msgid "SDA or SCL needs a pull up" msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/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 "" @@ -1070,7 +1149,7 @@ msgstr "" msgid "Slices not supported" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c +#: ports/nrf/common-hal/_bleio/Adapter.c #, c-format msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" @@ -1116,19 +1195,19 @@ msgid "" "exit safe mode.\n" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "" @@ -1136,8 +1215,12 @@ msgstr "" 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 indices must be 0 - 255" +msgid "Tile value out of bounds" msgstr "" #: shared-bindings/displayio/TileGrid.c @@ -1152,11 +1235,13 @@ msgstr "" msgid "Too many channels in sample." msgstr "" -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +#: 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 "" @@ -1176,15 +1261,15 @@ msgstr "" msgid "USB Error" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID integer value must be 0-0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID value is not str, int or byte buffer" msgstr "" @@ -1193,6 +1278,11 @@ msgstr "" 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" @@ -1210,7 +1300,7 @@ msgstr "" msgid "Unable to write to nvm." msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c msgid "Unexpected nrfx uuid type" msgstr "" @@ -1223,11 +1313,11 @@ msgstr "" msgid "Unsupported baudrate" msgstr "" -#: shared-module/displayio/Display.c +#: shared-module/displayio/display_core.c msgid "Unsupported display bus type" msgstr "" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Unsupported format" msgstr "" @@ -1239,12 +1329,18 @@ msgstr "" msgid "Unsupported pull value." msgstr "" -#: py/emitnative.c -msgid "Viper functions don't currently support more than 4 arguments" +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" msgstr "" -#: shared-module/audioio/Mixer.c -msgid "Voice index too high" +#: 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 "" #: main.c @@ -1329,10 +1425,6 @@ msgstr "" msgid "attributes not supported yet" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "" - #: py/builtinevex.c msgid "bad compile mode" msgstr "" @@ -1361,7 +1453,7 @@ msgstr "" msgid "bits must be 8" msgstr "pieces must be of 8" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "" @@ -1374,7 +1466,7 @@ msgstr "" msgid "buf is too small. need %d bytes" msgstr "" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "buffer must be a bytes-like object" msgstr "" @@ -1585,10 +1677,6 @@ msgstr "" msgid "casting" msgstr "" -#: shared-bindings/bleio/Service.c -msgid "characteristics includes an object that is not a Characteristic" -msgstr "" - #: shared-bindings/_stage/Text.c msgid "chars buffer too small" msgstr "" @@ -1736,7 +1824,8 @@ msgstr "" msgid "extra positional arguments given" msgstr "" -#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c msgid "file must be a file opened in byte mode" msgstr "" @@ -1865,7 +1954,7 @@ msgstr "" msgid "integer required" msgstr "" -#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c #, c-format msgid "interval must be in range %s-%s" msgstr "" @@ -1959,6 +2048,10 @@ msgstr "" msgid "length argument not allowed for this type" msgstr "" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "" @@ -1987,6 +2080,12 @@ msgstr "" 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 "" @@ -2032,7 +2131,7 @@ msgstr "" msgid "name '%q' is not defined" msgstr "" -#: shared-bindings/bleio/Peripheral.c +#: shared-bindings/_bleio/Peripheral.c msgid "name must be a string" msgstr "" @@ -2077,16 +2176,17 @@ msgstr "" 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 "" -#: shared-bindings/bleio/Peripheral.c -msgid "non-Service found in services" -msgstr "" - -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c @@ -2105,7 +2205,7 @@ msgstr "" msgid "non-keyword arg after keyword arg" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "not a 128-bit UUID" msgstr "" @@ -2171,6 +2271,14 @@ msgstr "" 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" @@ -2279,7 +2387,7 @@ msgstr "" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" @@ -2394,10 +2502,6 @@ msgstr "" msgid "threshold must be in the range 0-65536" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "tile index out of bounds" -msgstr "" - #: shared-bindings/time/__init__.c msgid "time.struct_time() takes a 9-sequence" msgstr "" @@ -2410,7 +2514,7 @@ msgstr "" msgid "timeout >100 (units are now seconds, not msecs)" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "timeout must be >= 0.0" msgstr "" @@ -2563,7 +2667,7 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Scanner.c msgid "window must be <= interval" msgstr "" diff --git a/locale/es.po b/locale/es.po index a1e90b0eb9..ca8593dcdf 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-09 09:07-0400\n" +"POT-Creation-Date: 2019-09-08 17:30-0500\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -54,7 +54,7 @@ msgstr "%q indice fuera de rango" msgid "%q indices must be integers, not %s" msgstr "%q indices deben ser enteros, no %s" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: 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" @@ -219,12 +219,12 @@ msgstr "pow() con 3 argumentos no soportado" msgid "A hardware interrupt channel is already in use" msgstr "El canal EXTINT ya está siendo utilizado" -#: shared-bindings/bleio/Address.c +#: 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 +#: shared-bindings/_bleio/Address.c msgid "Address type out of range" msgstr "" @@ -257,6 +257,7 @@ 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" @@ -304,6 +305,10 @@ 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" @@ -316,6 +321,10 @@ msgstr "Bits depth debe ser múltiplo de 8." 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" @@ -329,6 +338,19 @@ msgstr "El brillo no se puede ajustar" 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" @@ -339,7 +361,7 @@ msgstr "Buffer debe ser de longitud 1 como minimo" msgid "Bus pin %d is already in use" msgstr "Bus pin %d ya está siendo utilizado" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "Byte buffer debe de ser 16 bytes" @@ -356,8 +378,8 @@ msgstr "" 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 for local Characteristic" +#: 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 @@ -413,15 +435,7 @@ msgstr "No se puede obtener inequívocamente sizeof escalar" msgid "Cannot write without MOSI pin." msgstr "No se puede escribir sin pin MOSI." -#: shared-bindings/bleio/Service.c -msgid "Characteristic UUID doesn't match Service UUID" -msgstr "Características UUID no concide con el Service UUID" - -#: ports/nrf/common-hal/bleio/Service.c -msgid "Characteristic already in use by another Service." -msgstr "Características ya esta en uso por otro Serivice" - -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "CharateristicBuffer escritura no proporcionada" @@ -441,6 +455,10 @@ msgstr "Clock unit está siendo utilizado" 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." @@ -453,7 +471,7 @@ msgstr "" msgid "Corrupt raw code" msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c +#: 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" @@ -462,11 +480,11 @@ msgstr "No se puede descodificar ble_uuid, err 0x%04x" msgid "Could not initialize UART" msgstr "No se puede inicializar la UART" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "No se pudo asignar el primer buffer" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "No se pudo asignar el segundo buffer" @@ -483,11 +501,11 @@ msgstr "DAC ya está siendo utilizado" msgid "Data 0 pin must be byte aligned" msgstr "El pin Data 0 debe estar alineado a bytes" -#: shared-module/audioio/WaveFile.c +#: 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 +#: ports/nrf/common-hal/_bleio/Peripheral.c msgid "Data too large for advertisement packet" msgstr "Data es muy grande para el paquete de advertisement." @@ -495,7 +513,16 @@ msgstr "Data es muy grande para el paquete de advertisement." msgid "Destination capacity is smaller than destination_length." msgstr "Capacidad de destino es mas pequeña que destination_length." +#: ports/nrf/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +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 "Rotación de display debe ser en incrementos de 90 grados" @@ -519,16 +546,25 @@ msgstr "Error en regex" msgid "Expected a %q" msgstr "Se espera un %q" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c msgid "Expected a Characteristic" msgstr "Se esperaba una Característica." -#: shared-bindings/bleio/Characteristic.c shared-bindings/bleio/Descriptor.c -#: shared-bindings/bleio/Service.c +#: 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 +#: shared-bindings/_bleio/Central.c msgid "Expected an Address" msgstr "" @@ -546,12 +582,17 @@ msgstr "Fallo enviando comando" 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 +#: 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/Peripheral.c +#: 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" @@ -566,58 +607,63 @@ msgstr "Ha fallado la asignación del buffer RX" 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 +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c msgid "Failed to connect: timeout" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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/Central.c +#: 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 +#: 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 +#: 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 +#: 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/Characteristic.c +#: 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 -#, c-format +#: 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/Characteristic.c +#: 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 +#: 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" @@ -627,42 +673,47 @@ msgstr "Fallo al registrar el Vendor-Specific UUID, err 0x%04x" 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 +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c #, c-format msgid "Failed to start connecting, error 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Characteristic.c #, c-format msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: 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/Characteristic.c +#: 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" @@ -698,6 +749,11 @@ msgstr "Frecuencia capturada por encima de la capacidad. Captura en pausa." 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" @@ -756,7 +812,7 @@ msgstr "Tamaño de buffer inválido" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "Inválido periodo de captura. Rango válido: 1 - 500" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "Cuenta de canales inválida" @@ -764,11 +820,11 @@ msgstr "Cuenta de canales inválida" msgid "Invalid direction." msgstr "Dirección inválida." -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid file" msgstr "Archivo inválido" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" msgstr "Formato de fragmento de formato no válido" @@ -806,15 +862,27 @@ msgstr "pines inválidos" 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-bindings/audioio/Mixer.c +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "Cuenta de voces inválida" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid wave file" msgstr "Archivo wave inválido" @@ -878,7 +946,7 @@ msgstr "Micrófono demora de inicio debe estar en el rango 0.0 a 1.0" msgid "Must be a %q subclass." msgstr "Debe de ser una subclase de %q" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Characteristic.c msgid "No CCCD for this Characteristic" msgstr "" @@ -924,6 +992,10 @@ msgstr "Sin soporte de hardware en el pin clk" 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" @@ -932,12 +1004,14 @@ msgstr "No queda espacio en el dispositivo" msgid "No such file/directory" msgstr "No existe el archivo/directorio" -#: ports/nrf/common-hal/bleio/Characteristic.c -#: shared-bindings/bleio/CharacteristicBuffer.c +#: 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" @@ -967,11 +1041,9 @@ msgstr "" #: shared-module/displayio/OnDiskBitmap.c #, c-format msgid "" -"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " -"given" +"Only monochrome, indexed 4bpp or 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" #: shared-bindings/_pixelbuf/PixelBuf.c #, fuzzy @@ -1051,6 +1123,10 @@ msgstr "Sistema de archivos de solo-Lectura" 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" @@ -1071,11 +1147,12 @@ msgstr "Ejecutando en modo seguro! No se esta ejecutando el código guardado.\n" msgid "SDA or SCL needs a pull up" msgstr "SDA o SCL necesitan una pull up" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/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" @@ -1094,7 +1171,7 @@ msgstr "Slice y value tienen diferentes longitudes" msgid "Slices not supported" msgstr "Rebanadas no soportadas" -#: ports/nrf/common-hal/bleio/Adapter.c +#: 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" @@ -1152,19 +1229,19 @@ msgstr "" "El botón reset fue presionado mientras arrancaba CircuitPython. Presiona " "otra vez para salir del modo seguro.\n" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.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/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.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/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.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/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "El signo del sample no iguala al del mixer" @@ -1172,9 +1249,13 @@ msgstr "El signo del sample no iguala al del mixer" 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 indices must be 0 - 255" -msgstr "Los índices de Tile deben ser 0 - 255" +msgid "Tile value out of bounds" +msgstr "" #: shared-bindings/displayio/TileGrid.c msgid "Tile width must exactly divide bitmap width" @@ -1188,11 +1269,13 @@ msgstr "Para salir, por favor reinicia la tarjeta sin " msgid "Too many channels in sample." msgstr "Demasiados canales en sample." -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +#: 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" @@ -1212,15 +1295,15 @@ msgstr "USB ocupado" msgid "USB Error" msgstr "Error USB" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID integer value must be 0-0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c +#: 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 +#: 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" @@ -1229,6 +1312,11 @@ msgstr "UUID valor no es un str, int o byte buffer" 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" @@ -1246,7 +1334,7 @@ msgstr "No se pudo leer los datos de la paleta de colores" msgid "Unable to write to nvm." msgstr "Imposible escribir en nvm" -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c msgid "Unexpected nrfx uuid type" msgstr "Tipo de uuid nrfx inesperado" @@ -1259,12 +1347,12 @@ msgstr "Número incomparable de elementos en RHS (%d esperado,%d obtenido)" msgid "Unsupported baudrate" msgstr "Baudrate no soportado" -#: shared-module/displayio/Display.c +#: shared-module/displayio/display_core.c #, fuzzy msgid "Unsupported display bus type" msgstr "tipo de bitmap no soportado" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Unsupported format" msgstr "Formato no soportado" @@ -1276,14 +1364,20 @@ msgstr "Operación no soportada" 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/audioio/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" @@ -1374,10 +1468,6 @@ msgstr "array/bytes requeridos en el lado derecho" msgid "attributes not supported yet" msgstr "atributos aún no soportados" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "mal GATT role" - #: py/builtinevex.c msgid "bad compile mode" msgstr "modo de compilación erroneo" @@ -1406,7 +1496,7 @@ msgstr "bits deben ser 7, 8 ó 9" msgid "bits must be 8" msgstr "bits debe ser 8" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "bits_per_sample debe ser 8 ó 16" @@ -1419,7 +1509,7 @@ msgstr "El argumento de chr() no esta en el rango(256)" msgid "buf is too small. need %d bytes" msgstr "buf es demasiado pequeño. necesita %d bytes" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "buffer must be a bytes-like object" msgstr "buffer debe de ser un objeto bytes-like" @@ -1635,10 +1725,6 @@ msgstr "no se puedo realizar importación relativa" msgid "casting" msgstr "" -#: shared-bindings/bleio/Service.c -msgid "characteristics includes an object that is not a Characteristic" -msgstr "characteristics incluye un objeto que no es una Characteristica" - #: shared-bindings/_stage/Text.c msgid "chars buffer too small" msgstr "chars buffer es demasiado pequeño" @@ -1788,7 +1874,8 @@ msgstr "argumento(s) por palabra clave adicionales fueron dados" msgid "extra positional arguments given" msgstr "argumento posicional adicional dado" -#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c +#: 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" @@ -1917,7 +2004,7 @@ msgstr "int() arg 2 debe ser >= 2 y <= 36" msgid "integer required" msgstr "Entero requerido" -#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c #, c-format msgid "interval must be in range %s-%s" msgstr "" @@ -2014,6 +2101,10 @@ msgstr "etiqueta redefinida" msgid "length argument not allowed for this type" msgstr "argumento length no permitido para este tipo" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs y rhs deben ser compatibles" @@ -2042,6 +2133,12 @@ msgstr "map buffer muy pequeño" 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" @@ -2087,7 +2184,7 @@ msgstr "debe utilizar argumento de palabra clave para la función clave" msgid "name '%q' is not defined" msgstr "name '%q' no esta definido" -#: shared-bindings/bleio/Peripheral.c +#: shared-bindings/_bleio/Peripheral.c msgid "name must be a string" msgstr "name debe de ser un string" @@ -2132,16 +2229,17 @@ msgstr "no se ha encontrado ningún enlace para nonlocal" 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" -#: shared-bindings/bleio/Peripheral.c -msgid "non-Service found in services" -msgstr "" - -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c @@ -2162,7 +2260,7 @@ msgstr "" "no deberia estar/tener agumento por palabra clave despues de argumento por " "palabra clave" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "not a 128-bit UUID" msgstr "no es 128-bit UUID" @@ -2230,6 +2328,14 @@ msgstr "string de longitud impar" 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" @@ -2339,7 +2445,7 @@ msgstr "retorno esperado '%q' pero se obtuvo '%q'" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" @@ -2457,10 +2563,6 @@ msgstr "error de sintaxis en el descriptor uctypes" msgid "threshold must be in the range 0-65536" msgstr "limite debe ser en el rango 0-65536" -#: shared-bindings/displayio/TileGrid.c -msgid "tile index out of bounds" -msgstr "el indice del tile fuera de limite" - #: shared-bindings/time/__init__.c msgid "time.struct_time() takes a 9-sequence" msgstr "time.struct_time() toma un sequencio 9" @@ -2473,7 +2575,7 @@ msgstr "time.struct_time() acepta exactamente 1 argumento" msgid "timeout >100 (units are now seconds, not msecs)" msgstr "timepo muerto >100 (unidades en segundos)" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "timeout must be >= 0.0" msgstr "tiempo muerto debe ser >= 0.0" @@ -2626,7 +2728,7 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Scanner.c msgid "window must be <= interval" msgstr "" @@ -2690,6 +2792,12 @@ msgstr "paso cero" #~ 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." @@ -2793,6 +2901,13 @@ msgstr "paso cero" #~ 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" @@ -2817,6 +2932,9 @@ msgstr "paso cero" #~ 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" @@ -2836,6 +2954,12 @@ msgstr "paso cero" #~ msgstr "" #~ "Usa esptool para borrar la flash y vuelve a cargar Python en su lugar" +#~ msgid "Voice index too high" +#~ msgstr "Index de voz demasiado alto" + +#~ msgid "bad GATT role" +#~ msgstr "mal GATT role" + #~ msgid "buffer too long" #~ msgstr "buffer demasiado largo" @@ -2854,6 +2978,9 @@ msgstr "paso cero" #~ 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" @@ -2918,6 +3045,9 @@ msgstr "paso cero" #~ 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" diff --git a/locale/fil.po b/locale/fil.po index 29e969566d..6f460c94cf 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-09 09:06-0400\n" +"POT-Creation-Date: 2019-09-08 17:30-0500\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -52,7 +52,7 @@ msgstr "%q indeks wala sa sakop" msgid "%q indices must be integers, not %s" msgstr "%q indeks ay dapat integers, hindi %s" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c #, fuzzy msgid "%q must be >= 1" @@ -220,12 +220,12 @@ msgstr "3-arg pow() hindi suportado" msgid "A hardware interrupt channel is already in use" msgstr "Isang channel ng hardware interrupt ay ginagamit na" -#: shared-bindings/bleio/Address.c +#: 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 +#: shared-bindings/_bleio/Address.c msgid "Address type out of range" msgstr "" @@ -257,6 +257,7 @@ 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" @@ -302,6 +303,10 @@ 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" @@ -314,6 +319,10 @@ msgstr "Bit depth ay dapat multiple ng 8." 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" @@ -327,6 +336,19 @@ msgstr "" 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" @@ -337,7 +359,7 @@ msgstr "Buffer dapat ay hindi baba sa 1 na haba" msgid "Bus pin %d is already in use" msgstr "Ginagamit na ang DAC" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c #, fuzzy msgid "Byte buffer must be 16 bytes." msgstr "buffer ay dapat bytes-like object" @@ -355,8 +377,8 @@ msgstr "" msgid "Can not use dotstar with %s" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +#: 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 @@ -413,15 +435,7 @@ msgstr "Hindi puedeng hindi sigurado ang get sizeof scalar" msgid "Cannot write without MOSI pin." msgstr "Hindi maaring isulat kapag walang MOSI pin." -#: shared-bindings/bleio/Service.c -msgid "Characteristic UUID doesn't match Service UUID" -msgstr "" - -#: ports/nrf/common-hal/bleio/Service.c -msgid "Characteristic already in use by another Service." -msgstr "" - -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "" @@ -441,6 +455,10 @@ msgstr "Clock unit ginagamit" 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" @@ -454,7 +472,7 @@ msgstr "" msgid "Corrupt raw code" msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c #, c-format msgid "Could not decode ble_uuid, err 0x%04x" msgstr "" @@ -463,11 +481,11 @@ msgstr "" msgid "Could not initialize UART" msgstr "Hindi ma-initialize ang UART" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "Hindi ma-iallocate ang first buffer" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "Hindi ma-iallocate ang second buffer" @@ -485,11 +503,11 @@ msgstr "Ginagamit na ang DAC" msgid "Data 0 pin must be byte aligned" msgstr "graphic ay dapat 2048 bytes ang haba" -#: shared-module/audioio/WaveFile.c +#: 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 +#: 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" @@ -499,7 +517,16 @@ msgid "Destination capacity is smaller than destination_length." msgstr "" "Ang kapasidad ng destinasyon ay mas maliit kaysa sa destination_length." +#: ports/nrf/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +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 "" @@ -523,18 +550,27 @@ msgstr "May pagkakamali sa REGEX" msgid "Expected a %q" msgstr "Umasa ng %q" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c #, fuzzy msgid "Expected a Characteristic" msgstr "Hindi mabasa and Characteristic." -#: shared-bindings/bleio/Characteristic.c shared-bindings/bleio/Descriptor.c -#: shared-bindings/bleio/Service.c +#: 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 +#: shared-bindings/_bleio/Central.c msgid "Expected an Address" msgstr "" @@ -552,12 +588,17 @@ msgstr "" 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 +#: 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/Peripheral.c +#: 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" @@ -572,61 +613,66 @@ msgstr "Nabigong ilaan ang RX buffer" 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 +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c msgid "Failed to connect: timeout" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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/Central.c +#: 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 +#: 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 +#: 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 +#: 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/Characteristic.c +#: 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/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/Characteristic.c +#: 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 +#: 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" @@ -636,42 +682,47 @@ msgstr "Hindi matagumpay ang paglagay ng Vender Specific UUID, status: 0x%08lX" msgid "Failed to release mutex, err 0x%04x" msgstr "Nabigo sa pagrelease ng mutex, status: 0x%08lX" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c #, c-format msgid "Failed to start connecting, error 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Characteristic.c #, c-format msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: 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/Characteristic.c +#: 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" @@ -707,6 +758,11 @@ msgstr "" 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" @@ -765,7 +821,7 @@ msgstr "Mali ang buffer size" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "Maling bilang ng channel" @@ -773,11 +829,11 @@ msgstr "Maling bilang ng channel" msgid "Invalid direction." msgstr "Mali ang direksyon." -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid file" msgstr "Mali ang file" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" msgstr "Mali ang format ng chunk size" @@ -815,15 +871,27 @@ msgstr "Mali ang pins" 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-bindings/audioio/Mixer.c +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "Maling bilang ng voice" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid wave file" msgstr "May hindi tama sa wave file" @@ -887,7 +955,7 @@ msgstr "Ang delay ng startup ng mikropono ay dapat na nasa 0.0 hanggang 1.0" msgid "Must be a %q subclass." msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Characteristic.c msgid "No CCCD for this Characteristic" msgstr "" @@ -933,6 +1001,10 @@ msgstr "" 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 "" @@ -941,13 +1013,15 @@ msgstr "" msgid "No such file/directory" msgstr "Walang file/directory" -#: ports/nrf/common-hal/bleio/Characteristic.c -#: shared-bindings/bleio/CharacteristicBuffer.c +#: 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" @@ -975,8 +1049,8 @@ msgstr "" #: shared-module/displayio/OnDiskBitmap.c #, c-format msgid "" -"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " -"given" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" msgstr "" #: shared-bindings/_pixelbuf/PixelBuf.c @@ -1056,6 +1130,10 @@ msgstr "Basahin-lamang mode" 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" @@ -1076,11 +1154,12 @@ msgstr "Tumatakbo sa safe mode! Hindi tumatakbo ang nai-save na code.\n" msgid "SDA or SCL needs a pull up" msgstr "Kailangan ng pull up resistors ang SDA o SCL" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/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" @@ -1099,7 +1178,7 @@ msgstr "Slice at value iba't ibang haba." msgid "Slices not supported" msgstr "Hindi suportado ang Slices" -#: ports/nrf/common-hal/bleio/Adapter.c +#: ports/nrf/common-hal/_bleio/Adapter.c #, c-format msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" @@ -1155,19 +1234,19 @@ msgstr "" "Ang reset button ay pinindot habang nag boot ang CircuitPython. Pindutin " "ulit para lumabas sa safe mode.\n" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.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/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.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/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.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/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "Ang signedness ng sample hindi tugma sa mixer" @@ -1175,8 +1254,12 @@ msgstr "Ang signedness ng sample hindi tugma sa mixer" 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 indices must be 0 - 255" +msgid "Tile value out of bounds" msgstr "" #: shared-bindings/displayio/TileGrid.c @@ -1191,11 +1274,13 @@ msgstr "Para lumabas, paki-reset ang board na wala ang " msgid "Too many channels in sample." msgstr "Sobra ang channels sa sample." -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +#: 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 "" @@ -1215,15 +1300,15 @@ msgstr "Busy ang USB" msgid "USB Error" msgstr "May pagkakamali ang USB" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID integer value must be 0-0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID value is not str, int or byte buffer" msgstr "" @@ -1232,6 +1317,11 @@ msgstr "" 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" @@ -1249,7 +1339,7 @@ msgstr "" msgid "Unable to write to nvm." msgstr "Hindi ma i-sulat sa NVM." -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c #, fuzzy msgid "Unexpected nrfx uuid type" msgstr "hindi inaasahang indent" @@ -1263,12 +1353,12 @@ msgstr "" msgid "Unsupported baudrate" msgstr "Hindi supportadong baudrate" -#: shared-module/displayio/Display.c +#: shared-module/displayio/display_core.c #, fuzzy msgid "Unsupported display bus type" msgstr "Hindi supportadong tipo ng bitmap" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Unsupported format" msgstr "Hindi supportadong format" @@ -1280,16 +1370,22 @@ msgstr "Hindi sinusuportahang operasyon" 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/audioio/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" @@ -1378,10 +1474,6 @@ msgstr "array/bytes kinakailangan sa kanang bahagi" msgid "attributes not supported yet" msgstr "attributes hindi sinusuportahan" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "" - #: py/builtinevex.c msgid "bad compile mode" msgstr "masamang mode ng compile" @@ -1410,7 +1502,7 @@ msgstr "bits ay dapat 7, 8 o 9" msgid "bits must be 8" msgstr "bits ay dapat walo (8)" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "bits_per_sample ay dapat 8 o 16" @@ -1423,7 +1515,7 @@ msgstr "branch wala sa range" msgid "buf is too small. need %d bytes" msgstr "" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "buffer must be a bytes-like object" msgstr "buffer ay dapat bytes-like object" @@ -1641,10 +1733,6 @@ msgstr "hindi maaring isagawa ang relative import" msgid "casting" msgstr "casting" -#: shared-bindings/bleio/Service.c -msgid "characteristics includes an object that is not a Characteristic" -msgstr "" - #: shared-bindings/_stage/Text.c msgid "chars buffer too small" msgstr "masyadong maliit ang buffer" @@ -1797,7 +1885,8 @@ msgstr "dagdag na keyword argument na ibinigay" msgid "extra positional arguments given" msgstr "dagdag na positional argument na ibinigay" -#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c +#: 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" @@ -1927,7 +2016,7 @@ msgstr "int() arg 2 ay dapat >=2 at <= 36" msgid "integer required" msgstr "kailangan ng int" -#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c #, c-format msgid "interval must be in range %s-%s" msgstr "" @@ -2025,6 +2114,10 @@ msgstr "ang label ay na-define ulit" msgid "length argument not allowed for this type" msgstr "length argument ay walang pahintulot sa ganitong type" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs at rhs ay dapat magkasundo" @@ -2053,6 +2146,12 @@ msgstr "masyadong maliit ang buffer map" 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" @@ -2098,7 +2197,7 @@ msgstr "dapat gumamit ng keyword argument para sa key function" msgid "name '%q' is not defined" msgstr "name '%q' ay hindi defined" -#: shared-bindings/bleio/Peripheral.c +#: shared-bindings/_bleio/Peripheral.c #, fuzzy msgid "name must be a string" msgstr "ang keywords dapat strings" @@ -2144,16 +2243,17 @@ msgstr "no binding para sa nonlocal, nahanap" 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" -#: shared-bindings/bleio/Peripheral.c -msgid "non-Service found in services" -msgstr "" - -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c @@ -2172,7 +2272,7 @@ msgstr "non-keyword arg sa huli ng */**" msgid "non-keyword arg after keyword arg" msgstr "non-keyword arg sa huli ng keyword arg" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "not a 128-bit UUID" msgstr "" @@ -2239,6 +2339,14 @@ msgstr "odd-length string" 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" @@ -2349,7 +2457,7 @@ msgstr "return umasa ng '%q' pero ang nakuha ay ‘%q’" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" @@ -2467,10 +2575,6 @@ msgstr "may pagkakamali sa sintaks sa uctypes descriptor" msgid "threshold must be in the range 0-65536" msgstr "ang threshold ay dapat sa range 0-65536" -#: shared-bindings/displayio/TileGrid.c -msgid "tile index out of bounds" -msgstr "" - #: shared-bindings/time/__init__.c msgid "time.struct_time() takes a 9-sequence" msgstr "time.struct_time() kumukuha ng 9-sequence" @@ -2483,7 +2587,7 @@ msgstr "time.struct_time() kumukuha ng 1 argument" msgid "timeout >100 (units are now seconds, not msecs)" msgstr "timeout >100 (units ay seconds, hindi na msecs)" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c #, fuzzy msgid "timeout must be >= 0.0" msgstr "bits ay dapat walo (8)" @@ -2637,7 +2741,7 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Scanner.c msgid "window must be <= interval" msgstr "" @@ -2839,6 +2943,9 @@ msgstr "zero step" #~ msgstr "" #~ "Gamitin ang esptool upang burahin ang flash at muling i-upload ang Python" +#~ msgid "Voice index too high" +#~ msgstr "Index ng Voice ay masyadong mataas" + #~ msgid "[addrinfo error %d]" #~ msgstr "[addrinfo error %d]" diff --git a/locale/fr.po b/locale/fr.po index 3a4c418d48..c176fd8bcf 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-09 09:06-0400\n" +"POT-Creation-Date: 2019-09-08 17:30-0500\n" "PO-Revision-Date: 2019-04-14 20:05+0100\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -54,7 +54,7 @@ msgstr "index %q hors gamme" 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/_bleio/CharacteristicBuffer.c #: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c #, fuzzy msgid "%q must be >= 1" @@ -221,12 +221,12 @@ msgstr "pow() non supporté avec 3 arguments" 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 +#: 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 +#: shared-bindings/_bleio/Address.c msgid "Address type out of range" msgstr "" @@ -260,6 +260,7 @@ 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" @@ -307,6 +308,10 @@ 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" @@ -319,6 +324,10 @@ msgstr "La profondeur de bit doit être un multiple de 8." 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" @@ -332,6 +341,19 @@ msgstr "Luminosité non-ajustable" 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" @@ -342,7 +364,7 @@ msgstr "Le tampon doit être de longueur au moins 1" msgid "Bus pin %d is already in use" msgstr "La broche %d du bus est déjà utilisée" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c #, fuzzy msgid "Byte buffer must be 16 bytes." msgstr "Le tampon d'octets doit être de 16 octets." @@ -360,8 +382,8 @@ msgstr "" 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 for local Characteristic" +#: 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 @@ -419,15 +441,7 @@ msgstr "Impossible d'obtenir la taille du scalaire sans ambigüité" msgid "Cannot write without MOSI pin." msgstr "Impossible d'écrire sans broche MOSI." -#: shared-bindings/bleio/Service.c -msgid "Characteristic UUID doesn't match Service UUID" -msgstr "L'UUID de 'Characteristic' ne correspond pas à l'UUID du Service" - -#: ports/nrf/common-hal/bleio/Service.c -msgid "Characteristic already in use by another Service." -msgstr "'Characteristic' déjà en utilisation par un autre service" - -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "Ecriture sur 'CharacteristicBuffer' non fournie" @@ -447,6 +461,10 @@ msgstr "Horloge en cours d'utilisation" 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" @@ -460,7 +478,7 @@ msgstr "" msgid "Corrupt raw code" msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c +#: 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" @@ -469,11 +487,11 @@ msgstr "Impossible de décoder le 'ble_uuid', err 0x%04x" msgid "Could not initialize UART" msgstr "L'UART n'a pu être initialisé" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "Impossible d'allouer le 1er tampon" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "Impossible d'allouer le 2e tampon" @@ -491,11 +509,11 @@ msgstr "DAC déjà utilisé" msgid "Data 0 pin must be byte aligned" msgstr "La broche 'Data 0' doit être aligné sur l'octet" -#: shared-module/audioio/WaveFile.c +#: 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 +#: ports/nrf/common-hal/_bleio/Peripheral.c msgid "Data too large for advertisement packet" msgstr "Données trop volumineuses pour un paquet de diffusion" @@ -503,7 +521,16 @@ msgstr "Données trop volumineuses pour un paquet de diffusion" msgid "Destination capacity is smaller than destination_length." msgstr "La capacité de destination est plus petite que 'destination_length'." +#: ports/nrf/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +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 "La rotation d'affichage doit se faire par incréments de 90 degrés" @@ -527,18 +554,27 @@ msgstr "Erreur dans l'expression régulière" msgid "Expected a %q" msgstr "Attendu un %q" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c #, fuzzy msgid "Expected a Characteristic" msgstr "Une 'Characteristic' est attendue" -#: shared-bindings/bleio/Characteristic.c shared-bindings/bleio/Descriptor.c -#: shared-bindings/bleio/Service.c +#: 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 +#: shared-bindings/_bleio/Central.c msgid "Expected an Address" msgstr "" @@ -556,12 +592,17 @@ msgstr "" 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 +#: 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/Peripheral.c +#: 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" @@ -576,62 +617,67 @@ msgstr "Echec de l'allocation du tampon RX" 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 +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c msgid "Failed to connect: timeout" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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/Central.c +#: 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 +#: 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 +#: 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 +#: 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/Characteristic.c +#: 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/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/Characteristic.c +#: 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 +#: 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" @@ -641,42 +687,47 @@ msgstr "Echec de l'ajout de l'UUID du fournisseur, err 0x%04x" msgid "Failed to release mutex, err 0x%04x" msgstr "Impossible de libérer mutex, err 0x%04x" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c #, c-format msgid "Failed to start connecting, error 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Characteristic.c #, c-format msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: 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/Characteristic.c +#: 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" @@ -712,6 +763,11 @@ msgstr "La fréquence capturée est au delà des capacités. Capture en pause." 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" @@ -772,7 +828,7 @@ msgstr "Longueur de tampon invalide" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "Période de capture invalide. Gamme valide: 1 à 500" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "Invalid channel count" msgstr "Nombre de canaux invalide" @@ -781,11 +837,11 @@ msgstr "Nombre de canaux invalide" msgid "Invalid direction." msgstr "Direction invalide" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid file" msgstr "Fichier invalide" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" msgstr "Taille de bloc de formatage invalide" @@ -823,16 +879,28 @@ msgstr "Broches invalides" 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-bindings/audioio/Mixer.c +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "Invalid voice count" msgstr "Nombre de voix invalide" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid wave file" msgstr "Fichier WAVE invalide" @@ -896,7 +964,7 @@ msgstr "Le délais au démarrage du micro doit être entre 0.0 et 1.0" msgid "Must be a %q subclass." msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Characteristic.c msgid "No CCCD for this Characteristic" msgstr "" @@ -942,6 +1010,10 @@ msgstr "" 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" @@ -950,13 +1022,15 @@ msgstr "Il n'y a plus d'espace libre sur le périphérique" msgid "No such file/directory" msgstr "Fichier/dossier introuvable" -#: ports/nrf/common-hal/bleio/Characteristic.c -#: shared-bindings/bleio/CharacteristicBuffer.c +#: 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" @@ -987,10 +1061,9 @@ msgstr "" #: shared-module/displayio/OnDiskBitmap.c #, c-format msgid "" -"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " -"given" +"Only monochrome, indexed 4bpp or 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" #: shared-bindings/_pixelbuf/PixelBuf.c #, fuzzy @@ -1072,6 +1145,10 @@ msgstr "Système de fichier en lecture seule" 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é" @@ -1092,12 +1169,13 @@ msgstr "Mode sans-échec! Le code sauvegardé n'est pas éxecuté.\n" msgid "SDA or SCL needs a pull up" msgstr "SDA ou SCL a besoin d'une résistance de tirage ('pull up')" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/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" @@ -1116,7 +1194,7 @@ msgstr "Tranche et valeur de tailles différentes" msgid "Slices not supported" msgstr "Tranches non supportées" -#: ports/nrf/common-hal/bleio/Adapter.c +#: 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" @@ -1175,20 +1253,20 @@ 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/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.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/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.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/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.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/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "Le signe de l'échantillon ne correspond pas à celui du mixer" @@ -1196,9 +1274,13 @@ msgstr "Le signe de l'échantillon ne correspond pas à celui du mixer" 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 indices must be 0 - 255" -msgstr "Les indices des tuiles doivent être compris entre 0 et 255 " +msgid "Tile value out of bounds" +msgstr "" #: shared-bindings/displayio/TileGrid.c msgid "Tile width must exactly divide bitmap width" @@ -1212,11 +1294,13 @@ msgstr "Pour quitter, redémarrez la carte SVP sans " msgid "Too many channels in sample." msgstr "Trop de canaux dans l'échantillon." -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +#: 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" @@ -1236,16 +1320,16 @@ msgstr "USB occupé" msgid "USB Error" msgstr "Erreur USB" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID integer value must be 0-0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c +#: 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 +#: 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 " @@ -1256,6 +1340,11 @@ msgstr "" 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" @@ -1273,7 +1362,7 @@ msgstr "Impossible de lire les données de la palette de couleurs" msgid "Unable to write to nvm." msgstr "Impossible d'écrire sur la mémoire non-volatile." -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c #, fuzzy msgid "Unexpected nrfx uuid type" msgstr "Type inattendu pour l'uuid nrfx" @@ -1288,12 +1377,12 @@ msgstr "" msgid "Unsupported baudrate" msgstr "Débit non supporté" -#: shared-module/displayio/Display.c +#: shared-module/displayio/display_core.c #, fuzzy msgid "Unsupported display bus type" msgstr "Type de bus d'affichage non supporté" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Unsupported format" msgstr "Format non supporté" @@ -1305,15 +1394,21 @@ msgstr "Opération non supportée" 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/audioio/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" @@ -1403,10 +1498,6 @@ msgstr "tableau/octets requis à droite" msgid "attributes not supported yet" msgstr "attribut pas encore supporté" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "mauvais rôle GATT" - #: py/builtinevex.c msgid "bad compile mode" msgstr "mauvais mode de compilation" @@ -1435,7 +1526,7 @@ msgstr "bits doivent être 7, 8 ou 9" msgid "bits must be 8" msgstr "les bits doivent être 8" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "bits_per_sample must be 8 or 16" msgstr "'bits_per_sample' doivent être 8 ou 16" @@ -1450,7 +1541,7 @@ msgstr "branche hors-bornes" msgid "buf is too small. need %d bytes" msgstr "'buf' est trop petit. Besoin de %d octets" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "buffer must be a bytes-like object" msgstr "le tampon doit être un objet bytes-like" @@ -1672,10 +1763,6 @@ msgstr "ne peut pas réaliser un import relatif" msgid "casting" msgstr "typage" -#: shared-bindings/bleio/Service.c -msgid "characteristics includes an object that is not a Characteristic" -msgstr "'characteristics' inclut un objet qui n'est pas une 'Characteristic'" - #: shared-bindings/_stage/Text.c msgid "chars buffer too small" msgstr "tampon de caractères trop petit" @@ -1831,7 +1918,8 @@ msgstr "argument(s) nommé(s) supplémentaire(s) donné(s)" msgid "extra positional arguments given" msgstr "argument(s) positionnel(s) supplémentaire(s) donné(s)" -#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c +#: 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'" @@ -1960,7 +2048,7 @@ msgstr "l'argument 2 de int() doit être >=2 et <=36" msgid "integer required" msgstr "entier requis" -#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c #, c-format msgid "interval must be in range %s-%s" msgstr "" @@ -2058,6 +2146,10 @@ msgstr "label redéfini" msgid "length argument not allowed for this type" msgstr "argument 'length' non-permis pour ce type" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "Les parties gauches et droites doivent être compatibles" @@ -2086,6 +2178,12 @@ msgstr "tampon trop petit" 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" @@ -2131,7 +2229,7 @@ msgstr "doit utiliser un argument nommé pour une fonction key" msgid "name '%q' is not defined" msgstr "nom '%q' non défini" -#: shared-bindings/bleio/Peripheral.c +#: shared-bindings/_bleio/Peripheral.c #, fuzzy msgid "name must be a string" msgstr "les noms doivent être des chaînes de caractère" @@ -2178,16 +2276,17 @@ msgstr "pas de lien trouvé pour nonlocal" 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" -#: shared-bindings/bleio/Peripheral.c -msgid "non-Service found in services" -msgstr "" - -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c @@ -2207,7 +2306,7 @@ msgstr "argument non-nommé après */**" msgid "non-keyword arg after keyword arg" msgstr "argument non-nommé après argument nommé" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "not a 128-bit UUID" msgstr "n'est pas un UUID 128 bits" @@ -2275,6 +2374,14 @@ msgstr "chaîne de longueur impaire" 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" @@ -2390,7 +2497,7 @@ msgstr "return attendait '%q' mais a reçu '%q'" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" @@ -2509,10 +2616,6 @@ msgstr "erreur de syntaxe dans le descripteur d'uctypes" msgid "threshold must be in the range 0-65536" msgstr "le seuil doit être dans la gamme 0-65536" -#: shared-bindings/displayio/TileGrid.c -msgid "tile index out of bounds" -msgstr "indice de tuile hors limites" - #: shared-bindings/time/__init__.c msgid "time.struct_time() takes a 9-sequence" msgstr "time.struct_time() prend une séquence de longueur 9" @@ -2525,7 +2628,7 @@ msgstr "time.struct_time() prend exactement 1 argument" msgid "timeout >100 (units are now seconds, not msecs)" msgstr "timeout >100 (exprimé en secondes, pas en ms)" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c #, fuzzy msgid "timeout must be >= 0.0" msgstr "'timeout' doit être >=0.0" @@ -2680,7 +2783,7 @@ msgstr "" msgid "value_count must be > 0" msgstr "'value_count' doit être > 0" -#: shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Scanner.c msgid "window must be <= interval" msgstr "" @@ -2745,6 +2848,12 @@ msgstr "'step' nul" #~ 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" @@ -2844,6 +2953,13 @@ msgstr "'step' nul" #~ 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" @@ -2868,6 +2984,9 @@ msgstr "'step' nul" #~ 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" @@ -2887,6 +3006,12 @@ msgstr "'step' nul" #~ msgstr "" #~ "Utilisez 'esptool' pour effacer la flash et recharger Python à la place" +#~ msgid "Voice index too high" +#~ msgstr "Index de la voix trop grand" + +#~ msgid "bad GATT role" +#~ msgstr "mauvais rôle GATT" + #~ msgid "buffer too long" #~ msgstr "tampon trop long" @@ -2905,6 +3030,10 @@ msgstr "'step' nul" #~ 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" @@ -2964,6 +3093,9 @@ msgstr "'step' nul" #~ 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" diff --git a/locale/it_IT.po b/locale/it_IT.po index 7504fb1575..883c65d41f 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-09 09:06-0400\n" +"POT-Creation-Date: 2019-09-08 17:30-0500\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -52,7 +52,7 @@ msgstr "indice %q fuori intervallo" msgid "%q indices must be integers, not %s" msgstr "gli indici %q devono essere interi, non %s" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c #, fuzzy msgid "%q must be >= 1" @@ -112,7 +112,7 @@ msgid "'%s' expects {r0, r1, ...}" msgstr "'%s' aspetta un registro" #: py/emitinlinextensa.c -#, c-format +#, fuzzy, c-format msgid "'%s' integer %d is not within range %d..%d" msgstr "intero '%s' non è nell'intervallo %d..%d" @@ -219,12 +219,12 @@ msgstr "pow() con tre argmomenti non supportata" msgid "A hardware interrupt channel is already in use" msgstr "Un canale di interrupt hardware è già in uso" -#: shared-bindings/bleio/Address.c +#: 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 +#: shared-bindings/_bleio/Address.c msgid "Address type out of range" msgstr "" @@ -256,6 +256,7 @@ 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" @@ -301,6 +302,10 @@ 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 "" @@ -314,6 +319,10 @@ msgstr "La profondità di bit deve essere multipla di 8." 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" @@ -327,6 +336,19 @@ msgstr "Illiminazione non è regolabile" 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" @@ -337,7 +359,7 @@ msgstr "Il buffer deve essere lungo almeno 1" msgid "Bus pin %d is already in use" msgstr "DAC già in uso" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c #, fuzzy msgid "Byte buffer must be 16 bytes." msgstr "i buffer devono essere della stessa lunghezza" @@ -355,8 +377,8 @@ msgstr "" 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 for local Characteristic" +#: 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 @@ -414,15 +436,7 @@ msgstr "Impossibile ricavare la grandezza scalare di sizeof inequivocabilmente" msgid "Cannot write without MOSI pin." msgstr "Impossibile scrivere senza pin MOSI." -#: shared-bindings/bleio/Service.c -msgid "Characteristic UUID doesn't match Service UUID" -msgstr "caratteristico UUID non assomiglia servizio UUID" - -#: ports/nrf/common-hal/bleio/Service.c -msgid "Characteristic already in use by another Service." -msgstr "caratteristico già usato da un altro servizio" - -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "CharacteristicBuffer scritura non dato" @@ -442,6 +456,10 @@ msgstr "Unità di clock in uso" 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" @@ -455,7 +473,7 @@ msgstr "" msgid "Corrupt raw code" msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c #, c-format msgid "Could not decode ble_uuid, err 0x%04x" msgstr "" @@ -464,11 +482,11 @@ msgstr "" msgid "Could not initialize UART" msgstr "Impossibile inizializzare l'UART" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "Impossibile allocare il primo buffer" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "Impossibile allocare il secondo buffer" @@ -486,11 +504,11 @@ msgstr "DAC già in uso" msgid "Data 0 pin must be byte aligned" msgstr "graphic deve essere lunga 2048 byte" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Data chunk must follow fmt chunk" msgstr "" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: ports/nrf/common-hal/_bleio/Peripheral.c #, fuzzy msgid "Data too large for advertisement packet" msgstr "Impossibile inserire dati nel pacchetto di advertisement." @@ -499,7 +517,16 @@ msgstr "Impossibile inserire dati nel pacchetto di advertisement." msgid "Destination capacity is smaller than destination_length." msgstr "La capacità di destinazione è più piccola di destination_length." +#: ports/nrf/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +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 "" @@ -523,18 +550,27 @@ msgstr "Errore nella regex" msgid "Expected a %q" msgstr "Atteso un %q" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c #, fuzzy msgid "Expected a Characteristic" msgstr "Non è possibile aggiungere Characteristic." -#: shared-bindings/bleio/Characteristic.c shared-bindings/bleio/Descriptor.c -#: shared-bindings/bleio/Service.c +#: 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 +#: shared-bindings/_bleio/Central.c msgid "Expected an Address" msgstr "" @@ -552,12 +588,17 @@ msgstr "" msgid "Failed to acquire mutex, err 0x%04x" msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Service.c +#: 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/Peripheral.c +#: 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" @@ -572,60 +613,65 @@ msgstr "Impossibile allocare buffer RX" 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 +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c msgid "Failed to connect: timeout" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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/Central.c +#: 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 +#: ports/nrf/common-hal/_bleio/Adapter.c msgid "Failed to get local address" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c +#: 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 +#: 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/Characteristic.c +#: 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/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/Characteristic.c +#: 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 +#: 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" @@ -635,42 +681,47 @@ msgstr "Non è possibile aggiungere l'UUID del vendor specifico da 128-bit" msgid "Failed to release mutex, err 0x%04x" msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c #, c-format msgid "Failed to start connecting, error 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Characteristic.c #, c-format msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: 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/Characteristic.c +#: 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" @@ -706,6 +757,11 @@ msgstr "" 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" @@ -765,7 +821,7 @@ msgstr "lunghezza del buffer non valida" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "periodo di cattura invalido. Zona valida: 1 - 500" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "Invalid channel count" msgstr "Argomento non valido" @@ -774,11 +830,11 @@ msgstr "Argomento non valido" msgid "Invalid direction." msgstr "Direzione non valida." -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid file" msgstr "File non valido" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" msgstr "" @@ -816,16 +872,28 @@ msgstr "Pin non validi" 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-bindings/audioio/Mixer.c +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "Invalid voice count" msgstr "Tipo di servizio non valido" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid wave file" msgstr "File wave non valido" @@ -886,7 +954,7 @@ msgstr "" msgid "Must be a %q subclass." msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Characteristic.c msgid "No CCCD for this Characteristic" msgstr "" @@ -932,6 +1000,10 @@ msgstr "" 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" @@ -940,13 +1012,15 @@ msgstr "Non che spazio sul dispositivo" msgid "No such file/directory" msgstr "Nessun file/directory esistente" -#: ports/nrf/common-hal/bleio/Characteristic.c -#: shared-bindings/bleio/CharacteristicBuffer.c +#: 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" @@ -975,8 +1049,8 @@ msgstr "" #: shared-module/displayio/OnDiskBitmap.c #, c-format msgid "" -"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " -"given" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" msgstr "" #: shared-bindings/_pixelbuf/PixelBuf.c @@ -1060,6 +1134,10 @@ msgstr "Filesystem in sola lettura" 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" @@ -1080,12 +1158,13 @@ msgstr "Modalità sicura in esecuzione! Codice salvato non in esecuzione.\n" msgid "SDA or SCL needs a pull up" msgstr "SDA o SCL necessitano un pull-up" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/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 "" @@ -1105,7 +1184,7 @@ msgstr "" msgid "Slices not supported" msgstr "Slice non supportate" -#: ports/nrf/common-hal/bleio/Adapter.c +#: ports/nrf/common-hal/_bleio/Adapter.c #, c-format msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" @@ -1154,19 +1233,19 @@ msgid "" "exit safe mode.\n" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "" @@ -1174,8 +1253,12 @@ msgstr "" 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 indices must be 0 - 255" +msgid "Tile value out of bounds" msgstr "" #: shared-bindings/displayio/TileGrid.c @@ -1190,11 +1273,13 @@ msgstr "Per uscire resettare la scheda senza " msgid "Too many channels in sample." msgstr "" -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +#: 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" @@ -1214,15 +1299,15 @@ msgstr "USB occupata" msgid "USB Error" msgstr "Errore USB" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID integer value must be 0-0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID value is not str, int or byte buffer" msgstr "" @@ -1231,6 +1316,11 @@ msgstr "" 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" @@ -1248,7 +1338,7 @@ msgstr "" msgid "Unable to write to nvm." msgstr "Imposibile scrivere su nvm." -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c #, fuzzy msgid "Unexpected nrfx uuid type" msgstr "indentazione inaspettata" @@ -1262,12 +1352,12 @@ msgstr "" msgid "Unsupported baudrate" msgstr "baudrate non supportato" -#: shared-module/displayio/Display.c +#: shared-module/displayio/display_core.c #, fuzzy msgid "Unsupported display bus type" msgstr "tipo di bitmap non supportato" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Unsupported format" msgstr "Formato non supportato" @@ -1279,14 +1369,20 @@ msgstr "Operazione non supportata" 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/audioio/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" @@ -1372,10 +1468,6 @@ msgstr "" msgid "attributes not supported yet" msgstr "attributi non ancora supportati" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "" - #: py/builtinevex.c msgid "bad compile mode" msgstr "" @@ -1404,7 +1496,7 @@ msgstr "i bit devono essere 7, 8 o 9" msgid "bits must be 8" msgstr "i bit devono essere 8" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "bits_per_sample must be 8 or 16" msgstr "i bit devono essere 7, 8 o 9" @@ -1419,7 +1511,7 @@ msgstr "argomento di chr() non è in range(256)" msgid "buf is too small. need %d bytes" msgstr "" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "buffer must be a bytes-like object" msgstr "" @@ -1496,7 +1588,7 @@ msgid "can't assign to expression" msgstr "impossibile assegnare all'espressione" #: py/obj.c -#, c-format +#, fuzzy, c-format msgid "can't convert %s to complex" msgstr "non è possibile convertire a complex" @@ -1632,10 +1724,6 @@ msgstr "impossibile effettuare l'importazione relativa" msgid "casting" msgstr "casting" -#: shared-bindings/bleio/Service.c -msgid "characteristics includes an object that is not a Characteristic" -msgstr "" - #: shared-bindings/_stage/Text.c msgid "chars buffer too small" msgstr "buffer dei caratteri troppo piccolo" @@ -1789,7 +1877,8 @@ msgstr "argomento nominato aggiuntivo fornito" msgid "extra positional arguments given" msgstr "argomenti posizonali extra dati" -#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c msgid "file must be a file opened in byte mode" msgstr "" @@ -1919,7 +2008,7 @@ msgstr "il secondo argomanto di int() deve essere >= 2 e <= 36" msgid "integer required" msgstr "intero richiesto" -#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c #, c-format msgid "interval must be in range %s-%s" msgstr "" @@ -2018,6 +2107,10 @@ msgstr "etichetta ridefinita" msgid "length argument not allowed for this type" msgstr "" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs e rhs devono essere compatibili" @@ -2046,6 +2139,12 @@ msgstr "map buffer troppo piccolo" 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" @@ -2091,7 +2190,7 @@ msgstr "" msgid "name '%q' is not defined" msgstr "nome '%q'non definito" -#: shared-bindings/bleio/Peripheral.c +#: shared-bindings/_bleio/Peripheral.c #, fuzzy msgid "name must be a string" msgstr "argomenti nominati devono essere stringhe" @@ -2138,16 +2237,17 @@ msgstr "nessun binding per nonlocal trovato" 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" -#: shared-bindings/bleio/Peripheral.c -msgid "non-Service found in services" -msgstr "" - -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c @@ -2166,7 +2266,7 @@ msgstr "argomento non nominato dopo */**" msgid "non-keyword arg after keyword arg" msgstr "argomento non nominato seguito da argomento nominato" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "not a 128-bit UUID" msgstr "" @@ -2235,6 +2335,14 @@ msgstr "stringa di lunghezza dispari" 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" @@ -2347,7 +2455,7 @@ msgstr "return aspettava '%q' ma ha ottenuto '%q'" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" @@ -2465,10 +2573,6 @@ msgstr "errore di sintassi nel descrittore uctypes" msgid "threshold must be in the range 0-65536" msgstr "la soglia deve essere nell'intervallo 0-65536" -#: shared-bindings/displayio/TileGrid.c -msgid "tile index out of bounds" -msgstr "" - #: shared-bindings/time/__init__.c msgid "time.struct_time() takes a 9-sequence" msgstr "" @@ -2481,7 +2585,7 @@ msgstr "time.struct_time() prende esattamente un argomento" msgid "timeout >100 (units are now seconds, not msecs)" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c #, fuzzy msgid "timeout must be >= 0.0" msgstr "i bit devono essere 8" @@ -2560,7 +2664,7 @@ msgid "unindent does not match any outer indentation level" msgstr "" #: py/objstr.c -#, c-format +#, fuzzy, c-format msgid "unknown conversion specifier %c" msgstr "specificatore di conversione %s sconosciuto" @@ -2635,7 +2739,7 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Scanner.c msgid "window must be <= interval" msgstr "" @@ -2699,6 +2803,12 @@ msgstr "zero step" #~ 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." diff --git a/locale/pl.po b/locale/pl.po index dd4cf7db4a..9ed76924b5 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-09 09:06-0400\n" +"POT-Creation-Date: 2019-09-08 17:30-0500\n" "PO-Revision-Date: 2019-03-19 18:37-0700\n" "Last-Translator: Radomir Dopieralski \n" "Language-Team: pl\n" @@ -53,7 +53,7 @@ msgstr "%q poza zakresem" 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/_bleio/CharacteristicBuffer.c #: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c msgid "%q must be >= 1" msgstr "%q musi być >= 1" @@ -218,12 +218,12 @@ msgstr "3-argumentowy pow() jest niewspierany" msgid "A hardware interrupt channel is already in use" msgstr "Kanał przerwań sprzętowych w użyciu" -#: shared-bindings/bleio/Address.c +#: 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 +#: shared-bindings/_bleio/Address.c msgid "Address type out of range" msgstr "" @@ -254,6 +254,7 @@ 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" @@ -299,6 +300,10 @@ 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" @@ -311,6 +316,10 @@ msgstr "Głębia musi być wielokrotnością 8." 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" @@ -324,6 +333,19 @@ msgstr "Jasność nie jest regulowana" 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" @@ -334,7 +356,7 @@ msgstr "Bufor musi mieć długość 1 lub więcej" msgid "Bus pin %d is already in use" msgstr "Nóżka magistrali %d jest w użyciu" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "Bufor musi mieć 16 bajtów." @@ -351,8 +373,8 @@ msgstr "" 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 for local Characteristic" +#: 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 @@ -408,15 +430,7 @@ msgstr "Wielkość skalara jest niejednoznaczna" msgid "Cannot write without MOSI pin." msgstr "Nie można pisać bez nóżki MOSI." -#: shared-bindings/bleio/Service.c -msgid "Characteristic UUID doesn't match Service UUID" -msgstr "UUID charakterystyki inny niż UUID serwisu" - -#: ports/nrf/common-hal/bleio/Service.c -msgid "Characteristic already in use by another Service." -msgstr "Charakterystyka w użyciu w innym serwisie" - -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "Pisanie do CharacteristicBuffer niewspierane" @@ -436,6 +450,10 @@ msgstr "Jednostka zegara w użyciu" 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" @@ -448,7 +466,7 @@ msgstr "" msgid "Corrupt raw code" msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c +#: 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" @@ -457,11 +475,11 @@ msgstr "Nie można zdekodować ble_uuid, błąd 0x%04x" msgid "Could not initialize UART" msgstr "Ustawienie UART nie powiodło się" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "Nie udała się alokacja pierwszego bufora" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "Nie udała się alokacja drugiego bufora" @@ -478,11 +496,11 @@ msgstr "DAC w użyciu" msgid "Data 0 pin must be byte aligned" msgstr "Nóżka data 0 musi być wyrównana do bajtu" -#: shared-module/audioio/WaveFile.c +#: 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 +#: ports/nrf/common-hal/_bleio/Peripheral.c msgid "Data too large for advertisement packet" msgstr "Zbyt dużo danych pakietu rozgłoszeniowego" @@ -490,7 +508,16 @@ msgstr "Zbyt dużo danych pakietu rozgłoszeniowego" msgid "Destination capacity is smaller than destination_length." msgstr "Pojemność celu mniejsza od destination_length." +#: ports/nrf/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +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 "Wyświetlacz można obracać co 90 stopni" @@ -514,16 +541,25 @@ msgstr "Błąd w regex" msgid "Expected a %q" msgstr "Oczekiwano %q" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c msgid "Expected a Characteristic" msgstr "Oczekiwano charakterystyki" -#: shared-bindings/bleio/Characteristic.c shared-bindings/bleio/Descriptor.c -#: shared-bindings/bleio/Service.c +#: 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 +#: shared-bindings/_bleio/Central.c msgid "Expected an Address" msgstr "" @@ -537,16 +573,21 @@ msgid "Failed sending command." msgstr "" #: ports/nrf/sd_mutex.c -#, c-format +#, 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 -#, c-format +#: 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/Peripheral.c +#: 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" @@ -561,57 +602,62 @@ msgstr "Nie udała się alokacja bufora RX" 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 +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c msgid "Failed to connect: timeout" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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/Central.c +#: 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 +#: 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 +#: 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 +#: 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/Characteristic.c +#: 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/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/Characteristic.c +#: 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 +#: 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" @@ -621,42 +667,47 @@ msgstr "Nie udało się zarejestrować UUID dostawcy, błąd 0x%04x" 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 +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c #, c-format msgid "Failed to start connecting, error 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Characteristic.c #, c-format msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: 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/Characteristic.c +#: 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" @@ -692,6 +743,11 @@ msgstr "Uzyskana częstotliwość jest niemożliwa. Spauzowano." 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" @@ -750,7 +806,7 @@ msgstr "Zła wielkość bufora" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "Zły okres. Poprawny zakres to: 1 - 500" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "Zła liczba kanałów" @@ -758,11 +814,11 @@ msgstr "Zła liczba kanałów" msgid "Invalid direction." msgstr "Zły tryb" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid file" msgstr "Zły plik" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" msgstr "Zła wielkość fragmentu formatu" @@ -800,15 +856,27 @@ msgstr "Złe nóżki" 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-bindings/audioio/Mixer.c +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "Zła liczba głosów" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid wave file" msgstr "Zły plik wave" @@ -873,7 +941,7 @@ msgstr "Opóźnienie włączenia mikrofonu musi być w zakresie od 0.0 do 1.0" msgid "Must be a %q subclass." msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Characteristic.c msgid "No CCCD for this Characteristic" msgstr "" @@ -919,6 +987,10 @@ msgstr "" 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" @@ -927,12 +999,14 @@ msgstr "Brak miejsca" msgid "No such file/directory" msgstr "Brak pliku/katalogu" -#: ports/nrf/common-hal/bleio/Characteristic.c -#: shared-bindings/bleio/CharacteristicBuffer.c +#: 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" @@ -958,9 +1032,9 @@ msgstr "Wspierane są tylko nieskompresowane pliki BMP: wielkość nagłówka %d #: shared-module/displayio/OnDiskBitmap.c #, c-format 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 " +"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" @@ -1033,6 +1107,10 @@ msgstr "System plików tylko do odczytu" 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" @@ -1053,11 +1131,12 @@ msgstr "Uruchomiony tryb bezpieczeństwa! Zapisany kod nie jest uruchamiany.\n" msgid "SDA or SCL needs a pull up" msgstr "SDA lub SCL wymagają podciągnięcia" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/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" @@ -1076,7 +1155,7 @@ msgstr "Fragment i wartość są różnych długości." msgid "Slices not supported" msgstr "Fragmenty nieobsługiwane" -#: ports/nrf/common-hal/bleio/Adapter.c +#: 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" @@ -1132,19 +1211,19 @@ msgstr "" "Przycisk reset został wciśnięty podczas startu CircuitPythona. Wciśnij go " "ponownie aby wyjść z trybu bezpieczeństwa.\n" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.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/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "Liczba kanałów nie pasuje do miksera " -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "Sample rate nie pasuje do miksera" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "Znak nie pasuje do miksera" @@ -1152,9 +1231,13 @@ msgstr "Znak nie pasuje do miksera" 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 indices must be 0 - 255" -msgstr "Indeks kafelka musi być pomiędzy 0 a 255 włącznie" +msgid "Tile value out of bounds" +msgstr "" #: shared-bindings/displayio/TileGrid.c msgid "Tile width must exactly divide bitmap width" @@ -1168,11 +1251,13 @@ msgstr "By wyjść, proszę zresetować płytkę bez " msgid "Too many channels in sample." msgstr "Zbyt wiele kanałów." -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +#: 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" @@ -1192,15 +1277,15 @@ msgstr "USB Zajęte" msgid "USB Error" msgstr "Błąd USB" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID integer value must be 0-0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c +#: 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 +#: shared-bindings/_bleio/UUID.c msgid "UUID value is not str, int or byte buffer" msgstr "UUID nie jest typu str, int lub bytes" @@ -1209,6 +1294,11 @@ msgstr "UUID nie jest typu str, int lub bytes" 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" @@ -1226,7 +1316,7 @@ msgstr "Nie można odczytać danych palety" msgid "Unable to write to nvm." msgstr "Błąd zapisu do NVM." -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c msgid "Unexpected nrfx uuid type" msgstr "Nieoczekiwany typ nrfx uuid." @@ -1239,11 +1329,11 @@ msgstr "Zła liczba obiektów po prawej stronie (oczekiwano %d, jest %d)." msgid "Unsupported baudrate" msgstr "Zła szybkość transmisji" -#: shared-module/displayio/Display.c +#: shared-module/displayio/display_core.c msgid "Unsupported display bus type" msgstr "Zły typ magistrali wyświetlaczy" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Unsupported format" msgstr "Zły format" @@ -1255,14 +1345,20 @@ msgstr "Zła operacja" 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/audioio/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" @@ -1349,10 +1445,6 @@ msgstr "tablica/bytes wymagane po prawej stronie" msgid "attributes not supported yet" msgstr "atrybuty nie są jeszcze obsługiwane" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "zła rola GATT" - #: py/builtinevex.c msgid "bad compile mode" msgstr "zły tryb kompilacji" @@ -1381,7 +1473,7 @@ msgstr "bits musi być 7, 8 lub 9" msgid "bits must be 8" msgstr "bits musi być 8" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "bits_per_sample musi być 8 lub 16" @@ -1394,7 +1486,7 @@ msgstr "skok poza zakres" msgid "buf is too small. need %d bytes" msgstr "buf zbyt mały. Wymagane %d bajtów" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "buffer must be a bytes-like object" msgstr "bufor mysi być typu bytes" @@ -1605,10 +1697,6 @@ msgstr "nie można wykonać relatywnego importu" msgid "casting" msgstr "rzutowanie" -#: shared-bindings/bleio/Service.c -msgid "characteristics includes an object that is not a Characteristic" -msgstr "charakterystyki zawierają obiekt, który nie jest typu Characteristic" - #: shared-bindings/_stage/Text.c msgid "chars buffer too small" msgstr "bufor chars zbyt mały" @@ -1757,7 +1845,8 @@ msgstr "nadmiarowe argumenty nazwane" msgid "extra positional arguments given" msgstr "nadmiarowe argumenty pozycyjne" -#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c +#: 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" @@ -1886,7 +1975,7 @@ msgstr "argument 2 do int() busi być pomiędzy 2 a 36" msgid "integer required" msgstr "wymagana liczba całkowita" -#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c #, c-format msgid "interval must be in range %s-%s" msgstr "" @@ -1980,6 +2069,10 @@ msgstr "etykieta przedefiniowana" msgid "length argument not allowed for this type" msgstr "ten typ nie pozawala na podanie długości" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lewa i prawa strona powinny być kompatybilne" @@ -2008,6 +2101,12 @@ msgstr "bufor mapy zbyt mały" 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" @@ -2053,7 +2152,7 @@ msgstr "funkcja key musi być podana jako argument nazwany" msgid "name '%q' is not defined" msgstr "nazwa '%q' niezdefiniowana" -#: shared-bindings/bleio/Peripheral.c +#: shared-bindings/_bleio/Peripheral.c msgid "name must be a string" msgstr "nazwa musi być łańcuchem" @@ -2098,16 +2197,17 @@ msgstr "brak wiązania dla zmiennej nielokalnej" 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" -#: shared-bindings/bleio/Peripheral.c -msgid "non-Service found in services" -msgstr "" - -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c @@ -2126,7 +2226,7 @@ msgstr "argument nienazwany po */**" msgid "non-keyword arg after keyword arg" msgstr "argument nienazwany po nazwanym" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "not a 128-bit UUID" msgstr "to nie jest 128-bitowy UUID" @@ -2192,6 +2292,14 @@ msgstr "łańcuch o nieparzystej długości" 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" @@ -2301,7 +2409,7 @@ msgstr "return oczekiwał '%q', a jest '%q'" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" @@ -2417,10 +2525,6 @@ msgstr "błąd składni w deskryptorze uctypes" msgid "threshold must be in the range 0-65536" msgstr "threshold musi być w zakresie 0-65536" -#: shared-bindings/displayio/TileGrid.c -msgid "tile index out of bounds" -msgstr "indeks kafelka poza zakresem" - #: shared-bindings/time/__init__.c msgid "time.struct_time() takes a 9-sequence" msgstr "time.struct_time() wymaga 9-elementowej sekwencji" @@ -2433,7 +2537,7 @@ msgstr "time.struct_time() wymaga jednego argumentu" msgid "timeout >100 (units are now seconds, not msecs)" msgstr "timeout > 100 (jednostkami są sekundy)" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "timeout must be >= 0.0" msgstr "timeout musi być >= 0.0" @@ -2586,7 +2690,7 @@ msgstr "" msgid "value_count must be > 0" msgstr "value_count musi być > 0" -#: shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Scanner.c msgid "window must be <= interval" msgstr "" @@ -2633,6 +2737,12 @@ msgstr "zerowy krok" #~ 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" @@ -2675,11 +2785,32 @@ msgstr "zerowy krok" #~ 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 "Voice index too high" +#~ msgstr "Zbyt wysoki indeks głosu" + +#~ 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 index 8b74349faa..a17a275390 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-09 09:06-0400\n" +"POT-Creation-Date: 2019-09-08 17:30-0500\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -52,7 +52,7 @@ msgstr "" msgid "%q indices must be integers, not %s" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c #, fuzzy msgid "%q must be >= 1" @@ -219,12 +219,12 @@ msgstr "" 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 +#: 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 +#: shared-bindings/_bleio/Address.c msgid "Address type out of range" msgstr "" @@ -256,6 +256,7 @@ 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" @@ -299,6 +300,10 @@ msgid "" "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 "" @@ -311,6 +316,10 @@ msgstr "" 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" @@ -324,6 +333,19 @@ msgstr "" 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 "" @@ -334,7 +356,7 @@ msgstr "" msgid "Bus pin %d is already in use" msgstr "DAC em uso" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c #, fuzzy msgid "Byte buffer must be 16 bytes." msgstr "buffers devem ser o mesmo tamanho" @@ -352,8 +374,8 @@ msgstr "" msgid "Can not use dotstar with %s" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "Can't set CCCD for local Characteristic" +#: 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 @@ -410,15 +432,7 @@ msgstr "" msgid "Cannot write without MOSI pin." msgstr "Não é possível ler sem um pino MOSI" -#: shared-bindings/bleio/Service.c -msgid "Characteristic UUID doesn't match Service UUID" -msgstr "" - -#: ports/nrf/common-hal/bleio/Service.c -msgid "Characteristic already in use by another Service." -msgstr "" - -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "" @@ -438,6 +452,10 @@ msgstr "Unidade de Clock em uso" 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" @@ -451,7 +469,7 @@ msgstr "" msgid "Corrupt raw code" msgstr "" -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c #, c-format msgid "Could not decode ble_uuid, err 0x%04x" msgstr "" @@ -460,11 +478,11 @@ msgstr "" msgid "Could not initialize UART" msgstr "Não foi possível inicializar o UART" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "Não pôde alocar primeiro buffer" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "Não pôde alocar segundo buffer" @@ -481,11 +499,11 @@ msgstr "DAC em uso" msgid "Data 0 pin must be byte aligned" msgstr "" -#: shared-module/audioio/WaveFile.c +#: 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 +#: 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." @@ -494,7 +512,16 @@ msgstr "Não é possível ajustar dados no pacote de anúncios." msgid "Destination capacity is smaller than destination_length." msgstr "" +#: ports/nrf/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +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 "" @@ -518,18 +545,27 @@ msgstr "Erro no regex" msgid "Expected a %q" msgstr "Esperado um" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: 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/Characteristic.c shared-bindings/bleio/Descriptor.c -#: shared-bindings/bleio/Service.c +#: 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 +#: shared-bindings/_bleio/Central.c msgid "Expected an Address" msgstr "" @@ -547,12 +583,17 @@ msgstr "Falha ao enviar comando." 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 +#: 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/Peripheral.c +#: 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" @@ -567,60 +608,65 @@ msgstr "Falha ao alocar buffer RX" 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 +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c msgid "Failed to connect: timeout" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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/Central.c +#: 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 +#: ports/nrf/common-hal/_bleio/Adapter.c msgid "Failed to get local address" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c +#: 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 +#: 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/Characteristic.c +#: 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/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/Characteristic.c +#: 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 +#: 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." @@ -630,42 +676,47 @@ msgstr "Não é possível adicionar o UUID de 128 bits específico do fornecedor 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 +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c #, c-format msgid "Failed to start connecting, error 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Characteristic.c #, c-format msgid "Failed to write CCCD, err 0x%04x" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: 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/Characteristic.c +#: 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" @@ -701,6 +752,11 @@ msgstr "" 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" @@ -758,7 +814,7 @@ msgstr "Arquivo inválido" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "Invalid channel count" msgstr "certificado inválido" @@ -767,11 +823,11 @@ msgstr "certificado inválido" msgid "Invalid direction." msgstr "Direção inválida" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid file" msgstr "Arquivo inválido" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" msgstr "Tamanho do pedaço de formato inválido" @@ -809,16 +865,28 @@ msgstr "Pinos inválidos" msgid "Invalid polarity" msgstr "" +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "" -#: shared-bindings/audioio/Mixer.c +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "Invalid voice count" msgstr "certificado inválido" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid wave file" msgstr "Aqruivo de ondas inválido" @@ -878,7 +946,7 @@ msgstr "" msgid "Must be a %q subclass." msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Characteristic.c msgid "No CCCD for this Characteristic" msgstr "" @@ -924,6 +992,10 @@ msgstr "Sem suporte de hardware no pino de clock" 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 "" @@ -932,13 +1004,15 @@ msgstr "" msgid "No such file/directory" msgstr "" -#: ports/nrf/common-hal/bleio/Characteristic.c -#: shared-bindings/bleio/CharacteristicBuffer.c +#: 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 "" @@ -966,8 +1040,8 @@ msgstr "" #: shared-module/displayio/OnDiskBitmap.c #, c-format msgid "" -"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " -"given" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" msgstr "" #: shared-bindings/_pixelbuf/PixelBuf.c @@ -1043,6 +1117,10 @@ msgstr "Sistema de arquivos somente leitura" 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" @@ -1063,11 +1141,12 @@ msgstr "Rodando em modo seguro! Não está executando o código salvo.\n" msgid "SDA or SCL needs a pull up" msgstr "SDA ou SCL precisa de um pull up" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/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" @@ -1086,7 +1165,7 @@ msgstr "" msgid "Slices not supported" msgstr "" -#: ports/nrf/common-hal/bleio/Adapter.c +#: ports/nrf/common-hal/_bleio/Adapter.c #, c-format msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" @@ -1132,19 +1211,19 @@ msgid "" "exit safe mode.\n" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "" -#: shared-module/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "" @@ -1152,8 +1231,12 @@ msgstr "" 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 indices must be 0 - 255" +msgid "Tile value out of bounds" msgstr "" #: shared-bindings/displayio/TileGrid.c @@ -1168,11 +1251,13 @@ msgstr "Para sair, por favor, reinicie a placa sem " msgid "Too many channels in sample." msgstr "Muitos canais na amostra." -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +#: 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 "" @@ -1192,15 +1277,15 @@ msgstr "USB ocupada" msgid "USB Error" msgstr "Erro na USB" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID integer value must be 0-0xffff" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID value is not str, int or byte buffer" msgstr "" @@ -1209,6 +1294,11 @@ msgstr "" 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" @@ -1226,7 +1316,7 @@ msgstr "" msgid "Unable to write to nvm." msgstr "Não é possível gravar no nvm." -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c msgid "Unexpected nrfx uuid type" msgstr "" @@ -1239,12 +1329,12 @@ msgstr "" msgid "Unsupported baudrate" msgstr "Taxa de transmissão não suportada" -#: shared-module/displayio/Display.c +#: shared-module/displayio/display_core.c #, fuzzy msgid "Unsupported display bus type" msgstr "Taxa de transmissão não suportada" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Unsupported format" msgstr "Formato não suportado" @@ -1256,12 +1346,18 @@ msgstr "" msgid "Unsupported pull value." msgstr "" -#: py/emitnative.c -msgid "Viper functions don't currently support more than 4 arguments" +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" msgstr "" -#: shared-module/audioio/Mixer.c -msgid "Voice index too high" +#: 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 "" #: main.c @@ -1346,10 +1442,6 @@ msgstr "" msgid "attributes not supported yet" msgstr "atributos ainda não suportados" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "" - #: py/builtinevex.c msgid "bad compile mode" msgstr "" @@ -1378,7 +1470,7 @@ msgstr "" msgid "bits must be 8" msgstr "bits devem ser 8" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "bits_per_sample must be 8 or 16" msgstr "bits devem ser 8" @@ -1393,7 +1485,7 @@ msgstr "Calibração está fora do intervalo" msgid "buf is too small. need %d bytes" msgstr "" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "buffer must be a bytes-like object" msgstr "" @@ -1605,10 +1697,6 @@ msgstr "" msgid "casting" msgstr "" -#: shared-bindings/bleio/Service.c -msgid "characteristics includes an object that is not a Characteristic" -msgstr "" - #: shared-bindings/_stage/Text.c msgid "chars buffer too small" msgstr "" @@ -1757,7 +1845,8 @@ msgstr "argumentos extras de palavras-chave passados" msgid "extra positional arguments given" msgstr "argumentos extra posicionais passados" -#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c msgid "file must be a file opened in byte mode" msgstr "" @@ -1886,7 +1975,7 @@ msgstr "" msgid "integer required" msgstr "inteiro requerido" -#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c #, c-format msgid "interval must be in range %s-%s" msgstr "" @@ -1980,6 +2069,10 @@ msgstr "" msgid "length argument not allowed for this type" msgstr "" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "" @@ -2008,6 +2101,12 @@ msgstr "" 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 "" @@ -2053,7 +2152,7 @@ msgstr "" msgid "name '%q' is not defined" msgstr "" -#: shared-bindings/bleio/Peripheral.c +#: shared-bindings/_bleio/Peripheral.c #, fuzzy msgid "name must be a string" msgstr "heap deve ser uma lista" @@ -2099,16 +2198,17 @@ msgstr "" 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 "" -#: shared-bindings/bleio/Peripheral.c -msgid "non-Service found in services" -msgstr "" - -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" #: py/compile.c @@ -2127,7 +2227,7 @@ msgstr "" msgid "non-keyword arg after keyword arg" msgstr "" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "not a 128-bit UUID" msgstr "" @@ -2193,6 +2293,14 @@ msgstr "" 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" @@ -2302,7 +2410,7 @@ msgstr "" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" @@ -2418,10 +2526,6 @@ msgstr "" msgid "threshold must be in the range 0-65536" msgstr "Limite deve estar no alcance de 0-65536" -#: shared-bindings/displayio/TileGrid.c -msgid "tile index out of bounds" -msgstr "" - #: shared-bindings/time/__init__.c msgid "time.struct_time() takes a 9-sequence" msgstr "" @@ -2434,7 +2538,7 @@ msgstr "" msgid "timeout >100 (units are now seconds, not msecs)" msgstr "" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c #, fuzzy msgid "timeout must be >= 0.0" msgstr "bits devem ser 8" @@ -2588,7 +2692,7 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Scanner.c msgid "window must be <= interval" msgstr "" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index d8d11cd858..d5df0b7b0c 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: circuitpython-cn\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-09 09:06-0400\n" +"POT-Creation-Date: 2019-09-08 17:30-0500\n" "PO-Revision-Date: 2019-04-13 10:10-0700\n" "Last-Translator: hexthat\n" "Language-Team: Chinese Hanyu Pinyin\n" @@ -54,7 +54,7 @@ msgstr "%q suǒyǐn chāochū fànwéi" 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/_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" @@ -219,14 +219,14 @@ msgstr "bù zhīchí 3-arg pow ()" 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 +#: 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 +#: shared-bindings/_bleio/Address.c msgid "Address type out of range" -msgstr "" +msgstr "Dìzhǐ lèixíng chāochū fànwéi" #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" @@ -255,6 +255,7 @@ 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" @@ -300,6 +301,10 @@ 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 "Dī yú zuìdī zhèng sùlǜ" + #: 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" @@ -312,6 +317,10 @@ msgstr "Bǐtè shēndù bìxū shì 8 bèi yǐshàng." 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 "Liàngdù bìxū wèi 0-1.0" + #: 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" @@ -325,6 +334,19 @@ msgstr "Liàngdù wúfǎ tiáozhěng" 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 "Huǎnchōng qū bùshì bytearray" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is too small" +msgstr "Huǎnchōng qū tài xiǎo" + +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Buffer length %d too big. It must be less than %d" +msgstr "Huǎnchōng qū chángdù%d tài dà. Tā bìxū xiǎoyú%d" + #: 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" @@ -335,7 +357,7 @@ msgstr "Huǎnchōng qū bìxū zhìshǎo chángdù 1" 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 +#: 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é." @@ -345,15 +367,15 @@ 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 "" +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 for local Characteristic" +#: 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 @@ -409,15 +431,7 @@ msgstr "Wúfǎ míngquè de huòdé biāoliàng de dàxiǎo" msgid "Cannot write without MOSI pin." msgstr "Wúfǎ xiě rù MOSI de yǐn jiǎo." -#: shared-bindings/bleio/Service.c -msgid "Characteristic UUID doesn't match Service UUID" -msgstr "Zìfú UUID bù fúhé fúwù UUID" - -#: ports/nrf/common-hal/bleio/Service.c -msgid "Characteristic already in use by another Service." -msgstr "Qítā fúwù bùmén yǐ shǐyòng de gōngnéng." - -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" msgstr "Wèi tígōng zìfú huǎncún xiě rù" @@ -437,19 +451,23 @@ msgstr "Shǐyòng shízhōng dānwèi" 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 "" +msgstr "Fǔbài de .mpy wénjiàn" #: py/emitglue.c msgid "Corrupt raw code" -msgstr "" +msgstr "Sǔnhuài de yuánshǐ dàimǎ" -#: ports/nrf/common-hal/bleio/UUID.c +#: 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" @@ -458,11 +476,11 @@ msgstr "Wúfǎ jiěmǎ kě dú_uuid, err 0x%04x" msgid "Could not initialize UART" msgstr "Wúfǎ chūshǐhuà UART" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "Wúfǎ fēnpèi dì yī gè huǎnchōng qū" -#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "Wúfǎ fēnpèi dì èr gè huǎnchōng qū" @@ -479,11 +497,11 @@ msgstr "Fā yuán huì yǐjīng shǐyòng" 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/audioio/WaveFile.c +#: 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 +#: 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à" @@ -491,7 +509,16 @@ msgstr "Guǎnggào bāo de shùjù tài dà" msgid "Destination capacity is smaller than destination_length." msgstr "Mùbiāo róngliàng xiǎoyú mùdì de_chángdù." +#: ports/nrf/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +msgstr "Zhèngzài shǐyòng de shèbèi" + #: shared-bindings/displayio/Display.c +msgid "Display must have a 16 bit colorspace." +msgstr "Xiǎnshì bìxū jùyǒu 16 wèi yánsè kōngjiān." + +#: 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" @@ -515,18 +542,27 @@ msgstr "Zhèngzé biǎodá shì cuòwù" msgid "Expected a %q" msgstr "Yùqí %q" -#: shared-bindings/bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c msgid "Expected a Characteristic" msgstr "Yùqí de tèdiǎn" -#: shared-bindings/bleio/Characteristic.c shared-bindings/bleio/Descriptor.c -#: shared-bindings/bleio/Service.c +#: shared-bindings/_bleio/Service.c +msgid "Expected a Peripheral" +msgstr "Qídài yīgè wàiwéi shèbèi" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Expected a Service" +msgstr "Yùqí fúwù" + +#: 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 +#: shared-bindings/_bleio/Central.c msgid "Expected an Address" -msgstr "" +msgstr "Qídài yīgè dìzhǐ" #: shared-module/_pixelbuf/PixelBuf.c #, c-format @@ -535,19 +571,24 @@ 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 "" +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 +#: 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/Peripheral.c +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to add descriptor, err 0x%04x" +msgstr "Wúfǎ tiānjiā miáoshù fú, err 0x%04x" + +#: 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" @@ -562,57 +603,62 @@ msgstr "Fēnpèi RX huǎnchōng shībài" 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Peripheral.c #, c-format msgid "Failed to configure advertising, err 0x%04x" -msgstr "" +msgstr "Wúfǎ pèizhì guǎnggào, cuòwù 0x%04x" -#: ports/nrf/common-hal/bleio/Central.c +#: ports/nrf/common-hal/_bleio/Central.c msgid "Failed to connect: timeout" -msgstr "" +msgstr "Liánjiē shībài: Chāoshí" -#: ports/nrf/common-hal/bleio/Scanner.c +#: 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/Central.c +#: 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 +#: 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 +#: 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 +#: 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/Characteristic.c +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Failed to pair" +msgstr "Pèiduì shībài" + +#: 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/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/Characteristic.c +#: 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 +#: 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" @@ -622,42 +668,47 @@ msgstr "Wúfǎ zhùcè màizhǔ tèdìng de UUID, err 0x%04x" 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 +#: ports/nrf/common-hal/_bleio/Peripheral.c #, c-format msgid "Failed to set device name, err 0x%04x" -msgstr "" +msgstr "Wúfǎ shèzhì shèbèi míngchēng, cuòwù 0x%04x" -#: ports/nrf/common-hal/bleio/Peripheral.c +#: 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 +#: ports/nrf/common-hal/_bleio/Central.c #, c-format msgid "Failed to start connecting, error 0x%04x" -msgstr "" +msgstr "Wúfǎ kāishǐ liánjiē, cuòwù 0x%04x" -#: ports/nrf/common-hal/bleio/Scanner.c +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "Wúfǎ kāishǐ pèiduì, cuòwù 0x%04x" + +#: 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 +#: 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 +#: ports/nrf/common-hal/_bleio/Characteristic.c #, c-format msgid "Failed to write CCCD, err 0x%04x" -msgstr "" +msgstr "Wúfǎ xiě rù CCCD, cuòwù 0x%04x" -#: ports/nrf/common-hal/bleio/Characteristic.c +#: 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/Characteristic.c +#: 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" @@ -693,6 +744,11 @@ msgstr "Pínlǜ bǔhuò gāo yú nénglì. Bǔhuò zàntíng." 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 "Jítuán yǐjīng shǐyòngguò" + #: shared-module/displayio/Group.c msgid "Group full" msgstr "Fēnzǔ yǐ mǎn" @@ -751,7 +807,7 @@ msgstr "Wúxiào de huǎnchōng qū dàxiǎo" 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/audioio/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "Wúxiào de tōngdào jìshù" @@ -759,11 +815,11 @@ msgstr "Wúxiào de tōngdào jìshù" msgid "Invalid direction." msgstr "Wúxiào de fāngxiàng." -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid file" msgstr "Wúxiào de wénjiàn" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" msgstr "Géshì kuài dàxiǎo wúxiào" @@ -801,15 +857,27 @@ msgstr "Wúxiào de yǐn jiǎo" msgid "Invalid polarity" msgstr "Wúxiào liǎng jí zhí" +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "Wúxiào de shǔxìng" + #: shared-bindings/microcontroller/__init__.c msgid "Invalid run mode." msgstr "Wúxiào de yùnxíng móshì." -#: shared-bindings/audioio/Mixer.c +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "Ānquán móshì wúxiào" + +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "Yǔyīn wúxiào" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "Wúxiào de yǔyīn jìshù" -#: shared-module/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Invalid wave file" msgstr "Wúxiào de làng làngcháo wénjiàn" @@ -819,7 +887,7 @@ msgstr "Guānjiàn zì arg de LHS bìxū shì id" #: shared-module/displayio/Group.c msgid "Layer already in a group." -msgstr "" +msgstr "Tú céng yǐjīng zài yīgè zǔ zhōng." #: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass." @@ -871,11 +939,11 @@ 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 "" +msgstr "Bìxū shì %q zi lèi." -#: ports/nrf/common-hal/bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Characteristic.c msgid "No CCCD for this Characteristic" -msgstr "" +msgstr "Zhège tèzhēng méiyǒu CCCD" #: ports/atmel-samd/common-hal/analogio/AnalogOut.c msgid "No DAC on chip" @@ -912,13 +980,17 @@ 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 "" +msgstr "Shízhōng yǐn jiǎo wú yìngjiàn zhīchí" #: 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 "Yǐn jiǎo shàng méiyǒu xiàlā; 1Mohm tuījiàn" + #: py/moduerrno.c msgid "No space left on device" msgstr "Shèbèi shàng méiyǒu kònggé" @@ -927,12 +999,14 @@ msgstr "Shèbèi shàng méiyǒu kònggé" msgid "No such file/directory" msgstr "Méiyǒu cǐ lèi wénjiàn/mùlù" -#: ports/nrf/common-hal/bleio/Characteristic.c -#: shared-bindings/bleio/CharacteristicBuffer.c +#: 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" @@ -961,10 +1035,9 @@ msgstr "" #: shared-module/displayio/OnDiskBitmap.c #, c-format msgid "" -"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " -"given" +"Only monochrome, indexed 4bpp or 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" #: shared-bindings/_pixelbuf/PixelBuf.c msgid "Only slices with step=1 (aka None) are supported" @@ -1004,7 +1077,7 @@ 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 "" +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." @@ -1038,6 +1111,10 @@ msgstr "Zhǐ dú wénjiàn xìtǒng" msgid "Read-only object" msgstr "Zhǐ dú duìxiàng" +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Refresh too soon" +msgstr "Shuāxīn tài kuàile" + #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "Right channel unsupported" msgstr "Bù zhīchí yòu tōngdào" @@ -1058,11 +1135,12 @@ msgstr "Zài ānquán móshì xià yùnxíng! Bù yùnxíng yǐ bǎocún de dài msgid "SDA or SCL needs a pull up" msgstr "SDA huò SCL xūyào lādòng" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/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" @@ -1081,7 +1159,7 @@ msgstr "Qiēpiàn hé zhí bùtóng chángdù." msgid "Slices not supported" msgstr "Qiēpiàn bù shòu zhīchí" -#: ports/nrf/common-hal/bleio/Adapter.c +#: 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" @@ -1117,6 +1195,8 @@ 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 "" @@ -1137,19 +1217,19 @@ 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/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.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/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.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/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.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/audioio/Mixer.c +#: shared-module/audiomixer/MixerVoice.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" @@ -1157,9 +1237,13 @@ msgstr "Yàngběn de qiānmíng yǔ hǔn yīn qì de qiānmíng bù pǐpèi" 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 "Píng pū zhǐshù chāochū fànwéi" + #: shared-bindings/displayio/TileGrid.c -msgid "Tile indices must be 0 - 255" -msgstr "Píng pū zhǐshù bìxū wèi 0 - 255" +msgid "Tile value out of bounds" +msgstr "Píng pū zhí chāochū fànwéi" #: shared-bindings/displayio/TileGrid.c msgid "Tile width must exactly divide bitmap width" @@ -1173,11 +1257,13 @@ msgstr "Yào tuìchū, qǐng chóng zhì bǎnkuài ér bùyòng " 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/ParallelBus.c +#: 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ō" @@ -1197,15 +1283,15 @@ msgstr "USB máng" msgid "USB Error" msgstr "USB Cuòwù" -#: shared-bindings/bleio/UUID.c +#: shared-bindings/_bleio/UUID.c msgid "UUID integer value must be 0-0xffff" -msgstr "" +msgstr "UUID zhěngshù zhí bìxū wèi 0-0xffff" -#: shared-bindings/bleio/UUID.c +#: 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 +#: 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ū" @@ -1214,6 +1300,11 @@ msgstr "UUID zhí bùshì str,int huò zì jié huǎnchōng qū" 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" @@ -1231,7 +1322,7 @@ msgstr "Wúfǎ dòu qǔ sè tiáo shùjù" msgid "Unable to write to nvm." msgstr "Wúfǎ xiě rù nvm." -#: ports/nrf/common-hal/bleio/UUID.c +#: ports/nrf/common-hal/_bleio/UUID.c msgid "Unexpected nrfx uuid type" msgstr "Yìwài de nrfx uuid lèixíng" @@ -1244,11 +1335,11 @@ msgstr "RHS (yùqí %d, huòdé %d) shàng wèi pǐpèi de xiàngmù." msgid "Unsupported baudrate" msgstr "Bù zhīchí de baudrate" -#: shared-module/displayio/Display.c +#: 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/audioio/WaveFile.c +#: shared-module/audiocore/WaveFile.c msgid "Unsupported format" msgstr "Bù zhīchí de géshì" @@ -1260,14 +1351,20 @@ msgstr "Bù zhīchí de cāozuò" 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 "Zhí chángdù != Suǒ xū de gùdìng chángdù" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "Zhí chángdù > zuìdà chángdù" + #: 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/audioio/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" @@ -1357,10 +1454,6 @@ msgstr "yòu cè xūyào shùzǔ/zì jié" msgid "attributes not supported yet" msgstr "shǔxìng shàngwèi zhīchí" -#: ports/nrf/common-hal/bleio/Characteristic.c -msgid "bad GATT role" -msgstr "zǒng xiédìng de bùliáng juésè" - #: py/builtinevex.c msgid "bad compile mode" msgstr "biānyì móshì cuòwù" @@ -1389,7 +1482,7 @@ msgstr "bǐtè bìxū shì 7,8 huò 9" msgid "bits must be 8" msgstr "bǐtè bìxū shì 8" -#: shared-bindings/audioio/Mixer.c +#: shared-bindings/audiomixer/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" @@ -1402,7 +1495,7 @@ msgstr "fēnzhī bùzài fànwéi nèi" msgid "buf is too small. need %d bytes" msgstr "huǎnchōng tài xiǎo. Xūyào%d zì jié" -#: shared-bindings/audioio/RawSample.c +#: 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" @@ -1613,10 +1706,6 @@ msgstr "wúfǎ zhíxíng xiāngguān dǎorù" msgid "casting" msgstr "tóuyǐng" -#: shared-bindings/bleio/Service.c -msgid "characteristics includes an object that is not a Characteristic" -msgstr "tèxìng bāokuò bùshì zìfú de wùtǐ" - #: shared-bindings/_stage/Text.c msgid "chars buffer too small" msgstr "zìfú huǎnchōng qū tài xiǎo" @@ -1767,7 +1856,8 @@ msgstr "éwài de guānjiàn cí cānshù" msgid "extra positional arguments given" msgstr "gěi chūle éwài de wèizhì cānshù" -#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c +#: 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" @@ -1896,10 +1986,10 @@ msgstr "zhěngshù() cānshù 2 bìxū > = 2 qiě <= 36" msgid "integer required" msgstr "xūyào zhěngshù" -#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c #, c-format msgid "interval must be in range %s-%s" -msgstr "" +msgstr "Jiàngé bìxū zài %s-%s fànwéi nèi" #: extmod/machine_i2c.c msgid "invalid I2C peripheral" @@ -1991,6 +2081,10 @@ msgstr "biāoqiān chóngxīn dìngyì" msgid "length argument not allowed for this type" msgstr "bù yǔnxǔ gāi lèixíng de chángdù cānshù" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "Level bìxū jiè yú 0 hé 1 zhī jiān" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs hé rhs yīnggāi jiānróng" @@ -2019,6 +2113,12 @@ msgstr "dìtú huǎnchōng qū tài xiǎo" 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 "Dāng gùdìng chángdù wèi %s shí, zuìdà chángdù bìxū wèi 0-%d" + #: py/runtime.c msgid "maximum recursion depth exceeded" msgstr "chāochū zuìdà dìguī shēndù" @@ -2064,7 +2164,7 @@ msgstr "bìxū shǐyòng guānjiàn cí cānshù" msgid "name '%q' is not defined" msgstr "míngchēng '%q' wèi dìngyì" -#: shared-bindings/bleio/Peripheral.c +#: shared-bindings/_bleio/Peripheral.c msgid "name must be a string" msgstr "míngchēng bìxū shì yīgè zìfú chuàn" @@ -2110,17 +2210,18 @@ msgstr "zhǎo bù dào fēi běndì de bǎng dìng" 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 "Méiyǒu kěyòng de fùwèi yǐn jiǎo" + #: py/runtime.c shared-bindings/_pixelbuf/__init__.c msgid "no such attribute" msgstr "méiyǒu cǐ shǔxìng" -#: shared-bindings/bleio/Peripheral.c -msgid "non-Service found in services" -msgstr "" - -#: ports/nrf/common-hal/bleio/Central.c -msgid "non-UUID found in service_uuids" -msgstr "" +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" +msgstr "Zài service_uuids bái míngdān zhōng zhǎodào fēi UUID" #: py/compile.c msgid "non-default argument follows default argument" @@ -2138,7 +2239,7 @@ msgstr "zài */** zhīhòu fēi guānjiàn cí cānshù" 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 +#: shared-bindings/_bleio/UUID.c msgid "not a 128-bit UUID" msgstr "bùshì 128 wèi UUID" @@ -2204,6 +2305,14 @@ msgstr "jīshù zìfú chuàn" 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 "Jǐn zhīchí wèi shēndù = 16" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "Jǐn zhīchí cǎiyàng lǜ = 16000" + #: 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" @@ -2312,7 +2421,7 @@ msgstr "fǎnhuí yùqí de '%q' dàn huòdéle '%q'" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audioio/RawSample.c +#: shared-bindings/audiocore/RawSample.c msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" @@ -2429,10 +2538,6 @@ msgstr "uctypes miáoshù fú zhōng de yǔfǎ cuòwù" msgid "threshold must be in the range 0-65536" msgstr "yùzhí bìxū zài fànwéi 0-65536" -#: shared-bindings/displayio/TileGrid.c -msgid "tile index out of bounds" -msgstr "kuài suǒyǐn chāochū fànwéi" - #: shared-bindings/time/__init__.c msgid "time.struct_time() takes a 9-sequence" msgstr "time.struct_time() xūyào 9 xùliè" @@ -2445,7 +2550,7 @@ msgstr "time.struct_time() xūyào wánquán 1 cānshù" 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 +#: shared-bindings/_bleio/CharacteristicBuffer.c msgid "timeout must be >= 0.0" msgstr "chāoshí bìxū shì >= 0.0" @@ -2528,7 +2633,7 @@ msgid "unknown conversion specifier %c" msgstr "wèizhī de zhuǎnhuàn biāozhù %c" #: py/objstr.c -#, c-format +#, 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'" @@ -2592,15 +2697,15 @@ 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 "" +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 +#: shared-bindings/_bleio/Scanner.c msgid "window must be <= interval" -msgstr "" +msgstr "Chuāngkǒu bìxū shì <= jiàngé" #: shared-bindings/_pixelbuf/PixelBuf.c msgid "write_args must be a list, tuple, or None" @@ -2645,6 +2750,15 @@ msgstr "líng bù" #~ 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à" @@ -2699,9 +2813,27 @@ msgstr "líng bù" #~ 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 "Voice index too high" +#~ msgstr "Yǔyīn suǒyǐn tài gāo" + +#~ 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" @@ -2714,6 +2846,9 @@ msgstr "líng bù" #~ 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ù" diff --git a/main.c b/main.c index 6d7502ba44..6b56f5ff6f 100755 --- a/main.c +++ b/main.c @@ -45,7 +45,6 @@ #include "background.h" #include "mpconfigboard.h" -#include "shared-module/displayio/__init__.h" #include "supervisor/cpu.h" #include "supervisor/memory.h" #include "supervisor/port.h" @@ -58,6 +57,10 @@ #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 @@ -187,7 +190,9 @@ void cleanup_after_vm(supervisor_allocation* heap) { supervisor_move_memory(); reset_port(); + #if CIRCUITPY_BOARD reset_board_busses(); + #endif reset_board(); reset_status_led(); } @@ -248,6 +253,9 @@ bool run_code_py(safe_mode_t safe_mode) { } 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) { @@ -285,6 +293,13 @@ bool run_code_py(safe_mode_t safe_mode) { } 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); } } diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 8e3fe94606..11e6874edd 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -289,7 +289,8 @@ SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ $(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)) \ + $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) SRC_S = supervisor/$(CHIP_FAMILY)_cpu.s diff --git a/ports/atmel-samd/README.rst b/ports/atmel-samd/README.rst index 167373b262..9afa19b837 100644 --- a/ports/atmel-samd/README.rst +++ b/ports/atmel-samd/README.rst @@ -124,15 +124,20 @@ Setup ----- An ARM compiler is required for the build, along with the associated binary -utilities. On Ubuntu, these can be installed as follows: +utilities. They can be installed as follows: -.. code-block:: shell +- Ubuntu - sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa - sudo apt-get install gcc-arm-embedded + .. code-block:: shell -On Arch Linux the compiler is available for via the package -``arm-none-eabi-gcc``. + 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. diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h index d6f1898db8..c46f99b7db 100644 --- a/ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h @@ -51,7 +51,7 @@ // This defines the current in output buffer according to conversion rate // dac0_arch_cctrl #ifndef CONF_DAC0_CCTRL -#define CONF_DAC0_CCTRL 1 +#define CONF_DAC0_CCTRL 0 #endif // Run in standby @@ -90,7 +90,7 @@ // This defines the current in output buffer according to conversion rate // dac1_arch_cctrl #ifndef CONF_DAC1_CCTRL -#define CONF_DAC1_CCTRL 1 +#define CONF_DAC1_CCTRL 0 #endif // Run in standby diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_gclk_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_gclk_config.h index a0748d0fa8..6f4f01a7e6 100644 --- a/ports/atmel-samd/asf4_conf/samd51/hpl_gclk_config.h +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_gclk_config.h @@ -1,8 +1,9 @@ // Circuit Python SAMD51 clock tree: -// DFLL48M (with USBCRM on to sync with external USB ref) -> GCLK1, GCLK5 +// DFLL48M (with USBCRM on to sync with external USB ref) -> GCLK1, GCLK5, GCLK6 // GCLK1 (48MHz) -> 48 MHz peripherals -// GCLK5 (48 MHz divided down to 2 MHz) -> DPLL0, DAC peripherals +// GCLK5 (48 MHz divided down to 2 MHz) -> DPLL0 // DPLL0 (multiplied up to 120 MHz) -> GCLK0, GCLK4 (output for monitoring) +// GCLK6 (48 MHz divided down to 12 MHz) -> DAC // We'd like to use XOSC32K as a ref for DFLL48M on boards with a 32kHz crystal, // but haven't figured that out yet. @@ -472,7 +473,7 @@ // 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 +#define CONF_GCLK_GENERATOR_6_CONFIG 1 #endif // Generic Clock Generator Control @@ -488,7 +489,7 @@ // 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 +#define CONF_GCLK_GEN_6_SOURCE GCLK_GENCTRL_SRC_DFLL #endif // Run in Standby @@ -523,14 +524,14 @@ // 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 +#define CONF_GCLK_GEN_6_IDC 1 #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 +#define CONF_GCLK_GEN_6_GENEN 1 #endif // @@ -538,7 +539,7 @@ // Generic clock generator 6 division <0x0000-0xFFFF> // gclk_gen_6_div #ifndef CONF_GCLK_GEN_6_DIV -#define CONF_GCLK_GEN_6_DIV 1 +#define CONF_GCLK_GEN_6_DIV 4 #endif // // diff --git a/ports/atmel-samd/asf4_conf/samd51/peripheral_clk_config.h b/ports/atmel-samd/asf4_conf/samd51/peripheral_clk_config.h index 41efca755e..030a90a7a9 100644 --- a/ports/atmel-samd/asf4_conf/samd51/peripheral_clk_config.h +++ b/ports/atmel-samd/asf4_conf/samd51/peripheral_clk_config.h @@ -73,7 +73,7 @@ // dac_gclk_selection // Select the clock source for DAC. #ifndef CONF_GCLK_DAC_SRC -#define CONF_GCLK_DAC_SRC GCLK_PCHCTRL_GEN_GCLK5_Val +#define CONF_GCLK_DAC_SRC GCLK_PCHCTRL_GEN_GCLK6_Val #endif /** diff --git a/ports/atmel-samd/audio_dma.c b/ports/atmel-samd/audio_dma.c index 68d6f182d7..0478cc9bf4 100644 --- a/ports/atmel-samd/audio_dma.c +++ b/ports/atmel-samd/audio_dma.c @@ -29,25 +29,49 @@ #include "samd/events.h" #include "samd/dma.h" -#include "shared-bindings/audioio/RawSample.h" -#include "shared-bindings/audioio/WaveFile.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) { +static bool audio_dma_allocated[AUDIO_DMA_CHANNEL_COUNT]; + +uint8_t audio_dma_allocate_channel(void) { uint8_t channel; for (channel = 0; channel < AUDIO_DMA_CHANNEL_COUNT; channel++) { - if (!dma_channel_enabled(channel)) { + if (!audio_dma_allocated[channel]) { + audio_dma_allocated[channel] = true; return channel; } } - return channel; + return channel; // i.e., return failure +} + +void audio_dma_free_channel(uint8_t channel) { + assert(channel < AUDIO_DMA_CHANNEL_COUNT); + assert(audio_dma_allocated[channel]); + audio_dma_disable_channel(channel); + audio_dma_allocated[channel] = false; +} + +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, @@ -153,7 +177,7 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t* dma, bool output_signed, uint32_t output_register_address, uint8_t dma_trigger_source) { - uint8_t dma_channel = find_free_audio_dma_channel(); + uint8_t dma_channel = audio_dma_allocate_channel(); if (dma_channel >= AUDIO_DMA_CHANNEL_COUNT) { return AUDIO_DMA_DMA_BUSY; } @@ -252,16 +276,20 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t* dma, } dma_configure(dma_channel, dma_trigger_source, true); - dma_enable_channel(dma_channel); + audio_dma_enable_channel(dma_channel); return AUDIO_DMA_OK; } void audio_dma_stop(audio_dma_t* dma) { - dma_disable_channel(dma->dma_channel); - disable_event_channel(dma->event_channel); - MP_STATE_PORT(playing_audio)[dma->dma_channel] = NULL; - + 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; + audio_dma_free_channel(dma->dma_channel); + } dma->dma_channel = AUDIO_DMA_CHANNEL_COUNT; } @@ -290,7 +318,8 @@ 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; - dma_disable_channel(i); + audio_dma_allocated[i] = false; + audio_dma_disable_channel(i); dma_descriptor(i)->BTCTRL.bit.VALID = false; MP_STATE_PORT(playing_audio)[i] = NULL; } @@ -333,3 +362,4 @@ void audio_dma_background(void) { audio_dma_pending[i] = false; } } +#endif diff --git a/ports/atmel-samd/audio_dma.h b/ports/atmel-samd/audio_dma.h index 041d675a25..1ebec6f7e9 100644 --- a/ports/atmel-samd/audio_dma.h +++ b/ports/atmel-samd/audio_dma.h @@ -29,8 +29,8 @@ #include "extmod/vfs_fat.h" #include "py/obj.h" -#include "shared-module/audioio/RawSample.h" -#include "shared-module/audioio/WaveFile.h" +#include "shared-module/audiocore/RawSample.h" +#include "shared-module/audiocore/WaveFile.h" typedef struct { mp_obj_t sample; @@ -64,7 +64,8 @@ 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); +uint8_t audio_dma_allocate_channel(void); +void audio_dma_free_channel(uint8_t channel); // This sets everything up but doesn't start the timer. // Sample is the python object for the sample to play. @@ -83,6 +84,9 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t* dma, 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); diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c index 4e88d34e79..386ba07158 100644 --- a/ports/atmel-samd/background.c +++ b/ports/atmel-samd/background.c @@ -56,11 +56,11 @@ void run_background_tasks(void) { assert_heap_ok(); running_background_tasks = true; - #if (defined(SAMD21) && defined(PIN_PA02)) || defined(SAMD51) + #if CIRCUITPY_AUDIOIO || CIRCUITPY_AUDIOBUSIO audio_dma_background(); #endif #if CIRCUITPY_DISPLAYIO - displayio_refresh_displays(); + displayio_background(); #endif #if CIRCUITPY_NETWORK diff --git a/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk b/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk index 97c8eb8632..f390a8681a 100644 --- a/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk +++ b/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk @@ -14,5 +14,3 @@ LONGINT_IMPL = MPZ # No I2S on SAMD51G CIRCUITPY_AUDIOBUSIO = 0 -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/board.c b/ports/atmel-samd/boards/circuitplayground_express_displayio/board.c new file mode 100644 index 0000000000..578963642d --- /dev/null +++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/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_displayio/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h new file mode 100644 index 0000000000..333fc79f9b --- /dev/null +++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h @@ -0,0 +1,48 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit CircuitPlayground Express with displayio" +#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_displayio/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk new file mode 100644 index 0000000000..f0c9c6b8c4 --- /dev/null +++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk @@ -0,0 +1,31 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash-crystalless.ld +USB_VID = 0x239A +USB_PID = 0x8019 +USB_PRODUCT = "CircuitPlayground Express with displayio" +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_BITBANGIO = 0 +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_I2CSLAVE = 0 +CIRCUITPY_PIXELBUF = 0 +CIRCUITPY_GAMEPAD = 0 +CIRCUITPY_RTC = 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_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_displayio/pins.c b/ports/atmel-samd/boards/circuitplayground_express_displayio/pins.c new file mode 100644 index 0000000000..6fc46bd216 --- /dev/null +++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/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/mpconfigboard.mk b/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk index 72a191044a..86a7719b84 100644 --- a/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk @@ -14,5 +14,3 @@ EXTERNAL_FLASH_DEVICES = "W25Q128JV_PM" CIRCUITPY_PS2IO = 1 # No I2S on SAMD51G. CIRCUITPY_AUDIOBUSIO = 0 -# No touch on SAMD51 yet. -CIRCUITPY_TOUCHIO = 0 diff --git a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk index 794920fe33..aa5f47d400 100644 --- a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk @@ -15,5 +15,3 @@ LONGINT_IMPL = MPZ CIRCUITPY_NETWORK = 1 MICROPY_PY_WIZNET5K = 5500 CIRCUITPY_PS2IO = 1 -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk index 756c293ad9..5b89f1be4f 100644 --- a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk @@ -12,5 +12,9 @@ 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_supersized/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk index 33229044b7..c5fef4373c 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk @@ -11,3 +11,10 @@ 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_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk index 8169345f56..176ebac82c 100644 --- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk @@ -15,5 +15,3 @@ LONGINT_IMPL = MPZ CIRCUITPY_NETWORK = 1 MICROPY_PY_WIZNET5K = 5500 CIRCUITPY_PS2IO = 1 -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 diff --git a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h index bc60ba49ba..5f09ab4d2f 100644 --- a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h +++ b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h @@ -6,8 +6,6 @@ #define MICROPY_HW_APA102_MOSI (&pin_PA00) #define MICROPY_HW_APA102_SCK (&pin_PA01) -// #define CIRCUITPY_BITBANG_APA102 - #define MICROPY_PORT_A (PORT_PA00 | PORT_PA01 | PORT_PA24 | PORT_PA25) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk index 13631a7362..423761c3f7 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk @@ -13,5 +13,3 @@ EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" LONGINT_IMPL = MPZ CIRCUITPY_PS2IO = 1 -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 diff --git a/ports/atmel-samd/boards/hallowing_m0_express/board.c b/ports/atmel-samd/boards/hallowing_m0_express/board.c index a0e160757d..b4c54062f6 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m0_express/board.c @@ -91,6 +91,10 @@ void board_init(void) { 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 @@ -98,10 +102,13 @@ void board_init(void) { 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 + false, // data_as_commands + true, // auto_refresh + 60); // native_frames_per_second } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h index 4b5460706b..d5c2745009 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h @@ -35,3 +35,7 @@ // 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 index 8dfc741e5a..988d10d1cd 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk @@ -13,9 +13,15 @@ EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" LONGINT_IMPL = MPZ # To keep the build small -CIRCUITPY_I2CSLAVE = 0 -CIRCUITPY_FREQUENCYIO = 0 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. 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 0000000000..6bb2a591f0 --- /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 0000000000..654632db5d --- /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 0000000000..0d891abc82 --- /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 0000000000..89fe3fbcf4 --- /dev/null +++ b/ports/atmel-samd/boards/hallowing_m4_express/pins.c @@ -0,0 +1,71 @@ +#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_SPEAKER), 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_TOUCH1), MP_ROM_PTR(&pin_PA06) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH2), MP_ROM_PTR(&pin_PB09) }, + + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH3), MP_ROM_PTR(&pin_PB08) }, + + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH4), 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_TFT_BACKLIGHT), MP_ROM_PTR(&pin_PB14) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_PB31) }, + { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_PB30) }, + + { 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/mpconfigboard.h b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h index 79d0cd269e..6f9f661d94 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h @@ -3,7 +3,6 @@ #define MICROPY_HW_LED_STATUS (&pin_PA17) -#define CIRCUITPY_BITBANG_APA102 #define MICROPY_HW_APA102_MOSI (&pin_PA01) #define MICROPY_HW_APA102_SCK (&pin_PA00) diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk index e427e94301..2b64e90275 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk @@ -12,5 +12,13 @@ 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_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h index f4d17ac648..9e4d4a10c9 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h @@ -9,8 +9,6 @@ #define MICROPY_HW_APA102_MOSI (&pin_PB03) #define MICROPY_HW_APA102_SCK (&pin_PB02) -#define CIRCUITPY_BITBANG_APA102 - // These are pins not to reset. // QSPI Data pins #define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk index 31bb38e201..5cab5bf43a 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk @@ -15,5 +15,5 @@ LONGINT_IMPL = MPZ CIRCUITPY_PS2IO = 1 # No I2S on SAMD51G CIRCUITPY_AUDIOBUSIO = 0 -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 + +CIRCUITPY_BITBANG_APA102 = 1 diff --git a/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk index 5871cca2aa..706e551c5d 100644 --- a/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk +++ b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk @@ -11,8 +11,6 @@ QSPI_FLASH_FILESYSTEM = 0 INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = MPZ -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 # Not needed. CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_DISPLAYIO = 0 diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk index 93a8ffc117..d3f35ba8b0 100644 --- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk @@ -12,5 +12,8 @@ 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_m4_airlift_lite/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk index d7d0c1d6ed..98d85ba826 100644 --- a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk @@ -15,5 +15,3 @@ LONGINT_IMPL = MPZ CIRCUITPY_NETWORK = 1 MICROPY_PY_WIZNET5K = 5500 CIRCUITPY_PS2IO = 1 -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk index 829bf749f0..68b6f64065 100644 --- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk @@ -15,5 +15,3 @@ LONGINT_IMPL = MPZ CIRCUITPY_NETWORK = 1 MICROPY_PY_WIZNET5K = 5500 CIRCUITPY_PS2IO = 1 -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 diff --git a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.h b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.h index cd754924e6..c4563964f8 100644 --- a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.h +++ b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.h @@ -9,8 +9,6 @@ #define MICROPY_HW_APA102_MOSI (&pin_PB03) #define MICROPY_HW_APA102_SCK (&pin_PB02) -#define CIRCUITPY_BITBANG_APA102 - // These are pins not to reset. // QSPI Data pins #define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) diff --git a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk index a8f47dced1..4bd1d6e522 100644 --- a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk @@ -15,5 +15,5 @@ LONGINT_IMPL = MPZ CIRCUITPY_PS2IO = 1 # No I2S on SAMD51G CIRCUITPY_AUDIOBUSIO = 0 -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 + +CIRCUITPY_BITBANG_APA102 = 1 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 0000000000..2377f4a9da --- /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 0000000000..fc77520f5f --- /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 0000000000..a3db7dc890 --- /dev/null +++ b/ports/atmel-samd/boards/monster_m4sk/mpconfigboard.mk @@ -0,0 +1,16 @@ +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 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 0000000000..7272b9ed86 --- /dev/null +++ b/ports/atmel-samd/boards/monster_m4sk/pins.c @@ -0,0 +1,52 @@ +#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_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_NOSE), MP_ROM_PTR(&pin_PB08) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB09) }, + + { 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/pewpew_m4/board.c b/ports/atmel-samd/boards/pewpew_m4/board.c new file mode 100644 index 0000000000..b684f56016 --- /dev/null +++ b/ports/atmel-samd/boards/pewpew_m4/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, 0xa8, // _MADCTL + // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 cycle 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_PA13, &pin_PA15, 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_PA16, // TFT_DC Command or data + &pin_PA11, // TFT_CS Chip select + &pin_PA17, // 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 + 0, // 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), + NULL, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness (ignored) + true, // auto_brightness + false, // single_byte_bounds + false, // data_as_commands + false, // auto_refresh + 20); // native_frames_per_second +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.h b/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.h new file mode 100644 index 0000000000..1b3035e120 --- /dev/null +++ b/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.h @@ -0,0 +1,51 @@ +#define MICROPY_HW_BOARD_NAME "PewPew M4" +#define MICROPY_HW_MCU_NAME "samd51g19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// These are pins not to reset. +#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_PA01) +#define DEFAULT_I2C_BUS_SDA (&pin_PA00) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA04) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA05) +#define DEFAULT_SPI_BUS_MISO (&pin_PA00) + +#define DEFAULT_UART_BUS_RX (&pin_PA05) +#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 + +// Unused pins +#define IGNORE_PIN_PA03 1 +#define IGNORE_PIN_PA06 1 +#define IGNORE_PIN_PA08 1 +#define IGNORE_PIN_PA12 1 +#define IGNORE_PIN_PA14 1 +#define IGNORE_PIN_PA18 1 +#define IGNORE_PIN_PA19 1 +#define IGNORE_PIN_PA20 1 +#define IGNORE_PIN_PA21 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 + diff --git a/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk b/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk new file mode 100644 index 0000000000..54ec3d1d0e --- /dev/null +++ b/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk @@ -0,0 +1,40 @@ +LD_FILE = boards/samd51x19-bootloader.ld +USB_VID = 0x1d50 +USB_PID = 0x60e8 +USB_PRODUCT = "PewPew M4" +USB_MANUFACTURER = "Radomir Dopieralski" + +CHIP_VARIANT = SAMD51G19A +CHIP_FAMILY = samd51 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE + +CIRCUITPY_SMALL_BUILD = 1 +CIRCUITPY_PS2IO = 0 +CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_BITBANGIO = 0 +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_I2CSLAVE = 0 +CIRCUITPY_NEOPIXEL_WRITE = 0 +CIRCUITPY_PIXELBUF = 0 +CIRCUITPY_RTC = 0 +CIRCUITPY_TOUCHIO = 0 +CIRCUITPY_USB_HID = 0 +CIRCUITPY_USB_MIDI = 0 + +CIRCUITPY_AUDIOIO = 1 +CIRCUITPY_DISPLAYIO = 1 +CIRCUITPY_GAMEPAD = 1 +CIRCUITPY_STAGE = 1 +CIRCUITPY_MATH = 1 + +FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pewpew_m4 +CIRCUITPY_DISPLAY_FONT = $(TOP)/ports/atmel-samd/boards/ugame10/brutalist-6.bdf + +# Tweak inlining depending on language. +ifeq ($(TRANSLATION), zh_Latn_pinyin) +CFLAGS_INLINE_LIMIT = 45 +else +CFLAGS_INLINE_LIMIT = 70 +endif diff --git a/ports/atmel-samd/boards/pewpew_m4/pins.c b/ports/atmel-samd/boards/pewpew_m4/pins.c new file mode 100644 index 0000000000..7654432f57 --- /dev/null +++ b/ports/atmel-samd/boards/pewpew_m4/pins.c @@ -0,0 +1,45 @@ +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_LEFT), MP_ROM_PTR(&pin_PB23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_RIGHT), MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_UP), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_DOWN), MP_ROM_PTR(&pin_PA27) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_O), MP_ROM_PTR(&pin_PA10) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_X), MP_ROM_PTR(&pin_PA09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_Z), MP_ROM_PTR(&pin_PA22) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_P1), MP_ROM_PTR(&pin_PA30) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_P2), MP_ROM_PTR(&pin_PA31) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_P3), MP_ROM_PTR(&pin_PA00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_P4), MP_ROM_PTR(&pin_PA01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_P5), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_P6), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_P7), MP_ROM_PTR(&pin_PA05) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RST), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_SCK), MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_PA11) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02) }, + + { 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_SCK), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA00) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), 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_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/pirkey_m0/mpconfigboard.h b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.h index 288208f65a..5a8eb9d147 100644 --- a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.h +++ b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.h @@ -4,8 +4,6 @@ #define MICROPY_HW_APA102_MOSI (&pin_PA00) #define MICROPY_HW_APA102_SCK (&pin_PA01) -// #define CIRCUITPY_BITBANG_APA102 - #define MICROPY_PORT_A (PORT_PA00 | PORT_PA01 | PORT_PA24 | PORT_PA25) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) diff --git a/ports/atmel-samd/boards/pybadge/board.c b/ports/atmel-samd/boards/pybadge/board.c index 38902315aa..37f7991d15 100644 --- a/ports/atmel-samd/boards/pybadge/board.c +++ b/ports/atmel-samd/boards/pybadge/board.c @@ -93,6 +93,10 @@ void board_init(void) { 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 @@ -100,10 +104,13 @@ void board_init(void) { 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 + false, // data_as_commands + true, // auto_refresh + 60); // native_frames_per_second } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/pybadge/mpconfigboard.mk b/ports/atmel-samd/boards/pybadge/mpconfigboard.mk index b8d10387b2..7e2cb64398 100644 --- a/ports/atmel-samd/boards/pybadge/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pybadge/mpconfigboard.mk @@ -17,7 +17,5 @@ CIRCUITPY_DISPLAYIO = 1 CIRCUITPY_GAMEPAD = 1 CIRCUITPY_GAMEPADSHIFT = 1 CIRCUITPY_STAGE = 1 -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pybadge diff --git a/ports/atmel-samd/boards/pybadge_airlift/board.c b/ports/atmel-samd/boards/pybadge_airlift/board.c index a1f778df1c..7622de6f08 100644 --- a/ports/atmel-samd/boards/pybadge_airlift/board.c +++ b/ports/atmel-samd/boards/pybadge_airlift/board.c @@ -71,6 +71,10 @@ void board_init(void) { 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 @@ -78,10 +82,13 @@ void board_init(void) { 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 + false, // data_as_commands + true, // auto_refresh + 60); // native_frames_per_second } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.mk b/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.mk index 12683e995c..7e77b0feaf 100644 --- a/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.mk @@ -17,7 +17,5 @@ CIRCUITPY_DISPLAYIO = 1 CIRCUITPY_GAMEPAD = 1 CIRCUITPY_GAMEPADSHIFT = 1 CIRCUITPY_STAGE = 1 -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pybadge diff --git a/ports/atmel-samd/boards/pygamer/board.c b/ports/atmel-samd/boards/pygamer/board.c index 7b54b6fb53..b33ae4fb06 100644 --- a/ports/atmel-samd/boards/pygamer/board.c +++ b/ports/atmel-samd/boards/pygamer/board.c @@ -93,6 +93,10 @@ void board_init(void) { 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 @@ -100,10 +104,13 @@ void board_init(void) { 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 + false, // data_as_commands + true, // auto_refresh + 60); // native_frames_per_second } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/pygamer/mpconfigboard.mk b/ports/atmel-samd/boards/pygamer/mpconfigboard.mk index 69fb14358e..0fce468d9f 100644 --- a/ports/atmel-samd/boards/pygamer/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pygamer/mpconfigboard.mk @@ -17,7 +17,5 @@ CIRCUITPY_DISPLAYIO = 1 CIRCUITPY_GAMEPAD = 1 CIRCUITPY_GAMEPADSHIFT = 1 CIRCUITPY_STAGE = 1 -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pygamer diff --git a/ports/atmel-samd/boards/pygamer_advance/board.c b/ports/atmel-samd/boards/pygamer_advance/board.c index d1c5edc999..8eb501243f 100644 --- a/ports/atmel-samd/boards/pygamer_advance/board.c +++ b/ports/atmel-samd/boards/pygamer_advance/board.c @@ -71,6 +71,10 @@ void board_init(void) { 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 @@ -78,10 +82,13 @@ void board_init(void) { 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 + false, // data_as_commands + true, // auto_refresh + 60); // native_frames_per_second } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.mk b/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.mk index 1bb2c553d6..8711738d4f 100644 --- a/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.mk @@ -17,7 +17,5 @@ CIRCUITPY_DISPLAYIO = 1 CIRCUITPY_GAMEPAD = 1 CIRCUITPY_GAMEPADSHIFT = 1 CIRCUITPY_STAGE = 1 -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pybadge diff --git a/ports/atmel-samd/boards/pyportal/board.c b/ports/atmel-samd/boards/pyportal/board.c index bb80c5b489..2a72897784 100644 --- a/ports/atmel-samd/boards/pyportal/board.c +++ b/ports/atmel-samd/boards/pyportal/board.c @@ -83,17 +83,24 @@ void board_init(void) { 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, + &pin_PB31, // Backlight pin + NO_BRIGHTNESS_COMMAND, 1.0f, // brightness (ignored) true, // auto_brightness false, // single_byte_bounds - false); // data_as_commands + false, // data_as_commands + true, // auto_refresh + 60); // native_frames_per_second } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/pyportal/mpconfigboard.mk b/ports/atmel-samd/boards/pyportal/mpconfigboard.mk index 996b17b3b3..f763c74fa4 100644 --- a/ports/atmel-samd/boards/pyportal/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pyportal/mpconfigboard.mk @@ -11,6 +11,3 @@ QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 2 EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" LONGINT_IMPL = MPZ - -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 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 0000000000..a18bb380bb --- /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 0000000000..91c1188108 --- /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 0000000000..58b363779c --- /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 0000000000..6bc0a504a4 --- /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/robohatmm1/pins.c b/ports/atmel-samd/boards/robohatmm1/pins.c deleted file mode 100644 index fc3db7a304..0000000000 --- a/ports/atmel-samd/boards/robohatmm1/pins.c +++ /dev/null @@ -1,88 +0,0 @@ -#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_PA16) }, - { MP_ROM_QSTR(MP_QSTR_SERVO2), MP_ROM_PTR(&pin_PA17) }, - { MP_ROM_QSTR(MP_QSTR_SERVO3), MP_ROM_PTR(&pin_PA18) }, - { MP_ROM_QSTR(MP_QSTR_SERVO4), MP_ROM_PTR(&pin_PA19) }, - { 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) }, - - // RC_CH Pins - { MP_ROM_QSTR(MP_QSTR_RCH1), MP_ROM_PTR(&pin_PA07) }, - { MP_ROM_QSTR(MP_QSTR_RCH2), MP_ROM_PTR(&pin_PA06) }, - { MP_ROM_QSTR(MP_QSTR_RCH3), MP_ROM_PTR(&pin_PA05) }, - { MP_ROM_QSTR(MP_QSTR_RCH4), MP_ROM_PTR(&pin_PA04) }, - - // Special Function - { 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_ENABLE), MP_ROM_PTR(&pin_PA28) }, - - { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA20) }, - { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA21) }, - { 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_PB22) }, - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB23) }, - - // 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_I2C_SDA), MP_ROM_PTR(&pin_PA00) }, - { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_PA01) }, - - // SPI on SERCOM4 - { MP_ROM_QSTR(MP_QSTR_SPI_SCK), MP_ROM_PTR(&pin_PB11) }, - { MP_ROM_QSTR(MP_QSTR_SPI_MISO), MP_ROM_PTR(&pin_PB08) }, - { MP_ROM_QSTR(MP_QSTR_SPI_MOSI), MP_ROM_PTR(&pin_PB10) }, - { MP_ROM_QSTR(MP_QSTR_SPI_SS), MP_ROM_PTR(&pin_PB09) }, - - // 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_PI_GP24), MP_ROM_PTR(&pin_PA31) }, - { MP_ROM_QSTR(MP_QSTR_PI_GP5), MP_ROM_PTR(&pin_PA27) }, - { MP_ROM_QSTR(MP_QSTR_PI_RX), MP_ROM_PTR(&pin_PB22) }, - { MP_ROM_QSTR(MP_QSTR_PI_TX), MP_ROM_PTR(&pin_PB23) }, - - // SIGNAL / Digital pins (for reference) - { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB23) }, - { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB22) }, - { 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_PA00) }, - { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA01) }, - { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA28) }, - { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA03) }, - { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA20) }, - { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB11) }, - { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PB09) }, - { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PB10) }, - { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PB08) }, - { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA21) }, - { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PA03) }, - - { 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/board.c b/ports/atmel-samd/boards/robohatmm1_m0/board.c similarity index 100% rename from ports/atmel-samd/boards/robohatmm1/board.c rename to ports/atmel-samd/boards/robohatmm1_m0/board.c diff --git a/ports/atmel-samd/boards/robohatmm1/mpconfigboard.h b/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.h similarity index 72% rename from ports/atmel-samd/boards/robohatmm1/mpconfigboard.h rename to ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.h index dd31e912a1..c6856c68f8 100644 --- a/ports/atmel-samd/boards/robohatmm1/mpconfigboard.h +++ b/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.h @@ -1,7 +1,7 @@ -#define MICROPY_HW_BOARD_NAME "Robo HAT MM1" +#define MICROPY_HW_BOARD_NAME "Robo HAT MM1 M0" #define MICROPY_HW_MCU_NAME "samd21g18" -#define MICROPY_HW_LED_STATUS (&pin_PA21) +#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) @@ -24,23 +24,19 @@ #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) -//#define BOARD_HAS_CRYSTAL 0 #define CALIBRATE_CRYSTALLESS 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_PB08) +#define DEFAULT_SPI_BUS_SCK (&pin_PB09) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB08) +#define DEFAULT_SPI_BUS_MISO (&pin_PB11) -#define DEFAULT_UART_BUS_RX (&pin_PB23) -#define DEFAULT_UART_BUS_TX (&pin_PB22) +//#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 -//#define CIRCUITPY_I2CSLAVE -//#define CIRCUITPY_DISPLAYIO (0) - diff --git a/ports/atmel-samd/boards/robohatmm1/mpconfigboard.mk b/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.mk similarity index 63% rename from ports/atmel-samd/boards/robohatmm1/mpconfigboard.mk rename to ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.mk index 9523984b77..e703fbfb9f 100644 --- a/ports/atmel-samd/boards/robohatmm1/mpconfigboard.mk +++ b/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.mk @@ -1,33 +1,29 @@ LD_FILE = boards/samd21x18-bootloader-external-flash-crystalless.ld USB_VID = 0x1209 USB_PID = 0x4D43 -USB_PRODUCT = "Robo HAT MM1" +USB_PRODUCT = "Robo HAT MM1 M0" USB_MANUFACTURER = "Robotics Masters" CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 -# Non-Flash Edition -#INTERNAL_FLASH_FILESYSTEM = 1 -#LONGINT_IMPL = NONE -#SUPEROPT_GC = 0 - -# SPI-Flash Edition SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ" LONGINT_IMPL = MPZ -# Make room for frozen Libraries + +# Non-Flash Edition +#INTERNAL_FLASH_FILESYSTEM = 1 +#LONGINT_IMPL = NONE + CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_FREQUENCYIO = 0 -CFLAGS_INLINE_LIMIT = 55 +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_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 -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel -#FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Crickit -#FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Motor -#FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_seesaw 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 0000000000..edaf0bc4c5 --- /dev/null +++ b/ports/atmel-samd/boards/robohatmm1_m0/pins.c @@ -0,0 +1,92 @@ +#include "shared-bindings/board/__init__.h" +// Version 2.4 +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_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) }, + + // UART on SERCOM1 (Raspberry Pi) + { MP_ROM_QSTR(MP_QSTR_TX1), 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_PA16) }, + { MP_ROM_QSTR(MP_QSTR_PI_TX), MP_ROM_PTR(&pin_PA17) }, + + // I2C on SERCOM1 (External Connector) + { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_PA01) }, + + // 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 (RPi & Internal) + { 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_PI_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_PI_SCL), MP_ROM_PTR(&pin_PA23) }, + + // SPI on SERCOM4 + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_SS), 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) }, + + // 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_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 0000000000..0f60736a24 --- /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 0000000000..64040a6586 --- /dev/null +++ b/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.h @@ -0,0 +1,44 @@ +#define MICROPY_HW_BOARD_NAME "Robo HAT MM1 M4" +#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_PB09) +#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 0000000000..56f1617dbf --- /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 M4" +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 0000000000..edaf0bc4c5 --- /dev/null +++ b/ports/atmel-samd/boards/robohatmm1_m4/pins.c @@ -0,0 +1,92 @@ +#include "shared-bindings/board/__init__.h" +// Version 2.4 +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_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) }, + + // UART on SERCOM1 (Raspberry Pi) + { MP_ROM_QSTR(MP_QSTR_TX1), 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_PA16) }, + { MP_ROM_QSTR(MP_QSTR_PI_TX), MP_ROM_PTR(&pin_PA17) }, + + // I2C on SERCOM1 (External Connector) + { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_PA01) }, + + // 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 (RPi & Internal) + { 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_PI_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_PI_SCL), MP_ROM_PTR(&pin_PA23) }, + + // SPI on SERCOM4 + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_SS), 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) }, + + // 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_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/mpconfigboard.mk b/ports/atmel-samd/boards/sam32/mpconfigboard.mk index ca1e11f011..12884a9cc8 100644 --- a/ports/atmel-samd/boards/sam32/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sam32/mpconfigboard.mk @@ -9,6 +9,3 @@ CHIP_FAMILY = samd51 INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = MPZ - -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 diff --git a/ports/atmel-samd/boards/serpente/board.c b/ports/atmel-samd/boards/serpente/board.c new file mode 100644 index 0000000000..d7e856d611 --- /dev/null +++ b/ports/atmel-samd/boards/serpente/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/serpente/mpconfigboard.h b/ports/atmel-samd/boards/serpente/mpconfigboard.h new file mode 100644 index 0000000000..034e1f6c37 --- /dev/null +++ b/ports/atmel-samd/boards/serpente/mpconfigboard.h @@ -0,0 +1,39 @@ +#define MICROPY_HW_BOARD_NAME "Serpente" +#define MICROPY_HW_MCU_NAME "samd21e18" + +#define MICROPY_HW_LED_STATUS (&pin_PA23) + +#define SPI_FLASH_MOSI_PIN &pin_PA16 +#define SPI_FLASH_MISO_PIN &pin_PA18 +#define SPI_FLASH_SCK_PIN &pin_PA17 +#define SPI_FLASH_CS_PIN &pin_PA15 + +// 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_PA09) +#define DEFAULT_I2C_BUS_SDA (&pin_PA08) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA05) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA04) +#define DEFAULT_SPI_BUS_MISO (&pin_PA06) + +#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 + +// Not connected +#define IGNORE_PIN_PA13 1 +#define IGNORE_PIN_PA28 1 + diff --git a/ports/atmel-samd/boards/serpente/mpconfigboard.mk b/ports/atmel-samd/boards/serpente/mpconfigboard.mk new file mode 100644 index 0000000000..98e1e37297 --- /dev/null +++ b/ports/atmel-samd/boards/serpente/mpconfigboard.mk @@ -0,0 +1,17 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash-crystalless.ld +USB_VID = 0x239A +USB_PID = 0x8058 +USB_PRODUCT = "Serpente" +USB_MANUFACTURER = "arturo182" + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q32C +LONGINT_IMPL = NONE + +CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_GAMEPAD = 0 diff --git a/ports/atmel-samd/boards/serpente/pins.c b/ports/atmel-samd/boards/serpente/pins.c new file mode 100644 index 0000000000..0bf6866561 --- /dev/null +++ b/ports/atmel-samd/boards/serpente/pins.c @@ -0,0 +1,40 @@ +#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_PA04) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA09) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA04) }, + { 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_PA07) }, + { 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_LED_G), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_LED_R), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_LED_B), MP_ROM_PTR(&pin_PA23) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA05) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) }, + + { 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_RX2), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_PA04) }, + + { 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/snekboard/board.c b/ports/atmel-samd/boards/snekboard/board.c new file mode 100644 index 0000000000..c8e20206a1 --- /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 0000000000..a349143d91 --- /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 0000000000..db2e511abf --- /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 0000000000..48bdc672e0 --- /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_redboard_turbo/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk index 3be1a17d3a..e80ef62771 100755 --- a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk @@ -12,5 +12,8 @@ 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/trellis_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h index 6870b86ba0..8ca1df1621 100644 --- a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h @@ -8,8 +8,6 @@ #define MICROPY_HW_APA102_MOSI (&pin_PB03) #define MICROPY_HW_APA102_SCK (&pin_PB02) -#define CIRCUITPY_BITBANG_APA102 - // These are pins not to reset. // QSPI Data pins #define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) diff --git a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk index 6d108e649e..ec37186c3a 100644 --- a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk @@ -15,5 +15,5 @@ LONGINT_IMPL = MPZ CIRCUITPY_PS2IO = 1 # No I2S on SAMD51G CIRCUITPY_AUDIOBUSIO = 0 -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 + +CIRCUITPY_BITBANG_APA102 = 1 diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk index b9d36a7418..c20358e19f 100644 --- a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk @@ -11,3 +11,9 @@ 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/ugame10/board.c b/ports/atmel-samd/boards/ugame10/board.c index 828f0c87d2..ce389a2b1c 100644 --- a/ports/atmel-samd/boards/ugame10/board.c +++ b/ports/atmel-samd/boards/ugame10/board.c @@ -91,6 +91,10 @@ void board_init(void) { 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 @@ -98,10 +102,13 @@ void board_init(void) { 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 + false, // data as commands + true, // auto_refresh + 60); // native_frames_per_second } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk index 6361da2a64..f0310b4aaa 100644 --- a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk +++ b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk @@ -10,7 +10,7 @@ CHIP_FAMILY = samd21 SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = S25FL216K -LONGINT_IMPL = MPZ +LONGINT_IMPL = NONE CIRCUITPY_STAGE = 1 CIRCUITPY_MATH = 1 @@ -19,16 +19,24 @@ CIRCUITPY_ANALOGIO = 1 CIRCUITPY_GAMEPAD = 1 CIRCUITPY_DISPLAYIO = 1 -CIRCUITPY_TOUCHIO = 0 -CIRCUITPY_NEOPIXEL_WRITE = 0 -CIRCUITPY_RTC = 0 -CIRCUITPY_USB_MIDI = 0 -CIRCUITPY_USB_HID = 0 -CIRCUITPY_I2CSLAVE = 0 -CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_BITBANGIO = 0 +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_I2CSLAVE = 0 +CIRCUITPY_NEOPIXEL_WRITE = 0 CIRCUITPY_PIXELBUF = 0 +CIRCUITPY_RTC = 0 +CIRCUITPY_TOUCHIO = 0 +CIRCUITPY_USB_HID = 0 +CIRCUITPY_USB_MIDI = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/ugame10 CIRCUITPY_DISPLAY_FONT = $(TOP)/ports/atmel-samd/boards/ugame10/brutalist-6.bdf + +# Tweak inlining depending on language. +ifeq ($(TRANSLATION), zh_Latn_pinyin) +CFLAGS_INLINE_LIMIT = 45 +else +CFLAGS_INLINE_LIMIT = 70 +endif diff --git a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c index 20934bed4f..05a6aaf7b0 100644 --- a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c +++ b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -33,7 +33,7 @@ #include "py/runtime.h" #include "common-hal/audiobusio/I2SOut.h" #include "shared-bindings/audiobusio/I2SOut.h" -#include "shared-bindings/audioio/RawSample.h" +#include "shared-bindings/audiocore/RawSample.h" #include "shared-bindings/microcontroller/Pin.h" #include "supervisor/shared/translate.h" diff --git a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c index 8b308b60b0..3a51cce8f1 100644 --- a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c +++ b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -355,7 +355,7 @@ static uint16_t filter_sample(uint32_t pdm_samples[4]) { // 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 dma_channel = audio_dma_allocate_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")); @@ -385,7 +385,7 @@ uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* se 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); - dma_enable_channel(dma_channel); + audio_dma_enable_channel(dma_channel); // Record uint32_t buffers_processed = 0; @@ -408,9 +408,7 @@ uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* se // 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) { - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif + RUN_BACKGROUND_TASKS; } // The mic is running all the time, so we don't need to wait the usual 10msec or 100msec @@ -466,7 +464,7 @@ uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* se } disable_event_channel(event_channel); - dma_disable_channel(dma_channel); + audio_dma_free_channel(dma_channel); // Turn off serializer, but leave clock on, to avoid mic startup delay. i2s_set_serializer_enable(self->serializer, false); diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.c b/ports/atmel-samd/common-hal/audioio/AudioOut.c index a75abd324b..36ab520067 100644 --- a/ports/atmel-samd/common-hal/audioio/AudioOut.c +++ b/ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -69,9 +69,7 @@ static void ramp_value(uint16_t start, uint16_t end) { DAC->DATA.reg = value; DAC->DATABUF.reg = value; common_hal_mcu_delay_us(50); - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif + RUN_BACKGROUND_TASKS; } } #endif @@ -94,9 +92,7 @@ static void ramp_value(uint16_t start, uint16_t end) { DAC->DATABUF[1].reg = value; common_hal_mcu_delay_us(50); - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif + RUN_BACKGROUND_TASKS; } } #endif @@ -202,7 +198,7 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, #endif #ifdef SAMD51 DAC->EVCTRL.reg |= DAC_EVCTRL_STARTEI0; - DAC->DACCTRL[0].reg = DAC_DACCTRL_CCTRL_CC1M | + DAC->DACCTRL[0].reg = DAC_DACCTRL_CCTRL_CC100K | DAC_DACCTRL_ENABLE | DAC_DACCTRL_LEFTADJ; DAC->CTRLB.reg = DAC_CTRLB_REFSEL_VREFPU; @@ -211,7 +207,7 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, #ifdef SAMD51 if (channel1_enabled) { DAC->EVCTRL.reg |= DAC_EVCTRL_STARTEI1; - DAC->DACCTRL[1].reg = DAC_DACCTRL_CCTRL_CC1M | + DAC->DACCTRL[1].reg = DAC_DACCTRL_CCTRL_CC100K | DAC_DACCTRL_ENABLE | DAC_DACCTRL_LEFTADJ; DAC->CTRLB.reg = DAC_CTRLB_REFSEL_VREFPU; @@ -316,6 +312,10 @@ void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t* self) { return; } + if (common_hal_audioio_audioout_get_playing(self)) { + common_hal_audioio_audioout_stop(self); + } + // Ramp the DAC down. ramp_value(self->quiescent_value, 0); @@ -385,19 +385,17 @@ void common_hal_audioio_audioout_play(audioio_audioout_obj_t* self, #ifdef SAMD51 uint32_t left_channel_reg = (uint32_t) &DAC->DATABUF[0].reg; - uint8_t left_channel_trigger = DAC_DMAC_ID_EMPTY_0; + uint8_t tc_trig_id = TC0_DMAC_ID_OVF + 3 * self->tc_index; + uint8_t left_channel_trigger = tc_trig_id; uint32_t right_channel_reg = 0; - uint8_t right_channel_trigger = 0; + uint8_t right_channel_trigger = tc_trig_id; 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 */, diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c index a0c04d65da..cdc616bbc8 100644 --- a/ports/atmel-samd/common-hal/busio/I2C.c +++ b/ports/atmel-samd/common-hal/busio/I2C.c @@ -36,6 +36,8 @@ #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 @@ -225,3 +227,10 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, } 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/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c index 644b9a87b4..7a1426bedc 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.c +++ b/ports/atmel-samd/common-hal/busio/SPI.c @@ -122,7 +122,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, } Sercom* potential_sercom = sercom_insts[sercom_index]; if ( - #if defined(MICROPY_HW_APA102_SCK) && defined(MICROPY_HW_APA102_MOSI) && !defined(CIRCUITPY_BITBANG_APA102) + #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)) { @@ -181,7 +181,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, // 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) && !defined(CIRCUITPY_BITBANG_APA102) + #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 diff --git a/ports/atmel-samd/common-hal/busio/SPI.h b/ports/atmel-samd/common-hal/busio/SPI.h index 56d163a9d8..a1c0e15179 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.h +++ b/ports/atmel-samd/common-hal/busio/SPI.h @@ -43,6 +43,7 @@ typedef struct { } 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 index f04594842e..2505e894af 100644 --- a/ports/atmel-samd/common-hal/busio/UART.c +++ b/ports/atmel-samd/common-hal/busio/UART.c @@ -291,13 +291,11 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t // Reset the timeout on every character read. start_ticks = ticks_ms; } -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP ; + RUN_BACKGROUND_TASKS; // Allow user to break out of a timeout with a KeyboardInterrupt. if (mp_hal_is_interrupted()) { break; } -#endif // 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) { @@ -339,9 +337,7 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, done = true; break; } - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif + RUN_BACKGROUND_TASKS; } if (!done) { diff --git a/ports/atmel-samd/common-hal/displayio/ParallelBus.c b/ports/atmel-samd/common-hal/displayio/ParallelBus.c index 7a5f61448a..2479e3b40e 100644 --- a/ports/atmel-samd/common-hal/displayio/ParallelBus.c +++ b/ports/atmel-samd/common-hal/displayio/ParallelBus.c @@ -31,6 +31,7 @@ #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" @@ -66,10 +67,6 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel 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 = &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); - 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); @@ -82,11 +79,19 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel 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); - never_reset_pin_number(reset->number); for (uint8_t i = 0; i < 8; i++) { never_reset_pin_number(data_pin + i); } @@ -104,15 +109,31 @@ void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self) 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, bool command, uint8_t *data, uint32_t data_length) { +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, !command); + 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; diff --git a/ports/atmel-samd/common-hal/pulseio/PulseOut.c b/ports/atmel-samd/common-hal/pulseio/PulseOut.c index 528a5c808a..8b8bc6dc68 100644 --- a/ports/atmel-samd/common-hal/pulseio/PulseOut.c +++ b/ports/atmel-samd/common-hal/pulseio/PulseOut.c @@ -198,9 +198,7 @@ void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pu while(pulse_index < length) { // Do other things while we wait. The interrupts will handle sending the // signal. - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif + RUN_BACKGROUND_TASKS; } tc->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_STOP; diff --git a/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c b/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c index e3bcf395b5..0922718f96 100644 --- a/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +++ b/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c @@ -35,7 +35,7 @@ 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_a->has_extint) { + if (!pin_a->has_extint || !pin_b->has_extint) { mp_raise_RuntimeError(translate("Both pins must support hardware interrupts")); } diff --git a/ports/atmel-samd/common-hal/touchio/TouchIn.c b/ports/atmel-samd/common-hal/touchio/TouchIn.c index 9fb3a2ea1a..908d8d7228 100644 --- a/ports/atmel-samd/common-hal/touchio/TouchIn.c +++ b/ports/atmel-samd/common-hal/touchio/TouchIn.c @@ -34,9 +34,10 @@ #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" -#endif #include "samd/clocks.h" #include "samd/pins.h" @@ -51,9 +52,7 @@ static uint16_t get_raw_reading(touchio_touchin_obj_t *self) { while (!adafruit_ptc_is_conversion_finished(PTC)) { // wait - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif + RUN_BACKGROUND_TASKS; } return adafruit_ptc_get_conversion_result(PTC); @@ -67,7 +66,6 @@ void common_hal_touchio_touchin_construct(touchio_touchin_obj_t* self, claim_pin(pin); // Turn on the PTC if its not in use. We won't turn it off until reset. - #ifdef SAMD21 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); @@ -96,7 +94,6 @@ void common_hal_touchio_touchin_construct(touchio_touchin_obj_t* self, // but for touches using fruit or other objects, the difference is much less. self->threshold = get_raw_reading(self) + 100; - #endif } bool common_hal_touchio_touchin_deinited(touchio_touchin_obj_t* self) { @@ -141,3 +138,5 @@ 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) { 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 index ffe8a6c017..85550b8a3a 100644 --- a/ports/atmel-samd/common-hal/touchio/TouchIn.h +++ b/ports/atmel-samd/common-hal/touchio/TouchIn.h @@ -27,6 +27,9 @@ #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" @@ -42,4 +45,6 @@ typedef struct { void touchin_reset(void); +#endif // SAMD21 + #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_TOUCHIO_TOUCHIN_H diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index 66ee92e6be..51bbdd658d 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -17,12 +17,18 @@ endif # Put samd21-only choices here. ifeq ($(CHIP_FAMILY),samd21) # frequencyio not yet verified as working on SAMD21. -CIRCUITPY_FRQUENCYIO = 0 +CIRCUITPY_AUDIOMIXER = 0 +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_TOUCHIO_USE_NATIVE = 1 + +# SAMD21 needs separate endpoint pairs for MSC BULK IN and BULK OUT, otherwise it's erratic. +USB_MSC_NUM_ENDPOINT_PAIRS = 2 endif # Put samd51-only choices here. ifeq ($(CHIP_FAMILY),samd51) CIRCUITPY_SAMD = 1 +CIRCUITPY_TOUCHIO_USE_NATIVE = 0 endif INTERNAL_LIBM = 1 diff --git a/ports/atmel-samd/mphalport.c b/ports/atmel-samd/mphalport.c index 5c34a576a8..957bf6073e 100644 --- a/ports/atmel-samd/mphalport.c +++ b/ports/atmel-samd/mphalport.c @@ -53,9 +53,7 @@ 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 + 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))) { diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals index 83a4759d18..2ba5b20ba7 160000 --- a/ports/atmel-samd/peripherals +++ b/ports/atmel-samd/peripherals @@ -1 +1 @@ -Subproject commit 83a4759d186574d8034435cd2303def85e4ed793 +Subproject commit 2ba5b20ba725e1c91c77875fba3a5e22059cdb92 diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 37360deb0e..512fd8eb8d 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -54,7 +54,11 @@ #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" @@ -211,7 +215,7 @@ void reset_port(void) { //pdmin_reset(); #endif -#if CIRCUITPY_TOUCHIO +#if CIRCUITPY_TOUCHIO && CIRCUITPY_TOUCHIO_USE_NATIVE touchin_reset(); #endif eic_reset(); diff --git a/ports/atmel-samd/tick.c b/ports/atmel-samd/tick.c index dde473375e..4d7bb9dca7 100644 --- a/ports/atmel-samd/tick.c +++ b/ports/atmel-samd/tick.c @@ -29,6 +29,7 @@ #include "peripheral_clk_config.h" #include "supervisor/shared/autoreload.h" +#include "supervisor/filesystem.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Processor.h" @@ -52,10 +53,13 @@ void SysTick_Handler(void) { (void) SysTick->CTRL; common_hal_mcu_enable_interrupts(); - #ifdef CIRCUITPY_AUTORELOAD_DELAY_MS +#if CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS > 0 + filesystem_tick(); +#endif +#ifdef CIRCUITPY_AUTORELOAD_DELAY_MS autoreload_tick(); - #endif - #ifdef CIRCUITPY_GAMEPAD_TICKS +#endif +#ifdef CIRCUITPY_GAMEPAD_TICKS if (!(ticks_ms & CIRCUITPY_GAMEPAD_TICKS)) { #if CIRCUITPY_GAMEPAD gamepad_tick(); @@ -64,7 +68,7 @@ void SysTick_Handler(void) { gamepadshift_tick(); #endif } - #endif +#endif } void tick_init() { diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 83f87536bd..be8a71b3f3 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -81,6 +81,7 @@ 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 @@ -89,13 +90,10 @@ 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 + CFLAGS += -ggdb3 -Og else CFLAGS += -Os -DNDEBUG - # TODO: Test with -flto - ### CFLAGS += -flto + CFLAGS += -flto -flto-partition=none endif @@ -184,8 +182,7 @@ SRC_C += \ # USB source files for nrf52840 ifeq ($(MCU_SUB_VARIANT),nrf52840) SRC_C += \ - lib/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c \ - lib/tinyusb/src/portable/nordic/nrf5x/hal_nrf5x.c + lib/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c endif SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ @@ -193,7 +190,8 @@ SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ $(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)) \ + $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) SRC_S = supervisor/cpu.s diff --git a/ports/nrf/background.c b/ports/nrf/background.c index 9c4f3ab27e..305f607c5c 100644 --- a/ports/nrf/background.c +++ b/ports/nrf/background.c @@ -33,6 +33,14 @@ #include "shared-module/displayio/__init__.h" #endif +#if CIRCUITPY_AUDIOBUSIO +#include "common-hal/audiobusio/I2SOut.h" +#endif + +#if CIRCUITPY_AUDIOPWMIO +#include "common-hal/audiopwmio/PWMAudioOut.h" +#endif + static bool running_background_tasks = false; void background_tasks_reset(void) { @@ -47,9 +55,16 @@ void run_background_tasks(void) { running_background_tasks = true; filesystem_background(); usb_background(); +#if CIRCUITPY_AUDIOPWMIO + audiopwmout_background(); +#endif +#if CIRCUITPY_AUDIOBUSIO + i2s_background(); +#endif + #if CIRCUITPY_DISPLAYIO - displayio_refresh_displays(); + displayio_background(); #endif running_background_tasks = false; diff --git a/ports/nrf/bluetooth/ble_uart.c b/ports/nrf/bluetooth/ble_uart.c index 91d10cff15..787a2a1174 100644 --- a/ports/nrf/bluetooth/ble_uart.c +++ b/ports/nrf/bluetooth/ble_uart.c @@ -34,11 +34,11 @@ #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" +#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) @@ -138,9 +138,7 @@ void ble_uart_init(void) { m_cccd_enabled = false; while (!m_cccd_enabled) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif + RUN_BACKGROUND_TASKS; } } @@ -150,9 +148,7 @@ bool ble_uart_connected(void) { char ble_uart_rx_chr(void) { while (isBufferEmpty(&m_rx_ring_buffer)) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif + RUN_BACKGROUND_TASKS; } uint8_t byte; diff --git a/supervisor/shared/usb/usb_desc.h b/ports/nrf/boards/circuitplayground_bluefruit/board.c similarity index 79% rename from supervisor/shared/usb/usb_desc.h rename to ports/nrf/boards/circuitplayground_bluefruit/board.c index 250147aa66..4421970eef 100644 --- a/supervisor/shared/usb/usb_desc.h +++ b/ports/nrf/boards/circuitplayground_bluefruit/board.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2018 hathach for Adafruit Industries + * 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 @@ -24,20 +24,15 @@ * THE SOFTWARE. */ -#ifndef USB_DESC_H_ -#define USB_DESC_H_ +#include "boards/board.h" -#include "lib/tinyusb/src/tusb.h" +void board_init(void) { +} -#ifdef __cplusplus - extern "C" { -#endif +bool board_requests_safe_mode(void) { + return false; +} -// Descriptors set used by tinyusb stack -extern tud_desc_set_t tud_desc_set; +void reset_board(void) { -#ifdef __cplusplus - } -#endif - -#endif /* USB_DESC_H_ */ +} diff --git a/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.h b/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.h new file mode 100644 index 0000000000..1e55cd0260 --- /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 0000000000..dbb32629c6 --- /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 0000000000..e8e5f4110d --- /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_02) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_02) }, + + { 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) }, + + // This cannot be A7, as it is on CPX. We don't have enough analog inputs. + { 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/feather_nrf52840_express/mpconfigboard.h b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h index e1f43e3c93..70ccffc3f3 100644 --- a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h +++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h @@ -27,8 +27,6 @@ #include "nrfx/hal/nrf_gpio.h" -#define FEATHER52840 - #define MICROPY_HW_BOARD_NAME "Adafruit Feather nRF52840 Express" #define MICROPY_HW_MCU_NAME "nRF52840" #define MICROPY_PY_SYS_PLATFORM "Feather52840Express" diff --git a/ports/nrf/boards/make-pins.py b/ports/nrf/boards/make-pins.py deleted file mode 100644 index d1cfd5b706..0000000000 --- a/ports/nrf/boards/make-pins.py +++ /dev/null @@ -1,208 +0,0 @@ -#!/usr/bin/env python -"""Creates the pin file for the nRF5.""" - -from __future__ import print_function - -import argparse -import sys -import csv - - -def parse_port_pin(name_str): - """Parses a string and returns a (port-num, pin-num) tuple.""" - if len(name_str) < 4: - raise ValueError("Expecting pin name to be at least 5 charcters.") - if name_str[0] != 'P': - raise ValueError("Expecting pin name to start with P") - if name_str[1] not in ('0', '1'): - raise ValueError("Expecting pin port to be in 0 or 1") - port = ord(name_str[1]) - ord('0') - pin_str = name_str[3:] - if not pin_str.isdigit(): - raise ValueError("Expecting numeric pin number.") - return (port, int(pin_str)) - - -class Pin(object): - """Holds the information associated with a pin.""" - - def __init__(self, port, pin): - self.port = port - self.pin = pin - self.adc_channel = '0' - self.board_pin = False - - def cpu_pin_name(self): - return 'P{:d}_{:02d}'.format(self.port, self.pin) - - def is_board_pin(self): - return self.board_pin - - def set_is_board_pin(self): - self.board_pin = True - - def parse_adc(self, adc_str): - if (adc_str[:3] != 'AIN'): - return - self.adc_channel = 'SAADC_CH_PSELP_PSELP_AnalogInput%d' % int(adc_str[3]) - - def print(self): - print('const pin_obj_t pin_{:s} = PIN({:s}, {:d}, {:d}, {:s});'.format( - self.cpu_pin_name(), self.cpu_pin_name(), - self.port, self.pin, self.adc_channel)) - - def print_header(self, hdr_file): - hdr_file.write('extern const pin_obj_t pin_{:s};\n'. - format(self.cpu_pin_name())) - - -class NamedPin(object): - - def __init__(self, name, pin): - self._name = name - self._pin = pin - - def pin(self): - return self._pin - - def name(self): - return self._name - - -class Pins(object): - - def __init__(self): - self.cpu_pins = [] # list of NamedPin objects - self.board_pins = [] # list of NamedPin objects - - def find_pin(self, port_num, pin_num): - for named_pin in self.cpu_pins: - pin = named_pin.pin() - if pin.port == port_num and pin.pin == pin_num: - return pin - - def parse_af_file(self, filename): - with open(filename, 'r') as csvfile: - rows = csv.reader(csvfile) - for row in rows: - try: - (port_num, pin_num) = parse_port_pin(row[0]) - except: - continue - pin = Pin(port_num, pin_num) - if len(row) > 1: - pin.parse_adc(row[1]) - self.cpu_pins.append(NamedPin(pin.cpu_pin_name(), pin)) - - def parse_board_file(self, filename): - with open(filename, 'r') as csvfile: - rows = csv.reader(csvfile) - for row in rows: - try: - (port_num, pin_num) = parse_port_pin(row[1]) - except: - continue - pin = self.find_pin(port_num, pin_num) - if pin: - pin.set_is_board_pin() - self.board_pins.append(NamedPin(row[0], pin)) - - def print_named(self, label, named_pins): - print('') - print('STATIC const mp_rom_map_elem_t {:s}_table[] = {{'.format(label)) - for named_pin in named_pins: - pin = named_pin.pin() - if pin.is_board_pin(): - print(' {{ MP_ROM_QSTR(MP_QSTR_{:s}), MP_ROM_PTR(&pin_{:s}) }},'.format(named_pin.name(), pin.cpu_pin_name())) - print('};') - print('MP_DEFINE_CONST_DICT({:s}, {:s}_table);'.format(label, label)) - - def print(self): - for named_pin in self.cpu_pins: - pin = named_pin.pin() - if pin.is_board_pin(): - pin.print() - self.print_named('mcu_pin_globals', self.cpu_pins) - self.print_named('board_module_globals', self.board_pins) - - def print_header(self, hdr_filename): - with open(hdr_filename, 'wt') as hdr_file: - for named_pin in self.cpu_pins: - pin = named_pin.pin() - if pin.is_board_pin(): - pin.print_header(hdr_file) - - def print_qstr(self, qstr_filename): - with open(qstr_filename, 'wt') as qstr_file: - qstr_set = set([]) - for named_pin in self.cpu_pins: - pin = named_pin.pin() - if pin.is_board_pin(): - qstr_set |= set([named_pin.name()]) - for named_pin in self.board_pins: - qstr_set |= set([named_pin.name()]) - for qstr in sorted(qstr_set): - print('Q({})'.format(qstr), file=qstr_file) - - -def main(): - parser = argparse.ArgumentParser( - prog="make-pins.py", - usage="%(prog)s [options] [command]", - description="Generate board specific pin file" - ) - parser.add_argument( - "-a", "--af", - dest="af_filename", - help="Specifies the alternate function file for the chip", - default="nrf_af.csv" - ) - parser.add_argument( - "-b", "--board", - dest="board_filename", - help="Specifies the board file", - ) - parser.add_argument( - "-p", "--prefix", - dest="prefix_filename", - help="Specifies beginning portion of generated pins file", - default="nrf52_prefix.c" - ) - parser.add_argument( - "-q", "--qstr", - dest="qstr_filename", - help="Specifies name of generated qstr header file", - default="build/pins_qstr.h" - ) - parser.add_argument( - "-r", "--hdr", - dest="hdr_filename", - help="Specifies name of generated pin header file", - default="build/pins.h" - ) - args = parser.parse_args(sys.argv[1:]) - - pins = Pins() - - print('// This file was automatically generated by make-pins.py') - print('//') - if args.af_filename: - print('// --af {:s}'.format(args.af_filename)) - pins.parse_af_file(args.af_filename) - - if args.board_filename: - print('// --board {:s}'.format(args.board_filename)) - pins.parse_board_file(args.board_filename) - - if args.prefix_filename: - print('// --prefix {:s}'.format(args.prefix_filename)) - print('') - with open(args.prefix_filename, 'r') as prefix_file: - print(prefix_file.read()) - pins.print() - pins.print_header(args.hdr_filename) - pins.print_qstr(args.qstr_filename) - - -if __name__ == "__main__": - main() 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 0000000000..4421970eef --- /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 0000000000..520eef90d9 --- /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 0000000000..4c1c93c10a --- /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 0000000000..452e31202b --- /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/particle_argon/mpconfigboard.h b/ports/nrf/boards/particle_argon/mpconfigboard.h index 0ee785c31b..a4ecb2bb43 100644 --- a/ports/nrf/boards/particle_argon/mpconfigboard.h +++ b/ports/nrf/boards/particle_argon/mpconfigboard.h @@ -27,8 +27,6 @@ #include "nrfx/hal/nrf_gpio.h" -#define FEATHER52840 - #define MICROPY_HW_BOARD_NAME "Particle Argon" #define MICROPY_HW_MCU_NAME "nRF52840" #define MICROPY_PY_SYS_PLATFORM "Particle Argon" diff --git a/ports/nrf/boards/particle_boron/mpconfigboard.h b/ports/nrf/boards/particle_boron/mpconfigboard.h index b814fc6946..5e817311f9 100644 --- a/ports/nrf/boards/particle_boron/mpconfigboard.h +++ b/ports/nrf/boards/particle_boron/mpconfigboard.h @@ -27,8 +27,6 @@ #include "nrfx/hal/nrf_gpio.h" -#define FEATHER52840 - #define MICROPY_HW_BOARD_NAME "Particle Boron" #define MICROPY_HW_MCU_NAME "nRF52840" #define MICROPY_PY_SYS_PLATFORM "Particle Boron" diff --git a/ports/nrf/boards/particle_xenon/mpconfigboard.h b/ports/nrf/boards/particle_xenon/mpconfigboard.h index c8da667369..6c8cc7cef2 100644 --- a/ports/nrf/boards/particle_xenon/mpconfigboard.h +++ b/ports/nrf/boards/particle_xenon/mpconfigboard.h @@ -27,8 +27,6 @@ #include "nrfx/hal/nrf_gpio.h" -#define FEATHER52840 - #define MICROPY_HW_BOARD_NAME "Particle Xenon" #define MICROPY_HW_MCU_NAME "nRF52840" #define MICROPY_PY_SYS_PLATFORM "Particle Xenon" diff --git a/ports/nrf/common-hal/bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c similarity index 65% rename from ports/nrf/common-hal/bleio/Adapter.c rename to ports/nrf/common-hal/_bleio/Adapter.c index 9d0912930b..a8e1f19059 100644 --- a/ports/nrf/common-hal/bleio/Adapter.c +++ b/ports/nrf/common-hal/_bleio/Adapter.c @@ -34,10 +34,16 @@ #include "nrfx_power.h" #include "nrf_nvic.h" #include "nrf_sdm.h" +#include "py/objstr.h" #include "py/runtime.h" -#include "shared-bindings/bleio/Adapter.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, @@ -46,17 +52,28 @@ STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) { STATIC uint32_t ble_stack_enable(void) { nrf_clock_lf_cfg_t clock_config = { - .source = NRF_CLOCK_LF_SRC_XTAL, - .accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM +#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) + if (err_code != NRF_SUCCESS) { return err_code; + } err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn); - if (err_code != NRF_SUCCESS) + if (err_code != NRF_SUCCESS) { return err_code; + } // Start with no event handlers, etc. ble_drv_reset(); @@ -87,8 +104,22 @@ STATIC uint32_t ble_stack_enable(void) { return err_code; err_code = sd_ble_enable(&app_ram_start); + if (err_code != NRF_SUCCESS) + return err_code; - 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) { @@ -132,20 +163,42 @@ bool common_hal_bleio_adapter_get_enabled(void) { return is_enabled; } -void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address) { - ble_gap_addr_t local_address; +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(&local_address); + err_code = sd_ble_gap_addr_get(address); if (err_code != NRF_SUCCESS) { mp_raise_OSError_msg(translate("Failed to get local address")); } - - address->type = local_address.addr_type; - - mp_buffer_info_t buf_info; - mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ); - memcpy(address->bytes, buf_info.buf, NUM_BLEIO_ADDRESS_BYTES); +} + +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 similarity index 100% rename from ports/nrf/common-hal/bleio/Adapter.h rename to ports/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 0000000000..c55914b10d --- /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 0000000000..8cc361046e --- /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 0000000000..db67b763c6 --- /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 similarity index 91% rename from ports/nrf/common-hal/bleio/Central.h rename to ports/nrf/common-hal/_bleio/Central.h index ac16700888..01f7faca74 100644 --- a/ports/nrf/common-hal/bleio/Central.h +++ b/ports/nrf/common-hal/_bleio/Central.h @@ -31,15 +31,14 @@ #include #include "py/objlist.h" -#include "shared-module/bleio/__init__.h" -#include "shared-module/bleio/Address.h" +#include "shared-module/_bleio/Address.h" typedef struct { mp_obj_base_t base; - gatt_role_t gatt_role; volatile bool waiting_to_connect; volatile uint16_t conn_handle; - mp_obj_list_t *service_list; + // 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 0000000000..e8454d528c --- /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 similarity index 81% rename from ports/nrf/common-hal/bleio/Characteristic.h rename to ports/nrf/common-hal/_bleio/Characteristic.h index 7cb2275968..3a7691d07f 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.h +++ b/ports/nrf/common-hal/_bleio/Characteristic.h @@ -28,17 +28,23 @@ #ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTIC_H #define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTIC_H -#include "common-hal/bleio/Service.h" -#include "common-hal/bleio/UUID.h" -#include "shared-module/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; - volatile mp_obj_t value_data; + 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; diff --git a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c similarity index 97% rename from ports/nrf/common-hal/bleio/CharacteristicBuffer.c rename to ports/nrf/common-hal/_bleio/CharacteristicBuffer.c index 59eaaf02b9..95794feec0 100644 --- a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c +++ b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c @@ -37,8 +37,8 @@ #include "tick.h" -#include "common-hal/bleio/__init__.h" -#include "common-hal/bleio/CharacteristicBuffer.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. @@ -99,7 +99,7 @@ int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_ // Wait for all bytes received or timeout while ( (ringbuf_count(&self->ringbuf) < len) && (ticks_ms - start_ticks < self->timeout_ms) ) { - MICROPY_VM_HOOK_LOOP; + RUN_BACKGROUND_TASKS; // Allow user to break out of a timeout with a KeyboardInterrupt. if ( mp_hal_is_interrupted() ) { return 0; diff --git a/ports/nrf/common-hal/bleio/CharacteristicBuffer.h b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.h similarity index 97% rename from ports/nrf/common-hal/bleio/CharacteristicBuffer.h rename to ports/nrf/common-hal/_bleio/CharacteristicBuffer.h index db8fd2fade..f0949251cd 100644 --- a/ports/nrf/common-hal/bleio/CharacteristicBuffer.h +++ b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.h @@ -30,7 +30,7 @@ #include "nrf_soc.h" #include "py/ringbuf.h" -#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/_bleio/Characteristic.h" typedef struct { mp_obj_base_t base; diff --git a/ports/nrf/common-hal/_bleio/Descriptor.c b/ports/nrf/common-hal/_bleio/Descriptor.c new file mode 100644 index 0000000000..137f004bab --- /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 similarity index 84% rename from ports/nrf/common-hal/bleio/Descriptor.h rename to ports/nrf/common-hal/_bleio/Descriptor.h index b7af6a42f9..3adb0df184 100644 --- a/ports/nrf/common-hal/bleio/Descriptor.h +++ b/ports/nrf/common-hal/_bleio/Descriptor.h @@ -30,14 +30,21 @@ #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" + +#include "common-hal/_bleio/Characteristic.h" +#include "common-hal/_bleio/UUID.h" typedef struct { mp_obj_base_t base; - uint16_t handle; + // 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 similarity index 52% rename from ports/nrf/common-hal/bleio/Peripheral.c rename to ports/nrf/common-hal/_bleio/Peripheral.c index 608bd1342b..9b0f96d48f 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.c +++ b/ports/nrf/common-hal/_bleio/Peripheral.c @@ -36,22 +36,31 @@ #include "py/objlist.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 "common-hal/bleio/Service.h" - -#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) -#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(300, UNIT_0_625_MS) -#define BLE_SLAVE_LATENCY 0 -#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) +#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")); @@ -61,13 +70,24 @@ STATIC void check_data_fit(size_t data_len) { 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_conn_params_t conn_params; + 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); - sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &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; } @@ -86,25 +106,16 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { } case BLE_GAP_EVT_ADV_SET_TERMINATED: - // Someday may handle timeouts or limit reached. + // TODO: Someday may handle timeouts or limit reached. break; - case BLE_GAP_EVT_SEC_PARAMS_REQUEST: - sd_ble_gap_sec_params_reply(self->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(self->conn_handle, &request->conn_params); - 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; } @@ -113,6 +124,82 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { 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); @@ -120,43 +207,39 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { } } -void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_list_t *service_list, mp_obj_t name) { +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 = service_list; + 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->gatt_role = GATT_ROLE_SERVER; self->conn_handle = BLE_CONN_HANDLE_INVALID; self->adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; + self->pair_status = PAIR_NOT_PAIRED; - // Add all the services. - - for (size_t service_idx = 0; service_idx < service_list->len; ++service_idx) { - bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[service_idx]); - - service->device = MP_OBJ_FROM_PTR(self); - - 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); - } - - // Once the service has been registered, its characteristics can be added. - common_hal_bleio_service_add_all_characteristics(service); - } + 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); -mp_obj_list_t *common_hal_bleio_peripheral_get_service_list(bleio_peripheral_obj_t *self) { + 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; } @@ -182,9 +265,9 @@ void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *self, 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); @@ -247,3 +330,32 @@ void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *self) 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 similarity index 80% rename from ports/nrf/common-hal/bleio/Peripheral.h rename to ports/nrf/common-hal/_bleio/Peripheral.h index 2a12517159..a4f62d288a 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.h +++ b/ports/nrf/common-hal/_bleio/Peripheral.h @@ -35,22 +35,33 @@ #include "py/obj.h" #include "py/objlist.h" -#include "shared-module/bleio/__init__.h" -#include "shared-module/bleio/Address.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; - gatt_role_t gatt_role; 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 similarity index 95% rename from ports/nrf/common-hal/bleio/Scanner.c rename to ports/nrf/common-hal/_bleio/Scanner.c index 57ce940abd..ec73f7eb8f 100644 --- a/ports/nrf/common-hal/bleio/Scanner.c +++ b/ports/nrf/common-hal/_bleio/Scanner.c @@ -33,10 +33,10 @@ #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" +#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]; diff --git a/ports/nrf/common-hal/bleio/Scanner.h b/ports/nrf/common-hal/_bleio/Scanner.h similarity index 100% rename from ports/nrf/common-hal/bleio/Scanner.h rename to ports/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 0000000000..650cdc4ec9 --- /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 similarity index 95% rename from ports/nrf/common-hal/bleio/Service.h rename to ports/nrf/common-hal/_bleio/Service.h index 583593fb80..a4614b9f51 100644 --- a/ports/nrf/common-hal/bleio/Service.h +++ b/ports/nrf/common-hal/_bleio/Service.h @@ -29,12 +29,14 @@ #define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SERVICE_H #include "py/objlist.h" -#include "common-hal/bleio/UUID.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. diff --git a/ports/nrf/common-hal/bleio/UUID.c b/ports/nrf/common-hal/_bleio/UUID.c similarity index 98% rename from ports/nrf/common-hal/bleio/UUID.c rename to ports/nrf/common-hal/_bleio/UUID.c index ebd6b6d1fb..0e65b7d58d 100644 --- a/ports/nrf/common-hal/bleio/UUID.c +++ b/ports/nrf/common-hal/_bleio/UUID.c @@ -29,8 +29,8 @@ #include #include "py/runtime.h" -#include "common-hal/bleio/UUID.h" -#include "shared-bindings/bleio/Adapter.h" +#include "common-hal/_bleio/UUID.h" +#include "shared-bindings/_bleio/Adapter.h" #include "ble.h" #include "ble_drv.h" diff --git a/ports/nrf/common-hal/bleio/UUID.h b/ports/nrf/common-hal/_bleio/UUID.h similarity index 100% rename from ports/nrf/common-hal/bleio/UUID.h rename to ports/nrf/common-hal/_bleio/UUID.h diff --git a/ports/nrf/common-hal/bleio/Central.c b/ports/nrf/common-hal/_bleio/__init__.c similarity index 58% rename from ports/nrf/common-hal/bleio/Central.c rename to ports/nrf/common-hal/_bleio/__init__.c index d90737411f..5530441909 100644 --- a/ports/nrf/common-hal/bleio/Central.c +++ b/ports/nrf/common-hal/_bleio/__init__.c @@ -3,8 +3,9 @@ * * The MIT License (MIT) * - * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * 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 @@ -25,34 +26,72 @@ * 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/Adapter.h" -#include "shared-bindings/bleio/Characteristic.h" -#include "shared-bindings/bleio/Central.h" -#include "shared-bindings/bleio/Descriptor.h" -#include "shared-bindings/bleio/Service.h" -#include "shared-bindings/bleio/UUID.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" -static bleio_service_obj_t *m_char_discovery_service; -static bleio_characteristic_obj_t *m_desc_discovery_characteristic; +#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(bleio_central_obj_t *self, uint16_t start_handle, ble_uuid_t *service_uuid) { +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; - uint32_t err_code = sd_ble_gattc_primary_services_discover(self->conn_handle, start_handle, service_uuid); + 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")); @@ -65,7 +104,7 @@ STATIC bool discover_next_services(bleio_central_obj_t *self, uint16_t start_han return m_discovery_successful; } -STATIC bool discover_next_characteristics(bleio_central_obj_t *self, bleio_service_obj_t *service, uint16_t start_handle) { +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; @@ -75,7 +114,8 @@ STATIC bool discover_next_characteristics(bleio_central_obj_t *self, bleio_servi m_discovery_successful = false; m_discovery_in_process = true; - uint32_t err_code = sd_ble_gattc_characteristics_discover(self->conn_handle, &handle_range); + 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; } @@ -87,7 +127,7 @@ STATIC bool discover_next_characteristics(bleio_central_obj_t *self, bleio_servi return m_discovery_successful; } -STATIC bool discover_next_descriptors(bleio_central_obj_t *self, bleio_characteristic_obj_t *characteristic, uint16_t start_handle, uint16_t end_handle) { +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; @@ -97,7 +137,8 @@ STATIC bool discover_next_descriptors(bleio_central_obj_t *self, bleio_character m_discovery_successful = false; m_discovery_in_process = true; - uint32_t err_code = sd_ble_gattc_descriptors_discover(self->conn_handle, &handle_range); + 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; } @@ -109,7 +150,7 @@ STATIC bool discover_next_descriptors(bleio_central_obj_t *self, bleio_character return m_discovery_successful; } -STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, bleio_central_obj_t *central) { +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]; @@ -117,9 +158,9 @@ STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *res service->base.type = &bleio_service_type; // Initialize several fields at once. - common_hal_bleio_service_construct(service, NULL, mp_obj_new_list(0, NULL), false); + common_hal_bleio_service_construct(service, device, NULL, false); - service->device = MP_OBJ_FROM_PTR(central); + 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; @@ -130,7 +171,6 @@ STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *res uuid->base.type = &bleio_uuid_type; bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid); service->uuid = uuid; - service->device = MP_OBJ_FROM_PTR(central); } 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. @@ -138,7 +178,7 @@ STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *res service->uuid = NULL; } - mp_obj_list_append(central->service_list, service); + mp_obj_list_append(common_hal_bleio_device_get_remote_service_list(device), service); } if (response->count > 0) { @@ -147,15 +187,13 @@ STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *res m_discovery_in_process = false; } -STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio_central_obj_t *central) { +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; - characteristic->descriptor_list = mp_obj_new_list(0, NULL); - bleio_uuid_obj_t *uuid = NULL; if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) { @@ -169,19 +207,20 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio // For now, just leave the UUID as NULL. } - bleio_characteristic_properties_t props; - - props.broadcast = gattc_char->char_props.broadcast; - props.indicate = gattc_char->char_props.indicate; - props.notify = gattc_char->char_props.notify; - props.read = gattc_char->char_props.read; - props.write = gattc_char->char_props.write; - props.write_no_response = gattc_char->char_props.write_wo_resp; + 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, uuid, props, mp_obj_new_list(0, NULL)); + 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; - characteristic->service = m_char_discovery_service; mp_obj_list_append(m_char_discovery_service->characteristic_list, MP_OBJ_FROM_PTR(characteristic)); } @@ -192,21 +231,21 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio m_discovery_in_process = false; } -STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, bleio_central_obj_t *central) { +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 DESCRIPTOR_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION: + case BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG: m_desc_discovery_characteristic->cccd_handle = gattc_desc->handle; break; - case DESCRIPTOR_UUID_SERVER_CHARACTERISTIC_CONFIGURATION: + case BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG: m_desc_discovery_characteristic->sccd_handle = gattc_desc->handle; break; - case DESCRIPTOR_UUID_CHARACTERISTIC_USER_DESCRIPTION: + case BLE_UUID_DESCRIPTOR_CHAR_USER_DESC: m_desc_discovery_characteristic->user_desc_handle = gattc_desc->handle; break; @@ -233,9 +272,11 @@ STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, bleio // For now, just leave the UUID as NULL. } - common_hal_bleio_descriptor_construct(descriptor, uuid); + 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; - descriptor->characteristic = m_desc_discovery_characteristic; mp_obj_list_append(m_desc_discovery_characteristic->descriptor_list, MP_OBJ_FROM_PTR(descriptor)); } @@ -246,131 +287,62 @@ STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, bleio m_discovery_in_process = false; } -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; - +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_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; 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, central); + 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, central); + 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, central); + on_desc_discovery_rsp(&ble_evt->evt.gattc_evt.params.desc_disc_rsp, device); 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); + // mp_printf(&mp_plat_print, "Unhandled discovery 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->service_list = mp_obj_new_list(0, NULL); - self->gatt_role = GATT_ROLE_CLIENT; - self->conn_handle = BLE_CONN_HANDLE_INVALID; -} +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); -void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout, mp_obj_t service_uuids) { - common_hal_bleio_adapter_set_enabled(true); - ble_drv_add_event_handler(central_on_ble_evt, self); + ble_drv_add_event_handler(discovery_on_ble_evt, device); - 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) { - MICROPY_VM_HOOK_LOOP; - } - - if (self->conn_handle == BLE_CONN_HANDLE_INVALID) { - mp_raise_OSError_msg(translate("Failed to connect: timeout")); - } - - // Connection successful. - // Now discover services on the remote peripheral. - - if (service_uuids == mp_const_none) { + // 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(self, next_service_start_handle, MP_OBJ_NULL)) { - // discover_next_services() appends to service_list. + 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(self->service_list->items[self->service_list->len - 1]); + 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, &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")); + mp_raise_ValueError(translate("non-UUID found in service_uuids_whitelist")); } bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj); @@ -380,13 +352,13 @@ void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_o // 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(self, BLE_GATT_HANDLE_START, &nrf_uuid); + discover_next_services(device, BLE_GATT_HANDLE_START, &nrf_uuid); } } - for (size_t service_idx = 0; service_idx < self->service_list->len; ++service_idx) { - bleio_service_obj_t *service = MP_OBJ_TO_PTR(self->service_list->items[service_idx]); + 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) { @@ -399,7 +371,7 @@ void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_o // discovery call returns nothing. // discover_next_characteristics() appends to the characteristic_list. while (next_char_start_handle <= service->end_handle && - discover_next_characteristics(self, service, next_char_start_handle)) { + discover_next_characteristics(device, service, next_char_start_handle)) { // Get the most recently discovered characteristic, and then ask for characteristics @@ -436,7 +408,7 @@ void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_o // 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(self, characteristic, + discover_next_descriptors(device, characteristic, next_desc_start_handle, next_desc_end_handle)) { // Get the most recently discovered descriptor, and then ask for descriptors @@ -446,18 +418,85 @@ void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_o 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_central_disconnect(bleio_central_obj_t *self) { - sd_ble_gap_disconnect(self->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); -} +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); -bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self) { - return self->conn_handle != BLE_CONN_HANDLE_INVALID; -} + 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); + } -mp_obj_list_t *common_hal_bleio_central_get_remote_services(bleio_central_obj_t *self) { - return self->service_list; } diff --git a/ports/nrf/common-hal/bleio/__init__.h b/ports/nrf/common-hal/_bleio/__init__.h similarity index 85% rename from ports/nrf/common-hal/bleio/__init__.h rename to ports/nrf/common-hal/_bleio/__init__.h index 0c46b631fc..cf1a06945d 100644 --- a/ports/nrf/common-hal/bleio/__init__.h +++ b/ports/nrf/common-hal/_bleio/__init__.h @@ -27,16 +27,16 @@ #ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H #define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H -#include "shared-bindings/bleio/__init__.h" -#include "shared-bindings/bleio/Adapter.h" +void bleio_reset(void); -#include "shared-module/bleio/__init__.h" +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) -gatt_role_t common_hal_bleio_device_get_gatt_role(mp_obj_t device); -uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device); - #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 index f20802ac98..7cf6a6423b 100644 --- a/ports/nrf/common-hal/analogio/AnalogIn.c +++ b/ports/nrf/common-hal/analogio/AnalogIn.c @@ -67,8 +67,8 @@ uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { 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, + .gain = NRF_SAADC_GAIN1_4, + .reference = NRF_SAADC_REFERENCE_VDD4, .acq_time = NRF_SAADC_ACQTIME_3US, .mode = NRF_SAADC_MODE_SINGLE_ENDED, .burst = NRF_SAADC_BURST_DISABLED, @@ -108,5 +108,6 @@ 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) { + // The nominal VCC voltage return 3.3f; } diff --git a/ports/nrf/common-hal/audiobusio/I2SOut.c b/ports/nrf/common-hal/audiobusio/I2SOut.c new file mode 100644 index 0000000000..ac369277f2 --- /dev/null +++ b/ports/nrf/common-hal/audiobusio/I2SOut.c @@ -0,0 +1,328 @@ +/* + * 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 "common-hal/microcontroller/Pin.h" +#include "common-hal/audiobusio/I2SOut.h" +#include "shared-bindings/audiobusio/I2SOut.h" +#include "shared-module/audiocore/__init__.h" + +#include "py/obj.h" +#include "py/runtime.h" + +static audiobusio_i2sout_obj_t *instance; + +struct { int16_t l, r; } static_sample16 = {0x8000, 0x8000}; +struct { uint8_t l1, r1, l2, r2; } static_sample8 = {0x80, 0x80, 0x80, 0x80}; + +struct frequency_info { uint32_t RATIO; uint32_t MCKFREQ; int sample_rate; float abserr; }; +struct ratio_info { uint32_t RATIO; int16_t divisor; bool can_16bit; }; +struct ratio_info ratios[] = { + { I2S_CONFIG_RATIO_RATIO_32X, 32, true }, + { I2S_CONFIG_RATIO_RATIO_48X, 48, false }, + { I2S_CONFIG_RATIO_RATIO_64X, 64, true }, + { I2S_CONFIG_RATIO_RATIO_96X, 96, true }, + { I2S_CONFIG_RATIO_RATIO_128X, 128, true }, + { I2S_CONFIG_RATIO_RATIO_192X, 192, true }, + { I2S_CONFIG_RATIO_RATIO_256X, 256, true }, + { I2S_CONFIG_RATIO_RATIO_384X, 384, true }, + { I2S_CONFIG_RATIO_RATIO_512X, 512, true }, +}; + +struct mclk_info { uint32_t MCKFREQ; int divisor; }; +struct mclk_info mclks[] = { + { I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV8, 8 }, + { I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV10, 10 }, + { I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV11, 11 }, + { I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV15, 15 }, + { I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV16, 16 }, + { I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV21, 21 }, + { I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV23, 23 }, + { I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV31, 31 }, + { I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV42, 42 }, + { I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV63, 63 }, + { I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV125, 125 }, +}; + +static void calculate_ratio_info(uint32_t target_sample_rate, struct frequency_info *info, + int ratio_index, int mclk_index) { + info->RATIO = ratios[ratio_index].RATIO; + info->MCKFREQ = mclks[mclk_index].MCKFREQ; + info->sample_rate = 32000000 + / ratios[ratio_index].divisor / mclks[mclk_index].divisor; + info->abserr = fabsf(1.0f * target_sample_rate - info->sample_rate) + / target_sample_rate; +} + +void choose_i2s_clocking(audiobusio_i2sout_obj_t *self, uint32_t sample_rate) { + struct frequency_info best = {0, 0, 0, 1.0}; + for (size_t ri=0; riCONFIG.SWIDTH == I2S_CONFIG_SWIDTH_SWIDTH_16Bit + && !ratios[ri].can_16bit) { + continue; + } + + for (size_t mi=0; miCONFIG.RATIO = best.RATIO; + NRF_I2S->CONFIG.MCKFREQ = best.MCKFREQ; + self->sample_rate = best.sample_rate; +} + +static void i2s_buffer_fill(audiobusio_i2sout_obj_t* self) { + void *buffer = self->buffers[self->next_buffer]; + NRF_I2S->TXD.PTR = (uintptr_t)buffer; + self->next_buffer = !self->next_buffer; + size_t bytesleft = self->buffer_length; + + while (!self->paused && !self->stopping && bytesleft) { + if (self->sample_data == self->sample_end) { + uint32_t sample_buffer_length; + audioio_get_buffer_result_t get_buffer_result = + audiosample_get_buffer(self->sample, false, 0, + &self->sample_data, &sample_buffer_length); + self->sample_end = self->sample_data + sample_buffer_length; + if (get_buffer_result == GET_BUFFER_DONE) { + if (self->loop) { + audiosample_reset_buffer(self->sample, false, 0); + } else { + self->stopping = true; + break; + } + } + if (get_buffer_result == GET_BUFFER_ERROR || sample_buffer_length == 0) { + self->stopping = true; + break; + } + } + uint16_t bytecount = MIN(bytesleft, (size_t)(self->sample_end - self->sample_data)); + if (self->samples_signed) { + memcpy(buffer, self->sample_data, bytecount); + } else if (self->bytes_per_sample == 2) { + uint16_t *bp = (uint16_t*)buffer; + uint16_t *be = (uint16_t*)(buffer + bytecount); + uint16_t *sp = (uint16_t*)self->sample_data; + for (; bp != be; bp++) { + *bp++ = *sp++ + 0x8000; + } + } else { + uint8_t *bp = (uint8_t*)buffer; + uint8_t *be = (uint8_t*)(buffer + bytecount); + uint8_t *sp = (uint8_t*)self->sample_data; + for (; bp != be; bp++) { + *bp++ = *sp++ + 0x80; + } + } + buffer += bytecount; + self->sample_data += bytecount; + bytesleft -= bytecount; + } + + // Find the last frame of real audio data and replicate its samples until + // you have 32 bits worth, which is the fundamental unit of nRF I2S DMA + if (self->bytes_per_sample == 1 && self->channel_count == 1) { + // For 8-bit mono, 4 copies of the final sample are required + self->hold_value = 0x01010101 * *(uint8_t*)(buffer-1); + } else if (self->bytes_per_sample == 2 && self->channel_count == 2) { + // For 16-bit stereo, 1 copy of the final sample is required + self->hold_value = *(uint32_t*)(buffer-4); + } else { + // For 8-bit stereo and 16-bit mono, 2 copies of the final sample are required + self->hold_value = 0x00010001 * *(uint16_t*)(buffer-2); + } + + // Emulate pausing and stopping by filling the DMA buffer with copies of + // the last sample. This includes the case where this iteration of + // i2s_buffer_fill exhausted a non-looping sample. + if (self->paused || self->stopping) { + if (self->stopping) { + NRF_I2S->TASKS_STOP = 1; + self->playing = false; + } + uint32_t *bp = (uint32_t*)buffer; + uint32_t *be = (uint32_t*)(buffer + bytesleft); + for (; bp != be; ) + *bp++ = self->hold_value; + return; + } +} + +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) { + if (instance) + mp_raise_RuntimeError(translate("Device in use")); + instance = self; + + claim_pin(bit_clock); + claim_pin(word_select); + claim_pin(data); + + NRF_I2S->PSEL.SCK = self->bit_clock_pin_number = bit_clock->number; + NRF_I2S->PSEL.LRCK = self->word_select_pin_number = word_select->number; + NRF_I2S->PSEL.SDOUT = self->data_pin_number = data->number; + + NRF_I2S->CONFIG.MODE = I2S_CONFIG_MODE_MODE_Master; + NRF_I2S->CONFIG.RXEN = I2S_CONFIG_RXEN_RXEN_Disabled; + NRF_I2S->CONFIG.TXEN = I2S_CONFIG_TXEN_TXEN_Enabled; + NRF_I2S->CONFIG.MCKEN = I2S_CONFIG_MCKEN_MCKEN_Enabled; + NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_16Bit; + + NRF_I2S->CONFIG.ALIGN = I2S_CONFIG_ALIGN_ALIGN_Left; + NRF_I2S->CONFIG.FORMAT = left_justified ? I2S_CONFIG_FORMAT_FORMAT_Aligned + : I2S_CONFIG_FORMAT_FORMAT_I2S; +} + +bool common_hal_audiobusio_i2sout_deinited(audiobusio_i2sout_obj_t* self) { + return self->data_pin_number == 0xff; +} + +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_pin_number); + self->bit_clock_pin_number = 0xff; + reset_pin_number(self->word_select_pin_number); + self->word_select_pin_number = 0xff; + reset_pin_number(self->data_pin_number); + self->data_pin_number = 0xff; + instance = NULL; +} + +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); + } + + self->sample = sample; + self->loop = loop; + uint32_t sample_rate = audiosample_sample_rate(sample); + self->bytes_per_sample = audiosample_bits_per_sample(sample) / 8; + + uint32_t max_buffer_length; + bool single_buffer, samples_signed; + audiosample_get_buffer_structure(sample, /* single channel */ false, + &single_buffer, &samples_signed, &max_buffer_length, + &self->channel_count); + self->single_buffer = single_buffer; + self->samples_signed = samples_signed; + + choose_i2s_clocking(self, sample_rate); + /* Allocate buffers based on a maximum duration + * This duration was chosen empirically based on what would + * cause os.listdir('') to cause stuttering. It seems like a + * rather long time. + */ + enum { buffer_length_ms = 16 }; + self->buffer_length = sample_rate * buffer_length_ms + * self->bytes_per_sample * self->channel_count / 1000; + self->buffer_length = (self->buffer_length + 3) & ~3; + self->buffers[0] = m_malloc(self->buffer_length, false); + self->buffers[1] = m_malloc(self->buffer_length, false); + + + audiosample_reset_buffer(self->sample, false, 0); + + self->next_buffer = 0; + self->sample_data = self->sample_end = 0; + self->playing = true; + self->paused = false; + self->stopping = false; + i2s_buffer_fill(self); + + NRF_I2S->CONFIG.CHANNELS = self->channel_count == 1 ? I2S_CONFIG_CHANNELS_CHANNELS_Left : I2S_CONFIG_CHANNELS_CHANNELS_Stereo; + + + NRF_I2S->RXTXD.MAXCNT = self->buffer_length / 4; + NRF_I2S->ENABLE = I2S_ENABLE_ENABLE_Enabled; + + NRF_I2S->TASKS_START = 1; + + i2s_background(); +} + +void common_hal_audiobusio_i2sout_pause(audiobusio_i2sout_obj_t* self) { + self->paused = true; +} + +void common_hal_audiobusio_i2sout_resume(audiobusio_i2sout_obj_t* self) { + self->paused = false; +} + +bool common_hal_audiobusio_i2sout_get_paused(audiobusio_i2sout_obj_t* self) { + return self->paused; +} + +void common_hal_audiobusio_i2sout_stop(audiobusio_i2sout_obj_t* self) { + NRF_I2S->TASKS_STOP = 1; + self->stopping = true; +} + +bool common_hal_audiobusio_i2sout_get_playing(audiobusio_i2sout_obj_t* self) { + if (NRF_I2S->EVENTS_STOPPED) { + self->playing = false; + NRF_I2S->EVENTS_STOPPED = 0; + } + return self->playing; +} + +void i2s_background(void) { + if (NRF_I2S->EVENTS_TXPTRUPD) { + NRF_I2S->EVENTS_TXPTRUPD = 0; + if (instance) { + i2s_buffer_fill(instance); + } else { + NRF_I2S->TASKS_STOP = 1; + } + } +} + +void i2s_reset(void) { + NRF_I2S->TASKS_STOP = 1; + NRF_I2S->ENABLE = I2S_ENABLE_ENABLE_Disabled; + NRF_I2S->PSEL.MCK = 0xFFFFFFFF; + NRF_I2S->PSEL.SCK = 0xFFFFFFFF; + NRF_I2S->PSEL.LRCK = 0xFFFFFFFF; + NRF_I2S->PSEL.SDOUT = 0xFFFFFFFF; + NRF_I2S->PSEL.SDIN = 0xFFFFFFFF; + instance = NULL; +} diff --git a/ports/nrf/common-hal/audiobusio/I2SOut.h b/ports/nrf/common-hal/audiobusio/I2SOut.h new file mode 100644 index 0000000000..16047e0ab8 --- /dev/null +++ b/ports/nrf/common-hal/audiobusio/I2SOut.h @@ -0,0 +1,63 @@ +/* + * 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; + + mp_obj_t *sample; + uint8_t *buffers[2]; + uint8_t *sample_data, *sample_end; + + uint16_t buffer_length; + uint16_t sample_rate; + uint32_t hold_value; + + uint8_t next_buffer; + uint8_t bit_clock_pin_number; + uint8_t word_select_pin_number; + uint8_t data_pin_number; + + uint8_t channel_count; + uint8_t bytes_per_sample; + + bool left_justified : 1; + bool playing : 1; + bool stopping : 1; + bool paused : 1; + bool loop : 1; + bool samples_signed : 1; + bool single_buffer : 1; +} audiobusio_i2sout_obj_t; + +void i2s_reset(void); +void i2s_background(void); + +#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 0000000000..a7f9c9d747 --- /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 0000000000..d921e42ff3 --- /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 0000000000..e69de29bb2 diff --git a/ports/nrf/common-hal/audiopwmio/PWMAudioOut.c b/ports/nrf/common-hal/audiopwmio/PWMAudioOut.c new file mode 100644 index 0000000000..0321b751ca --- /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 0000000000..8deff5d340 --- /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 0000000000..e69de29bb2 diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c deleted file mode 100644 index 17417a5e64..0000000000 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * 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 -#include - -#include "ble_drv.h" -#include "ble_gatts.h" -#include "nrf_soc.h" - -#include "py/runtime.h" -#include "common-hal/bleio/__init__.h" -#include "common-hal/bleio/Characteristic.h" - -STATIC volatile bleio_characteristic_obj_t *m_read_characteristic; - -STATIC uint16_t get_cccd(bleio_characteristic_obj_t *characteristic) { - const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); - 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, characteristic->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 gatts_read(bleio_characteristic_obj_t *characteristic) { - // This 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. - const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); - - 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. - - uint32_t err_code = sd_ble_gatts_value_get(conn_handle, characteristic->handle, &gatts_value); - if (err_code == NRF_SUCCESS) { - characteristic->value_data = mp_obj_new_bytearray_of_zeros(gatts_value.len); - mp_get_buffer_raise(characteristic->value_data, &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, characteristic->handle, &gatts_value); - } - - if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg_varg(translate("Failed to read gatts value, err 0x%04x"), err_code); - } -} - - -STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { - // This might be BLE_CONN_HANDLE_INVALID if we're not conected, but that's OK, because - // we can still read and write the local value. - const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); - - 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, characteristic->handle, &gatts_value); - if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg_varg(translate("Failed to write gatts value, err 0x%04x"), err_code); - } -} - -STATIC void gatts_notify_indicate(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo, uint16_t hvx_type) { - uint16_t hvx_len = bufinfo->len; - - ble_gatts_hvx_params_t hvx_params = { - .handle = characteristic->handle, - .type = hvx_type, - .offset = 0, - .p_len = &hvx_len, - .p_data = bufinfo->buf, - }; - - const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); - - 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) { - MICROPY_VM_HOOK_LOOP; - 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 check_connected(uint16_t conn_handle) { - if (conn_handle == BLE_CONN_HANDLE_INVALID) { - mp_raise_OSError_msg(translate("Not connected")); - } -} - -STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) { - const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); - check_connected(conn_handle); - - m_read_characteristic = 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) { - MICROPY_VM_HOOK_LOOP; - } -} - -STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { - const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); - check_connected(conn_handle); - - ble_gattc_write_params_t write_params = { - .write_op = characteristic->props.write_no_response ? BLE_GATT_OP_WRITE_CMD : BLE_GATT_OP_WRITE_REQ, - .handle = characteristic->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); - } - -} - -STATIC void characteristic_on_ble_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; - m_read_characteristic->value_data = mp_obj_new_bytearray(response->len, response->data); - // Indicate to busy-wait loop that we've read the characteristic. - m_read_characteristic = NULL; - break; - } - - // For debugging. - default: - // mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id); - break; - } - -} - -void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, mp_obj_list_t *descriptor_list) { - self->service = mp_const_none; - self->uuid = uuid; - self->value_data = mp_const_none; - self->props = props; - self->descriptor_list = descriptor_list; - self->handle = BLE_GATT_HANDLE_INVALID; - - ble_drv_add_event_handler(characteristic_on_ble_evt, self); -} - -mp_obj_list_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self) { - return self->descriptor_list; -} - -mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self) { - switch (common_hal_bleio_device_get_gatt_role(self->service->device)) { - case GATT_ROLE_CLIENT: - gattc_read(self); - break; - - case GATT_ROLE_SERVER: - gatts_read(self); - break; - - default: - mp_raise_RuntimeError(translate("bad GATT role")); - break; - } - - return self->value_data; -} - -void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { - bool sent = false; - uint16_t cccd = 0; - - switch (common_hal_bleio_device_get_gatt_role(self->service->device)) { - case GATT_ROLE_SERVER: - if (self->props.notify || self->props.indicate) { - cccd = get_cccd(self); - } - // It's possible that both notify and indicate are set. - if (self->props.notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) { - gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_NOTIFICATION); - sent = true; - } - if (self->props.indicate && (cccd & BLE_GATT_HVX_INDICATION)) { - gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_INDICATION); - sent = true; - } - if (!sent) { - gatts_write(self, bufinfo); - } - break; - - case GATT_ROLE_CLIENT: - gattc_write(self, bufinfo); - break; - - default: - mp_raise_RuntimeError(translate("bad GATT role")); - break; - } -} - - -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_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_device_get_gatt_role(self->service->device) != GATT_ROLE_CLIENT) { - mp_raise_ValueError(translate("Can't set CCCD for local Characteristic")); - } - - uint16_t cccd_value = - (notify ? BLE_GATT_HVX_NOTIFICATION : 0) | - (indicate ? BLE_GATT_HVX_INDICATION : 0); - - const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device); - check_connected(conn_handle); - - - 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. - MICROPY_VM_HOOK_LOOP; - 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/Service.c b/ports/nrf/common-hal/bleio/Service.c deleted file mode 100644 index b6fcde8277..0000000000 --- a/ports/nrf/common-hal/bleio/Service.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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 "common-hal/bleio/Characteristic.h" -#include "shared-bindings/bleio/Characteristic.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_uuid_obj_t *uuid, mp_obj_list_t *characteristic_list, bool is_secondary) { - self->device = mp_const_none; - self->handle = 0xFFFF; - self->uuid = uuid; - self->characteristic_list = characteristic_list; - self->is_secondary = is_secondary; - - for (size_t characteristic_idx = 0; characteristic_idx < characteristic_list->len; ++characteristic_idx) { - bleio_characteristic_obj_t *characteristic = - MP_OBJ_TO_PTR(characteristic_list->items[characteristic_idx]); - characteristic->service = self; - } - -} - -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_secondary(bleio_service_obj_t *self) { - return self->is_secondary; -} - -// Call this after the Service has been added to the Peripheral. -void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self) { - // Add all the characteristics. - for (size_t characteristic_idx = 0; characteristic_idx < self->characteristic_list->len; ++characteristic_idx) { - bleio_characteristic_obj_t *characteristic = - MP_OBJ_TO_PTR(self->characteristic_list->items[characteristic_idx]); - - ble_gatts_char_md_t char_md = { - .char_props.broadcast = characteristic->props.broadcast, - .char_props.read = characteristic->props.read, - .char_props.write_wo_resp = characteristic->props.write_no_response, - .char_props.write = characteristic->props.write, - .char_props.notify = characteristic->props.notify, - .char_props.indicate = characteristic->props.indicate, - }; - - ble_gatts_attr_md_t cccd_md = { - .vloc = BLE_GATTS_VLOC_STACK, - }; - - if (char_md.char_props.notify || char_md.char_props.indicate) { - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); - - char_md.p_cccd_md = &cccd_md; - } - - ble_uuid_t uuid; - bleio_uuid_convert_to_nrf_ble_uuid(characteristic->uuid, &uuid); - - ble_gatts_attr_md_t attr_md = { - .vloc = BLE_GATTS_VLOC_STACK, - .vlen = 1, - }; - - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); - - ble_gatts_attr_t attr_char_value = { - .p_uuid = &uuid, - .p_attr_md = &attr_md, - .init_len = sizeof(uint8_t), - .max_len = GATT_MAX_DATA_LENGTH, - }; - - ble_gatts_char_handles_t handles; - - uint32_t err_code; - err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &attr_char_value, &handles); - if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg_varg(translate("Failed to add characteristic, err 0x%04x"), err_code); - } - - if (characteristic->handle != BLE_GATT_HANDLE_INVALID) { - mp_raise_ValueError(translate("Characteristic already in use by another Service.")); - } - - characteristic->user_desc_handle = handles.user_desc_handle; - characteristic->cccd_handle = handles.cccd_handle; - characteristic->sccd_handle = handles.sccd_handle; - characteristic->handle = handles.value_handle; - } -} diff --git a/ports/nrf/common-hal/bleio/__init__.c b/ports/nrf/common-hal/bleio/__init__.c deleted file mode 100644 index 2dba5780c1..0000000000 --- a/ports/nrf/common-hal/bleio/__init__.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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 "shared-bindings/bleio/__init__.h" -#include "shared-bindings/bleio/Adapter.h" -#include "shared-bindings/bleio/Central.h" -#include "shared-bindings/bleio/Peripheral.h" -#include "common-hal/bleio/__init__.h" - -// 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, - }, -}; - -gatt_role_t common_hal_bleio_device_get_gatt_role(mp_obj_t device) { - if (MP_OBJ_IS_TYPE(device, &bleio_peripheral_type)) { - return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->gatt_role; - } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) { - return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->gatt_role; - } else { - return GATT_ROLE_NONE; - } -} - -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 0; - } -} diff --git a/ports/nrf/common-hal/busio/I2C.c b/ports/nrf/common-hal/busio/I2C.c index 538c87f2da..71835d16ad 100644 --- a/ports/nrf/common-hal/busio/I2C.c +++ b/ports/nrf/common-hal/busio/I2C.c @@ -57,13 +57,30 @@ STATIC twim_peripheral_t twim_peripherals[] = { #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: diff --git a/ports/nrf/common-hal/busio/SPI.c b/ports/nrf/common-hal/busio/SPI.c index 6ab6d9493b..5f1aac1934 100644 --- a/ports/nrf/common-hal/busio/SPI.c +++ b/ports/nrf/common-hal/busio/SPI.c @@ -61,7 +61,7 @@ STATIC spim_peripheral_t spim_peripherals[] = { #endif }; -STATIC bool never_reset[4]; +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++) { diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index b9e9e55387..54a66ddbe7 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -235,13 +235,11 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t // Wait for all bytes received or timeout while ( (ringbuf_count(&self->rbuf) < len) && (ticks_ms - start_ticks < self->timeout_ms) ) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP ; + RUN_BACKGROUND_TASKS; // Allow user to break out of a timeout with a KeyboardInterrupt. if ( mp_hal_is_interrupted() ) { return 0; } -#endif } // prevent conflict with uart irq @@ -271,9 +269,7 @@ size_t common_hal_busio_uart_write (busio_uart_obj_t *self, const uint8_t *data, // Wait for on-going transfer to complete while ( nrfx_uarte_tx_in_progress(self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif + RUN_BACKGROUND_TASKS; } // Time up @@ -295,9 +291,7 @@ size_t common_hal_busio_uart_write (busio_uart_obj_t *self, const uint8_t *data, (*errcode) = 0; while ( nrfx_uarte_tx_in_progress(self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif + RUN_BACKGROUND_TASKS; } if ( !nrfx_is_in_ram(data) ) { diff --git a/ports/nrf/common-hal/displayio/ParallelBus.c b/ports/nrf/common-hal/displayio/ParallelBus.c index 42231be527..be4b28a6e6 100644 --- a/ports/nrf/common-hal/displayio/ParallelBus.c +++ b/ports/nrf/common-hal/displayio/ParallelBus.c @@ -31,6 +31,7 @@ #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" @@ -70,10 +71,6 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel 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 = &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); - 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); @@ -93,11 +90,19 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel } 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); - never_reset_pin_number(reset->number); for (uint8_t i = 0; i < 8; i++) { never_reset_pin_number(data_pin + i); } @@ -115,15 +120,32 @@ void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self) 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, bool command, uint8_t *data, uint32_t data_length) { +// 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, !command); + 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; diff --git a/ports/nrf/common-hal/microcontroller/Pin.c b/ports/nrf/common-hal/microcontroller/Pin.c index b9c0ecacab..3cee784b63 100644 --- a/ports/nrf/common-hal/microcontroller/Pin.c +++ b/ports/nrf/common-hal/microcontroller/Pin.c @@ -105,7 +105,7 @@ void reset_pin_number(uint8_t pin_number) { #ifdef SPEAKER_ENABLE_PIN if (pin_number == SPEAKER_ENABLE_PIN->number) { speaker_enable_in_use = false; - common_hal_digitalio_digitalinout_switch_to_output( + 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); } diff --git a/ports/nrf/common-hal/microcontroller/__init__.c b/ports/nrf/common-hal/microcontroller/__init__.c index ab7b5d5d68..a6b1c4ba3b 100644 --- a/ports/nrf/common-hal/microcontroller/__init__.c +++ b/ports/nrf/common-hal/microcontroller/__init__.c @@ -37,6 +37,7 @@ #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 @@ -52,7 +53,13 @@ void common_hal_mcu_enable_interrupts() { } void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { - // TODO: see atmel-samd for functionality + 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) { diff --git a/ports/nrf/common-hal/neopixel_write/__init__.c b/ports/nrf/common-hal/neopixel_write/__init__.c index 78e0038e8f..3b67778a62 100644 --- a/ports/nrf/common-hal/neopixel_write/__init__.c +++ b/ports/nrf/common-hal/neopixel_write/__init__.c @@ -200,9 +200,7 @@ void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout // But we have to wait for the flag to be set. while ( !nrf_pwm_event_check(pwm, NRF_PWM_EVENT_SEQEND0) ) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif + RUN_BACKGROUND_TASKS; } // Before leave we clear the flag for the event. diff --git a/ports/nrf/common-hal/pulseio/PWMOut.c b/ports/nrf/common-hal/pulseio/PWMOut.c index 5233c9adc6..6921091f8a 100644 --- a/ports/nrf/common-hal/pulseio/PWMOut.c +++ b/ports/nrf/common-hal/pulseio/PWMOut.c @@ -57,6 +57,12 @@ 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]; @@ -133,6 +139,57 @@ bool convert_frequency(uint32_t frequency, uint16_t *countertop, nrf_pwm_clk_t * 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, @@ -148,48 +205,16 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, return PWMOUT_INVALID_FREQUENCY; } - self->pwm = NULL; - self->channel = CHANNELS_PER_PWM; // out-of-range value. + int8_t channel; bool pwm_already_in_use; - NRF_PWM_Type* pwm; - size_t pwm_index = 0; - for (; pwm_index < MP_ARRAY_SIZE(pwms); pwm_index++) { - pwm = pwms[pwm_index]; - 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. - self->pwm = pwm; - self->channel = chan; - break; - } - } - // Did we find a channel? If not, loop and check the next pwm. - if (self->pwm != NULL) { - break; - } - } - } else { - // PWM not yet in use, so we can start to use it. Use channel 0. - self->pwm = pwm; - self->channel = 0; - break; - } - } + 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); @@ -200,17 +225,17 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, nrf_gpio_cfg_output(self->pin_number); // disable before mapping pin channel - nrf_pwm_disable(pwm); + nrf_pwm_disable(self->pwm); if (!pwm_already_in_use) { - reset_single_pwmout(pwm_index); - nrf_pwm_configure(pwm, base_clock, NRF_PWM_MODE_UP, countertop); + 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. - pwm->PSEL.OUT[self->channel] = pin->number; + self->pwm->PSEL.OUT[self->channel] = pin->number; - nrf_pwm_enable(pwm); + nrf_pwm_enable(self->pwm); common_hal_pulseio_pwmout_set_duty_cycle(self, duty); return PWMOUT_OK; @@ -230,17 +255,10 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { NRF_PWM_Type* pwm = self->pwm; self->pwm = NULL; - // Disconnect pin from channel. - pwm->PSEL.OUT[self->channel] = 0xFFFFFFFF; + pwmout_free_channel(pwm, self->channel); - for(int i=0; i < CHANNELS_PER_PWM; i++) { - if (self->pwm->PSEL.OUT[i] != 0xFFFFFFFF) { - // Some channel is still being used, so don't disable. - return; - } - } - - nrf_pwm_disable(pwm); + reset_pin_number(self->pin_number); + self->pin_number = NO_PIN; } void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty_cycle) { diff --git a/ports/nrf/common-hal/pulseio/PWMOut.h b/ports/nrf/common-hal/pulseio/PWMOut.h index a4e58dc1a5..b6798cb685 100644 --- a/ports/nrf/common-hal/pulseio/PWMOut.h +++ b/ports/nrf/common-hal/pulseio/PWMOut.h @@ -41,5 +41,8 @@ typedef struct { } 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/PulseOut.c b/ports/nrf/common-hal/pulseio/PulseOut.c index be5deca9fb..d0433247ac 100644 --- a/ports/nrf/common-hal/pulseio/PulseOut.c +++ b/ports/nrf/common-hal/pulseio/PulseOut.c @@ -155,9 +155,7 @@ void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pu while(pulse_array_index < length) { // Do other things while we wait. The interrupts will handle sending the // signal. - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif + RUN_BACKGROUND_TASKS; } nrfx_timer_disable(timer); diff --git a/ports/nrf/device/nrf52/startup_nrf52840.c b/ports/nrf/device/nrf52/startup_nrf52840.c index 30634a1b54..8e1c360128 100644 --- a/ports/nrf/device/nrf52/startup_nrf52840.c +++ b/ports/nrf/device/nrf52/startup_nrf52840.c @@ -116,7 +116,7 @@ void CRYPTOCELL_IRQHandler (void) __attribute__ ((weak, alias("Default_Han void SPIM3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void PWM3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); -const func __Vectors[] __attribute__ ((section(".isr_vector"))) = { +const func __Vectors[] __attribute__ ((used, section(".isr_vector"))) = { (func)&_estack, Reset_Handler, NMI_Handler, diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index 5ed521e859..0b755a156b 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -53,6 +53,11 @@ #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; \ diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk index 83166708a6..02bde3effa 100644 --- a/ports/nrf/mpconfigport.mk +++ b/ports/nrf/mpconfigport.mk @@ -10,11 +10,12 @@ USB_SERIAL_NUMBER_LENGTH = 16 # All nRF ports have longints. LONGINT_IMPL = MPZ -# No DAC, so no regular audio. +# Audio via PWM +CIRCUITPY_AUDIOCORE = 1 CIRCUITPY_AUDIOIO = 0 - -# No I2S yet. -CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_AUDIOMIXER = 1 +CIRCUITPY_AUDIOPWMIO = 1 +CIRCUITPY_AUDIOBUSIO = 1 # No I2CSlave implementation CIRCUITPY_I2CSLAVE = 0 diff --git a/ports/nrf/mphalport.c b/ports/nrf/mphalport.c index 7d9463d0be..bcd9fb1145 100644 --- a/ports/nrf/mphalport.c +++ b/ports/nrf/mphalport.c @@ -39,9 +39,7 @@ 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 + 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))) { diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h index d51739fac2..8fa6721e2c 100644 --- a/ports/nrf/nrfx_config.h +++ b/ports/nrf/nrfx_config.h @@ -78,16 +78,17 @@ // 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 NRFX_TIMER3 +#ifdef NRF_TIMER3 #define NRFX_TIMER3_ENABLED 1 #else #define NRFX_TIMER3_ENABLED 0 #endif -#ifdef NRFX_TIMER4 +#ifdef NRF_TIMER4 #define NRFX_TIMER4_ENABLED 1 #else #define NRFX_TIMER4_ENABLED 0 diff --git a/ports/nrf/peripherals/nrf/clocks.c b/ports/nrf/peripherals/nrf/clocks.c index 4acb878db9..269365cc94 100644 --- a/ports/nrf/peripherals/nrf/clocks.c +++ b/ports/nrf/peripherals/nrf/clocks.c @@ -26,11 +26,15 @@ */ #include "nrfx.h" +#include "mpconfigport.h" void nrf_peripherals_clocks_init(void) { - // Set low-frequency clock source to be crystal. If there's a crystalless board, this will need to be - // generalized. + +#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. diff --git a/ports/nrf/peripherals/nrf/timers.c b/ports/nrf/peripherals/nrf/timers.c index 7f7a003d3b..88f3dd4681 100644 --- a/ports/nrf/peripherals/nrf/timers.c +++ b/ports/nrf/peripherals/nrf/timers.c @@ -36,7 +36,7 @@ STATIC nrfx_timer_t nrfx_timers[] = { #if NRFX_CHECK(NRFX_TIMER0_ENABLED) - // Note that TIMER0 is reserved for use by the SoftDevice, so it should not usually be 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) diff --git a/ports/nrf/sd_mutex.c b/ports/nrf/sd_mutex.c index 7682ffa623..b3162e6af9 100644 --- a/ports/nrf/sd_mutex.c +++ b/ports/nrf/sd_mutex.c @@ -37,9 +37,7 @@ void sd_mutex_acquire_check(nrf_mutex_t* p_mutex) { void sd_mutex_acquire_wait(nrf_mutex_t* p_mutex) { while (sd_mutex_acquire(p_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif + RUN_BACKGROUND_TASKS; } } diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index 8fbf75498f..e061c90b09 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -38,7 +38,7 @@ #include "shared-module/gamepad/__init__.h" #include "common-hal/microcontroller/Pin.h" -#include "common-hal/bleio/__init__.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" @@ -50,6 +50,14 @@ #include "shared-bindings/rtc/__init__.h" +#ifdef CIRCUITPY_AUDIOBUSIO +#include "common-hal/audiobusio/I2SOut.h" +#endif + +#ifdef CIRCUITPY_AUDIOPWMIO +#include "common-hal/audiopwmio/PWMAudioOut.h" +#endif + static void power_warning_handler(void) { reset_into_safe_mode(BROWNOUT); } @@ -94,6 +102,15 @@ void reset_port(void) { spi_reset(); uart_reset(); +#ifdef CIRCUITPY_AUDIOBUSIO + i2s_reset(); +#endif + +#ifdef CIRCUITPY_AUDIOPWMIO + audiopwmout_reset(); +#endif + + #if CIRCUITPY_PULSEIO pwmout_reset(); pulseout_reset(); diff --git a/ports/stm32f4/.gitignore b/ports/stm32f4/.gitignore new file mode 100644 index 0000000000..3080ece14d --- /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 0000000000..bef26d662a --- /dev/null +++ b/ports/stm32f4/Makefile @@ -0,0 +1,261 @@ +# 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_DEFS = -DMCU_PACKAGE=$(MCU_PACKAGE) -DUSE_HAL_DRIVER -DUSE_FULL_LL_DRIVER -D$(CMSIS_MCU) + +CFLAGS += $(INC) -Werror -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 += -DHSE_VALUE=8000000 -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 = \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_gpio.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_adc.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.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_hal_i2c.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.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 \ + boards/$(BOARD)/pins.c \ + peripherals/stm32f4/$(MCU_SUB_VARIANT)/pins.c \ + peripherals/stm32f4/$(MCU_SUB_VARIANT)/clocks.c \ + peripherals/stm32f4/$(MCU_SUB_VARIANT)/gpio.c \ + peripherals/stm32f4/$(MCU_SUB_VARIANT)/periph.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/synopsys/dcd_synopsys.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)) + + +ifneq ($(FROZEN_MPY_DIR),) +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)) +endif + +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 0000000000..a860c01ce4 --- /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 0000000000..8c18970434 --- /dev/null +++ b/ports/stm32f4/background.c @@ -0,0 +1,60 @@ +/* + * 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(); + + #if USB_AVAILABLE + usb_background(); + #endif + + #if CIRCUITPY_DISPLAYIO + displayio_background(); + #endif + running_background_tasks = false; + + assert_heap_ok(); +} diff --git a/shared-bindings/bleio/__init__.h b/ports/stm32f4/background.h similarity index 77% rename from shared-bindings/bleio/__init__.h rename to ports/stm32f4/background.h index 4aa6dd45b7..05a4f894a6 100644 --- a/shared-bindings/bleio/__init__.h +++ b/ports/stm32f4/background.h @@ -4,8 +4,6 @@ * 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 @@ -26,11 +24,12 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO___INIT___H +#ifndef MICROPY_INCLUDED_STM32F4_BACKGROUND_H +#define MICROPY_INCLUDED_STM32F4_BACKGROUND_H -#include "common-hal/bleio/Adapter.h" +#include -extern const super_adapter_obj_t common_hal_bleio_adapter_obj; +void background_tasks_reset(void); +void run_background_tasks(void); -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO___INIT___H +#endif // MICROPY_INCLUDED_STM32F4_BACKGROUND_H diff --git a/ports/stm32f4/boards/STM32F405.ld b/ports/stm32f4/boards/STM32F405.ld new file mode 100644 index 0000000000..7f7c917846 --- /dev/null +++ b/ports/stm32f4/boards/STM32F405.ld @@ -0,0 +1,108 @@ +/* + GNU linker script for STM32F405 via Micropython +*/ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K /* entire flash */ + FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */ + FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 48K /* sectors 1,2,3 are 16K */ + FLASH_TEXT (rx) : ORIGIN = 0x08010000, LENGTH = 960K /* sector 4 is 64K, sectors 5,6,7 are 128K */ + CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* produce a link error if there is not this amount of RAM for these sections */ +_minimum_stack_size = 2K; +_minimum_heap_size = 16K; + +/* Define tho top end of the stack. The stack is full descending so begins just + above last byte of RAM. Note that EABI requires the stack to be 8-byte + aligned for a call. */ +_estack = ORIGIN(RAM) + LENGTH(RAM); + +/* RAM extents for the garbage collector */ +_ram_start = ORIGIN(RAM); +_ram_end = ORIGIN(RAM) + LENGTH(RAM); + +ENTRY(Reset_Handler) + +/* define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + + /* This first flash block is 16K annd the isr vectors only take up + about 400 bytes. Micropython pads this with files, but this didn't + work with the size of Circuitpython's ff object. */ + + . = ALIGN(4); + } >FLASH_ISR + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text*) /* .text* sections (code) */ + *(.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 + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* 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 : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + *(.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 AT> FLASH_TEXT + + /* Uninitialized data section */ + .bss : + { + . = ALIGN(4); + _sbss = .; /* define a global symbol at bss start; used by startup code */ + *(.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); + . = . + _minimum_heap_size; + . = ALIGN(4); + } >RAM + + /* this just checks there is enough RAM for the stack */ + .stack : + { + . = ALIGN(4); + . = . + _minimum_stack_size; + . = ALIGN(4); + } >RAM + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/ports/stm32f4/boards/STM32F411VETx_FLASH.ld b/ports/stm32f4/boards/STM32F411VETx_FLASH.ld new file mode 100644 index 0000000000..ac1ba32408 --- /dev/null +++ b/ports/stm32f4/boards/STM32F411VETx_FLASH.ld @@ -0,0 +1,109 @@ +/* + GNU linker script for STM32F411 via Micropython +*/ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K /* entire flash */ + FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */ + FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 48K /* sectors 1,2,3 are 16K */ + FLASH_TEXT (rx) : ORIGIN = 0x08010000, LENGTH = 448K /* sector 4 is 64K, sectors 5,6,7 are 128K */ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* produce a link error if there is not this amount of RAM for these sections */ +_minimum_stack_size = 2K; +_minimum_heap_size = 16K; + +/* Define tho top end of the stack. The stack is full descending so begins just + above last byte of RAM. Note that EABI requires the stack to be 8-byte + aligned for a call. */ +_estack = ORIGIN(RAM) + LENGTH(RAM); + +/* RAM extents for the garbage collector */ +_ram_start = ORIGIN(RAM); +_ram_end = ORIGIN(RAM) + LENGTH(RAM); +_heap_start = _ebss; /* heap starts just after statically allocated memory */ +_heap_end = 0x2001c000; /* tunable */ + +ENTRY(Reset_Handler) + +/* define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + + /* This first flash block is 16K annd the isr vectors only take up + about 400 bytes. Micropython pads this with files, but this didn't + work with the size of Circuitpython's ff object. */ + + . = ALIGN(4); + } >FLASH_ISR + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text*) /* .text* sections (code) */ + *(.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 + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* 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 : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + *(.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 AT> FLASH_TEXT + + /* Uninitialized data section */ + .bss : + { + . = ALIGN(4); + _sbss = .; /* define a global symbol at bss start; used by startup code */ + *(.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); + . = . + _minimum_heap_size; + . = ALIGN(4); + } >RAM + + /* this just checks there is enough RAM for the stack */ + .stack : + { + . = ALIGN(4); + . = . + _minimum_stack_size; + . = ALIGN(4); + } >RAM + + .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 0000000000..e0586709e6 --- /dev/null +++ b/ports/stm32f4/boards/STM32F412ZGTx_FLASH.ld @@ -0,0 +1,105 @@ +/* + GNU linker script for STM32F412 +*/ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K /* entire flash */ + FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */ + FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 48K /* sectors 1,2,3 are 16K */ + FLASH_TEXT (rx) : ORIGIN = 0x08010000, LENGTH = 960K /* sector 4 is 64K, sectors 5,6,7 are 128K */ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K +} + +/* produce a link error if there is not this amount of RAM for these sections */ +_minimum_stack_size = 2K; +_minimum_heap_size = 16K; + +/* Define tho top end of the stack. The stack is full descending so begins just + above last byte of RAM. Note that EABI requires the stack to be 8-byte + aligned for a call. */ +_estack = ORIGIN(RAM) + LENGTH(RAM); + +/* RAM extents for the garbage collector */ +_ram_start = ORIGIN(RAM); +_ram_end = ORIGIN(RAM) + LENGTH(RAM); +_heap_start = _ebss; /* heap starts just after statically allocated memory */ +_heap_end = 0x20020000; /* tunable */ + +ENTRY(Reset_Handler) + +/* define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + + /* This first flash block is 16K annd the isr vectors only take up + about 400 bytes. Micropython pads this with files, but this didn't + work with the size of Circuitpython's ff object. */ + + . = ALIGN(4); + } >FLASH_ISR + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text*) /* .text* sections (code) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + . = ALIGN(4); + _etext = .; /* define a global symbol at end of code */ + } >FLASH_TEXT + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* 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 : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + *(.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 AT> FLASH_TEXT + + /* Uninitialized data section */ + .bss : + { + . = ALIGN(4); + _sbss = .; /* define a global symbol at bss start; used by startup code */ + *(.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); + . = . + _minimum_heap_size; + . = ALIGN(4); + } >RAM + + /* this just checks there is enough RAM for the stack */ + .stack : + { + . = ALIGN(4); + . = . + _minimum_stack_size; + . = ALIGN(4); + } >RAM + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/ports/stm32f4/boards/board.h b/ports/stm32f4/boards/board.h new file mode 100644 index 0000000000..22d9e99be0 --- /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/feather_f405/board.c b/ports/stm32f4/boards/feather_f405/board.c new file mode 100644 index 0000000000..4421970eef --- /dev/null +++ b/ports/stm32f4/boards/feather_f405/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/feather_f405/mpconfigboard.h b/ports/stm32f4/boards/feather_f405/mpconfigboard.h new file mode 100644 index 0000000000..831a17573a --- /dev/null +++ b/ports/stm32f4/boards/feather_f405/mpconfigboard.h @@ -0,0 +1,43 @@ +/* + * 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 "Feather F405" +#define MICROPY_HW_MCU_NAME "STM32F405RG" + +#define FLASH_SIZE (0x100000) +#define FLASH_PAGE_SIZE (0x4000) + +#define AUTORESET_DELAY_MS 500 +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000) + +// On-board flash +#define SPI_FLASH_MOSI_PIN &pin_PB05 +#define SPI_FLASH_MISO_PIN &pin_PB04 +#define SPI_FLASH_SCK_PIN &pin_PB03 +#define SPI_FLASH_CS_PIN &pin_PA15 diff --git a/ports/stm32f4/boards/feather_f405/mpconfigboard.mk b/ports/stm32f4/boards/feather_f405/mpconfigboard.mk new file mode 100644 index 0000000000..789dc0f05d --- /dev/null +++ b/ports/stm32f4/boards/feather_f405/mpconfigboard.mk @@ -0,0 +1,19 @@ +USB_VID = 0x239A +USB_PID = 0x805A +USB_PRODUCT = "Feather F405" +USB_MANUFACTURER = "Adafruit Industries LLC" +USB_DEVICES = "CDC,MSC" + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q16C +LONGINT_IMPL = MPZ + +MCU_SERIES = m4 +MCU_VARIANT = stm32f4 +MCU_SUB_VARIANT = stm32f405xx +MCU_PACKAGE = 64 +CMSIS_MCU = STM32F405xx +LD_FILE = boards/STM32F405.ld +TEXT0_ADDR = 0x08000000 +TEXT1_ADDR = 0x08010000 \ No newline at end of file diff --git a/ports/stm32f4/boards/feather_f405/pins.c b/ports/stm32f4/boards/feather_f405/pins.c new file mode 100644 index 0000000000..518ab6d2a0 --- /dev/null +++ b/ports/stm32f4/boards/feather_f405/pins.c @@ -0,0 +1,29 @@ +#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_PA04) }, + { 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_PA07) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PC04) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PC05) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PC07) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PC06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PC03) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PC02) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PC01) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB07) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB06) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB13) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB14) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB15) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB11) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/stm32f4/boards/feather_f405/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/feather_f405/stm32f4xx_hal_conf.h new file mode 100644 index 0000000000..019b03ca7a --- /dev/null +++ b/ports/stm32f4/boards/feather_f405/stm32f4xx_hal_conf.h @@ -0,0 +1,440 @@ +/** + ****************************************************************************** + * @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)12000000) /*!< 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)16000000) /*!< 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)40000) +#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)32768) /*!< 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/pyboard_v11/board.c b/ports/stm32f4/boards/pyboard_v11/board.c new file mode 100644 index 0000000000..4421970eef --- /dev/null +++ b/ports/stm32f4/boards/pyboard_v11/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/common-hal/bleio/Descriptor.c b/ports/stm32f4/boards/pyboard_v11/mpconfigboard.h similarity index 73% rename from ports/nrf/common-hal/bleio/Descriptor.c rename to ports/stm32f4/boards/pyboard_v11/mpconfigboard.h index 005af6eaae..e8441d665c 100644 --- a/ports/nrf/common-hal/bleio/Descriptor.c +++ b/ports/stm32f4/boards/pyboard_v11/mpconfigboard.h @@ -3,9 +3,8 @@ * * The MIT License (MIT) * - * Copyright (c) 2018 Dan Halbert for Adafruit Industries - * Copyright (c) 2018 Artur Pacholec * 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 @@ -26,17 +25,13 @@ * THE SOFTWARE. */ -#include "common-hal/bleio/Descriptor.h" -#include "shared-bindings/bleio/UUID.h" +//Micropython setup -void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid) { - self->uuid = uuid; -} +#define MICROPY_HW_BOARD_NAME "PyboardV1_1" +#define MICROPY_HW_MCU_NAME "STM32F405RG" -mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self) { - return self->handle; -} +#define FLASH_SIZE (0x100000) +#define FLASH_PAGE_SIZE (0x4000) -bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) { - return self->uuid; -} +#define AUTORESET_DELAY_MS 500 +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000) \ No newline at end of file diff --git a/ports/stm32f4/boards/pyboard_v11/mpconfigboard.mk b/ports/stm32f4/boards/pyboard_v11/mpconfigboard.mk new file mode 100644 index 0000000000..a01ff7923c --- /dev/null +++ b/ports/stm32f4/boards/pyboard_v11/mpconfigboard.mk @@ -0,0 +1,17 @@ +USB_VID = 0x239A +USB_PID = 0x805C +USB_PRODUCT = "Pyboard Version 1.1" +USB_MANUFACTURER = "George Robotic" +USB_DEVICES = "CDC,MSC" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE + +MCU_SERIES = m4 +MCU_VARIANT = stm32f4 +MCU_SUB_VARIANT = stm32f405xx +MCU_PACKAGE = 64 +CMSIS_MCU = STM32F405xx +LD_FILE = boards/STM32F405.ld +TEXT0_ADDR = 0x08000000 +TEXT1_ADDR = 0x08010000 diff --git a/ports/stm32f4/boards/pyboard_v11/pins.c b/ports/stm32f4/boards/pyboard_v11/pins.c new file mode 100644 index 0000000000..ccbb58ab9e --- /dev/null +++ b/ports/stm32f4/boards/pyboard_v11/pins.c @@ -0,0 +1,50 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_Y1), MP_ROM_PTR(&pin_PC06) }, + { MP_ROM_QSTR(MP_QSTR_Y2), MP_ROM_PTR(&pin_PC07) }, + { MP_ROM_QSTR(MP_QSTR_Y3), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_Y4), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_Y5), MP_ROM_PTR(&pin_PB12) }, + { MP_ROM_QSTR(MP_QSTR_Y6), MP_ROM_PTR(&pin_PB13) }, + { MP_ROM_QSTR(MP_QSTR_Y7), MP_ROM_PTR(&pin_PB14) }, + { MP_ROM_QSTR(MP_QSTR_Y8), MP_ROM_PTR(&pin_PB15) }, + { MP_ROM_QSTR(MP_QSTR_Y9), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_Y10), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_Y11), MP_ROM_PTR(&pin_PB00) }, + { MP_ROM_QSTR(MP_QSTR_Y12), MP_ROM_PTR(&pin_PB01) }, + + { MP_ROM_QSTR(MP_QSTR_X1), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_X2), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_X3), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_X4), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_X5), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_X6), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_X7), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_X8), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_X9), MP_ROM_PTR(&pin_PB06) }, + { MP_ROM_QSTR(MP_QSTR_X10), MP_ROM_PTR(&pin_PB07) }, + { MP_ROM_QSTR(MP_QSTR_X11), MP_ROM_PTR(&pin_PC04) }, + { MP_ROM_QSTR(MP_QSTR_X12), MP_ROM_PTR(&pin_PC05) }, + + { MP_ROM_QSTR(MP_QSTR_X17), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_X18), MP_ROM_PTR(&pin_PC13) }, + { MP_ROM_QSTR(MP_QSTR_X19), MP_ROM_PTR(&pin_PC00) }, + { MP_ROM_QSTR(MP_QSTR_X20), MP_ROM_PTR(&pin_PC01) }, + { MP_ROM_QSTR(MP_QSTR_X21), MP_ROM_PTR(&pin_PC02) }, + { MP_ROM_QSTR(MP_QSTR_X22), MP_ROM_PTR(&pin_PC03) }, + + { MP_ROM_QSTR(MP_QSTR_P2), MP_ROM_PTR(&pin_PB04) }, + { MP_ROM_QSTR(MP_QSTR_P3), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_P4), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_P5), MP_ROM_PTR(&pin_PA13) }, + + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_PB04) }, + { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_LED3), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_LED4), MP_ROM_PTR(&pin_PA13) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB06) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB07) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/stm32f4/boards/pyboard_v11/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/pyboard_v11/stm32f4xx_hal_conf.h new file mode 100644 index 0000000000..019b03ca7a --- /dev/null +++ b/ports/stm32f4/boards/pyboard_v11/stm32f4xx_hal_conf.h @@ -0,0 +1,440 @@ +/** + ****************************************************************************** + * @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)12000000) /*!< 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)16000000) /*!< 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)40000) +#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)32768) /*!< 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/startup_stm32f405xx.s b/ports/stm32f4/boards/startup_stm32f405xx.s new file mode 100644 index 0000000000..6b77655ca1 --- /dev/null +++ b/ports/stm32f4/boards/startup_stm32f405xx.s @@ -0,0 +1,516 @@ +/** + ****************************************************************************** + * @file startup_stm32f405xx.s + * @author MCD Application Team + * @brief STM32F405xx 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 FSMC_IRQHandler /* FSMC */ + .word SDIO_IRQHandler /* SDIO */ + .word TIM5_IRQHandler /* TIM5 */ + .word SPI3_IRQHandler /* SPI3 */ + .word UART4_IRQHandler /* UART4 */ + .word UART5_IRQHandler /* UART5 */ + .word TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */ + .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 0 /* Reserved */ + .word 0 /* Reserved */ + .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 OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */ + .word OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */ + .word OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */ + .word OTG_HS_IRQHandler /* USB OTG HS */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word HASH_RNG_IRQHandler /* Hash and Rng */ + .word FPU_IRQHandler /* FPU */ + + +/******************************************************************************* +* +* 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 FSMC_IRQHandler + .thumb_set FSMC_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 UART4_IRQHandler + .thumb_set UART4_IRQHandler,Default_Handler + + .weak UART5_IRQHandler + .thumb_set UART5_IRQHandler,Default_Handler + + .weak TIM6_DAC_IRQHandler + .thumb_set TIM6_DAC_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 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 OTG_HS_EP1_OUT_IRQHandler + .thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler + + .weak OTG_HS_EP1_IN_IRQHandler + .thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler + + .weak OTG_HS_WKUP_IRQHandler + .thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler + + .weak OTG_HS_IRQHandler + .thumb_set OTG_HS_IRQHandler,Default_Handler + + .weak HASH_RNG_IRQHandler + .thumb_set HASH_RNG_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + diff --git a/ports/stm32f4/boards/startup_stm32f411xe.s b/ports/stm32f4/boards/startup_stm32f411xe.s new file mode 100644 index 0000000000..3aac640cb2 --- /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 0000000000..8012207957 --- /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/stm32f411ve_discovery/board.c b/ports/stm32f4/boards/stm32f411ve_discovery/board.c new file mode 100644 index 0000000000..4421970eef --- /dev/null +++ b/ports/stm32f4/boards/stm32f411ve_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/stm32f411ve_discovery/mpconfigboard.h b/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h new file mode 100644 index 0000000000..d5491fe362 --- /dev/null +++ b/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h @@ -0,0 +1,40 @@ +/* + * 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 (0x80000) //512K +#define FLASH_PAGE_SIZE (0x4000) //16K + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x2000 - 0xC000) + +#define AUTORESET_DELAY_MS 500 diff --git a/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.mk b/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.mk new file mode 100644 index 0000000000..d6f369b6ea --- /dev/null +++ b/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.mk @@ -0,0 +1,17 @@ +USB_VID = 0x239A +USB_PID = 0x805E +USB_PRODUCT = "STM32F411VE Discovery Board - CPy" +USB_MANUFACTURER = "STMicroelectronics" +USB_DEVICES = "CDC,MSC" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE + +MCU_SERIES = m4 +MCU_VARIANT = stm32f4 +MCU_SUB_VARIANT = stm32f411xe +MCU_PACKAGE = 100 +CMSIS_MCU = STM32F411xE +LD_FILE = boards/STM32F411VETx_FLASH.ld +TEXT0_ADDR = 0x08000000 +TEXT1_ADDR = 0x08020000 \ No newline at end of file diff --git a/ports/stm32f4/boards/stm32f411ve_discovery/pins.c b/ports/stm32f4/boards/stm32f411ve_discovery/pins.c new file mode 100644 index 0000000000..673c412d51 --- /dev/null +++ b/ports/stm32f4/boards/stm32f411ve_discovery/pins.c @@ -0,0 +1,106 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + //P1 + { 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_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_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) }, + //P2 + { MP_ROM_QSTR(MP_QSTR_PC14), MP_ROM_PTR(&pin_PC14) }, + { MP_ROM_QSTR(MP_QSTR_PC15), MP_ROM_PTR(&pin_PC15) }, + { MP_ROM_QSTR(MP_QSTR_PC13), MP_ROM_PTR(&pin_PC13) }, + { MP_ROM_QSTR(MP_QSTR_PE06), MP_ROM_PTR(&pin_PE06) }, + { MP_ROM_QSTR(MP_QSTR_PE05), MP_ROM_PTR(&pin_PE05) }, + { MP_ROM_QSTR(MP_QSTR_PE04), MP_ROM_PTR(&pin_PE04) }, + { MP_ROM_QSTR(MP_QSTR_PE03), MP_ROM_PTR(&pin_PE03) }, + { MP_ROM_QSTR(MP_QSTR_PE02), MP_ROM_PTR(&pin_PE02) }, + { MP_ROM_QSTR(MP_QSTR_PE01), MP_ROM_PTR(&pin_PE01) }, + { MP_ROM_QSTR(MP_QSTR_PE00), MP_ROM_PTR(&pin_PE00) }, + { MP_ROM_QSTR(MP_QSTR_PB09), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_PB08), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_PB07), MP_ROM_PTR(&pin_PB07) }, + { MP_ROM_QSTR(MP_QSTR_PB06), MP_ROM_PTR(&pin_PB06) }, + { MP_ROM_QSTR(MP_QSTR_PB05), MP_ROM_PTR(&pin_PB05) }, + { MP_ROM_QSTR(MP_QSTR_PB04), MP_ROM_PTR(&pin_PB04) }, + { MP_ROM_QSTR(MP_QSTR_PB03), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_PD07), MP_ROM_PTR(&pin_PD07) }, + { MP_ROM_QSTR(MP_QSTR_PD06), MP_ROM_PTR(&pin_PD06) }, + { MP_ROM_QSTR(MP_QSTR_PD05), MP_ROM_PTR(&pin_PD05) }, + { MP_ROM_QSTR(MP_QSTR_PD04), MP_ROM_PTR(&pin_PD04) }, + { MP_ROM_QSTR(MP_QSTR_PD03), MP_ROM_PTR(&pin_PD03) }, + { MP_ROM_QSTR(MP_QSTR_PD02), MP_ROM_PTR(&pin_PD02) }, + { MP_ROM_QSTR(MP_QSTR_PD01), MP_ROM_PTR(&pin_PD01) }, + { MP_ROM_QSTR(MP_QSTR_PD00), MP_ROM_PTR(&pin_PD00) }, + { MP_ROM_QSTR(MP_QSTR_PC12), MP_ROM_PTR(&pin_PC12) }, + { MP_ROM_QSTR(MP_QSTR_PC11), MP_ROM_PTR(&pin_PC11) }, + { MP_ROM_QSTR(MP_QSTR_PC10), MP_ROM_PTR(&pin_PC10) }, + { MP_ROM_QSTR(MP_QSTR_PA15), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_PA14), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_PA13), MP_ROM_PTR(&pin_PA13) }, + { 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_PA08), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_PC09), MP_ROM_PTR(&pin_PC09) }, + { MP_ROM_QSTR(MP_QSTR_PC08), MP_ROM_PTR(&pin_PC08) }, + { MP_ROM_QSTR(MP_QSTR_PC07), MP_ROM_PTR(&pin_PC07) }, + { MP_ROM_QSTR(MP_QSTR_PC06), MP_ROM_PTR(&pin_PC06) }, + //ST LED names + { MP_ROM_QSTR(MP_QSTR_LD3), MP_ROM_PTR(&pin_PD13) }, + { MP_ROM_QSTR(MP_QSTR_LD4), MP_ROM_PTR(&pin_PD12) }, + { MP_ROM_QSTR(MP_QSTR_LD5), MP_ROM_PTR(&pin_PD14) }, + { MP_ROM_QSTR(MP_QSTR_LD6), MP_ROM_PTR(&pin_PD15) }, + //more useful LED names + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_PD13) }, + { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_PD12) }, + { MP_ROM_QSTR(MP_QSTR_LED3), MP_ROM_PTR(&pin_PD14) }, + { MP_ROM_QSTR(MP_QSTR_LED4), MP_ROM_PTR(&pin_PD15) }, + //AnalogIO names + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA05) }, + //actual LED names + { MP_ROM_QSTR(MP_QSTR_LED_ORANGE), MP_ROM_PTR(&pin_PD13) }, + { MP_ROM_QSTR(MP_QSTR_LED_GREEN), MP_ROM_PTR(&pin_PD12) }, + { MP_ROM_QSTR(MP_QSTR_LED_RED), MP_ROM_PTR(&pin_PD14) }, + { MP_ROM_QSTR(MP_QSTR_LED_BLUE), MP_ROM_PTR(&pin_PD15) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/stm32f4/boards/stm32f411ve_discovery/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/stm32f411ve_discovery/stm32f4xx_hal_conf.h new file mode 100644 index 0000000000..b244a69b5e --- /dev/null +++ b/ports/stm32f4/boards/stm32f411ve_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/board.c b/ports/stm32f4/boards/stm32f412zg_discovery/board.c new file mode 100644 index 0000000000..4421970eef --- /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 0000000000..ebee98f89f --- /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 AUTORESET_DELAY_MS 500 +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000) + diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk new file mode 100644 index 0000000000..509a244106 --- /dev/null +++ b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk @@ -0,0 +1,22 @@ +USB_VID = 0x239A +USB_PID = 0x8056 +USB_PRODUCT = "STM32F412ZG Discovery Board - CPy" +USB_MANUFACTURER = "STMicroelectronics" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE + +# QSPI_FLASH_FILESYSTEM = 1 +# EXTERNAL_FLASH_DEVICE_COUNT = 1 +# EXTERNAL_FLASH_DEVICES = N25Q128A +# LONGINT_IMPL = MPZ + +MCU_SERIES = m4 +MCU_VARIANT = stm32f4 +MCU_SUB_VARIANT = stm32f412zx +MCU_PACKAGE = 144 +CMSIS_MCU = STM32F412Zx +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 0000000000..a0b477a470 --- /dev/null +++ b/ports/stm32f4/boards/stm32f412zg_discovery/pins.c @@ -0,0 +1,92 @@ +#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_SCL), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB09) }, + { 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 0000000000..2ad0fee20b --- /dev/null +++ b/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h @@ -0,0 +1,438 @@ +/** + ****************************************************************************** + * @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_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/common-hal/analogio/AnalogIn.c b/ports/stm32f4/common-hal/analogio/AnalogIn.c new file mode 100644 index 0000000000..3ee3c4dbbb --- /dev/null +++ b/ports/stm32f4/common-hal/analogio/AnalogIn.c @@ -0,0 +1,129 @@ +/* + * 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 "common-hal/analogio/AnalogIn.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +#include "common-hal/microcontroller/Pin.h" + +#include "stm32f4xx_hal.h" +#include "stm32f4xx_ll_gpio.h" +#include "stm32f4xx_ll_adc.h" +#include "stm32f4xx_ll_bus.h" + +void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, + const mcu_pin_obj_t *pin) { + + // No ADC function on pin + if (pin->adc_unit == 0x00) { + mp_raise_ValueError(translate("Pin does not have ADC capabilities")); + } + // TODO: add ADC traits to structure? + + // Note that ADC2 is always bundled pin-to-pin with ADC1 if it exists, and used only + // for dual conversion. For this basic application it is never used. + LL_GPIO_SetPinMode(pin_port(pin->port), (uint32_t)pin_mask(pin->number), LL_GPIO_MODE_ANALOG); + if (pin->adc_unit & 0x01) { + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1); + } else if (pin->adc_unit == 0x04) { + #ifdef LL_APB2_GRP1_PERIPH_ADC3 + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC3); + #endif + } else { + mp_raise_ValueError(translate("Invalid ADC Unit value")); + } + 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; + } + reset_pin_number(self->pin->port,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. + ADC_TypeDef * ADCx; + + if(self->pin->adc_unit & 0x01) { + ADCx = ADC1; + } else if (self->pin->adc_unit == 0x04) { + #ifdef ADC3 + ADCx = ADC3; + #endif + } else { + mp_raise_ValueError(translate("Invalid ADC Unit value")); + } + + LL_GPIO_SetPinMode(pin_port(self->pin->port), (uint32_t)pin_mask(self->pin->number), LL_GPIO_MODE_ANALOG); + //LL_GPIO_PIN_0 + + //HAL Implementation + ADC_HandleTypeDef AdcHandle; + ADC_ChannelConfTypeDef sConfig; + + AdcHandle.Instance = ADCx; + AdcHandle.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; + AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; + AdcHandle.Init.ScanConvMode = DISABLE; + AdcHandle.Init.ContinuousConvMode = DISABLE; + AdcHandle.Init.DiscontinuousConvMode = DISABLE; + AdcHandle.Init.NbrOfDiscConversion = 0; + AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; + AdcHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START; + AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; + AdcHandle.Init.NbrOfConversion = 1; + AdcHandle.Init.DMAContinuousRequests = DISABLE; + AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; + HAL_ADC_Init(&AdcHandle); + + sConfig.Channel = (uint32_t)self->pin->adc_channel; //ADC_CHANNEL_0 <-normal iteration, not mask + sConfig.Rank = 1; + sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES; //Taken from micropython + HAL_ADC_ConfigChannel(&AdcHandle, &sConfig); + + HAL_ADC_Start(&AdcHandle); + HAL_ADC_PollForConversion(&AdcHandle,1); + uint16_t value = (uint16_t)HAL_ADC_GetValue(&AdcHandle); + HAL_ADC_Stop(&AdcHandle); + + // // 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/stm32f4/common-hal/analogio/AnalogIn.h b/ports/stm32f4/common-hal/analogio/AnalogIn.h new file mode 100644 index 0000000000..910092897e --- /dev/null +++ b/ports/stm32f4/common-hal/analogio/AnalogIn.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 + * 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_ANALOGIO_ANALOGIN_H +#define MICROPY_INCLUDED_STM32F4_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; + +static inline uint8_t stm32_adc_units(uint8_t adc_packed) { + return adc_packed >> 5; +} + +static inline uint8_t stm32_adc_channel(uint8_t adc_packed) { + return adc_packed & 0x1f; +} + +#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_ANALOGIO_ANALOGIN_H diff --git a/ports/stm32f4/common-hal/analogio/AnalogOut.c b/ports/stm32f4/common-hal/analogio/AnalogOut.c new file mode 100644 index 0000000000..a59a8b190e --- /dev/null +++ b/ports/stm32f4/common-hal/analogio/AnalogOut.c @@ -0,0 +1,57 @@ +/* + * 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/microcontroller/Pin.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_ValueError(translate("DAC not supported")); +} + +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) { + +} + +void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, + uint16_t value) { +} + +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. +} diff --git a/ports/stm32f4/common-hal/analogio/AnalogOut.h b/ports/stm32f4/common-hal/analogio/AnalogOut.h new file mode 100644 index 0000000000..f2952e9f96 --- /dev/null +++ b/ports/stm32f4/common-hal/analogio/AnalogOut.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_ATMEL_SAMD_COMMON_HAL_ANALOGIO_ANALOGOUT_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ANALOGIO_ANALOGOUT_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + 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/stm32f4/common-hal/analogio/__init__.c b/ports/stm32f4/common-hal/analogio/__init__.c new file mode 100644 index 0000000000..eea58c77d6 --- /dev/null +++ b/ports/stm32f4/common-hal/analogio/__init__.c @@ -0,0 +1 @@ +// No analogio module functions. diff --git a/ports/stm32f4/common-hal/board/__init__.c b/ports/stm32f4/common-hal/board/__init__.c new file mode 100644 index 0000000000..880033ed67 --- /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/busio/I2C.c b/ports/stm32f4/common-hal/busio/I2C.c new file mode 100644 index 0000000000..c2f5dbe0a2 --- /dev/null +++ b/ports/stm32f4/common-hal/busio/I2C.c @@ -0,0 +1,231 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * 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 "shared-bindings/busio/I2C.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "stm32f4xx_hal.h" + +#include "shared-bindings/microcontroller/__init__.h" +#include "supervisor/shared/translate.h" +#include "common-hal/microcontroller/Pin.h" + +STATIC bool reserved_i2c[3]; + +void i2c_reset(void) { + //Note: I2Cs are also forcibly reset in construct, due to silicon error + #ifdef I2C1 + reserved_i2c[0] = false; + __HAL_RCC_I2C1_CLK_DISABLE(); + #endif + #ifdef I2C2 + reserved_i2c[1] = false; + __HAL_RCC_I2C2_CLK_DISABLE(); + #endif + #ifdef I2C3 + reserved_i2c[3] = false; + __HAL_RCC_I2C3_CLK_DISABLE(); + #endif +} + +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) { + + //match pins to I2C objects + I2C_TypeDef * I2Cx; + + uint8_t sda_len = sizeof(mcu_i2c_sda_list)/sizeof(*mcu_i2c_sda_list); + uint8_t scl_len = sizeof(mcu_i2c_scl_list)/sizeof(*mcu_i2c_scl_list); + for(uint i=0; iscl = &mcu_i2c_scl_list[j]; + self->sda = &mcu_i2c_sda_list[i]; + break; + } + } + } + } + + //handle typedef selection, errors + if(self->sda!=NULL && self->scl!=NULL ) { + I2Cx = mcu_i2c_banks[self->sda->i2c_index-1]; + } else { + mp_raise_RuntimeError(translate("Invalid I2C pin selection")); + } + + if(reserved_i2c[self->sda->i2c_index-1]) { + mp_raise_RuntimeError(translate("Hardware busy, try alternative pins")); + } + + //Start GPIO for each pin + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = pin_mask(sda->number); + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = self->sda->altfn_index; + HAL_GPIO_Init(pin_port(sda->port), &GPIO_InitStruct); + + GPIO_InitStruct.Pin = pin_mask(scl->number); + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = self->scl->altfn_index; + HAL_GPIO_Init(pin_port(scl->port), &GPIO_InitStruct); + + //Fix for HAL error caused by soft reboot GPIO init SDA pin voltage drop. See Eratta. + //Must be in this exact spot or I2C will get stuck in infinite loop. + //TODO: See git issue #2172 + #ifdef I2C1 + __HAL_RCC_I2C1_FORCE_RESET(); + HAL_Delay(2); + __HAL_RCC_I2C1_RELEASE_RESET(); + #endif + #ifdef I2C2 + __HAL_RCC_I2C2_FORCE_RESET(); + HAL_Delay(2); + __HAL_RCC_I2C2_RELEASE_RESET(); + #endif + #ifdef I2C3 + __HAL_RCC_I2C3_FORCE_RESET(); + HAL_Delay(2); + __HAL_RCC_I2C3_RELEASE_RESET(); + #endif + + //Keep separate so above hack can be cleanly replaced + #ifdef I2C1 + if(I2Cx==I2C1) { + reserved_i2c[0] = true; + __HAL_RCC_I2C1_CLK_ENABLE(); + } + #endif + #ifdef I2C2 + if(I2Cx==I2C2) { + reserved_i2c[1] = true; + __HAL_RCC_I2C2_CLK_ENABLE(); + } + #endif + #ifdef I2C3 + if(I2Cx==I2C3) { + reserved_i2c[2] = true; + __HAL_RCC_I2C3_CLK_ENABLE(); + } + #endif + + self->handle.Instance = I2Cx; + self->handle.Init.ClockSpeed = 100000; + self->handle.Init.DutyCycle = I2C_DUTYCYCLE_2; + self->handle.Init.OwnAddress1 = 0; + self->handle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; + self->handle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; + self->handle.Init.OwnAddress2 = 0; + self->handle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; + self->handle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; + if(HAL_I2C_Init(&(self->handle)) != HAL_OK) { + mp_raise_RuntimeError(translate("I2C Init Error")); + } + claim_pin(sda); + claim_pin(scl); +} + +bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { + return self->sda->pin == mp_const_none; +} + +void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { + if (common_hal_busio_i2c_deinited(self)) { + return; + } + #ifdef I2C1 + if(self->handle.Instance==I2C1) { + reserved_i2c[0] = 0; + __HAL_RCC_I2C1_CLK_DISABLE(); + } + #endif + #ifdef I2C2 + if(self->handle.Instance==I2C2) { + reserved_i2c[1] = 0; + __HAL_RCC_I2C2_CLK_DISABLE(); + } + #endif + #ifdef I2C3 + if(self->handle.Instance==I2C3) { + reserved_i2c[3] = 0; + __HAL_RCC_I2C3_CLK_DISABLE(); + } + #endif + reset_pin_number(self->sda->pin->port,self->sda->pin->number); + reset_pin_number(self->scl->pin->port,self->scl->pin->number); + self->sda = mp_const_none; + self->scl = mp_const_none; +} + +bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { + return HAL_I2C_IsDeviceReady(&(self->handle), (uint16_t)(addr<<1),2,2) == HAL_OK; +} + +bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { + bool grabbed_lock = false; + + //Critical section code that may be required at some point. + // uint32_t store_primask = __get_PRIMASK(); + // __disable_irq(); + // __DMB(); + + if (!self->has_lock) { + grabbed_lock = true; + self->has_lock = true; + } + + // __DMB(); + // __set_PRIMASK(store_primask); + + 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) { + HAL_StatusTypeDef result = HAL_I2C_Master_Transmit(&(self->handle), (uint16_t)(addr<<1), (uint8_t *)data, (uint16_t)len, 500); + return result == HAL_OK ? 0 : MP_EIO; +} + +uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *data, size_t len) { + return HAL_I2C_Master_Receive(&(self->handle), (uint16_t)(addr<<1), data, (uint16_t)len, 500) == HAL_OK ? 0 : MP_EIO; +} diff --git a/ports/stm32f4/common-hal/busio/I2C.h b/ports/stm32f4/common-hal/busio/I2C.h new file mode 100644 index 0000000000..b5c891a98d --- /dev/null +++ b/ports/stm32f4/common-hal/busio/I2C.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 + * 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_BUSIO_I2C_H +#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_I2C_H + +#include "common-hal/microcontroller/Pin.h" + +#include "stm32f4xx_hal.h" +#include "stm32f4/periph.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + I2C_HandleTypeDef handle; + bool has_lock; + const mcu_i2c_scl_obj_t *scl; + const mcu_i2c_sda_obj_t *sda; +} busio_i2c_obj_t; + +void i2c_reset(void); + +#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_I2C_H diff --git a/ports/stm32f4/common-hal/busio/OneWire.h b/ports/stm32f4/common-hal/busio/OneWire.h new file mode 100644 index 0000000000..6e8c829793 --- /dev/null +++ b/ports/stm32f4/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_STM32F4_COMMON_HAL_BUSIO_ONEWIRE_H +#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_ONEWIRE_H + +// Use bitbangio. +#include "shared-module/busio/OneWire.h" + +#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_ONEWIRE_H diff --git a/ports/stm32f4/common-hal/busio/SPI.c b/ports/stm32f4/common-hal/busio/SPI.c new file mode 100644 index 0000000000..e20bd7a947 --- /dev/null +++ b/ports/stm32f4/common-hal/busio/SPI.c @@ -0,0 +1,415 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * 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 "shared-bindings/busio/SPI.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "stm32f4xx_hal.h" + +#include "shared-bindings/microcontroller/__init__.h" +#include "boards/board.h" +#include "supervisor/shared/translate.h" +#include "common-hal/microcontroller/Pin.h" + +STATIC bool reserved_spi[6]; +STATIC bool never_reset_spi[6]; + +void spi_reset(void) { + #ifdef SPI1 + if(!never_reset_spi[0]) { + reserved_spi[0] = false; + __HAL_RCC_SPI1_CLK_DISABLE(); + } + #endif + #ifdef SPI2 + if(!never_reset_spi[1]) { + reserved_spi[1] = false; + __HAL_RCC_SPI2_CLK_DISABLE(); + } + #endif + #ifdef SPI3 + if(!never_reset_spi[2]) { + reserved_spi[2] = false; + __HAL_RCC_SPI3_CLK_DISABLE(); + } + #endif + #ifdef SPI4 + if(!never_reset_spi[3]) { + reserved_spi[3] = false; + __HAL_RCC_SPI4_CLK_DISABLE(); + } + #endif + #ifdef SPI5 + if(!never_reset_spi[4]) { + reserved_spi[4] = false; + __HAL_RCC_SPI5_CLK_DISABLE(); + } + #endif + #ifdef SPI6 + if(!never_reset_spi[5]) { + reserved_spi[5] = false; + __HAL_RCC_SPI6_CLK_DISABLE(); + } + #endif +} + +void common_hal_busio_spi_construct(busio_spi_obj_t *self, + const mcu_pin_obj_t * sck, const mcu_pin_obj_t * mosi, + const mcu_pin_obj_t * miso) { + + //match pins to SPI objects + SPI_TypeDef * SPIx; + + uint8_t sck_len = sizeof(mcu_spi_sck_list)/sizeof(*mcu_spi_sck_list); + uint8_t mosi_len = sizeof(mcu_spi_mosi_list)/sizeof(*mcu_spi_mosi_list); + uint8_t miso_len = sizeof(mcu_spi_miso_list)/sizeof(*mcu_spi_miso_list); + + bool spi_taken = false; + //sck + for(uint i=0; isck = &mcu_spi_sck_list[i]; + self->mosi = &mcu_spi_mosi_list[j]; + self->miso = &mcu_spi_miso_list[k]; + break; + } + } + } + } + } + } + + //handle typedef selection, errors + if(self->sck!=NULL && self->mosi!=NULL && self->miso!=NULL ) { + SPIx = mcu_spi_banks[self->sck->spi_index-1]; + } else { + if (spi_taken) { + mp_raise_ValueError(translate("Hardware busy, try alternative pins")); + } else { + mp_raise_ValueError(translate("Invalid SPI pin selection")); + } + } + + //Start GPIO for each pin + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = pin_mask(sck->number); + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = self->sck->altfn_index; + HAL_GPIO_Init(pin_port(sck->port), &GPIO_InitStruct); + + GPIO_InitStruct.Pin = pin_mask(mosi->number); + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = self->mosi->altfn_index; + HAL_GPIO_Init(pin_port(mosi->port), &GPIO_InitStruct); + + GPIO_InitStruct.Pin = pin_mask(miso->number); + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = self->miso->altfn_index; + HAL_GPIO_Init(pin_port(miso->port), &GPIO_InitStruct); + + #ifdef SPI1 + if(SPIx==SPI1) { + reserved_spi[0] = true; + __HAL_RCC_SPI1_CLK_ENABLE(); + } + #endif + #ifdef SPI2 + if(SPIx==SPI2) { + reserved_spi[1] = true; + __HAL_RCC_SPI2_CLK_ENABLE(); + } + #endif + #ifdef SPI3 + if(SPIx==SPI3) { + reserved_spi[2] = true; + __HAL_RCC_SPI3_CLK_ENABLE(); + } + #endif + #ifdef SPI4 + if(SPIx==SPI4) { + reserved_spi[3] = true; + __HAL_RCC_SPI4_CLK_ENABLE(); + } + #endif + #ifdef SPI5 + if(SPIx==SPI5) { + reserved_spi[4] = true; + __HAL_RCC_SPI5_CLK_ENABLE(); + } + #endif + #ifdef SPI6 + if(SPIx==SPI6) { + reserved_spi[5] = true; + __HAL_RCC_SPI6_CLK_ENABLE(); + } + #endif + + self->handle.Instance = SPIx; + self->handle.Init.Mode = SPI_MODE_MASTER; + self->handle.Init.Direction = SPI_DIRECTION_2LINES; + self->handle.Init.DataSize = SPI_DATASIZE_8BIT; + self->handle.Init.CLKPolarity = SPI_POLARITY_LOW; + self->handle.Init.CLKPhase = SPI_PHASE_1EDGE; + self->handle.Init.NSS = SPI_NSS_SOFT; + self->handle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; + self->handle.Init.FirstBit = SPI_FIRSTBIT_MSB; + self->handle.Init.TIMode = SPI_TIMODE_DISABLE; + self->handle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + self->handle.Init.CRCPolynomial = 10; + if (HAL_SPI_Init(&self->handle) != HAL_OK) + { + mp_raise_ValueError(translate("SPI Init Error")); + } + self->baudrate = (HAL_RCC_GetPCLK2Freq()/16); + self->prescaler = 16; + self->polarity = 0; + self->phase = 1; + self->bits = 8; + + claim_pin(sck); + claim_pin(mosi); + claim_pin(miso); +} + +void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { + for(size_t i = 0 ; i < MP_ARRAY_SIZE(mcu_spi_banks); i++) { + if (mcu_spi_banks[i] == self->handle.Instance) { + never_reset_spi[i] = true; + never_reset_pin_number(self->sck->pin->port, self->sck->pin->number); + never_reset_pin_number(self->mosi->pin->port, self->mosi->pin->number); + never_reset_pin_number(self->miso->pin->port, self->miso->pin->number); + break; + } + } +} + +bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { + return self->sck->pin == mp_const_none; +} + +void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { + #ifdef SPI1 + if(self->handle.Instance==SPI1) { + reserved_spi[0] = false; + __HAL_RCC_SPI1_CLK_DISABLE(); + } + #endif + #ifdef SPI2 + if(self->handle.Instance==SPI2) { + reserved_spi[1] = false; + __HAL_RCC_SPI2_CLK_DISABLE(); + } + #endif + #ifdef SPI3 + if(self->handle.Instance==SPI3) { + reserved_spi[2] = false; + __HAL_RCC_SPI3_CLK_DISABLE(); + } + #endif + #ifdef SPI4 + if(self->handle.Instance==SPI4) { + reserved_spi[3] = false; + __HAL_RCC_SPI4_CLK_DISABLE(); + } + #endif + #ifdef SPI5 + if(self->handle.Instance==SPI5) { + reserved_spi[4] = false; + __HAL_RCC_SPI5_CLK_DISABLE(); + } + #endif + #ifdef SPI6 + if(self->handle.Instance==SPI6) { + reserved_spi[5] = false; + __HAL_RCC_SPI6_CLK_DISABLE(); + } + #endif + reset_pin_number(self->sck->pin->port,self->sck->pin->number); + reset_pin_number(self->mosi->pin->port,self->mosi->pin->number); + reset_pin_number(self->miso->pin->port,self->miso->pin->number); + self->sck = mp_const_none; + self->mosi = mp_const_none; + self->miso = mp_const_none; +} + +static uint32_t stm32_baud_to_spi_div(uint32_t baudrate, uint16_t * prescaler) { + static const uint32_t baud_map[8][2] = { + {2,SPI_BAUDRATEPRESCALER_2}, + {4,SPI_BAUDRATEPRESCALER_4}, + {8,SPI_BAUDRATEPRESCALER_8}, + {16,SPI_BAUDRATEPRESCALER_16}, + {32,SPI_BAUDRATEPRESCALER_32}, + {64,SPI_BAUDRATEPRESCALER_64}, + {128,SPI_BAUDRATEPRESCALER_128}, + {256,SPI_BAUDRATEPRESCALER_256} + }; + size_t i = 0; + uint16_t divisor; + do { + divisor = baud_map[i][0]; + if (baudrate >= (HAL_RCC_GetPCLK2Freq()/divisor)) { + *prescaler = divisor; + return baud_map[i][1]; + } + i++; + } while (divisor != 256); + //only gets here if requested baud is lower than minimum + *prescaler = 256; + return SPI_BAUDRATEPRESCALER_256; +} + +bool common_hal_busio_spi_configure(busio_spi_obj_t *self, + uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { + //This resets the SPI, so check before updating it redundantly + if (baudrate == self->baudrate && polarity== self->polarity + && phase == self->phase && bits == self->bits) return true; + + //Deinit SPI + HAL_SPI_DeInit(&self->handle); + + if (bits == 8) { + self->handle.Init.DataSize = SPI_DATASIZE_8BIT; + } else if (bits == 16) { + self->handle.Init.DataSize = SPI_DATASIZE_16BIT; + } else { + return false; + } + + if (polarity) { + self->handle.Init.CLKPolarity = SPI_POLARITY_HIGH; + } else { + self->handle.Init.CLKPolarity = SPI_POLARITY_LOW; + } + + if (phase) { + self->handle.Init.CLKPhase = SPI_PHASE_2EDGE; + } else { + self->handle.Init.CLKPhase = SPI_PHASE_1EDGE; + } + + self->handle.Init.BaudRatePrescaler = stm32_baud_to_spi_div(baudrate, &self->prescaler); + + self->handle.Init.Mode = SPI_MODE_MASTER; + self->handle.Init.Direction = SPI_DIRECTION_2LINES; + self->handle.Init.NSS = SPI_NSS_SOFT; + self->handle.Init.FirstBit = SPI_FIRSTBIT_MSB; + self->handle.Init.TIMode = SPI_TIMODE_DISABLE; + self->handle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + self->handle.Init.CRCPolynomial = 10; + + if (HAL_SPI_Init(&self->handle) != HAL_OK) + { + mp_raise_ValueError(translate("SPI Re-initialization error")); + } + + self->baudrate = baudrate; + self->polarity = polarity; + self->phase = phase; + self->bits = bits; + return true; +} + +bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { + bool grabbed_lock = false; + + //Critical section code that may be required at some point. + // uint32_t store_primask = __get_PRIMASK(); + // __disable_irq(); + // __DMB(); + + if (!self->has_lock) { + grabbed_lock = true; + self->has_lock = true; + } + + // __DMB(); + // __set_PRIMASK(store_primask); + + 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) { + HAL_StatusTypeDef result = HAL_SPI_Transmit (&self->handle, (uint8_t *)data, (uint16_t)len, HAL_MAX_DELAY); + return result == HAL_OK; +} + +bool common_hal_busio_spi_read(busio_spi_obj_t *self, + uint8_t *data, size_t len, uint8_t write_value) { + HAL_StatusTypeDef result = HAL_SPI_Receive (&self->handle, data, (uint16_t)len, HAL_MAX_DELAY); + return result == HAL_OK; +} + +bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, + uint8_t *data_out, uint8_t *data_in, size_t len) { + HAL_StatusTypeDef result = HAL_SPI_TransmitReceive (&self->handle, + data_out, data_in, (uint16_t)len,HAL_MAX_DELAY); + return result == HAL_OK; +} + +uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self) { + //returns actual frequency + uint32_t result = HAL_RCC_GetPCLK2Freq()/self->prescaler; + return result; +} + +uint8_t common_hal_busio_spi_get_phase(busio_spi_obj_t* self) { + return self->phase; +} + +uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t* self) { + return self->polarity; +} \ No newline at end of file diff --git a/ports/stm32f4/common-hal/busio/SPI.h b/ports/stm32f4/common-hal/busio/SPI.h new file mode 100644 index 0000000000..067d2fcb65 --- /dev/null +++ b/ports/stm32f4/common-hal/busio/SPI.h @@ -0,0 +1,55 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * 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_BUSIO_SPI_H +#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_SPI_H + +#include "common-hal/microcontroller/Pin.h" + +#include "stm32f4xx_hal.h" +#include "stm32f4/periph.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + SPI_HandleTypeDef handle; + bool has_lock; + const mcu_spi_sck_obj_t *sck; + const mcu_spi_mosi_obj_t *mosi; + const mcu_spi_miso_obj_t *miso; + const mcu_spi_nss_obj_t *nss; + uint32_t baudrate; + uint16_t prescaler; + uint8_t polarity; + uint8_t phase; + uint8_t bits; +} busio_spi_obj_t; + +void spi_reset(void); + +#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_SPI_H diff --git a/ports/stm32f4/common-hal/busio/UART.c b/ports/stm32f4/common-hal/busio/UART.c new file mode 100644 index 0000000000..e1810b131e --- /dev/null +++ b/ports/stm32f4/common-hal/busio/UART.c @@ -0,0 +1,80 @@ +/* + * 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" + +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) { + mp_raise_NotImplementedError(translate("UART not yet supported")); +} + +bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { + return 0; +} + +void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { +} + +// Read characters. +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) { + return 0; +} + +uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) { + return 0; +} + +void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t 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 0; +} diff --git a/ports/stm32f4/common-hal/busio/UART.h b/ports/stm32f4/common-hal/busio/UART.h new file mode 100644 index 0000000000..6992339340 --- /dev/null +++ b/ports/stm32f4/common-hal/busio/UART.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 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 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_BUSIO_UART_H +#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_UART_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + 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_STM32F4_COMMON_HAL_BUSIO_UART_H diff --git a/ports/stm32f4/common-hal/busio/__init__.c b/ports/stm32f4/common-hal/busio/__init__.c new file mode 100644 index 0000000000..41761b6743 --- /dev/null +++ b/ports/stm32f4/common-hal/busio/__init__.c @@ -0,0 +1 @@ +// No busio module functions. diff --git a/ports/stm32f4/common-hal/digitalio/DigitalInOut.c b/ports/stm32f4/common-hal/digitalio/DigitalInOut.c new file mode 100644 index 0000000000..51b1fde738 --- /dev/null +++ b/ports/stm32f4/common-hal/digitalio/DigitalInOut.c @@ -0,0 +1,160 @@ +/* + * 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, 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 = pin_mask(self->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(self->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, 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 = pin_mask(self->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(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(pin_port(self->pin->port), pin_mask(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(pin_port(self->pin->port), pin_mask(self->pin->number), value); +} + +bool common_hal_digitalio_digitalinout_get_value( + digitalio_digitalinout_obj_t *self) { + return (LL_GPIO_GetPinMode(pin_port(self->pin->port), pin_mask(self->pin->number)) == LL_GPIO_MODE_INPUT) + ? HAL_GPIO_ReadPin(pin_port(self->pin->port), pin_mask(self->pin->number)) + : LL_GPIO_IsOutputPinSet(pin_port(self->pin->port), pin_mask(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 = pin_mask(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(pin_port(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(pin_port(self->pin->port), pin_mask(self->pin->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(pin_port(self->pin->port), pin_mask(self->pin->number),LL_GPIO_PULL_UP); + break; + case PULL_DOWN: + LL_GPIO_SetPinPull(pin_port(self->pin->port), pin_mask(self->pin->number),LL_GPIO_PULL_DOWN); + break; + case PULL_NONE: + LL_GPIO_SetPinPull(pin_port(self->pin->port), pin_mask(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(pin_port(self->pin->port), pin_mask(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 0000000000..76aa2c8556 --- /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 0000000000..20fad45959 --- /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 0000000000..5761d7fb15 --- /dev/null +++ b/ports/stm32f4/common-hal/microcontroller/Pin.c @@ -0,0 +1,94 @@ +/* + * 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" + +#if MCU_PACKAGE == 144 + #define GPIO_PORT_COUNT 7 + GPIO_TypeDef * ports[GPIO_PORT_COUNT] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG}; +#elif MCU_PACKAGE == 100 + #define GPIO_PORT_COUNT 5 + GPIO_TypeDef * ports[GPIO_PORT_COUNT] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE}; +#elif MCU_PACKAGE == 64 + #define GPIO_PORT_COUNT 3 + GPIO_TypeDef * ports[GPIO_PORT_COUNT] = {GPIOA, GPIOB, GPIOC}; +#endif + +STATIC uint16_t claimed_pins[GPIO_PORT_COUNT]; +STATIC uint16_t never_reset_pins[GPIO_PORT_COUNT]; + +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_port == 0x0F) { + return; + } + + // Clear claimed bit. + claimed_pins[pin_port] &= ~(1<port] |= 1<number; +} + +bool pin_number_is_free(uint8_t pin_port, uint8_t pin_number) { + return !(claimed_pins[pin_port] & 1<port, pin->number); +} + +GPIO_TypeDef * pin_port(uint8_t pin_port) { + return ports[pin_port]; +} + +uint16_t pin_mask(uint8_t pin_number) { + return 1<= 100 + { 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) }, +#endif + { MP_ROM_QSTR(MP_QSTR_PC13), MP_ROM_PTR(&pin_PC13) }, +#if MCU_PACKAGE == 144 + { 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) }, +#endif + { 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) }, +#if MCU_PACKAGE == 144 + { 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) }, +#endif +#if MCU_PACKAGE >= 100 + { 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) }, +#endif + { MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10) }, +#if MCU_PACKAGE != 100 + { MP_ROM_QSTR(MP_QSTR_PB11), MP_ROM_PTR(&pin_PB11) }, +#endif + { 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) }, +#if MCU_PACKAGE >= 100 + { 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) }, +#endif +#if MCU_PACKAGE == 144 + { 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) }, +#endif + { 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) }, +#if MCU_PACKAGE >= 100 + { 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) }, +#endif +#if MCU_PACKAGE == 144 + { 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) }, +#endif + { 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) }, +#if MCU_PACKAGE >= 100 + { MP_ROM_QSTR(MP_QSTR_PE00), MP_ROM_PTR(&pin_PE00) }, + { MP_ROM_QSTR(MP_QSTR_PE01), MP_ROM_PTR(&pin_PE01) }, +#endif +}; +MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_globals_table); diff --git a/ports/stm32f4/common-hal/os/__init__.c b/ports/stm32f4/common-hal/os/__init__.c new file mode 100644 index 0000000000..aa80a02f5e --- /dev/null +++ b/ports/stm32f4/common-hal/os/__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 + * 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 "genhdr/mpversion.h" +#include "py/mpconfig.h" +#include "py/objstr.h" +#include "py/objtuple.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, "stm32f4"); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, "stm32f4"); + +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) { + + for (uint32_t i = 0; i < length; i++) { + buffer[i] = 4; //read in my coffee dregs; the truest random number, chosen by Nrthalotep + //todo: spurn the gods, replace with actual code. + } + return true; +} \ No newline at end of file diff --git a/ports/stm32f4/common-hal/supervisor/Runtime.c b/ports/stm32f4/common-hal/supervisor/Runtime.c new file mode 100755 index 0000000000..feab6987d8 --- /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 0000000000..9a798e0567 --- /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 0000000000..ac88556b45 --- /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 0000000000..e3cb481ef4 --- /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 0000000000..13ac21fb1b --- /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 0000000000..543a55942e --- /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 0000000000..0dd4862ec5 --- /dev/null +++ b/ports/stm32f4/mpconfigport.mk @@ -0,0 +1,29 @@ +# 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 = 24 + +# Longints can be implemented as mpz, as longlong, or not +LONGINT_IMPL = MPZ + +#Reduced feature set for early port +CIRCUITPY_MINIMAL_BUILD = 1 + +CIRCUITPY_BOARD = 1 +CIRCUITPY_DIGITALIO = 1 +CIRCUITPY_ANALOGIO = 1 +CIRCUITPY_MICROCONTROLLER = 1 +CIRCUITPY_BUSIO = 1 +CIRCUITPY_TIME = 1 +CIRCUITPY_OS = 1 +CIRCUITPY_STRUCT = 1 +CIRCUITPY_MATH = 1 + +#ifeq ($(MCU_SUB_VARIANT), stm32f412zx) +#endif diff --git a/ports/stm32f4/mphalport.c b/ports/stm32f4/mphalport.c new file mode 100644 index 0000000000..ea864e7ceb --- /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 0000000000..131f2751dc --- /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 0000000000..c7ba846622 --- /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 0000000000..34f89e7921 --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/gpio.h @@ -0,0 +1,28 @@ +/* + * 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); +void stm32f4_peripherals_status_led(uint8_t led, uint8_t state); diff --git a/ports/stm32f4/peripherals/stm32f4/periph.h b/ports/stm32f4/peripherals/stm32f4/periph.h new file mode 100644 index 0000000000..06ab2d3e4f --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/periph.h @@ -0,0 +1,114 @@ +/* + * 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_PERIPH_H__ +#define __MICROPY_INCLUDED_STM32F4_PERIPHERALS_PERIPH_H__ + +#include +#include + +#include "stm32f4xx_hal.h" +#include "stm32f4/pins.h" + +// I2C +//TODO: these objects should be condensed into a single 'periph_pin' unless we +//find a compelling reason to store more unique data in them. + +typedef struct { + uint8_t i2c_index:4; // Index of the I2C unit (1 to 3) + uint8_t altfn_index:4; //Index of the altfn for this pin (0 to 15) + const mcu_pin_obj_t * pin; +} mcu_i2c_sda_obj_t; + +typedef struct { + uint8_t i2c_index:4; + uint8_t altfn_index:4; + const mcu_pin_obj_t * pin; +} mcu_i2c_scl_obj_t; + + +#define I2C_SDA(index, alt, sda_pin) \ +{ \ + .i2c_index = index, \ + .altfn_index = alt, \ + .pin = sda_pin, \ +} + +#define I2C_SCL(index, alt, scl_pin) \ +{ \ + .i2c_index = index, \ + .altfn_index = alt, \ + .pin = scl_pin, \ +} + +// SPI +//TODO: these objects should be condensed into a single 'periph_pin' unless we +//find a compelling reason to store more unique data in them. + +typedef struct { + uint8_t spi_index:4; //Up to 6 SPI units + uint8_t altfn_index:4; //Up to 15 alt channels + const mcu_pin_obj_t * pin; +} mcu_spi_sck_obj_t; + +typedef struct { + uint8_t spi_index:4; + uint8_t altfn_index:4; + const mcu_pin_obj_t * pin; +} mcu_spi_mosi_obj_t; + +typedef struct { + uint8_t spi_index:4; + uint8_t altfn_index:4; + const mcu_pin_obj_t * pin; +} mcu_spi_miso_obj_t; + +typedef struct { + uint8_t spi_index:4; + uint8_t altfn_index:4; + const mcu_pin_obj_t * pin; +} mcu_spi_nss_obj_t; + +#define SPI(index, alt, spi_pin) \ +{ \ + .spi_index = index, \ + .altfn_index = alt, \ + .pin = spi_pin, \ +} + +// TODO: SPI, UART, etc + +// Choose based on chip +#ifdef STM32F412Zx +#include "stm32f412zx/periph.h" +#endif +#ifdef STM32F411xE +#include "stm32f411xe/periph.h" +#endif +#ifdef STM32F405xx +#include "stm32f405xx/periph.h" +#endif +#endif // __MICROPY_INCLUDED_STM32F4_PERIPHERALS_PERIPH_H__ diff --git a/ports/stm32f4/peripherals/stm32f4/pins.h b/ports/stm32f4/peripherals/stm32f4/pins.h new file mode 100644 index 0000000000..ced83562ec --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/pins.h @@ -0,0 +1,89 @@ +/* + * 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 port:4; + uint8_t number:4; + uint8_t adc_unit:3; + uint8_t adc_channel:5; +} mcu_pin_obj_t; + +//Standard stm32 adc unit combinations +#define ADC_1 1 +#define ADC_12 3 +#define ADC_123 7 +#define ADC_3 4 + +//STM32 ADC pins can have a combination of 1, 2 or all 3 ADCs on a single pin, +//but all 3 ADCs will share the same input number per pin. +//F4 family has 3 ADC max, 24 channels max. +#define ADC_INPUT(mask, number) \ + .adc_unit = mask, \ + .adc_channel = number, + +#define NO_ADC \ + .adc_unit = 0x00, \ + .adc_channel = 0x1f + +extern const mp_obj_type_t mcu_pin_type; + +// STM32 can have up to 9 ports, each restricted to 16 pins +// We split the pin/port evenly, in contrast to nrf. +#define PIN(p_port, p_number, p_adc) \ +{ \ + { &mcu_pin_type }, \ + .port = p_port, \ + .number = p_number, \ + p_adc \ +} + +// Use illegal pin value to mark unassigned pins. +#define NO_PIN 0xff + +// Choose based on chip +#ifdef STM32F412Zx +#include "stm32f412zx/pins.h" +#endif +#ifdef STM32F411xE +#include "stm32f411xe/pins.h" +#endif +#ifdef STM32F405xx +#include "stm32f405xx/pins.h" +#endif +#endif // __MICROPY_INCLUDED_STM32F4_PERIPHERALS_PINS_H__ diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/clocks.c b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/clocks.c new file mode 100644 index 0000000000..74eeb4b244 --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/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) { + //TODO: All parameters must be moved to board level, due to relationship with HSE Osc. + + //System clock init + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + 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 = 12; + RCC_OscInitStruct.PLL.PLLN = 336; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4; + RCC_OscInitStruct.PLL.PLLQ = 7; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | 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_5); +} diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/gpio.c b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/gpio.c new file mode 100644 index 0000000000..f9be3b4ec2 --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/gpio.c @@ -0,0 +1,56 @@ +/* + * 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" +#include "stm32f4/gpio.h" +#include "common-hal/microcontroller/Pin.h" + +void stm32f4_peripherals_gpio_init(void) { + //Enable all GPIO for now + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + + //Never reset pins + never_reset_pin_number(2,13); //PC13 anti tamp + never_reset_pin_number(2,14); //PC14 OSC32_IN + never_reset_pin_number(2,15); //PC15 OSC32_OUT + never_reset_pin_number(0,13); //PA13 SWDIO + never_reset_pin_number(0,14); //PA14 SWCLK + // never_reset_pin_number(0,15); //PA15 JTDI + // never_reset_pin_number(1,3); //PB3 JTDO + // never_reset_pin_number(1,4); //PB4 JTRST + + // Port H is not included in GPIO port array + // never_reset_pin_number(5,0); //PH0 JTDO + // never_reset_pin_number(5,1); //PH1 JTRST +} + +void stm32f4_peripherals_status_led(uint8_t led, uint8_t state) { + +} + + diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.c b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.c new file mode 100644 index 0000000000..7b0a54e55e --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.c @@ -0,0 +1,88 @@ + /* + * 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" +#include "stm32f4/periph.h" + +// I2C + +I2C_TypeDef * mcu_i2c_banks[3] = {I2C1, I2C2, I2C3}; + +const mcu_i2c_sda_obj_t mcu_i2c_sda_list[4] = { + I2C_SDA(1, 4, &pin_PB07), + I2C_SDA(1, 4, &pin_PB09), + I2C_SDA(2, 4, &pin_PB11), + I2C_SDA(3, 4, &pin_PC09), +}; + +const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4] = { + I2C_SCL(1, 4, &pin_PB06), + I2C_SCL(1, 4, &pin_PB08), + I2C_SCL(2, 4, &pin_PB10), + I2C_SCL(3, 4, &pin_PA08) +}; + +SPI_TypeDef * mcu_spi_banks[3] = {SPI1, SPI2, SPI3}; + +const mcu_spi_sck_obj_t mcu_spi_sck_list[7] = { + SPI(1, 5, &pin_PA05), + SPI(1, 5, &pin_PB03), + SPI(2, 5, &pin_PB10), + SPI(2, 5, &pin_PB13), + SPI(2, 5, &pin_PC07), + SPI(3, 6, &pin_PB03), + SPI(3, 6, &pin_PC10), +}; + +const mcu_spi_mosi_obj_t mcu_spi_mosi_list[6] = { + SPI(1, 5, &pin_PA07), + SPI(1, 5, &pin_PB05), + SPI(2, 5, &pin_PB15), + SPI(2, 5, &pin_PC03), + SPI(3, 6, &pin_PB05), + SPI(3, 6, &pin_PC12), +}; + +const mcu_spi_miso_obj_t mcu_spi_miso_list[6] = { + SPI(1, 5, &pin_PA06), + SPI(1, 5, &pin_PB04), + SPI(2, 5, &pin_PB14), + SPI(2, 5, &pin_PC02), + SPI(3, 6, &pin_PB04), + SPI(3, 6, &pin_PC11), +}; + +const mcu_spi_nss_obj_t mcu_spi_nss_list[6] = { + SPI(1, 5, &pin_PA04), + SPI(1, 5, &pin_PA15), + SPI(2, 5, &pin_PB09), + SPI(2, 5, &pin_PB12), + SPI(3, 6, &pin_PA04), + SPI(3, 6, &pin_PA15), +}; +//UART, Etc diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.h b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.h new file mode 100644 index 0000000000..cb9b33f6eb --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.h @@ -0,0 +1,45 @@ +/* + * 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_STM32F405XX_PERIPH_H +#define MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F405XX_PERIPH_H + +//I2C +extern I2C_TypeDef * mcu_i2c_banks[3]; + +extern const mcu_i2c_sda_obj_t mcu_i2c_sda_list[4]; +extern const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4]; + +//SPI +extern SPI_TypeDef * mcu_spi_banks[3]; + +extern const mcu_spi_sck_obj_t mcu_spi_sck_list[7]; +extern const mcu_spi_mosi_obj_t mcu_spi_mosi_list[6]; +extern const mcu_spi_miso_obj_t mcu_spi_miso_list[6]; +extern const mcu_spi_nss_obj_t mcu_spi_nss_list[6]; + + +#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F405XX_PERIPH_H \ No newline at end of file diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/pins.c b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/pins.c new file mode 100644 index 0000000000..86445fe140 --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/pins.c @@ -0,0 +1,161 @@ + /* + * 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, 2, NO_ADC); +const mcu_pin_obj_t pin_PE03 = PIN(4, 3, NO_ADC); +const mcu_pin_obj_t pin_PE04 = PIN(4, 4, NO_ADC); +const mcu_pin_obj_t pin_PE05 = PIN(4, 5, NO_ADC); +const mcu_pin_obj_t pin_PE06 = PIN(4, 6, NO_ADC); + +const mcu_pin_obj_t pin_PC13 = PIN(2, 13, NO_ADC); //anti-tamp +const mcu_pin_obj_t pin_PC14 = PIN(2, 14, NO_ADC); //OSC32_IN +const mcu_pin_obj_t pin_PC15 = PIN(2, 15, NO_ADC); //OSC32_OUT + +const mcu_pin_obj_t pin_PF00 = PIN(5, 0, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF01 = PIN(5, 1, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF02 = PIN(5, 2, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF03 = PIN(5, 3, ADC_INPUT(ADC_3,9)); // 144 only +const mcu_pin_obj_t pin_PF04 = PIN(5, 4, ADC_INPUT(ADC_3,14)); // 144 only +const mcu_pin_obj_t pin_PF05 = PIN(5, 5, ADC_INPUT(ADC_3,15)); // 144 only +const mcu_pin_obj_t pin_PF06 = PIN(5, 6, ADC_INPUT(ADC_3,4)); // 144 only +const mcu_pin_obj_t pin_PF07 = PIN(5, 7, ADC_INPUT(ADC_3,5)); // 144 only +const mcu_pin_obj_t pin_PF08 = PIN(5, 8, ADC_INPUT(ADC_3,6)); // 144 only +const mcu_pin_obj_t pin_PF09 = PIN(5, 9, ADC_INPUT(ADC_3,7)); // 144 only +const mcu_pin_obj_t pin_PF10 = PIN(5, 10, ADC_INPUT(ADC_3,8)); // 144 only + +const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_123,10)); +const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_123,11)); +const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_123,12)); +const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_123,13)); + +const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_123,0)); +const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_123,1)); +const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_123,2)); +const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_123,3)); +const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_12,4)); +const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_12,5)); +const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_12,6)); +const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_12,7)); + +const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_12,14)); +const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_12,15)); + +const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_12,8)); +const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_12,9)); +const mcu_pin_obj_t pin_PB02 = PIN(1, 2, NO_ADC); //BOOT1 + +const mcu_pin_obj_t pin_PF11 = PIN(5, 11, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF12 = PIN(5, 12, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF13 = PIN(5, 13, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF14 = PIN(5, 14, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF15 = PIN(5, 15, NO_ADC); // 144 only + +const mcu_pin_obj_t pin_PG00 = PIN(6, 0, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG01 = PIN(6, 1, NO_ADC); // 144 only + +const mcu_pin_obj_t pin_PE07 = PIN(4, 7, NO_ADC); +const mcu_pin_obj_t pin_PE08 = PIN(4, 8, NO_ADC); +const mcu_pin_obj_t pin_PE09 = PIN(4, 9, NO_ADC); +const mcu_pin_obj_t pin_PE10 = PIN(4, 10, NO_ADC); +const mcu_pin_obj_t pin_PE11 = PIN(4, 11, NO_ADC); +const mcu_pin_obj_t pin_PE12 = PIN(4, 12, NO_ADC); +const mcu_pin_obj_t pin_PE13 = PIN(4, 13, NO_ADC); +const mcu_pin_obj_t pin_PE14 = PIN(4, 14, NO_ADC); +const mcu_pin_obj_t pin_PE15 = PIN(4, 15, NO_ADC); + +const mcu_pin_obj_t pin_PB10 = PIN(1, 10, NO_ADC); +const mcu_pin_obj_t pin_PB11 = PIN(1, 11, NO_ADC); +const mcu_pin_obj_t pin_PB12 = PIN(1, 12, NO_ADC); +const mcu_pin_obj_t pin_PB13 = PIN(1, 13, NO_ADC); +const mcu_pin_obj_t pin_PB14 = PIN(1, 14, NO_ADC); +const mcu_pin_obj_t pin_PB15 = PIN(1, 15, NO_ADC); + +const mcu_pin_obj_t pin_PD08 = PIN(3, 8, NO_ADC); +const mcu_pin_obj_t pin_PD09 = PIN(3, 9, NO_ADC); +const mcu_pin_obj_t pin_PD10 = PIN(3, 10, NO_ADC); +const mcu_pin_obj_t pin_PD11 = PIN(3, 11, NO_ADC); +const mcu_pin_obj_t pin_PD12 = PIN(3, 12, NO_ADC); +const mcu_pin_obj_t pin_PD13 = PIN(3, 13, NO_ADC); +const mcu_pin_obj_t pin_PD14 = PIN(3, 14, NO_ADC); +const mcu_pin_obj_t pin_PD15 = PIN(3, 15, NO_ADC); + +const mcu_pin_obj_t pin_PG02 = PIN(6, 2, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG03 = PIN(6, 3, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG04 = PIN(6, 4, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG05 = PIN(6, 5, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG06 = PIN(6, 6, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG07 = PIN(6, 7, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG08 = PIN(6, 8, NO_ADC); // 144 only + +const mcu_pin_obj_t pin_PC06 = PIN(2, 6, NO_ADC); +const mcu_pin_obj_t pin_PC07 = PIN(2, 7, NO_ADC); +const mcu_pin_obj_t pin_PC08 = PIN(2, 8, NO_ADC); +const mcu_pin_obj_t pin_PC09 = PIN(2, 9, NO_ADC); + +const mcu_pin_obj_t pin_PA08 = PIN(0, 8, NO_ADC); +const mcu_pin_obj_t pin_PA09 = PIN(0, 9, NO_ADC); +const mcu_pin_obj_t pin_PA10 = PIN(0, 10, NO_ADC); +const mcu_pin_obj_t pin_PA11 = PIN(0, 11, NO_ADC); +const mcu_pin_obj_t pin_PA12 = PIN(0, 12, NO_ADC); +const mcu_pin_obj_t pin_PA13 = PIN(0, 13, NO_ADC); +const mcu_pin_obj_t pin_PA14 = PIN(0, 14, NO_ADC); +const mcu_pin_obj_t pin_PA15 = PIN(0, 15, NO_ADC); + +const mcu_pin_obj_t pin_PC10 = PIN(2, 10, NO_ADC); +const mcu_pin_obj_t pin_PC11 = PIN(2, 11, NO_ADC); +const mcu_pin_obj_t pin_PC12 = PIN(2, 12, NO_ADC); + +const mcu_pin_obj_t pin_PD00 = PIN(3, 0, NO_ADC); +const mcu_pin_obj_t pin_PD01 = PIN(3, 1, NO_ADC); +const mcu_pin_obj_t pin_PD02 = PIN(3, 2, NO_ADC); +const mcu_pin_obj_t pin_PD03 = PIN(3, 3, NO_ADC); +const mcu_pin_obj_t pin_PD04 = PIN(3, 4, NO_ADC); +const mcu_pin_obj_t pin_PD05 = PIN(3, 5, NO_ADC); +const mcu_pin_obj_t pin_PD06 = PIN(3, 6, NO_ADC); +const mcu_pin_obj_t pin_PD07 = PIN(3, 7, NO_ADC); + +const mcu_pin_obj_t pin_PG09 = PIN(6, 9, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG10 = PIN(6, 10, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG11 = PIN(6, 11, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG12 = PIN(6, 12, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG13 = PIN(6, 13, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG14 = PIN(6, 14, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG15 = PIN(6, 15, NO_ADC); // 144 only + +const mcu_pin_obj_t pin_PB03 = PIN(1, 3, NO_ADC); +const mcu_pin_obj_t pin_PB04 = PIN(1, 4, NO_ADC); +const mcu_pin_obj_t pin_PB05 = PIN(1, 5, NO_ADC); +const mcu_pin_obj_t pin_PB06 = PIN(1, 6, NO_ADC); +const mcu_pin_obj_t pin_PB07 = PIN(1, 7, NO_ADC); +const mcu_pin_obj_t pin_PB08 = PIN(1, 8, NO_ADC); +const mcu_pin_obj_t pin_PB09 = PIN(1, 9, NO_ADC); + +const mcu_pin_obj_t pin_PE00 = PIN(4, 0, NO_ADC); +const mcu_pin_obj_t pin_PE01 = PIN(4, 1, NO_ADC); diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/pins.h b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/pins.h new file mode 100644 index 0000000000..180f5c316f --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/pins.h @@ -0,0 +1,158 @@ +/* + * 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; +extern const mcu_pin_obj_t pin_PC14; +//pg 51 +extern const mcu_pin_obj_t pin_PC15; +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/peripherals/stm32f4/stm32f411xe/clocks.c b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/clocks.c new file mode 100644 index 0000000000..883c252d51 --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/clocks.c @@ -0,0 +1,61 @@ + +/* + * 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_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + 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 = 8; + RCC_OscInitStruct.PLL.PLLN = 336; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4; + RCC_OscInitStruct.PLL.PLLQ = 7; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | 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_3); +} diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/gpio.c b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/gpio.c new file mode 100644 index 0000000000..2b80647c0e --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/gpio.c @@ -0,0 +1,169 @@ +/* + * 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" +#include "stm32f4/gpio.h" +#include "common-hal/microcontroller/Pin.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 + stm32f4_peripherals_status_led(0,1); + stm32f4_peripherals_status_led(1,0); + stm32f4_peripherals_status_led(2,0); + stm32f4_peripherals_status_led(3,0); + + //Never reset pins + never_reset_pin_number(2,13); //PC13 anti tamp + never_reset_pin_number(2,14); //PC14 OSC32_IN + never_reset_pin_number(2,15); //PC15 OSC32_OUT + never_reset_pin_number(0,13); //PA13 SWDIO + never_reset_pin_number(0,14); //PA14 SWCLK + never_reset_pin_number(0,15); //PA15 JTDI + never_reset_pin_number(1,3); //PB3 JTDO + never_reset_pin_number(1,4); //PB4 JTRST + + // Port H is not included in GPIO port array + // never_reset_pin_number(5,0); //PH0 JTDO + // never_reset_pin_number(5,1); //PH1 JTRST +} + +//LEDs are inverted on F411 DISCO +void stm32f4_peripherals_status_led(uint8_t led, uint8_t state) { + switch(led) + { + case 0: HAL_GPIO_WritePin(GPIOD, LD4_Pin, (state ^ 1)); + break; + case 1: HAL_GPIO_WritePin(GPIOD, LD3_Pin, (state ^ 1)); + break; + case 2: HAL_GPIO_WritePin(GPIOD, LD5_Pin, (state ^ 1)); + break; + case 3: HAL_GPIO_WritePin(GPIOD, LD6_Pin, (state ^ 1)); + break; + default: break; + } +} + + diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.c b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.c new file mode 100644 index 0000000000..f0966f785f --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.c @@ -0,0 +1,122 @@ + /* + * 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" +#include "stm32f4/periph.h" + +// I2C + +I2C_TypeDef * mcu_i2c_banks[3] = {I2C1, I2C2, I2C3}; + +const mcu_i2c_sda_obj_t mcu_i2c_sda_list[7] = { + I2C_SDA(1, 4, &pin_PB07), + I2C_SDA(1, 4, &pin_PB09), + I2C_SDA(2, 9, &pin_PB09), + I2C_SDA(2, 9, &pin_PB03), + I2C_SDA(3, 4, &pin_PC09), + I2C_SDA(3, 9, &pin_PB04), + I2C_SDA(3, 9, &pin_PB08) +}; + +const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4] = { + I2C_SCL(1, 4, &pin_PB06), + I2C_SCL(1, 4, &pin_PB08), + I2C_SCL(2, 4, &pin_PB10), + I2C_SCL(3, 4, &pin_PA08) +}; + +// SPI + +SPI_TypeDef * mcu_spi_banks[5] = {SPI1, SPI2, SPI3, SPI4, SPI5}; + +const mcu_spi_sck_obj_t mcu_spi_sck_list[15] = { + SPI(1, 5, &pin_PA05), + SPI(1, 5, &pin_PB03), + SPI(2, 5, &pin_PB10), + SPI(2, 5, &pin_PB13), + SPI(2, 5, &pin_PC07), + SPI(2, 5, &pin_PD03), + SPI(3, 6, &pin_PB03), + SPI(3, 7, &pin_PB12), + SPI(3, 6, &pin_PC10), + SPI(4, 6, &pin_PB13), + SPI(4, 5, &pin_PE02), + SPI(4, 5, &pin_PE12), + SPI(5, 6, &pin_PB00), + SPI(5, 6, &pin_PE02), + SPI(5, 6, &pin_PE12) +}; + +const mcu_spi_mosi_obj_t mcu_spi_mosi_list[14] = { + SPI(1, 5, &pin_PA07), + SPI(1, 5, &pin_PB05), + SPI(2, 5, &pin_PB15), + SPI(2, 5, &pin_PC03), + SPI(3, 6, &pin_PB05), + SPI(3, 6, &pin_PC12), + SPI(3, 5, &pin_PD06), + SPI(4, 5, &pin_PA01), + SPI(4, 5, &pin_PE06), + SPI(4, 5, &pin_PE14), + SPI(5, 6, &pin_PA10), + SPI(5, 6, &pin_PB08), + SPI(5, 6, &pin_PE06), + SPI(5, 6, &pin_PE14) +}; + +const mcu_spi_miso_obj_t mcu_spi_miso_list[12] = { + SPI(1, 5, &pin_PA06), + SPI(1, 5, &pin_PB04), + SPI(2, 5, &pin_PB14), + SPI(2, 5, &pin_PC02), + SPI(3, 6, &pin_PB04), + SPI(3, 6, &pin_PC11), + SPI(4, 6, &pin_PA11), + SPI(4, 5, &pin_PE05), + SPI(4, 5, &pin_PE13), + SPI(5, 6, &pin_PA12), + SPI(5, 6, &pin_PE05), + SPI(5, 6, &pin_PE13) +}; + +const mcu_spi_nss_obj_t mcu_spi_nss_list[12] = { + SPI(1, 5, &pin_PA04), + SPI(1, 5, &pin_PA15), + SPI(2, 5, &pin_PB09), + SPI(2, 5, &pin_PB12), + SPI(3, 6, &pin_PA04), + SPI(3, 6, &pin_PA15), + SPI(4, 6, &pin_PB12), + SPI(4, 5, &pin_PE04), + SPI(4, 5, &pin_PE11), + SPI(5, 6, &pin_PB01), + SPI(5, 6, &pin_PE04), + SPI(5, 6, &pin_PE11) +}; + +//UART, Etc diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.h b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.h new file mode 100644 index 0000000000..08efa14ca5 --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.h @@ -0,0 +1,44 @@ +/* + * 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_STM32F411VE_PERIPH_H +#define MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411VE_PERIPH_H + +//I2C +extern I2C_TypeDef * mcu_i2c_banks[3]; + +extern const mcu_i2c_sda_obj_t mcu_i2c_sda_list[7]; +extern const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4]; + +//SPI +extern SPI_TypeDef * mcu_spi_banks[5]; + +extern const mcu_spi_sck_obj_t mcu_spi_sck_list[15]; +extern const mcu_spi_mosi_obj_t mcu_spi_mosi_list[14]; +extern const mcu_spi_miso_obj_t mcu_spi_miso_list[12]; +extern const mcu_spi_nss_obj_t mcu_spi_nss_list[12]; + +#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411VE_PERIPH_H \ No newline at end of file diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.c b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.c new file mode 100644 index 0000000000..7e88c3dcba --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.c @@ -0,0 +1,123 @@ + /* + * 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, 2, NO_ADC); +const mcu_pin_obj_t pin_PE03 = PIN(4, 3, NO_ADC); +const mcu_pin_obj_t pin_PE04 = PIN(4, 4, NO_ADC); +const mcu_pin_obj_t pin_PE05 = PIN(4, 5, NO_ADC); +const mcu_pin_obj_t pin_PE06 = PIN(4, 6, NO_ADC); + +const mcu_pin_obj_t pin_PC13 = PIN(2, 13, NO_ADC); //anti-tamp +const mcu_pin_obj_t pin_PC14 = PIN(2, 14, NO_ADC); //OSC32_IN +const mcu_pin_obj_t pin_PC15 = PIN(2, 15, NO_ADC); //OSC32_OUT + +const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_1,10)); +const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_1,11)); +const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_1,12)); +const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_1,13)); + +const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_1,0)); +const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_1,1)); +const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_1,2)); +const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_1,3)); +const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_1,4)); +const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_1,5)); +const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_1,6)); +const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_1,7)); + +const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_1,14)); +const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_1,15)); + +const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_1,8)); +const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_1,9)); +const mcu_pin_obj_t pin_PB02 = PIN(1, 2, NO_ADC); + +const mcu_pin_obj_t pin_PE07 = PIN(4, 7, NO_ADC); +const mcu_pin_obj_t pin_PE08 = PIN(4, 8, NO_ADC); +const mcu_pin_obj_t pin_PE09 = PIN(4, 9, NO_ADC); +const mcu_pin_obj_t pin_PE10 = PIN(4, 10, NO_ADC); +const mcu_pin_obj_t pin_PE11 = PIN(4, 11, NO_ADC); +const mcu_pin_obj_t pin_PE12 = PIN(4, 12, NO_ADC); +const mcu_pin_obj_t pin_PE13 = PIN(4, 13, NO_ADC); +const mcu_pin_obj_t pin_PE14 = PIN(4, 14, NO_ADC); +const mcu_pin_obj_t pin_PE15 = PIN(4, 15, NO_ADC); + +const mcu_pin_obj_t pin_PB10 = PIN(1, 10, NO_ADC); +const mcu_pin_obj_t pin_PB12 = PIN(1, 12, NO_ADC); +const mcu_pin_obj_t pin_PB13 = PIN(1, 13, NO_ADC); +const mcu_pin_obj_t pin_PB14 = PIN(1, 14, NO_ADC); +const mcu_pin_obj_t pin_PB15 = PIN(1, 15, NO_ADC); + +const mcu_pin_obj_t pin_PD08 = PIN(3, 8, NO_ADC); +const mcu_pin_obj_t pin_PD09 = PIN(3, 9, NO_ADC); +const mcu_pin_obj_t pin_PD10 = PIN(3, 10, NO_ADC); +const mcu_pin_obj_t pin_PD11 = PIN(3, 11, NO_ADC); +const mcu_pin_obj_t pin_PD12 = PIN(3, 12, NO_ADC); +const mcu_pin_obj_t pin_PD13 = PIN(3, 13, NO_ADC); +const mcu_pin_obj_t pin_PD14 = PIN(3, 14, NO_ADC); +const mcu_pin_obj_t pin_PD15 = PIN(3, 15, NO_ADC); + +const mcu_pin_obj_t pin_PC06 = PIN(2, 6, NO_ADC); +const mcu_pin_obj_t pin_PC07 = PIN(2, 7, NO_ADC); +const mcu_pin_obj_t pin_PC08 = PIN(2, 8, NO_ADC); +const mcu_pin_obj_t pin_PC09 = PIN(2, 9, NO_ADC); + +const mcu_pin_obj_t pin_PA08 = PIN(0, 8, NO_ADC); +const mcu_pin_obj_t pin_PA09 = PIN(0, 9, NO_ADC); +const mcu_pin_obj_t pin_PA10 = PIN(0, 10, NO_ADC); +const mcu_pin_obj_t pin_PA11 = PIN(0, 11, NO_ADC); +const mcu_pin_obj_t pin_PA12 = PIN(0, 12, NO_ADC); +const mcu_pin_obj_t pin_PA13 = PIN(0, 13, NO_ADC); //SWDIO +const mcu_pin_obj_t pin_PA14 = PIN(0, 14, NO_ADC); //SWCLK +const mcu_pin_obj_t pin_PA15 = PIN(0, 15, NO_ADC); //JTDI + +const mcu_pin_obj_t pin_PC10 = PIN(2, 10, NO_ADC); +const mcu_pin_obj_t pin_PC11 = PIN(2, 11, NO_ADC); +const mcu_pin_obj_t pin_PC12 = PIN(2, 12, NO_ADC); + +const mcu_pin_obj_t pin_PD00 = PIN(3, 0, NO_ADC); +const mcu_pin_obj_t pin_PD01 = PIN(3, 1, NO_ADC); +const mcu_pin_obj_t pin_PD02 = PIN(3, 2, NO_ADC); +const mcu_pin_obj_t pin_PD03 = PIN(3, 3, NO_ADC); +const mcu_pin_obj_t pin_PD04 = PIN(3, 4, NO_ADC); +const mcu_pin_obj_t pin_PD05 = PIN(3, 5, NO_ADC); +const mcu_pin_obj_t pin_PD06 = PIN(3, 6, NO_ADC); +const mcu_pin_obj_t pin_PD07 = PIN(3, 7, NO_ADC); + +const mcu_pin_obj_t pin_PB03 = PIN(1, 3, NO_ADC); +const mcu_pin_obj_t pin_PB04 = PIN(1, 4, NO_ADC); +const mcu_pin_obj_t pin_PB05 = PIN(1, 5, NO_ADC); +const mcu_pin_obj_t pin_PB06 = PIN(1, 6, NO_ADC); +const mcu_pin_obj_t pin_PB07 = PIN(1, 7, NO_ADC); +const mcu_pin_obj_t pin_PB08 = PIN(1, 8, NO_ADC); +const mcu_pin_obj_t pin_PB09 = PIN(1, 9, NO_ADC); + +const mcu_pin_obj_t pin_PE00 = PIN(4, 0, NO_ADC); +const mcu_pin_obj_t pin_PE01 = PIN(4, 1, NO_ADC); \ 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 0000000000..37d3a5cf11 --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.h @@ -0,0 +1,121 @@ +/* + * 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_STM32F411VE_PINS_H +#define MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411VE_PINS_H + +//Pins in datasheet order: DocID026289 Rev 7 page 38. LQFP100 only +//pg 38 +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; +//pg 39 +extern const mcu_pin_obj_t pin_PE06; +extern const mcu_pin_obj_t pin_PC13; +extern const mcu_pin_obj_t pin_PC14; +extern const mcu_pin_obj_t pin_PC15; +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; +//pg 40 +extern const mcu_pin_obj_t pin_PA00; +extern const mcu_pin_obj_t pin_PA01; +extern const mcu_pin_obj_t pin_PA02; +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; +//pg 41 +extern const mcu_pin_obj_t pin_PC04; +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_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; +extern const mcu_pin_obj_t pin_PE15; +//pg 42 +extern const mcu_pin_obj_t pin_PB10; +extern const mcu_pin_obj_t pin_PB12; +extern const mcu_pin_obj_t pin_PB13; +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 43 +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_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; +//pg 44 +extern const mcu_pin_obj_t pin_PA10; +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; +extern const mcu_pin_obj_t pin_PC12; +//pg 45 +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; +extern const mcu_pin_obj_t pin_PB03; +extern const mcu_pin_obj_t pin_PB04; +extern const mcu_pin_obj_t pin_PB05; +extern const mcu_pin_obj_t pin_PB06; +//pg 46 +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_STM32F411VE_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 0000000000..1070565507 --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/clocks.c @@ -0,0 +1,74 @@ + +/* + * 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_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the + * device is clocked below the maximum system frequency, to update the + * voltage scaling value regarding system frequency refer to product + * datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + 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 = 8; + RCC_OscInitStruct.PLL.PLLN = 200; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 7; + RCC_OscInitStruct.PLL.PLLR = 2; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLLSAI output as USB clock source */ + PeriphClkInitStruct.PLLI2S.PLLI2SM = 8; + PeriphClkInitStruct.PLLI2S.PLLI2SQ = 4; + PeriphClkInitStruct.PLLI2S.PLLI2SN = 192; + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CK48; + PeriphClkInitStruct.Clk48ClockSelection = RCC_CK48CLKSOURCE_PLLI2SQ; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + * clocks dividers */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | + 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_3); +} diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/gpio.c b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/gpio.c new file mode 100644 index 0000000000..d17ab4e018 --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/gpio.c @@ -0,0 +1,243 @@ +/* + * 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" +#include "stm32f4/gpio.h" +#include "common-hal/microcontroller/Pin.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 + stm32f4_peripherals_status_led(0,1); + stm32f4_peripherals_status_led(1,0); + stm32f4_peripherals_status_led(2,0); + stm32f4_peripherals_status_led(3,0); + + //Never reset pins + never_reset_pin_number(2,13); //PC13 anti tamp + never_reset_pin_number(2,14); //PC14 OSC32_IN + never_reset_pin_number(2,15); //PC15 OSC32_OUT + never_reset_pin_number(0,13); //PA13 SWDIO + never_reset_pin_number(0,14); //PA14 SWCLK + //never_reset_pin_number(0,15); //PA15 JTDI + //never_reset_pin_number(1,3); //PB3 JTDO + //never_reset_pin_number(1,4); //PB4 JTRST + + // Port H is not included in GPIO port array + // never_reset_pin_number(5,0); //PH0 JTDO + // never_reset_pin_number(5,1); //PH1 JTRST +} + +//LEDs are inverted on F411 DISCO +void stm32f4_peripherals_status_led(uint8_t led, uint8_t state) { + switch(led) + { + case 0: HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0, (state ^ 1)); + break; + case 1: HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, (state ^ 1)); + break; + case 2: HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, (state ^ 1)); + break; + case 3: HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, (state ^ 1)); + break; + default: break; + } +} + + diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.c b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.c new file mode 100644 index 0000000000..ea94719ecc --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.c @@ -0,0 +1,123 @@ + /* + * 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" +#include "stm32f4/periph.h" + +// I2C + +I2C_TypeDef * mcu_i2c_banks[3] = {I2C1, I2C2, I2C3}; + +const mcu_i2c_sda_obj_t mcu_i2c_sda_list[8] = { + I2C_SDA(1, 4, &pin_PB07), + I2C_SDA(1, 4, &pin_PB09), + I2C_SDA(2, 4, &pin_PB11), //not on LQFP100 + I2C_SDA(2, 9, &pin_PB09), + I2C_SDA(2, 9, &pin_PB03), + I2C_SDA(3, 4, &pin_PC09), + I2C_SDA(3, 9, &pin_PB04), + I2C_SDA(3, 9, &pin_PB08) +}; + +const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4] = { + I2C_SCL(1, 4, &pin_PB06), + I2C_SCL(1, 4, &pin_PB08), + I2C_SCL(2, 4, &pin_PB10), + I2C_SCL(3, 4, &pin_PA08) +}; + +// SPI + +SPI_TypeDef * mcu_spi_banks[5] = {SPI1, SPI2, SPI3, SPI4, SPI5}; + +const mcu_spi_sck_obj_t mcu_spi_sck_list[15] = { + SPI(1, 5, &pin_PA05), + SPI(1, 5, &pin_PB03), + SPI(2, 5, &pin_PB10), + SPI(2, 5, &pin_PB13), + SPI(2, 5, &pin_PC07), + SPI(2, 5, &pin_PD03), + SPI(3, 6, &pin_PB03), + SPI(3, 7, &pin_PB12), + SPI(3, 6, &pin_PC10), + SPI(4, 6, &pin_PB13), + SPI(4, 5, &pin_PE02), + SPI(4, 5, &pin_PE12), + SPI(5, 6, &pin_PB00), + SPI(5, 6, &pin_PE02), + SPI(5, 6, &pin_PE12) +}; + +const mcu_spi_mosi_obj_t mcu_spi_mosi_list[14] = { + SPI(1, 5, &pin_PA07), + SPI(1, 5, &pin_PB05), + SPI(2, 5, &pin_PB15), + SPI(2, 5, &pin_PC03), + SPI(3, 6, &pin_PB05), + SPI(3, 6, &pin_PC12), + SPI(3, 5, &pin_PD06), + SPI(4, 5, &pin_PA01), + SPI(4, 5, &pin_PE06), + SPI(4, 5, &pin_PE14), + SPI(5, 6, &pin_PA10), + SPI(5, 6, &pin_PB08), + SPI(5, 6, &pin_PE06), + SPI(5, 6, &pin_PE14) +}; + +const mcu_spi_miso_obj_t mcu_spi_miso_list[12] = { + SPI(1, 5, &pin_PA06), + SPI(1, 5, &pin_PB04), + SPI(2, 5, &pin_PB14), + SPI(2, 5, &pin_PC02), + SPI(3, 6, &pin_PB04), + SPI(3, 6, &pin_PC11), + SPI(4, 6, &pin_PA11), + SPI(4, 5, &pin_PE05), + SPI(4, 5, &pin_PE13), + SPI(5, 6, &pin_PA12), + SPI(5, 6, &pin_PE05), + SPI(5, 6, &pin_PE13) +}; + +const mcu_spi_nss_obj_t mcu_spi_nss_list[12] = { + SPI(1, 5, &pin_PA04), + SPI(1, 5, &pin_PA15), + SPI(2, 5, &pin_PB09), + SPI(2, 5, &pin_PB12), + SPI(3, 6, &pin_PA04), + SPI(3, 6, &pin_PA15), + SPI(4, 6, &pin_PB12), + SPI(4, 5, &pin_PE04), + SPI(4, 5, &pin_PE11), + SPI(5, 6, &pin_PB01), + SPI(5, 6, &pin_PE04), + SPI(5, 6, &pin_PE11) +}; + +//UART, Etc diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.h b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.h new file mode 100644 index 0000000000..d12bbba93e --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.h @@ -0,0 +1,45 @@ +/* + * 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_STM32F411VE_PERIPH_H +#define MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411VE_PERIPH_H + +//I2C +extern I2C_TypeDef * mcu_i2c_banks[3]; + +extern const mcu_i2c_sda_obj_t mcu_i2c_sda_list[8]; +extern const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4]; + + +//SPI +extern SPI_TypeDef * mcu_spi_banks[5]; + +extern const mcu_spi_sck_obj_t mcu_spi_sck_list[15]; +extern const mcu_spi_mosi_obj_t mcu_spi_mosi_list[14]; +extern const mcu_spi_miso_obj_t mcu_spi_miso_list[12]; +extern const mcu_spi_nss_obj_t mcu_spi_nss_list[12]; + +#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411VE_PERIPH_H \ No newline at end of file diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.c b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.c new file mode 100644 index 0000000000..c56de5a295 --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.c @@ -0,0 +1,161 @@ + /* + * 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, 2, NO_ADC); +const mcu_pin_obj_t pin_PE03 = PIN(4, 3, NO_ADC); +const mcu_pin_obj_t pin_PE04 = PIN(4, 4, NO_ADC); +const mcu_pin_obj_t pin_PE05 = PIN(4, 5, NO_ADC); +const mcu_pin_obj_t pin_PE06 = PIN(4, 6, NO_ADC); + +const mcu_pin_obj_t pin_PC13 = PIN(2, 13, NO_ADC); //anti-tamp +const mcu_pin_obj_t pin_PC14 = PIN(2, 14, NO_ADC); //OSC32_IN +const mcu_pin_obj_t pin_PC15 = PIN(2, 15, NO_ADC); //OSC32_OUT + +const mcu_pin_obj_t pin_PF00 = PIN(5, 0, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF01 = PIN(5, 1, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF02 = PIN(5, 2, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF03 = PIN(5, 3, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF04 = PIN(5, 4, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF05 = PIN(5, 5, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF06 = PIN(5, 6, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF07 = PIN(5, 7, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF08 = PIN(5, 8, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF09 = PIN(5, 9, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF10 = PIN(5, 10, NO_ADC); // 144 only + +const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_1,10)); +const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_1,11)); +const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_1,12)); +const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_1,13)); + +const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_1,0)); +const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_1,1)); +const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_1,2)); +const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_1,3)); +const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_1,4)); +const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_1,5)); +const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_1,6)); +const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_1,7)); + +const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_1,14)); +const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_1,15)); + +const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_1,8)); +const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_1,9)); +const mcu_pin_obj_t pin_PB02 = PIN(1, 2, NO_ADC); + +const mcu_pin_obj_t pin_PF11 = PIN(5, 11, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF12 = PIN(5, 12, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF13 = PIN(5, 13, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF14 = PIN(5, 14, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PF15 = PIN(5, 15, NO_ADC); // 144 only + +const mcu_pin_obj_t pin_PG00 = PIN(6, 0, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG01 = PIN(6, 1, NO_ADC); // 144 only + +const mcu_pin_obj_t pin_PE07 = PIN(4, 7, NO_ADC); +const mcu_pin_obj_t pin_PE08 = PIN(4, 8, NO_ADC); +const mcu_pin_obj_t pin_PE09 = PIN(4, 9, NO_ADC); +const mcu_pin_obj_t pin_PE10 = PIN(4, 10, NO_ADC); +const mcu_pin_obj_t pin_PE11 = PIN(4, 11, NO_ADC); +const mcu_pin_obj_t pin_PE12 = PIN(4, 12, NO_ADC); +const mcu_pin_obj_t pin_PE13 = PIN(4, 13, NO_ADC); +const mcu_pin_obj_t pin_PE14 = PIN(4, 14, NO_ADC); +const mcu_pin_obj_t pin_PE15 = PIN(4, 15, NO_ADC); + +const mcu_pin_obj_t pin_PB10 = PIN(1, 10, NO_ADC); +const mcu_pin_obj_t pin_PB11 = PIN(1, 11, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PB12 = PIN(1, 12, NO_ADC); +const mcu_pin_obj_t pin_PB13 = PIN(1, 13, NO_ADC); +const mcu_pin_obj_t pin_PB14 = PIN(1, 14, NO_ADC); +const mcu_pin_obj_t pin_PB15 = PIN(1, 15, NO_ADC); + +const mcu_pin_obj_t pin_PD08 = PIN(3, 8, NO_ADC); +const mcu_pin_obj_t pin_PD09 = PIN(3, 9, NO_ADC); +const mcu_pin_obj_t pin_PD10 = PIN(3, 10, NO_ADC); +const mcu_pin_obj_t pin_PD11 = PIN(3, 11, NO_ADC); +const mcu_pin_obj_t pin_PD12 = PIN(3, 12, NO_ADC); +const mcu_pin_obj_t pin_PD13 = PIN(3, 13, NO_ADC); +const mcu_pin_obj_t pin_PD14 = PIN(3, 14, NO_ADC); +const mcu_pin_obj_t pin_PD15 = PIN(3, 15, NO_ADC); + +const mcu_pin_obj_t pin_PG02 = PIN(6, 2, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG03 = PIN(6, 3, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG04 = PIN(6, 4, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG05 = PIN(6, 5, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG06 = PIN(6, 6, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG07 = PIN(6, 7, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG08 = PIN(6, 8, NO_ADC); // 144 only + +const mcu_pin_obj_t pin_PC06 = PIN(2, 6, NO_ADC); +const mcu_pin_obj_t pin_PC07 = PIN(2, 7, NO_ADC); +const mcu_pin_obj_t pin_PC08 = PIN(2, 8, NO_ADC); +const mcu_pin_obj_t pin_PC09 = PIN(2, 9, NO_ADC); + +const mcu_pin_obj_t pin_PA08 = PIN(0, 8, NO_ADC); +const mcu_pin_obj_t pin_PA09 = PIN(0, 9, NO_ADC); +const mcu_pin_obj_t pin_PA10 = PIN(0, 10, NO_ADC); +const mcu_pin_obj_t pin_PA11 = PIN(0, 11, NO_ADC); +const mcu_pin_obj_t pin_PA12 = PIN(0, 12, NO_ADC); +const mcu_pin_obj_t pin_PA13 = PIN(0, 13, NO_ADC); +const mcu_pin_obj_t pin_PA14 = PIN(0, 14, NO_ADC); +const mcu_pin_obj_t pin_PA15 = PIN(0, 15, NO_ADC); + +const mcu_pin_obj_t pin_PC10 = PIN(2, 10, NO_ADC); +const mcu_pin_obj_t pin_PC11 = PIN(2, 11, NO_ADC); +const mcu_pin_obj_t pin_PC12 = PIN(2, 12, NO_ADC); + +const mcu_pin_obj_t pin_PD00 = PIN(3, 0, NO_ADC); +const mcu_pin_obj_t pin_PD01 = PIN(3, 1, NO_ADC); +const mcu_pin_obj_t pin_PD02 = PIN(3, 2, NO_ADC); +const mcu_pin_obj_t pin_PD03 = PIN(3, 3, NO_ADC); +const mcu_pin_obj_t pin_PD04 = PIN(3, 4, NO_ADC); +const mcu_pin_obj_t pin_PD05 = PIN(3, 5, NO_ADC); +const mcu_pin_obj_t pin_PD06 = PIN(3, 6, NO_ADC); +const mcu_pin_obj_t pin_PD07 = PIN(3, 7, NO_ADC); + +const mcu_pin_obj_t pin_PG09 = PIN(6, 9, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG10 = PIN(6, 10, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG11 = PIN(6, 11, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG12 = PIN(6, 12, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG13 = PIN(6, 13, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG14 = PIN(6, 14, NO_ADC); // 144 only +const mcu_pin_obj_t pin_PG15 = PIN(6, 15, NO_ADC); // 144 only + +const mcu_pin_obj_t pin_PB03 = PIN(1, 3, NO_ADC); +const mcu_pin_obj_t pin_PB04 = PIN(1, 4, NO_ADC); +const mcu_pin_obj_t pin_PB05 = PIN(1, 5, NO_ADC); +const mcu_pin_obj_t pin_PB06 = PIN(1, 6, NO_ADC); +const mcu_pin_obj_t pin_PB07 = PIN(1, 7, NO_ADC); +const mcu_pin_obj_t pin_PB08 = PIN(1, 8, NO_ADC); +const mcu_pin_obj_t pin_PB09 = PIN(1, 9, NO_ADC); + +const mcu_pin_obj_t pin_PE00 = PIN(4, 0, NO_ADC); +const mcu_pin_obj_t pin_PE01 = PIN(4, 1, NO_ADC); diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.h b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.h new file mode 100644 index 0000000000..180f5c316f --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.h @@ -0,0 +1,158 @@ +/* + * 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; +extern const mcu_pin_obj_t pin_PC14; +//pg 51 +extern const mcu_pin_obj_t pin_PC15; +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 0000000000..3ba897069b --- /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 0000000000..89a356f0b4 --- /dev/null +++ b/ports/stm32f4/stm32f4 @@ -0,0 +1 @@ +Subproject commit 89a356f0b44883d55c45a5d22940777a44a2b881 diff --git a/ports/stm32f4/supervisor/cpu.s b/ports/stm32f4/supervisor/cpu.s new file mode 100755 index 0000000000..9e6807a5e2 --- /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 0000000000..046b26baf2 --- /dev/null +++ b/ports/stm32f4/supervisor/internal_flash.c @@ -0,0 +1,204 @@ +/* + * 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 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 "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" + +#include "stm32f4xx_hal.h" + +typedef struct { + uint32_t base_address; + uint32_t sector_size; + uint32_t sector_count; +} flash_layout_t; + +/*------------------------------------------------------------------*/ +/* Internal Flash API + *------------------------------------------------------------------*/ + +static const flash_layout_t flash_layout[] = { + { 0x08000000, 0x04000, 4 }, + { 0x08010000, 0x10000, 1 }, + { 0x08020000, 0x20000, 3 }, + #if defined(FLASH_SECTOR_8) + { 0x08080000, 0x20000, 4 }, + #endif + #if defined(FLASH_SECTOR_12) + { 0x08100000, 0x04000, 4 }, + { 0x08110000, 0x10000, 1 }, + { 0x08120000, 0x20000, 7 }, + #endif +}; + +static uint8_t sector_copy[0x4000] __attribute__((aligned(4))); + +//Return the sector of a given flash address. +uint32_t flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *size) { + if (addr >= flash_layout[0].base_address) { + uint32_t sector_index = 0; + for (uint8_t i = 0; i < MP_ARRAY_SIZE(flash_layout); ++i) { + for (uint8_t j = 0; j < flash_layout[i].sector_count; ++j) { + uint32_t sector_start_next = flash_layout[i].base_address + + (j + 1) * flash_layout[i].sector_size; + if (addr < sector_start_next) { + if (start_addr != NULL) { + *start_addr = flash_layout[i].base_address + + j * flash_layout[i].sector_size; + } + if (size != NULL) { + *size = flash_layout[i].sector_size; + } + return sector_index; + } + ++sector_index; + } + } + } + return 0; +} + +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 INTERNAL_FLASH_FILESYSTEM_NUM_BLOCKS; +} + +void supervisor_flash_flush(void) { +} + +static int32_t convert_block_to_flash_addr(uint32_t block) { + if (0 <= block && block < INTERNAL_FLASH_FILESYSTEM_NUM_BLOCKS) { + // a block in partition 1 + return INTERNAL_FLASH_FILESYSTEM_START_ADDR + block * FILESYSTEM_BLOCK_SIZE; + } + // bad block + return -1; +} + +mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { + int32_t src = convert_block_to_flash_addr(block); + if (src == -1) { + // bad block number + return false; + } + memcpy(dest, (uint8_t*) src, FILESYSTEM_BLOCK_SIZE*num_blocks); + return 0; // success +} + +bool supervisor_flash_write_block(const uint8_t *src, uint32_t block) { + int32_t dest = convert_block_to_flash_addr(block); + if (dest == -1) { + // bad block number + mp_printf(&mp_plat_print, "BAD FLASH BLOCK ERROR"); + return false; + } + + // unlock flash + HAL_FLASH_Unlock(); + + // set up for erase + FLASH_EraseInitTypeDef EraseInitStruct; + EraseInitStruct.TypeErase = TYPEERASE_SECTORS; + EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3; // voltage range needs to be 2.7V to 3.6V + // get the sector information + uint32_t sector_size; + uint32_t sector_start_addr; + EraseInitStruct.Sector = flash_get_sector_info(dest, §or_start_addr, §or_size); + EraseInitStruct.NbSectors = 1; + if (sector_size>0x4000) return false; + + // copy the sector + memcpy(sector_copy,(void *)sector_start_addr,sector_size); + + // // overwrite sector data + memcpy(sector_copy+(dest-sector_start_addr),src,FILESYSTEM_BLOCK_SIZE); + + // find end address, subtract for number of sectors + // Shouldn't be required since blocks will always fit in a single sector, they should never overlap + //EraseInitStruct.NbSectors = flash_get_sector_info(dest + FILESYSTEM_BLOCK_SIZE - 1, NULL, NULL) - EraseInitStruct.Sector + 1; + + // erase the sector + uint32_t SectorError = 0; + if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) { + // error occurred during sector erase + HAL_FLASH_Lock(); // lock the flash + mp_printf(&mp_plat_print, "FLASH SECTOR ERASE ERROR"); + return false; + } + + __HAL_FLASH_DATA_CACHE_DISABLE(); + __HAL_FLASH_INSTRUCTION_CACHE_DISABLE(); + + __HAL_FLASH_DATA_CACHE_RESET(); + __HAL_FLASH_INSTRUCTION_CACHE_RESET(); + + __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); + __HAL_FLASH_DATA_CACHE_ENABLE(); + + // reprogram the sector + for (uint32_t i = 0; i < sector_size; i++) { + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, sector_start_addr, (uint64_t)sector_copy[i]) != HAL_OK) { + // error occurred during flash write + HAL_FLASH_Lock(); // lock the flash + mp_printf(&mp_plat_print, "FLASH WRITE ERROR"); + return false; + } + sector_start_addr += 1; + } + + // lock the flash + HAL_FLASH_Lock(); + + return true; +} + +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 +} + +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 0000000000..b6d26a07fe --- /dev/null +++ b/ports/stm32f4/supervisor/internal_flash.h @@ -0,0 +1,58 @@ +/* + * 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 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_INTERNAL_FLASH_H +#define MICROPY_INCLUDED_STM32F4_INTERNAL_FLASH_H + +#include +#include + +#include "py/mpconfig.h" + +#ifdef STM32F411xE +#define STM32_FLASH_SIZE 0x80000 //512KiB +#define INTERNAL_FLASH_FILESYSTEM_SIZE 0xC000 //48KiB +#endif + +#ifdef STM32F412Zx +#define STM32_FLASH_SIZE 0x100000 //1MB +#define INTERNAL_FLASH_FILESYSTEM_SIZE 0xC000 //48KiB +#endif + +#ifdef STM32F405xx +#define STM32_FLASH_SIZE 0x100000 //1MB +#define INTERNAL_FLASH_FILESYSTEM_SIZE 0xC000 //48KiB +#endif + +#define STM32_FLASH_OFFSET 0x8000000 //All STM32 chips map to this flash location + +#define INTERNAL_FLASH_FILESYSTEM_START_ADDR 0x08004000 +#define INTERNAL_FLASH_FILESYSTEM_NUM_BLOCKS (INTERNAL_FLASH_FILESYSTEM_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_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 0000000000..7a8681bd95 --- /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 0000000000..df7a6ca427 --- /dev/null +++ b/ports/stm32f4/supervisor/port.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 + * 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 "common-hal/microcontroller/Pin.h" +#include "common-hal/busio/I2C.h" +#include "common-hal/busio/SPI.h" + +#include "stm32f4/clocks.h" +#include "stm32f4/gpio.h" + +#include "stm32f4xx_hal.h" + +safe_mode_t port_init(void) { + HAL_Init(); + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + + stm32f4_peripherals_clocks_init(); + stm32f4_peripherals_gpio_init(); + + tick_init(); + board_init(); + + return NO_SAFE_MODE; +} + +void reset_port(void) { + reset_all_pins(); + i2c_reset(); + spi_reset(); +} + +void reset_to_bootloader(void) { + +} + +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/stm32f4/supervisor/qspi_flash.c b/ports/stm32f4/supervisor/qspi_flash.c new file mode 100644 index 0000000000..f3915273b3 --- /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 0000000000..ce13660000 --- /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 + * 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/mphal.h" +#include +#include "supervisor/serial.h" +#include "stm32f4xx_hal.h" +#include "stm32f4/gpio.h" + +UART_HandleTypeDef huart2; + +void serial_init(void) { + huart2.Instance = USART2; + huart2.Init.BaudRate = 115200; + 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) + { + stm32f4_peripherals_status_led(1,1); + } +} + +bool serial_connected(void) { + return true; +} + +char serial_read(void) { + uint8_t data; + HAL_UART_Receive(&huart2, &data, 1,500); + 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 0000000000..f327050f58 --- /dev/null +++ b/ports/stm32f4/supervisor/usb.c @@ -0,0 +1,85 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach 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 "tick.h" +#include "supervisor/usb.h" +#include "lib/utils/interrupt_char.h" +#include "lib/mp-readline/readline.h" +#include "stm32f4xx_hal.h" + +#include "common-hal/microcontroller/Pin.h" + +void init_usb_hardware(void) { + //TODO: if future chips overload this with options, move to peripherals management. + + 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 + */ + __HAL_RCC_GPIOA_CLK_ENABLE(); + + /* Configure DM DP Pins */ + GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + never_reset_pin_number(0, 11); + never_reset_pin_number(0, 12); + + /* Configure VBUS Pin */ + GPIO_InitStruct.Pin = GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + never_reset_pin_number(0, 9); + + /* This for ID line debug */ + GPIO_InitStruct.Pin = GPIO_PIN_10; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + never_reset_pin_number(0, 10); + +#ifdef STM32F412Zx + /* Configure POWER_SWITCH IO pin (F412 ONLY)*/ + GPIO_InitStruct.Pin = GPIO_PIN_8; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + never_reset_pin_number(0, 8); +#endif + + /* Peripheral clock enable */ + __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); +} diff --git a/ports/stm32f4/system_stm32f4xx.c b/ports/stm32f4/system_stm32f4xx.c new file mode 100644 index 0000000000..3303f969d9 --- /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 0000000000..43521fb516 --- /dev/null +++ b/ports/stm32f4/tick.c @@ -0,0 +1,90 @@ +/* + * 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 +} + +uint32_t HAL_GetTick(void) //override ST HAL +{ + return (uint32_t)ticks_ms; +} + +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 0000000000..e4772fa2cf --- /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/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 782314fc70..b72d753904 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -108,11 +108,24 @@ 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_AUDIOMIXER),1) +SRC_PATTERNS += audiomixer/% +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/% +SRC_PATTERNS += _bleio/% endif ifeq ($(CIRCUITPY_BOARD),1) SRC_PATTERNS += board/% @@ -211,27 +224,29 @@ ifeq ($(CIRCUITPY_PEW),1) SRC_PATTERNS += _pew/% endif -# All possible sources are listed here, and are filtered by SRC_PATTERNS. -SRC_COMMON_HAL = \ -$(filter $(SRC_PATTERNS), \ +# 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 \ - bleio/__init__.c \ - bleio/Adapter.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 \ board/__init__.c \ busio/I2C.c \ busio/SPI.c \ @@ -263,16 +278,18 @@ $(filter $(SRC_PATTERNS), \ rtc/__init__.c \ supervisor/Runtime.c \ supervisor/__init__.c \ - time/__init__.c \ - touchio/TouchIn.c \ - touchio/__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 \ @@ -286,37 +303,36 @@ SRC_BINDINGS_ENUMS += \ help.c \ util.c -SRC_BINDINGS_ENUMS += \ -$(filter $(SRC_PATTERNS), \ - bleio/Address.c \ - bleio/ScanEntry.c \ -) - -# All possible sources are listed here, and are filtered by SRC_PATTERNS. -SRC_SHARED_MODULE = \ -$(filter $(SRC_PATTERNS), \ +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 \ - audioio/Mixer.c \ - audioio/RawSample.c \ - audioio/WaveFile.c \ + audiocore/__init__.c \ + audiocore/RawSample.c \ + audiocore/WaveFile.c \ + audiomixer/__init__.c \ + audiomixer/Mixer.c \ + audiomixer/MixerVoice.c \ bitbangio/I2C.c \ bitbangio/OneWire.c \ bitbangio/SPI.c \ bitbangio/__init__.c \ board/__init__.c \ - bleio/Address.c \ - bleio/ScanEntry.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 \ @@ -339,7 +355,28 @@ $(filter $(SRC_PATTERNS), \ uheap/__init__.c \ ustack/__init__.c \ _pew/__init__.c \ - _pew/PewPew.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) diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 2026185ef9..2cb6178198 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -230,6 +230,13 @@ extern const struct _mp_obj_module_t audiobusio_module; #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; @@ -237,6 +244,20 @@ extern const struct _mp_obj_module_t audioio_module; #define AUDIOIO_MODULE #endif +#if CIRCUITPY_AUDIOMIXER +#define AUDIOMIXER_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_audiomixer), (mp_obj_t)&audiomixer_module }, +extern const struct _mp_obj_module_t audiomixer_module; +#else +#define AUDIOMIXER_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; @@ -245,7 +266,7 @@ extern const struct _mp_obj_module_t bitbangio_module; #endif #if CIRCUITPY_BLEIO -#define BLEIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_bleio), (mp_obj_t)&bleio_module }, +#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 @@ -259,13 +280,7 @@ extern const struct _mp_obj_module_t board_module; #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)) -#if BOARD_I2C -#define BOARD_I2C_ROOT_POINTER mp_obj_t shared_i2c_bus; -#else -#define BOARD_I2C_ROOT_POINTER -#endif - -// SPI is always allocated off the heap. +// I2C and SPI are always allocated off the heap. #if BOARD_UART #define BOARD_UART_ROOT_POINTER mp_obj_t shared_uart_bus; @@ -275,7 +290,6 @@ extern const struct _mp_obj_module_t board_module; #else #define BOARD_MODULE -#define BOARD_I2C_ROOT_POINTER #define BOARD_UART_ROOT_POINTER #endif @@ -300,7 +314,7 @@ 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 (3) +#define CIRCUITPY_DISPLAY_LIMIT (1) #else #define DISPLAYIO_MODULE #define FONTIO_MODULE @@ -564,7 +578,10 @@ extern const struct _mp_obj_module_t ustack_module; #define MICROPY_PORT_BUILTIN_MODULES_STRONG_LINKS \ ANALOGIO_MODULE \ AUDIOBUSIO_MODULE \ + AUDIOCORE_MODULE \ AUDIOIO_MODULE \ + AUDIOMIXER_MODULE \ + AUDIOPWMIO_MODULE \ BITBANGIO_MODULE \ BLEIO_MODULE \ BOARD_MODULE \ @@ -587,8 +604,8 @@ extern const struct _mp_obj_module_t ustack_module; WIZNET_MODULE \ PEW_MODULE \ PIXELBUF_MODULE \ - PULSEIO_MODULE \ PS2IO_MODULE \ + PULSEIO_MODULE \ RANDOM_MODULE \ RE_MODULE \ ROTARYIO_MODULE \ @@ -631,12 +648,12 @@ extern const struct _mp_obj_module_t ustack_module; GAMEPAD_ROOT_POINTERS \ mp_obj_t pew_singleton; \ mp_obj_t terminal_tilegrid_tiles; \ - BOARD_I2C_ROOT_POINTER \ 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() diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 47303a73a7..c5756f4880 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -41,13 +41,26 @@ ifndef CIRCUITPY_FULL_BUILD 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 = 1 +CIRCUITPY_ANALOGIO = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_ANALOGIO=$(CIRCUITPY_ANALOGIO) @@ -61,29 +74,54 @@ 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_AUDIOMIXER +CIRCUITPY_AUDIOMIXER = $(CIRCUITPY_AUDIOIO) +endif +CFLAGS += -DCIRCUITPY_AUDIOMIXER=$(CIRCUITPY_AUDIOMIXER) + ifndef CIRCUITPY_BITBANGIO CIRCUITPY_BITBANGIO = $(CIRCUITPY_FULL_BUILD) endif CFLAGS += -DCIRCUITPY_BITBANGIO=$(CIRCUITPY_BITBANGIO) -# Explicitly enabled for boards that support bleio. +# Explicitly enabled for boards that support _bleio. ifndef CIRCUITPY_BLEIO CIRCUITPY_BLEIO = 0 endif CFLAGS += -DCIRCUITPY_BLEIO=$(CIRCUITPY_BLEIO) ifndef CIRCUITPY_BOARD -CIRCUITPY_BOARD = 1 +CIRCUITPY_BOARD = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_BOARD=$(CIRCUITPY_BOARD) ifndef CIRCUITPY_BUSIO -CIRCUITPY_BUSIO = 1 +CIRCUITPY_BUSIO = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_BUSIO=$(CIRCUITPY_BUSIO) ifndef CIRCUITPY_DIGITALIO -CIRCUITPY_DIGITALIO = 1 +CIRCUITPY_DIGITALIO = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_DIGITALIO=$(CIRCUITPY_DIGITALIO) @@ -113,17 +151,17 @@ endif CFLAGS += -DCIRCUITPY_I2CSLAVE=$(CIRCUITPY_I2CSLAVE) ifndef CIRCUITPY_MATH -CIRCUITPY_MATH = 1 +CIRCUITPY_MATH = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH) ifndef CIRCUITPY_MICROCONTROLLER -CIRCUITPY_MICROCONTROLLER = 1 +CIRCUITPY_MICROCONTROLLER = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_MICROCONTROLLER=$(CIRCUITPY_MICROCONTROLLER) ifndef CIRCUITPY_NEOPIXEL_WRITE -CIRCUITPY_NEOPIXEL_WRITE = 1 +CIRCUITPY_NEOPIXEL_WRITE = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_NEOPIXEL_WRITE=$(CIRCUITPY_NEOPIXEL_WRITE) @@ -134,12 +172,12 @@ endif CFLAGS += -DCIRCUITPY_NETWORK=$(CIRCUITPY_NETWORK) ifndef CIRCUITPY_NVM -CIRCUITPY_NVM = 1 +CIRCUITPY_NVM = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_NVM=$(CIRCUITPY_NVM) ifndef CIRCUITPY_OS -CIRCUITPY_OS = 1 +CIRCUITPY_OS = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_OS=$(CIRCUITPY_OS) @@ -149,7 +187,7 @@ endif CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF) ifndef CIRCUITPY_PULSEIO -CIRCUITPY_PULSEIO = 1 +CIRCUITPY_PULSEIO = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_PULSEIO=$(CIRCUITPY_PULSEIO) @@ -160,17 +198,17 @@ endif CFLAGS += -DCIRCUITPY_PS2IO=$(CIRCUITPY_PS2IO) ifndef CIRCUITPY_RANDOM -CIRCUITPY_RANDOM = 1 +CIRCUITPY_RANDOM = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_RANDOM=$(CIRCUITPY_RANDOM) ifndef CIRCUITPY_ROTARYIO -CIRCUITPY_ROTARYIO = 1 +CIRCUITPY_ROTARYIO = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_ROTARYIO=$(CIRCUITPY_ROTARYIO) ifndef CIRCUITPY_RTC -CIRCUITPY_RTC = 1 +CIRCUITPY_RTC = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_RTC=$(CIRCUITPY_RTC) @@ -189,27 +227,33 @@ endif CFLAGS += -DCIRCUITPY_STAGE=$(CIRCUITPY_STAGE) ifndef CIRCUITPY_STORAGE -CIRCUITPY_STORAGE = 1 +CIRCUITPY_STORAGE = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_STORAGE=$(CIRCUITPY_STORAGE) ifndef CIRCUITPY_STRUCT -CIRCUITPY_STRUCT = 1 +CIRCUITPY_STRUCT = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_STRUCT=$(CIRCUITPY_STRUCT) ifndef CIRCUITPY_SUPERVISOR -CIRCUITPY_SUPERVISOR = 1 +CIRCUITPY_SUPERVISOR = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_SUPERVISOR=$(CIRCUITPY_SUPERVISOR) ifndef CIRCUITPY_TIME -CIRCUITPY_TIME = 1 +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 = 1 +CIRCUITPY_TOUCHIO = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_TOUCHIO=$(CIRCUITPY_TOUCHIO) @@ -220,12 +264,12 @@ endif CFLAGS += -DCIRCUITPY_UHEAP=$(CIRCUITPY_UHEAP) ifndef CIRCUITPY_USB_HID -CIRCUITPY_USB_HID = 1 +CIRCUITPY_USB_HID = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_USB_HID=$(CIRCUITPY_USB_HID) ifndef CIRCUITPY_USB_MIDI -CIRCUITPY_USB_MIDI = 1 +CIRCUITPY_USB_MIDI = $(CIRCUITPY_DEFAULT_BUILD) endif CFLAGS += -DCIRCUITPY_USB_MIDI=$(CIRCUITPY_USB_MIDI) @@ -239,3 +283,9 @@ 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/makeqstrdata.py b/py/makeqstrdata.py index 5b5ec1c378..8e3835d861 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -180,7 +180,7 @@ def compress(encoding_table, decompressed): if not isinstance(decompressed, bytes): raise TypeError() values, lengths = encoding_table - enc = bytearray(len(decompressed)) + enc = bytearray(len(decompressed) * 2) #print(decompressed) #print(lengths) current_bit = 7 @@ -227,6 +227,8 @@ def compress(encoding_table, decompressed): 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): diff --git a/py/obj.c b/py/obj.c index 322a302f97..bd2aaf9d26 100644 --- a/py/obj.c +++ b/py/obj.c @@ -63,6 +63,9 @@ const char *mp_obj_get_type_str(mp_const_obj_t o_in) { void mp_obj_print_helper(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { // There can be data structures nested too deep, or just recursive MP_STACK_CHECK(); + #ifdef RUN_BACKGROUND_TASKS + RUN_BACKGROUND_TASKS; + #endif #ifndef NDEBUG if (o_in == MP_OBJ_NULL) { mp_print_str(print, "(nil)"); diff --git a/py/obj.h b/py/obj.h index 6eead377db..cf4216d02f 100644 --- a/py/obj.h +++ b/py/obj.h @@ -647,6 +647,7 @@ 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); @@ -668,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); diff --git a/py/objlist.c b/py/objlist.c index 558c4c6115..ea38e64e55 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -68,6 +68,11 @@ STATIC mp_obj_t list_extend_from_iter(mp_obj_t list, mp_obj_t iterable) { return list; } +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, kw_args, 0, 1, false); diff --git a/py/objstr.c b/py/objstr.c index ebd11d5cc2..6ef9a15b5e 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -41,6 +41,12 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ 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 */ @@ -2088,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; diff --git a/py/objstr.h b/py/objstr.h index 0efe62a801..61a11d0bd6 100644 --- a/py/objstr.h +++ b/py/objstr.h @@ -77,6 +77,9 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s 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/objtuple.c b/py/objtuple.c index 474f81c1a5..ed13cdcef2 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -251,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/stream.c b/py/stream.c index 08c749cc30..1d25f64706 100644 --- a/py/stream.c +++ b/py/stream.c @@ -341,6 +341,9 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in) { p = vstr_extend(&vstr, DEFAULT_BUFFER_SIZE); current_read = DEFAULT_BUFFER_SIZE; } + #ifdef RUN_BACKGROUND_TASKS + RUN_BACKGROUND_TASKS; + #endif } vstr.len = total_size; diff --git a/shared-bindings/bleio/Adapter.c b/shared-bindings/_bleio/Adapter.c similarity index 73% rename from shared-bindings/bleio/Adapter.c rename to shared-bindings/_bleio/Adapter.c index 7b8df51034..0caca96b86 100644 --- a/shared-bindings/bleio/Adapter.c +++ b/shared-bindings/_bleio/Adapter.c @@ -26,10 +26,10 @@ */ #include "py/objproperty.h" -#include "shared-bindings/bleio/Address.h" -#include "shared-bindings/bleio/Adapter.h" +#include "shared-bindings/_bleio/Address.h" +#include "shared-bindings/_bleio/Adapter.h" -//| .. currentmodule:: bleio +//| .. currentmodule:: _bleio //| //| :class:`Adapter` --- BLE adapter information //| ---------------------------------------------------- @@ -38,27 +38,21 @@ //| //| Usage:: //| -//| import bleio -//| bleio.adapter.enabled = True -//| print(bleio.adapter.address) +//| 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. +//| 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. //| - -//| .. attribute:: adapter.address -//| -//| MAC address of the BLE adapter. (read-only) -//| - STATIC mp_obj_t bleio_adapter_get_enabled(mp_obj_t self) { return mp_obj_new_bool(common_hal_bleio_adapter_get_enabled()); } @@ -80,13 +74,13 @@ const mp_obj_property_t bleio_adapter_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) { - mp_obj_t obj = bleio_address_type.make_new(&bleio_address_type, 1, 0, mp_const_none); - bleio_address_obj_t *address = MP_OBJ_TO_PTR(obj); + return MP_OBJ_FROM_PTR(common_hal_bleio_adapter_get_address()); - common_hal_bleio_adapter_get_address(address); - - return obj; } MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_address_obj, bleio_adapter_get_address); @@ -97,9 +91,29 @@ const mp_obj_property_t bleio_adapter_address_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); diff --git a/shared-bindings/bleio/Adapter.h b/shared-bindings/_bleio/Adapter.h similarity index 90% rename from shared-bindings/bleio/Adapter.h rename to shared-bindings/_bleio/Adapter.h index de9d1d6db1..932fc9c958 100644 --- a/shared-bindings/bleio/Adapter.h +++ b/shared-bindings/_bleio/Adapter.h @@ -28,12 +28,13 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H -#include "shared-module/bleio/Address.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 void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address); +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 similarity index 80% rename from shared-bindings/bleio/Address.c rename to shared-bindings/_bleio/Address.c index 37f01042ce..cdee02b5d7 100644 --- a/shared-bindings/bleio/Address.c +++ b/shared-bindings/_bleio/Address.c @@ -31,10 +31,10 @@ #include "py/objproperty.h" #include "py/objstr.h" #include "py/runtime.h" -#include "shared-bindings/bleio/Address.h" -#include "shared-module/bleio/Address.h" +#include "shared-bindings/_bleio/Address.h" +#include "shared-module/_bleio/Address.h" -//| .. currentmodule:: bleio +//| .. currentmodule:: _bleio //| //| :class:`Address` -- BLE address //| ========================================================= @@ -83,7 +83,21 @@ STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, //| .. attribute:: address_bytes //| -//| The bytes that make up the device address (read-only) +//| 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); @@ -147,18 +161,13 @@ STATIC mp_obj_t bleio_address_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_o 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); - if (kind == PRINT_STR) { - 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); + 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, - "%02x:%02x:%02x:%02x:%02x:%02x", - buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]); - } else { - mp_printf(print, "
"); - } + 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 @@ -179,13 +188,13 @@ STATIC void bleio_address_print(const mp_print_t *print, mp_obj_t self_in, mp_pr //| 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) }, + { 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_OBJ_NEW_SMALL_INT(0) }, - { MP_ROM_QSTR(MP_QSTR_RANDOM_STATIC), MP_OBJ_NEW_SMALL_INT(1) }, - { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_RESOLVABLE), MP_OBJ_NEW_SMALL_INT(2) }, - { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE), MP_OBJ_NEW_SMALL_INT(3) }, + { 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) }, }; diff --git a/shared-bindings/bleio/Address.h b/shared-bindings/_bleio/Address.h similarity index 98% rename from shared-bindings/bleio/Address.h rename to shared-bindings/_bleio/Address.h index 5e02ee210f..98b6f80e0e 100644 --- a/shared-bindings/bleio/Address.h +++ b/shared-bindings/_bleio/Address.h @@ -29,7 +29,7 @@ #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H #include "py/objtype.h" -#include "shared-module/bleio/Address.h" +#include "shared-module/_bleio/Address.h" #define BLEIO_ADDRESS_TYPE_PUBLIC (0) #define BLEIO_ADDRESS_TYPE_RANDOM_STATIC (1) diff --git a/shared-bindings/_bleio/Attribute.c b/shared-bindings/_bleio/Attribute.c new file mode 100644 index 0000000000..2d8b15b9f4 --- /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-module/bleio/Characteristic.h b/shared-bindings/_bleio/Attribute.h similarity index 72% rename from shared-module/bleio/Characteristic.h rename to shared-bindings/_bleio/Attribute.h index 27b43588fa..a0ce045003 100644 --- a/shared-module/bleio/Characteristic.h +++ b/shared-bindings/_bleio/Attribute.h @@ -24,17 +24,16 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H -#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ATTRIBUTE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ATTRIBUTE_H -// Flags for each characteristic property. Common across ports. -typedef struct { - bool broadcast : 1; - bool read : 1; - bool write_no_response : 1; - bool write : 1; - bool notify : 1; - bool indicate : 1; -} bleio_characteristic_properties_t; +#include "py/obj.h" -#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_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 similarity index 66% rename from shared-bindings/bleio/Central.c rename to shared-bindings/_bleio/Central.c index fc00bce5cc..084f40cd62 100644 --- a/shared-bindings/bleio/Central.c +++ b/shared-bindings/_bleio/Central.c @@ -34,13 +34,13 @@ #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" +#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 +//| .. currentmodule:: _bleio //| //| :class:`Central` -- A BLE central device //| ========================================================= @@ -49,19 +49,23 @@ //| //| Usage:: //| -//| import bleio +//| import _bleio //| -//| scanner = bleio.Scanner() +//| scanner = _bleio.Scanner() //| entries = scanner.scan(2.5) //| //| my_entry = None //| for entry in entries: -//| if entry.name is not None and entry.name == 'MyPeripheral': +//| if entry.name is not None and entry.name == 'InterestingPeripheral': //| my_entry = entry //| break //| -//| central = bleio.Central(my_entry.address) -//| central.connect(10.0) # timeout after 10 seconds +//| 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() @@ -79,24 +83,11 @@ STATIC mp_obj_t bleio_central_make_new(const mp_obj_type_t *type, size_t n_args, return MP_OBJ_FROM_PTR(self); } -//| .. method:: connect(address, timeout, *, service_uuids=None) -//| Attempts a connection to the remote peripheral. If the connection is successful, -//| Do BLE discovery for the listed services, to find their handles and characteristics. -//| The attribute `remote_services` will contain a list of all discovered services. +//| .. method:: connect(address, timeout, *, service_uuids_whitelist=None) +//| Attempts a connection to the remote peripheral. //| -//| :param bleio.Address address: The address of the peripheral to connect to +//| :param Address address: The address of the peripheral to connect to //| :param float/int timeout: Try to connect for timeout seconds. -//| :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. -//| If a service in service_uuids is not found during discovery, it will not -//| appear in `remote_services`. -//| -//| 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. (This restriction may be lifted in the future.) //| 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]); @@ -105,7 +96,6 @@ STATIC mp_obj_t bleio_central_connect(mp_uint_t n_args, const mp_obj_t *pos_args 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_QSTR_service_uuids_whitelist, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -119,7 +109,7 @@ STATIC mp_obj_t bleio_central_connect(mp_uint_t n_args, const mp_obj_t *pos_args 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, args[ARG_service_uuids_whitelist].u_obj); + common_hal_bleio_central_connect(self, address, timeout); return mp_const_none; } @@ -139,6 +129,46 @@ STATIC mp_obj_t bleio_central_disconnect(mp_obj_t self_in) { } 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. @@ -157,36 +187,14 @@ const mp_obj_property_t bleio_central_connected_obj = { (mp_obj_t)&mp_const_none_obj }, }; - -//| .. attribute:: remote_services (read-only) -//| -//| A tuple of services provided by the remote peripheral. -//| If the Central is not connected, an empty tuple will be returned. -//| -STATIC mp_obj_t bleio_central_get_remote_services(mp_obj_t self_in) { - bleio_central_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 *service_list = common_hal_bleio_central_get_remote_services(self); - return mp_obj_new_tuple(service_list->len, service_list->items); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_get_remote_services_obj, bleio_central_get_remote_services); - -const mp_obj_property_t bleio_central_remote_services_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_central_get_remote_services_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_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) }, - { MP_ROM_QSTR(MP_QSTR_remote_services), MP_ROM_PTR(&bleio_central_remote_services_obj) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_central_locals_dict, bleio_central_locals_dict_table); diff --git a/shared-bindings/bleio/Central.h b/shared-bindings/_bleio/Central.h similarity index 85% rename from shared-bindings/bleio/Central.h rename to shared-bindings/_bleio/Central.h index 0e84037f91..85d788654f 100644 --- a/shared-bindings/bleio/Central.h +++ b/shared-bindings/_bleio/Central.h @@ -28,15 +28,16 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H -#include "common-hal/bleio/Central.h" -#include "common-hal/bleio/Service.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, mp_obj_t service_uuids); +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_list_t *common_hal_bleio_central_get_remote_services(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 0000000000..1981555891 --- /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 similarity index 75% rename from shared-bindings/bleio/Characteristic.h rename to shared-bindings/_bleio/Characteristic.h index d450c42b4e..a816c60506 100644 --- a/shared-bindings/bleio/Characteristic.h +++ b/shared-bindings/_bleio/Characteristic.h @@ -28,17 +28,22 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H -#include "shared-module/bleio/Characteristic.h" -#include "common-hal/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_uuid_obj_t *uuid, bleio_characteristic_properties_t props, mp_obj_list_t *descriptor_list); +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 similarity index 97% rename from shared-bindings/bleio/CharacteristicBuffer.c rename to shared-bindings/_bleio/CharacteristicBuffer.c index 26f9e012b5..9cc708eb78 100644 --- a/shared-bindings/bleio/CharacteristicBuffer.c +++ b/shared-bindings/_bleio/CharacteristicBuffer.c @@ -30,8 +30,8 @@ #include "py/runtime.h" #include "py/stream.h" -#include "shared-bindings/bleio/CharacteristicBuffer.h" -#include "shared-bindings/bleio/UUID.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) { @@ -40,7 +40,7 @@ STATIC void raise_error_if_not_connected(bleio_characteristic_buffer_obj_t *self } } -//| .. currentmodule:: bleio +//| .. currentmodule:: _bleio //| //| :class:`CharacteristicBuffer` -- BLE Service incoming values buffer. //| ===================================================================== @@ -52,7 +52,7 @@ STATIC void raise_error_if_not_connected(bleio_characteristic_buffer_obj_t *self //| Monitor the given Characteristic. Each time a new value is written to the Characteristic //| add the newly-written bytes to a FIFO buffer. //| -//| :param bleio.Characteristic characteristic: The Characteristic to monitor. +//| :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. diff --git a/shared-bindings/bleio/CharacteristicBuffer.h b/shared-bindings/_bleio/CharacteristicBuffer.h similarity index 97% rename from shared-bindings/bleio/CharacteristicBuffer.h rename to shared-bindings/_bleio/CharacteristicBuffer.h index b45835ff39..83e6fef02f 100644 --- a/shared-bindings/bleio/CharacteristicBuffer.h +++ b/shared-bindings/_bleio/CharacteristicBuffer.h @@ -27,7 +27,7 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTICBUFFER_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTICBUFFER_H -#include "common-hal/bleio/CharacteristicBuffer.h" +#include "common-hal/_bleio/CharacteristicBuffer.h" extern const mp_obj_type_t bleio_characteristic_buffer_type; diff --git a/shared-bindings/_bleio/Descriptor.c b/shared-bindings/_bleio/Descriptor.c new file mode 100644 index 0000000000..0ab9fe8e9e --- /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 similarity index 57% rename from shared-bindings/bleio/Descriptor.h rename to shared-bindings/_bleio/Descriptor.h index fd11ea08cd..7544bdb17b 100644 --- a/shared-bindings/bleio/Descriptor.h +++ b/shared-bindings/_bleio/Descriptor.h @@ -28,31 +28,17 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H -#include "common-hal/bleio/Descriptor.h" -#include "common-hal/bleio/UUID.h" - -enum { - DESCRIPTOR_UUID_CHARACTERISTIC_EXTENDED_PROPERTIES = 0x2900, - DESCRIPTOR_UUID_CHARACTERISTIC_USER_DESCRIPTION = 0x2901, - DESCRIPTOR_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION = 0x2902, - DESCRIPTOR_UUID_SERVER_CHARACTERISTIC_CONFIGURATION = 0x2903, - DESCRIPTOR_UUID_CHARACTERISTIC_PRESENTATION_FORMAT = 0x2904, - DESCRIPTOR_UUID_CHARACTERISTIC_AGGREGATE_FORMAT = 0x2905, - DESCRIPTOR_UUID_VALID_RANGE = 0x2906, - DESCRIPTOR_UUID_EXTERNAL_REPORT_REFERENCE = 0x2907, - DESCRIPTOR_UUID_REPORT_REFERENCE = 0x2908, - DESCRIPTOR_UUID_NUMBER_OF_DIGITALS = 0x2909, - DESCRIPTOR_UUID_VALUE_TRIGGER_SETTING = 0x290A, - DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_CONFIGURATION = 0x290B, - DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_MEASUREMENT = 0x290C, - DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_TRIGGER_SETTING = 0x290D, - DESCRIPTOR_UUID_TIME_TRIGGER_SETTING = 0x290E, -}; +#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_uuid_obj_t *uuid); -extern mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self); -extern mp_obj_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self); +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 similarity index 60% rename from shared-bindings/bleio/Peripheral.c rename to shared-bindings/_bleio/Peripheral.c index 1302c96523..0bf2927442 100644 --- a/shared-bindings/bleio/Peripheral.c +++ b/shared-bindings/_bleio/Peripheral.c @@ -35,24 +35,23 @@ #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 "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" +#include "common-hal/_bleio/Peripheral.h" -static const char default_name[] = "CIRCUITPY"; - -#define ADV_INTERVAL_DEFAULT (1.0f) #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 +//| .. currentmodule:: _bleio //| //| :class:`Peripheral` -- A BLE peripheral device //| ========================================================= @@ -62,78 +61,58 @@ static const char default_name[] = "CIRCUITPY"; //| //| Usage:: //| -//| import bleio +//| from _bleio import Characteristic, Peripheral, Service //| from adafruit_ble.advertising import ServerAdvertisement //| -//| # Create a Characteristic. -//| chara = bleio.Characteristic(bleio.UUID(0x2919), read=True, notify=True) -//| -//| # Create a Service providing that one Characteristic. -//| serv = bleio.Service(bleio.UUID(0x180f), [chara]) -//| //| # Create a peripheral and start it up. -//| periph = bleio.Peripheral([service]) -//| adv = ServerAdvertisement(periph) -//| periph.start_advertising(adv.advertising_data_bytes, adv.scan_response_bytes) +//| peripheral = _bleio.Peripheral() //| -//| while not periph.connected: +//| # 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(services=(), \*, name='CIRCUITPY') +//| .. class:: Peripheral(name=None) //| //| Create a new Peripheral object. //| -//| :param iterable services: the Service objects representing services available from this peripheral, if any. -//| A non-connectable peripheral will have no services. -//| :param str name: The name used when advertising this peripheral. Use ``None`` when a name is not needed, -//| such as when the peripheral is a beacon +//| :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_services, ARG_name }; + enum { ARG_name }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_services, MP_ARG_OBJ, {.u_obj = mp_const_empty_tuple} }, - { MP_QSTR_name, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { 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); - // If services is not an iterable, an exception will be thrown. - mp_obj_iter_buf_t iter_buf; - mp_obj_t iterable = mp_getiter(args[ARG_services].u_obj, &iter_buf); - bleio_peripheral_obj_t *self = m_new_obj(bleio_peripheral_obj_t); self->base.type = &bleio_peripheral_type; - // Copy the services list and validate its items. - mp_obj_t service_list_obj = mp_obj_new_list(0, NULL); - mp_obj_list_t *service_list = MP_OBJ_FROM_PTR(service_list_obj); - - mp_obj_t service; - while ((service = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - if (!MP_OBJ_IS_TYPE(service, &bleio_service_type)) { - mp_raise_ValueError(translate("non-Service found in services")); - } - mp_obj_list_append(service_list, service); - } - - const mp_obj_t name = args[ARG_name].u_obj; - mp_obj_t name_str; - if (name == MP_OBJ_NULL || name == mp_const_none) { - name_str = mp_obj_new_str(default_name, strlen(default_name)); - } else if (MP_OBJ_IS_STR(name)) { - name_str = name; - } else { + 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, service_list, name_str); + common_hal_bleio_peripheral_construct(self, name); return MP_OBJ_FROM_PTR(self); } -//| .. attribute:: connected +//| .. attribute:: connected (read-only) //| //| True if connected to a BLE Central device. //| @@ -153,13 +132,13 @@ const mp_obj_property_t bleio_peripheral_connected_obj = { //| .. attribute:: services //| -//| A `tuple` of `bleio.Service` that are offered by this peripheral. (read-only) +//| 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 *service_list = common_hal_bleio_peripheral_get_service_list(self); - return mp_obj_new_tuple(service_list->len, service_list->items); + 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); @@ -188,7 +167,7 @@ const mp_obj_property_t bleio_peripheral_name_obj = { (mp_obj_t)&mp_const_none_obj }, }; -//| .. method:: start_advertising(data, *, scan_response=None, connectable=True, interval=1) +//| .. 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. @@ -222,7 +201,7 @@ STATIC mp_obj_t bleio_peripheral_start_advertising(mp_uint_t n_args, const mp_ob } if (args[ARG_interval].u_obj == MP_OBJ_NULL) { - args[ARG_interval].u_obj = mp_obj_new_float(1.0F); + 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); @@ -265,16 +244,75 @@ STATIC mp_obj_t bleio_peripheral_disconnect(mp_obj_t self_in) { } 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_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) }, + { 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); diff --git a/shared-bindings/bleio/Peripheral.h b/shared-bindings/_bleio/Peripheral.h similarity index 79% rename from shared-bindings/bleio/Peripheral.h rename to shared-bindings/_bleio/Peripheral.h index 846250a5fc..bc56a93389 100644 --- a/shared-bindings/bleio/Peripheral.h +++ b/shared-bindings/_bleio/Peripheral.h @@ -28,16 +28,21 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H -#include "common-hal/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_list_t *service_list, mp_obj_t name); -extern mp_obj_list_t *common_hal_bleio_peripheral_get_service_list(bleio_peripheral_obj_t *self); +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 similarity index 92% rename from shared-bindings/bleio/ScanEntry.c rename to shared-bindings/_bleio/ScanEntry.c index 6eb02c7166..bec380d03f 100644 --- a/shared-bindings/bleio/ScanEntry.c +++ b/shared-bindings/_bleio/ScanEntry.c @@ -29,24 +29,24 @@ #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" +#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 +//| .. 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. +//| by a `_bleio.Scanner`: it has no user-visible constructor. //| //| .. attribute:: address //| -//| The address of the device (read-only), of type `bleio.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); diff --git a/shared-bindings/bleio/ScanEntry.h b/shared-bindings/_bleio/ScanEntry.h similarity index 97% rename from shared-bindings/bleio/ScanEntry.h rename to shared-bindings/_bleio/ScanEntry.h index 77e93175f9..8af1f050a8 100644 --- a/shared-bindings/bleio/ScanEntry.h +++ b/shared-bindings/_bleio/ScanEntry.h @@ -30,7 +30,7 @@ #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H #include "py/obj.h" -#include "shared-module/bleio/ScanEntry.h" +#include "shared-module/_bleio/ScanEntry.h" extern const mp_obj_type_t bleio_scanentry_type; diff --git a/shared-bindings/bleio/Scanner.c b/shared-bindings/_bleio/Scanner.c similarity index 96% rename from shared-bindings/bleio/Scanner.c rename to shared-bindings/_bleio/Scanner.c index 269c42591d..94cec97529 100644 --- a/shared-bindings/bleio/Scanner.c +++ b/shared-bindings/_bleio/Scanner.c @@ -27,8 +27,8 @@ #include "py/objproperty.h" #include "py/runtime.h" -#include "shared-bindings/bleio/ScanEntry.h" -#include "shared-bindings/bleio/Scanner.h" +#include "shared-bindings/_bleio/ScanEntry.h" +#include "shared-bindings/_bleio/Scanner.h" #define INTERVAL_DEFAULT (0.1f) #define INTERVAL_MIN (0.0025f) @@ -37,7 +37,7 @@ #define INTERVAL_MAX_STRING "40.959375" #define WINDOW_DEFAULT (0.1f) -//| .. currentmodule:: bleio +//| .. currentmodule:: _bleio //| //| :class:`Scanner` -- scan for nearby BLE devices //| ========================================================= @@ -46,8 +46,8 @@ //| //| Usage:: //| -//| import bleio -//| scanner = bleio.Scanner() +//| import _bleio +//| scanner = _bleio.Scanner() //| entries = scanner.scan(2.5) # Scan for 2.5 seconds //| diff --git a/shared-bindings/bleio/Scanner.h b/shared-bindings/_bleio/Scanner.h similarity index 97% rename from shared-bindings/bleio/Scanner.h rename to shared-bindings/_bleio/Scanner.h index 3a0ce7eae4..cbaa778662 100644 --- a/shared-bindings/bleio/Scanner.h +++ b/shared-bindings/_bleio/Scanner.h @@ -29,7 +29,7 @@ #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H #include "py/objtype.h" -#include "common-hal/bleio/Scanner.h" +#include "common-hal/_bleio/Scanner.h" extern const mp_obj_type_t bleio_scanner_type; diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/_bleio/Service.c similarity index 58% rename from shared-bindings/bleio/Service.c rename to shared-bindings/_bleio/Service.c index db06069913..da5633f2a3 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/_bleio/Service.c @@ -28,81 +28,79 @@ #include "py/objproperty.h" #include "py/runtime.h" -#include "shared-bindings/bleio/Characteristic.h" -#include "shared-bindings/bleio/Service.h" -#include "shared-bindings/bleio/UUID.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 +//| .. 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. -//| .. class:: Service(uuid, characteristics, *, secondary=False) -//| -//| Create a new Service object identified by the specified UUID. -//| To mark the service as secondary, pass `True` as :py:data:`secondary`. -//| -//| :param bleio.UUID uuid: The uuid of the service -//| :param iterable characteristics: the Characteristic objects for this service -//| :param bool secondary: If the service is a secondary one -//| - -STATIC mp_obj_t bleio_service_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_uuid, ARG_characteristics, ARG_secondary }; + enum { ARG_peripheral, ARG_uuid, ARG_secondary }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_characteristics, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { 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, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, 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")); } - bleio_service_obj_t *self = m_new_obj(bleio_service_obj_t); - self->base.type = &bleio_service_type; - const bool is_secondary = args[ARG_secondary].u_bool; - bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj); - // If characteristics is not an iterable, an exception will be thrown. - mp_obj_iter_buf_t iter_buf; - mp_obj_t iterable = mp_getiter(args[ARG_characteristics].u_obj, &iter_buf); - mp_obj_t characteristic_obj; + bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t); + service->base.type = &bleio_service_type; - // Copy the characteristics list and validate its items. - mp_obj_t char_list_obj = mp_obj_new_list(0, NULL); - mp_obj_list_t *char_list = MP_OBJ_TO_PTR(char_list_obj); + common_hal_bleio_service_construct( + service, MP_OBJ_TO_PTR(peripheral_obj), MP_OBJ_TO_PTR(uuid_obj), is_secondary); - while ((characteristic_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - if (!MP_OBJ_IS_TYPE(characteristic_obj, &bleio_characteristic_type)) { - mp_raise_ValueError(translate("characteristics includes an object that is not a Characteristic")); - } - bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(characteristic_obj); - if (common_hal_bleio_uuid_get_uuid128_reference(uuid) != - common_hal_bleio_uuid_get_uuid128_reference(characteristic->uuid)) { - // The descriptor base UUID doesn't match the characteristic base UUID. - mp_raise_ValueError(translate("Characteristic UUID doesn't match Service UUID")); - } - mp_obj_list_append(char_list_obj, characteristic_obj); - } + common_hal_bleio_peripheral_add_service(peripheral_obj, service); - common_hal_bleio_service_construct(self, uuid, char_list, is_secondary); - - return MP_OBJ_FROM_PTR(self); + 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 `bleio.Characteristic` that are offered by this service. (read-only) +//| 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); @@ -119,6 +117,24 @@ const mp_obj_property_t bleio_service_characteristics_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) @@ -157,10 +173,12 @@ const mp_obj_property_t bleio_service_uuid_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_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) }, + { 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); @@ -178,7 +196,6 @@ STATIC void bleio_service_print(const mp_print_t *print, mp_obj_t self_in, mp_pr const mp_obj_type_t bleio_service_type = { { &mp_type_type }, .name = MP_QSTR_Service, - .make_new = bleio_service_make_new, .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 similarity index 82% rename from shared-bindings/bleio/Service.h rename to shared-bindings/_bleio/Service.h index f646c81a9b..e061bcffcb 100644 --- a/shared-bindings/bleio/Service.h +++ b/shared-bindings/_bleio/Service.h @@ -28,14 +28,16 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H -#include "common-hal/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_uuid_obj_t *uuid, mp_obj_list_t *characteristic_list, bool is_secondary); +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_all_characteristics(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 similarity index 99% rename from shared-bindings/bleio/UUID.c rename to shared-bindings/_bleio/UUID.c index dca7ea0109..3c0889aad9 100644 --- a/shared-bindings/bleio/UUID.c +++ b/shared-bindings/_bleio/UUID.c @@ -31,9 +31,9 @@ #include "py/objproperty.h" #include "py/objstr.h" #include "py/runtime.h" -#include "shared-bindings/bleio/UUID.h" +#include "shared-bindings/_bleio/UUID.h" -//| .. currentmodule:: bleio +//| .. currentmodule:: _bleio //| //| :class:`UUID` -- BLE UUID //| ========================================================= diff --git a/shared-bindings/bleio/UUID.h b/shared-bindings/_bleio/UUID.h similarity index 98% rename from shared-bindings/bleio/UUID.h rename to shared-bindings/_bleio/UUID.h index caf039aecb..46ac54ff39 100644 --- a/shared-bindings/bleio/UUID.h +++ b/shared-bindings/_bleio/UUID.h @@ -28,7 +28,7 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H -#include "common-hal/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); diff --git a/shared-bindings/_bleio/__init__.c b/shared-bindings/_bleio/__init__.c new file mode 100644 index 0000000000..f207be8cfc --- /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 0000000000..67379ae2e1 --- /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/_stage/__init__.c b/shared-bindings/_stage/__init__.c index 03775b1ded..1154bbbf12 100644 --- a/shared-bindings/_stage/__init__.c +++ b/shared-bindings/_stage/__init__.c @@ -30,6 +30,7 @@ #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" @@ -50,7 +51,7 @@ //| Layer //| Text //| -//| .. function:: render(x0, y0, x1, y1, layers, buffer, display) +//| .. function:: render(x0, y0, x1, y1, layers, buffer, display[, scale]) //| //| Render and send to the display a fragment of the screen. //| @@ -61,6 +62,7 @@ //| :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 @@ -89,19 +91,17 @@ STATIC mp_obj_t stage_render(size_t n_args, const mp_obj_t *args) { mp_raise_TypeError(translate("argument num/types mismatch")); } displayio_display_obj_t *display = MP_OBJ_TO_PTR(native_display); - - while (!displayio_display_begin_transaction(display)) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP ; -#endif + uint8_t scale = 1; + if (n_args >= 8) { + scale = mp_obj_get_int(args[7]); } - displayio_display_set_region_to_update(display, x0, y0, x1, y1); - render_stage(x0, y0, x1, y1, layers, layers_size, buffer, buffer_size, display); - displayio_display_end_transaction(display); + + render_stage(x0, y0, x1, y1, layers, layers_size, buffer, buffer_size, + display, scale); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stage_render_obj, 7, 7, stage_render); +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[] = { diff --git a/shared-bindings/audiobusio/I2SOut.c b/shared-bindings/audiobusio/I2SOut.c index 980f113929..2cd2b67289 100644 --- a/shared-bindings/audiobusio/I2SOut.c +++ b/shared-bindings/audiobusio/I2SOut.c @@ -56,7 +56,7 @@ //| using `UDA1334 Breakout `_:: //| //| import audiobusio -//| import audioio +//| import audiocore //| import board //| import array //| import time @@ -68,7 +68,7 @@ //| for i in range(length): //| sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15) //| -//| sine_wave = audiobusio.RawSample(sine_wave, sample_rate=8000) +//| 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) @@ -78,12 +78,13 @@ //| //| import board //| import audioio +//| import audiocore //| import audiobusio //| import digitalio //| //| //| f = open("cplay-5.1-16bit-16khz.wav", "rb") -//| wav = audioio.WaveFile(f) +//| wav = audiocore.WaveFile(f) //| //| a = audiobusio.I2SOut(board.D1, board.D0, board.D9) //| @@ -163,7 +164,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_i2sout___exit___obj, 4, 4, //| Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| -//| Sample must be an `audioio.WaveFile` or `audioio.RawSample`. +//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiomixer.Mixer`. //| //| The sample itself should consist of 8 bit or 16 bit samples. //| diff --git a/shared-bindings/audioio/RawSample.c b/shared-bindings/audiocore/RawSample.c similarity index 98% rename from shared-bindings/audioio/RawSample.c rename to shared-bindings/audiocore/RawSample.c index 62998f5801..07f8c683f2 100644 --- a/shared-bindings/audioio/RawSample.c +++ b/shared-bindings/audiocore/RawSample.c @@ -31,11 +31,11 @@ #include "py/objproperty.h" #include "py/runtime.h" #include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/audioio/AudioOut.h" #include "shared-bindings/util.h" +#include "shared-bindings/audiocore/RawSample.h" #include "supervisor/shared/translate.h" -//| .. currentmodule:: audioio +//| .. currentmodule:: audiocore //| //| :class:`RawSample` -- A raw audio sample buffer //| ======================================================== @@ -55,6 +55,7 @@ //| //| Simple 8ksps 440 Hz sin wave:: //| +//| import audiocore //| import audioio //| import board //| import array @@ -68,7 +69,7 @@ //| sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15)) //| //| dac = audioio.AudioOut(board.SPEAKER) -//| sine_wave = audioio.RawSample(sine_wave) +//| sine_wave = audiocore.RawSample(sine_wave) //| dac.play(sine_wave, loop=True) //| time.sleep(1) //| dac.stop() diff --git a/shared-bindings/audioio/RawSample.h b/shared-bindings/audiocore/RawSample.h similarity index 96% rename from shared-bindings/audioio/RawSample.h rename to shared-bindings/audiocore/RawSample.h index 0d764b77c3..b02778cad3 100644 --- a/shared-bindings/audioio/RawSample.h +++ b/shared-bindings/audiocore/RawSample.h @@ -27,9 +27,8 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_RAWSAMPLE_H #define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_RAWSAMPLE_H -#include "common-hal/audioio/AudioOut.h" #include "common-hal/microcontroller/Pin.h" -#include "shared-module/audioio/RawSample.h" +#include "shared-module/audiocore/RawSample.h" extern const mp_obj_type_t audioio_rawsample_type; diff --git a/shared-bindings/audioio/WaveFile.c b/shared-bindings/audiocore/WaveFile.c similarity index 88% rename from shared-bindings/audioio/WaveFile.c rename to shared-bindings/audiocore/WaveFile.c index 242c915d38..1b3a94ff37 100644 --- a/shared-bindings/audioio/WaveFile.c +++ b/shared-bindings/audiocore/WaveFile.c @@ -29,27 +29,31 @@ #include "lib/utils/context_manager_helpers.h" #include "py/objproperty.h" #include "py/runtime.h" -#include "shared-bindings/audioio/WaveFile.h" +#include "shared-bindings/audiocore/WaveFile.h" #include "shared-bindings/util.h" #include "supervisor/shared/translate.h" -//| .. currentmodule:: audioio +//| .. 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. +//| 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) +//| .. 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 //| @@ -58,7 +62,7 @@ //| speaker_enable.switch_to_output(value=True) //| //| data = open("cplay-5.1-16bit-16khz.wav", "rb") -//| wav = audioio.WaveFile(data) +//| wav = audiocore.WaveFile(data) //| a = audioio.AudioOut(board.A0) //| //| print("playing") @@ -68,15 +72,23 @@ //| 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, 1, false); + 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)) { - common_hal_audioio_wavefile_construct(self, MP_OBJ_TO_PTR(args[0])); - } else { + 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); } diff --git a/shared-bindings/audioio/WaveFile.h b/shared-bindings/audiocore/WaveFile.h similarity index 94% rename from shared-bindings/audioio/WaveFile.h rename to shared-bindings/audiocore/WaveFile.h index 62a4200dc6..f4a1723192 100644 --- a/shared-bindings/audioio/WaveFile.h +++ b/shared-bindings/audiocore/WaveFile.h @@ -27,14 +27,15 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_WAVEFILE_H #define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_WAVEFILE_H -#include "common-hal/audioio/AudioOut.h" -#include "common-hal/microcontroller/Pin.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); + 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); diff --git a/shared-bindings/audiocore/__init__.c b/shared-bindings/audiocore/__init__.c new file mode 100644 index 0000000000..cf05112cb7 --- /dev/null +++ b/shared-bindings/audiocore/__init__.c @@ -0,0 +1,67 @@ +/* + * 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/RawSample.h" +#include "shared-bindings/audiocore/WaveFile.h" +//#include "shared-bindings/audiomixer/Mixer.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 +//| +//| 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_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 0000000000..02437cd135 --- /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 index 571dcdaca1..eb4ef1fc6c 100644 --- a/shared-bindings/audioio/AudioOut.c +++ b/shared-bindings/audioio/AudioOut.c @@ -32,7 +32,7 @@ #include "py/runtime.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/audioio/AudioOut.h" -#include "shared-bindings/audioio/RawSample.h" +#include "shared-bindings/audiocore/RawSample.h" #include "shared-bindings/util.h" #include "supervisor/shared/translate.h" @@ -55,6 +55,7 @@ //| //| Simple 8ksps 440 Hz sin wave:: //| +//| import audiocore //| import audioio //| import board //| import array @@ -68,7 +69,7 @@ //| sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15) //| //| dac = audioio.AudioOut(board.SPEAKER) -//| sine_wave = audioio.RawSample(sine_wave, sample_rate=8000) +//| sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000) //| dac.play(sine_wave, loop=True) //| time.sleep(1) //| dac.stop() @@ -84,7 +85,7 @@ //| speaker_enable.switch_to_output(value=True) //| //| data = open("cplay-5.1-16bit-16khz.wav", "rb") -//| wav = audioio.WaveFile(data) +//| wav = audiocore.WaveFile(data) //| a = audioio.AudioOut(board.A0) //| //| print("playing") @@ -162,7 +163,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_audioout___exit___obj, 4, 4, //| Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| -//| Sample must be an `audioio.WaveFile` or `audioio.RawSample`. +//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiomixer.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 diff --git a/shared-bindings/audioio/AudioOut.h b/shared-bindings/audioio/AudioOut.h index d09a5c9caa..1076ac5ccc 100644 --- a/shared-bindings/audioio/AudioOut.h +++ b/shared-bindings/audioio/AudioOut.h @@ -29,7 +29,7 @@ #include "common-hal/audioio/AudioOut.h" #include "common-hal/microcontroller/Pin.h" -#include "shared-bindings/audioio/RawSample.h" +#include "shared-bindings/audiocore/RawSample.h" extern const mp_obj_type_t audioio_audioout_type; diff --git a/shared-bindings/audioio/__init__.c b/shared-bindings/audioio/__init__.c index 4786b64253..7fa37d5c51 100644 --- a/shared-bindings/audioio/__init__.c +++ b/shared-bindings/audioio/__init__.c @@ -32,9 +32,15 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/audioio/__init__.h" #include "shared-bindings/audioio/AudioOut.h" -#include "shared-bindings/audioio/Mixer.h" -#include "shared-bindings/audioio/RawSample.h" -#include "shared-bindings/audioio/WaveFile.h" + +#if CIRCUITPY_AUDIOIO_COMPAT +#include "shared-bindings/audiomixer/Mixer.h" +#include "shared-bindings/audiocore/RawSample.h" +#include "shared-bindings/audiocore/WaveFile.h" +#endif +#if CIRCUITPY_AUDIOMIXER +#include "shared-bindings/audiomixer/Mixer.h" +#endif //| :mod:`audioio` --- Support for audio input and output //| ====================================================== @@ -51,22 +57,30 @@ //| :maxdepth: 3 //| //| AudioOut -//| Mixer -//| RawSample -//| WaveFile //| //| 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, `RawSample` and `WaveFile` are moved +//| to :mod:`audiocore`, and `Mixer` is moved to :mod:`audiomixer`. +//| +//| 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) }, - { MP_ROM_QSTR(MP_QSTR_Mixer), MP_ROM_PTR(&audioio_mixer_type) }, +#if CIRCUITPY_AUDIOIO_COMPAT + #if CIRCUITPY_AUDIOMIXER + { MP_ROM_QSTR(MP_QSTR_Mixer), MP_ROM_PTR(&audiomixer_mixer_type) }, + #endif { 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); diff --git a/shared-bindings/audioio/Mixer.c b/shared-bindings/audiomixer/Mixer.c similarity index 50% rename from shared-bindings/audioio/Mixer.c rename to shared-bindings/audiomixer/Mixer.c index dce4b39553..ed7b95d9e0 100644 --- a/shared-bindings/audioio/Mixer.c +++ b/shared-bindings/audiomixer/Mixer.c @@ -23,7 +23,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "shared-bindings/audioio/Mixer.h" +#include "shared-bindings/audiomixer/Mixer.h" +#include "shared-bindings/audiomixer/MixerVoice.h" +#include "shared-module/audiomixer/MixerVoice.h" #include @@ -32,48 +34,55 @@ #include "py/objproperty.h" #include "py/runtime.h" #include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/audioio/RawSample.h" +#include "shared-bindings/audiocore/RawSample.h" #include "shared-bindings/util.h" #include "supervisor/shared/translate.h" -//| .. currentmodule:: audioio +//| .. currentmodule:: audiomixer //| //| :class:`Mixer` -- Mixes one or more audio samples together //| =========================================================== //| //| Mixer mixes multiple samples into one sample. //| -//| .. class:: Mixer(channel_count=2, buffer_size=1024) +//| .. class:: Mixer(voice_count=2, buffer_size=1024, channel_count=2, bits_per_sample=16, samples_signed=True, sample_rate=8000) //| //| Create a Mixer object that can mix multiple channels with the same sample rate. +//| Samples are accessed and controlled with the mixer's `audiomixer.MixerVoice` objects. //| -//| :param int channel_count: The maximum number of samples to mix at once +//| :param int voice_count: The maximum number of voices to mix //| :param int buffer_size: The total size in bytes of the buffers to mix into +//| :param int channel_count: The number of channels the source samples contain. 1 = mono; 2 = stereo. +//| :param int bits_per_sample: The bits per sample of the samples being played +//| :param bool samples_signed: Samples are signed (True) or unsigned (False) +//| :param int sample_rate: The sample rate to be used for all samples //| //| Playing a wave file from flash:: //| //| import board //| import audioio +//| import audiocore +//| import audiomixer //| import digitalio //| -//| # Required for CircuitPlayground Express -//| speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) -//| speaker_enable.switch_to_output(value=True) -//| -//| music = audioio.WaveFile(open("cplay-5.1-16bit-16khz.wav", "rb")) -//| drum = audioio.WaveFile(open("drum.wav", "rb")) -//| mixer = audioio.Mixer(voice_count=2, sample_rate=16000, channel_count=1, bits_per_sample=16, samples_signed=True) //| a = audioio.AudioOut(board.A0) +//| music = audiocore.WaveFile(open("cplay-5.1-16bit-16khz.wav", "rb")) +//| drum = audiocore.WaveFile(open("drum.wav", "rb")) +//| mixer = audiomixer.Mixer(voice_count=2, sample_rate=16000, channel_count=1, +//| bits_per_sample=16, samples_signed=True) //| //| print("playing") +//| # Have AudioOut play our Mixer source //| a.play(mixer) -//| mixer.play(music, voice=0) +//| # Play the first sample voice +//| mixer.voice[0].play(music) //| while mixer.playing: -//| mixer.play(drum, voice=1) +//| # Play the second sample voice +//| mixer.voice[1].play(drum) //| 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) { +STATIC mp_obj_t audiomixer_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} }, @@ -103,9 +112,15 @@ STATIC mp_obj_t audioio_mixer_make_new(const mp_obj_type_t *type, size_t n_args, 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); + audiomixer_mixer_obj_t *self = m_new_obj_var(audiomixer_mixer_obj_t, mp_obj_t, voice_count); + self->base.type = &audiomixer_mixer_type; + common_hal_audiomixer_mixer_construct(self, voice_count, args[ARG_buffer_size].u_int, bits_per_sample, args[ARG_samples_signed].u_bool, channel_count, sample_rate); + + for(int v=0; vvoice[v] = audiomixer_mixervoice_type.make_new(&audiomixer_mixervoice_type, 0, 0, NULL); + common_hal_audiomixer_mixervoice_set_parent(self->voice[v], self); + } + self->voice_tuple = mp_obj_new_tuple(self->voice_count, self->voice); return MP_OBJ_FROM_PTR(self); } @@ -114,15 +129,15 @@ STATIC mp_obj_t audioio_mixer_make_new(const mp_obj_type_t *type, size_t n_args, //| //| 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); +STATIC mp_obj_t audiomixer_mixer_deinit(mp_obj_t self_in) { + audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiomixer_mixer_deinit(self); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_deinit_obj, audioio_mixer_deinit); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixer_deinit_obj, audiomixer_mixer_deinit); -STATIC void check_for_deinit(audioio_mixer_obj_t *self) { - if (common_hal_audioio_mixer_deinited(self)) { +STATIC void check_for_deinit(audiomixer_mixer_obj_t *self) { + if (common_hal_audiomixer_mixer_deinited(self)) { raise_deinited_error(); } } @@ -138,75 +153,27 @@ STATIC void check_for_deinit(audioio_mixer_obj_t *self) { //| 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) { +STATIC mp_obj_t audiomixer_mixer_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; - common_hal_audioio_mixer_deinit(args[0]); + common_hal_audiomixer_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 `audioio.WaveFile`, `audioio.Mixer` or `audioio.RawSample`. -//| -//| 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); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiomixer_mixer___exit___obj, 4, 4, audiomixer_mixer_obj___exit__); //| .. 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); +STATIC mp_obj_t audiomixer_mixer_obj_get_playing(mp_obj_t self_in) { + audiomixer_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)); + return mp_obj_new_bool(common_hal_audiomixer_mixer_get_playing(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_get_playing_obj, audioio_mixer_obj_get_playing); +MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixer_get_playing_obj, audiomixer_mixer_obj_get_playing); -const mp_obj_property_t audioio_mixer_playing_obj = { +const mp_obj_property_t audiomixer_mixer_playing_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&audioio_mixer_get_playing_obj, + .proxy = {(mp_obj_t)&audiomixer_mixer_get_playing_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj}, }; @@ -215,38 +182,118 @@ const mp_obj_property_t audioio_mixer_playing_obj = { //| //| 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); +STATIC mp_obj_t audiomixer_mixer_obj_get_sample_rate(mp_obj_t self_in) { + audiomixer_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)); + return MP_OBJ_NEW_SMALL_INT(common_hal_audiomixer_mixer_get_sample_rate(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_get_sample_rate_obj, audioio_mixer_obj_get_sample_rate); +MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixer_get_sample_rate_obj, audiomixer_mixer_obj_get_sample_rate); - -const mp_obj_property_t audioio_mixer_sample_rate_obj = { +const mp_obj_property_t audiomixer_mixer_sample_rate_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&audioio_mixer_get_sample_rate_obj, + .proxy = {(mp_obj_t)&audiomixer_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[] = { +//| .. attribute:: voice +//| +//| A tuple of the mixer's `audiomixer.MixerVoice` object(s). +//| +//| .. code-block:: python +//| +//| >>> mixer.voice +//| (,) +STATIC mp_obj_t audiomixer_mixer_obj_get_voice(mp_obj_t self_in) { + audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return self->voice_tuple; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixer_get_voice_obj, audiomixer_mixer_obj_get_voice); + +const mp_obj_property_t audiomixer_mixer_voice_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audiomixer_mixer_get_voice_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. 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 `audiomixer.Mixer`. +//| +//| The sample must match the Mixer's encoding settings given in the constructor. +//| +STATIC mp_obj_t audiomixer_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} }, + }; + audiomixer_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); + + uint8_t v = args[ARG_voice].u_int; + if (v > (self->voice_count - 1)) { + mp_raise_ValueError(translate("Invalid voice")); + } + audiomixer_mixervoice_obj_t *voice = MP_OBJ_TO_PTR(self->voice[v]); + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audiomixer_mixervoice_play(voice, sample, args[ARG_loop].u_bool); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixer_play_obj, 1, audiomixer_mixer_obj_play); + +//| .. method:: stop_voice(voice=0) +//| +//| Stops playback of the sample on the given voice. +//| +STATIC mp_obj_t audiomixer_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} }, + }; + audiomixer_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); + + uint8_t v = args[ARG_voice].u_int; + if (v > (self->voice_count - 1)) { + mp_raise_ValueError(translate("Invalid voice")); + } + audiomixer_mixervoice_obj_t *voice = MP_OBJ_TO_PTR(self->voice[v]); + common_hal_audiomixer_mixervoice_stop(voice); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixer_stop_voice_obj, 1, audiomixer_mixer_obj_stop_voice); + + +STATIC const mp_rom_map_elem_t audiomixer_mixer_locals_dict_table[] = { // Methods - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audioio_mixer_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiomixer_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) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiomixer_mixer___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiomixer_mixer_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop_voice), MP_ROM_PTR(&audiomixer_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) }, + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiomixer_mixer_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audiomixer_mixer_sample_rate_obj) }, + { MP_ROM_QSTR(MP_QSTR_voice), MP_ROM_PTR(&audiomixer_mixer_voice_obj) } }; -STATIC MP_DEFINE_CONST_DICT(audioio_mixer_locals_dict, audioio_mixer_locals_dict_table); +STATIC MP_DEFINE_CONST_DICT(audiomixer_mixer_locals_dict, audiomixer_mixer_locals_dict_table); -const mp_obj_type_t audioio_mixer_type = { +const mp_obj_type_t audiomixer_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, + .make_new = audiomixer_mixer_make_new, + .locals_dict = (mp_obj_dict_t*)&audiomixer_mixer_locals_dict, }; diff --git a/shared-bindings/audioio/Mixer.h b/shared-bindings/audiomixer/Mixer.h similarity index 51% rename from shared-bindings/audioio/Mixer.h rename to shared-bindings/audiomixer/Mixer.h index 832072b8f0..9eabbf61df 100644 --- a/shared-bindings/audioio/Mixer.h +++ b/shared-bindings/audiomixer/Mixer.h @@ -24,29 +24,28 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MIXER_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MIXER_H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMIXER_MIXER_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMIXER_MIXER_H #include "common-hal/microcontroller/Pin.h" -#include "shared-module/audioio/Mixer.h" -#include "shared-bindings/audioio/RawSample.h" +#include "shared-module/audiomixer/Mixer.h" +#include "shared-bindings/audiocore/RawSample.h" -extern const mp_obj_type_t audioio_mixer_type; +extern const mp_obj_type_t audiomixer_mixer_type; +extern const mp_obj_type_t audiomixer_mixervoice_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_audiomixer_mixer_construct(audiomixer_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); +void common_hal_audiomixer_mixer_deinit(audiomixer_mixer_obj_t* self); +bool common_hal_audiomixer_mixer_deinited(audiomixer_mixer_obj_t* self); -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); +bool common_hal_audiomixer_mixer_get_playing(audiomixer_mixer_obj_t* self); +uint32_t common_hal_audiomixer_mixer_get_sample_rate(audiomixer_mixer_obj_t* self); -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MIXER_H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMIXER_MIXER_H diff --git a/shared-bindings/audiomixer/MixerVoice.c b/shared-bindings/audiomixer/MixerVoice.c new file mode 100644 index 0000000000..188f76f579 --- /dev/null +++ b/shared-bindings/audiomixer/MixerVoice.c @@ -0,0 +1,178 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 DeanM for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF 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/audiomixer/Mixer.h" +#include "shared-bindings/audiomixer/MixerVoice.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:: audiomixer +//| +//| :class:`MixerVoice` -- Voice objects used with Mixer +//| ===================================================== +//| +//| Used to access and control samples with `audiomixer.Mixer`. +//| +//| .. class:: MixerVoice() +//| +//| MixerVoice instance object(s) created by `audiomixer.Mixer`. +//| +// TODO: support mono or stereo voices +STATIC mp_obj_t audiomixer_mixervoice_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + audiomixer_mixervoice_obj_t *self = m_new_obj(audiomixer_mixervoice_obj_t); + self->base.type = &audiomixer_mixervoice_type; + + common_hal_audiomixer_mixervoice_construct(self); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. 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`, `audiomixer.Mixer` or `audiocore.RawSample`. +//| +//| The sample must match the `audiomixer.Mixer`'s encoding settings given in the constructor. +//| +STATIC mp_obj_t audiomixer_mixervoice_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} }, + }; + audiomixer_mixervoice_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); + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audiomixer_mixervoice_play(self, sample, args[ARG_loop].u_bool); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_play_obj, 1, audiomixer_mixervoice_obj_play); + +//| .. method:: stop() +//| +//| Stops playback of the sample on this voice. +//| +STATIC mp_obj_t audiomixer_mixervoice_obj_stop(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} }, + }; + audiomixer_mixervoice_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); + + common_hal_audiomixer_mixervoice_stop(self); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_stop_obj, 1, audiomixer_mixervoice_obj_stop); + +//| .. attribute:: level() +//| +//| The volume level of a voice, as a floating point number between 0 and 1. +//| +STATIC mp_obj_t audiomixer_mixervoice_obj_get_level(mp_obj_t self_in) { + return mp_obj_new_float(common_hal_audiomixer_mixervoice_get_level(self_in)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixervoice_get_level_obj, audiomixer_mixervoice_obj_get_level); + +STATIC mp_obj_t audiomixer_mixervoice_obj_set_level(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_level }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_level, MP_ARG_OBJ | MP_ARG_REQUIRED }, + }; + audiomixer_mixervoice_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); + + float level = mp_obj_get_float(args[ARG_level].u_obj); + + if (level > 1 || level < 0) { + mp_raise_ValueError(translate("level must be between 0 and 1")); + } + + common_hal_audiomixer_mixervoice_set_level(self, level); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_set_level_obj, 1, audiomixer_mixervoice_obj_set_level); + +const mp_obj_property_t audiomixer_mixervoice_level_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audiomixer_mixervoice_get_level_obj, + (mp_obj_t)&audiomixer_mixervoice_set_level_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: playing +//| +//| True when this voice is being output. (read-only) +//| + +STATIC mp_obj_t audiomixer_mixervoice_obj_get_playing(mp_obj_t self_in) { + audiomixer_mixervoice_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(common_hal_audiomixer_mixervoice_get_playing(self)); + +} +MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixervoice_get_playing_obj, audiomixer_mixervoice_obj_get_playing); + +const mp_obj_property_t audiomixer_mixervoice_playing_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audiomixer_mixervoice_get_playing_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t audiomixer_mixervoice_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiomixer_mixervoice_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiomixer_mixervoice_stop_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiomixer_mixervoice_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_level), MP_ROM_PTR(&audiomixer_mixervoice_level_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(audiomixer_mixervoice_locals_dict, audiomixer_mixervoice_locals_dict_table); + +const mp_obj_type_t audiomixer_mixervoice_type = { + { &mp_type_type }, + .name = MP_QSTR_MixerVoice, + .make_new = audiomixer_mixervoice_make_new, + .locals_dict = (mp_obj_dict_t*)&audiomixer_mixervoice_locals_dict, +}; diff --git a/shared-bindings/audiomixer/MixerVoice.h b/shared-bindings/audiomixer/MixerVoice.h new file mode 100644 index 0000000000..83098bc9dd --- /dev/null +++ b/shared-bindings/audiomixer/MixerVoice.h @@ -0,0 +1,47 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 DeanM for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF 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_AUDIOMIXER_MIXERVOICE_H_ +#define SHARED_BINDINGS_AUDIOMIXER_MIXERVOICE_H_ + +#include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/audiocore/RawSample.h" + +#include "shared-module/audiomixer/MixerVoice.h" +#include "shared-module/audiomixer/Mixer.h" + +extern const mp_obj_type_t audiomixer_mixer_type; +extern const mp_obj_type_t audiomixer_mixervoice_type; + +void common_hal_audiomixer_mixervoice_construct(audiomixer_mixervoice_obj_t *self); +void common_hal_audiomixer_mixervoice_set_parent(audiomixer_mixervoice_obj_t* self, audiomixer_mixer_obj_t *parent); +void common_hal_audiomixer_mixervoice_play(audiomixer_mixervoice_obj_t* self, mp_obj_t sample, bool loop); +void common_hal_audiomixer_mixervoice_stop(audiomixer_mixervoice_obj_t* self); +float common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t* self); +void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t* self, float gain); + +bool common_hal_audiomixer_mixervoice_get_playing(audiomixer_mixervoice_obj_t* self); + +#endif /* SHARED_BINDINGS_AUDIOMIXER_MIXERVOICE_H_ */ diff --git a/shared-bindings/audiomixer/__init__.c b/shared-bindings/audiomixer/__init__.c new file mode 100644 index 0000000000..79bab440e5 --- /dev/null +++ b/shared-bindings/audiomixer/__init__.c @@ -0,0 +1,62 @@ +/* + * 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/audiomixer/Mixer.h" + +//| :mod:`audiomixer` --- Support for audio mixer +//| ======================================================== +//| +//| .. module:: audiomixer +//| :synopsis: Support for audio mixer +//| +//| The `audiomixer` module contains core classes for mixing audio sources +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Mixer +//| MixerVoice +//| + +STATIC const mp_rom_map_elem_t audiomixer_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiomixer) }, + { MP_ROM_QSTR(MP_QSTR_Mixer), MP_ROM_PTR(&audiomixer_mixer_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(audiomixer_module_globals, audiomixer_module_globals_table); + +const mp_obj_module_t audiomixer_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&audiomixer_module_globals, +}; diff --git a/shared-bindings/audiomixer/__init__.h b/shared-bindings/audiomixer/__init__.h new file mode 100644 index 0000000000..35a90441c4 --- /dev/null +++ b/shared-bindings/audiomixer/__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_AUDIOMIXER___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMIXER___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMIXER___INIT___H diff --git a/shared-bindings/audiopwmio/PWMAudioOut.c b/shared-bindings/audiopwmio/PWMAudioOut.c new file mode 100644 index 0000000000..60bf085002 --- /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 `audiomixer.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 0000000000..22afc70d38 --- /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 0000000000..8a2b202b36 --- /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 0000000000..e4b7067d11 --- /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 index 0a3b03f512..01a128393b 100644 --- a/shared-bindings/bitbangio/I2C.c +++ b/shared-bindings/bitbangio/I2C.c @@ -175,6 +175,23 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_unlock_obj, bitbangio_i2c_obj_unlock); //| :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[] = { @@ -185,33 +202,21 @@ STATIC mp_obj_t bitbangio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_a }; 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); - check_lock(self); - 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; - uint32_t length = bufinfo.len; - normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); - if (length == 0) { - mp_raise_ValueError(translate("Buffer must be at least length 1")); - } - uint8_t status = shared_module_bitbangio_i2c_read(self, - args[ARG_address].u_int, - ((uint8_t*)bufinfo.buf) + start, - length); - if (status != 0) { - mp_raise_OSError(status); - } + 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``. -//| Transmits a stop bit if ``stop`` is set. +//| 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 @@ -224,9 +229,27 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_readfrom_into_obj, 3, bitbangio_i2c_rea //| :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 +//| :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[] = { @@ -242,24 +265,57 @@ STATIC mp_obj_t bitbangio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, m 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); - // get the buffer to write the data from - 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; - uint32_t length = bufinfo.len; - normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); - - // do the transfer - uint8_t status = shared_module_bitbangio_i2c_write(self, args[ARG_address].u_int, - ((uint8_t*) bufinfo.buf) + start, length, args[ARG_stop].u_bool); - if (status != 0) { - mp_raise_OSError(status); - } + 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) }, @@ -271,6 +327,7 @@ STATIC const mp_rom_map_elem_t bitbangio_i2c_locals_dict_table[] = { { 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); diff --git a/shared-bindings/bitbangio/SPI.c b/shared-bindings/bitbangio/SPI.c index 88bd3d6cb3..9a51bde665 100644 --- a/shared-bindings/bitbangio/SPI.c +++ b/shared-bindings/bitbangio/SPI.c @@ -275,13 +275,13 @@ STATIC mp_obj_t bitbangio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_ 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; - uint32_t out_length = buf_out_info.len; + 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; - uint32_t in_length = buf_in_info.len; + 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) { diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c deleted file mode 100644 index 3bf0476ab5..0000000000 --- a/shared-bindings/bleio/Characteristic.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * 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/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(uuid, *, broadcast=False, indicate=False, notify=False, read=False, write=False, write_no_response=False) -//| -//| Create a new Characteristic object identified by the specified UUID. -//| -//| :param bleio.UUID uuid: The uuid of the characteristic -//| :param bool broadcast: Allowed in advertising packets -//| :param bool indicate: Server will indicate to the client when the value is set and wait for a response -//| :param bool notify: Server will notify the client when the value is set -//| :param bool read: Clients may read this characteristic -//| :param bool write: Clients may write this characteristic; a response will be sent back -//| :param bool write_no_response: Clients may write this characteristic; no response will be sent back -//| -STATIC mp_obj_t bleio_characteristic_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_uuid, ARG_broadcast, ARG_indicate, ARG_notify, ARG_read, ARG_write, ARG_write_no_response, - }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_broadcast, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, - { MP_QSTR_indicate, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, - { MP_QSTR_notify, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, - { MP_QSTR_read, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, - { MP_QSTR_write, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, - { MP_QSTR_write_no_response, 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); - - 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")); - } - bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj); - - bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t); - self->base.type = &bleio_characteristic_type; - - bleio_characteristic_properties_t properties; - - properties.broadcast = args[ARG_broadcast].u_bool; - properties.indicate = args[ARG_indicate].u_bool; - properties.notify = args[ARG_notify].u_bool; - properties.read = args[ARG_read].u_bool; - properties.write = args[ARG_write].u_bool; - properties.write_no_response = args[ARG_write_no_response].u_bool; - - // Initialize, with an empty descriptor list. - common_hal_bleio_characteristic_construct(self, uuid, properties, mp_obj_new_list(0, NULL)); - - return MP_OBJ_FROM_PTR(self); -} - -//| .. attribute:: broadcast -//| -//| A `bool` specifying if the characteristic allows broadcasting its value. (read-only) -//| -STATIC mp_obj_t bleio_characteristic_get_broadcast(mp_obj_t self_in) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - - return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).broadcast); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_broadcast_obj, bleio_characteristic_get_broadcast); - -const mp_obj_property_t bleio_characteristic_broadcast_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_characteristic_get_broadcast_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj }, -}; - -//| .. attribute:: indicate -//| -//| A `bool` specifying if the characteristic allows indicating its value. (read-only) -//| -STATIC mp_obj_t bleio_characteristic_get_indicate(mp_obj_t self_in) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - - return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).indicate); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_indicate_obj, bleio_characteristic_get_indicate); - - -const mp_obj_property_t bleio_characteristic_indicate_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_characteristic_get_indicate_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj }, -}; - -//| .. attribute:: notify -//| -//| A `bool` specifying if the characteristic allows notifying its value. (read-only) -//| -STATIC mp_obj_t bleio_characteristic_get_notify(mp_obj_t self_in) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - - return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).notify); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_notify_obj, bleio_characteristic_get_notify); - -const mp_obj_property_t bleio_characteristic_notify_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_characteristic_get_notify_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj }, -}; - -//| .. attribute:: read -//| -//| A `bool` specifying if the characteristic allows reading its value. (read-only) -//| -STATIC mp_obj_t bleio_characteristic_get_read(mp_obj_t self_in) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - - return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).read); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_read_obj, bleio_characteristic_get_read); - -const mp_obj_property_t bleio_characteristic_read_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_characteristic_get_read_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj }, -}; - -//| .. attribute:: write -//| -//| A `bool` specifying if the characteristic allows writing to its value. (read-only) -//| -STATIC mp_obj_t bleio_characteristic_get_write(mp_obj_t self_in) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - - return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).write); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_obj, bleio_characteristic_get_write); - -const mp_obj_property_t bleio_characteristic_write_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_characteristic_get_write_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj }, -}; - -//| .. attribute:: write_no_response -//| -//| A `bool` specifying if the characteristic allows writing to its value without response. (read-only) -//| -STATIC mp_obj_t bleio_characteristic_get_write_no_response(mp_obj_t self_in) { - bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); - - return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).write_no_response); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_no_response_obj, bleio_characteristic_get_write_no_response); - -const mp_obj_property_t bleio_characteristic_write_no_response_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bleio_characteristic_get_write_no_response_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. The value can be written to if the `write` property allows it. -//| If the `read` property allows it, the value can be read. If the `notify` property is set, writing -//| to the value will generate a BLE notification. -//| -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 `bleio.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 }, -}; - -//| .. 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_broadcast), MP_ROM_PTR(&bleio_characteristic_broadcast_obj) }, - { MP_ROM_QSTR(MP_QSTR_descriptors), MP_ROM_PTR(&bleio_characteristic_descriptors_obj) }, - { MP_ROM_QSTR(MP_QSTR_indicate), MP_ROM_PTR(&bleio_characteristic_indicate_obj) }, - { MP_ROM_QSTR(MP_QSTR_notify), MP_ROM_PTR(&bleio_characteristic_notify_obj) }, - { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&bleio_characteristic_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_set_cccd), MP_ROM_PTR(&bleio_characteristic_set_cccd_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_write), MP_ROM_PTR(&bleio_characteristic_write_obj) }, - { MP_ROM_QSTR(MP_QSTR_write_no_response), MP_ROM_PTR(&bleio_characteristic_write_no_response_obj) }, -}; -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, - .make_new = bleio_characteristic_make_new, - .print = bleio_characteristic_print, - .locals_dict = (mp_obj_dict_t*)&bleio_characteristic_locals_dict -}; diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c deleted file mode 100644 index f2e5aa01df..0000000000 --- a/shared-bindings/bleio/Descriptor.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * 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/Descriptor.h" -#include "shared-bindings/bleio/UUID.h" - -//| .. currentmodule:: bleio -//| -//| :class:`Descriptor` -- BLE descriptor -//| ========================================================= -//| -//| Stores information about a BLE descriptor. -//| Descriptors are encapsulated by BLE characteristics and provide contextual -//| information about the characteristic. -//| - -//| .. class:: Descriptor(uuid) -//| -//| Create a new descriptor object with the UUID uuid. - -//| .. attribute:: handle -//| -//| The descriptor handle. (read-only) -//| - -//| .. attribute:: uuid -//| -//| The descriptor uuid. (read-only) -//| -STATIC mp_obj_t bleio_descriptor_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_uuid }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - }; - - 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 uuid_arg = args[ARG_uuid].u_obj; - - if (!MP_OBJ_IS_TYPE(uuid_arg, &bleio_uuid_type)) { - mp_raise_ValueError(translate("Expected a UUID")); - } - - bleio_descriptor_obj_t *self = m_new_obj(bleio_descriptor_obj_t); - self->base.type = type; - bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_arg); - common_hal_bleio_descriptor_construct(self, uuid); - - return MP_OBJ_FROM_PTR(self); -} - -STATIC mp_obj_t bleio_descriptor_get_handle(mp_obj_t self_in) { - bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); - - return mp_obj_new_int(common_hal_bleio_descriptor_get_handle(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_handle_obj, bleio_descriptor_get_handle); - -const mp_obj_property_t bleio_descriptor_handle_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&bleio_descriptor_get_handle_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -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}, -}; - -STATIC const mp_rom_map_elem_t bleio_descriptor_locals_dict_table[] = { - // Properties - { MP_ROM_QSTR(MP_QSTR_handle), MP_ROM_PTR(&bleio_descriptor_handle_obj) }, - { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_descriptor_uuid_obj) }, - - // Static variables - { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_EXTENDED_PROPERTIES), - MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_EXTENDED_PROPERTIES) }, - - { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_USER_DESCRIPTION), - MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_USER_DESCRIPTION) }, - - { MP_ROM_QSTR(MP_QSTR_CLIENT_CHARACTERISTIC_CONFIGURATION), - MP_ROM_INT(DESCRIPTOR_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION) }, - - { MP_ROM_QSTR(MP_QSTR_SERVER_CHARACTERISTIC_CONFIGURATION), - MP_ROM_INT(DESCRIPTOR_UUID_SERVER_CHARACTERISTIC_CONFIGURATION) }, - - { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_PRESENTATION_FORMAT), - MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_PRESENTATION_FORMAT) }, - - { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_AGGREGATE_FORMAT), - MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_AGGREGATE_FORMAT) }, - - { MP_ROM_QSTR(MP_QSTR_VALID_RANGE), - MP_ROM_INT(DESCRIPTOR_UUID_VALID_RANGE) }, - - { MP_ROM_QSTR(MP_QSTR_EXTERNAL_REPORT_REFERENCE), - MP_ROM_INT(DESCRIPTOR_UUID_EXTERNAL_REPORT_REFERENCE) }, - - { MP_ROM_QSTR(MP_QSTR_REPORT_REFERENCE), - MP_ROM_INT(DESCRIPTOR_UUID_REPORT_REFERENCE) }, - - { MP_ROM_QSTR(MP_QSTR_NUMBER_OF_DIGITALS), - MP_ROM_INT(DESCRIPTOR_UUID_NUMBER_OF_DIGITALS) }, - - { MP_ROM_QSTR(MP_QSTR_VALUE_TRIGGER_SETTING), - MP_ROM_INT(DESCRIPTOR_UUID_VALUE_TRIGGER_SETTING) }, - - { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_CONFIGURATION), - MP_ROM_INT(DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_CONFIGURATION) }, - - { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_MEASUREMENT ), - MP_ROM_INT(DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_MEASUREMENT) }, - - { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_TRIGGER_SETTING), - MP_ROM_INT(DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_TRIGGER_SETTING) }, - - { MP_ROM_QSTR(MP_QSTR_TIME_TRIGGER_SETTING), - MP_ROM_INT(DESCRIPTOR_UUID_TIME_TRIGGER_SETTING) }, -}; - -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, - .make_new = bleio_descriptor_make_new, - .print = bleio_descriptor_print, - .locals_dict = (mp_obj_dict_t*)&bleio_descriptor_locals_dict -}; diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c deleted file mode 100644 index ba3bae6c75..0000000000 --- a/shared-bindings/bleio/__init__.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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/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 functionality -//| ================================================================ -//| -//| .. module:: bleio -//| :synopsis: Bluetooth Low Energy functionality -//| :platform: nRF -//| -//| The `bleio` module contains methods for managing the BLE adapter. -//| -//| Libraries -//| -//| .. toctree:: -//| :maxdepth: 3 -//| -//| Address -//| Adapter -//| 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_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/busio/I2C.c b/shared-bindings/busio/I2C.c index 0e639f0b5b..3bd89e2e20 100644 --- a/shared-bindings/busio/I2C.c +++ b/shared-bindings/busio/I2C.c @@ -189,6 +189,23 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_unlock_obj, busio_i2c_obj_unlock); //| :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[] = { @@ -203,21 +220,8 @@ STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_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); - 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; - uint32_t length = bufinfo.len; - normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); - if (length == 0) { - mp_raise_ValueError(translate("Buffer must be at least length 1")); - } - - uint8_t status = common_hal_busio_i2c_read(self, args[ARG_address].u_int, ((uint8_t*)bufinfo.buf) + start, length); - if (status != 0) { - mp_raise_OSError(status); - } - + 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); @@ -225,7 +229,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_readfrom_into_obj, 3, busio_i2c_readfrom_in //| .. 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 if ``stop`` is set. +//| 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 @@ -238,9 +244,26 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_readfrom_into_obj, 3, busio_i2c_readfrom_in //| :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 +//| :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[] = { @@ -256,25 +279,56 @@ STATIC mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_ma 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); - // get the buffer to write the data from - 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; - uint32_t length = bufinfo.len; - normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); - - // do the transfer - uint8_t status = common_hal_busio_i2c_write(self, args[ARG_address].u_int, - ((uint8_t*) bufinfo.buf) + start, length, args[ARG_stop].u_bool); - if (status != 0) { - mp_raise_OSError(status); - } + 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) }, @@ -286,6 +340,7 @@ STATIC const mp_rom_map_elem_t busio_i2c_locals_dict_table[] = { { 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); diff --git a/shared-bindings/busio/I2C.h b/shared-bindings/busio/I2C.h index 739732e97b..a2d5dbf507 100644 --- a/shared-bindings/busio/I2C.h +++ b/shared-bindings/busio/I2C.h @@ -69,4 +69,7 @@ extern uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addres 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/SPI.c b/shared-bindings/busio/SPI.c index a7d7d515c5..d47bf499a2 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -244,7 +244,7 @@ STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_ 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; - uint32_t length = bufinfo.len; + size_t length = bufinfo.len; normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); if (length == 0) { @@ -288,7 +288,7 @@ STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_m 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; - uint32_t length = bufinfo.len; + size_t length = bufinfo.len; normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); if (length == 0) { @@ -337,13 +337,13 @@ STATIC mp_obj_t busio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_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; - uint32_t out_length = buf_out_info.len; + 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; - uint32_t in_length = buf_in_info.len; + 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) { diff --git a/shared-bindings/displayio/ColorConverter.c b/shared-bindings/displayio/ColorConverter.c index 561883810f..db2d1b6e29 100644 --- a/shared-bindings/displayio/ColorConverter.c +++ b/shared-bindings/displayio/ColorConverter.c @@ -43,25 +43,35 @@ //| //| Converts one color format to another. //| -//| .. class:: ColorConverter() +//| .. class:: ColorConverter(*, dither=False) //| //| Create a ColorConverter object to convert color formats. Only supports RGB888 to RGB565 //| currently. -//| +//| :param bool dither: Adds random noise to dither the output image + // 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); + enum { ARG_dither}; + + static const mp_arg_t allowed_args[] = { + { MP_QSTR_dither, 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); displayio_colorconverter_t *self = m_new_obj(displayio_colorconverter_t); self->base.type = &displayio_colorconverter_type; - common_hal_displayio_colorconverter_construct(self); + + common_hal_displayio_colorconverter_construct(self, args[ARG_dither].u_bool); 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); @@ -69,14 +79,44 @@ STATIC mp_obj_t displayio_colorconverter_obj_convert(mp_obj_t self_in, mp_obj_t if (!mp_obj_get_int_maybe(color_obj, &color)) { mp_raise_ValueError(translate("color should be an int")); } - uint16_t output_color; - common_hal_displayio_colorconverter_convert(self, color, &output_color); + _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); +//| .. attribute:: dither +//| +//| When true the color converter dithers the output by adding random noise when +//| truncating to display bitdepth +//| +STATIC mp_obj_t displayio_colorconverter_obj_get_dither(mp_obj_t self_in) { + displayio_colorconverter_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(common_hal_displayio_colorconverter_get_dither(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_colorconverter_get_dither_obj, displayio_colorconverter_obj_get_dither); + +STATIC mp_obj_t displayio_colorconverter_obj_set_dither(mp_obj_t self_in, mp_obj_t dither) { + displayio_colorconverter_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_displayio_colorconverter_set_dither(self, mp_obj_is_true(dither)); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_colorconverter_set_dither_obj, displayio_colorconverter_obj_set_dither); + +const mp_obj_property_t displayio_colorconverter_dither_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_colorconverter_get_dither_obj, + (mp_obj_t)&displayio_colorconverter_set_dither_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + 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) }, + { MP_ROM_QSTR(MP_QSTR_dither), MP_ROM_PTR(&displayio_colorconverter_dither_obj) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_colorconverter_locals_dict, displayio_colorconverter_locals_dict_table); @@ -86,3 +126,4 @@ const mp_obj_type_t displayio_colorconverter_type = { .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 index 71be7f5430..d550d81be5 100644 --- a/shared-bindings/displayio/ColorConverter.h +++ b/shared-bindings/displayio/ColorConverter.h @@ -29,9 +29,14 @@ #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); -bool common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *colorconverter, uint32_t input_color, uint16_t* output_color); +void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t* self, bool dither); +void common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *colorconverter, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color); + +void common_hal_displayio_colorconverter_set_dither(displayio_colorconverter_t* self, bool dither); +bool common_hal_displayio_colorconverter_get_dither(displayio_colorconverter_t* self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_COLORCONVERTER_H diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 1a36872a6e..5ce7b3581b 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -51,7 +51,7 @@ //| 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, set_column_command=0x2a, set_row_command=0x2b, write_ram_command=0x2c, set_vertical_scroll=0, backlight_pin=None, brightness=1.0, auto_brightness=False, single_byte_bounds=False, data_as_commands=False) +//| .. 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`). //| @@ -88,18 +88,25 @@ //| :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 +//| :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_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_set_vertical_scroll, ARG_backlight_pin, ARG_brightness, ARG_auto_brightness, ARG_single_byte_bounds, ARG_data_as_commands }; + 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 }, @@ -109,15 +116,22 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a { 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); @@ -157,15 +171,20 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a 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_set_column_command].u_int, args[ARG_set_row_command].u_int, + 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_data_as_commands].u_bool, + args[ARG_auto_refresh].u_bool, + args[ARG_native_frames_per_second].u_int ); return self; @@ -191,32 +210,74 @@ STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in) group = MP_OBJ_TO_PTR(native_group(group_in)); } - common_hal_displayio_display_show(self, group); + 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_soon() +//| .. method:: refresh(*, target_frames_per_second=60, minimum_frames_per_second=1) //| -//| Queues up a display refresh that happens in the background. +//| 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. //| -STATIC mp_obj_t displayio_display_obj_refresh_soon(mp_obj_t self_in) { +//| 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); - common_hal_displayio_display_refresh_soon(self); + 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_1(displayio_display_refresh_soon_obj, displayio_display_obj_refresh_soon); +MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_set_auto_refresh_obj, displayio_display_obj_set_auto_refresh); -//| .. method:: wait_for_frame() -//| -//| Waits until the next frame has been transmitted to the display unless the wait count is -//| behind the rendered frames. In that case, this will return immediately with the wait count. -//| -STATIC mp_obj_t displayio_display_obj_wait_for_frame(mp_obj_t self_in) { - displayio_display_obj_t *self = native_display(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_display_wait_for_frame(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_wait_for_frame_obj, displayio_display_obj_wait_for_frame); +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 //| @@ -234,10 +295,14 @@ STATIC mp_obj_t displayio_display_obj_get_brightness(mp_obj_t self_in) { } 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) { +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); - bool ok = common_hal_displayio_display_set_brightness(self, mp_obj_get_float(brightness)); + 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")); } @@ -281,6 +346,9 @@ const mp_obj_property_t displayio_display_auto_brightness_obj = { (mp_obj_t)&mp_const_none_obj}, }; + + + //| .. attribute:: width //| //| Gets the width of the board @@ -317,6 +385,23 @@ const mp_obj_property_t displayio_display_height_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 @@ -324,7 +409,7 @@ const mp_obj_property_t displayio_display_height_obj = { //| STATIC mp_obj_t displayio_display_obj_get_bus(mp_obj_t self_in) { displayio_display_obj_t *self = native_display(self_in); - return self->bus; + return common_hal_displayio_display_get_bus(self); } MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_bus_obj, displayio_display_obj_get_bus); @@ -336,16 +421,79 @@ const mp_obj_property_t displayio_display_bus_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_soon), MP_ROM_PTR(&displayio_display_refresh_soon_obj) }, - { MP_ROM_QSTR(MP_QSTR_wait_for_frame), MP_ROM_PTR(&displayio_display_wait_for_frame_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); diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h index 5a027561b8..ca2b2d4765 100644 --- a/shared-bindings/displayio/Display.h +++ b/shared-bindings/displayio/Display.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_DISPLAY_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_DISPLAY_H #include "common-hal/microcontroller/Pin.h" @@ -36,38 +36,39 @@ 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, + 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, + 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 single_byte_bounds, bool data_as_commands, bool auto_refresh, uint16_t native_frames_per_second); -int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* self); +bool common_hal_displayio_display_show(displayio_display_obj_t* self, + displayio_group_t* root_group); -void 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); -void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self); +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); -bool displayio_display_begin_transaction(displayio_display_obj_t* self); -void displayio_display_end_transaction(displayio_display_obj_t* self); - -// The second point of the region is exclusive. -void displayio_display_set_region_to_update(displayio_display_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); -bool displayio_display_frame_queued(displayio_display_obj_t* self); - -bool displayio_display_refresh_queued(displayio_display_obj_t* self); -void displayio_display_finish_refresh(displayio_display_obj_t* self); -void displayio_display_send_pixels(displayio_display_obj_t* self, uint8_t* pixels, uint32_t length); +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); -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); +bool common_hal_displayio_display_get_dither(displayio_display_obj_t* self); +void common_hal_displayio_display_set_dither(displayio_display_obj_t* self, bool dither); 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); -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H +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 0000000000..81e06f82f9 --- /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 0000000000..e4b81c8838 --- /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 index af64a20286..51203d4604 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -103,35 +103,63 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ return self; } -//| .. method:: send(command, data) +//| .. 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(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) { +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(data_obj, &bufinfo, MP_BUFFER_READ); + 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)) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP ; -#endif + RUN_BACKGROUND_TASKS; } - common_hal_displayio_fourwire_send(self, true, &command, 1); - common_hal_displayio_fourwire_send(self, false, ((uint8_t*) bufinfo.buf), bufinfo.len); + 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_3(displayio_fourwire_send_obj, displayio_fourwire_obj_send); +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); diff --git a/shared-bindings/displayio/FourWire.h b/shared-bindings/displayio/FourWire.h index 5dbd607649..d0935f0639 100644 --- a/shared-bindings/displayio/FourWire.h +++ b/shared-bindings/displayio/FourWire.h @@ -28,6 +28,8 @@ #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" @@ -40,9 +42,12 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, 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, bool command, uint8_t *data, uint32_t data_length); +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); diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c index 5a35424ce4..dd7600eb9c 100644 --- a/shared-bindings/displayio/Group.c +++ b/shared-bindings/displayio/Group.c @@ -90,6 +90,32 @@ displayio_group_t* native_group(mp_obj_t group_obj) { return MP_OBJ_TO_PTR(native_group); } +//| .. attribute:: hidden +//| +//| True when the Group and all of it's layers are not visible. When False, the Group's layers +//| are visible if they haven't been hidden. +//| +STATIC mp_obj_t displayio_group_obj_get_hidden(mp_obj_t self_in) { + displayio_group_t *self = native_group(self_in); + return mp_obj_new_bool(common_hal_displayio_group_get_hidden(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_group_get_hidden_obj, displayio_group_obj_get_hidden); + +STATIC mp_obj_t displayio_group_obj_set_hidden(mp_obj_t self_in, mp_obj_t hidden_obj) { + displayio_group_t *self = native_group(self_in); + + common_hal_displayio_group_set_hidden(self, mp_obj_is_true(hidden_obj)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_set_hidden_obj, displayio_group_obj_set_hidden); + +const mp_obj_property_t displayio_group_hidden_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_group_get_hidden_obj, + (mp_obj_t)&displayio_group_set_hidden_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + //| .. attribute:: scale //| //| Scales each pixel within the Group in both directions. For example, when scale=2 each pixel @@ -305,6 +331,7 @@ STATIC mp_obj_t group_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t valu } STATIC const mp_rom_map_elem_t displayio_group_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_hidden), MP_ROM_PTR(&displayio_group_hidden_obj) }, { 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) }, diff --git a/shared-bindings/displayio/Group.h b/shared-bindings/displayio/Group.h index dc9616f2e9..942a207f2d 100644 --- a/shared-bindings/displayio/Group.h +++ b/shared-bindings/displayio/Group.h @@ -36,6 +36,8 @@ 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); +bool common_hal_displayio_group_get_hidden(displayio_group_t* self); +void common_hal_displayio_group_set_hidden(displayio_group_t* self, bool hidden); 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); diff --git a/shared-bindings/displayio/I2CDisplay.c b/shared-bindings/displayio/I2CDisplay.c new file mode 100644 index 0000000000..4339d182f4 --- /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 0000000000..bae53c4914 --- /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/Palette.c b/shared-bindings/displayio/Palette.c index 11c2f677ce..dda58e3c53 100644 --- a/shared-bindings/displayio/Palette.c +++ b/shared-bindings/displayio/Palette.c @@ -66,11 +66,26 @@ STATIC mp_obj_t displayio_palette_make_new(const mp_obj_type_t *type, size_t n_a 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). +//| 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:: @@ -89,12 +104,12 @@ STATIC mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t val if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) { return MP_OBJ_NULL; } - // index read is not supported - if (value == MP_OBJ_SENTINEL) { - 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; @@ -160,5 +175,7 @@ const mp_obj_type_t displayio_palette_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 index 767fc7b636..8c9fe11e38 100644 --- a/shared-bindings/displayio/Palette.h +++ b/shared-bindings/displayio/Palette.h @@ -33,6 +33,8 @@ 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); diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c index 00a96d2301..f7195b9ccb 100644 --- a/shared-bindings/displayio/ParallelBus.c +++ b/shared-bindings/displayio/ParallelBus.c @@ -106,6 +106,21 @@ STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t 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 @@ -122,12 +137,10 @@ STATIC mp_obj_t displayio_parallelbus_obj_send(mp_obj_t self, mp_obj_t command_o // Wait for display bus to be available. while (!common_hal_displayio_parallelbus_begin_transaction(self)) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP ; -#endif + RUN_BACKGROUND_TASKS; } - common_hal_displayio_parallelbus_send(self, true, &command, 1); - common_hal_displayio_parallelbus_send(self, false, ((uint8_t*) bufinfo.buf), bufinfo.len); + 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; @@ -135,6 +148,7 @@ STATIC mp_obj_t displayio_parallelbus_obj_send(mp_obj_t self, mp_obj_t command_o 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); diff --git a/shared-bindings/displayio/ParallelBus.h b/shared-bindings/displayio/ParallelBus.h index c4cde5ff53..be2aef7d44 100644 --- a/shared-bindings/displayio/ParallelBus.h +++ b/shared-bindings/displayio/ParallelBus.h @@ -28,8 +28,9 @@ #define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_PARALLELBUS_H #include "common-hal/displayio/ParallelBus.h" -#include "common-hal/microcontroller/Pin.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; @@ -40,9 +41,12 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel 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, bool command, uint8_t *data, uint32_t data_length); +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); diff --git a/shared-bindings/displayio/TileGrid.c b/shared-bindings/displayio/TileGrid.c index 6ba4914a02..288eb4b236 100644 --- a/shared-bindings/displayio/TileGrid.c +++ b/shared-bindings/displayio/TileGrid.c @@ -131,7 +131,8 @@ STATIC mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_ 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, + 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); @@ -143,6 +144,30 @@ static displayio_tilegrid_t* native_tilegrid(mp_obj_t tilegrid_obj) { mp_obj_assert_native_inited(native_tilegrid); return MP_OBJ_TO_PTR(native_tilegrid); } +//| .. attribute:: hidden +//| +//| True when the TileGrid is hidden. This may be False even when a part of a hidden Group. +//| +STATIC mp_obj_t displayio_tilegrid_obj_get_hidden(mp_obj_t self_in) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + return mp_obj_new_bool(common_hal_displayio_tilegrid_get_hidden(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_hidden_obj, displayio_tilegrid_obj_get_hidden); + +STATIC mp_obj_t displayio_tilegrid_obj_set_hidden(mp_obj_t self_in, mp_obj_t hidden_obj) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + + common_hal_displayio_tilegrid_set_hidden(self, mp_obj_is_true(hidden_obj)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_hidden_obj, displayio_tilegrid_obj_set_hidden); + +const mp_obj_property_t displayio_tilegrid_hidden_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_tilegrid_get_hidden_obj, + (mp_obj_t)&displayio_tilegrid_set_hidden_obj, + (mp_obj_t)&mp_const_none_obj}, +}; //| .. attribute:: x //| @@ -346,7 +371,7 @@ STATIC mp_obj_t tilegrid_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t v } 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")); + mp_raise_IndexError(translate("Tile index out of bounds")); } if (value_obj == MP_OBJ_SENTINEL) { @@ -357,7 +382,7 @@ STATIC mp_obj_t tilegrid_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t v } else { mp_int_t value = mp_obj_get_int(value_obj); if (value < 0 || value > 255) { - mp_raise_ValueError(translate("Tile indices must be 0 - 255")); + mp_raise_ValueError(translate("Tile value out of bounds")); } common_hal_displayio_tilegrid_set_tile(self, x, y, value); } @@ -367,6 +392,7 @@ STATIC mp_obj_t tilegrid_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t v STATIC const mp_rom_map_elem_t displayio_tilegrid_locals_dict_table[] = { // Properties + { MP_ROM_QSTR(MP_QSTR_hidden), MP_ROM_PTR(&displayio_tilegrid_hidden_obj) }, { 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) }, diff --git a/shared-bindings/displayio/TileGrid.h b/shared-bindings/displayio/TileGrid.h index 1f9995a949..0ee1c78836 100644 --- a/shared-bindings/displayio/TileGrid.h +++ b/shared-bindings/displayio/TileGrid.h @@ -32,9 +32,12 @@ 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, mp_obj_t pixel_shader, uint16_t width, uint16_t height, + 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); +bool common_hal_displayio_tilegrid_get_hidden(displayio_tilegrid_t* self); +void common_hal_displayio_tilegrid_set_hidden(displayio_tilegrid_t* self, bool hidden); 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); diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index 9dc17103b4..f783255930 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -33,8 +33,10 @@ #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" @@ -59,8 +61,10 @@ //| Bitmap //| ColorConverter //| Display +//| EPaperDisplay //| FourWire //| Group +//| I2CDisplay //| OnDiskBitmap //| Palette //| ParallelBus @@ -73,7 +77,7 @@ //| //| 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. +//| 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. @@ -89,6 +93,7 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { { 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) }, @@ -96,6 +101,7 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { { 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) }, diff --git a/shared-bindings/displayio/__init__.h b/shared-bindings/displayio/__init__.h index 427ddb47dd..a7748d029a 100644 --- a/shared-bindings/displayio/__init__.h +++ b/shared-bindings/displayio/__init__.h @@ -27,6 +27,24 @@ #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/i2cslave/I2CSlave.c b/shared-bindings/i2cslave/I2CSlave.c index 2598accbb4..c98ea52e06 100644 --- a/shared-bindings/i2cslave/I2CSlave.c +++ b/shared-bindings/i2cslave/I2CSlave.c @@ -182,7 +182,7 @@ STATIC mp_obj_t i2cslave_i2c_slave_request(size_t n_args, const mp_obj_t *pos_ar bool is_read; bool is_restart; - MICROPY_VM_HOOK_LOOP + RUN_BACKGROUND_TASKS; if (mp_hal_is_interrupted()) { return mp_const_none; } @@ -337,7 +337,7 @@ STATIC mp_obj_t i2cslave_i2c_slave_request_read(size_t n_args, const mp_obj_t *p uint8_t *buffer = NULL; uint64_t timeout_end = common_hal_time_monotonic() + 10 * 1000; while (common_hal_time_monotonic() < timeout_end) { - MICROPY_VM_HOOK_LOOP + RUN_BACKGROUND_TASKS; if (mp_hal_is_interrupted()) { break; } @@ -382,7 +382,7 @@ STATIC mp_obj_t i2cslave_i2c_slave_request_write(mp_obj_t self_in, mp_obj_t buf_ mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); for (size_t i = 0; i < bufinfo.len; i++) { - MICROPY_VM_HOOK_LOOP + RUN_BACKGROUND_TASKS; if (mp_hal_is_interrupted()) { break; } diff --git a/shared-bindings/index.rst b/shared-bindings/index.rst index 8f9bbbb31a..cbffdb6140 100644 --- a/shared-bindings/index.rst +++ b/shared-bindings/index.rst @@ -1,11 +1,11 @@ Core Modules ======================================== -These core modules are intended on being consistent across ports. Currently -they are only implemented in the SAMD21 and ESP8266 ports. A module may not exist -in a port if no underlying hardware support is present or if flash space is -limited. For example, a microcontroller without analog features will not have -`analogio`. +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 --------- @@ -14,55 +14,6 @@ Modules :glob: :maxdepth: 3 + support_matrix */__init__ help - -.. _module-support-matrix: - -Support Matrix ---------------- -NOTE 1: **All Supported** means the following ports are supported: SAMD21, SAMD21 Express, -SAMD51, SAMD51 Express, and ESP8266. - -NOTE 2: **SAMD** and/or **SAMD Express** without additional numbers, means both SAMD21 & SAMD51 versions -are supported. - -NOTE 3: The `pIRkey SAMD21 board `_ is specialized and may not -have modules as listed below. - -================= ============================== -Module Supported Ports -================= ============================== -`analogio` **All Supported** -`audiobusio` **SAMD/SAMD Express** -`audioio` **SAMD Express** -`binascii` **ESP8266** -`bitbangio` **SAMD Express, ESP8266** -`board` **All Supported** -`bleio` **nRF** -`busio` **All Supported** -`digitalio` **All Supported** -`frequencyio` **SAMD51** -`gamepad` **SAMD Express, nRF** -`hashlib` **ESP8266** -`i2cslave` **SAMD Express** -`math` **All Supported** -`microcontroller` **All Supported** -`multiterminal` **ESP8266** -`neopixel_write` **All Supported** -`nvm` **SAMD Express** -`os` **All Supported** -`pulseio` **SAMD/SAMD Express** -`ps2io` **SAMD/SAMD Express** -`random` **All Supported** -`rotaryio` **SAMD51, SAMD Express** -`storage` **All Supported** -`struct` **All Supported** -`supervisor` **SAMD/SAMD Express** -`time` **All Supported** -`touchio` **SAMD/SAMD Express** -`uheap` **Debug (All)** -`usb_hid` **SAMD/SAMD Express** -`_pixelbuf` **SAMD Express** -`_stage` **SAMD/SAMD Express** -================= ============================== diff --git a/shared-bindings/support_matrix.rst b/shared-bindings/support_matrix.rst new file mode 100644 index 0000000000..124f3a8104 --- /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/time/__init__.c b/shared-bindings/time/__init__.c index 70c01c2d83..2654de09aa 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -99,16 +99,17 @@ mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, const mp //| //| Structure used to capture a date and time. Note that it takes a tuple! //| -//| :param Tuple[tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst] time_tuple: Tuple of time info. -//| * the year, 2017 for example -//| * the month, range [1, 12] -//| * the day of the month, range [1, 31] -//| * the hour, range [0, 23] -//| * the minute, range [0, 59] -//| * the second, range [0, 61] -//| * the day of the week, range [0, 6], Monday is 0 -//| * the day of the year, range [1, 366], -1 indicates not known -//| * 1 when in daylight savings, 0 when not, -1 if unknown. +//| :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 = { @@ -235,9 +236,16 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { return rtc_get_time_source_time(); } - mp_int_t secs = mp_obj_int_get_checked(args[0]); - if (secs < EPOCH1970_EPOCH2000_DIFF_SECS) + 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); @@ -269,8 +277,9 @@ STATIC mp_obj_t time_mktime(mp_obj_t t) { mp_raise_TypeError(translate("function takes exactly 9 arguments")); } - if (mp_obj_get_int(elem[0]) < 2000) + 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])); diff --git a/shared-bindings/touchio/TouchIn.c b/shared-bindings/touchio/TouchIn.c index 78fceef416..33d369c748 100644 --- a/shared-bindings/touchio/TouchIn.c +++ b/shared-bindings/touchio/TouchIn.c @@ -68,10 +68,11 @@ STATIC mp_obj_t touchio_touchin_make_new(const mp_obj_type_t *type, // 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; - const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); common_hal_touchio_touchin_construct(self, pin); return (mp_obj_t) self; diff --git a/shared-bindings/touchio/TouchIn.h b/shared-bindings/touchio/TouchIn.h index 2e5c516079..e04e79c0b6 100644 --- a/shared-bindings/touchio/TouchIn.h +++ b/shared-bindings/touchio/TouchIn.h @@ -28,7 +28,12 @@ #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; diff --git a/shared-module/bleio/Address.c b/shared-module/_bleio/Address.c similarity index 95% rename from shared-module/bleio/Address.c rename to shared-module/_bleio/Address.c index 6bc458b7cc..8c8b043fec 100644 --- a/shared-module/bleio/Address.c +++ b/shared-module/_bleio/Address.c @@ -28,8 +28,8 @@ #include #include "py/objstr.h" -#include "shared-bindings/bleio/Address.h" -#include "shared-module/bleio/Address.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); diff --git a/shared-module/bleio/Address.h b/shared-module/_bleio/Address.h similarity index 100% rename from shared-module/bleio/Address.h rename to shared-module/_bleio/Address.h diff --git a/shared-module/_bleio/Attribute.c b/shared-module/_bleio/Attribute.c new file mode 100644 index 0000000000..3acfcf1f53 --- /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 0000000000..a498a14a51 --- /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 0000000000..409a57c76e --- /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 similarity index 92% rename from shared-module/bleio/ScanEntry.c rename to shared-module/_bleio/ScanEntry.c index 306ac33c58..8dfa17f31f 100644 --- a/shared-module/bleio/ScanEntry.c +++ b/shared-module/_bleio/ScanEntry.c @@ -28,9 +28,9 @@ #include -#include "shared-bindings/bleio/Address.h" -#include "shared-module/bleio/Address.h" -#include "shared-module/bleio/ScanEntry.h" +#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); diff --git a/shared-module/bleio/ScanEntry.h b/shared-module/_bleio/ScanEntry.h similarity index 97% rename from shared-module/bleio/ScanEntry.h rename to shared-module/_bleio/ScanEntry.h index b302460e67..1e798d78fd 100644 --- a/shared-module/bleio/ScanEntry.h +++ b/shared-module/_bleio/ScanEntry.h @@ -29,7 +29,7 @@ #define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H #include "py/obj.h" -#include "shared-bindings/bleio/Address.h" +#include "shared-bindings/_bleio/Address.h" typedef struct { mp_obj_base_t base; diff --git a/shared-module/_stage/__init__.c b/shared-module/_stage/__init__.c index 1af279e92b..d5da74272f 100644 --- a/shared-module/_stage/__init__.c +++ b/shared-module/_stage/__init__.c @@ -34,34 +34,60 @@ 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) { + displayio_display_obj_t *display, uint8_t scale) { + + 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); + + while (!displayio_display_core_begin_transaction(&display->core)) { + RUN_BACKGROUND_TASKS; + } + display->core.send(display->core.bus, DISPLAY_COMMAND, + CHIP_SELECT_TOGGLE_EVERY_BYTE, + &display->write_ram_command, 1); size_t index = 0; for (uint16_t y = y0; y < y1; ++y) { - for (uint16_t x = x0; x < x1; ++x) { - for (size_t layer = 0; layer < layers_size; ++layer) { + for (uint8_t yscale = 0; yscale < scale; ++yscale) { + for (uint16_t x = x0; x < x1; ++x) { uint16_t c = TRANSPARENT; - 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); + 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; + } } - if (c != TRANSPARENT) { + for (uint8_t xscale = 0; xscale < scale; ++xscale) { buffer[index] = c; - break; + 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; + } } } - index += 1; - // The buffer is full, send it. - if (index >= buffer_size) { - display->send(display->bus, false, ((uint8_t*)buffer), buffer_size * 2); - index = 0; - } } } // Send the remaining data. if (index) { - display->send(display->bus, false, ((uint8_t*)buffer), index * 2); + display->core.send(display->core.bus, DISPLAY_DATA, + CHIP_SELECT_UNTOUCHED, + ((uint8_t*)buffer), index * 2); } + + displayio_display_core_end_transaction(&display->core); } diff --git a/shared-module/_stage/__init__.h b/shared-module/_stage/__init__.h index d263302b48..5af2124aeb 100644 --- a/shared-module/_stage/__init__.h +++ b/shared-module/_stage/__init__.h @@ -37,6 +37,6 @@ 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); + displayio_display_obj_t *display, uint8_t scale); #endif // MICROPY_INCLUDED_SHARED_MODULE__STAGE diff --git a/shared-module/audioio/RawSample.c b/shared-module/audiocore/RawSample.c similarity index 97% rename from shared-module/audioio/RawSample.c rename to shared-module/audiocore/RawSample.c index 6422e346b7..d6bf3a567a 100644 --- a/shared-module/audioio/RawSample.c +++ b/shared-module/audiocore/RawSample.c @@ -24,11 +24,11 @@ * THE SOFTWARE. */ -#include "shared-bindings/audioio/RawSample.h" +#include "shared-bindings/audiocore/RawSample.h" #include -#include "shared-module/audioio/RawSample.h" +#include "shared-module/audiocore/RawSample.h" void common_hal_audioio_rawsample_construct(audioio_rawsample_obj_t* self, uint8_t* buffer, diff --git a/shared-module/audioio/RawSample.h b/shared-module/audiocore/RawSample.h similarity index 98% rename from shared-module/audioio/RawSample.h rename to shared-module/audiocore/RawSample.h index fe5283db45..6c2c19c9bf 100644 --- a/shared-module/audioio/RawSample.h +++ b/shared-module/audiocore/RawSample.h @@ -29,7 +29,7 @@ #include "py/obj.h" -#include "shared-module/audioio/__init__.h" +#include "shared-module/audiocore/__init__.h" typedef struct { mp_obj_base_t base; diff --git a/shared-module/audioio/WaveFile.c b/shared-module/audiocore/WaveFile.c similarity index 88% rename from shared-module/audioio/WaveFile.c rename to shared-module/audiocore/WaveFile.c index d5dd9419c3..0248d42e22 100644 --- a/shared-module/audioio/WaveFile.c +++ b/shared-module/audiocore/WaveFile.c @@ -24,7 +24,7 @@ * THE SOFTWARE. */ -#include "shared-bindings/audioio/WaveFile.h" +#include "shared-bindings/audiocore/WaveFile.h" #include #include @@ -32,7 +32,7 @@ #include "py/mperrno.h" #include "py/runtime.h" -#include "shared-module/audioio/WaveFile.h" +#include "shared-module/audiocore/WaveFile.h" #include "supervisor/shared/translate.h" struct wave_format_chunk { @@ -46,7 +46,9 @@ struct wave_format_chunk { }; void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self, - pyb_file_obj_t* file) { + pyb_file_obj_t* file, + uint8_t *buffer, + size_t buffer_size) { // Load the wave self->file = file; uint8_t chunk_header[16]; @@ -84,7 +86,6 @@ void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self, } // Get the sample_rate self->sample_rate = format.sample_rate; - self->len = 256; self->channel_count = format.num_channels; self->bits_per_sample = format.bits_per_sample; @@ -111,21 +112,31 @@ void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self, // Try to allocate two buffers, one will be loaded from file and the other // DMAed to DAC. - 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")); - } + 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")); + 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) { @@ -205,7 +216,7 @@ audioio_get_buffer_result_t audioio_wavefile_get_buffer(audioio_wavefile_obj_t* } else { *buffer = self->buffer; } - if (f_read(&self->file->fp, *buffer, num_bytes_to_load, &length_read) != FR_OK) { + if (f_read(&self->file->fp, *buffer, num_bytes_to_load, &length_read) != FR_OK || length_read != num_bytes_to_load) { return GET_BUFFER_ERROR; } self->bytes_remaining -= length_read; diff --git a/shared-module/audioio/WaveFile.h b/shared-module/audiocore/WaveFile.h similarity index 97% rename from shared-module/audioio/WaveFile.h rename to shared-module/audiocore/WaveFile.h index 2cee2b1d28..3eecbf15ce 100644 --- a/shared-module/audioio/WaveFile.h +++ b/shared-module/audiocore/WaveFile.h @@ -27,9 +27,10 @@ #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/audioio/__init__.h" +#include "shared-module/audiocore/__init__.h" typedef struct { mp_obj_base_t base; diff --git a/shared-module/audiocore/__init__.c b/shared-module/audiocore/__init__.c new file mode 100644 index 0000000000..f9762676fd --- /dev/null +++ b/shared-module/audiocore/__init__.c @@ -0,0 +1,138 @@ +/* + * 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/RawSample.h" +#include "shared-bindings/audiocore/WaveFile.h" +#include "shared-module/audiocore/RawSample.h" +#include "shared-module/audiocore/WaveFile.h" + +#include "shared-bindings/audiomixer/Mixer.h" +#include "shared-module/audiomixer/Mixer.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; + #if CIRCUITPY_AUDIOMIXER + } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) { + audiomixer_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj); + return mixer->sample_rate; + #endif + } + 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; + #if CIRCUITPY_AUDIOMIXER + } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) { + audiomixer_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj); + return mixer->bits_per_sample; + #endif + } + 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; + #if CIRCUITPY_AUDIOMIXER + } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) { + audiomixer_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj); + return mixer->channel_count; + #endif + } + 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); + #if CIRCUITPY_AUDIOMIXER + } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) { + audiomixer_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + audiomixer_mixer_reset_buffer(file, single_channel, audio_channel); + #endif + } +} + +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); + #if CIRCUITPY_AUDIOMIXER + } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) { + audiomixer_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + return audiomixer_mixer_get_buffer(file, single_channel, channel, buffer, buffer_length); + #endif + } + 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); + #if CIRCUITPY_AUDIOMIXER + } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) { + audiomixer_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + audiomixer_mixer_get_buffer_structure(file, single_channel, single_buffer, samples_signed, + max_buffer_length, spacing); + #endif + } +} diff --git a/shared-module/audiocore/__init__.h b/shared-module/audiocore/__init__.h new file mode 100644 index 0000000000..7aa0c1824a --- /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 index b87b06a833..e69de29bb2 100644 --- a/shared-module/audioio/__init__.c +++ b/shared-module/audioio/__init__.c @@ -1,125 +0,0 @@ -/* - * 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/audioio/Mixer.h" -#include "shared-bindings/audioio/RawSample.h" -#include "shared-bindings/audioio/WaveFile.h" -#include "shared-module/audioio/Mixer.h" -#include "shared-module/audioio/RawSample.h" -#include "shared-module/audioio/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/audioio/__init__.h b/shared-module/audioio/__init__.h index c805f31164..53b2d4a161 100644 --- a/shared-module/audioio/__init__.h +++ b/shared-module/audioio/__init__.h @@ -27,27 +27,6 @@ #ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO__INIT__H #define MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO__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); +#include "shared-module/audiocore/__init__.h" #endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO__INIT__H diff --git a/shared-module/audioio/Mixer.c b/shared-module/audiomixer/Mixer.c similarity index 50% rename from shared-module/audioio/Mixer.c rename to shared-module/audiomixer/Mixer.c index 8020a621ed..a52489f856 100644 --- a/shared-module/audioio/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -4,6 +4,8 @@ * The MIT License (MIT) * * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * 2018 DeanM for Adafruit Industries + * 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 @@ -24,32 +26,33 @@ * THE SOFTWARE. */ -#include "shared-bindings/audioio/Mixer.h" +#include "shared-bindings/audiomixer/Mixer.h" +#include "shared-bindings/audiomixer/MixerVoice.h" #include #include "py/runtime.h" -#include "shared-module/audioio/__init__.h" -#include "shared-module/audioio/RawSample.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) { +void common_hal_audiomixer_mixer_construct(audiomixer_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); + common_hal_audiomixer_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); + common_hal_audiomixer_mixer_deinit(self); mp_raise_msg(&mp_type_MemoryError, translate("Couldn't allocate second buffer")); } @@ -58,130 +61,85 @@ void common_hal_audioio_mixer_construct(audioio_mixer_obj_t* self, 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) { +void common_hal_audiomixer_mixer_deinit(audiomixer_mixer_obj_t* self) { self->first_buffer = NULL; self->second_buffer = NULL; } -bool common_hal_audioio_mixer_deinited(audioio_mixer_obj_t* self) { +bool common_hal_audiomixer_mixer_deinited(audiomixer_mixer_obj_t* self) { return self->first_buffer == NULL; } -uint32_t common_hal_audioio_mixer_get_sample_rate(audioio_mixer_obj_t* self) { +uint32_t common_hal_audiomixer_mixer_get_sample_rate(audiomixer_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) { +bool common_hal_audiomixer_mixer_get_playing(audiomixer_mixer_obj_t* self) { + for (uint8_t v = 0; v < self->voice_count; v++) { + if (common_hal_audiomixer_mixervoice_get_playing(MP_OBJ_TO_PTR(self->voice[v]))) { 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; +void audiomixer_mixer_reset_buffer(audiomixer_mixer_obj_t* self, + bool single_channel, + uint8_t channel) { + for (uint8_t i = 0; i < self->voice_count; i++) { + common_hal_audiomixer_mixervoice_stop(self->voice[i]); } } uint32_t add8signed(uint32_t a, uint32_t b) { - #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) - return __QADD8(a, b); + #if (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) //Cortex-M4 w/FPU + return __SHADD8(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; + int32_t intermediate = (int32_t) ai + bi / 2; if (intermediate > CHAR_MAX) { intermediate = CHAR_MAX; } else if (intermediate < CHAR_MIN) { - //intermediate = CHAR_MIN; + intermediate = CHAR_MIN; } - result |= (((uint32_t) intermediate) & 0xff) << (sizeof(int8_t) * 8 * i); + 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); + #if (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) //Cortex-M4 w/FPU + return __UHADD8(a, b); #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; + uint8_t ai = (a >> (sizeof(uint8_t) * 8 * i)); + uint8_t bi = (b >> (sizeof(uint8_t) * 8 * i)); + int32_t intermediate = (int32_t) (ai + bi) / 2; if (intermediate > UCHAR_MAX) { intermediate = UCHAR_MAX; } - result |= ((uint8_t) intermediate + 128) << (sizeof(uint8_t) * 8 * i); + result |= ((uint32_t) intermediate & 0xff) << (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); + #if (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) //Cortex-M4 w/FPU + return __SHADD16(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; + int32_t intermediate = (int32_t) ai + bi / 2; if (intermediate > SHRT_MAX) { intermediate = SHRT_MAX; } else if (intermediate < SHRT_MIN) { @@ -194,32 +152,146 @@ uint32_t add16signed(uint32_t a, uint32_t b) { } 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); + #if (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) //Cortex-M4 w/FPU + return __UHADD16(a, b); #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; + int32_t intermediate = (int32_t) ai + bi / 2; if (intermediate > USHRT_MAX) { intermediate = USHRT_MAX; } - result |= ((uint16_t) intermediate + 0x8000) << (sizeof(int16_t) * 8 * i); + result |= ((uint32_t) intermediate & 0xffff) << (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) { +static inline uint32_t mult8unsigned(uint32_t val, int32_t mul) { + // if mul == 0, no need in wasting cycles + if (mul == 0) { + return 0; + } + /* TODO: workout ARMv7 instructions + #if (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) //Cortex-M4 w/FPU + return val; + #else*/ + uint32_t result = 0; + float mod_mul = (float) mul / (float) ((1<<15)-1); + for (int8_t i = 0; i < 4; i++) { + uint8_t ai = val >> (sizeof(uint8_t) * 8 * i); + int32_t intermediate = ai * mod_mul; + if (intermediate > SHRT_MAX) { + intermediate = SHRT_MAX; + } + result |= ((uint32_t) intermediate & 0xff) << (sizeof(uint8_t) * 8 * i); + } + + return result; + //#endif +} + +static inline uint32_t mult8signed(uint32_t val, int32_t mul) { + // if mul == 0, no need in wasting cycles + if (mul == 0) { + return 0; + } + /* TODO: workout ARMv7 instructions + #if (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) //Cortex-M4 w/FPU + return val; + #else + */ + uint32_t result = 0; + float mod_mul = (float)mul / (float)((1<<15)-1); + for (int8_t i = 0; i < 4; i++) { + int16_t ai = val >> (sizeof(int8_t) * 8 * i); + int32_t intermediate = ai * mod_mul; + if (intermediate > CHAR_MAX) { + intermediate = CHAR_MAX; + } else if (intermediate < CHAR_MIN) { + intermediate = CHAR_MIN; + } + result |= (((uint32_t) intermediate) & 0xff) << (sizeof(int16_t) * 8 * i); + } + return result; + //#endif +} + +//TODO: +static inline uint32_t mult16unsigned(uint32_t val, int32_t mul) { + // if mul == 0, no need in wasting cycles + if (mul == 0) { + return 0; + } + /* TODO: the below ARMv7m instructions "work", but the amplitude is much higher/louder + #if (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) //Cortex-M4 w/FPU + // there is no unsigned equivalent to the 'SMULWx' ARMv7 Thumb function, + // so we have to do it by hand. + uint32_t lo = val & 0xffff; + uint32_t hi = val >> 16; + //mp_printf(&mp_plat_print, "pre-asm: (mul: %d)\n\tval: %x\tlo: %x\thi: %x\n", mul, val, lo, hi); + uint32_t val_lo; + asm volatile("mul %0, %1, %2" : "=r" (val_lo) : "r" (mul), "r" (lo)); + asm volatile("mla %0, %1, %2, %3" : "=r" (val) : "r" (mul), "r" (hi), "r" (val_lo)); + //mp_printf(&mp_plat_print, "post-asm:\n\tval: %x\tlo: %x\n\n", val, val_lo); + return val; + #else + */ + uint32_t result = 0; + float mod_mul = (float)mul / (float)((1<<15)-1); + for (int8_t i = 0; i < 2; i++) { + int16_t ai = (val >> (sizeof(uint16_t) * 8 * i)) - 0x8000; + int32_t intermediate = ai * mod_mul; + if (intermediate > SHRT_MAX) { + intermediate = SHRT_MAX; + } else if (intermediate < SHRT_MIN) { + intermediate = SHRT_MIN; + } + result |= (((uint32_t) intermediate) + 0x8000) << (sizeof(int16_t) * 8 * i); + } + return result; + //#endif +} + +static inline uint32_t mult16signed(uint32_t val, int32_t mul) { + // if mul == 0, no need in wasting cycles + if (mul == 0) { + return 0; + } + #if (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) //Cortex-M4 w/FPU + int32_t hi, lo; + enum { bits = 16 }; // saturate to 16 bits + enum { shift = 0 }; // shift is done automatically + asm volatile("smulwb %0, %1, %2" : "=r" (lo) : "r" (mul), "r" (val)); + asm volatile("smulwt %0, %1, %2" : "=r" (hi) : "r" (mul), "r" (val)); + asm volatile("ssat %0, %1, %2, asr %3" : "=r" (lo) : "I" (bits), "r" (lo), "I" (shift)); + asm volatile("ssat %0, %1, %2, asr %3" : "=r" (hi) : "I" (bits), "r" (hi), "I" (shift)); + asm volatile("pkhbt %0, %1, %2, lsl #16" : "=r" (val) : "r" (lo), "r" (hi)); // pack + return val; + #else + uint32_t result = 0; + float mod_mul = (float)mul / (float)((1<<15)-1); + for (int8_t i = 0; i < 2; i++) { + int16_t ai = val >> (sizeof(int16_t) * 8 * i); + int32_t intermediate = ai * mod_mul; + 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 +} + +audioio_get_buffer_result_t audiomixer_mixer_get_buffer(audiomixer_mixer_obj_t* self, + bool single_channel, + uint8_t channel, + uint8_t** buffer, + uint32_t* buffer_length) { if (!single_channel) { channel = 0; } @@ -243,7 +315,7 @@ audioio_get_buffer_result_t audioio_mixer_get_buffer(audioio_mixer_obj_t* self, 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]; + audiomixer_mixervoice_obj_t* voice = MP_OBJ_TO_PTR(self->voice[v]); uint32_t j = 0; bool voice_done = voice->sample == NULL; @@ -285,6 +357,21 @@ audioio_get_buffer_result_t audioio_mixer_get_buffer(audioio_mixer_obj_t* self, sample_value = voice->remaining_buffer[j]; } + // apply the mixer level + if (!self->samples_signed) { + if (self->bits_per_sample == 8) { + sample_value = mult8unsigned(sample_value, voice->level); + } else { + sample_value = mult16unsigned(sample_value, voice->level); + } + } else { + if (self->bits_per_sample == 8) { + sample_value = mult8signed(sample_value, voice->level); + } else { + sample_value = mult16signed(sample_value, voice->level); + } + } + if (!voices_active) { word_buffer[i] = sample_value; } else { @@ -327,7 +414,7 @@ audioio_get_buffer_result_t audioio_mixer_get_buffer(audioio_mixer_obj_t* self, return GET_BUFFER_MORE_DATA; } -void audioio_mixer_get_buffer_structure(audioio_mixer_obj_t* self, bool single_channel, +void audiomixer_mixer_get_buffer_structure(audiomixer_mixer_obj_t* self, bool single_channel, bool* single_buffer, bool* samples_signed, uint32_t* max_buffer_length, uint8_t* spacing) { *single_buffer = false; diff --git a/shared-module/audioio/Mixer.h b/shared-module/audiomixer/Mixer.h similarity index 78% rename from shared-module/audioio/Mixer.h rename to shared-module/audiomixer/Mixer.h index 6a88fe0bd5..ab4780efc6 100644 --- a/shared-module/audioio/Mixer.h +++ b/shared-module/audiomixer/Mixer.h @@ -24,20 +24,13 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_MIXER_H -#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_MIXER_H +#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOMIXER_MIXER_H +#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOMIXER_MIXER_H #include "py/obj.h" +#include "py/objtuple.h" -#include "shared-module/audioio/__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; +#include "shared-module/audiocore/__init__.h" typedef struct { mp_obj_base_t base; @@ -55,21 +48,22 @@ typedef struct { uint32_t right_read_count; uint8_t voice_count; - audioio_mixer_voice_t voice[]; -} audioio_mixer_obj_t; + mp_obj_tuple_t *voice_tuple; + mp_obj_t voice[]; +} audiomixer_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, +void audiomixer_mixer_reset_buffer(audiomixer_mixer_obj_t* self, bool single_channel, uint8_t channel); -audioio_get_buffer_result_t audioio_mixer_get_buffer(audioio_mixer_obj_t* self, +audioio_get_buffer_result_t audiomixer_mixer_get_buffer(audiomixer_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, +void audiomixer_mixer_get_buffer_structure(audiomixer_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 +#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOMIXER_MIXER_H diff --git a/shared-module/audiomixer/MixerVoice.c b/shared-module/audiomixer/MixerVoice.c new file mode 100644 index 0000000000..ff05dc93e4 --- /dev/null +++ b/shared-module/audiomixer/MixerVoice.c @@ -0,0 +1,87 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 DeanM for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF 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/audiomixer/Mixer.h" +#include "shared-module/audiomixer/MixerVoice.h" + +#include + +#include "py/runtime.h" +#include "shared-module/audiomixer/__init__.h" +#include "shared-module/audiocore/RawSample.h" + +void common_hal_audiomixer_mixervoice_construct(audiomixer_mixervoice_obj_t *self) { + self->sample = NULL; + self->level = ((1 << 15) - 1); +} + +void common_hal_audiomixer_mixervoice_set_parent(audiomixer_mixervoice_obj_t* self, audiomixer_mixer_obj_t *parent) { + self->parent = parent; +} + +float common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t* self) { + return ((float) self->level / ((1 << 15) - 1)); +} + +void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t* self, float level) { + self->level = level * ((1 << 15)-1); +} + +void common_hal_audiomixer_mixervoice_play(audiomixer_mixervoice_obj_t* self, mp_obj_t sample, bool loop) { + if (audiosample_sample_rate(sample) != self->parent->sample_rate) { + mp_raise_ValueError(translate("The sample's sample rate does not match the mixer's")); + } + if (audiosample_channel_count(sample) != self->parent->channel_count) { + mp_raise_ValueError(translate("The sample's channel count does not match the mixer's")); + } + if (audiosample_bits_per_sample(sample) != self->parent->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->parent->samples_signed) { + mp_raise_ValueError(translate("The sample's signedness does not match the mixer's")); + } + self->sample = sample; + self->loop = loop; + + audiosample_reset_buffer(sample, false, 0); + audioio_get_buffer_result_t result = audiosample_get_buffer(sample, false, 0, (uint8_t**) &self->remaining_buffer, &self->buffer_length); + // Track length in terms of words. + self->buffer_length /= sizeof(uint32_t); + self->more_data = result == GET_BUFFER_MORE_DATA; +} + +bool common_hal_audiomixer_mixervoice_get_playing(audiomixer_mixervoice_obj_t* self) { + return self->sample != NULL; +} + +void common_hal_audiomixer_mixervoice_stop(audiomixer_mixervoice_obj_t* self) { + self->sample = NULL; +} diff --git a/shared-module/audiomixer/MixerVoice.h b/shared-module/audiomixer/MixerVoice.h new file mode 100644 index 0000000000..efac191565 --- /dev/null +++ b/shared-module/audiomixer/MixerVoice.h @@ -0,0 +1,46 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 DeanM for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF 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_AUDIOMIXER_MIXERVOICE_H_ +#define SHARED_MODULE_AUDIOMIXER_MIXERVOICE_H_ + +#include "py/obj.h" + +#include "shared-module/audiomixer/__init__.h" +#include "shared-module/audiomixer/Mixer.h" + +typedef struct { + mp_obj_base_t base; + audiomixer_mixer_obj_t *parent; + mp_obj_t sample; + bool loop; + bool more_data; + uint32_t* remaining_buffer; + uint32_t buffer_length; + int16_t level; +} audiomixer_mixervoice_obj_t; + + +#endif /* SHARED_MODULE_AUDIOMIXER_MIXERVOICE_H_ */ diff --git a/shared-module/audiomixer/__init__.c b/shared-module/audiomixer/__init__.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shared-module/bleio/__init__.h b/shared-module/audiomixer/__init__.h similarity index 81% rename from shared-module/bleio/__init__.h rename to shared-module/audiomixer/__init__.h index 07d1485946..35b7315588 100644 --- a/shared-module/bleio/__init__.h +++ b/shared-module/audiomixer/__init__.h @@ -24,15 +24,9 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H -#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H +#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOMIXER__INIT__H +#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOMIXER__INIT__H -typedef enum { - GATT_ROLE_NONE, - GATT_ROLE_SERVER, - GATT_ROLE_CLIENT, -} gatt_role_t; +#include "shared-module/audiocore/__init__.h" -extern void bleio_reset(void); - -#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H +#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOMIXER__INIT__H diff --git a/shared-module/audiopwmio/__init__.c b/shared-module/audiopwmio/__init__.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shared-module/audiopwmio/__init__.h b/shared-module/audiopwmio/__init__.h new file mode 100644 index 0000000000..964e4aafe2 --- /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/board/__init__.c b/shared-module/board/__init__.c index be8502bc09..dd07d7190c 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -24,31 +24,41 @@ * THE SOFTWARE. */ -#include "shared-bindings/busio/I2C.h" -#include "shared-bindings/busio/SPI.h" -#include "shared-bindings/busio/UART.h" - #include "shared-bindings/microcontroller/Pin.h" #include "supervisor/shared/translate.h" #include "mpconfigboard.h" #include "py/runtime.h" -#ifdef CIRCUITPY_DISPLAYIO +#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 MP_STATE_VM(shared_i2c_bus); + return i2c_singleton; } mp_obj_t common_hal_board_create_i2c(void) { - busio_i2c_obj_t *self = m_new_ll_obj(busio_i2c_obj_t); + 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); - MP_STATE_VM(shared_i2c_bus) = MP_OBJ_FROM_PTR(self); - return MP_STATE_VM(shared_i2c_bus); + i2c_singleton = (mp_obj_t)self; + return i2c_singleton; } #endif @@ -99,7 +109,18 @@ mp_obj_t common_hal_board_create_uart(void) { void reset_board_busses(void) { #if BOARD_I2C - MP_STATE_VM(shared_i2c_bus) = NULL; + 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; diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index f8dc24c15e..59971d25cc 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -63,6 +63,11 @@ void common_hal_displayio_bitmap_construct(displayio_bitmap_t *self, uint32_t wi } 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) { @@ -104,6 +109,26 @@ void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *self, int16_t x, 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) { @@ -124,3 +149,16 @@ void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *self, int16_t x, } } } + +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 index 48ca9e2cf6..f4bd7ce4d3 100644 --- a/shared-module/displayio/Bitmap.h +++ b/shared-module/displayio/Bitmap.h @@ -31,6 +31,7 @@ #include #include "py/obj.h" +#include "shared-module/displayio/area.h" typedef struct { mp_obj_base_t base; @@ -41,8 +42,12 @@ typedef struct { 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 index 3928e115ab..a5d7f0b051 100644 --- a/shared-module/displayio/ColorConverter.c +++ b/shared-module/displayio/ColorConverter.c @@ -26,20 +26,163 @@ #include "shared-bindings/displayio/ColorConverter.h" -void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t* self) { +#include "py/misc.h" + +uint32_t displayio_colorconverter_dither_noise_1 (uint32_t n) +{ + n = (n >> 13) ^ n; + int nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; + return (uint32_t) (((float)nn / (1073741824.0f*2)) * 255); } -bool common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *self, uint32_t input_color, uint16_t* output_color) { - // TODO(tannewt): Validate the color input against the input format. - uint32_t r5 = (input_color >> 19); - uint32_t g6 = (input_color >> 10) & 0x3f; - uint32_t b5 = (input_color >> 3) & 0x1f; +uint32_t displayio_colorconverter_dither_noise_2(uint32_t x, uint32_t y) { + return displayio_colorconverter_dither_noise_1(x + y * 0xFFFF); +} + +void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t* self, bool dither) { + self->dither = dither; +} + +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 - *output_color = __builtin_bswap16(packed); - return true; + 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; + } +} + +void common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color) { + displayio_input_pixel_t input_pixel; + input_pixel.pixel = input_color; + input_pixel.x = input_pixel.y = input_pixel.tile = input_pixel.tile_x = input_pixel.tile_y = 0; + + displayio_output_pixel_t output_pixel; + output_pixel.pixel = 0; + output_pixel.opaque = false; + + displayio_colorconverter_convert(self, colorspace, &input_pixel, &output_pixel); + + (*output_color) = output_pixel.pixel; +} + +void common_hal_displayio_colorconverter_set_dither(displayio_colorconverter_t* self, bool dither) { + self->dither = dither; +} + +bool common_hal_displayio_colorconverter_get_dither(displayio_colorconverter_t* self) { + return self->dither; +} + +void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color) { + uint32_t pixel = input_pixel->pixel; + + if (self->dither){ + uint8_t randr = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x,input_pixel->tile_y)); + uint8_t randg = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x+33,input_pixel->tile_y)); + uint8_t randb = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x,input_pixel->tile_y+33)); + + uint32_t r8 = (pixel >> 16); + uint32_t g8 = (pixel >> 8) & 0xff; + uint32_t b8 = pixel & 0xff; + + if (colorspace->depth == 16) { + b8 = MIN(255,b8 + (randb&0x07)); + r8 = MIN(255,r8 + (randr&0x07)); + g8 = MIN(255,g8 + (randg&0x03)); + } else { + int bitmask = 0xFF >> colorspace->depth; + b8 = MIN(255,b8 + (randb&bitmask)); + r8 = MIN(255,r8 + (randr&bitmask)); + g8 = MIN(255,g8 + (randg&bitmask)); + } + pixel = r8 << 16 | g8 << 8 | b8; + } + + if (colorspace->depth == 16) { + output_color->pixel = displayio_colorconverter_compute_rgb565(pixel); + output_color->opaque = true; + return; + } else if (colorspace->tricolor) { + uint8_t luma = displayio_colorconverter_compute_luma(pixel); + output_color->pixel = luma >> (8 - colorspace->depth); + if (displayio_colorconverter_compute_chroma(pixel) <= 16) { + if (!colorspace->grayscale) { + output_color->pixel = 0; + } + output_color->opaque = true; + return; + } + uint8_t pixel_hue = displayio_colorconverter_compute_hue(pixel); + displayio_colorconverter_compute_tricolor(colorspace, pixel_hue, luma, &output_color->pixel); + return; + } else if (colorspace->grayscale && colorspace->depth <= 8) { + uint8_t luma = displayio_colorconverter_compute_luma(pixel); + output_color->pixel = luma >> (8 - colorspace->depth); + output_color->opaque = true; + return; + } + output_color->opaque = false; +} + + + // Currently no refresh logic is needed for a ColorConverter. bool displayio_colorconverter_needs_refresh(displayio_colorconverter_t *self) { return false; @@ -47,3 +190,4 @@ bool displayio_colorconverter_needs_refresh(displayio_colorconverter_t *self) { void displayio_colorconverter_finish_refresh(displayio_colorconverter_t *self) { } + diff --git a/shared-module/displayio/ColorConverter.h b/shared-module/displayio/ColorConverter.h index 7f3c1a0a03..10b1604a49 100644 --- a/shared-module/displayio/ColorConverter.h +++ b/shared-module/displayio/ColorConverter.h @@ -31,12 +31,24 @@ #include #include "py/obj.h" +#include "shared-module/displayio/Palette.h" typedef struct { mp_obj_base_t base; + bool dither; } displayio_colorconverter_t; bool displayio_colorconverter_needs_refresh(displayio_colorconverter_t *self); void displayio_colorconverter_finish_refresh(displayio_colorconverter_t *self); +void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color); + +uint32_t displayio_colorconverter_dither_noise_1 (uint32_t n); +uint32_t displayio_colorconverter_dither_noise_2(uint32_t x, uint32_t y); + +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 index 0ae88300aa..06b81f2f84 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -28,70 +28,70 @@ #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" -#define DELAY 0x80 - 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, 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, mp_float_t brightness, bool auto_brightness, - bool single_byte_bounds, bool data_as_commands) { - self->color_depth = color_depth; + 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) { + // Turn off auto-refresh as we init. + self->auto_refresh = false; + 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->refresh = false; - self->current_group = NULL; - self->colstart = colstart; - self->rowstart = rowstart; + self->brightness_command = brightness_command; self->auto_brightness = auto_brightness; + self->first_manual_refresh = !auto_refresh; self->data_as_commands = data_as_commands; - self->single_byte_bounds = single_byte_bounds; - if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) { - 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->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 { - mp_raise_ValueError(translate("Unsupported display bus type")); - } - self->bus = bus; + self->native_frames_per_second = native_frames_per_second; + self->native_ms_per_frame = 1000 / native_frames_per_second; uint32_t i = 0; - while (!self->begin_transaction(self->bus)) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP ; -#endif - } 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; - self->send(self->bus, true, cmd, 1); - if (self->data_as_commands) { - // Loop through each parameter to force a CS toggle - for (uint32_t j=0; j < data_size; j++) { - self->send(self->bus, true, data + j, 1); - } - } else { - self->send(self->bus, false, data, data_size); + 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); + } + displayio_display_core_end_transaction(&self->core); uint16_t delay_length_ms = 10; if (delay) { data_size++; @@ -103,33 +103,9 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, common_hal_time_delay_ms(delay_length_ms); i += 2 + data_size; } - self->end_transaction(self->bus); supervisor_start_terminal(width, height); - self->width = width; - self->height = 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; - } - } - // 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)) { @@ -141,110 +117,43 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, } else { self->backlight_pwm.base.type = &pulseio_pwmout_type; common_hal_pulseio_pwmout_never_reset(&self->backlight_pwm); - if (!self->auto_brightness) { - common_hal_displayio_display_set_brightness(self, brightness); - } } } - - 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; - } + 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->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; - } + 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); + self->auto_refresh = auto_refresh; } -void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) { - if (root_group == NULL) { - root_group = &circuitpython_splash; - } - if (root_group == self->current_group) { - return; - } - displayio_group_update_transform(root_group, &self->transform); - self->current_group = root_group; - self->full_refresh = true; - common_hal_displayio_display_refresh_soon(self); +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); } -void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self) { - self->refresh = true; +uint16_t common_hal_displayio_display_get_width(displayio_display_obj_t* self){ + return displayio_display_core_get_width(&self->core); } -const displayio_area_t* displayio_display_get_refresh_areas(displayio_display_obj_t *self) { - if (self->full_refresh) { - self->area.next = NULL; - return &self->area; - } else { - return displayio_group_get_refresh_areas(self->current_group, NULL); - } -} - -int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* self) { - uint64_t last_refresh = self->last_refresh; - // Don't try to refresh if we got an exception. - while (last_refresh == self->last_refresh && MP_STATE_VM(mp_pending_exception) == NULL) { - MICROPY_VM_HOOK_LOOP - } - return 0; +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; } -uint16_t common_hal_displayio_display_get_width(displayio_display_obj_t* self){ - return self->width; -} - -uint16_t common_hal_displayio_display_get_height(displayio_display_obj_t* self){ - return self->height; -} - 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) { - if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { - uint16_t duty_cycle = common_hal_pulseio_pwmout_get_duty_cycle(&self->backlight_pwm); - return duty_cycle / ((mp_float_t) 0xffff); - } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { - if (common_hal_digitalio_digitalinout_get_value(&self->backlight_inout)) { - return 1.0; - } else { - return 0.0; - } - } - return -1.0; + return self->current_brightness; } bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self, mp_float_t brightness) { @@ -256,76 +165,188 @@ bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self, } 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; } -bool displayio_display_begin_transaction(displayio_display_obj_t* self) { - return self->begin_transaction(self->bus); +mp_obj_t common_hal_displayio_display_get_bus(displayio_display_obj_t* self) { + return self->core.bus; } -void displayio_display_end_transaction(displayio_display_obj_t* self) { - self->end_transaction(self->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; } -void displayio_display_set_region_to_update(displayio_display_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { - self->send(self->bus, true, &self->set_column_command, 1); - bool isCommand = self->data_as_commands; - if (self->single_byte_bounds) { - uint8_t data[2]; - data[0] = x0 + self->colstart; - data[1] = x1 - 1 + self->colstart; - self->send(self->bus, isCommand, (uint8_t*) data, 2); - } else { - uint16_t data[2]; - data[0] = __builtin_bswap16(x0 + self->colstart); - data[1] = __builtin_bswap16(x1 - 1 + self->colstart); - self->send(self->bus, isCommand, (uint8_t*) data, 4); - } - self->send(self->bus, true, &self->set_row_command, 1); - if (self->single_byte_bounds) { - uint8_t data[2]; - data[0] = y0 + self->rowstart; - data[1] = y1 - 1 + self->rowstart; - self->send(self->bus, isCommand, (uint8_t*) data, 2); - } else { - uint16_t data[2]; - data[0] = __builtin_bswap16(y0 + self->rowstart); - data[1] = __builtin_bswap16(y1 - 1 + self->rowstart); - self->send(self->bus, isCommand, (uint8_t*) data, 4); - } +STATIC void _send_pixels(displayio_display_obj_t* self, uint8_t* pixels, uint32_t length) { if (!self->data_as_commands) { - self->send(self->bus, true, &self->write_ram_command, 1); + 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); } -void displayio_display_start_refresh(displayio_display_obj_t* self) { - self->last_refresh = ticks_ms; -} +STATIC bool _refresh_area(displayio_display_obj_t* self, const displayio_area_t* area) { + uint16_t buffer_size = 128; // In uint32_ts -bool displayio_display_frame_queued(displayio_display_obj_t* self) { - if (self->current_group == NULL) { - return false; + 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; } - // Refresh at ~60 fps. - return (ticks_ms - self->last_refresh) > 16; -} - -void displayio_display_finish_refresh(displayio_display_obj_t* self) { - if (self->current_group != NULL) { - displayio_group_finish_refresh(self->current_group); + 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; + } } - self->refresh = false; - self->full_refresh = false; - self->last_refresh = ticks_ms; + + // 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; } -void displayio_display_send_pixels(displayio_display_obj_t* self, uint8_t* pixels, uint32_t length) { - self->send(self->bus, false, pixels, length); +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); } -void displayio_display_update_backlight(displayio_display_obj_t* self) { +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; } @@ -339,7 +360,16 @@ void displayio_display_update_backlight(displayio_display_obj_t* self) { 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); @@ -348,10 +378,12 @@ void release_display(displayio_display_obj_t* self) { } } -bool displayio_display_fill_area(displayio_display_obj_t *self, displayio_area_t* area, uint32_t* mask, uint32_t *buffer) { - return displayio_group_fill_area(self->current_group, area, mask, buffer); +void reset_display(displayio_display_obj_t* self) { + self->auto_refresh = true; + self->auto_brightness = true; + common_hal_displayio_display_show(self, NULL); } -bool displayio_display_clip_area(displayio_display_obj_t *self, const displayio_area_t* area, displayio_area_t* clipped) { - return displayio_area_compute_overlap(&self->area, area, clipped); +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 index fa8902ceda..e5fe0a7088 100644 --- a/shared-module/displayio/Display.h +++ b/shared-module/displayio/Display.h @@ -32,47 +32,35 @@ #include "shared-bindings/pulseio/PWMOut.h" #include "shared-module/displayio/area.h" - -typedef bool (*display_bus_begin_transaction)(mp_obj_t bus); -typedef void (*display_bus_send)(mp_obj_t bus, bool command, uint8_t *data, uint32_t data_length); -typedef void (*display_bus_end_transaction)(mp_obj_t bus); +#include "shared-module/displayio/display_core.h" typedef struct { mp_obj_base_t base; - mp_obj_t bus; - displayio_group_t *current_group; - uint64_t last_refresh; - display_bus_begin_transaction begin_transaction; - display_bus_send send; - display_bus_end_transaction end_transaction; + displayio_display_core_t core; union { digitalio_digitalinout_obj_t backlight_inout; pulseio_pwmout_obj_t backlight_pwm; }; uint64_t last_backlight_refresh; - displayio_buffer_transform_t transform; - displayio_area_t area; - uint16_t width; - uint16_t height; - uint16_t color_depth; - int16_t colstart; - int16_t rowstart; + 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 refresh; - bool single_byte_bounds; + bool auto_refresh; + bool first_manual_refresh; bool data_as_commands; bool auto_brightness; bool updating_backlight; - bool full_refresh; // New group means we need to refresh the whole display. } displayio_display_obj_t; -void displayio_display_start_refresh(displayio_display_obj_t* self); -const displayio_area_t* displayio_display_get_refresh_areas(displayio_display_obj_t *self); -bool displayio_display_fill_area(displayio_display_obj_t *self, displayio_area_t* area, uint32_t* mask, uint32_t *buffer); -void displayio_display_update_backlight(displayio_display_obj_t* self); -bool displayio_display_clip_area(displayio_display_obj_t *self, const displayio_area_t* area, displayio_area_t* clipped); +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 0000000000..efbd9f3ddb --- /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 0000000000..d08bed5462 --- /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 index d38da56fc0..fcc4c1a20a 100644 --- a/shared-module/displayio/FourWire.c +++ b/shared-module/displayio/FourWire.c @@ -33,6 +33,7 @@ #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" @@ -55,10 +56,13 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, 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); @@ -75,6 +79,27 @@ void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self) { 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)) { @@ -86,15 +111,21 @@ bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t obj) { return true; } -void common_hal_displayio_fourwire_send(mp_obj_t obj, bool command, uint8_t *data, uint32_t data_length) { +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); - if (command) { - 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); + 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); } - common_hal_digitalio_digitalinout_set_value(&self->command, !command); - common_hal_busio_spi_write(self->bus, data, data_length); } void common_hal_displayio_fourwire_end_transaction(mp_obj_t obj) { diff --git a/shared-module/displayio/FourWire.h b/shared-module/displayio/FourWire.h index 743139e627..a4260a3ac5 100644 --- a/shared-module/displayio/FourWire.h +++ b/shared-module/displayio/FourWire.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_FOURWIRE_H -#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_FOURWIRE_H +#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" @@ -43,4 +43,4 @@ typedef struct { uint8_t phase; } displayio_fourwire_obj_t; -#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_FOURWIRE_H +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_FOURWIRE_H diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index 15060e87b6..d69e9f5859 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -34,6 +34,47 @@ void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t max_ displayio_group_construct(self, children, max_size, scale, x, y); } +bool common_hal_displayio_group_get_hidden(displayio_group_t* self) { + return self->hidden; +} + +void common_hal_displayio_group_set_hidden(displayio_group_t* self, bool hidden) { + if (self->hidden == hidden) { + return; + } + self->hidden = hidden; + if (self->hidden_by_parent) { + 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_set_hidden_by_parent(layer, hidden); + } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + displayio_group_set_hidden_by_parent(layer, hidden); + } + } +} + +void displayio_group_set_hidden_by_parent(displayio_group_t *self, bool hidden) { + if (self->hidden_by_parent == hidden) { + return; + } + self->hidden_by_parent = hidden; + // If we're already hidden, then we're done. + if (self->hidden) { + 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_set_hidden_by_parent(layer, hidden); + } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + displayio_group_set_hidden_by_parent(layer, hidden); + } + } +} + uint32_t common_hal_displayio_group_get_scale(displayio_group_t* self) { return self->scale; } @@ -270,19 +311,19 @@ void displayio_group_construct(displayio_group_t* self, displayio_group_child_t* self->in_group = false; } -bool displayio_group_fill_area(displayio_group_t *self, const displayio_area_t* area, uint32_t* mask, uint32_t* buffer) { +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, area, mask, buffer)) { + 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, area, mask, buffer)) { + if (displayio_group_fill_area(layer, colorspace, area, mask, buffer)) { full_coverage = true; break; } diff --git a/shared-module/displayio/Group.h b/shared-module/displayio/Group.h index 7ce19a4cdb..5afaac1bae 100644 --- a/shared-module/displayio/Group.h +++ b/shared-module/displayio/Group.h @@ -32,6 +32,7 @@ #include "py/obj.h" #include "shared-module/displayio/area.h" +#include "shared-module/displayio/Palette.h" typedef struct { mp_obj_t native; @@ -41,20 +42,24 @@ typedef struct { typedef struct { mp_obj_base_t base; displayio_group_child_t* children; + displayio_buffer_transform_t absolute_transform; + displayio_area_t dirty_area; // Catch all for changed area 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 + bool item_removed :1; + bool in_group :1; + bool hidden :1; + bool hidden_by_parent :1; + uint8_t padding :4; } 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); +void displayio_group_set_hidden_by_parent(displayio_group_t *self, bool hidden); 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_area_t* area, uint32_t* mask, uint32_t *buffer); +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); diff --git a/shared-module/displayio/I2CDisplay.c b/shared-module/displayio/I2CDisplay.c new file mode 100644 index 0000000000..d9452dc503 --- /dev/null +++ b/shared-module/displayio/I2CDisplay.c @@ -0,0 +1,123 @@ +/* + * 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; + } + common_hal_busio_i2c_unlock(self->bus); + return true; +} + +bool common_hal_displayio_i2cdisplay_begin_transaction(mp_obj_t obj) { + displayio_i2cdisplay_obj_t* self = MP_OBJ_TO_PTR(obj); + return common_hal_busio_i2c_try_lock(self->bus); +} + +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 0000000000..4636c3f73a --- /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 index 2b56424375..993fc03de6 100644 --- a/shared-module/displayio/OnDiskBitmap.c +++ b/shared-module/displayio/OnDiskBitmap.c @@ -74,7 +74,7 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self, self->g_bitmask = 0x3e0; self->b_bitmask = 0x1f; } - } else if ((indexed) && (self->bits_per_pixel != 1)) { + } 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; @@ -90,25 +90,24 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self, 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 == 4 ) || (( bits_per_pixel == 8) && (number_of_colors == 0))) { - mp_raise_ValueError_varg(translate("Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp given"), bits_per_pixel); + 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); } - if (self->bits_per_pixel >=8){ - self->stride = (self->width * (bits_per_pixel / 8)); + 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; + uint32_t bit_stride = self->width * self->bits_per_pixel; if (bit_stride % 32 != 0) { bit_stride += 32 - bit_stride % 32; } @@ -126,10 +125,11 @@ uint32_t common_hal_displayio_ondiskbitmap_get_pixel(displayio_ondiskbitmap_t *s uint32_t location; uint8_t bytes_per_pixel = (self->bits_per_pixel / 8) ? (self->bits_per_pixel /8) : 1; - if (self->bits_per_pixel >= 8){ + 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 / 8; + 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); @@ -141,20 +141,19 @@ uint32_t common_hal_displayio_ondiskbitmap_get_pixel(displayio_ondiskbitmap_t *s uint8_t red; uint8_t green; uint8_t blue; - if (self->bits_per_pixel == 1) { - uint8_t bit_offset = x%8; - tmp = ( pixel_data & (0x80 >> (bit_offset))) >> (7 - bit_offset); - if (tmp == 1) { - return 0x00FFFFFF; - } else { - return 0x00000000; + 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; + } } - } else if (bytes_per_pixel == 1) { - blue = ((self->palette_data[pixel_data] & 0xFF) >> 0); - red = ((self->palette_data[pixel_data] & 0xFF0000) >> 16); - green = ((self->palette_data[pixel_data] & 0xFF00) >> 8); - tmp = (red << 16 | green << 8 | blue ); - return tmp; + return self->palette_data[index]; } else if (bytes_per_pixel == 2) { if (self->g_bitmask == 0x07e0) { // 565 red =((pixel_data & self->r_bitmask) >>11); diff --git a/shared-module/displayio/Palette.c b/shared-module/displayio/Palette.c index 8dc6e766bd..3bce86f484 100644 --- a/shared-module/displayio/Palette.c +++ b/shared-module/displayio/Palette.c @@ -26,49 +26,65 @@ #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 = (uint32_t *) m_malloc(color_count * sizeof(uint16_t), false); - uint32_t opaque_byte_count = color_count / 8; - if (color_count % 8 > 0) { - opaque_byte_count += 1; - } - self->opaque = (uint32_t *) m_malloc(opaque_byte_count, false); + 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->opaque[palette_index / 32] &= ~(0x1 << (palette_index % 32)); + self->colors[palette_index].transparent = false; } void common_hal_displayio_palette_make_transparent(displayio_palette_t* self, uint32_t palette_index) { - self->opaque[palette_index / 32] |= (0x1 << (palette_index % 32)); + 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) { - uint32_t shift = (palette_index % 2) * 16; - uint32_t masked = self->colors[palette_index / 2] & ~(0xffff << shift); - uint32_t r5 = (color >> 19); - uint32_t g6 = (color >> 10) & 0x3f; - uint32_t b5 = (color >> 3) & 0x1f; - uint32_t packed = r5 << 11 | g6 << 5 | b5; - // swap bytes - packed = __builtin_bswap16(packed); - uint32_t final_color = masked | packed << shift; - if (self->colors[palette_index / 2] == final_color) { + if (self->colors[palette_index].rgb888 == color) { return; } - self->colors[palette_index / 2] = final_color; + 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; } -bool displayio_palette_get_color(displayio_palette_t *self, uint32_t palette_index, uint16_t* color) { - if (palette_index > self->color_count) { - return false; +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 ((self->opaque[palette_index / 32] & (0x1 << (palette_index % 32))) != 0) { - return false; + + 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; } - *color = (self->colors[palette_index / 2] >> (16 * (palette_index % 2))) & 0xffff; return true; } diff --git a/shared-module/displayio/Palette.h b/shared-module/displayio/Palette.h index 3813e8bddf..758fd43fc1 100644 --- a/shared-module/displayio/Palette.h +++ b/shared-module/displayio/Palette.h @@ -32,15 +32,51 @@ #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; + bool dither; +} _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 { + uint32_t pixel; + uint16_t x; + uint16_t y; + uint8_t tile; + uint16_t tile_x; + uint16_t tile_y; +} displayio_input_pixel_t; + +typedef struct { + uint32_t pixel; + bool opaque; +} displayio_output_pixel_t; + typedef struct { mp_obj_base_t base; - uint32_t* opaque; - uint32_t* colors; + _displayio_color_t* colors; uint32_t color_count; bool needs_refresh; } displayio_palette_t; -bool displayio_palette_get_color(displayio_palette_t *palette, uint32_t palette_index, uint16_t* color); +// 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); diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index 0cd00e0ce6..c4855c3331 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -26,6 +26,7 @@ #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" @@ -33,7 +34,7 @@ #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_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; @@ -54,6 +55,7 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_ 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; @@ -65,14 +67,30 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_ self->bitmap = bitmap; self->pixel_shader = pixel_shader; self->in_group = false; - self->first_draw = true; + self->hidden = false; + self->hidden_by_parent = false; + self->previous_area.x1 = 0xffff; + self->previous_area.x2 = self->previous_area.x1; self->flip_x = false; self->flip_y = false; self->transpose_xy = false; } + +bool common_hal_displayio_tilegrid_get_hidden(displayio_tilegrid_t* self) { + return self->hidden; +} + +void common_hal_displayio_tilegrid_set_hidden(displayio_tilegrid_t* self, bool hidden) { + self->hidden = hidden; +} + +void displayio_tilegrid_set_hidden_by_parent(displayio_tilegrid_t *self, bool hidden) { + self->hidden_by_parent = hidden; +} + bool displayio_tilegrid_get_previous_area(displayio_tilegrid_t *self, displayio_area_t* area) { - if (self->first_draw) { + if (self->previous_area.x1 == self->previous_area.x2) { return false; } displayio_area_copy(&self->previous_area, area); @@ -136,12 +154,10 @@ void displayio_tilegrid_update_transform(displayio_tilegrid_t *self, self->in_group = absolute_transform != NULL; self->absolute_transform = absolute_transform; if (absolute_transform != NULL) { - self->moved = !self->first_draw; + self->moved = true; _update_current_x(self); _update_current_y(self); - } else { - self->first_draw = true; } } @@ -153,7 +169,7 @@ void common_hal_displayio_tilegrid_set_x(displayio_tilegrid_t *self, mp_int_t x) return; } - self->moved = !self->first_draw; + self->moved = true; self->x = x; if (self->absolute_transform != NULL) { @@ -168,7 +184,7 @@ 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->moved = true; self->y = y; if (self->absolute_transform != NULL) { _update_current_y(self); @@ -204,6 +220,9 @@ uint8_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint1 } 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; @@ -291,7 +310,7 @@ void common_hal_displayio_tilegrid_set_top_left(displayio_tilegrid_t *self, uint self->full_change = true; } -bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const displayio_area_t* area, uint32_t* mask, uint32_t *buffer) { +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) { @@ -301,6 +320,11 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const displayio_ar return false; } + bool hidden = self->hidden || self->hidden_by_parent; + if (hidden) { + return false; + } + displayio_area_t overlap; if (!displayio_area_compute_overlap(area, &self->current_area, &overlap)) { return false; @@ -371,14 +395,19 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const displayio_ar y_shift = temp_shift; } - for (int16_t y = start_y; y < end_y; y++) { - int16_t row_start = start + (y - start_y + y_shift) * y_stride; - 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; + uint8_t pixels_per_byte = 8 / colorspace->depth; - // This is super useful for debugging out range accesses. Uncomment to use. + displayio_input_pixel_t input_pixel; + displayio_output_pixel_t output_pixel; + + for (input_pixel.y = start_y; input_pixel.y < end_y; ++input_pixel.y) { + int16_t row_start = start + (input_pixel.y - start_y + y_shift) * y_stride; // in pixels + int16_t local_y = input_pixel.y / self->absolute_transform->scale; + for (input_pixel.x = start_x; input_pixel.x < end_x; ++input_pixel.x) { + // Compute the destination pixel in the buffer and mask based on the transformations. + int16_t offset = row_start + (input_pixel.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"); // } @@ -387,40 +416,62 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const displayio_ar if ((mask[offset / 32] & (1 << (offset % 32))) != 0) { continue; } - int16_t local_x = x / self->absolute_transform->scale; + int16_t local_x = input_pixel.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; + input_pixel.tile = tiles[tile_location]; + input_pixel.tile_x = (input_pixel.tile % self->bitmap_width_in_tiles) * self->tile_width + local_x % self->tile_width; + input_pixel.tile_y = (input_pixel.tile / self->bitmap_width_in_tiles) * self->tile_height + local_y % self->tile_height; + + //uint32_t value = 0; + output_pixel.pixel = 0; + input_pixel.pixel = 0; - 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); + input_pixel.pixel = common_hal_displayio_bitmap_get_pixel(self->bitmap, input_pixel.tile_x, input_pixel.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); + input_pixel.pixel = common_hal_displayio_shape_get_pixel(self->bitmap, input_pixel.tile_x, input_pixel.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); + input_pixel.pixel = common_hal_displayio_ondiskbitmap_get_pixel(self->bitmap, input_pixel.tile_x, input_pixel.tile_y); } - - uint16_t* pixel = ((uint16_t*) buffer) + offset; + + output_pixel.opaque = true; if (self->pixel_shader == mp_const_none) { - *pixel = value; - return true; + output_pixel.pixel = input_pixel.pixel; } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) { - if (!displayio_palette_get_color(self->pixel_shader, value, pixel)) { - // A pixel is transparent so we haven't fully covered the area ourselves. - full_coverage = false; - } else { - mask[offset / 32] |= 1 << (offset % 32); - } + output_pixel.opaque = displayio_palette_get_color(self->pixel_shader, colorspace, input_pixel.pixel, &output_pixel.pixel); } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) { - if (!common_hal_displayio_colorconverter_convert(self->pixel_shader, value, pixel)) { - // A pixel is transparent so we haven't fully covered the area ourselves. - full_coverage = false; - } else { - mask[offset / 32] |= 1 << (offset % 32); + displayio_colorconverter_convert(self->pixel_shader, colorspace, &input_pixel, &output_pixel); + } + if (!output_pixel.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) = output_pixel.pixel; + } else if (colorspace->depth == 8) { + *(((uint8_t*) buffer) + offset) = output_pixel.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] |= output_pixel.pixel << shift; } } } @@ -429,25 +480,46 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const displayio_ar } void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self) { - if (self->moved || self->first_draw) { + bool first_draw = self->previous_area.x1 == self->previous_area.x2; + bool hidden = self->hidden || self->hidden_by_parent; + if (!first_draw && hidden) { + self->previous_area.x2 = self->previous_area.x1; + } else if (self->moved || 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) { + bool first_draw = self->previous_area.x1 == self->previous_area.x2; + bool hidden = self->hidden || self->hidden_by_parent; + // Check hidden first because it trumps all other changes. + if (hidden) { + if (!first_draw) { + self->previous_area.next = tail; + return &self->previous_area; + } else { + return tail; + } + } else if (self->moved && !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; @@ -458,14 +530,27 @@ displayio_area_t* displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *sel return &self->current_area; } - // We must recheck if our sources require a refresh because needs_refresh may or may not have - // been called. + // 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) { + if (self->full_change || first_draw) { self->current_area.next = tail; return &self->current_area; } diff --git a/shared-module/displayio/TileGrid.h b/shared-module/displayio/TileGrid.h index 4d97eccc2b..e97d3dfd47 100644 --- a/shared-module/displayio/TileGrid.h +++ b/shared-module/displayio/TileGrid.h @@ -32,6 +32,7 @@ #include "py/obj.h" #include "shared-module/displayio/area.h" +#include "shared-module/displayio/Palette.h" typedef struct { mp_obj_base_t base; @@ -41,7 +42,8 @@ typedef struct { int16_t y; uint16_t pixel_width; uint16_t pixel_height; - uint16_t bitmap_width_in_tiles; + 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; @@ -53,17 +55,21 @@ typedef struct { 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; + bool partial_change :1; + bool full_change :1; + bool moved :1; + bool inline_tiles :1; + bool in_group :1; + bool flip_x :1; + bool flip_y :1; + bool transpose_xy :1; + bool hidden :1; + bool hidden_by_parent :1; + uint8_t padding :6; } displayio_tilegrid_t; +void displayio_tilegrid_set_hidden_by_parent(displayio_tilegrid_t *self, bool hidden); + // Updating the screen is a three stage process. // The first stage is used to determine i @@ -71,7 +77,7 @@ displayio_area_t* displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *sel // 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_area_t* area, uint32_t* mask, uint32_t *buffer); +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 diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index b6709e0eb7..af22cb0df8 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -4,7 +4,6 @@ #include "shared-module/displayio/__init__.h" #include "lib/utils/interrupt_char.h" -#include "py/gc.h" #include "py/reload.h" #include "py/runtime.h" #include "shared-bindings/board/__init__.h" @@ -16,89 +15,13 @@ #include "supervisor/shared/autoreload.h" #include "supervisor/shared/display.h" #include "supervisor/memory.h" -#include "supervisor/usb.h" primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; -bool refresh_area(displayio_display_obj_t* display, const displayio_area_t* area) { - uint16_t buffer_size = 512; +// Check for recursive calls to displayio_background. +bool displayio_background_in_progress = false; - 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_clip_area(display, area, &clipped)) { - return true; - } - uint16_t subrectangles = 1; - uint16_t rows_per_buffer = displayio_area_height(&clipped); - if (displayio_area_size(area) > buffer_size) { - rows_per_buffer = buffer_size / displayio_area_width(&clipped); - subrectangles = displayio_area_height(&clipped) / rows_per_buffer; - if (displayio_area_height(&clipped) % rows_per_buffer != 0) { - subrectangles++; - } - buffer_size = rows_per_buffer * displayio_area_width(&clipped); - } - uint32_t buffer[buffer_size / 2]; - 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_begin_transaction(display); - displayio_display_set_region_to_update(display, subrectangle.x1, subrectangle.y1, - subrectangle.x2, subrectangle.y2); - displayio_display_end_transaction(display); - - uint32_t mask[(buffer_size / 32) + 1]; - for (uint16_t k = 0; k < (buffer_size / 32) + 1; k++) { - mask[k] = 0x00000000; - } - - bool full_coverage = displayio_display_fill_area(display, &subrectangle, mask, buffer); - if (!full_coverage) { - uint32_t index = 0; - uint32_t current_mask = 0; - for (int16_t y = subrectangle.y1; y < subrectangle.y2; y++) { - for (int16_t x = subrectangle.x1; x < subrectangle.x2; x++) { - if (index % 32 == 0) { - current_mask = mask[index / 32]; - } - if ((current_mask & (1 << (index % 32))) == 0) { - ((uint16_t*) buffer)[index] = 0x0000; - } - index++; - } - } - } - - if (!displayio_display_begin_transaction(display)) { - // Can't acquire display bus; skip the rest of the data. Try next display. - return false; - } - displayio_display_send_pixels(display, (uint8_t*) buffer, displayio_area_size(&subrectangle) * sizeof(uint16_t)); - displayio_display_end_transaction(display); - - // TODO(tannewt): Make refresh displays faster so we don't starve other - // background tasks. - usb_background(); - } - return true; -} - -// Check for recursive calls to displayio_refresh_displays. -bool refresh_displays_in_progress = false; -uint32_t frame_count = 0; - -void displayio_refresh_displays(void) { +void displayio_background(void) { if (mp_hal_is_interrupted()) { return; } @@ -107,61 +30,56 @@ void displayio_refresh_displays(void) { return; } - if (refresh_displays_in_progress) { + if (displayio_background_in_progress) { // Don't allow recursive calls to this routine. return; } - refresh_displays_in_progress = true; + 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; } - displayio_display_obj_t* display = &displays[i].display; - displayio_display_update_backlight(display); - - // Time to refresh at specified frame rate? - if (!displayio_display_frame_queued(display)) { - // Too soon. Try next 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); } - if (!displayio_display_begin_transaction(display)) { - // Can't acquire display bus; skip updating this display. Try next display. - continue; - } - displayio_display_end_transaction(display); - displayio_display_start_refresh(display); - const displayio_area_t* current_area = displayio_display_get_refresh_areas(display); - while (current_area != NULL) { - refresh_area(display, current_area); - current_area = current_area->next; - } - displayio_display_finish_refresh(display); - frame_count++; } // All done. - refresh_displays_in_progress = false; + 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) { + 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; } - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - release_display(&displays[i].display); - displays[i].display.base.type = &mp_type_NoneType; - } supervisor_stop_terminal(); } @@ -169,39 +87,67 @@ void common_hal_displayio_release_displays(void) { 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) { - continue; - } - 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.bus == original_spi) { - displays[i].fourwire_bus.bus = &fourwire->inline_bus; + 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++) { - if (displays[i].display.base.type == NULL) { - continue; + // 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); } - displayio_display_obj_t* display = &displays[i].display; - display->auto_brightness = true; - common_hal_displayio_display_show(display, &circuitpython_splash); } } @@ -213,8 +159,11 @@ void displayio_gc_collect(void) { // Alternatively, we could use gc_collect_root over the whole object, // but this is more precise, and is the only field that needs marking. - gc_collect_ptr(displays[i].display.current_group); - + 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); + } } } diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 18c1a4f4a9..e78bc61ce4 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -28,23 +28,29 @@ #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; }; - displayio_display_obj_t display; + 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_refresh_displays(void); +void displayio_background(void); void reset_displays(void); void displayio_gc_collect(void); diff --git a/shared-module/displayio/display_core.c b/shared-module/displayio/display_core.c new file mode 100644 index 0000000000..a73ea81d1f --- /dev/null +++ b/shared-module/displayio/display_core.c @@ -0,0 +1,335 @@ +/* + * 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->colorspace.dither = false; + 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->rotation = rotation; + 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; +} + +void displayio_display_core_set_dither(displayio_display_core_t* self, bool dither){ + self->colorspace.dither = dither; +} + +bool displayio_display_core_get_dither(displayio_display_core_t* self){ + return self->colorspace.dither; +} + +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 0000000000..3a69cd40a2 --- /dev/null +++ b/shared-module/displayio/display_core.h @@ -0,0 +1,88 @@ +/* + * 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); + +void displayio_display_core_set_dither(displayio_display_core_t* self, bool dither); +bool displayio_display_core_get_dither(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/os/__init__.c b/shared-module/os/__init__.c index 313893d977..8060eec4f3 100644 --- a/shared-module/os/__init__.c +++ b/shared-module/os/__init__.c @@ -128,6 +128,7 @@ mp_obj_t common_hal_os_listdir(const char* path) { 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)); + RUN_BACKGROUND_TASKS; } return dir_list; } diff --git a/shared-module/terminalio/Terminal.c b/shared-module/terminalio/Terminal.c index 7adf9d0328..df92a5dc48 100644 --- a/shared-module/terminalio/Terminal.c +++ b/shared-module/terminalio/Terminal.c @@ -35,6 +35,14 @@ void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, d 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) { diff --git a/ports/nrf/common-hal/touchio/TouchIn.c b/shared-module/touchio/TouchIn.c similarity index 78% rename from ports/nrf/common-hal/touchio/TouchIn.c rename to shared-module/touchio/TouchIn.c index ba50b17b0c..88d12b8b81 100644 --- a/ports/nrf/common-hal/touchio/TouchIn.c +++ b/shared-module/touchio/TouchIn.c @@ -28,15 +28,9 @@ #include #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" - -#include "nrf.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 @@ -57,15 +51,14 @@ static uint16_t get_raw_reading(touchio_touchin_obj_t *self) { for (uint16_t i = 0; i < N_SAMPLES; i++) { // set pad to digital output high for 10us to charge it - nrf_gpio_cfg_output(self->pin->number); - nrf_gpio_pin_set(self->pin->number); + 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 - nrf_gpio_cfg_input(self->pin->number, NRF_GPIO_PIN_NOPULL); + common_hal_digitalio_digitalinout_switch_to_input(self->digitalinout, PULL_NONE); - while(nrf_gpio_pin_read(self->pin->number)) { + while(common_hal_digitalio_digitalinout_get_value(self->digitalinout)) { if (ticks >= TIMEOUT_TICKS) return TIMEOUT_TICKS; ticks++; } @@ -73,16 +66,22 @@ static uint16_t get_raw_reading(touchio_touchin_obj_t *self) { return ticks; } -void common_hal_touchio_touchin_construct(touchio_touchin_obj_t* self, - const mcu_pin_obj_t *pin) { - self->pin = pin; +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; - self->threshold = get_raw_reading(self) * 1.05 + 100; + 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->pin == NULL; + return self->digitalinout == MP_OBJ_NULL; } void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t* self) { @@ -90,8 +89,8 @@ void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t* self) { return; } - reset_pin_number(self->pin->number); - self->pin = NULL; + common_hal_digitalio_digitalinout_deinit(self->digitalinout); + self->digitalinout = MP_OBJ_NULL; } void touchin_reset() { diff --git a/ports/nrf/common-hal/touchio/TouchIn.h b/shared-module/touchio/TouchIn.h similarity index 84% rename from ports/nrf/common-hal/touchio/TouchIn.h rename to shared-module/touchio/TouchIn.h index 121580eac6..8ff6fda8f4 100644 --- a/ports/nrf/common-hal/touchio/TouchIn.h +++ b/shared-module/touchio/TouchIn.h @@ -25,19 +25,20 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_TOUCHIO_TOUCHIN_H -#define MICROPY_INCLUDED_NRF_COMMON_HAL_TOUCHIO_TOUCHIN_H +#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; - const mcu_pin_obj_t *pin; + digitalio_digitalinout_obj_t *digitalinout; uint16_t threshold; } touchio_touchin_obj_t; void touchin_reset(void); -#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_TOUCHIO_TOUCHIN_H +#endif // MICROPY_INCLUDED_SHARED_MODULE_TOUCHIO_TOUCHIN_H diff --git a/ports/nrf/common-hal/touchio/__init__.c b/shared-module/touchio/__init__.c similarity index 100% rename from ports/nrf/common-hal/touchio/__init__.c rename to shared-module/touchio/__init__.c diff --git a/shared-module/usb_hid/Device.c b/shared-module/usb_hid/Device.c index 0e256cb5e4..bed7d163f9 100644 --- a/shared-module/usb_hid/Device.c +++ b/shared-module/usb_hid/Device.c @@ -47,15 +47,17 @@ void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t* // Wait until interface is ready, timeout = 2 seconds uint64_t end_ticks = ticks_ms + 2000; - while ( (ticks_ms < end_ticks) && !tud_hid_generic_ready() ) { } + while ( (ticks_ms < end_ticks) && !tud_hid_ready() ) { + RUN_BACKGROUND_TASKS; + } - if ( !tud_hid_generic_ready() ) { + if ( !tud_hid_ready() ) { mp_raise_msg(&mp_type_OSError, translate("USB Busy")); } memcpy(self->report_buffer, report, len); - if ( !tud_hid_generic_report(self->report_id, self->report_buffer, len) ) { + if ( !tud_hid_report(self->report_id, self->report_buffer, len) ) { mp_raise_msg(&mp_type_OSError, translate("USB Error")); } } @@ -70,7 +72,7 @@ static usb_hid_device_obj_t* get_hid_device(uint8_t report_id) { } // Callbacks invoked when receive Get_Report request through control endpoint -uint16_t tud_hid_generic_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) { +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; @@ -80,7 +82,7 @@ uint16_t tud_hid_generic_get_report_cb(uint8_t report_id, hid_report_type_t repo } // Callbacks invoked when receive Set_Report request through control endpoint -void tud_hid_generic_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) { +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 ) { diff --git a/shared-module/usb_hid/__init__.c b/shared-module/usb_hid/__init__.c index f14fdd41e3..d88f9787ac 100644 --- a/shared-module/usb_hid/__init__.c +++ b/shared-module/usb_hid/__init__.c @@ -24,131 +24,4 @@ * 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 - } -}; +// Nothing needed here. Tables of HID devices are generated in autogen_usb_descriptor.c at compile-time. diff --git a/shared-module/usb_midi/PortOut.c b/shared-module/usb_midi/PortOut.c index 99a4fad438..0b37dcfd41 100644 --- a/shared-module/usb_midi/PortOut.c +++ b/shared-module/usb_midi/PortOut.c @@ -33,5 +33,5 @@ size_t common_hal_usb_midi_portout_write(usb_midi_portout_obj_t *self, const uin } bool common_hal_usb_midi_portout_ready_to_tx(usb_midi_portout_obj_t *self) { - return tud_midi_connected(); + return tud_midi_mounted(); } diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index 414f850344..c6fda0f168 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -82,8 +82,7 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) { grid->pixel_height = height_in_tiles * grid->tile_height; grid->tiles = tiles; - supervisor_terminal.cursor_x = 0; - supervisor_terminal.cursor_y = 0; + common_hal_terminalio_terminal_construct(&supervisor_terminal, grid, &supervisor_terminal_font); } void supervisor_stop_terminal(void) { @@ -147,17 +146,61 @@ displayio_bitmap_t blinka_bitmap = { .read_only = true }; -uint32_t blinka_transparency[1] = {0x80000000}; - -// These colors are RGB 565 with the bytes swapped. -uint32_t blinka_colors[8] = {0x78890000, 0x9F86B8FC, 0xffff0D5A, 0x0000f501, - 0x00000000, 0x00000000, 0x00000000, 0x00000000}; +_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 }, - .opaque = blinka_transparency, .colors = blinka_colors, - .color_count = 16, + .color_count = 7, .needs_refresh = false }; @@ -179,7 +222,8 @@ displayio_tilegrid_t blinka_sprite = { .tiles = 0, .partial_change = false, .full_change = false, - .first_draw = true, + .hidden = false, + .hidden_by_parent = false, .moved = false, .inline_tiles = true, .in_group = true @@ -198,5 +242,8 @@ displayio_group_t circuitpython_splash = { .size = 2, .max_size = 2, .children = splash_children, - .item_removed = false + .item_removed = false, + .in_group = false, + .hidden = false, + .hidden_by_parent = false }; diff --git a/supervisor/shared/display.h b/supervisor/shared/display.h index d5faa7777d..2a2ccf46df 100644 --- a/supervisor/shared/display.h +++ b/supervisor/shared/display.h @@ -35,11 +35,10 @@ // These are autogenerated resources. // This is fixed so it doesn't need to be in RAM. -extern const displayio_bitmap_t supervisor_terminal_font_bitmap; - 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; diff --git a/supervisor/shared/external_flash/devices.h b/supervisor/shared/external_flash/devices.h index 5b8f9b298d..4de22719a7 100644 --- a/supervisor/shared/external_flash/devices.h +++ b/supervisor/shared/external_flash/devices.h @@ -66,7 +66,7 @@ typedef struct { bool single_status_byte: 1; } external_flash_device; -// Settings for the Adesto Tech AT25DF081A 1MiB SPI flash. Its on the SAMD21 +// 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 {\ @@ -103,6 +103,24 @@ typedef struct { .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 {\ @@ -424,4 +442,5 @@ typedef struct { .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 index ad10bab516..99df553e19 100644 --- a/supervisor/shared/external_flash/external_flash.c +++ b/supervisor/shared/external_flash/external_flash.c @@ -428,6 +428,7 @@ static bool flush_ram_cache(bool keep_cache) { } // Delegates to the correct flash flush method depending on the existing cache. +// TODO Don't blink the status indicator if we don't actually do any writing (hard to tell right now). 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); diff --git a/supervisor/shared/rgb_led_status.c b/supervisor/shared/rgb_led_status.c index 0e69cd2e0e..4d93715161 100644 --- a/supervisor/shared/rgb_led_status.c +++ b/supervisor/shared/rgb_led_status.c @@ -39,8 +39,11 @@ static digitalio_digitalinout_obj_t status_neopixel; #if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK) uint8_t rgb_status_brightness = 255; -static uint8_t status_apa102_color[12] = {0, 0, 0, 0, 0xff, 0, 0, 0}; -#ifdef CIRCUITPY_BITBANG_APA102 + +#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; @@ -81,7 +84,7 @@ void rgb_led_status_init() { 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) - #ifdef CIRCUITPY_BITBANG_APA102 + #if CIRCUITPY_BITBANG_APA102 shared_module_bitbangio_spi_construct(&status_apa102, MICROPY_HW_APA102_SCK, MICROPY_HW_APA102_MOSI, @@ -102,12 +105,14 @@ void rgb_led_status_init() { // mark them as used. apa102_mosi_in_use = false; apa102_sck_in_use = false; - #ifdef CIRCUITPY_BITBANG_APA102 + #if CIRCUITPY_BITBANG_APA102 shared_module_bitbangio_spi_try_lock(&status_apa102); - shared_module_bitbangio_spi_configure(&status_apa102, 100000, 0, 1, 8); + // 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, 100000, 0, 1, 8); + common_hal_busio_spi_configure(&status_apa102, 1000000, 0, 0, 8); #endif #endif @@ -120,7 +125,7 @@ void rgb_led_status_init() { 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); @@ -185,10 +190,10 @@ void new_status_color(uint32_t rgb) { status_apa102_color[6] = (rgb_adjusted >> 8) & 0xff; status_apa102_color[7] = (rgb_adjusted >> 16) & 0xff; - #ifdef CIRCUITPY_BITBANG_APA102 - shared_module_bitbangio_spi_write(&status_apa102, status_apa102_color, 8); + #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, 8); + common_hal_busio_spi_write(&status_apa102, status_apa102_color, APA102_BUFFER_LENGTH); #endif #endif @@ -229,20 +234,20 @@ void temp_status_color(uint32_t rgb) { if (apa102_mosi_in_use || apa102_sck_in_use) { return; } - uint8_t colors[12] = {0, 0, 0, 0, 0xff, rgb_adjusted & 0xff, (rgb_adjusted >> 8) & 0xff, (rgb_adjusted >> 16) & 0xff, 0x0, 0x0, 0x0, 0x0}; - #ifdef CIRCUITPY_BITBANG_APA102 - shared_module_bitbangio_spi_write(&status_apa102, colors, 12); + 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, 12); + 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); @@ -261,13 +266,19 @@ void temp_status_color(uint32_t rgb) { void clear_temp_status() { #ifdef MICROPY_HW_NEOPIXEL + if (neopixel_in_use) { + return; + } common_hal_neopixel_write(&status_neopixel, status_neopixel_color, 3); #endif #if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK) - #ifdef CIRCUITPY_BITBANG_APA102 - shared_module_bitbangio_spi_write(&status_apa102, status_apa102_color, 8); + if (apa102_mosi_in_use || apa102_sck_in_use) { + return; + } + #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, 8); + common_hal_busio_spi_write(&status_apa102, status_apa102_color, APA102_BUFFER_LENGTH); #endif #endif #if defined(CP_RGB_STATUS_LED) diff --git a/supervisor/shared/rgb_led_status.h b/supervisor/shared/rgb_led_status.h index 83f4822d72..e4e1981a21 100644 --- a/supervisor/shared/rgb_led_status.h +++ b/supervisor/shared/rgb_led_status.h @@ -44,7 +44,7 @@ // 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) && !defined(CIRCUITPY_BITBANG_APA102) +#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 diff --git a/supervisor/shared/status_leds.c b/supervisor/shared/status_leds.c index d99853cebe..672242a963 100644 --- a/supervisor/shared/status_leds.c +++ b/supervisor/shared/status_leds.c @@ -26,8 +26,10 @@ #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; diff --git a/supervisor/shared/usb/tusb_config.h b/supervisor/shared/usb/tusb_config.h index 301805275a..ad5825b6c9 100644 --- a/supervisor/shared/usb/tusb_config.h +++ b/supervisor/shared/usb/tusb_config.h @@ -107,7 +107,7 @@ // USB RAM PLACEMENT //--------------------------------------------------------------------+ #define CFG_TUSB_ATTR_USBRAM -#define CFG_TUSB_MEM_ALIGN ATTR_ALIGNED(4) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #ifdef __cplusplus diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index 0678a3a3fc..c1d70c5b0f 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -25,6 +25,7 @@ */ #include "tick.h" +#include "py/objstr.h" #include "shared-bindings/microcontroller/Processor.h" #include "shared-module/usb_midi/__init__.h" #include "supervisor/port.h" @@ -43,13 +44,11 @@ void load_serial_number(void) { uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH]; common_hal_mcu_processor_get_uid(raw_id); - static const char nibble_to_hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F'}; 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[nibble]; + usb_serial_number[1 + i * 2 + j] = nibble_to_hex_upper[nibble]; } } } diff --git a/supervisor/shared/usb/usb_desc.c b/supervisor/shared/usb/usb_desc.c index 5a0de1ffc8..9b333d6fea 100644 --- a/supervisor/shared/usb/usb_desc.c +++ b/supervisor/shared/usb/usb_desc.c @@ -24,23 +24,35 @@ * THE SOFTWARE. */ -#include "supervisor/shared/usb/usb_desc.h" +#include "lib/tinyusb/src/tusb.h" #include "shared-module/usb_hid/Device.h" #include "genhdr/autogen_usb_descriptor.h" -// tud_desc_set is required by tinyusb stack -tud_desc_set_t tud_desc_set = -{ - .device = &usb_desc_dev, - .config = &usb_desc_cfg, - .string_arr = (uint8_t const **) string_desc_arr, - .string_count = sizeof(string_desc_arr)/sizeof(string_desc_arr[0]), +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const * tud_descriptor_device_cb(void) { + return usb_desc_dev; +} - .hid_report = - { - .generic = hid_report_descriptor, - .boot_keyboard = NULL, - .boot_mouse = NULL - } -}; +// 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 index f6f0fa9c34..205cb7b500 100644 --- a/supervisor/shared/usb/usb_msc_flash.c +++ b/supervisor/shared/usb/usb_msc_flash.c @@ -59,59 +59,18 @@ static fs_user_mount_t* get_vfs(int lun) { } // Callback invoked when received an SCSI command not in built-in list below -// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE +// - 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_TEST_UNIT_READY: - // Command that host uses to check our readiness before sending other commands - resplen = 0; - if (lun > 1) { - resplen = -1; - } else { - fs_user_mount_t* current_mount = get_vfs(lun); - if (current_mount == NULL) { - resplen = -1; - } - if (ejected[lun]) { - resplen = -1; - } - } - break; - case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: // Host is about to read/write etc ... better not to disconnect disk resplen = 0; break; - case SCSI_CMD_START_STOP_UNIT: - { - // Host try to eject/safe remove/poweroff us. We could safely disconnect with disk storage, or go into lower power - const scsi_start_stop_unit_t* start_stop = (const scsi_start_stop_unit_t*) scsi_cmd; - // Start bit = 0 : low power mode, if load_eject = 1 : unmount disk storage as well - // Start bit = 1 : Ready mode, if load_eject = 1 : mount disk storage - resplen = 0; - if (start_stop->load_eject == 1) { - if (lun > 1) { - resplen = -1; - } else { - fs_user_mount_t* current_mount = get_vfs(lun); - if (current_mount == NULL) { - resplen = -1; - } - if (disk_ioctl(current_mount, CTRL_SYNC, NULL) != RES_OK) { - resplen = -1; - } else { - ejected[lun] = true; - } - } - } - } - break; - default: // Set Sense = Invalid Command Operation tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); @@ -127,7 +86,7 @@ int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer, } // copy response to stack's buffer if any - if ( response && resplen ) { + if ( response && (resplen > 0) ) { memcpy(buffer, response, resplen); } @@ -206,3 +165,54 @@ void tud_msc_write10_complete_cb (uint8_t 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/stub/internal_flash.c b/supervisor/stub/internal_flash.c new file mode 100644 index 0000000000..5db6b5bc00 --- /dev/null +++ b/supervisor/stub/internal_flash.c @@ -0,0 +1,66 @@ +/* + * 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" + +void supervisor_flash_init(void) { +} + +uint32_t supervisor_flash_get_block_size(void) { + return 0; +} + +uint32_t supervisor_flash_get_block_count(void) { + return 0; +} + +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 +} + +bool supervisor_flash_write_block(const uint8_t *src, uint32_t block) { + return true; +} + +mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { + return 0; // success +} + +void supervisor_flash_release_cache(void) { +} + diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index 2d50e7a8b1..ee47be4b00 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -13,7 +13,7 @@ SRC_SUPERVISOR = \ supervisor/shared/translate.c ifndef $(NO_USB) -NO_USB = $(wildcard supervisor/usb.c) + NO_USB = $(wildcard supervisor/usb.c) endif ifneq ($(INTERNAL_FLASH_FILESYSTEM),) @@ -44,7 +44,11 @@ ifdef EXTERNAL_FLASH_DEVICES SRC_SUPERVISOR += supervisor/qspi_flash.c supervisor/shared/external_flash/qspi_flash.c endif else - SRC_SUPERVISOR += supervisor/internal_flash.c + ifeq ($(DISABLE_FILESYSTEM),1) + SRC_SUPERVISOR += supervisor/stub/internal_flash.c + else + SRC_SUPERVISOR += supervisor/internal_flash.c + endif endif ifeq ($(USB),FALSE) @@ -78,9 +82,23 @@ else shared-module/usb_midi/PortIn.c \ shared-module/usb_midi/PortOut.c \ $(BUILD)/autogen_usb_descriptor.c + CFLAGS += -DUSB_AVAILABLE endif +ifndef USB_DEVICES +USB_DEVICES = "CDC,MSC,AUDIO,HID" +endif + +ifndef USB_HID_DEVICES +USB_HID_DEVICES = "KEYBOARD,MOUSE,CONSUMER,GAMEPAD" +endif + +# SAMD21 needs separate endpoint pairs for MSC BULK IN and BULK OUT, otherwise it's erratic. +ifndef USB_MSC_NUM_ENDPOINT_PAIRS +USB_MSC_NUM_ENDPOINT_PAIRS = 1 +endif + SUPERVISOR_O = $(addprefix $(BUILD)/, $(SRC_SUPERVISOR:.c=.o)) $(BUILD)/autogen_display_resources.o $(BUILD)/supervisor/shared/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h @@ -98,6 +116,9 @@ autogen_usb_descriptor.intermediate: ../../tools/gen_usb_descriptor.py Makefile --vid $(USB_VID)\ --pid $(USB_PID)\ --serial_number_length $(USB_SERIAL_NUMBER_LENGTH)\ + --devices $(USB_DEVICES)\ + --hid_devices $(USB_HID_DEVICES)\ + --msc_num_endpoint_pairs $(USB_MSC_NUM_ENDPOINT_PAIRS)\ --output_c_file $(BUILD)/autogen_usb_descriptor.c\ --output_h_file $(BUILD)/genhdr/autogen_usb_descriptor.h diff --git a/tools/build_board_info.py b/tools/build_board_info.py index 8731a6feb0..7d0d2996cc 100644 --- a/tools/build_board_info.py +++ b/tools/build_board_info.py @@ -12,7 +12,7 @@ from sh.contrib import git sys.path.append("adabot") import adabot.github_requests as github -SUPPORTED_PORTS = ["nrf", "atmel-samd"] +SUPPORTED_PORTS = ["nrf", "atmel-samd", "stm32f4"] BIN = ('bin',) UF2 = ('uf2',) @@ -23,6 +23,7 @@ HEX = ('hex',) extension_by_port = { "nrf": UF2, "atmel-samd": UF2, + "stm32f4": BIN, } # Per board overrides @@ -88,10 +89,8 @@ def get_version_info(): # No exact match pass - if "TRAVIS" in os.environ and os.environ["TRAVIS"] == "true": - sha = os.environ["TRAVIS_COMMIT"] - if os.environ["TRAVIS_PULL_REQUEST"] != "false": - sha = os.environ["TRAVIS_PULL_REQUEST_SHA"] + if "GITHUB_SHA" in os.environ: + sha = os.environ["GITHUB_SHA"] if not version: version="{}-{}".format(date.today().strftime("%Y%m%d"), sha[:7]) @@ -119,7 +118,7 @@ def get_current_info(): current_info[info["id"]] = info return git_info, current_info -def create_pr(changes, updated, git_info): +def create_pr(changes, updated, git_info, user): commit_sha, original_blob_sha = git_info branch_name = "new_release_" + changes["new_release"] @@ -132,7 +131,7 @@ def create_pr(changes, updated, git_info): updated_list.append(info) updated = json.dumps(updated_list, sort_keys=True, indent=4).encode("utf-8") + b"\n" - print(updated.decode("utf-8")) + #print(updated.decode("utf-8")) pr_title = "Automated website update for release {}".format(changes["new_release"]) boards = "" if changes["new_boards"]: @@ -140,7 +139,7 @@ def create_pr(changes, updated, git_info): 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( + message = "Automated website update for release {} by Blinka.\n\n{}\n\n{}\n".format( changes["new_release"], boards, languages @@ -150,7 +149,7 @@ def create_pr(changes, updated, git_info): "ref": "refs/heads/" + branch_name, "sha": commit_sha } - response = github.post("/repos/adafruit-adabot/circuitpython-org/git/refs", json=create_branch) + response = github.post("/repos/{}/circuitpython-org/git/refs".format(user), json=create_branch) if not response.ok and response.json()["message"] != "Reference already exists": print("unable to create branch") print(response.text) @@ -163,14 +162,14 @@ def create_pr(changes, updated, git_info): "branch": branch_name } - response = github.put("/repos/adafruit-adabot/circuitpython-org/contents/_data/files.json", json=update_file) + response = github.put("/repos/{}/circuitpython-org/contents/_data/files.json".format(user), 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, + "head": user + ":" + branch_name, "base": "master", "body": message, "maintainer_can_modify": True @@ -200,15 +199,18 @@ def update_downloads(boards, release): def print_active_user(): response = github.get("/user") if response.ok: - print("Logged in as {}".format(response.json()["login"])) + user = response.json()["login"] + print("Logged in as {}".format(user)) + return user else: print("Not logged in") + return None def generate_download_info(): boards = {} errors = [] - new_tag = os.environ["TRAVIS_TAG"] + new_tag = os.environ["RELEASE_TAG"] changes = { "new_release": new_tag, @@ -216,7 +218,7 @@ def generate_download_info(): "new_languages": [] } - print_active_user() + user = print_active_user() sha, this_version = get_version_info() @@ -240,7 +242,6 @@ def generate_download_info(): board_mapping = get_board_mapping() - print(previous_releases) for release in previous_releases: update_downloads(board_mapping, release) @@ -274,13 +275,13 @@ def generate_download_info(): changes["new_languages"] = set(languages) - previous_languages - if changes["new_release"]: - create_pr(changes, current_info, git_info) + if changes["new_release"] and user: + create_pr(changes, current_info, git_info, user) else: print("No new release to update") if __name__ == "__main__": - if "TRAVIS_TAG" in os.environ and os.environ["TRAVIS_TAG"]: + 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_release_files.py b/tools/build_release_files.py index e29b098c79..09133e51fa 100755 --- a/tools/build_release_files.py +++ b/tools/build_release_files.py @@ -10,21 +10,14 @@ import time for port in build_info.SUPPORTED_PORTS: result = subprocess.run("rm -rf ../ports/{port}/build*".format(port=port), shell=True) -ROSIE_SETUPS = ["rosie-ci"] -rosie_ok = {} -for rosie in ROSIE_SETUPS: - rosie_ok[rosie] = True - PARALLEL = "-j 5" -travis = False -if "TRAVIS" in os.environ and os.environ["TRAVIS"] == "true": +if "GITHUB_ACTION" in os.environ: PARALLEL="-j 2" - travis = True all_boards = build_info.get_board_mapping() build_boards = list(all_boards.keys()) -if "TRAVIS_BOARDS" in os.environ: - build_boards = os.environ["TRAVIS_BOARDS"].split() +if "BOARDS" in os.environ: + build_boards = os.environ["BOARDS"].split() sha, version = build_info.get_version_info() @@ -83,25 +76,14 @@ for board in build_boards: if exit_status == 0: exit_status = 1 - if travis: - print('travis_fold:start:adafruit-bins-{}-{}\\r'.format(language, board)) 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)) - if make_result.returncode != 0: - print(make_result.stdout.decode("utf-8")) - print(other_output) - # Only upload to Rosie if its a pull request. - if travis: - for rosie in ROSIE_SETUPS: - if not rosie_ok[rosie]: - break - print("Uploading to https://{rosie}.ngrok.io/upload/{sha}".format(rosie=rosie, sha=sha)) - #curl -F "file=@$final_filename" https://$rosie.ngrok.io/upload/$sha - if travis: - print('travis_fold:end:adafruit-bins-{}-{}\\r'.format(language, board)) - # Flush so travis will see something before 10 minutes has passed. + 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/check_translations.py b/tools/check_translations.py index 4bea040bfe..7c008d3da7 100644 --- a/tools/check_translations.py +++ b/tools/check_translations.py @@ -16,8 +16,10 @@ for po_filename in po_filenames: po_file = polib.pofile(po_filename) po_ids = set([x.msgid for x in po_file]) - if all_ids - po_ids: + 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 0000000000..8bb8876fbc --- /dev/null +++ b/tools/ci_new_boards_check.py @@ -0,0 +1,51 @@ +#! /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: + ok = False + 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 index 4805f182a7..87b7e444b7 100644 --- a/tools/convert_release_notes.py +++ b/tools/convert_release_notes.py @@ -31,6 +31,11 @@ class AdafruitBBCodeRenderer: def link(self, link, title, text): return "[url={}]{}[/url]".format(link, text) + def autolink(self, link, is_email): + if not is_email: + return "[url={}]{}[/url]".format(link, link) + return link + def header(self, text, level, raw): return "[b][size=150]{}[/size][/b]\n".format(text) diff --git a/tools/gen_display_resources.py b/tools/gen_display_resources.py index 2c674c8ebd..781b5e69b2 100644 --- a/tools/gen_display_resources.py +++ b/tools/gen_display_resources.py @@ -98,14 +98,23 @@ c_file.write("""\ """) c_file.write("""\ -uint32_t terminal_transparency[1] = {0x00000000}; - -// These colors are RGB 565 with the bytes swapped. -uint32_t terminal_colors[1] = {0xffff0000}; +_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 }, - .opaque = terminal_transparency, .colors = terminal_colors, .color_count = 2, .needs_refresh = false @@ -122,6 +131,7 @@ displayio_tilegrid_t supervisor_terminal_text_grid = {{ .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}, @@ -129,7 +139,8 @@ displayio_tilegrid_t supervisor_terminal_text_grid = {{ .tiles = NULL, .partial_change = false, .full_change = false, - .first_draw = true, + .hidden = false, + .hidden_by_parent = false, .moved = false, .inline_tiles = false, .in_group = true @@ -150,7 +161,7 @@ c_file.write("""\ """) c_file.write("""\ -const displayio_bitmap_t supervisor_terminal_font_bitmap = {{ +displayio_bitmap_t supervisor_terminal_font_bitmap = {{ .base = {{.type = &displayio_bitmap_type }}, .width = {}, .height = {}, diff --git a/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py index 10bbf50663..c4ff74d394 100644 --- a/tools/gen_usb_descriptor.py +++ b/tools/gen_usb_descriptor.py @@ -8,6 +8,15 @@ sys.path.append("../../tools/usb_descriptor") from adafruit_usb_descriptor import audio, audio10, cdc, hid, midi, msc, standard, util import hid_report_descriptors +ALL_DEVICES='CDC,MSC,AUDIO,HID' +ALL_DEVICES_SET=frozenset(ALL_DEVICES.split(',')) +DEFAULT_DEVICES='CDC,MSC,AUDIO,HID' + +ALL_HID_DEVICES='KEYBOARD,MOUSE,CONSUMER,SYS_CONTROL,GAMEPAD,DIGITIZER,XAC_COMPATIBLE_GAMEPAD,RAW' +ALL_HID_DEVICES_SET=frozenset(ALL_HID_DEVICES.split(',')) +# Digitizer works on Linux but conflicts with mouse, so omit it. +DEFAULT_HID_DEVICES='KEYBOARD,MOUSE,CONSUMER,GAMEPAD' + parser = argparse.ArgumentParser(description='Generate USB descriptors.') parser.add_argument('--manufacturer', type=str, help='manufacturer of the device') @@ -19,11 +28,29 @@ 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('--devices', type=lambda l: tuple(l.split(',')), default=DEFAULT_DEVICES, + help='devices to include in descriptor (AUDIO includes MIDI support)') +parser.add_argument('--hid_devices', type=lambda l: tuple(l.split(',')), default=DEFAULT_HID_DEVICES, + help='HID devices to include in HID report descriptor') +parser.add_argument('--msc_num_endpoint_pairs', type=int, default=1, + help='Use 1 or 2 endpoint pairs for MSC (1 bidirectional, or 1 input + 1 output (required by SAMD21))') 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() +unknown_devices = list(frozenset(args.devices) - ALL_DEVICES_SET) +if unknown_devices: + raise ValueError("Unknown device(s)", unknown_devices) + +unknown_hid_devices = list(frozenset(args.hid_devices) - ALL_HID_DEVICES_SET) +if unknown_hid_devices: + raise ValueError("Unknown HID devices(s)", unknown_hid_devices) + +if args.msc_num_endpoint_pairs not in (1, 2): + raise ValueError("--msc_num_endpoint_pairs must be 1 or 2") + + class StringIndex: """Assign a monotonically increasing index to each unique string. Start with 0.""" string_to_index = {} @@ -131,25 +158,40 @@ msc_interfaces = [ bInterval=0), standard.EndpointDescriptor( description="MSC out", - bEndpointAddress=0x1 | standard.EndpointDescriptor.DIRECTION_OUT, + # SAMD21 needs to use a separate pair of endpoints for MSC. + bEndpointAddress=((0x1 if args.msc_num_endpoint_pairs == 2 else 0x0) | + 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") +# When there's only one hid_device, it shouldn't have a report id. +# Otherwise, report ids are assigned sequentially: +# args.hid_devices[0] has report_id 1 +# args.hid_devices[1] has report_id 2 +# etc. -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 )) +report_ids = {} -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()) +if len(args.hid_devices) == 1: + name = args.hid_devices[0] + combined_hid_report_descriptor = hid.ReportDescriptor( + description=name, + report_descriptor=bytes(hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](0))) + report_ids[name] = 0 +else: + report_id = 1 + concatenated_descriptors = bytearray() + for name in args.hid_devices: + concatenated_descriptors.extend( + bytes(hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](report_id))) + report_ids[name] = report_id + report_id += 1 + combined_hid_report_descriptor = hid.ReportDescriptor( + description="MULTIDEVICE", + report_descriptor=bytes(concatenated_descriptors)) # ASF4 expects keyboard and generic devices to have both in and out endpoints, # and will fail (possibly silently) if both are not supplied. @@ -157,7 +199,13 @@ hid_endpoint_in_descriptor = standard.EndpointDescriptor( description="HID in", bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, - bInterval=10) + bInterval=8) + +hid_endpoint_out_descriptor = standard.EndpointDescriptor( + description="HID out", + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT, + bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, + bInterval=8) hid_interfaces = [ standard.InterfaceDescriptor( @@ -171,6 +219,7 @@ hid_interfaces = [ description="HID", wDescriptorLength=len(bytes(combined_hid_report_descriptor))), hid_endpoint_in_descriptor, + hid_endpoint_out_descriptor, ] ), ] @@ -250,10 +299,24 @@ audio_control_interface = standard.InterfaceDescriptor( # 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, +interfaces_to_join = [] + +if 'CDC' in args.devices: + interfaces_to_join.append(cdc_interfaces) + +if 'MSC' in args.devices: + interfaces_to_join.append(msc_interfaces) + +if 'HID' in args.devices: + interfaces_to_join.append(hid_interfaces) + +if 'AUDIO' in args.devices: + interfaces_to_join.append(audio_interfaces) + +# util.join_interfaces() 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) +interfaces = util.join_interfaces(*interfaces_to_join) # Now adjust the CDC interface cross-references. @@ -271,19 +334,29 @@ cdc_iad = standard.InterfaceAssociationDescriptor( 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) + +if 'CDC' in args.devices: + # 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.append(cdc_iad) + descriptor_list.extend(cdc_interfaces) + +if 'MSC' in args.devices: + descriptor_list.extend(msc_interfaces) + +if 'HID' in args.devices: + descriptor_list.extend(hid_interfaces) + +if 'AUDIO' in args.devices: + # Only add the control interface because other audio interfaces are managed by it to ensure the + # correct ordering. + descriptor_list.append(audio_control_interface) + +# Finally, build the composite descriptor. configuration = standard.ConfigurationDescriptor( description="Composite configuration", @@ -302,6 +375,8 @@ h_file = args.output_h_file c_file.write("""\ #include +#include "py/objtuple.h" +#include "shared-bindings/usb_hid/Device.h" #include "{H_FILE_NAME}" """.format(H_FILE_NAME=h_file.name)) @@ -420,7 +495,9 @@ 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}]; +const uint8_t hid_report_descriptor[{hid_report_descriptor_length}]; + +#define USB_HID_NUM_DEVICES {hid_num_devices} // Vendor name included in Inquiry response, max 8 bytes #define CFG_TUD_MSC_VENDOR "{msc_vendor}" @@ -434,36 +511,11 @@ const uint8_t hid_report_descriptor[{HID_REPORT_DESCRIPTOR_LENGTH}]; 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)), + hid_report_descriptor_length=len(bytes(combined_hid_report_descriptor)), + hid_num_devices=len(args.hid_devices), 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}] = {{ @@ -471,7 +523,55 @@ const uint8_t hid_report_descriptor[{HID_DESCRIPTOR_LENGTH}] = {{ for b in bytes(combined_hid_report_descriptor): c_file.write("0x{:02x}, ".format(b)) +c_file.write("""\ +}; + +""") + +# Write out USB HID report buffer definitions. +for name in args.hid_devices: + c_file.write("""\ +static uint8_t {name}_report_buffer[{report_length}]; +""".format(name=name.lower(), report_length=hid_report_descriptors.HID_DEVICE_DATA[name].report_length)) + +# Write out table of device objects. c_file.write(""" +usb_hid_device_obj_t usb_hid_devices[] = { +"""); +for name in args.hid_devices: + device_data = hid_report_descriptors.HID_DEVICE_DATA[name] + c_file.write("""\ + {{ + .base = {{ .type = &usb_hid_device_type }}, + .report_buffer = {name}_report_buffer, + .report_id = {report_id}, + .report_length = {report_length}, + .usage_page = {usage_page:#04x}, + .usage = {usage:#04x}, + }}, +""".format(name=name.lower(), report_id=report_ids[name], + report_length=device_data.report_length, + usage_page=device_data.usage_page, + usage=device_data.usage)) +c_file.write("""\ +}; +""") + +# Write out tuple of device objects. +c_file.write(""" +mp_obj_tuple_t common_hal_usb_hid_devices = {{ + .base = {{ + .type = &mp_type_tuple, + }}, + .len = {num_devices}, + .items = {{ +""".format(num_devices=len(args.hid_devices))) +for idx in range(len(args.hid_devices)): + c_file.write("""\ + (mp_obj_t) &usb_hid_devices[{idx}], +""".format(idx=idx)) +c_file.write("""\ + }, }; """) diff --git a/tools/hid_report_descriptors.py b/tools/hid_report_descriptors.py index f3b28ebcf3..92c962d59b 100644 --- a/tools/hid_report_descriptors.py +++ b/tools/hid_report_descriptors.py @@ -29,211 +29,284 @@ HID specific descriptors * Author(s): Dan Halbert """ +from collections import namedtuple + from adafruit_usb_descriptor import hid -REPORT_IDS = { - "KEYBOARD" : 1, - "MOUSE" : 2, - "CONSUMER" : 3, - "SYS_CONTROL" : 4, - "GAMEPAD" : 5, - "DIGITIZER" : 6, +# Information about each kind of device +# report_length does not include report ID in first byte, if present when sent. +DeviceData = namedtuple('DeviceData', ('report_length', 'usage_page', 'usage')) +HID_DEVICE_DATA = { + "KEYBOARD" : DeviceData(report_length=8, usage_page=0x01, usage=0x06), # Generic Desktop, Keyboard + "MOUSE" : DeviceData(report_length=4, usage_page=0x01, usage=0x02), # Generic Desktop, Mouse + "CONSUMER" : DeviceData(report_length=2, usage_page=0x0C, usage=0x01), # Consumer, Consumer Control + "SYS_CONTROL" : DeviceData(report_length=1, usage_page=0x01, usage=0x80), # Generic Desktop, Sys Control + "GAMEPAD" : DeviceData(report_length=6, usage_page=0x01, usage=0x05), # Generic Desktop, Game Pad + "DIGITIZER" : DeviceData(report_length=5, usage_page=0x0D, usage=0x02), # Digitizers, Pen + "XAC_COMPATIBLE_GAMEPAD" : DeviceData(report_length=3, usage_page=0x01, usage=0x05), # Generic Desktop, Game Pad + "RAW" : DeviceData(report_length=64, usage_page=0xFFAF, usage=0xAF), # Vendor 0xFFAF "Adafruit", 0xAF } -# 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, - } +def keyboard_hid_descriptor(report_id): + data = HID_DEVICE_DATA["KEYBOARD"] + return hid.ReportDescriptor( + description="KEYBOARD", + report_descriptor=bytes( + # Regular keyboard + (0x05, data.usage_page, # Usage Page (Generic Desktop) + 0x09, data.usage, # Usage (Keyboard) + 0xA1, 0x01, # Collection (Application) + ) + + ((0x85, report_id) if report_id != 0 else ()) + + (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 + ))) -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 - ])) +def mouse_hid_descriptor(report_id): + data = HID_DEVICE_DATA["MOUSE"] + return hid.ReportDescriptor( + description="MOUSE", + report_descriptor=bytes( + # Regular mouse + (0x05, data.usage_page, # Usage Page (Generic Desktop) + 0x09, data.usage, # Usage (Mouse) + 0xA1, 0x01, # Collection (Application) + 0x09, 0x01, # Usage (Pointer) + 0xA1, 0x00, # Collection (Physical) + ) + + ((0x85, report_id) if report_id != 0 else ()) + + (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 + ))) -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 - ])) +def consumer_hid_descriptor(report_id): + data = HID_DEVICE_DATA["CONSUMER"] + return hid.ReportDescriptor( + description="CONSUMER", + report_descriptor=bytes( + # Consumer ("multimedia") keys + (0x05, data.usage_page, # Usage Page (Consumer) + 0x09, data.usage, # Usage (Consumer Control) + 0xA1, 0x01, # Collection (Application) + ) + + ((0x85, report_id) if report_id != 0 else ()) + + (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 + ))) -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 - ])) +def sys_control_hid_descriptor(report_id): + data = HID_DEVICE_DATA["SYS_CONTROL"] + return hid.ReportDescriptor( + description="SYS_CONTROL", + report_descriptor=bytes( + # Power controls + (0x05, data.usage_page, # Usage Page (Generic Desktop Ctrls) + 0x09, data.usage, # Usage (Sys Control) + 0xA1, 0x01, # Collection (Application) + ) + + ((0x85, report_id) if report_id != 0 else ()) + + (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 + ))) -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 - ])) +def gamepad_hid_descriptor(report_id): + data = HID_DEVICE_DATA["GAMEPAD"] + return hid.ReportDescriptor( + description="GAMEPAD", + report_descriptor=bytes( + # Gamepad with 16 buttons and two joysticks + (0x05, data.usage_page, # Usage Page (Generic Desktop Ctrls) + 0x09, data.usage, # Usage (Game Pad) + 0xA1, 0x01, # Collection (Application) + ) + + ((0x85, report_id) if report_id != 0 else ()) + + (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 + ))) -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 - ])) +def digitizer_hid_descriptor(report_id): + data = HID_DEVICE_DATA["DIGITIZER"] + return hid.ReportDescriptor( + description="DIGITIZER", + report_descriptor=bytes( + # Digitizer (used as an absolute pointer) + (0x05, data.usage_page, # Usage Page (Digitizers) + 0x09, data.usage, # Usage (Pen) + 0xA1, 0x01, # Collection (Application) + ) + + ((0x85, report_id) if report_id != 0 else ()) + + (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 + ))) -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 - ])) +def xac_compatible_gamepad_hid_descriptor(report_id): + data = HID_DEVICE_DATA["XAC_COMPATIBLE_GAMEPAD"] + return hid.ReportDescriptor( + description="XAC", + report_descriptor=bytes( + # This descriptor mimics the simple joystick from PDP that the XBox likes + (0x05, data.usage_page, # Usage Page (Desktop), + 0x09, data.usage, # Usage (Gamepad), + 0xA1, 0x01, # Collection (Application), + ) + + ((0x85, report_id) if report_id != 0 else ()) + + (0x15, 0x00, # Logical Minimum (0), + 0x25, 0x01, # Logical Maximum (1), + 0x35, 0x00, # Physical Minimum (0), + 0x45, 0x01, # Physical Maximum (1), + 0x75, 0x01, # Report Size (1), + 0x95, 0x08, # Report Count (8), + 0x05, 0x09, # Usage Page (Button), + 0x19, 0x01, # Usage Minimum (01h), + 0x29, 0x08, # Usage Maximum (08h), + 0x81, 0x02, # Input (Variable), + 0x05, 0x01, # Usage Page (Desktop), + 0x26, 0xFF, 0x00, # Logical Maximum (255), + 0x46, 0xFF, 0x00, # Physical Maximum (255), + 0x09, 0x30, # Usage (X), + 0x09, 0x31, # Usage (Y), + 0x75, 0x08, # Report Size (8), + 0x95, 0x02, # Report Count (2), + 0x81, 0x02, # Input (Variable), + 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, - } +def raw_hid_descriptor(report_id): + if report_id != 0: + raise ValueError("raw hid must not have a report id") + data = HID_DEVICE_DATA["RAW"] + return hid.ReportDescriptor( + description="RAW", + report_descriptor=bytes( + # Provide vendor-defined + # This is a two-byte page value. + (0x06, data.usage_page & 0xff, (data.usage_page >> 8) & 0xff, # Usage Page (Vendor 0xFFAF "Adafruit"), + 0x09, data.usage, # Usage (AF), + 0xA1, 0x01, # Collection (Application), + 0x75, 0x08, # Report Size (8), + 0x15, 0x00, # Logical Minimum (0), + 0x26, 0xFF, 0x00, # Logical Maximum (255), + 0x95, 0x08, # Report Count (8), + 0x09, 0x01, # Usage(xxx) + 0x81, 0x02, # Input (Variable) + 0x95, 0x08, # Report Count (8), + 0x09, 0x02, # Usage(xxx) + 0x91, 0x02, # Input (Variable) + 0xC0 # End Collection + ))) + +# Function to call for each kind of HID descriptor. +REPORT_DESCRIPTOR_FUNCTIONS = { + "KEYBOARD" : keyboard_hid_descriptor, + "MOUSE" : mouse_hid_descriptor, + "CONSUMER" : consumer_hid_descriptor, + "SYS_CONTROL" : sys_control_hid_descriptor, + "GAMEPAD" : gamepad_hid_descriptor, + "DIGITIZER" : digitizer_hid_descriptor, + "XAC_COMPATIBLE_GAMEPAD" : xac_compatible_gamepad_hid_descriptor, + "RAW" : raw_hid_descriptor, +} diff --git a/tools/preprocess_frozen_modules.py b/tools/preprocess_frozen_modules.py index bb6959f0d8..2199e9d395 100755 --- a/tools/preprocess_frozen_modules.py +++ b/tools/preprocess_frozen_modules.py @@ -32,8 +32,9 @@ def version_string(path=None, *, valid_semver=False): 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']: + # Skip library examples directory and subfolders. + relative_path_parts = Path(root).relative_to(in_dir).parts + if relative_path_parts and relative_path_parts[0] in ['examples', 'docs', 'tests']: continue for file in files: diff --git a/tools/upload_release_files.py b/tools/upload_release_files.py new file mode 100755 index 0000000000..4f193a8bec --- /dev/null +++ b/tools/upload_release_files.py @@ -0,0 +1,35 @@ +#! /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: + if response.status_code == 422 and response.json().get("errors", [{"code":""}])[0]["code"] == "already_exists": + print("File already uploaded. Skipping.") + continue + print("Upload of {} failed with {}.".format(filename, response.status_code)) + print(response.text) + sys.exit(response.status_code) + +sys.exit(exit_status)