commit
db8365c79e
|
@ -0,0 +1,279 @@
|
|||
name: Build CI
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
release:
|
||||
types: [published]
|
||||
check_suite:
|
||||
types: [rerequested]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-16.04
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- 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 eatmydata
|
||||
sudo eatmydata apt-get install -y gettext librsvg2-bin mingw-w64
|
||||
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: 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
|
||||
|
||||
- name: Build mpy-cross.static-raspbian
|
||||
run: make -C mpy-cross -j2 -f Makefile.static-raspbian
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: mpy-cross.static-raspbian
|
||||
path: mpy-cross/mpy-cross.static-raspbian
|
||||
|
||||
- name: Build mpy-cross.static
|
||||
run: make -C mpy-cross -j2 -f Makefile.static
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: mpy-cross.static-amd64-linux
|
||||
path: mpy-cross/mpy-cross.static
|
||||
|
||||
- name: Build mpy-cross.static-mingw
|
||||
run: make -C mpy-cross -j2 -f Makefile.static-mingw
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: mpy-cross.static-x64-windows
|
||||
path: mpy-cross/mpy-cross.static.exe
|
||||
|
||||
mpy-cross-mac:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- name: Install deps
|
||||
run: |
|
||||
brew link --force gettext
|
||||
- name: Versions
|
||||
run: |
|
||||
gcc --version
|
||||
python3 --version
|
||||
msgfmt --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
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: mpy-cross-macos-catalina
|
||||
path: mpy-cross/mpy-cross
|
||||
|
||||
build-arm:
|
||||
runs-on: ubuntu-16.04
|
||||
needs: test
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board:
|
||||
- "aramcon_badge_2019"
|
||||
- "arduino_mkr1300"
|
||||
- "arduino_mkrzero"
|
||||
- "arduino_nano_33_ble"
|
||||
- "arduino_zero"
|
||||
- "bast_pro_mini_m0"
|
||||
- "capablerobot_usbhub"
|
||||
- "catwan_usbstick"
|
||||
- "circuitbrains_basic_m0"
|
||||
- "circuitbrains_deluxe_m4"
|
||||
- "circuitplayground_bluefruit"
|
||||
- "circuitplayground_express"
|
||||
- "circuitplayground_express_crickit"
|
||||
- "circuitplayground_express_displayio"
|
||||
- "clue_nrf52840_express"
|
||||
- "cp32-m4"
|
||||
- "datalore_ip_m4"
|
||||
- "datum_distance"
|
||||
- "datum_imu"
|
||||
- "datum_light"
|
||||
- "datum_weather"
|
||||
- "electronut_labs_blip"
|
||||
- "electronut_labs_papyr"
|
||||
- "escornabot_makech"
|
||||
- "espruino_pico"
|
||||
- "feather_bluefruit_sense"
|
||||
- "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_mimxrt1011"
|
||||
- "feather_mimxrt1062"
|
||||
- "feather_nrf52840_express"
|
||||
- "feather_radiofruit_zigbee"
|
||||
- "feather_stm32f405_express"
|
||||
- "gemma_m0"
|
||||
- "grandcentral_m4_express"
|
||||
- "hallowing_m0_express"
|
||||
- "hallowing_m4_express"
|
||||
- "imxrt1010_evk"
|
||||
- "imxrt1020_evk"
|
||||
- "imxrt1060_evk"
|
||||
- "itsybitsy_m0_express"
|
||||
- "itsybitsy_m4_express"
|
||||
- "itsybitsy_nrf52840_express"
|
||||
- "kicksat-sprite"
|
||||
- "makerdiary_nrf52840_mdk"
|
||||
- "makerdiary_nrf52840_mdk_usb_dongle"
|
||||
- "meowbit_v121"
|
||||
- "meowmeow"
|
||||
- "metro_m0_express"
|
||||
- "metro_m4_airlift_lite"
|
||||
- "metro_m4_express"
|
||||
- "metro_nrf52840_express"
|
||||
- "mini_sam_m4"
|
||||
- "monster_m4sk"
|
||||
- "ndgarage_ndbit6"
|
||||
- "ohs2020_badge"
|
||||
- "openbook_m4"
|
||||
- "particle_argon"
|
||||
- "particle_boron"
|
||||
- "particle_xenon"
|
||||
- "pca10056"
|
||||
- "pca10059"
|
||||
- "pewpew10"
|
||||
- "pewpew_m4"
|
||||
- "pirkey_m0"
|
||||
- "pyb_nano_v2"
|
||||
- "pybadge"
|
||||
- "pybadge_airlift"
|
||||
- "pyboard_v11"
|
||||
- "pygamer"
|
||||
- "pygamer_advance"
|
||||
- "pyportal"
|
||||
- "pyportal_titano"
|
||||
- "pyruler"
|
||||
- "robohatmm1_m4"
|
||||
- "sam32"
|
||||
- "seeeduino_xiao"
|
||||
- "serpente"
|
||||
- "shirtty"
|
||||
- "snekboard"
|
||||
- "sparkfun_lumidrive"
|
||||
- "sparkfun_nrf52840_mini"
|
||||
- "sparkfun_qwiic_micro_no_flash"
|
||||
- "sparkfun_qwiic_micro_with_flash"
|
||||
- "sparkfun_redboard_turbo"
|
||||
- "sparkfun_samd21_dev"
|
||||
- "sparkfun_samd21_mini"
|
||||
- "spresense"
|
||||
- "stm32f411ce_blackpill"
|
||||
- "stm32f411ve_discovery"
|
||||
- "stm32f412zg_discovery"
|
||||
- "stringcar_m0_express"
|
||||
- "teensy40"
|
||||
- "teknikio_bluebird"
|
||||
- "trellis_m4_express"
|
||||
- "trinket_m0"
|
||||
- "trinket_m0_haxpress"
|
||||
- "uchip"
|
||||
- "ugame10"
|
||||
- "winterbloom_sol"
|
||||
- "xinabox_cc03"
|
||||
- "xinabox_cs11"
|
||||
|
||||
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://adafruit-circuit-python.s3.amazonaws.com/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2
|
||||
sudo tar -C /usr --strip-components=1 -xaf gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2
|
||||
- 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: "[ -z \"$AWS_ACCESS_KEY_ID\" ] || 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: "[ -z \"$ADABOT_GITHUB_ACCESS_TOKEN\" ] || 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')
|
|
@ -0,0 +1,37 @@
|
|||
name: Update CircuitPython.org
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
website:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- 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')
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
# Packages
|
||||
############
|
||||
dist/
|
||||
*.egg-info
|
||||
|
||||
# Logs and Databases
|
||||
######################
|
||||
|
@ -25,6 +27,7 @@
|
|||
######################
|
||||
build/
|
||||
bin/
|
||||
circuitpython-stubs/
|
||||
|
||||
# Test failure outputs
|
||||
######################
|
||||
|
@ -62,6 +65,8 @@ TAGS
|
|||
*~
|
||||
|
||||
*.DS_Store
|
||||
**/*.DS_Store
|
||||
*.icloud
|
||||
|
||||
# POEdit mo files
|
||||
####################
|
||||
|
|
|
@ -76,7 +76,8 @@
|
|||
[submodule "lib/tinyusb"]
|
||||
path = lib/tinyusb
|
||||
url = https://github.com/hathach/tinyusb.git
|
||||
branch = develop
|
||||
branch = master
|
||||
fetchRecurseSubmodules = false
|
||||
[submodule "tools/huffman"]
|
||||
path = tools/huffman
|
||||
url = https://github.com/tannewt/huffman.git
|
||||
|
@ -95,3 +96,18 @@
|
|||
[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
|
||||
[submodule "ports/cxd56/spresense-exported-sdk"]
|
||||
path = ports/cxd56/spresense-exported-sdk
|
||||
url = https://github.com/sonydevworld/spresense-exported-sdk.git
|
||||
[submodule "frozen/Adafruit_CircuitPython_SD"]
|
||||
path = frozen/Adafruit_CircuitPython_SD
|
||||
url = https://github.com/adafruit/Adafruit_CircuitPython_SD.git
|
||||
[submodule "lib/mp3"]
|
||||
path = lib/mp3
|
||||
url = https://github.com/adafruit/Adafruit_MP3
|
||||
[submodule "ports/mimxrt10xx/sdk"]
|
||||
path = ports/mimxrt10xx/sdk
|
||||
url = https://github.com/adafruit/MIMXRT10xx_SDK
|
||||
|
|
|
@ -1,2 +1,10 @@
|
|||
# .readthedocs.yml
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
version: 2
|
||||
|
||||
python:
|
||||
version: 3
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
|
|
134
.travis.yml
134
.travis.yml
|
@ -1,134 +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 pca10056 pca10059 feather_nrf52840_express makerdiary_nrf52840_mdk makerdiary_nrf52840_mdk_usb_dongle particle_boron particle_argon particle_xenon sparkfun_nrf52840_mini" 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" TRAVIS_SDK=arm
|
||||
- TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow sam32 uchip" 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" 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" TRAVIS_SDK=arm
|
||||
|
||||
addons:
|
||||
artifacts:
|
||||
paths:
|
||||
- $(ls -d1 bin/*/*/* | tr "\n" ":")
|
||||
target_paths: /
|
||||
|
||||
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 || pip install --user Sphinx sphinx-rtd-theme recommonmark)
|
||||
- (! 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)
|
|
@ -0,0 +1,82 @@
|
|||
|
||||
# Building CircuitPython
|
||||
|
||||
Welcome to CircuitPython!
|
||||
|
||||
This document is a quick-start guide only.
|
||||
|
||||
Detailed guides on how to build CircuitPython can be found in the Adafruit Learn system at
|
||||
https://learn.adafruit.com/building-circuitpython/
|
||||
|
||||
## Setup
|
||||
|
||||
Please ensure you setup your build environment appropriately, as per the guide. You will need:
|
||||
|
||||
* Linux: https://learn.adafruit.com/building-circuitpython/linux
|
||||
* MacOS: https://learn.adafruit.com/building-circuitpython/macos
|
||||
* Windows Subsystem for Linux (WSL): https://learn.adafruit.com/building-circuitpython/windows-subsystem-for-linux
|
||||
|
||||
### Submodules
|
||||
|
||||
This project has a bunch of git submodules. You will need to update them regularly.
|
||||
|
||||
git submodule sync
|
||||
git submodule update --init
|
||||
|
||||
### mpy-cross
|
||||
|
||||
As part of the build process, mpy-cross is needed to compile .py files into .mpy files.
|
||||
To compile (or recompile) mpy-cross:
|
||||
|
||||
make -C mpy-cross
|
||||
|
||||
# Building
|
||||
|
||||
There a number of ports of CircuitPython! To build for your board, change to the appropriate ports directory and build.
|
||||
|
||||
Examples:
|
||||
|
||||
cd ports/atmel-samd
|
||||
make BOARD=circuitplayground_express
|
||||
|
||||
cd ports/nrf
|
||||
make BOARD=circuitplayground_bluefruit
|
||||
|
||||
If you aren't sure what boards exist, have a peek in the boards subdirectory of your port.
|
||||
If you have a fast computer with many cores, consider adding `-j` to your build flags, such as `-j17` on
|
||||
a 6-core 12-thread machine.
|
||||
|
||||
# Testing
|
||||
|
||||
If you are working on changes to the core language, you might find it useful to run the test suite.
|
||||
The test suite in the top level `tests` directory. It needs the unix port to run.
|
||||
|
||||
cd ports/unix
|
||||
make axtls
|
||||
make micropython
|
||||
|
||||
Then you can run the test suite:
|
||||
|
||||
cd ../../tests
|
||||
./run-tests
|
||||
|
||||
A successful run will say something like
|
||||
|
||||
676 tests performed (19129 individual testcases)
|
||||
676 tests passed
|
||||
30 tests skipped: buffered_writer builtin_help builtin_range_binop class_delattr_setattr cmd_parsetree extra_coverage framebuf1 framebuf16 framebuf2 framebuf4 framebuf8 framebuf_subclass mpy_invalid namedtuple_asdict non_compliant resource_stream schedule sys_getsizeof urandom_extra ure_groups ure_span ure_sub ure_sub_unmatched vfs_basic vfs_fat_fileio1 vfs_fat_fileio2 vfs_fat_more vfs_fat_oldproto vfs_fat_ramdisk vfs_userfs
|
||||
|
||||
# Debugging
|
||||
|
||||
The easiest way to debug CircuitPython on hardware is with a JLink device, JLinkGDBServer, and an appropriate GDB.
|
||||
Instructions can be found at https://learn.adafruit.com/debugging-the-samd21-with-gdb
|
||||
|
||||
If using JLink, you'll need both the `JLinkGDBServer` and `arm-none-eabi-gdb` running.
|
||||
|
||||
Example:
|
||||
|
||||
JLinkGDBServer -if SWD -device ATSAMD51J19
|
||||
arm-none-eabi-gdb build-metro_m4_express/firmware.elf -iex "target extended-remote :2331"
|
||||
|
||||
If your port/build includes `arm-none-eabi-gdb-py`, consider using it instead, as it can be used for better register
|
||||
debugging with https://github.com/bnahill/PyCortexMDebug
|
|
@ -14,7 +14,15 @@ If you have an employment contract with your employer please make sure that they
|
|||
don't automatically own your work product. Make sure to get any necessary approvals
|
||||
before contributing. Another term for this contribution off-hours is moonlighting.
|
||||
|
||||
## Getting started
|
||||
## Ways to contribute
|
||||
As CircuitPython grows, there are more and more ways to contribute. Here are some ideas:
|
||||
|
||||
* Build a project with CircuitPython and share how to do it online.
|
||||
* Test the latest libraries and CircuitPython versions with your projects and file issues for any bugs you find.
|
||||
* Contribute Python code to CircuitPython libraries that support new devices or features of an existing device.
|
||||
* Contribute C code to CircuitPython which fixes an open issue or adds a new feature.
|
||||
|
||||
## Getting started with C
|
||||
CircuitPython developer Dan Halbert (@dhalbert) has written up build instructions using native build
|
||||
tools [here](https://learn.adafruit.com/building-circuitpython).
|
||||
|
||||
|
|
24
Makefile
24
Makefile
|
@ -1,4 +1,4 @@
|
|||
# Makefile for Sphinx documentation
|
||||
# Top-level Makefile for documentation builds and miscellaneous tasks.
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
|
@ -17,6 +17,13 @@ CONFDIR = .
|
|||
FORCE = -E
|
||||
VERBOSE = -v
|
||||
|
||||
# path to generated type stubs
|
||||
STUBDIR = circuitpython-stubs
|
||||
# Run "make VALIDATE= stubs" to avoid validating generated stub files
|
||||
VALIDATE = -v
|
||||
# path to pypi source distributions
|
||||
DISTDIR = dist
|
||||
|
||||
# Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the
|
||||
# full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the
|
||||
# executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
|
||||
|
@ -29,9 +36,9 @@ ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(BASEOPTS)
|
|||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(BASEOPTS)
|
||||
|
||||
TRANSLATE_SOURCES = extmod lib main.c ports/atmel-samd ports/nrf py shared-bindings shared-module supervisor
|
||||
TRANSLATE_SOURCES = extmod lib main.c ports/atmel-samd ports/cxd56 ports/mimxrt10xx ports/nrf ports/stm32f4 py shared-bindings shared-module supervisor
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext stubs
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
|
@ -60,6 +67,7 @@ help:
|
|||
|
||||
clean:
|
||||
rm -rf $(BUILDDIR)/*
|
||||
rm -rf $(STUBDIR) $(DISTDIR) *.egg-info
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
|
@ -196,10 +204,18 @@ pseudoxml:
|
|||
all-source:
|
||||
|
||||
locale/circuitpython.pot: all-source
|
||||
find $(TRANSLATE_SOURCES) -iname "*.c" | xargs xgettext -L C -s --add-location=file --keyword=translate -o circuitpython.pot -p locale
|
||||
find $(TRANSLATE_SOURCES) -iname "*.c" -print | (LC_ALL=C sort) | xgettext -f- -L C -s --add-location=file --keyword=translate -o circuitpython.pot -p locale
|
||||
|
||||
translate: locale/circuitpython.pot
|
||||
for po in $(shell ls locale/*.po); do msgmerge -U $$po -s --no-fuzzy-matching --add-location=file locale/circuitpython.pot; done
|
||||
|
||||
check-translate: locale/circuitpython.pot $(wildcard locale/*.po)
|
||||
$(PYTHON) tools/check_translations.py $^
|
||||
|
||||
stubs:
|
||||
rst2pyi $(VALIDATE) shared-bindings/ $(STUBDIR)
|
||||
python setup.py sdist
|
||||
|
||||
update-frozen-libraries:
|
||||
@echo "Updating all frozen libraries to latest tagged version."
|
||||
cd frozen; for library in *; do cd $$library; ../../tools/git-checkout-latest-tag.sh; cd ..; done
|
||||
|
|
217
README.rst
217
README.rst
|
@ -1,94 +1,46 @@
|
|||
Adafruit CircuitPython
|
||||
======================
|
||||
CircuitPython
|
||||
=============
|
||||
|
||||
.. image:: https://github.com/adafruit/circuitpython/blob/master/logo/CircuitPython_Repo_header_logo.png
|
||||
.. image:: https://s3.amazonaws.com/adafruit-circuit-python/CircuitPython_Repo_header_logo.png
|
||||
|
||||
|Build Status| |Doc Status| |License| |Discord|
|
||||
|
||||
`Status <#status>`__ \| `Supported Boards <#supported-boards>`__
|
||||
\| `Download <#download>`__ \|
|
||||
`Documentation <#documentation>`__ \|
|
||||
`Contributing <#contributing>`__ \| `Differences from
|
||||
Micropython <#differences-from-micropython>`__ \| `Project
|
||||
Structure <#project-structure>`__
|
||||
`circuitpython.org <https://circuitpython.org>`__ \| `Get CircuitPython <#get-circuitpython>`__ \|
|
||||
`Documentation <#documentation>`__ \| `Contributing <#contributing>`__ \|
|
||||
`Branding <#branding>`__ \| `Differences from Micropython <#differences-from-micropython>`__ \|
|
||||
`Project Structure <#project-structure>`__
|
||||
|
||||
**CircuitPython** is an *education friendly* open source derivative of
|
||||
`MicroPython <https://micropython.org>`_. CircuitPython supports use
|
||||
on educational development boards designed and sold by
|
||||
`Adafruit <https://adafruit.com>`_. Adafruit CircuitPython features
|
||||
unified Python core APIs and a growing list of Adafruit libraries and
|
||||
drivers of that work with it.
|
||||
**CircuitPython** is a *beginner friendly*, open source version of Python for tiny, inexpensive
|
||||
computers called microcontrollers. Microcontrollers are the brains of many electronics including a
|
||||
wide variety of development boards used to build hobby projects and prototypes. CircuitPython in
|
||||
electronics is one of the best ways to learn to code because it connects code to reality. Simply
|
||||
install CircuitPython on a supported board via drag and drop and then edit a ``code.py`` file on
|
||||
the CIRCUITPY drive. The code will automatically reload. No software installs are needed besides a
|
||||
text editor (we recommend `Mu <https://codewith.mu/>`_ for beginners.)
|
||||
|
||||
Status
|
||||
------
|
||||
CircuitPython features unified Python core APIs and a growing list of 150+ device libraries and
|
||||
drivers that work with it. These libraries also work on single board computers with regular
|
||||
Python via the `Adafruit Blinka Library <https://github.com/adafruit/Adafruit_Blinka>`_.
|
||||
|
||||
This project is stable. Most APIs should be stable going forward. Those
|
||||
that change will change on major version numbers such as 2.0.0 and
|
||||
3.0.0.
|
||||
CircuitPython is based on `MicroPython <https://micropython.org>`_. See
|
||||
`below <#differences-from-micropython>`_ for differences. CircuitPython development is sponsored by
|
||||
`Adafruit <https://adafruit.com>`_ and is available on their educational development boards. Please
|
||||
support both MicroPython and Adafruit.
|
||||
|
||||
Supported Boards
|
||||
----------------
|
||||
Get CircuitPython
|
||||
------------------
|
||||
|
||||
Designed for CircuitPython
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**M0 Boards**
|
||||
|
||||
- `Adafruit CircuitPlayground Express <https://www.adafruit.com/product/3333>`__ (`CircuitPython Guide <https://learn.adafruit.com/adafruit-circuit-playground-express/circuitpython-quickstart>`__)
|
||||
- `Adafruit Feather M0 Express <https://www.adafruit.com/product/3403>`__ (`CircuitPython Guide <https://learn.adafruit.com/adafruit-feather-m0-express-designed-for-circuit-python-circuitpython/kattni-circuitpython>`__)
|
||||
- `Adafruit Gemma M0 <https://www.adafruit.com/product/3501>`__ (`CircuitPython Guide <https://learn.adafruit.com/adafruit-gemma-m0/circuitpython>`__)
|
||||
- `Adafruit Hallowing M0 Express <https://www.adafruit.com/product/3900>`__ (`CircuitPython Guide <https://learn.adafruit.com/adafruit-hallowing/circuitpython>`__)
|
||||
- `Adafruit ItsyBitsy M0 Express <https://www.adafruit.com/product/3727>`_ (`CircuitPython Guide <https://learn.adafruit.com/introducing-itsy-bitsy-m0/circuitpython>`__)
|
||||
- `Adafruit Metro M0 Express <https://www.adafruit.com/product/3505>`_ (`CircuitPython Guide <https://learn.adafruit.com/adafruit-metro-m0-express-designed-for-circuitpython/circuitpython>`__)
|
||||
- `Adafruit Trinket M0 <https://www.adafruit.com/product/3500>`__ (`CircuitPython Guide <https://learn.adafruit.com/adafruit-trinket-m0-circuitpython-arduino/circuitpython>`__)
|
||||
|
||||
**M4 Boards**
|
||||
|
||||
- `Adafruit Feather M4 Express <https://www.adafruit.com/product/3857>`__ (`CircuitPython Guide <https://learn.adafruit.com/adafruit-feather-m4-express-atsamd51/circuitpython>`__)
|
||||
- `Adafruit ItsyBitsy M4 Express <https://www.adafruit.com/product/3800>`__ (`CircuitPython Guide <https://learn.adafruit.com/introducing-adafruit-itsybitsy-m4/circuitpython>`__)
|
||||
- `Adafruit Metro M4 Express <https://www.adafruit.com/product/3382>`__ (`CircuitPython Guide <https://learn.adafruit.com/adafruit-metro-m4-express-featuring-atsamd51/circuitpython>`__)
|
||||
|
||||
Other
|
||||
~~~~~
|
||||
|
||||
- `Adafruit Feather HUZZAH <https://www.adafruit.com/products/2821>`__
|
||||
- `Adafruit Feather M0
|
||||
Basic <https://www.adafruit.com/products/2772>`__
|
||||
- `Adafruit Feather M0 Bluefruit
|
||||
LE <https://www.adafruit.com/products/2995>`__ (uses M0 Basic
|
||||
binaries)
|
||||
- `Adafruit Feather M0
|
||||
Adalogger <https://www.adafruit.com/product/2796>`__ (MicroSD card
|
||||
supported using the `Adafruit CircuitPython SD
|
||||
library <https://github.com/adafruit/Adafruit_CircuitPython_SD>`__)
|
||||
- `Arduino Zero <https://www.arduino.cc/en/Main/ArduinoBoardZero>`__
|
||||
- `Arduino MKR Zero <https://store.arduino.cc/arduino-mkrzero>`__ (MicroSD card
|
||||
supported using the `Adafruit CircuitPython SD
|
||||
library <https://github.com/adafruit/Adafruit_CircuitPython_SD>`__)
|
||||
|
||||
"Third-party" or "non-Adafruit" boards
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- `Electronic Cats Meow Meow <https://electroniccats.com/gomeow/>`__
|
||||
- `Electronic Cats CatWAN USB Stick <https://electroniccats.com/producto/catwan_usb_stick/>`__
|
||||
|
||||
Download
|
||||
--------
|
||||
|
||||
Official binaries are available through the `latest GitHub
|
||||
releases <https://github.com/adafruit/circuitpython/releases>`__.
|
||||
Continuous (one per commit) builds are available
|
||||
`here <https://adafruit-circuit-python.s3.amazonaws.com/index.html?prefix=bin>`__
|
||||
and includes experimental hardware support.
|
||||
Official binaries for all supported boards are available through
|
||||
`circuitpython.org/downloads <https://circuitpython.org/downloads>`_. The site includes stable, unstable and
|
||||
continuous builds. Full release notes and assets are available through
|
||||
`GitHub releases <https://github.com/adafruit/circuitpython/releases>`_ as well.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
Guides and videos are available through the `Adafruit Learning
|
||||
System <https://learn.adafruit.com/>`__ under the `CircuitPython
|
||||
category <https://learn.adafruit.com/category/circuitpython>`__ and
|
||||
`MicroPython
|
||||
category <https://learn.adafruit.com/category/micropython>`__. An API
|
||||
category <https://learn.adafruit.com/category/circuitpython>`__. An API
|
||||
reference is also available on `Read the Docs
|
||||
<http://circuitpython.readthedocs.io/en/latest/?>`__. A collection of awesome
|
||||
resources can be found at `Awesome CircuitPython <https://github.com/adafruit/awesome-circuitpython>`__.
|
||||
|
@ -111,7 +63,29 @@ Contributors who follow the `Code of
|
|||
Conduct <https://github.com/adafruit/circuitpython/blob/master/CODE_OF_CONDUCT.md>`__
|
||||
are welcome to submit pull requests and they will be promptly reviewed
|
||||
by project admins. Please join the
|
||||
`Discord <https://discord.gg/nBQh6qu>`__ too.
|
||||
`Discord <https://adafru.it/discord>`__ too.
|
||||
|
||||
Branding
|
||||
------------
|
||||
|
||||
While we are happy to see CircuitPython forked and modified, we'd appreciate it if forked releases
|
||||
not use the name "CircuitPython" or the Blinka logo. "CircuitPython" means something special to
|
||||
us and those who learn about it. As a result, we'd like to make sure products referring to it meet a
|
||||
common set of requirements.
|
||||
|
||||
If you'd like to use the term "CircuitPython" and Blinka for your product here is what we ask:
|
||||
|
||||
* Your product is supported by the primary
|
||||
`"adafruit/circuitpython" <https://github.com/adafruit/circuitpython>`_ repo. This way we can
|
||||
update any custom code as we update the CircuitPython internals.
|
||||
* Your product is listed on `circuitpython.org <https://circuitpython.org>`__ (source
|
||||
`here <https://github.com/adafruit/circuitpython-org/>`_). This is to ensure that a user of your
|
||||
product can always download the latest version of CircuitPython from the standard place.
|
||||
* Your product has a user accessible USB plug which appears as a CIRCUITPY drive when plugged in.
|
||||
|
||||
If you choose not to meet these requirements, then we ask you call your version of CircuitPython
|
||||
something else (for example, SuperDuperPython) and not use the Blinka logo. You can say it is
|
||||
"CircuitPython-compatible" if most CircuitPython drivers will work with it.
|
||||
|
||||
--------------
|
||||
|
||||
|
@ -120,15 +94,13 @@ Differences from `MicroPython <https://github.com/micropython/micropython>`__
|
|||
|
||||
CircuitPython:
|
||||
|
||||
- includes a ports for MicroChip SAMD21 (Commonly known as M0 in Adafruit
|
||||
product names) and SAMD51 (M4).
|
||||
- supports only SAMD21, SAMD51, and ESP8266 ports. An nRF port is under
|
||||
development.
|
||||
- tracks MicroPython's releases (not master).
|
||||
- Longints (arbitrary-length integers) are enabled for most M0
|
||||
Express boards (those boards with SPI flash chips external
|
||||
to the microcontroller), and for all M4 builds.
|
||||
Longints are disabled on other boards due to lack of flash space.
|
||||
- Supports native USB on all boards, allowing file editing without special tools.
|
||||
- Supports only SAMD21, SAMD51, nRF52840, CXD56, STM32F4 and i.MX RT ports.
|
||||
- Tracks MicroPython's releases (not master).
|
||||
- Floats (aka decimals) are enabled for all builds.
|
||||
- Error messages are translated into 10+ languages.
|
||||
- Does not support concurrency within Python (including interrupts and threading). Some concurrency
|
||||
is achieved with native modules for tasks that require it such as audio file playback.
|
||||
|
||||
Behavior
|
||||
~~~~~~~~
|
||||
|
@ -142,8 +114,8 @@ Behavior
|
|||
output is written to ``boot_out.txt``.
|
||||
- ``code.py`` (or ``main.py``) is run after every reload until it
|
||||
finishes or is interrupted. After it is done running, the vm and
|
||||
hardware is reinitialized. **This means you cannot read state from
|
||||
``code.py`` in the REPL anymore.** CircuitPython's goal for this
|
||||
hardware is reinitialized. **This means you cannot read state from**
|
||||
``code.py`` **in the REPL anymore.** CircuitPython's goal for this
|
||||
change includes reduce confusion about pins and memory being used.
|
||||
- After ``code.py`` the REPL can be entered by pressing any key. It no
|
||||
longer shares state with ``code.py`` so it is a fresh vm.
|
||||
|
@ -153,12 +125,23 @@ Behavior
|
|||
causes nasty crashes by making it available through mass storage
|
||||
after the crash. A reset (the button) is needed after its fixed to
|
||||
get back into normal mode.
|
||||
- RGB status LED indicating CircuitPython state, and errors through a sequence of colored flashes.
|
||||
- Re-runs ``code.py`` or other main file after file system writes over USB mass storage. (Disable with
|
||||
``samd.disable_autoreload()``)
|
||||
- Entering the REPL after the main code is finished requires a key press which enters the REPL and
|
||||
disables autoreload.
|
||||
- Main is one of these: ``code.txt``, ``code.py``, ``main.py``,
|
||||
``main.txt``
|
||||
- Boot is one of these: ``settings.txt``, ``settings.py``, ``boot.py``,
|
||||
``boot.txt``
|
||||
|
||||
API
|
||||
~~~
|
||||
|
||||
- Unified hardware APIs: `audioio <https://circuitpython.readthedocs.io/en/latest/shared-bindings/audioio/__init__.html>`_, `analogio <https://circuitpython.readthedocs.io/en/latest/shared-bindings/analogio/__init__.html>`_, `bleio <https://circuitpython.readthedocs.io/en/latest/shared-bindings/bleio/__init__.html>`_, `busio <https://circuitpython.readthedocs.io/en/latest/shared-bindings/busio/__init__.html>`_, `digitalio <https://circuitpython.readthedocs.io/en/latest/shared-bindings/digitalio/__init__.html>`_, `pulseio <https://circuitpython.readthedocs.io/en/latest/shared-bindings/pulseio/__init__.html>`_, `touchio <https://circuitpython.readthedocs.io/en/latest/shared-bindings/touchio/__init__.html>`_, `microcontroller <https://circuitpython.readthedocs.io/en/latest/shared-bindings/microcontroller/__init__.html>`_, `board <https://circuitpython.readthedocs.io/en/latest/shared-bindings/board/__init__.html>`_, `bitbangio <https://circuitpython.readthedocs.io/en/latest/shared-bindings/bitbangio/__init__.html>`_
|
||||
- No ``machine`` API on Atmel SAMD21 port.
|
||||
- Unified hardware APIs. Documented
|
||||
`on ReadTheDocs <https://circuitpython.readthedocs.io/en/latest/shared-bindings/index.html>`_.
|
||||
- API docs are rST within the C files in ``shared-bindings``.
|
||||
- No ``machine`` API.
|
||||
|
||||
Modules
|
||||
~~~~~~~
|
||||
|
@ -178,18 +161,6 @@ Modules
|
|||
- tick count is available as
|
||||
`time.monotonic() <https://circuitpython.readthedocs.io/en/latest/shared-bindings/time/__init__.html#time.monotonic>`__
|
||||
|
||||
atmel-samd21 features
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- RGB status LED
|
||||
- Auto-reload after file write over mass storage. (Disable with
|
||||
``samd.disable_autoreload()``)
|
||||
- Wait state after boot and main run, before REPL.
|
||||
- Main is one of these: ``code.txt``, ``code.py``, ``main.py``,
|
||||
``main.txt``
|
||||
- Boot is one of these: ``settings.txt``, ``settings.py``, ``boot.py``,
|
||||
``boot.txt``
|
||||
|
||||
--------------
|
||||
|
||||
Project Structure
|
||||
|
@ -231,40 +202,14 @@ Ports
|
|||
Ports include the code unique to a microcontroller line and also
|
||||
variations based on the board.
|
||||
|
||||
- ``atmel-samd`` Support for SAMD21 based boards such as `Arduino
|
||||
Zero <https://www.arduino.cc/en/Main/ArduinoBoardZero>`__, `Adafruit
|
||||
Feather M0 Basic <https://www.adafruit.com/products/2772>`__, and
|
||||
`Adafruit Feather M0 Bluefruit
|
||||
LE <https://www.adafruit.com/products/2995>`__.
|
||||
- ``bare-arm`` A bare minimum version of MicroPython for ARM MCUs.
|
||||
- ``cc3200`` Support for boards based
|
||||
`CC3200 <http://www.ti.com/product/CC3200>`__ from TI such as the
|
||||
`WiPy 1.0 <https://www.pycom.io/solutions/py-boards/wipy1/>`__.
|
||||
- ``esp8266`` Support for boards based on ESP8266 WiFi modules such as
|
||||
the `Adafruit Feather
|
||||
HUZZAH <https://www.adafruit.com/products/2821>`__.
|
||||
- ``minimal`` A minimal MicroPython port. Start with this if you want
|
||||
to port MicroPython to another microcontroller.
|
||||
- ``pic16bit`` Support for 16-bit PIC microcontrollers.
|
||||
- ``qemu-arm`` Support for ARM emulation through
|
||||
`QEMU <https://qemu.org>`__.
|
||||
- ``stmhal`` Support for boards based on STM32 microcontrollers
|
||||
including the MicroPython flagship
|
||||
`PyBoard <https://store.micropython.org/store/#/products/PYBv1_1>`__.
|
||||
- ``teensy`` Support for the Teensy line of boards such as the `Teensy
|
||||
3.1 <https://www.pjrc.com/teensy/teensy31.html>`__.
|
||||
- ``unix`` Support for UNIX.
|
||||
- ``windows`` Support for
|
||||
`Windows <https://www.microsoft.com/en-us/windows/>`__.
|
||||
- ``zephyr`` Support for `Zephyr <https://www.zephyrproject.org/>`__, a
|
||||
real-time operating system by the Linux Foundation.
|
||||
- ``atmel-samd`` Support for SAMD21 and SAMD51 based boards.
|
||||
- ``nrf`` Support for the nRF52840 based boards.
|
||||
- ``unix`` Support for UNIX. Only used for automated testing.
|
||||
|
||||
CircuitPython only maintains the ``atmel-samd`` and ``esp8266`` ports.
|
||||
The rest are here to maintain compatibility with the
|
||||
`MicroPython <https://github.com/micropython/micropython>`__ parent
|
||||
project.
|
||||
The remaining port directories not listed above are in the repo to maintain compatibility with the
|
||||
`MicroPython <https://github.com/micropython/micropython>`__ parent project.
|
||||
|
||||
`⬆ back to top <#adafruit-circuitpython>`__
|
||||
`back to top <#circuitpython>`__
|
||||
|
||||
.. |Build Status| image:: https://travis-ci.com/adafruit/circuitpython.svg?branch=master
|
||||
:target: https://travis-ci.org/adafruit/circuitpython
|
||||
|
@ -272,5 +217,5 @@ project.
|
|||
:target: http://circuitpython.readthedocs.io/
|
||||
.. |Discord| image:: https://img.shields.io/discord/327254708534116352.svg
|
||||
:target: https://adafru.it/discord
|
||||
.. |License| image:: https://github.com/adafruit/circuitpython/blob/master/logo/license-MIT-brightgreen.svg
|
||||
:target: https://opensource.org/licenses/MIT
|
||||
.. |License| image:: https://img.shields.io/badge/License-MIT-brightgreen.svg
|
||||
:target: https://choosealicense.com/licenses/mit/
|
||||
|
|
32
conf.py
32
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.
|
||||
|
@ -37,9 +50,12 @@ needs_sphinx = '1.3'
|
|||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.doctest',
|
||||
'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.
|
||||
|
@ -48,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'
|
||||
|
@ -83,6 +98,7 @@ version = release = '0.0.0'
|
|||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ["**/build*",
|
||||
".git",
|
||||
".venv",
|
||||
".direnv",
|
||||
"docs/README.md",
|
||||
|
@ -109,17 +125,24 @@ exclude_patterns = ["**/build*",
|
|||
"ports/cc3200",
|
||||
"ports/cc3200/FreeRTOS",
|
||||
"ports/cc3200/hal",
|
||||
"ports/cxd56/mkspk",
|
||||
"ports/cxd56/spresense-exported-sdk",
|
||||
"ports/esp32",
|
||||
"ports/esp8266/boards",
|
||||
"ports/esp8266/common-hal",
|
||||
"ports/esp8266/modules",
|
||||
"ports/minimal",
|
||||
"ports/mimxrt10xx/peripherals",
|
||||
"ports/mimxrt10xx/sdk",
|
||||
"ports/nrf/device",
|
||||
"ports/nrf/bluetooth",
|
||||
"ports/nrf/modules",
|
||||
"ports/nrf/nrfx",
|
||||
"ports/nrf/peripherals",
|
||||
"ports/nrf/usb",
|
||||
"ports/stm32f4/stm32f4",
|
||||
"ports/stm32f4/peripherals",
|
||||
"ports/stm32f4/ref",
|
||||
"ports/pic16bit",
|
||||
"ports/qemu-arm",
|
||||
"ports/stm32",
|
||||
|
@ -349,3 +372,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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -60,6 +60,7 @@ For example, a user can then use ``deinit()```::
|
|||
|
||||
import digitalio
|
||||
import board
|
||||
import time
|
||||
|
||||
led = digitalio.DigitalInOut(board.D13)
|
||||
led.direction = digitalio.Direction.OUTPUT
|
||||
|
@ -79,6 +80,7 @@ Alternatively, using a ``with`` statement ensures that the hardware is deinitial
|
|||
|
||||
import digitalio
|
||||
import board
|
||||
import time
|
||||
|
||||
with digitalio.DigitalInOut(board.D13) as led:
|
||||
led.direction = digitalio.Direction.OUTPUT
|
||||
|
|
|
@ -43,6 +43,7 @@ Full Table of Contents
|
|||
|
||||
../README
|
||||
../CONTRIBUTING
|
||||
../BUILDING
|
||||
../CODE_OF_CONDUCT
|
||||
../license.rst
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ Exceptions
|
|||
|
||||
.. exception:: OSError
|
||||
|
||||
|see_cpython| `OSError`. CircuitPython doesn't implement the ``errno``
|
||||
|see_cpython| :py:class:`cpython:OSError`. CircuitPython doesn't implement the ``errno``
|
||||
attribute, instead use the standard way to access exception arguments:
|
||||
``exc.args[0]``.
|
||||
|
||||
|
@ -198,11 +198,11 @@ Exceptions
|
|||
|
||||
.. exception:: SystemExit
|
||||
|
||||
|see_cpython| :py:class:`python:SystemExit`.
|
||||
|see_cpython| :py:class:`cpython:SystemExit`.
|
||||
|
||||
.. exception:: TypeError
|
||||
|
||||
|see_cpython| :py:class:`python:TypeError`.
|
||||
|see_cpython| :py:class:`cpython:TypeError`.
|
||||
|
||||
.. exception:: ValueError
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
sphinx==1.8.5
|
||||
recommonmark==0.5.0
|
||||
sphinxcontrib-svg2pdfconverter==0.1.0
|
|
@ -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)
|
|
@ -0,0 +1,287 @@
|
|||
# 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", "mimxrt10xx"]
|
||||
|
||||
|
||||
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 = r"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:
|
||||
board_is_excluded = find_module.group(1) == "0"
|
||||
|
||||
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
|
|
@ -8,5 +8,7 @@ and ESP8266.
|
|||
:maxdepth: 2
|
||||
|
||||
../ports/atmel-samd/README
|
||||
../ports/esp8266/README
|
||||
../ports/mimxrt10xx/README
|
||||
../ports/nrf/README
|
||||
../ports/stm32f4/README
|
||||
../ports/cxd56/README
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "tick.h"
|
||||
#include "supervisor/shared/tick.h"
|
||||
|
||||
//#include "Ethernet/socket.h"
|
||||
//#include "Internet/DNS/dns.h"
|
||||
|
@ -125,7 +125,7 @@ uint16_t DNS_MSGID; // DNS message ID
|
|||
|
||||
|
||||
uint32_t HAL_GetTick(void) {
|
||||
return ticks_ms;
|
||||
return supervisor_ticks_ms32();
|
||||
}
|
||||
|
||||
uint32_t hal_sys_tick;
|
||||
|
|
|
@ -318,7 +318,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_init_obj, 1, machine_i2c_obj_init);
|
|||
|
||||
STATIC mp_obj_t machine_i2c_scan(mp_obj_t self_in) {
|
||||
mp_obj_base_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
|
||||
mp_obj_t list = mp_obj_new_list(0, NULL);
|
||||
// 7-bit addresses 0b0000xxx and 0b1111xxx are reserved
|
||||
for (int addr = 0x08; addr < 0x78; ++addr) {
|
||||
|
@ -333,7 +333,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_scan_obj, machine_i2c_scan);
|
|||
|
||||
STATIC mp_obj_t machine_i2c_start(mp_obj_t self_in) {
|
||||
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(self_in);
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
|
||||
if (i2c_p->start == NULL) {
|
||||
mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported"));
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_start_obj, machine_i2c_start);
|
|||
|
||||
STATIC mp_obj_t machine_i2c_stop(mp_obj_t self_in) {
|
||||
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(self_in);
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
|
||||
if (i2c_p->stop == NULL) {
|
||||
mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported"));
|
||||
}
|
||||
|
@ -361,7 +361,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_stop_obj, machine_i2c_stop);
|
|||
|
||||
STATIC mp_obj_t machine_i2c_readinto(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(args[0]);
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
|
||||
if (i2c_p->read == NULL) {
|
||||
mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported"));
|
||||
}
|
||||
|
@ -385,7 +385,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readinto_obj, 2, 3, machine_i2c_
|
|||
|
||||
STATIC mp_obj_t machine_i2c_write(mp_obj_t self_in, mp_obj_t buf_in) {
|
||||
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(self_in);
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
|
||||
if (i2c_p->write == NULL) {
|
||||
mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported"));
|
||||
}
|
||||
|
@ -407,7 +407,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(machine_i2c_write_obj, machine_i2c_write);
|
|||
|
||||
STATIC mp_obj_t machine_i2c_readfrom(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(args[0]);
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
|
||||
mp_int_t addr = mp_obj_get_int(args[1]);
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, mp_obj_get_int(args[2]));
|
||||
|
@ -422,7 +422,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readfrom_obj, 3, 4, machine_i2c_
|
|||
|
||||
STATIC mp_obj_t machine_i2c_readfrom_into(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(args[0]);
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
|
||||
mp_int_t addr = mp_obj_get_int(args[1]);
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_WRITE);
|
||||
|
@ -437,7 +437,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readfrom_into_obj, 3, 4, machine
|
|||
|
||||
STATIC mp_obj_t machine_i2c_writeto(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(args[0]);
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
|
||||
mp_int_t addr = mp_obj_get_int(args[1]);
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ);
|
||||
|
@ -453,7 +453,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_writeto_obj, 3, 4, machin
|
|||
|
||||
STATIC int read_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t addrsize, uint8_t *buf, size_t len) {
|
||||
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(self_in);
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
|
||||
uint8_t memaddr_buf[4];
|
||||
size_t memaddr_len = 0;
|
||||
for (int16_t i = addrsize - 8; i >= 0; i -= 8) {
|
||||
|
@ -473,7 +473,7 @@ STATIC int read_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t a
|
|||
|
||||
STATIC int write_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t addrsize, const uint8_t *buf, size_t len) {
|
||||
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(self_in);
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
|
||||
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
|
||||
|
||||
// need some memory to create the buffer to send; try to use stack if possible
|
||||
uint8_t buf2_stack[MAX_MEMADDR_SIZE + BUF_STACK_SIZE];
|
||||
|
@ -621,6 +621,7 @@ int mp_machine_soft_i2c_write(mp_obj_base_t *self_in, const uint8_t *src, size_t
|
|||
}
|
||||
|
||||
STATIC const mp_machine_i2c_p_t mp_machine_soft_i2c_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_i2c)
|
||||
.start = (int(*)(mp_obj_base_t*))mp_hal_i2c_start,
|
||||
.stop = (int(*)(mp_obj_base_t*))mp_hal_i2c_stop,
|
||||
.read = mp_machine_soft_i2c_read,
|
||||
|
|
|
@ -27,10 +27,12 @@
|
|||
#define MICROPY_INCLUDED_EXTMOD_MACHINE_I2C_H
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/proto.h"
|
||||
|
||||
// I2C protocol
|
||||
// the first 4 methods can be NULL, meaning operation is not supported
|
||||
typedef struct _mp_machine_i2c_p_t {
|
||||
MP_PROTOCOL_HEAD
|
||||
int (*start)(mp_obj_base_t *obj);
|
||||
int (*stop)(mp_obj_base_t *obj);
|
||||
int (*read)(mp_obj_base_t *obj, uint8_t *dest, size_t len, bool nack);
|
||||
|
|
|
@ -74,6 +74,7 @@ mp_uint_t pinbase_ioctl(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *err
|
|||
}
|
||||
|
||||
STATIC const mp_pin_p_t pinbase_pin_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_pin)
|
||||
.ioctl = pinbase_ioctl,
|
||||
};
|
||||
|
||||
|
|
|
@ -47,12 +47,7 @@ STATIC mp_obj_t signal_make_new(const mp_obj_type_t *type, size_t n_args, const
|
|||
bool invert = false;
|
||||
|
||||
#if defined(MICROPY_PY_MACHINE_PIN_MAKE_NEW)
|
||||
mp_pin_p_t *pin_p = NULL;
|
||||
|
||||
if (MP_OBJ_IS_OBJ(pin)) {
|
||||
mp_obj_base_t *pin_base = (mp_obj_base_t*)MP_OBJ_TO_PTR(args[0]);
|
||||
pin_p = (mp_pin_p_t*)pin_base->type->protocol;
|
||||
}
|
||||
mp_pin_p_t *pin_p = (mp_pin_t*)mp_proto_get(QSTR_pin_protocol, pin);
|
||||
|
||||
if (pin_p == NULL) {
|
||||
// If first argument isn't a Pin-like object, we filter out "invert"
|
||||
|
@ -170,6 +165,7 @@ STATIC const mp_rom_map_elem_t signal_locals_dict_table[] = {
|
|||
STATIC MP_DEFINE_CONST_DICT(signal_locals_dict, signal_locals_dict_table);
|
||||
|
||||
STATIC const mp_pin_p_t signal_pin_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_pin)
|
||||
.ioctl = signal_ioctl,
|
||||
};
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ mp_obj_t mp_machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, const
|
|||
|
||||
STATIC mp_obj_t machine_spi_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
mp_obj_base_t *s = (mp_obj_base_t*)MP_OBJ_TO_PTR(args[0]);
|
||||
mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t*)s->type->protocol;
|
||||
mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t*)mp_proto_get(QSTR_protocol_spi, s);
|
||||
spi_p->init(s, n_args - 1, args + 1, kw_args);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_spi_init_obj, 1, machine_spi_init);
|
|||
|
||||
STATIC mp_obj_t machine_spi_deinit(mp_obj_t self) {
|
||||
mp_obj_base_t *s = (mp_obj_base_t*)MP_OBJ_TO_PTR(self);
|
||||
mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t*)s->type->protocol;
|
||||
mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t*)mp_proto_get(QSTR_protocol_spi, s);
|
||||
if (spi_p->deinit != NULL) {
|
||||
spi_p->deinit(s);
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_spi_deinit_obj, machine_spi_deinit);
|
|||
|
||||
STATIC void mp_machine_spi_transfer(mp_obj_t self, size_t len, const void *src, void *dest) {
|
||||
mp_obj_base_t *s = (mp_obj_base_t*)MP_OBJ_TO_PTR(self);
|
||||
mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t*)s->type->protocol;
|
||||
mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t*)mp_proto_get(QSTR_protocol_spi, s);
|
||||
spi_p->transfer(s, len, src, dest);
|
||||
}
|
||||
|
||||
|
@ -268,6 +268,7 @@ STATIC void mp_machine_soft_spi_transfer(mp_obj_base_t *self_in, size_t len, con
|
|||
}
|
||||
|
||||
const mp_machine_spi_p_t mp_machine_soft_spi_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_spi)
|
||||
.init = mp_machine_soft_spi_init,
|
||||
.deinit = NULL,
|
||||
.transfer = mp_machine_soft_spi_transfer,
|
||||
|
|
|
@ -27,11 +27,13 @@
|
|||
#define MICROPY_INCLUDED_EXTMOD_MACHINE_SPI_H
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/proto.h"
|
||||
#include "py/mphal.h"
|
||||
#include "drivers/bus/spi.h"
|
||||
|
||||
// SPI protocol
|
||||
typedef struct _mp_machine_spi_p_t {
|
||||
MP_PROTOCOL_HEAD
|
||||
void (*init)(mp_obj_base_t *obj, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
||||
void (*deinit)(mp_obj_base_t *obj); // can be NULL
|
||||
void (*transfer)(mp_obj_base_t *obj, size_t len, const uint8_t *src, uint8_t *dest);
|
||||
|
|
|
@ -247,7 +247,7 @@ STATIC mp_obj_t btree_iternext(mp_obj_t self_in) {
|
|||
}
|
||||
|
||||
STATIC mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_obj_btree_t *self = mp_instance_cast_to_native_base(self_in, &btree_type);
|
||||
if (value == MP_OBJ_NULL) {
|
||||
// delete
|
||||
DBT key;
|
||||
|
|
|
@ -28,10 +28,12 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/objtype.h"
|
||||
#include "py/proto.h"
|
||||
|
||||
#if MICROPY_PY_FRAMEBUF
|
||||
|
||||
#include "ports/stm32/font_petme128_8x8.h"
|
||||
#include "font_petme128_8x8.h"
|
||||
|
||||
typedef struct _mp_obj_framebuf_t {
|
||||
mp_obj_base_t base;
|
||||
|
@ -46,6 +48,7 @@ typedef uint32_t (*getpixel_t)(const mp_obj_framebuf_t*, int, int);
|
|||
typedef void (*fill_rect_t)(const mp_obj_framebuf_t *, int, int, int, int, uint32_t);
|
||||
|
||||
typedef struct _mp_framebuf_p_t {
|
||||
MP_PROTOCOL_HEAD
|
||||
setpixel_t setpixel;
|
||||
getpixel_t getpixel;
|
||||
fill_rect_t fill_rect;
|
||||
|
@ -227,13 +230,13 @@ STATIC void gs8_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int
|
|||
}
|
||||
|
||||
STATIC mp_framebuf_p_t formats[] = {
|
||||
[FRAMEBUF_MVLSB] = {mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect},
|
||||
[FRAMEBUF_RGB565] = {rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect},
|
||||
[FRAMEBUF_GS2_HMSB] = {gs2_hmsb_setpixel, gs2_hmsb_getpixel, gs2_hmsb_fill_rect},
|
||||
[FRAMEBUF_GS4_HMSB] = {gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect},
|
||||
[FRAMEBUF_GS8] = {gs8_setpixel, gs8_getpixel, gs8_fill_rect},
|
||||
[FRAMEBUF_MHLSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
|
||||
[FRAMEBUF_MHMSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
|
||||
[FRAMEBUF_MVLSB] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect},
|
||||
[FRAMEBUF_RGB565] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect},
|
||||
[FRAMEBUF_GS2_HMSB] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) gs2_hmsb_setpixel, gs2_hmsb_getpixel, gs2_hmsb_fill_rect},
|
||||
[FRAMEBUF_GS4_HMSB] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect},
|
||||
[FRAMEBUF_GS8] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) gs8_setpixel, gs8_getpixel, gs8_fill_rect},
|
||||
[FRAMEBUF_MHLSB] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
|
||||
[FRAMEBUF_MHMSB] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
|
||||
};
|
||||
|
||||
static inline void setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
|
||||
|
@ -302,9 +305,18 @@ STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, cons
|
|||
return MP_OBJ_FROM_PTR(o);
|
||||
}
|
||||
|
||||
STATIC const mp_obj_type_t mp_type_framebuf;
|
||||
|
||||
// Helper to ensure we have the native super class instead of a subclass.
|
||||
static mp_obj_framebuf_t* native_framebuf(mp_obj_t framebuf_obj) {
|
||||
mp_obj_t native_framebuf = mp_instance_cast_to_native_base(framebuf_obj, &mp_type_framebuf);
|
||||
mp_obj_assert_native_inited(native_framebuf);
|
||||
return MP_OBJ_TO_PTR(native_framebuf);
|
||||
}
|
||||
|
||||
STATIC mp_int_t framebuf_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
|
||||
(void)flags;
|
||||
mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_obj_framebuf_t *self = native_framebuf(self_in);
|
||||
bufinfo->buf = self->buf;
|
||||
bufinfo->len = self->stride * self->height * (self->format == FRAMEBUF_RGB565 ? 2 : 1);
|
||||
bufinfo->typecode = 'B'; // view framebuf as bytes
|
||||
|
@ -312,7 +324,7 @@ STATIC mp_int_t framebuf_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo,
|
|||
}
|
||||
|
||||
STATIC mp_obj_t framebuf_fill(mp_obj_t self_in, mp_obj_t col_in) {
|
||||
mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_obj_framebuf_t *self = native_framebuf(self_in);
|
||||
mp_int_t col = mp_obj_get_int(col_in);
|
||||
formats[self->format].fill_rect(self, 0, 0, self->width, self->height, col);
|
||||
return mp_const_none;
|
||||
|
@ -322,7 +334,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(framebuf_fill_obj, framebuf_fill);
|
|||
STATIC mp_obj_t framebuf_fill_rect(size_t n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
|
||||
mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
||||
mp_int_t x = mp_obj_get_int(args[1]);
|
||||
mp_int_t y = mp_obj_get_int(args[2]);
|
||||
mp_int_t width = mp_obj_get_int(args[3]);
|
||||
|
@ -336,7 +348,7 @@ STATIC mp_obj_t framebuf_fill_rect(size_t n_args, const mp_obj_t *args) {
|
|||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_fill_rect_obj, 6, 6, framebuf_fill_rect);
|
||||
|
||||
STATIC mp_obj_t framebuf_pixel(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
||||
mp_int_t x = mp_obj_get_int(args[1]);
|
||||
mp_int_t y = mp_obj_get_int(args[2]);
|
||||
if (0 <= x && x < self->width && 0 <= y && y < self->height) {
|
||||
|
@ -355,7 +367,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_pixel_obj, 3, 4, framebuf_pi
|
|||
STATIC mp_obj_t framebuf_hline(size_t n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
|
||||
mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
||||
mp_int_t x = mp_obj_get_int(args[1]);
|
||||
mp_int_t y = mp_obj_get_int(args[2]);
|
||||
mp_int_t w = mp_obj_get_int(args[3]);
|
||||
|
@ -370,7 +382,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_hline_obj, 5, 5, framebuf_hl
|
|||
STATIC mp_obj_t framebuf_vline(size_t n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
|
||||
mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
||||
mp_int_t x = mp_obj_get_int(args[1]);
|
||||
mp_int_t y = mp_obj_get_int(args[2]);
|
||||
mp_int_t h = mp_obj_get_int(args[3]);
|
||||
|
@ -385,7 +397,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_vline_obj, 5, 5, framebuf_vl
|
|||
STATIC mp_obj_t framebuf_rect(size_t n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
|
||||
mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
||||
mp_int_t x = mp_obj_get_int(args[1]);
|
||||
mp_int_t y = mp_obj_get_int(args[2]);
|
||||
mp_int_t w = mp_obj_get_int(args[3]);
|
||||
|
@ -404,7 +416,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_rect_obj, 6, 6, framebuf_rec
|
|||
STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
|
||||
mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
||||
mp_int_t x1 = mp_obj_get_int(args[1]);
|
||||
mp_int_t y1 = mp_obj_get_int(args[2]);
|
||||
mp_int_t x2 = mp_obj_get_int(args[3]);
|
||||
|
@ -468,8 +480,8 @@ STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args) {
|
|||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_line_obj, 6, 6, framebuf_line);
|
||||
|
||||
STATIC mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
mp_obj_framebuf_t *source = MP_OBJ_TO_PTR(args[1]);
|
||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
||||
mp_obj_framebuf_t *source = native_framebuf(args[1]);
|
||||
mp_int_t x = mp_obj_get_int(args[2]);
|
||||
mp_int_t y = mp_obj_get_int(args[3]);
|
||||
mp_int_t key = -1;
|
||||
|
@ -511,7 +523,7 @@ STATIC mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args) {
|
|||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_blit_obj, 4, 5, framebuf_blit);
|
||||
|
||||
STATIC mp_obj_t framebuf_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t ystep_in) {
|
||||
mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_obj_framebuf_t *self = native_framebuf(self_in);
|
||||
mp_int_t xstep = mp_obj_get_int(xstep_in);
|
||||
mp_int_t ystep = mp_obj_get_int(ystep_in);
|
||||
int sx, y, xend, yend, dx, dy;
|
||||
|
@ -544,7 +556,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(framebuf_scroll_obj, framebuf_scroll);
|
|||
|
||||
STATIC mp_obj_t framebuf_text(size_t n_args, const mp_obj_t *args) {
|
||||
// extract arguments
|
||||
mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
||||
const char *str = mp_obj_str_get_str(args[1]);
|
||||
mp_int_t x0 = mp_obj_get_int(args[2]);
|
||||
mp_int_t y0 = mp_obj_get_int(args[3]);
|
||||
|
|
|
@ -1261,6 +1261,7 @@ STATIC const mp_rom_map_elem_t lwip_socket_locals_dict_table[] = {
|
|||
STATIC MP_DEFINE_CONST_DICT(lwip_socket_locals_dict, lwip_socket_locals_dict_table);
|
||||
|
||||
STATIC const mp_stream_p_t lwip_socket_stream_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
|
||||
.read = lwip_socket_read,
|
||||
.write = lwip_socket_write,
|
||||
.ioctl = lwip_socket_ioctl,
|
||||
|
|
|
@ -518,8 +518,8 @@ STATIC void uctypes_struct_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
|||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) {
|
||||
mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_obj_t value) {
|
||||
mp_obj_uctypes_struct_t *self = mp_instance_cast_to_native_base(base_in, &uctypes_struct_type);
|
||||
|
||||
if (value == MP_OBJ_NULL) {
|
||||
// delete
|
||||
|
|
|
@ -221,6 +221,7 @@ STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
|
|||
STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table);
|
||||
|
||||
STATIC const mp_stream_p_t ussl_socket_stream_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
|
||||
.read = socket_read,
|
||||
.write = socket_write,
|
||||
.ioctl = socket_ioctl,
|
||||
|
|
|
@ -305,6 +305,7 @@ STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
|
|||
STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table);
|
||||
|
||||
STATIC const mp_stream_p_t ussl_socket_stream_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
|
||||
.read = socket_read,
|
||||
.write = socket_write,
|
||||
.ioctl = socket_ioctl,
|
||||
|
|
|
@ -134,6 +134,7 @@ STATIC const mp_rom_map_elem_t decompio_locals_dict_table[] = {
|
|||
STATIC MP_DEFINE_CONST_DICT(decompio_locals_dict, decompio_locals_dict_table);
|
||||
|
||||
STATIC const mp_stream_p_t decompio_stream_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
|
||||
.read = decompio_read,
|
||||
};
|
||||
|
||||
|
|
|
@ -331,6 +331,7 @@ STATIC const mp_rom_map_elem_t webrepl_locals_dict_table[] = {
|
|||
STATIC MP_DEFINE_CONST_DICT(webrepl_locals_dict, webrepl_locals_dict_table);
|
||||
|
||||
STATIC const mp_stream_p_t webrepl_stream_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
|
||||
.read = webrepl_read,
|
||||
.write = webrepl_write,
|
||||
.ioctl = webrepl_ioctl,
|
||||
|
|
|
@ -286,6 +286,7 @@ STATIC const mp_rom_map_elem_t websocket_locals_dict_table[] = {
|
|||
STATIC MP_DEFINE_CONST_DICT(websocket_locals_dict, websocket_locals_dict_table);
|
||||
|
||||
STATIC const mp_stream_p_t websocket_stream_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
|
||||
.read = websocket_read,
|
||||
.write = websocket_write,
|
||||
.ioctl = websocket_ioctl,
|
||||
|
|
|
@ -126,7 +126,7 @@ mp_import_stat_t mp_vfs_import_stat(const char *path) {
|
|||
}
|
||||
|
||||
// If the mounted object has the VFS protocol, call its import_stat helper
|
||||
const mp_vfs_proto_t *proto = mp_obj_get_type(vfs->obj)->protocol;
|
||||
const mp_vfs_proto_t *proto = (mp_vfs_proto_t*)mp_proto_get(MP_QSTR_protocol_vfs, vfs->obj);
|
||||
if (proto != NULL) {
|
||||
return proto->import_stat(MP_OBJ_TO_PTR(vfs->obj), path_out);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "py/lexer.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/proto.h"
|
||||
|
||||
// return values of mp_vfs_lookup_path
|
||||
// ROOT is 0 so that the default current directory is the root directory
|
||||
|
@ -47,6 +48,7 @@
|
|||
|
||||
// At the moment the VFS protocol just has import_stat, but could be extended to other methods
|
||||
typedef struct _mp_vfs_proto_t {
|
||||
MP_PROTOCOL_HEAD
|
||||
mp_import_stat_t (*import_stat)(void *self, const char *path);
|
||||
} mp_vfs_proto_t;
|
||||
|
||||
|
|
|
@ -488,6 +488,7 @@ STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
|
|||
STATIC MP_DEFINE_CONST_DICT(fat_vfs_locals_dict, fat_vfs_locals_dict_table);
|
||||
|
||||
STATIC const mp_vfs_proto_t fat_vfs_proto = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_vfs)
|
||||
.import_stat = fat_vfs_import_stat,
|
||||
};
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#if MICROPY_VFS && MICROPY_VFS_FAT
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
|
@ -199,7 +200,7 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar
|
|||
FRESULT res = f_open(&vfs->fatfs, &o->fp, fname, mode);
|
||||
if (res != FR_OK) {
|
||||
m_del_obj(pyb_file_obj_t, o);
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
mp_raise_OSError_errno_str(fresult_to_errno_table[res], args[0].u_obj);
|
||||
}
|
||||
// If we're reading, turn on fast seek.
|
||||
if (mode == FA_READ) {
|
||||
|
@ -254,6 +255,7 @@ STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict, rawfile_locals_dict_table);
|
|||
|
||||
#if MICROPY_PY_IO_FILEIO
|
||||
STATIC const mp_stream_p_t fileio_stream_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
|
||||
.read = file_obj_read,
|
||||
.write = file_obj_write,
|
||||
.ioctl = file_obj_ioctl,
|
||||
|
@ -272,6 +274,7 @@ const mp_obj_type_t mp_type_vfs_fat_fileio = {
|
|||
#endif
|
||||
|
||||
STATIC const mp_stream_p_t textio_stream_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
|
||||
.read = file_obj_read,
|
||||
.write = file_obj_write,
|
||||
.ioctl = file_obj_ioctl,
|
||||
|
|
|
@ -350,6 +350,7 @@ STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
|
|||
STATIC MP_DEFINE_CONST_DICT(vfs_posix_locals_dict, vfs_posix_locals_dict_table);
|
||||
|
||||
STATIC const mp_vfs_proto_t vfs_posix_proto = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_vfs)
|
||||
.import_stat = mp_vfs_posix_import_stat,
|
||||
};
|
||||
|
||||
|
|
|
@ -220,6 +220,7 @@ STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict, rawfile_locals_dict_table);
|
|||
|
||||
#if MICROPY_PY_IO_FILEIO
|
||||
STATIC const mp_stream_p_t fileio_stream_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
|
||||
.read = vfs_posix_file_read,
|
||||
.write = vfs_posix_file_write,
|
||||
.ioctl = vfs_posix_file_ioctl,
|
||||
|
@ -238,6 +239,7 @@ const mp_obj_type_t mp_type_vfs_posix_fileio = {
|
|||
#endif
|
||||
|
||||
STATIC const mp_stream_p_t textio_stream_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
|
||||
.read = vfs_posix_file_read,
|
||||
.write = vfs_posix_file_write,
|
||||
.ioctl = vfs_posix_file_ioctl,
|
||||
|
|
|
@ -25,15 +25,16 @@
|
|||
*/
|
||||
|
||||
#include "extmod/virtpin.h"
|
||||
#include "py/proto.h"
|
||||
|
||||
int mp_virtual_pin_read(mp_obj_t pin) {
|
||||
mp_obj_base_t* s = (mp_obj_base_t*)MP_OBJ_TO_PTR(pin);
|
||||
mp_pin_p_t *pin_p = (mp_pin_p_t*)s->type->protocol;
|
||||
const mp_pin_p_t *pin_p = mp_proto_get(MP_QSTR_protocol_pin, s);
|
||||
return pin_p->ioctl(pin, MP_PIN_READ, 0, NULL);
|
||||
}
|
||||
|
||||
void mp_virtual_pin_write(mp_obj_t pin, int value) {
|
||||
mp_obj_base_t* s = (mp_obj_base_t*)MP_OBJ_TO_PTR(pin);
|
||||
mp_pin_p_t *pin_p = (mp_pin_p_t*)s->type->protocol;
|
||||
const mp_pin_p_t *pin_p = mp_proto_get(MP_QSTR_protocol_pin, s);
|
||||
pin_p->ioctl(pin, MP_PIN_WRITE, value, NULL);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#define MICROPY_INCLUDED_EXTMOD_VIRTPIN_H
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/proto.h"
|
||||
|
||||
#define MP_PIN_READ (1)
|
||||
#define MP_PIN_WRITE (2)
|
||||
|
@ -35,6 +36,7 @@
|
|||
|
||||
// Pin protocol
|
||||
typedef struct _mp_pin_p_t {
|
||||
MP_PROTOCOL_HEAD
|
||||
mp_uint_t (*ioctl)(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *errcode);
|
||||
} mp_pin_p_t;
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 6b3402965999d068316882d63fae3ab26006477c
|
||||
Subproject commit 0b0d1e999a6c7944e55bed59a30ccc21b3c96666
|
|
@ -1 +1 @@
|
|||
Subproject commit 1d38fd81edd30f1bd70c0cfe77819ab610ea89a3
|
||||
Subproject commit 2cf0f40ab818fddbc2cecf3ec495ed16067c5f7e
|
|
@ -1 +1 @@
|
|||
Subproject commit a1686803566793ec2de7e043bf6822e47cfa31d1
|
||||
Subproject commit 09bd10e94894a4eec7e3a02b51ffb5d8581b3024
|
|
@ -1 +1 @@
|
|||
Subproject commit 409e90902ac49720c4add985e8e1a1660bbe63a0
|
||||
Subproject commit 84eadeafa9144829b8c6faf903b4282d58a77353
|
|
@ -1 +1 @@
|
|||
Subproject commit 836bb9843fd793683061c15150944f8897d806e9
|
||||
Subproject commit f044548d6d3aa21650b50232bb16e0b29f540b8f
|
|
@ -1 +1 @@
|
|||
Subproject commit aa4428f304b982aa19a5800822e78c47dc8a3b6c
|
||||
Subproject commit 9dac9628e48675308d447b70b2005f7d1f0ddf6b
|
|
@ -1 +1 @@
|
|||
Subproject commit a03f9011279f9e630549432589463912831fcee1
|
||||
Subproject commit 42a55eafcb29f563b31e23af902c31dac8289900
|
|
@ -1 +1 @@
|
|||
Subproject commit 98563ab65800aac6464f671c0d005df56ecaa6c6
|
||||
Subproject commit ddcd1e7154f1b27f9a87daffb6e691e1e7051b64
|
|
@ -1 +1 @@
|
|||
Subproject commit c0ed34813a608b64ed044826553918ddbad12f0c
|
||||
Subproject commit 10db851c81873fd8db207ff0c4d9342426ee25a4
|
|
@ -0,0 +1 @@
|
|||
Subproject commit efd548b1e36c534bbce494f4cb0d9a625dd170cd
|
|
@ -1 +1 @@
|
|||
Subproject commit 893c5ec6a9aeef38284985074c2058e87754ad3d
|
||||
Subproject commit ac83a3dc703ec50b2236c773d22c47a0c0aaba43
|
|
@ -1 +1 @@
|
|||
Subproject commit 1d12cfc0b729b4ae0a2f3f4e7c1933a0fbd3b166
|
||||
Subproject commit dc01285aa45dd8260bb3ae35a657e4cdcbf325b8
|
|
@ -1 +1 @@
|
|||
Subproject commit d8a9d8c1d73041e4cc5669c5441f531ecba517fc
|
||||
Subproject commit 19a66d79f0650a15e502464b42e16692365eab36
|
|
@ -0,0 +1 @@
|
|||
Subproject commit c3c664bf4db6a36d11808dfcbb5dbf7cff1715b8
|
|
@ -3382,7 +3382,11 @@ FRESULT f_read (
|
|||
if (!sect) ABORT(fs, FR_INT_ERR);
|
||||
sect += csect;
|
||||
cc = btr / SS(fs); /* When remaining bytes >= sector size, */
|
||||
if (cc) { /* Read maximum contiguous sectors directly */
|
||||
if (cc
|
||||
#if _FS_DISK_READ_ALIGNED
|
||||
&& (((int)rbuff & 3) == 0)
|
||||
#endif
|
||||
) {/* Read maximum contiguous sectors directly */
|
||||
if (csect + cc > fs->csize) { /* Clip at cluster boundary */
|
||||
cc = fs->csize - csect;
|
||||
}
|
||||
|
|
|
@ -343,6 +343,12 @@
|
|||
/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
// Set to nonzero if buffers passed to disk_read have a word alignment
|
||||
// restriction
|
||||
#ifndef _FS_DISK_READ_ALIGNED
|
||||
#define _FS_DISK_READ_ALIGNED 0
|
||||
#endif
|
||||
|
||||
/* #include <windows.h> // O/S definitions */
|
||||
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit d2bcfda543d3b99361e44112aca929225bdcc07f
|
|
@ -1 +1 @@
|
|||
Subproject commit 0848c462b3e431a9da42e96537d2b597a4579636
|
||||
Subproject commit 1f95f439e11f519e69d75a4a8b7b9f28eaf5060e
|
|
@ -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) {
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
#define MICROPY_INCLUDED_LIB_UTILS_BUFFER_HELPER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.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);
|
||||
|
||||
#endif // MICROPY_INCLUDED_LIB_UTILS_BUFFER_HELPER_H
|
||||
|
|
|
@ -49,7 +49,7 @@ void mp_keyboard_interrupt(void) {
|
|||
|
||||
// Check to see if we've been CTRL-C'ed by autoreload or the user.
|
||||
bool mp_hal_is_interrupted(void) {
|
||||
return MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception));
|
||||
return MP_STATE_VM(mp_pending_exception) != NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -103,9 +103,11 @@ STATIC void strn_print_strn(void *data, const char *str, size_t len) {
|
|||
strn_print_env->remain -= len;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 9
|
||||
// uClibc requires this alias to be defined, or there may be link errors
|
||||
// when linkings against it statically.
|
||||
// GCC 9 gives a warning about missing attributes so it's excluded until
|
||||
// uClibc+GCC9 support is needed.
|
||||
int __GI_vsnprintf(char *str, size_t size, const char *fmt, va_list ap) __attribute__((weak, alias ("vsnprintf")));
|
||||
#endif
|
||||
|
||||
|
|
|
@ -131,7 +131,9 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input
|
|||
// at the moment, the value of SystemExit is unused
|
||||
ret = pyexec_system_exit;
|
||||
} else {
|
||||
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
|
||||
if ((mp_obj_t) nlr.ret_val != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
|
||||
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
|
||||
}
|
||||
ret = PYEXEC_EXCEPTION;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,6 +123,7 @@ STATIC const mp_rom_map_elem_t stdio_locals_dict_table[] = {
|
|||
STATIC MP_DEFINE_CONST_DICT(stdio_locals_dict, stdio_locals_dict_table);
|
||||
|
||||
STATIC const mp_stream_p_t stdio_obj_stream_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
|
||||
.read = stdio_read,
|
||||
.write = stdio_write,
|
||||
.ioctl = stdio_ioctl,
|
||||
|
@ -158,6 +159,7 @@ STATIC mp_uint_t stdio_buffer_write(mp_obj_t self_in, const void *buf, mp_uint_t
|
|||
}
|
||||
|
||||
STATIC const mp_stream_p_t stdio_buffer_obj_stream_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
|
||||
.read = stdio_buffer_read,
|
||||
.write = stdio_buffer_write,
|
||||
.is_text = false,
|
||||
|
|
1094
locale/ID.po
1094
locale/ID.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1305
locale/de_DE.po
1305
locale/de_DE.po
File diff suppressed because it is too large
Load Diff
931
locale/en_US.po
931
locale/en_US.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1438
locale/es.po
1438
locale/es.po
File diff suppressed because it is too large
Load Diff
1200
locale/fil.po
1200
locale/fil.po
File diff suppressed because it is too large
Load Diff
1626
locale/fr.po
1626
locale/fr.po
File diff suppressed because it is too large
Load Diff
1222
locale/it_IT.po
1222
locale/it_IT.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1583
locale/pl.po
1583
locale/pl.po
File diff suppressed because it is too large
Load Diff
1060
locale/pt_BR.po
1060
locale/pt_BR.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="78" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="78" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h47v20H0z"/><path fill="#4c1" d="M47 0h31v20H47z"/><path fill="url(#b)" d="M0 0h78v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="245" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="370">license</text><text x="245" y="140" transform="scale(.1)" textLength="370">license</text><text x="615" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="210">MIT</text><text x="615" y="140" transform="scale(.1)" textLength="210">MIT</text></g> <head xmlns=""/></svg>
|
Before Width: | Height: | Size: 963 B |
93
main.c
93
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,12 @@
|
|||
#include "supervisor/shared/stack.h"
|
||||
#include "supervisor/serial.h"
|
||||
|
||||
#include "boards/board.h"
|
||||
|
||||
#if CIRCUITPY_DISPLAYIO
|
||||
#include "shared-module/displayio/__init__.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_NETWORK
|
||||
#include "shared-module/network/__init__.h"
|
||||
#endif
|
||||
|
@ -66,6 +71,11 @@
|
|||
#include "shared-module/board/__init__.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_BLEIO
|
||||
#include "shared-bindings/_bleio/__init__.h"
|
||||
#include "supervisor/shared/bluetooth.h"
|
||||
#endif
|
||||
|
||||
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
if (lex == NULL) {
|
||||
|
@ -176,9 +186,27 @@ bool maybe_run_list(const char ** filenames, pyexec_result_t* exec_result) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void cleanup_after_vm(supervisor_allocation* heap) {
|
||||
// Turn off the display and flush the fileystem before the heap disappears.
|
||||
#if CIRCUITPY_DISPLAYIO
|
||||
reset_displays();
|
||||
#endif
|
||||
filesystem_flush();
|
||||
stop_mp();
|
||||
free_memory(heap);
|
||||
supervisor_move_memory();
|
||||
|
||||
reset_port();
|
||||
#if CIRCUITPY_BOARD
|
||||
reset_board_busses();
|
||||
#endif
|
||||
reset_board();
|
||||
reset_status_led();
|
||||
}
|
||||
|
||||
bool run_code_py(safe_mode_t safe_mode) {
|
||||
bool serial_connected_at_start = serial_connected();
|
||||
#ifdef CIRCUITPY_AUTORELOAD_DELAY_MS
|
||||
#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
|
||||
if (serial_connected_at_start) {
|
||||
serial_write("\n");
|
||||
if (autoreload_is_enabled()) {
|
||||
|
@ -219,19 +247,7 @@ bool run_code_py(safe_mode_t safe_mode) {
|
|||
serial_write_compressed(translate("WARNING: Your code filename has two extensions\n"));
|
||||
}
|
||||
}
|
||||
// Turn off the display and flush the fileystem before the heap disappears.
|
||||
#if CIRCUITPY_DISPLAYIO
|
||||
reset_displays();
|
||||
#endif
|
||||
filesystem_flush();
|
||||
stop_mp();
|
||||
free_memory(heap);
|
||||
supervisor_move_memory();
|
||||
|
||||
reset_port();
|
||||
reset_board_busses();
|
||||
reset_board();
|
||||
reset_status_led();
|
||||
cleanup_after_vm(heap);
|
||||
|
||||
if (result.return_code & PYEXEC_FORCED_EXIT) {
|
||||
return reload_requested;
|
||||
|
@ -244,12 +260,13 @@ 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) {
|
||||
#ifdef MICROPY_VM_HOOK_LOOP
|
||||
MICROPY_VM_HOOK_LOOP
|
||||
#endif
|
||||
RUN_BACKGROUND_TASKS;
|
||||
if (reload_requested) {
|
||||
reload_requested = false;
|
||||
return true;
|
||||
|
@ -281,6 +298,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);
|
||||
}
|
||||
}
|
||||
|
@ -359,13 +383,7 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
|
|||
boot_output_file = NULL;
|
||||
#endif
|
||||
|
||||
// Reset to remove any state that boot.py setup. It should only be used to
|
||||
// change internal state that's not in the heap.
|
||||
reset_port();
|
||||
reset_board();
|
||||
stop_mp();
|
||||
free_memory(heap);
|
||||
supervisor_move_memory();
|
||||
cleanup_after_vm(heap);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -382,12 +400,7 @@ int run_repl(void) {
|
|||
} else {
|
||||
exit_code = pyexec_friendly_repl();
|
||||
}
|
||||
filesystem_flush();
|
||||
reset_port();
|
||||
reset_board();
|
||||
stop_mp();
|
||||
free_memory(heap);
|
||||
supervisor_move_memory();
|
||||
cleanup_after_vm(heap);
|
||||
autoreload_resume();
|
||||
return exit_code;
|
||||
}
|
||||
|
@ -414,6 +427,9 @@ int __attribute__((used)) main(void) {
|
|||
// no SPI flash filesystem, and we might erase the existing one.
|
||||
filesystem_init(safe_mode == NO_SAFE_MODE, false);
|
||||
|
||||
// displays init after filesystem, since they could share the flash SPI
|
||||
board_init();
|
||||
|
||||
// Reset everything and prep MicroPython to run boot.py.
|
||||
reset_port();
|
||||
reset_board();
|
||||
|
@ -431,6 +447,10 @@ int __attribute__((used)) main(void) {
|
|||
// Start serial and HID after giving boot.py a chance to tweak behavior.
|
||||
serial_init();
|
||||
|
||||
#if CIRCUITPY_BLEIO
|
||||
supervisor_start_bluetooth();
|
||||
#endif
|
||||
|
||||
// Boot script is finished, so now go into REPL/main mode.
|
||||
int exit_code = PYEXEC_FORCED_EXIT;
|
||||
bool skip_repl = true;
|
||||
|
@ -462,9 +482,18 @@ void gc_collect(void) {
|
|||
// This collects root pointers from the VFS mount table. Some of them may
|
||||
// have lost their references in the VM even though they are mounted.
|
||||
gc_collect_root((void**)&MP_STATE_VM(vfs_mount_table), sizeof(mp_vfs_mount_t) / sizeof(mp_uint_t));
|
||||
|
||||
#if CIRCUITPY_DISPLAYIO
|
||||
displayio_gc_collect();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_BLEIO
|
||||
common_hal_bleio_gc_collect();
|
||||
#endif
|
||||
|
||||
// This naively collects all object references from an approximate stack
|
||||
// range.
|
||||
gc_collect_root((void**)sp, ((uint32_t)&_estack - sp) / sizeof(uint32_t));
|
||||
gc_collect_root((void**)sp, ((uint32_t)port_stack_get_top() - sp) / sizeof(uint32_t));
|
||||
gc_collect_end();
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1,6 @@
|
|||
mpy-cross
|
||||
/build-*
|
||||
/mpy-cross
|
||||
/mpy-cross.static
|
||||
/mpy-cross.static.exe
|
||||
/mpy-cross.static-raspbian
|
||||
/pitools
|
||||
|
|
|
@ -11,84 +11,4 @@ override undefine BUILD
|
|||
override undefine PROG
|
||||
endif
|
||||
|
||||
include ../py/mkenv.mk
|
||||
|
||||
# define main target
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
# Detect a MINGW32 build, and change the name of the final executable.
|
||||
PROG = mpy-cross.exe
|
||||
else
|
||||
PROG = mpy-cross
|
||||
endif
|
||||
|
||||
# qstr definitions (must come before including py.mk)
|
||||
QSTR_DEFS = qstrdefsport.h
|
||||
|
||||
# OS name, for simple autoconfig
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
# include py core make definitions
|
||||
include $(TOP)/py/py.mk
|
||||
|
||||
INC += -I.
|
||||
INC += -I$(TOP)
|
||||
INC += -I$(BUILD)
|
||||
|
||||
# compiler settings
|
||||
CWARN = -Wall -Werror
|
||||
CWARN += -Wpointer-arith -Wuninitialized
|
||||
CFLAGS = $(INC) $(CWARN) -std=gnu99 $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA)
|
||||
CFLAGS += -fdata-sections -ffunction-sections -fno-asynchronous-unwind-tables
|
||||
|
||||
# Build a static executable.
|
||||
# Useful for Windows builds, etc., that must run on multiple operating system versions.
|
||||
ifdef STATIC_BUILD
|
||||
CFLAGS += -static -static-libgcc -static-libstdc++
|
||||
endif
|
||||
|
||||
|
||||
# Debugging/Optimization
|
||||
ifdef DEBUG
|
||||
CFLAGS += -g
|
||||
COPT = -O0
|
||||
else
|
||||
COPT = -Os #-DNDEBUG
|
||||
endif
|
||||
|
||||
# On OSX, 'gcc' is a symlink to clang unless a real gcc is installed.
|
||||
# The unix port of MicroPython on OSX must be compiled with clang,
|
||||
# while cross-compile ports require gcc, so we test here for OSX and
|
||||
# if necessary override the value of 'CC' set in py/mkenv.mk
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
CC = clang
|
||||
# Use clang syntax for map file
|
||||
LDFLAGS_ARCH = -Wl,-map,$@.map -Wl,-dead_strip
|
||||
else
|
||||
# Use gcc syntax for map file
|
||||
LDFLAGS_ARCH = -Wl,-Map=$@.map,--cref -Wl,--gc-sections
|
||||
endif
|
||||
LDFLAGS = $(LDFLAGS_MOD) $(LDFLAGS_ARCH) -lm $(LDFLAGS_EXTRA)
|
||||
|
||||
ifdef STATIC_BUILD
|
||||
LDFLAGS += -static -static-libgcc -static-libstdc++
|
||||
endif
|
||||
|
||||
# source files
|
||||
SRC_C = \
|
||||
main.c \
|
||||
gccollect.c \
|
||||
supervisor/stub/safe_mode.c \
|
||||
supervisor/stub/stack.c \
|
||||
supervisor/shared/translate.c
|
||||
|
||||
# Add fmode when compiling with mingw gcc
|
||||
COMPILER_TARGET := $(shell $(CC) -dumpmachine)
|
||||
ifneq (,$(findstring mingw,$(COMPILER_TARGET)))
|
||||
SRC_C += ports/windows/fmode.c
|
||||
endif
|
||||
|
||||
OBJ = $(PY_O)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
|
||||
include $(TOP)/py/mkrules.mk
|
||||
include mpy-cross.mk
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
PROG=mpy-cross.static
|
||||
BUILD=build-static
|
||||
STATIC_BUILD=1
|
||||
|
||||
include mpy-cross.mk
|
|
@ -0,0 +1,6 @@
|
|||
PROG=mpy-cross.static.exe
|
||||
CROSS_COMPILE = x86_64-w64-mingw32-
|
||||
BUILD=build-static-mingw
|
||||
STATIC_BUILD=1
|
||||
|
||||
include mpy-cross.mk
|
|
@ -0,0 +1,8 @@
|
|||
PROG=mpy-cross.static-raspbian
|
||||
BUILD=build-static-raspbian
|
||||
STATIC_BUILD=1
|
||||
|
||||
CROSS_COMPILE = pitools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-
|
||||
include mpy-cross.mk
|
||||
|
||||
$(shell [ -d pitools ] || git clone --progress --verbose https://github.com/raspberrypi/tools.git --depth=1 pitools)
|
|
@ -35,7 +35,7 @@
|
|||
#include "py/gc.h"
|
||||
#include "py/stackctrl.h"
|
||||
#ifdef _WIN32
|
||||
#include "ports/windows/fmode.h"
|
||||
#include "fmode.h"
|
||||
#endif
|
||||
|
||||
// Command line options, with their defaults
|
||||
|
@ -284,3 +284,7 @@ void nlr_jump_fail(void *val) {
|
|||
printf("FATAL: uncaught NLR %p\n", val);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void serial_write(const char* text) {
|
||||
printf("%s", text);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
include ../py/mkenv.mk
|
||||
|
||||
# define main target
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
# Detect a MINGW32 build, and change the name of the final executable.
|
||||
PROG ?= mpy-cross.exe
|
||||
else
|
||||
PROG ?= mpy-cross
|
||||
endif
|
||||
|
||||
# qstr definitions (must come before including py.mk)
|
||||
QSTR_DEFS = qstrdefsport.h
|
||||
|
||||
# OS name, for simple autoconfig
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
# include py core make definitions
|
||||
include $(TOP)/py/py.mk
|
||||
|
||||
INC += -I.
|
||||
INC += -I$(TOP)
|
||||
INC += -I$(BUILD)
|
||||
|
||||
# compiler settings
|
||||
CWARN = -Wall -Werror
|
||||
CWARN += -Wpointer-arith -Wuninitialized
|
||||
CFLAGS = $(INC) $(CWARN) -std=gnu99 $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA)
|
||||
CFLAGS += -fdata-sections -ffunction-sections -fno-asynchronous-unwind-tables
|
||||
|
||||
# Build a static executable.
|
||||
# Useful for Windows builds, etc., that must run on multiple operating system versions.
|
||||
ifdef STATIC_BUILD
|
||||
CFLAGS += -static -static-libgcc -static-libstdc++
|
||||
endif
|
||||
|
||||
|
||||
# Debugging/Optimization
|
||||
ifdef DEBUG
|
||||
CFLAGS += -g
|
||||
COPT = -O0
|
||||
else
|
||||
COPT = -Os #-DNDEBUG
|
||||
endif
|
||||
|
||||
# On OSX, 'gcc' is a symlink to clang unless a real gcc is installed.
|
||||
# The unix port of MicroPython on OSX must be compiled with clang,
|
||||
# while cross-compile ports require gcc, so we test here for OSX and
|
||||
# if necessary override the value of 'CC' set in py/mkenv.mk
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
CC = clang
|
||||
# Use clang syntax for map file
|
||||
LDFLAGS_ARCH = -Wl,-map,$@.map -Wl,-dead_strip
|
||||
else
|
||||
# Use gcc syntax for map file
|
||||
LDFLAGS_ARCH = -Wl,-Map=$@.map,--cref -Wl,--gc-sections
|
||||
endif
|
||||
LDFLAGS = $(LDFLAGS_MOD) $(LDFLAGS_ARCH) -lm $(LDFLAGS_EXTRA)
|
||||
|
||||
ifdef STATIC_BUILD
|
||||
LDFLAGS += -static -static-libgcc -static-libstdc++
|
||||
endif
|
||||
|
||||
# source files
|
||||
SRC_C = \
|
||||
main.c \
|
||||
gccollect.c \
|
||||
supervisor/stub/safe_mode.c \
|
||||
supervisor/stub/stack.c \
|
||||
supervisor/shared/translate.c
|
||||
|
||||
# Add fmode when compiling with mingw gcc
|
||||
COMPILER_TARGET := $(shell $(CC) -dumpmachine)
|
||||
ifneq (,$(findstring mingw,$(COMPILER_TARGET)))
|
||||
SRC_C += fmode.c
|
||||
endif
|
||||
|
||||
OBJ = $(PY_O)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
|
||||
include $(TOP)/py/mkrules.mk
|
|
@ -99,10 +99,9 @@ endif
|
|||
|
||||
#Debugging/Optimization
|
||||
ifeq ($(DEBUG), 1)
|
||||
# Turn on Python modules useful for debugging (e.g. uheap, ustack).
|
||||
CFLAGS += -ggdb
|
||||
# You may want to disable -flto if it interferes with debugging.
|
||||
CFLAGS += -flto
|
||||
CFLAGS += -flto -flto-partition=none
|
||||
# You may want to enable these flags to make setting breakpoints easier.
|
||||
# CFLAGS += -fno-inline -fno-ipa-sra
|
||||
ifeq ($(CHIP_FAMILY), samd21)
|
||||
|
@ -112,13 +111,27 @@ else
|
|||
# -finline-limit can shrink the image size.
|
||||
# -finline-limit=80 or so is similar to not having it on.
|
||||
# There is no simple default value, though.
|
||||
ifeq ($(INTERNAL_FLASH_FILESYSTEM),1)
|
||||
CFLAGS += -finline-limit=50
|
||||
|
||||
# Do a default shrink for small builds.
|
||||
ifndef CFLAGS_INLINE_LIMIT
|
||||
ifeq ($(CIRCUITPY_SMALL_BUILD),1)
|
||||
CFLAGS_INLINE_LIMIT = 50
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef CFLAGS_INLINE_LIMIT
|
||||
CFLAGS += -finline-limit=$(CFLAGS_INLINE_LIMIT)
|
||||
endif
|
||||
CFLAGS += -flto
|
||||
|
||||
CFLAGS += -flto -flto-partition=none
|
||||
|
||||
ifeq ($(CIRCUITPY_SMALL_BUILD),1)
|
||||
CFLAGS += --param inline-unit-growth=15 --param max-inline-insns-auto=20
|
||||
endif
|
||||
|
||||
ifdef CFLAGS_BOARD
|
||||
CFLAGS += $(CFLAGS_BOARD)
|
||||
endif
|
||||
endif
|
||||
|
||||
CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT)
|
||||
|
@ -144,7 +157,7 @@ endif
|
|||
|
||||
|
||||
|
||||
LDFLAGS = $(CFLAGS) -nostartfiles -fshort-enums -Wl,-nostdlib -Wl,-T,$(LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections -specs=nano.specs
|
||||
LDFLAGS = $(CFLAGS) -nostartfiles -fshort-enums -Wl,-nostdlib -Wl,-T,$(GENERATED_LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections -specs=nano.specs
|
||||
LIBS := -lgcc -lc
|
||||
|
||||
# Use toolchain libm if we're not using our own.
|
||||
|
@ -220,7 +233,7 @@ SRC_C = \
|
|||
lib/oofatfs/ff.c \
|
||||
lib/oofatfs/option/ccsbcs.c \
|
||||
lib/timeutils/timeutils.c \
|
||||
lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/dcd_$(CHIP_FAMILY).c \
|
||||
lib/tinyusb/src/portable/microchip/samd/dcd_samd.c \
|
||||
lib/utils/buffer_helper.c \
|
||||
lib/utils/context_manager_helpers.c \
|
||||
lib/utils/interrupt_char.c \
|
||||
|
@ -285,14 +298,20 @@ 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))
|
||||
|
||||
# There may be duplicates between SRC_COMMON_HAL_EXPANDED and SRC_SHARED_MODULE_EXPANDED,
|
||||
# because a few modules have files both in common-hal/ and shared-modules/.
|
||||
# Doing a $(sort ...) removes duplicates as part of sorting.
|
||||
SRC_COMMON_HAL_SHARED_MODULE_EXPANDED = $(sort $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED))
|
||||
|
||||
|
||||
SRC_S = supervisor/$(CHIP_FAMILY)_cpu.s
|
||||
|
||||
OBJ = $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_ASF:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_EXPANDED:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o))
|
||||
ifeq ($(INTERNAL_LIBM),1)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o))
|
||||
endif
|
||||
|
@ -305,10 +324,10 @@ SRC_QSTR_PREPROCESSOR += peripherals/samd/$(CHIP_FAMILY)/clocks.c
|
|||
|
||||
all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2
|
||||
|
||||
$(BUILD)/firmware.elf: $(OBJ)
|
||||
$(BUILD)/firmware.elf: $(OBJ) $(GENERATED_LD_FILE)
|
||||
$(STEPECHO) "LINK $@"
|
||||
$(Q)$(CC) -o $@ $(LDFLAGS) $^ -Wl,--start-group $(LIBS) -Wl,--end-group
|
||||
$(Q)$(SIZE) $@ | $(PYTHON3) $(TOP)/tools/build_memory_info.py $(LD_FILE)
|
||||
$(Q)$(CC) -o $@ $(LDFLAGS) $(OBJ) -Wl,--start-group $(LIBS) -Wl,--end-group
|
||||
$(Q)$(SIZE) $@ | $(PYTHON3) $(TOP)/tools/build_memory_info.py $(GENERATED_LD_FILE)
|
||||
|
||||
$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
|
||||
$(STEPECHO) "Create $@"
|
||||
|
|
|
@ -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 <https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads>`_
|
||||
may be available in binary form.
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
// <i> This defines the current in output buffer according to conversion rate
|
||||
// <id> dac0_arch_cctrl
|
||||
#ifndef CONF_DAC0_CCTRL
|
||||
#define CONF_DAC0_CCTRL 1
|
||||
#define CONF_DAC0_CCTRL 0
|
||||
#endif
|
||||
|
||||
// <q> Run in standby
|
||||
|
@ -90,7 +90,7 @@
|
|||
// <i> This defines the current in output buffer according to conversion rate
|
||||
// <id> dac1_arch_cctrl
|
||||
#ifndef CONF_DAC1_CCTRL
|
||||
#define CONF_DAC1_CCTRL 1
|
||||
#define CONF_DAC1_CCTRL 0
|
||||
#endif
|
||||
|
||||
// <q> Run in standby
|
||||
|
|
|
@ -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 @@
|
|||
// <i> Indicates whether generic clock 6 configuration is enabled or not
|
||||
// <id> 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
|
||||
|
||||
// <h> Generic Clock Generator Control
|
||||
|
@ -488,7 +489,7 @@
|
|||
// <i> This defines the clock source for generic clock generator 6
|
||||
// <id> 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
|
||||
|
||||
// <q> Run in Standby
|
||||
|
@ -523,14 +524,14 @@
|
|||
// <i> Indicates whether Improve Duty Cycle is enabled or not
|
||||
// <id> 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
|
||||
|
||||
// <q> Generic Clock Generator Enable
|
||||
// <i> Indicates whether Generic Clock Generator Enable is enabled or not
|
||||
// <id> 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
|
||||
// </h>
|
||||
|
||||
|
@ -538,7 +539,7 @@
|
|||
//<o> Generic clock generator 6 division <0x0000-0xFFFF>
|
||||
// <id> 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
|
||||
// </h>
|
||||
// </e>
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
// <id> dac_gclk_selection
|
||||
// <i> 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
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -179,13 +203,13 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t* dma,
|
|||
if (output_signed != samples_signed) {
|
||||
output_spacing = 1;
|
||||
max_buffer_length /= dma->spacing;
|
||||
dma->first_buffer = (uint8_t*) m_malloc(max_buffer_length, false);
|
||||
dma->first_buffer = (uint8_t*) m_realloc(dma->first_buffer, max_buffer_length);
|
||||
if (dma->first_buffer == NULL) {
|
||||
return AUDIO_DMA_MEMORY_ERROR;
|
||||
}
|
||||
dma->first_buffer_free = true;
|
||||
if (!single_buffer) {
|
||||
dma->second_buffer = (uint8_t*) m_malloc(max_buffer_length, false);
|
||||
dma->second_buffer = (uint8_t*) m_realloc(dma->second_buffer, max_buffer_length);
|
||||
if (dma->second_buffer == NULL) {
|
||||
return AUDIO_DMA_MEMORY_ERROR;
|
||||
}
|
||||
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue