summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Osterwood <osterwood@gmail.com>2019-08-08 14:14:23 -0400
committerChris Osterwood <osterwood@gmail.com>2019-08-08 14:14:23 -0400
commitfb2712410e49e2e056ca1900b9c49bb0831bad74 (patch)
tree8959d4afaa94175a870a5268ed638bac620a9023
parent97e7fea517cef72926ac4e8d30c711a59226f259 (diff)
parent47a0b7cba141efb0909d74db3401ae902f6e9a96 (diff)
Merge branch 'master' into capablerobot-usbhub
-rw-r--r--.gitignore3
-rw-r--r--.gitmodules3
-rwxr-xr-x.travis.yml29
-rw-r--r--Makefile22
-rw-r--r--README.rst8
-rw-r--r--conf.py25
-rw-r--r--docs/c2rst.py46
-rw-r--r--docs/design_guide.rst2
-rw-r--r--docs/library/builtins.rst6
-rw-r--r--docs/library/network.rst1
-rw-r--r--docs/requirements.txt4
-rw-r--r--docs/rstjinja.py24
-rw-r--r--docs/shared_bindings_matrix.py244
m---------frozen/Adafruit_CircuitPython_BusDevice0
m---------frozen/Adafruit_CircuitPython_CircuitPlayground0
m---------frozen/Adafruit_CircuitPython_Crickit0
m---------frozen/Adafruit_CircuitPython_HID0
m---------frozen/Adafruit_CircuitPython_IRRemote0
m---------frozen/Adafruit_CircuitPython_LIS3DH0
m---------frozen/Adafruit_CircuitPython_Motor0
m---------frozen/Adafruit_CircuitPython_NeoPixel0
m---------frozen/Adafruit_CircuitPython_seesaw0
m---------frozen/circuitpython-stage0
m---------lib/tinyusb0
-rw-r--r--lib/utils/printf.c4
-rw-r--r--locale/ID.po298
-rw-r--r--locale/circuitpython.pot222
-rw-r--r--locale/de_DE.po305
-rw-r--r--locale/en_US.po234
-rw-r--r--locale/en_x_pirate.po234
-rw-r--r--locale/es.po617
-rw-r--r--locale/fil.po312
-rw-r--r--locale/fr.po339
-rw-r--r--locale/it_IT.po317
-rw-r--r--locale/pl.po321
-rw-r--r--locale/pt_BR.po284
-rw-r--r--locale/zh_Latn_pinyin.po325
-rwxr-xr-xmain.c12
-rw-r--r--ports/atmel-samd/Makefile14
-rw-r--r--ports/atmel-samd/README.rst17
-rw-r--r--ports/atmel-samd/audio_dma.c4
-rw-r--r--ports/atmel-samd/audio_dma.h4
-rw-r--r--ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk7
-rw-r--r--ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk8
-rw-r--r--ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk14
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk17
-rw-r--r--ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk11
-rw-r--r--ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk13
-rw-r--r--ports/atmel-samd/boards/datum_distance/board.c (renamed from ports/atmel-samd/boards/robohatmm1/board.c)0
-rw-r--r--ports/atmel-samd/boards/datum_distance/mpconfigboard.h29
-rw-r--r--ports/atmel-samd/boards/datum_distance/mpconfigboard.mk14
-rw-r--r--ports/atmel-samd/boards/datum_distance/pins.c27
-rw-r--r--ports/atmel-samd/boards/datum_imu/board.c38
-rw-r--r--ports/atmel-samd/boards/datum_imu/mpconfigboard.h29
-rw-r--r--ports/atmel-samd/boards/datum_imu/mpconfigboard.mk14
-rw-r--r--ports/atmel-samd/boards/datum_imu/pins.c29
-rw-r--r--ports/atmel-samd/boards/datum_light/board.c38
-rw-r--r--ports/atmel-samd/boards/datum_light/mpconfigboard.h29
-rw-r--r--ports/atmel-samd/boards/datum_light/mpconfigboard.mk14
-rw-r--r--ports/atmel-samd/boards/datum_light/pins.c27
-rw-r--r--ports/atmel-samd/boards/datum_weather/board.c38
-rw-r--r--ports/atmel-samd/boards/datum_weather/mpconfigboard.h29
-rw-r--r--ports/atmel-samd/boards/datum_weather/mpconfigboard.mk14
-rw-r--r--ports/atmel-samd/boards/datum_weather/pins.c27
-rw-r--r--ports/atmel-samd/boards/escornabot_makech/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/escornabot_makech/pins.c5
-rw-r--r--ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk10
-rw-r--r--ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk10
-rw-r--r--ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk7
-rw-r--r--ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk13
-rwxr-xr-xports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk8
-rw-r--r--ports/atmel-samd/boards/hallowing_m0_express/board.c9
-rw-r--r--ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk10
-rw-r--r--ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk14
-rw-r--r--ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk7
-rw-r--r--ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk7
-rw-r--r--ports/atmel-samd/boards/meowmeow/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk13
-rw-r--r--ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk13
-rw-r--r--ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk13
-rw-r--r--ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk8
-rw-r--r--ports/atmel-samd/boards/pewpew10/mpconfigboard.mk15
-rw-r--r--ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk10
-rw-r--r--ports/atmel-samd/boards/pirkey_m0/pins.c3
-rw-r--r--ports/atmel-samd/boards/pybadge/board.c13
-rw-r--r--ports/atmel-samd/boards/pybadge/mpconfigboard.mk20
-rw-r--r--ports/atmel-samd/boards/pybadge_airlift/board.c97
-rw-r--r--ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.h37
-rw-r--r--ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.mk23
-rw-r--r--ports/atmel-samd/boards/pybadge_airlift/pins.c75
-rw-r--r--ports/atmel-samd/boards/pygamer/board.c9
-rw-r--r--ports/atmel-samd/boards/pygamer/mpconfigboard.mk22
-rw-r--r--ports/atmel-samd/boards/pygamer/pins.c7
-rw-r--r--ports/atmel-samd/boards/pygamer_advance/board.c97
-rw-r--r--ports/atmel-samd/boards/pygamer_advance/mpconfigboard.h36
-rw-r--r--ports/atmel-samd/boards/pygamer_advance/mpconfigboard.mk23
-rw-r--r--ports/atmel-samd/boards/pygamer_advance/pins.c75
-rw-r--r--ports/atmel-samd/boards/pyportal/board.c7
-rw-r--r--ports/atmel-samd/boards/pyportal/mpconfigboard.mk9
-rw-r--r--ports/atmel-samd/boards/pyruler/board.c37
-rw-r--r--ports/atmel-samd/boards/pyruler/mpconfigboard.h63
-rw-r--r--ports/atmel-samd/boards/pyruler/mpconfigboard.mk14
-rw-r--r--ports/atmel-samd/boards/pyruler/pins.c50
-rw-r--r--ports/atmel-samd/boards/robohatmm1/pins.c88
-rw-r--r--ports/atmel-samd/boards/robohatmm1_m0/board.c38
-rw-r--r--ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.h (renamed from ports/atmel-samd/boards/robohatmm1/mpconfigboard.h)16
-rw-r--r--ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.mk (renamed from ports/atmel-samd/boards/robohatmm1/mpconfigboard.mk)23
-rw-r--r--ports/atmel-samd/boards/robohatmm1_m0/pins.c88
-rw-r--r--ports/atmel-samd/boards/robohatmm1_m4/board.c39
-rw-r--r--ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.h44
-rw-r--r--ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk31
-rw-r--r--ports/atmel-samd/boards/robohatmm1_m4/pins.c89
-rw-r--r--ports/atmel-samd/boards/sam32/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/snekboard/board.c38
-rw-r--r--ports/atmel-samd/boards/snekboard/mpconfigboard.h35
-rw-r--r--ports/atmel-samd/boards/snekboard/mpconfigboard.mk16
-rw-r--r--ports/atmel-samd/boards/snekboard/pins.c28
-rwxr-xr-xports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk11
-rwxr-xr-xports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk11
-rw-r--r--ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk7
-rw-r--r--ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/uchip/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/ugame10/board.c9
-rw-r--r--ports/atmel-samd/boards/ugame10/brutalist-6.bdf1147
-rw-r--r--ports/atmel-samd/boards/ugame10/brutalist.sfd1034
-rw-r--r--ports/atmel-samd/boards/ugame10/mpconfigboard.mk8
-rw-r--r--ports/atmel-samd/common-hal/audiobusio/I2SOut.c2
-rw-r--r--ports/atmel-samd/common-hal/busio/I2C.c9
-rw-r--r--ports/atmel-samd/common-hal/busio/SPI.h1
-rw-r--r--ports/atmel-samd/common-hal/busio/UART.c12
-rw-r--r--ports/atmel-samd/common-hal/displayio/ParallelBus.c17
-rw-r--r--ports/atmel-samd/common-hal/ps2io/Ps2.c441
-rw-r--r--ports/atmel-samd/common-hal/ps2io/Ps2.h62
-rw-r--r--ports/atmel-samd/common-hal/ps2io/__init__.c1
-rw-r--r--ports/atmel-samd/eic_handler.c7
-rw-r--r--ports/atmel-samd/eic_handler.h1
-rw-r--r--ports/atmel-samd/mpconfigport.mk2
-rw-r--r--ports/atmel-samd/supervisor/port.c1
-rw-r--r--ports/atmel-samd/tools/gen_pin_name_table.py3
-rw-r--r--ports/esp8266/common-hal/busio/UART.c2
-rwxr-xr-xports/nrf/Makefile2
-rw-r--r--ports/nrf/README.md1
-rw-r--r--ports/nrf/background.c11
-rw-r--r--ports/nrf/bluetooth/ble_drv.c3
-rw-r--r--ports/nrf/bluetooth/ble_drv.h10
-rw-r--r--ports/nrf/bluetooth/ble_uart.c3
-rw-r--r--ports/nrf/boards/electronut_labs_blip/README.md67
-rw-r--r--ports/nrf/boards/electronut_labs_blip/board.c (renamed from supervisor/shared/usb/usb_desc.h)23
-rw-r--r--ports/nrf/boards/electronut_labs_blip/mpconfigboard.h53
-rw-r--r--ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk30
-rw-r--r--ports/nrf/boards/electronut_labs_blip/pins.c72
-rw-r--r--ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h2
-rw-r--r--ports/nrf/boards/metro_nrf52840_express/board.c38
-rw-r--r--ports/nrf/boards/metro_nrf52840_express/mpconfigboard.h73
-rw-r--r--ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk26
-rw-r--r--ports/nrf/boards/metro_nrf52840_express/pins.c56
-rw-r--r--ports/nrf/boards/particle_argon/mpconfigboard.h2
-rw-r--r--ports/nrf/boards/particle_boron/mpconfigboard.h2
-rw-r--r--ports/nrf/boards/particle_xenon/mpconfigboard.h8
-rw-r--r--ports/nrf/common-hal/analogio/AnalogIn.c2
-rw-r--r--ports/nrf/common-hal/audiopwmio/PWMAudioOut.c316
-rw-r--r--ports/nrf/common-hal/audiopwmio/PWMAudioOut.h (renamed from ports/nrf/common-hal/bleio/Broadcaster.h)44
-rw-r--r--ports/nrf/common-hal/audiopwmio/__init__.c0
-rw-r--r--ports/nrf/common-hal/bleio/Adapter.c11
-rw-r--r--ports/nrf/common-hal/bleio/Adapter.h3
-rw-r--r--ports/nrf/common-hal/bleio/Broadcaster.c98
-rw-r--r--ports/nrf/common-hal/bleio/Central.c463
-rw-r--r--ports/nrf/common-hal/bleio/Central.h (renamed from shared-module/bleio/Device.h)20
-rw-r--r--ports/nrf/common-hal/bleio/Characteristic.c228
-rw-r--r--ports/nrf/common-hal/bleio/Characteristic.h14
-rw-r--r--ports/nrf/common-hal/bleio/CharacteristicBuffer.c45
-rw-r--r--ports/nrf/common-hal/bleio/CharacteristicBuffer.h8
-rw-r--r--ports/nrf/common-hal/bleio/Descriptor.c8
-rw-r--r--ports/nrf/common-hal/bleio/Descriptor.h5
-rw-r--r--ports/nrf/common-hal/bleio/Device.c601
-rw-r--r--ports/nrf/common-hal/bleio/Peripheral.c359
-rw-r--r--ports/nrf/common-hal/bleio/Peripheral.h23
-rw-r--r--ports/nrf/common-hal/bleio/Scanner.c57
-rw-r--r--ports/nrf/common-hal/bleio/Scanner.h (renamed from shared-module/bleio/Scanner.h)9
-rw-r--r--ports/nrf/common-hal/bleio/Service.c34
-rw-r--r--ports/nrf/common-hal/bleio/Service.h (renamed from shared-module/bleio/Service.h)14
-rw-r--r--ports/nrf/common-hal/bleio/UUID.c3
-rw-r--r--ports/nrf/common-hal/bleio/UUID.h3
-rw-r--r--ports/nrf/common-hal/bleio/__init__.c14
-rw-r--r--ports/nrf/common-hal/bleio/__init__.h6
-rw-r--r--ports/nrf/common-hal/busio/I2C.c22
-rw-r--r--ports/nrf/common-hal/busio/SPI.c10
-rw-r--r--ports/nrf/common-hal/busio/UART.c2
-rw-r--r--ports/nrf/common-hal/microcontroller/Pin.c2
-rw-r--r--ports/nrf/common-hal/microcontroller/__init__.c9
-rw-r--r--ports/nrf/common-hal/neopixel_write/__init__.c11
-rw-r--r--ports/nrf/common-hal/pulseio/PWMOut.c160
-rw-r--r--ports/nrf/common-hal/pulseio/PWMOut.h3
-rw-r--r--ports/nrf/mpconfigport.mk4
-rw-r--r--ports/nrf/mphalport.c3
-rw-r--r--ports/nrf/nrfx_config.h4
-rw-r--r--ports/nrf/supervisor/port.c18
-rw-r--r--ports/stm32f4/.gitignore9
-rwxr-xr-xports/stm32f4/Makefile271
-rw-r--r--ports/stm32f4/README.md3
-rw-r--r--ports/stm32f4/background.c57
-rw-r--r--ports/stm32f4/background.h35
-rw-r--r--ports/stm32f4/boards/STM32F411VETx_FLASH.ld189
-rw-r--r--ports/stm32f4/boards/STM32F412ZGTx_FLASH.ld189
-rw-r--r--ports/stm32f4/boards/board.h45
-rw-r--r--ports/stm32f4/boards/startup_stm32f411xe.s452
-rw-r--r--ports/stm32f4/boards/startup_stm32f412zx.s524
-rw-r--r--ports/stm32f4/boards/stm32f411.ld189
-rw-r--r--ports/stm32f4/boards/stm32f411re_discovery/board.c38
-rw-r--r--ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.h38
-rw-r--r--ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.mk13
-rw-r--r--ports/stm32f4/boards/stm32f411re_discovery/pins.c90
-rw-r--r--ports/stm32f4/boards/stm32f411re_discovery/stm32f4xx_hal_conf.h439
-rw-r--r--ports/stm32f4/boards/stm32f411re_discovery/stm32f4xx_hal_msp.c427
-rw-r--r--ports/stm32f4/boards/stm32f412zg_discovery/board.c38
-rw-r--r--ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h38
-rw-r--r--ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk13
-rw-r--r--ports/stm32f4/boards/stm32f412zg_discovery/pins.c90
-rw-r--r--ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h439
-rw-r--r--ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_msp.c832
-rw-r--r--ports/stm32f4/common-hal/board/__init__.c25
-rw-r--r--ports/stm32f4/common-hal/digitalio/DigitalInOut.c159
-rw-r--r--ports/stm32f4/common-hal/digitalio/DigitalInOut.h38
-rw-r--r--ports/stm32f4/common-hal/digitalio/__init__.c1
-rw-r--r--ports/stm32f4/common-hal/microcontroller/Pin.c81
-rw-r--r--ports/stm32f4/common-hal/microcontroller/Pin.h42
-rw-r--r--ports/stm32f4/common-hal/microcontroller/Processor.c44
-rw-r--r--ports/stm32f4/common-hal/microcontroller/Processor.h39
-rw-r--r--ports/stm32f4/common-hal/microcontroller/__init__.c191
-rw-r--r--ports/stm32f4/common-hal/nvm/ByteArray.c81
-rw-r--r--ports/stm32f4/common-hal/nvm/ByteArray.h36
-rw-r--r--ports/stm32f4/common-hal/nvm/__init__.c27
-rwxr-xr-xports/stm32f4/common-hal/supervisor/Runtime.c38
-rwxr-xr-xports/stm32f4/common-hal/supervisor/Runtime.h37
-rwxr-xr-xports/stm32f4/common-hal/supervisor/__init__.c40
-rw-r--r--ports/stm32f4/common-hal/time/__init__.c37
-rw-r--r--ports/stm32f4/fatfs_port.c33
-rw-r--r--ports/stm32f4/mpconfigport.h45
-rw-r--r--ports/stm32f4/mpconfigport.mk22
-rw-r--r--ports/stm32f4/mphalport.c52
-rw-r--r--ports/stm32f4/mphalport.h45
-rw-r--r--ports/stm32f4/peripherals/stm32f4/clocks.h27
-rw-r--r--ports/stm32f4/peripherals/stm32f4/gpio.h27
-rw-r--r--ports/stm32f4/peripherals/stm32f4/pins.h73
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f411xe/clocks.c63
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f411xe/gpio.c137
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.c33
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.h36
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f412zx/clocks.c75
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f412zx/gpio.c218
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.c159
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.h156
-rw-r--r--ports/stm32f4/qstrdefsport.h1
m---------ports/stm32f4/stm32f40
-rwxr-xr-xports/stm32f4/supervisor/cpu.s27
-rw-r--r--ports/stm32f4/supervisor/internal_flash.c73
-rw-r--r--ports/stm32f4/supervisor/internal_flash.h37
-rw-r--r--ports/stm32f4/supervisor/internal_flash_root_pointers.h31
-rw-r--r--ports/stm32f4/supervisor/port.c80
-rw-r--r--ports/stm32f4/supervisor/qspi_flash.c162
-rw-r--r--ports/stm32f4/supervisor/serial.c75
-rw-r--r--ports/stm32f4/supervisor/usb.c80
-rw-r--r--ports/stm32f4/system_stm32f4xx.c761
-rw-r--r--ports/stm32f4/tick.c85
-rw-r--r--ports/stm32f4/tick.h46
-rw-r--r--py/binary.c8
-rw-r--r--py/circuitpy_defns.mk33
-rw-r--r--py/circuitpy_mpconfig.h26
-rw-r--r--py/circuitpy_mpconfig.mk85
-rw-r--r--py/emitglue.c7
-rwxr-xr-xpy/gc.c4
-rw-r--r--py/gc.h1
-rw-r--r--py/makeqstrdata.py4
-rw-r--r--py/modbuiltins.c6
-rw-r--r--py/obj.c30
-rw-r--r--py/obj.h5
-rw-r--r--py/objint.c45
-rw-r--r--py/objint.h5
-rw-r--r--py/objlist.c4
-rw-r--r--py/objtype.c10
-rw-r--r--py/objtype.h2
-rw-r--r--py/persistentcode.c26
-rw-r--r--py/py.mk17
-rw-r--r--py/vmentrytable.h4
-rw-r--r--requirements-dev.txt1
-rw-r--r--setup.py22
-rw-r--r--shared-bindings/_pew/PewPew.c15
-rw-r--r--shared-bindings/_pixelbuf/PixelBuf.c42
-rw-r--r--shared-bindings/_pixelbuf/__init__.c38
-rw-r--r--shared-bindings/_stage/__init__.c21
-rw-r--r--shared-bindings/analogio/AnalogIn.c9
-rw-r--r--shared-bindings/analogio/AnalogOut.c4
-rw-r--r--shared-bindings/audiobusio/I2SOut.c26
-rw-r--r--shared-bindings/audiobusio/PDMIn.c11
-rw-r--r--shared-bindings/audiocore/Mixer.c (renamed from shared-bindings/audioio/Mixer.c)29
-rw-r--r--shared-bindings/audiocore/Mixer.h (renamed from shared-bindings/audioio/Mixer.h)4
-rw-r--r--shared-bindings/audiocore/RawSample.c (renamed from shared-bindings/audioio/RawSample.c)17
-rw-r--r--shared-bindings/audiocore/RawSample.h (renamed from shared-bindings/audioio/RawSample.h)3
-rw-r--r--shared-bindings/audiocore/WaveFile.c (renamed from shared-bindings/audioio/WaveFile.c)25
-rw-r--r--shared-bindings/audiocore/WaveFile.h (renamed from shared-bindings/audioio/WaveFile.h)5
-rw-r--r--shared-bindings/audiocore/__init__.c69
-rw-r--r--shared-bindings/audiocore/__init__.h (renamed from shared-bindings/bleio/AdvertisementData.h)10
-rw-r--r--shared-bindings/audioio/AudioOut.c26
-rw-r--r--shared-bindings/audioio/AudioOut.h2
-rw-r--r--shared-bindings/audioio/__init__.c12
-rw-r--r--shared-bindings/audiopwmio/PWMAudioOut.c294
-rw-r--r--shared-bindings/audiopwmio/PWMAudioOut.h49
-rw-r--r--shared-bindings/audiopwmio/__init__.c71
-rw-r--r--shared-bindings/audiopwmio/__init__.h34
-rw-r--r--shared-bindings/bitbangio/I2C.c35
-rw-r--r--shared-bindings/bitbangio/OneWire.c12
-rw-r--r--shared-bindings/bitbangio/SPI.c40
-rw-r--r--shared-bindings/bleio/Adapter.c1
-rw-r--r--shared-bindings/bleio/Adapter.h1
-rw-r--r--shared-bindings/bleio/Address.c195
-rw-r--r--shared-bindings/bleio/Address.h14
-rw-r--r--shared-bindings/bleio/AddressType.c99
-rw-r--r--shared-bindings/bleio/AdvertisementData.c90
-rw-r--r--shared-bindings/bleio/Broadcaster.c132
-rw-r--r--shared-bindings/bleio/Central.c199
-rw-r--r--shared-bindings/bleio/Central.h (renamed from shared-bindings/bleio/Device.h)24
-rw-r--r--shared-bindings/bleio/Characteristic.c92
-rw-r--r--shared-bindings/bleio/Characteristic.h10
-rw-r--r--shared-bindings/bleio/CharacteristicBuffer.c28
-rw-r--r--shared-bindings/bleio/CharacteristicBuffer.h2
-rw-r--r--shared-bindings/bleio/Descriptor.c99
-rw-r--r--shared-bindings/bleio/Descriptor.h19
-rw-r--r--shared-bindings/bleio/Device.c363
-rw-r--r--shared-bindings/bleio/Peripheral.c117
-rw-r--r--shared-bindings/bleio/Peripheral.h9
-rw-r--r--shared-bindings/bleio/ScanEntry.c252
-rw-r--r--shared-bindings/bleio/ScanEntry.h6
-rw-r--r--shared-bindings/bleio/Scanner.c151
-rw-r--r--shared-bindings/bleio/Scanner.h7
-rw-r--r--shared-bindings/bleio/Service.c75
-rw-r--r--shared-bindings/bleio/Service.h9
-rw-r--r--shared-bindings/bleio/UUID.c34
-rw-r--r--shared-bindings/bleio/UUID.h1
-rw-r--r--shared-bindings/bleio/__init__.c32
-rw-r--r--shared-bindings/bleio/__init__.h3
-rw-r--r--shared-bindings/board/__init__.c7
-rw-r--r--shared-bindings/busio/I2C.c38
-rw-r--r--shared-bindings/busio/I2C.h3
-rw-r--r--shared-bindings/busio/OneWire.c12
-rw-r--r--shared-bindings/busio/SPI.c47
-rw-r--r--shared-bindings/busio/UART.c24
-rw-r--r--shared-bindings/busio/UART.h2
-rw-r--r--shared-bindings/busio/__init__.c1
-rw-r--r--shared-bindings/digitalio/DigitalInOut.c33
-rw-r--r--shared-bindings/digitalio/Direction.c2
-rw-r--r--shared-bindings/digitalio/DriveMode.c2
-rw-r--r--shared-bindings/digitalio/Pull.c2
-rw-r--r--shared-bindings/displayio/ColorConverter.c8
-rw-r--r--shared-bindings/displayio/ColorConverter.h4
-rw-r--r--shared-bindings/displayio/Display.c46
-rw-r--r--shared-bindings/displayio/Display.h14
-rw-r--r--shared-bindings/displayio/FourWire.c8
-rw-r--r--shared-bindings/displayio/FourWire.h2
-rw-r--r--shared-bindings/displayio/Group.c41
-rw-r--r--shared-bindings/displayio/Group.h2
-rw-r--r--shared-bindings/displayio/I2CDisplay.c138
-rw-r--r--shared-bindings/displayio/I2CDisplay.h (renamed from shared-bindings/bleio/AddressType.h)34
-rw-r--r--shared-bindings/displayio/Palette.c38
-rw-r--r--shared-bindings/displayio/Palette.h2
-rw-r--r--shared-bindings/displayio/TileGrid.c91
-rw-r--r--shared-bindings/displayio/TileGrid.h11
-rw-r--r--shared-bindings/displayio/__init__.c5
-rw-r--r--shared-bindings/fontio/Glyph.c2
-rw-r--r--shared-bindings/frequencyio/FrequencyIn.c18
-rw-r--r--shared-bindings/gamepad/GamePad.c2
-rw-r--r--shared-bindings/gamepadshift/GamePadShift.c2
-rw-r--r--shared-bindings/help.c2
-rw-r--r--shared-bindings/i2cslave/I2CSlave.c4
-rw-r--r--shared-bindings/index.rst60
-rw-r--r--shared-bindings/microcontroller/Pin.c2
-rw-r--r--shared-bindings/microcontroller/RunMode.c14
-rw-r--r--shared-bindings/microcontroller/__init__.c16
-rw-r--r--shared-bindings/neopixel_write/__init__.c4
-rw-r--r--shared-bindings/network/__init__.c2
-rw-r--r--shared-bindings/ps2io/Ps2.c243
-rw-r--r--shared-bindings/ps2io/Ps2.h45
-rw-r--r--shared-bindings/ps2io/__init__.c73
-rw-r--r--shared-bindings/ps2io/__init__.h35
-rw-r--r--shared-bindings/pulseio/PWMOut.c16
-rw-r--r--shared-bindings/pulseio/PulseIn.c24
-rw-r--r--shared-bindings/pulseio/PulseOut.c4
-rw-r--r--shared-bindings/pulseio/__init__.c4
-rw-r--r--shared-bindings/rotaryio/IncrementalEncoder.c10
-rw-r--r--shared-bindings/socket/__init__.c15
-rw-r--r--shared-bindings/storage/__init__.c6
-rw-r--r--shared-bindings/struct/__init__.c8
-rw-r--r--shared-bindings/support_matrix.rst16
-rw-r--r--shared-bindings/time/__init__.c33
-rw-r--r--shared-bindings/touchio/TouchIn.c14
-rw-r--r--shared-bindings/uheap/__init__.c2
-rw-r--r--shared-bindings/ustack/__init__.c6
-rw-r--r--shared-bindings/util.c8
-rw-r--r--shared-bindings/util.h2
-rw-r--r--shared-bindings/wiznet/wiznet5k.c2
-rw-r--r--shared-module/_stage/__init__.c37
-rw-r--r--shared-module/_stage/__init__.h2
-rw-r--r--shared-module/audiocore/Mixer.c (renamed from shared-module/audioio/Mixer.c)6
-rw-r--r--shared-module/audiocore/Mixer.h (renamed from shared-module/audioio/Mixer.h)2
-rw-r--r--shared-module/audiocore/RawSample.c (renamed from shared-module/audioio/RawSample.c)4
-rw-r--r--shared-module/audiocore/RawSample.h (renamed from shared-module/audioio/RawSample.h)2
-rw-r--r--shared-module/audiocore/WaveFile.c (renamed from shared-module/audioio/WaveFile.c)4
-rw-r--r--shared-module/audiocore/WaveFile.h (renamed from shared-module/audioio/WaveFile.h)5
-rw-r--r--shared-module/audiocore/__init__.c125
-rw-r--r--shared-module/audiocore/__init__.h53
-rw-r--r--shared-module/audioio/__init__.c125
-rw-r--r--shared-module/audioio/__init__.h23
-rw-r--r--shared-module/audiopwmio/__init__.c0
-rw-r--r--shared-module/audiopwmio/__init__.h32
-rw-r--r--shared-module/bleio/Address.c45
-rw-r--r--shared-module/bleio/Address.h9
-rw-r--r--shared-module/bleio/AdvertisementData.h85
-rw-r--r--shared-module/bleio/Characteristic.h3
-rw-r--r--shared-module/bleio/ScanEntry.c (renamed from shared-bindings/bleio/Broadcaster.h)23
-rw-r--r--shared-module/bleio/ScanEntry.h6
-rw-r--r--shared-module/board/__init__.c14
-rw-r--r--shared-module/displayio/Bitmap.c38
-rw-r--r--shared-module/displayio/Bitmap.h5
-rw-r--r--shared-module/displayio/ColorConverter.c35
-rw-r--r--shared-module/displayio/ColorConverter.h4
-rw-r--r--shared-module/displayio/Display.c277
-rw-r--r--shared-module/displayio/Display.h40
-rw-r--r--shared-module/displayio/FourWire.c26
-rw-r--r--shared-module/displayio/FourWire.h6
-rw-r--r--shared-module/displayio/Group.c243
-rw-r--r--shared-module/displayio/Group.h15
-rw-r--r--shared-module/displayio/I2CDisplay.c105
-rw-r--r--shared-module/displayio/I2CDisplay.h41
-rw-r--r--shared-module/displayio/Palette.c50
-rw-r--r--shared-module/displayio/Palette.h23
-rw-r--r--shared-module/displayio/TileGrid.c445
-rw-r--r--shared-module/displayio/TileGrid.h41
-rw-r--r--shared-module/displayio/__init__.c422
-rw-r--r--shared-module/displayio/__init__.h9
-rw-r--r--shared-module/displayio/area.h73
-rw-r--r--shared-module/terminalio/Terminal.c2
-rw-r--r--shared-module/usb_hid/Device.c10
-rw-r--r--shared-module/usb_midi/PortOut.c2
-rw-r--r--supervisor/shared/display.c78
-rw-r--r--supervisor/shared/display.h3
-rw-r--r--supervisor/shared/filesystem.c3
-rw-r--r--supervisor/shared/rgb_led_status.c125
-rw-r--r--supervisor/shared/status_leds.c2
-rw-r--r--supervisor/shared/usb/tusb_config.h2
-rw-r--r--supervisor/shared/usb/usb_desc.c42
-rw-r--r--supervisor/shared/usb/usb_msc_flash.c96
-rw-r--r--tests/basics/bigint_array_overflow.py (renamed from tests/basics/array_overflow.py)7
-rw-r--r--tests/basics/int_bytes.py2
-rw-r--r--tests/basics/smallint_array_overflow.py52
-rw-r--r--tests/import/mpy_invalid.py4
-rw-r--r--tests/import/mpy_invalid.py.exp6
-rw-r--r--tools/build_board_info.py3
-rwxr-xr-xtools/build_release_files.py37
-rw-r--r--tools/gen_display_resources.py39
-rwxr-xr-xtools/git-checkout-latest-tag.sh3
-rw-r--r--tools/travis_new_boards_check.py51
473 files changed, 22302 insertions, 5648 deletions
diff --git a/.gitignore b/.gitignore
index 69f71847b..3e5bd2830 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,8 @@
# Packages
############
+dist/
+*.egg-info
# Logs and Databases
######################
@@ -25,6 +27,7 @@
######################
build/
bin/
+circuitpython-stubs/
# Test failure outputs
######################
diff --git a/.gitmodules b/.gitmodules
index 163d45fcd..7b57cab54 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -95,3 +95,6 @@
[submodule "frozen/circuitpython-stage"]
path = frozen/circuitpython-stage
url = https://github.com/python-ugame/circuitpython-stage.git
+[submodule "ports/stm32f4/stm32f4"]
+ path = ports/stm32f4/stm32f4
+ url = https://github.com/adafruit/stm32f4.git
diff --git a/.travis.yml b/.travis.yml
index caa5378ab..4863b9542 100755
--- a/.travis.yml
+++ b/.travis.yml
@@ -21,11 +21,11 @@ git:
# 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 electronut_labs_papyr" 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 escornabot_makech" TRAVIS_SDK=arm
- - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300 arduino_mkrzero pewpew10 kicksat-sprite ugame10 robohatmm1" 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
+ - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="trinket_m0_haxpress circuitplayground_express mini_sam_m4 grandcentral_m4_express capablerobot_usbhub pygamer pca10056 pca10059 feather_nrf52840_express metro_nrf52840_express makerdiary_nrf52840_mdk makerdiary_nrf52840_mdk_usb_dongle particle_boron particle_argon particle_xenon sparkfun_nrf52840_mini electronut_labs_papyr electronut_labs_blip" TRAVIS_SDK=arm:nrf
+ - TRAVIS_BOARDS="metro_m0_express metro_m4_express metro_m4_airlift_lite pirkey_m0 trellis_m4_express trinket_m0 sparkfun_lumidrive sparkfun_redboard_turbo bast_pro_mini_m0 datum_distance pyruler" TRAVIS_SDK=arm
+ - TRAVIS_BOARDS="cp32-m4 feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow sam32 uchip escornabot_makech pygamer_advance datum_imu snekboard" TRAVIS_SDK=arm
+ - TRAVIS_BOARDS="feather_m0_supersized feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300 arduino_mkrzero pewpew10 kicksat-sprite ugame10 robohatmm1_m0 robohatmm1_m4 datum_light" TRAVIS_SDK=arm
+ - TRAVIS_BOARDS="datalore_ip_m4 circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express catwan_usbstick pyportal sparkfun_samd21_mini sparkfun_samd21_dev pybadge pybadge_airlift datum_weather" TRAVIS_SDK=arm
addons:
artifacts:
@@ -33,6 +33,16 @@ addons:
- $(ls -d1 bin/*/*/* | tr "\n" ":")
target_paths: /
+# Some deploy jobs take over 10 minutes so use this keep alive hack to make sure Travis doesn't kill us.
+before_deploy: |
+ function keep_alive() {
+ while true; do
+ echo -en "\a"
+ sleep 5
+ done
+ }
+ keep_alive &
+
deploy:
provider: releases
api_key:
@@ -61,7 +71,6 @@ before_script:
- 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
@@ -70,12 +79,16 @@ before_script:
# For coverage testing (upgrade is used to get latest urllib3 version)
- sudo apt-get install -y python3-pip
- - pip3 install --user sh click
+ - pip3 install --user sh click setuptools
- ([[ -z "$TRAVIS_TESTS" ]] || sudo pip install --upgrade cpp-coveralls)
- (! var_search "${TRAVIS_TESTS-}" docs || sudo apt-get install -y librsvg2-bin)
- - (! var_search "${TRAVIS_TESTS-}" docs || pip install --user Sphinx sphinx-rtd-theme recommonmark sphinxcontrib-svg2pdfconverter)
+ - (! var_search "${TRAVIS_TESTS-}" docs || pip3 install --user Sphinx sphinx-rtd-theme recommonmark sphinxcontrib-svg2pdfconverter)
- (! var_search "${TRAVIS_TESTS-}" translations || pip3 install --user polib)
+ # Check if there's any board missing in TRAVIS_BOARDS
+ - cd tools && python3 -u travis_new_boards_check.py
+ - cd ..
+
# report some good version numbers to the build
- gcc --version
- (! var_search "${TRAVIS_SDK-}" arm || arm-none-eabi-gcc --version)
diff --git a/Makefile b/Makefile
index 9b7a5a32c..b9c489fd4 100644
--- a/Makefile
+++ b/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/)
@@ -31,7 +38,7 @@ I18NSPHINXOPTS = $(BASEOPTS)
TRANSLATE_SOURCES = extmod lib main.c ports/atmel-samd ports/nrf py shared-bindings shared-module supervisor
-.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+.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" -print0 | (LC_ALL=C sort -z) | xargs -0 xgettext -L C -s --add-location=file --keyword=translate -o circuitpython.pot -p locale
translate: locale/circuitpython.pot
for po in $(shell ls locale/*.po); do msgmerge -U $$po -s --no-fuzzy-matching --add-location=file locale/circuitpython.pot; done
check-translate: locale/circuitpython.pot $(wildcard locale/*.po)
$(PYTHON) tools/check_translations.py $^
+
+stubs:
+ rst2pyi $(VALIDATE) shared-bindings/ $(STUBDIR)
+ python setup.py sdist
+
+update-frozen-libraries:
+ @echo "Updating all frozen libraries to latest tagged version."
+ cd frozen; for library in *; do cd $$library; ../../tools/git-checkout-latest-tag.sh; cd ..; done
diff --git a/README.rst b/README.rst
index 53ac4cbcd..f5f9cccea 100644
--- a/README.rst
+++ b/README.rst
@@ -115,8 +115,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.
@@ -131,9 +131,9 @@ Behavior
``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 is one of these: ``code.txt``, ``code.py``, ``main.py``,
``main.txt``
-- Boot is one of these: ``settings.txt``, ``settings.py``, **``boot.py``**,
+- Boot is one of these: ``settings.txt``, ``settings.py``, ``boot.py``,
``boot.txt``
API
diff --git a/conf.py b/conf.py
index 858657388..56625e758 100644
--- a/conf.py
+++ b/conf.py
@@ -13,6 +13,7 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
+import json
import sys
import os
@@ -24,8 +25,20 @@ from recommonmark.parser import CommonMarkParser
sys.path.insert(0, os.path.abspath('docs'))
sys.path.insert(0, os.path.abspath('.'))
+import shared_bindings_matrix
+
master_doc = 'docs/index'
+# Grab the JSON values to use while building the module support matrix
+# in 'shared-bindings/index.rst'
+
+#modules_support_matrix = shared_bindings_matrix.support_matrix_excluded_boards()
+modules_support_matrix = shared_bindings_matrix.support_matrix_by_board()
+
+html_context = {
+ 'support_matrix': modules_support_matrix
+}
+
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
@@ -40,7 +53,9 @@ extensions = [
'sphinxcontrib.rsvgconverter',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
- 'sphinx.ext.coverage'
+ 'sphinx.ext.coverage',
+ 'rstjinja',
+ 'c2rst'
]
# Add any paths that contain templates here, relative to this directory.
@@ -49,8 +64,7 @@ templates_path = ['templates']
# The suffix of source filenames.
source_suffix = ['.rst', '.md', '.c', '.h']
-source_parsers = {'.md': CommonMarkParser,
- '.c': "c2rst.CStrip", '.h': "c2rst.CStrip"}
+source_parsers = {'.md': CommonMarkParser}
# The encoding of source files.
#source_encoding = 'utf-8-sig'
@@ -84,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",
@@ -121,6 +136,10 @@ exclude_patterns = ["**/build*",
"ports/nrf/nrfx",
"ports/nrf/peripherals",
"ports/nrf/usb",
+ "ports/stm32f4/stm32f4",
+ "ports/stm32f4/peripherals",
+ "ports/stm32f4/ref",
+ "ports/stm32f4/README.md",
"ports/pic16bit",
"ports/qemu-arm",
"ports/stm32",
diff --git a/docs/c2rst.py b/docs/c2rst.py
index 904fb7408..76489dca3 100644
--- a/docs/c2rst.py
+++ b/docs/c2rst.py
@@ -1,19 +1,31 @@
-import sphinx.parsers
+def c2rst(app, docname, source):
+ """ Pre-parse '.c' & '.h' files that contain rST source.
+ """
+ # Make sure we're outputting HTML
+ if app.builder.format != 'html':
+ return
-class CStrip(sphinx.parsers.Parser):
- def __init__(self):
- self.rst_parser = sphinx.parsers.RSTParser()
+ fname = app.env.doc2path(docname)
+ if (not fname.endswith(".c") and
+ not fname.endswith(".h")):
+ #print("skipping:", fname)
+ return
- def parse(self, inputstring, document):
- # This setting is missing starting with Sphinx 1.7.1 so we set it ourself.
- document.settings.tab_width = 4
- document.settings.character_level_inline_markup = False
- stripped = []
- for line in inputstring.split("\n"):
- line = line.strip()
- if line == "//|":
- stripped.append("")
- elif line.startswith("//| "):
- stripped.append(line[len("//| "):])
- stripped = "\r\n".join(stripped)
- self.rst_parser.parse(stripped, document)
+ src = source[0]
+
+ stripped = []
+ for line in src.split("\n"):
+ line = line.strip()
+ if line == "//|":
+ stripped.append("")
+ elif line.startswith("//| "):
+ stripped.append(line[len("//| "):])
+ stripped = "\r\n".join(stripped)
+
+ rendered = app.builder.templates.render_string(
+ stripped, app.config.html_context
+ )
+ source[0] = rendered
+
+def setup(app):
+ app.connect("source-read", c2rst)
diff --git a/docs/design_guide.rst b/docs/design_guide.rst
index 2efbdc34c..5d965f907 100644
--- a/docs/design_guide.rst
+++ b/docs/design_guide.rst
@@ -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
diff --git a/docs/library/builtins.rst b/docs/library/builtins.rst
index 0061a8cea..6cbf95d53 100644
--- a/docs/library/builtins.rst
+++ b/docs/library/builtins.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
diff --git a/docs/library/network.rst b/docs/library/network.rst
index d25f9f388..cdcc5f323 100644
--- a/docs/library/network.rst
+++ b/docs/library/network.rst
@@ -5,6 +5,7 @@
.. include:: ../templates/unsupported_in_circuitpython.inc
.. module:: network
+ :noindex:
:synopsis: network configuration
This module provides network drivers and routing configuration. To use this
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 1835d8107..9edf6d328 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1 +1,3 @@
-sphinxcontrib-svg2pdfconverter
+sphinx==1.8.5
+recommonmark==0.5.0
+sphinxcontrib-svg2pdfconverter==0.1.0
diff --git a/docs/rstjinja.py b/docs/rstjinja.py
new file mode 100644
index 000000000..3a08b2599
--- /dev/null
+++ b/docs/rstjinja.py
@@ -0,0 +1,24 @@
+# Derived from code on Eric Holscher's blog, found at:
+# https://www.ericholscher.com/blog/2016/jul/25/integrating-jinja-rst-sphinx/
+
+def rstjinja(app, docname, source):
+ """
+ Render our pages as a jinja template for fancy templating goodness.
+ """
+ # Make sure we're outputting HTML
+ if app.builder.format != 'html':
+ return
+
+ # we only want our one jinja template to run through this func
+ if "shared-bindings/support_matrix" not in docname:
+ return
+
+ src = source[0]
+ print(docname)
+ rendered = app.builder.templates.render_string(
+ src, app.config.html_context
+ )
+ source[0] = rendered
+
+def setup(app):
+ app.connect("source-read", rstjinja)
diff --git a/docs/shared_bindings_matrix.py b/docs/shared_bindings_matrix.py
new file mode 100644
index 000000000..ed88efc75
--- /dev/null
+++ b/docs/shared_bindings_matrix.py
@@ -0,0 +1,244 @@
+# The MIT License (MIT)
+#
+# Copyright (c) 2019 Michael Schroeder
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+import json
+import os
+import re
+
+
+SUPPORTED_PORTS = ["atmel-samd", "nrf"]
+
+
+def parse_port_config(contents, chip_keyword=None):
+ """ Compile a dictionary of port-wide module configs, which may
+ be categorized by chipset.
+ """
+ chip_fam = "all"
+ ifeq_found = False
+ port_config_results = {"all": []}
+
+ chip_pattern = ""
+ if chip_keyword:
+ chip_pattern = (
+ re.compile("(?<=ifeq\s\(\$\({}\)\,)(\w+)".format(chip_keyword))
+ )
+
+ for line in contents:
+ if chip_keyword:
+ if not ifeq_found:
+ check_ifeq = chip_pattern.search(line)
+ if check_ifeq:
+ ifeq_found = True
+ chip_fam = check_ifeq.group(1)
+ #print("found chip:", chip_fam)
+ else:
+ ifeq_found = False
+ chip_fam = "all"
+ else:
+ if "endif" in line:
+ ifeq_found = False
+ chip_fam = "all"
+
+ if "CIRCUITPY_" in line:
+ if chip_fam in port_config_results:
+ port_config_results[chip_fam].append(line.rstrip("\n"))
+ else:
+ port_config_results[chip_fam] = [line.rstrip("\n")]
+
+ #print(port_config_results)
+ return port_config_results
+
+def get_shared_bindings():
+ """ Get a list of modules in shared-bindings based on folder names
+ """
+ return [item for item in os.listdir("./shared-bindings")]
+
+
+def read_mpconfig():
+ """ Open 'circuitpy_mpconfig.mk' and return the contents.
+ """
+ configs = []
+ with open("py/circuitpy_mpconfig.mk") as mpconfig:
+ configs = mpconfig.read()
+
+ return configs
+
+
+def build_module_map():
+ """ Establish the base of the JSON file, based on the contents from
+ `configs`. Base will contain module names, if they're part of
+ the `FULL_BUILD`, or their default value (0 | 1).
+
+ """
+ base = dict()
+ modules = get_shared_bindings()
+ configs = read_mpconfig()
+ full_build = False
+ for module in modules:
+ full_name = module
+ search_name = module.lstrip("_")
+ re_pattern = "CIRCUITPY_{}\s=\s(.+)".format(search_name.upper())
+ find_config = re.search(re_pattern, configs)
+ #print(module, "|", find_config)
+ if not find_config:
+ continue
+ full_build = int("FULL_BUILD" in find_config.group(0))
+ #print(find_config[1])
+ if not full_build:
+ default_val = find_config.group(1)
+ else:
+ default_val = "None"
+ base[search_name] = {
+ "name": full_name,
+ "full_build": str(full_build),
+ "default_value": default_val,
+ "excluded": {}
+ }
+
+ return base
+
+
+def get_excluded_boards(base):
+ """ Cycles through each board's `mpconfigboard.mk` file to determine
+ if each module is included or not. Boards are selected by existence
+ in a port listed in `SUPPORTED_PORTS` (e.g. `/port/nrf/feather_52840`)
+
+ Boards are further categorized by their respective chipset (SAMD21,
+ SAMD51, nRF52840, etc.)
+ """
+ modules = list(base.keys())
+
+ re_board_chip = None
+ chip_keyword = None
+ for port in SUPPORTED_PORTS:
+ # each port appears to use its own define for the chipset
+ if port in ["atmel-samd"]:
+ re_board_chip = re.compile("CHIP_FAMILY\s=\s(\w+)")
+ chip_keyword = "CHIP_FAMILY"
+ elif port in ["nrf"]:
+ re_board_chip = re.compile("MCU_VARIANT\s=\s(\w+)")
+
+ port_dir = "ports/{}".format(port)
+
+ port_config_contents = ""
+ with open(os.path.join(port_dir, "mpconfigport.mk")) as port_config:
+ port_config_contents = port_config.readlines()
+ port_config = parse_port_config(port_config_contents, chip_keyword)
+
+ for entry in os.scandir(os.path.join(port_dir, "boards")):
+ if not entry.is_dir():
+ continue
+
+ contents = ""
+ board_dir = os.path.join(entry.path, "mpconfigboard.mk")
+ with open(board_dir) as board:
+ contents = board.read()
+
+ board_chip = re_board_chip.search(contents)
+ #print(entry.name, board_chip.group(1))
+ if not board_chip:
+ board_chip = "Unknown Chip"
+ else:
+ board_chip = board_chip.group(1)
+
+ # add port_config results to contents
+ contents += "\n" + "\n".join(port_config["all"])
+ if board_chip in port_config:
+ contents += "\n" + "\n".join(port_config[board_chip])
+
+ for module in modules:
+ board_is_excluded = False
+ # check if board uses `SMALL_BUILD`. if yes, and current
+ # module is marked as `FULL_BUILD`, board is excluded
+ small_build = re.search("CIRCUITPY_SMALL_BUILD = 1", contents)
+ if small_build and base[module]["full_build"] == "1":
+ board_is_excluded = True
+ # check if module is specifically disabled for this board
+ re_pattern = "CIRCUITPY_{}\s=\s(\w)".format(module.upper())
+ find_module = re.search(re_pattern, contents)
+ if not find_module:
+ # check if default inclusion is off ('0'). if the board doesn't
+ # have it explicitly enabled, its excluded.
+ if base[module]["default_value"] == "0":
+ board_is_excluded = True
+ else:
+ if (find_module.group(1) == "0" and
+ find_module.group(1) != base[module]["default_value"]):
+ board_is_excluded = True
+
+ if board_is_excluded:
+ if board_chip in base[module]["excluded"]:
+ base[module]["excluded"][board_chip].append(entry.name)
+ else:
+ base[module]["excluded"][board_chip] = [entry.name]
+ #print(json.dumps(base, indent=2))
+ return base
+
+
+def support_matrix_excluded_boards():
+ """ Compiles a list of available modules, and which board definitions
+ do not include them.
+ """
+ base = build_module_map()
+
+ return get_excluded_boards(base)
+
+def support_matrix_by_board():
+ """ Compiles a list of the available core modules available for each
+ board.
+ """
+ base = build_module_map()
+ base_with_exclusions = get_excluded_boards(base)
+
+ boards = dict()
+ for port in SUPPORTED_PORTS:
+ port_dir = "ports/{}/boards".format(port)
+ for entry in os.scandir(port_dir):
+ if not entry.is_dir():
+ continue
+ board_modules = []
+
+ board_name = entry.name
+ board_contents = ""
+ with open(os.path.join(entry.path, "mpconfigboard.h")) as get_name:
+ board_contents = get_name.read()
+ board_name_re = re.search("(?<=MICROPY_HW_BOARD_NAME)\s+(.+)",
+ board_contents)
+ if board_name_re:
+ board_name = board_name_re.group(1).strip('"')
+
+ for module in base_with_exclusions.keys():
+ #print(module)
+ board_has_module = True
+ if base_with_exclusions[module]["excluded"]:
+ for port in base_with_exclusions[module]["excluded"].values():
+ #print(port)
+ if entry.name in port:
+ board_has_module = False
+
+ if board_has_module:
+ board_modules.append(base_with_exclusions[module]["name"])
+ boards[board_name] = sorted(board_modules)
+
+ #print(json.dumps(boards, indent=2))
+ return boards
diff --git a/frozen/Adafruit_CircuitPython_BusDevice b/frozen/Adafruit_CircuitPython_BusDevice
-Subproject 6b3402965999d068316882d63fae3ab26006477
+Subproject b9280af5142fc41639229544678e23b5cca07c3
diff --git a/frozen/Adafruit_CircuitPython_CircuitPlayground b/frozen/Adafruit_CircuitPython_CircuitPlayground
-Subproject 1d38fd81edd30f1bd70c0cfe77819ab610ea89a
+Subproject 154b74de020764597ba49f0d1e8cc18d55b3643
diff --git a/frozen/Adafruit_CircuitPython_Crickit b/frozen/Adafruit_CircuitPython_Crickit
-Subproject a1686803566793ec2de7e043bf6822e47cfa31d
+Subproject 617bb0787f2c61283d248632a62b27be80f64b2
diff --git a/frozen/Adafruit_CircuitPython_HID b/frozen/Adafruit_CircuitPython_HID
-Subproject 836bb9843fd793683061c15150944f8897d806e
+Subproject 89faee0eb08a6855e14f117c514fecf2dd90769
diff --git a/frozen/Adafruit_CircuitPython_IRRemote b/frozen/Adafruit_CircuitPython_IRRemote
-Subproject aa4428f304b982aa19a5800822e78c47dc8a3b6
+Subproject 70865ac6e09f821b26ec727e2df300a6d9ebf6b
diff --git a/frozen/Adafruit_CircuitPython_LIS3DH b/frozen/Adafruit_CircuitPython_LIS3DH
-Subproject a03f9011279f9e630549432589463912831fcee
+Subproject bd7ddc67dc86f7ad0115f58ab80d5605739c648
diff --git a/frozen/Adafruit_CircuitPython_Motor b/frozen/Adafruit_CircuitPython_Motor
-Subproject 98563ab65800aac6464f671c0d005df56ecaa6c
+Subproject ddc74844983b35b027bd45091c7b8bb3c8d7a2d
diff --git a/frozen/Adafruit_CircuitPython_NeoPixel b/frozen/Adafruit_CircuitPython_NeoPixel
-Subproject c0ed34813a608b64ed044826553918ddbad12f0
+Subproject c0bdd8b10383725ee9293f5d88fb8d47eb1272b
diff --git a/frozen/Adafruit_CircuitPython_seesaw b/frozen/Adafruit_CircuitPython_seesaw
-Subproject 1d12cfc0b729b4ae0a2f3f4e7c1933a0fbd3b16
+Subproject f1171f94083ba64d153ff3f90eeb07500331d6e
diff --git a/frozen/circuitpython-stage b/frozen/circuitpython-stage
-Subproject 340bd688e4a9684c557e65236f203049d56a421
+Subproject 0d2d660e886de8a1b96778c865c7fa48df5f4ea
diff --git a/lib/tinyusb b/lib/tinyusb
-Subproject 0848c462b3e431a9da42e96537d2b597a457963
+Subproject 1ee9ef4f2b7c6acfab6c398a4f57ca22036958f
diff --git a/lib/utils/printf.c b/lib/utils/printf.c
index e19da2dc0..3a4cc2549 100644
--- a/lib/utils/printf.c
+++ b/lib/utils/printf.c
@@ -103,9 +103,11 @@ STATIC void strn_print_strn(void *data, const char *str, size_t len) {
strn_print_env->remain -= len;
}
-#if defined(__GNUC__) && !defined(__clang__)
+#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 9
// uClibc requires this alias to be defined, or there may be link errors
// when linkings against it statically.
+// GCC 9 gives a warning about missing attributes so it's excluded until
+// uClibc+GCC9 support is needed.
int __GI_vsnprintf(char *str, size_t size, const char *fmt, va_list ap) __attribute__((weak, alias ("vsnprintf")));
#endif
diff --git a/locale/ID.po b/locale/ID.po
index 551c253c7..e8fdf3595 100644
--- a/locale/ID.po
+++ b/locale/ID.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-05-09 01:06-0400\n"
+"POT-Creation-Date: 2019-08-05 17:52-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -52,8 +52,8 @@ msgstr ""
msgid "%q indices must be integers, not %s"
msgstr ""
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
#, fuzzy
msgid "%q must be >= 1"
msgstr "buffers harus mempunyai panjang yang sama"
@@ -219,15 +219,14 @@ msgid "A hardware interrupt channel is already in use"
msgstr "Sebuah channel hardware interrupt sedang digunakan"
#: shared-bindings/bleio/Address.c
-#, c-format
-msgid "Address is not %d bytes long or is in wrong format"
-msgstr ""
-
-#: shared-bindings/bleio/Address.c
#, fuzzy, c-format
msgid "Address must be %d bytes long"
msgstr "buffers harus mempunyai panjang yang sama"
+#: shared-bindings/bleio/Address.c
+msgid "Address type out of range"
+msgstr ""
+
#: ports/nrf/common-hal/busio/I2C.c
msgid "All I2C peripherals are in use"
msgstr "Semua perangkat I2C sedang digunakan"
@@ -253,9 +252,10 @@ msgstr "Semua channel event yang disinkronisasi sedang digunakan"
msgid "All timers for this pin are in use"
msgstr "Semua timer untuk pin ini sedang digunakan"
-#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c
#: shared-module/_pew/PewPew.c
msgid "All timers in use"
@@ -313,6 +313,10 @@ msgstr ""
msgid "Both pins must support hardware interrupts"
msgstr "Kedua pin harus mendukung hardware interrut"
+#: shared-bindings/displayio/Display.c
+msgid "Brightness must be 0-1.0"
+msgstr ""
+
#: shared-bindings/supervisor/__init__.c
msgid "Brightness must be between 0 and 255"
msgstr ""
@@ -326,6 +330,11 @@ msgstr ""
msgid "Buffer incorrect size. Should be %d bytes."
msgstr ""
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
+#, c-format
+msgid "Buffer length %d too big. It must be less than %d"
+msgstr ""
+
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
msgstr ""
@@ -345,25 +354,17 @@ msgstr "buffers harus mempunyai panjang yang sama"
msgid "Bytes must be between 0 and 255."
msgstr ""
+#: py/objtype.c
+msgid "Call super().__init__() before accessing native object."
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Can not use dotstar with %s"
msgstr ""
-#: shared-bindings/bleio/Device.c
-msgid "Can't add services in Central mode"
-msgstr ""
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't advertise in Central mode"
-msgstr ""
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't change the name in Central mode"
-msgstr ""
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't connect in Peripheral mode"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Can't set CCCD for local Characteristic"
msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
@@ -452,10 +453,22 @@ msgstr "Clock unit sedang digunakan"
msgid "Column entry must be digitalio.DigitalInOut"
msgstr ""
+#: shared-bindings/displayio/I2CDisplay.c
+msgid "Command must be 0-255"
+msgstr ""
+
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
msgid "Command must be an int between 0 and 255"
msgstr ""
+#: py/persistentcode.c
+msgid "Corrupt .mpy file"
+msgstr ""
+
+#: py/emitglue.c
+msgid "Corrupt raw code"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/UUID.c
#, c-format
msgid "Could not decode ble_uuid, err 0x%04x"
@@ -465,11 +478,11 @@ msgstr ""
msgid "Could not initialize UART"
msgstr "Tidak dapat menginisialisasi UART"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate first buffer"
msgstr ""
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate second buffer"
msgstr ""
@@ -486,21 +499,15 @@ msgstr "DAC sudah digunakan"
msgid "Data 0 pin must be byte aligned"
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Data chunk must follow fmt chunk"
msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy
msgid "Data too large for advertisement packet"
msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Data too large for the advertisement packet"
-msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment"
-
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr ""
@@ -514,6 +521,7 @@ msgid "Drive mode not used when direction is input."
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "EXTINT channel already in use"
msgstr "Channel EXTINT sedang digunakan"
@@ -537,17 +545,20 @@ msgstr ""
msgid "Expected a UUID"
msgstr ""
+#: shared-bindings/bleio/Central.c
+msgid "Expected an Address"
+msgstr ""
+
#: shared-module/_pixelbuf/PixelBuf.c
#, c-format
msgid "Expected tuple of length %d, got %d"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to acquire mutex"
-msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Failed sending command."
+msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, fuzzy, c-format
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX"
@@ -557,11 +568,6 @@ msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX"
msgid "Failed to add characteristic, err 0x%04x"
msgstr "Gagal untuk menambahkan karakteristik, status: 0x%08lX"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to add service"
-msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX"
-
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy, c-format
msgid "Failed to add service, err 0x%04x"
@@ -582,27 +588,21 @@ msgstr "Gagal untuk megalokasikan buffer RX dari %d byte"
msgid "Failed to change softdevice state"
msgstr "Gagal untuk merubah status softdevice, error: 0x%08lX"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to connect:"
-msgstr "Gagal untuk menyambungkan, status: 0x%08lX"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to configure advertising, err 0x%04x"
+msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to continue scanning"
-msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX"
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "Failed to connect: timeout"
+msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
#, fuzzy, c-format
msgid "Failed to continue scanning, err 0x%04x"
msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to create mutex"
-msgstr "Gagal untuk membuat mutex, status: 0x%08lX"
-
-#: ports/nrf/common-hal/bleio/Device.c
+#: ports/nrf/common-hal/bleio/Central.c
#, fuzzy
msgid "Failed to discover services"
msgstr "Gagal untuk menemukan layanan, status: 0x%08lX"
@@ -642,49 +642,42 @@ msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX"
msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
msgstr "Gagal untuk menambahkan Vendor Spesific UUID, status: 0x%08lX"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to release mutex"
-msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX"
-
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, fuzzy, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to start advertising"
-msgstr "Gagal untuk memulai advertisement, status: 0x%08lX"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to set device name, err 0x%04x"
+msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy, c-format
msgid "Failed to start advertising, err 0x%04x"
msgstr "Gagal untuk memulai advertisement, status: 0x%08lX"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to start scanning"
-msgstr "Gagal untuk melakukan scanning, status: 0x%08lX"
+#: ports/nrf/common-hal/bleio/Central.c
+#, c-format
+msgid "Failed to start connecting, error 0x%04x"
+msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
#, fuzzy, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "Gagal untuk melakukan scanning, status: 0x%08lX"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to stop advertising"
-msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX"
-
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy, c-format
msgid "Failed to stop advertising, err 0x%04x"
msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX"
#: ports/nrf/common-hal/bleio/Characteristic.c
+#, c-format
+msgid "Failed to write CCCD, err 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
#, fuzzy, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "Gagal untuk menulis nilai atribut, status: 0x%08lX"
@@ -725,6 +718,10 @@ msgstr ""
msgid "Function requires lock"
msgstr ""
+#: shared-bindings/displayio/Display.c
+msgid "Group already used"
+msgstr ""
+
#: shared-module/displayio/Group.c
msgid "Group full"
msgstr ""
@@ -751,8 +748,8 @@ msgstr ""
msgid "Input/output error"
msgstr ""
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
msgstr "%q pada tidak valid"
@@ -781,7 +778,7 @@ msgstr "Ukuran buffer tidak valid"
msgid "Invalid capture period. Valid range: 1 - 500"
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid channel count"
msgstr ""
@@ -789,11 +786,11 @@ msgstr ""
msgid "Invalid direction."
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid file"
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid format chunk size"
msgstr ""
@@ -835,11 +832,11 @@ msgstr ""
msgid "Invalid run mode."
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid wave file"
msgstr ""
@@ -848,6 +845,10 @@ msgid "LHS of keyword arg must be an id"
msgstr "LHS dari keyword arg harus menjadi sebuah id"
#: shared-module/displayio/Group.c
+msgid "Layer already in a group."
+msgstr ""
+
+#: shared-module/displayio/Group.c
msgid "Layer must be a Group or TileGrid subclass."
msgstr ""
@@ -891,8 +892,12 @@ msgstr ""
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr ""
-#: shared-bindings/displayio/Display.c
-msgid "Must be a Group subclass."
+#: shared-bindings/displayio/Group.c
+msgid "Must be a %q subclass."
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "No CCCD for this Characteristic"
msgstr ""
#: ports/atmel-samd/common-hal/analogio/AnalogOut.c
@@ -928,6 +933,10 @@ msgstr "Tidak ada GCLK yang kosong"
msgid "No hardware random available"
msgstr ""
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
+msgid "No hardware support on clk pin"
+msgstr ""
+
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "No hardware support on pin"
@@ -941,12 +950,14 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
+#: ports/nrf/common-hal/bleio/Characteristic.c
#: shared-bindings/bleio/CharacteristicBuffer.c
#, fuzzy
msgid "Not connected"
msgstr "Tidak dapat menyambungkan ke AP"
#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c
+#: shared-bindings/audiopwmio/PWMAudioOut.c
msgid "Not playing"
msgstr ""
@@ -1011,6 +1022,10 @@ msgstr ""
msgid "Plus any modules on the filesystem\n"
msgstr "Tambahkan module apapun pada filesystem\n"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Pop from an empty Ps2 buffer"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1067,17 +1082,18 @@ msgstr ""
msgid "SDA or SCL needs a pull up"
msgstr "SDA atau SCL membutuhkan pull up"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Sample rate must be positive"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#, c-format
msgid "Sample rate too high. It must be less than %d"
msgstr "Nilai sampel terlalu tinggi. Nilai harus kurang dari %d"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
msgstr "Serializer sedang digunakan"
@@ -1139,19 +1155,19 @@ msgid ""
"exit safe mode.\n"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's bits_per_sample does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's channel count does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's sample rate does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's signedness does not match the mixer's"
msgstr ""
@@ -1160,7 +1176,11 @@ msgid "Tile height must exactly divide bitmap height"
msgstr ""
#: shared-bindings/displayio/TileGrid.c
-msgid "Tile indices must be 0 - 255"
+msgid "Tile index out of bounds"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
+msgid "Tile value out of bounds"
msgstr ""
#: shared-bindings/displayio/TileGrid.c
@@ -1175,7 +1195,8 @@ msgstr "Untuk keluar, silahkan reset board tanpa "
msgid "Too many channels in sample."
msgstr "Terlalu banyak channel dalam sampel"
-#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
+#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
+#: shared-bindings/displayio/ParallelBus.c
msgid "Too many display busses"
msgstr ""
@@ -1200,7 +1221,7 @@ msgid "USB Error"
msgstr ""
#: shared-bindings/bleio/UUID.c
-msgid "UUID integer value not in range 0 to 0xffff"
+msgid "UUID integer value must be 0-0xffff"
msgstr ""
#: shared-bindings/bleio/UUID.c
@@ -1216,8 +1237,13 @@ msgstr ""
msgid "Unable to allocate buffers for signed conversion"
msgstr "Tidak dapat mengalokasikan buffer untuk signed conversion"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+#: shared-module/displayio/I2CDisplay.c
+#, c-format
+msgid "Unable to find I2C Display at %x"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Unable to find free GCLK"
msgstr "Tidak dapat menemukan GCLK yang kosong"
@@ -1251,7 +1277,7 @@ msgstr "Baudrate tidak didukung"
msgid "Unsupported display bus type"
msgstr "Baudrate tidak didukung"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Unsupported format"
msgstr ""
@@ -1267,7 +1293,7 @@ msgstr ""
msgid "Viper functions don't currently support more than 4 arguments"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "Voice index too high"
msgstr ""
@@ -1394,7 +1420,7 @@ msgstr ""
msgid "bits must be 8"
msgstr "bits harus memilki nilai 8"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "bits_per_sample must be 8 or 16"
msgstr ""
@@ -1407,7 +1433,7 @@ msgstr ""
msgid "buf is too small. need %d bytes"
msgstr ""
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr ""
@@ -1709,7 +1735,7 @@ msgstr ""
msgid "empty"
msgstr ""
-#: extmod/modutimeq.c extmod/moduheapq.c
+#: extmod/moduheapq.c extmod/modutimeq.c
msgid "empty heap"
msgstr "heap kosong"
@@ -1770,7 +1796,8 @@ msgstr "argumen keyword ekstra telah diberikan"
msgid "extra positional arguments given"
msgstr "argumen posisi ekstra telah diberikan"
-#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c
+#: shared-bindings/audiocore/WaveFile.c
+#: shared-bindings/displayio/OnDiskBitmap.c
msgid "file must be a file opened in byte mode"
msgstr ""
@@ -1899,8 +1926,9 @@ msgstr ""
msgid "integer required"
msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
-msgid "interval not in range 0.0020 to 10.24"
+#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c
+#, c-format
+msgid "interval must be in range %s-%s"
msgstr ""
#: extmod/machine_i2c.c
@@ -2115,6 +2143,14 @@ msgstr "tidak ada modul yang bernama '%q'"
msgid "no such attribute"
msgstr ""
+#: shared-bindings/bleio/Peripheral.c
+msgid "non-Service found in services"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "non-UUID found in service_uuids"
+msgstr ""
+
#: py/compile.c
msgid "non-default argument follows default argument"
msgstr "argumen non-default mengikuti argumen standar(default)"
@@ -2172,7 +2208,7 @@ msgstr ""
msgid "object not callable"
msgstr ""
-#: py/sequence.c
+#: py/sequence.c shared-bindings/displayio/Group.c
msgid "object not in sequence"
msgstr ""
@@ -2306,7 +2342,7 @@ msgstr ""
msgid "rsplit(None,n)"
msgstr ""
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid ""
"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or "
"'B'"
@@ -2324,10 +2360,6 @@ msgstr ""
msgid "script compilation not supported"
msgstr "kompilasi script tidak didukung"
-#: shared-bindings/bleio/Peripheral.c
-msgid "services includes an object that is not a Service"
-msgstr ""
-
#: py/objstr.c
msgid "sign not allowed in string format specifier"
msgstr ""
@@ -2425,10 +2457,6 @@ msgstr "sintaksis error pada pendeskripsi uctypes"
msgid "threshold must be in the range 0-65536"
msgstr ""
-#: shared-bindings/displayio/TileGrid.c
-msgid "tile index out of bounds"
-msgstr ""
-
#: shared-bindings/time/__init__.c
msgid "time.struct_time() takes a 9-sequence"
msgstr ""
@@ -2588,13 +2616,17 @@ msgstr ""
#: py/objint.c
#, c-format
-msgid "value would overflow a %d byte buffer"
+msgid "value must fit in %d byte(s)"
msgstr ""
#: shared-bindings/displayio/Bitmap.c
msgid "value_count must be > 0"
msgstr ""
+#: shared-bindings/bleio/Scanner.c
+msgid "window must be <= interval"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "write_args must be a list, tuple, or None"
msgstr ""
@@ -2641,6 +2673,10 @@ msgstr ""
#~ msgid "Cannot update i/f status"
#~ msgstr "Tidak dapat memperbarui status i/f"
+#, fuzzy
+#~ msgid "Data too large for the advertisement packet"
+#~ msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment"
+
#~ msgid "Don't know how to pass object to native function"
#~ msgstr "Tidak tahu cara meloloskan objek ke fungsi native"
@@ -2654,6 +2690,26 @@ msgstr ""
#~ msgstr "Errod pada ffi_prep_cif"
#, fuzzy
+#~ msgid "Failed to acquire mutex"
+#~ msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to add service"
+#~ msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to connect:"
+#~ msgstr "Gagal untuk menyambungkan, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to continue scanning"
+#~ msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to create mutex"
+#~ msgstr "Gagal untuk membuat mutex, status: 0x%08lX"
+
+#, fuzzy
#~ msgid "Failed to notify or indicate attribute value, err %0x04x"
#~ msgstr "Gagal untuk melaporkan nilai atribut, status: 0x%08lX"
@@ -2661,6 +2717,22 @@ msgstr ""
#~ msgid "Failed to read attribute value, err %0x04x"
#~ msgstr "Gagal untuk membaca nilai atribut, status: 0x%08lX"
+#, fuzzy
+#~ msgid "Failed to release mutex"
+#~ msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to start advertising"
+#~ msgstr "Gagal untuk memulai advertisement, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to start scanning"
+#~ msgstr "Gagal untuk melakukan scanning, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to stop advertising"
+#~ msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX"
+
#~ msgid "GPIO16 does not support pull up."
#~ msgstr "GPIO16 tidak mendukung pull up"
diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot
index 758ee841e..a2e66cc5d 100644
--- a/locale/circuitpython.pot
+++ b/locale/circuitpython.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-05-10 10:09-0700\n"
+"POT-Creation-Date: 2019-08-05 17:52-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -219,12 +219,11 @@ msgstr ""
#: shared-bindings/bleio/Address.c
#, c-format
-msgid "Address is not %d bytes long or is in wrong format"
+msgid "Address must be %d bytes long"
msgstr ""
#: shared-bindings/bleio/Address.c
-#, c-format
-msgid "Address must be %d bytes long"
+msgid "Address type out of range"
msgstr ""
#: ports/nrf/common-hal/busio/I2C.c
@@ -254,6 +253,7 @@ msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c
#: shared-module/_pew/PewPew.c
msgid "All timers in use"
@@ -309,6 +309,10 @@ msgstr ""
msgid "Both pins must support hardware interrupts"
msgstr ""
+#: shared-bindings/displayio/Display.c
+msgid "Brightness must be 0-1.0"
+msgstr ""
+
#: shared-bindings/supervisor/__init__.c
msgid "Brightness must be between 0 and 255"
msgstr ""
@@ -322,6 +326,11 @@ msgstr ""
msgid "Buffer incorrect size. Should be %d bytes."
msgstr ""
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
+#, c-format
+msgid "Buffer length %d too big. It must be less than %d"
+msgstr ""
+
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
msgstr ""
@@ -340,25 +349,17 @@ msgstr ""
msgid "Bytes must be between 0 and 255."
msgstr ""
+#: py/objtype.c
+msgid "Call super().__init__() before accessing native object."
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Can not use dotstar with %s"
msgstr ""
-#: shared-bindings/bleio/Device.c
-msgid "Can't add services in Central mode"
-msgstr ""
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't advertise in Central mode"
-msgstr ""
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't change the name in Central mode"
-msgstr ""
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't connect in Peripheral mode"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Can't set CCCD for local Characteristic"
msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
@@ -442,10 +443,22 @@ msgstr ""
msgid "Column entry must be digitalio.DigitalInOut"
msgstr ""
+#: shared-bindings/displayio/I2CDisplay.c
+msgid "Command must be 0-255"
+msgstr ""
+
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
msgid "Command must be an int between 0 and 255"
msgstr ""
+#: py/persistentcode.c
+msgid "Corrupt .mpy file"
+msgstr ""
+
+#: py/emitglue.c
+msgid "Corrupt raw code"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/UUID.c
#, c-format
msgid "Could not decode ble_uuid, err 0x%04x"
@@ -455,11 +468,11 @@ msgstr ""
msgid "Could not initialize UART"
msgstr ""
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate first buffer"
msgstr ""
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate second buffer"
msgstr ""
@@ -476,19 +489,14 @@ msgstr ""
msgid "Data 0 pin must be byte aligned"
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Data chunk must follow fmt chunk"
msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
msgid "Data too large for advertisement packet"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Data too large for the advertisement packet"
-msgstr ""
-
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr ""
@@ -502,6 +510,7 @@ msgid "Drive mode not used when direction is input."
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "EXTINT channel already in use"
msgstr ""
@@ -525,16 +534,20 @@ msgstr ""
msgid "Expected a UUID"
msgstr ""
+#: shared-bindings/bleio/Central.c
+msgid "Expected an Address"
+msgstr ""
+
#: shared-module/_pixelbuf/PixelBuf.c
#, c-format
msgid "Expected tuple of length %d, got %d"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to acquire mutex"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Failed sending command."
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, c-format
msgid "Failed to acquire mutex, err 0x%04x"
msgstr ""
@@ -544,10 +557,6 @@ msgstr ""
msgid "Failed to add characteristic, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to add service"
-msgstr ""
-
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to add service, err 0x%04x"
@@ -567,12 +576,13 @@ msgstr ""
msgid "Failed to change softdevice state"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to connect:"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to configure advertising, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to continue scanning"
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "Failed to connect: timeout"
msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
@@ -580,11 +590,7 @@ msgstr ""
msgid "Failed to continue scanning, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to create mutex"
-msgstr ""
-
-#: ports/nrf/common-hal/bleio/Device.c
+#: ports/nrf/common-hal/bleio/Central.c
msgid "Failed to discover services"
msgstr ""
@@ -621,27 +627,24 @@ msgstr ""
msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to release mutex"
-msgstr ""
-
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to start advertising"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to set device name, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to start advertising, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to start scanning"
+#: ports/nrf/common-hal/bleio/Central.c
+#, c-format
+msgid "Failed to start connecting, error 0x%04x"
msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
@@ -649,11 +652,6 @@ msgstr ""
msgid "Failed to start scanning, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to stop advertising"
-msgstr ""
-
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to stop advertising, err 0x%04x"
@@ -661,6 +659,11 @@ msgstr ""
#: ports/nrf/common-hal/bleio/Characteristic.c
#, c-format
+msgid "Failed to write CCCD, err 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr ""
@@ -700,6 +703,10 @@ msgstr ""
msgid "Function requires lock"
msgstr ""
+#: shared-bindings/displayio/Display.c
+msgid "Group already used"
+msgstr ""
+
#: shared-module/displayio/Group.c
msgid "Group full"
msgstr ""
@@ -756,7 +763,7 @@ msgstr ""
msgid "Invalid capture period. Valid range: 1 - 500"
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid channel count"
msgstr ""
@@ -764,11 +771,11 @@ msgstr ""
msgid "Invalid direction."
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid file"
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid format chunk size"
msgstr ""
@@ -810,11 +817,11 @@ msgstr ""
msgid "Invalid run mode."
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid wave file"
msgstr ""
@@ -823,6 +830,10 @@ msgid "LHS of keyword arg must be an id"
msgstr ""
#: shared-module/displayio/Group.c
+msgid "Layer already in a group."
+msgstr ""
+
+#: shared-module/displayio/Group.c
msgid "Layer must be a Group or TileGrid subclass."
msgstr ""
@@ -866,8 +877,12 @@ msgstr ""
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr ""
-#: shared-bindings/displayio/Display.c
-msgid "Must be a Group subclass."
+#: shared-bindings/displayio/Group.c
+msgid "Must be a %q subclass."
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "No CCCD for this Characteristic"
msgstr ""
#: ports/atmel-samd/common-hal/analogio/AnalogOut.c
@@ -903,6 +918,10 @@ msgstr ""
msgid "No hardware random available"
msgstr ""
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
+msgid "No hardware support on clk pin"
+msgstr ""
+
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "No hardware support on pin"
@@ -916,11 +935,13 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
+#: ports/nrf/common-hal/bleio/Characteristic.c
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "Not connected"
msgstr ""
#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c
+#: shared-bindings/audiopwmio/PWMAudioOut.c
msgid "Not playing"
msgstr ""
@@ -985,6 +1006,10 @@ msgstr ""
msgid "Plus any modules on the filesystem\n"
msgstr ""
+#: shared-bindings/ps2io/Ps2.c
+msgid "Pop from an empty Ps2 buffer"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1037,11 +1062,12 @@ msgstr ""
msgid "SDA or SCL needs a pull up"
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Sample rate must be positive"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#, c-format
msgid "Sample rate too high. It must be less than %d"
msgstr ""
@@ -1106,19 +1132,19 @@ msgid ""
"exit safe mode.\n"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's bits_per_sample does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's channel count does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's sample rate does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's signedness does not match the mixer's"
msgstr ""
@@ -1127,7 +1153,11 @@ msgid "Tile height must exactly divide bitmap height"
msgstr ""
#: shared-bindings/displayio/TileGrid.c
-msgid "Tile indices must be 0 - 255"
+msgid "Tile index out of bounds"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
+msgid "Tile value out of bounds"
msgstr ""
#: shared-bindings/displayio/TileGrid.c
@@ -1142,7 +1172,8 @@ msgstr ""
msgid "Too many channels in sample."
msgstr ""
-#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
+#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
+#: shared-bindings/displayio/ParallelBus.c
msgid "Too many display busses"
msgstr ""
@@ -1167,7 +1198,7 @@ msgid "USB Error"
msgstr ""
#: shared-bindings/bleio/UUID.c
-msgid "UUID integer value not in range 0 to 0xffff"
+msgid "UUID integer value must be 0-0xffff"
msgstr ""
#: shared-bindings/bleio/UUID.c
@@ -1183,6 +1214,11 @@ msgstr ""
msgid "Unable to allocate buffers for signed conversion"
msgstr ""
+#: shared-module/displayio/I2CDisplay.c
+#, c-format
+msgid "Unable to find I2C Display at %x"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Unable to find free GCLK"
@@ -1217,7 +1253,7 @@ msgstr ""
msgid "Unsupported display bus type"
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Unsupported format"
msgstr ""
@@ -1233,7 +1269,7 @@ msgstr ""
msgid "Viper functions don't currently support more than 4 arguments"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "Voice index too high"
msgstr ""
@@ -1351,7 +1387,7 @@ msgstr ""
msgid "bits must be 8"
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "bits_per_sample must be 8 or 16"
msgstr ""
@@ -1364,7 +1400,7 @@ msgstr ""
msgid "buf is too small. need %d bytes"
msgstr ""
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr ""
@@ -1726,7 +1762,8 @@ msgstr ""
msgid "extra positional arguments given"
msgstr ""
-#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c
+#: shared-bindings/audiocore/WaveFile.c
+#: shared-bindings/displayio/OnDiskBitmap.c
msgid "file must be a file opened in byte mode"
msgstr ""
@@ -1855,8 +1892,9 @@ msgstr ""
msgid "integer required"
msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
-msgid "interval not in range 0.0020 to 10.24"
+#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c
+#, c-format
+msgid "interval must be in range %s-%s"
msgstr ""
#: extmod/machine_i2c.c
@@ -2070,6 +2108,14 @@ msgstr ""
msgid "no such attribute"
msgstr ""
+#: shared-bindings/bleio/Peripheral.c
+msgid "non-Service found in services"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "non-UUID found in service_uuids"
+msgstr ""
+
#: py/compile.c
msgid "non-default argument follows default argument"
msgstr ""
@@ -2127,7 +2173,7 @@ msgstr ""
msgid "object not callable"
msgstr ""
-#: py/sequence.c
+#: py/sequence.c shared-bindings/displayio/Group.c
msgid "object not in sequence"
msgstr ""
@@ -2260,7 +2306,7 @@ msgstr ""
msgid "rsplit(None,n)"
msgstr ""
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid ""
"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or "
"'B'"
@@ -2278,10 +2324,6 @@ msgstr ""
msgid "script compilation not supported"
msgstr ""
-#: shared-bindings/bleio/Peripheral.c
-msgid "services includes an object that is not a Service"
-msgstr ""
-
#: py/objstr.c
msgid "sign not allowed in string format specifier"
msgstr ""
@@ -2379,10 +2421,6 @@ msgstr ""
msgid "threshold must be in the range 0-65536"
msgstr ""
-#: shared-bindings/displayio/TileGrid.c
-msgid "tile index out of bounds"
-msgstr ""
-
#: shared-bindings/time/__init__.c
msgid "time.struct_time() takes a 9-sequence"
msgstr ""
@@ -2541,13 +2579,17 @@ msgstr ""
#: py/objint.c
#, c-format
-msgid "value would overflow a %d byte buffer"
+msgid "value must fit in %d byte(s)"
msgstr ""
#: shared-bindings/displayio/Bitmap.c
msgid "value_count must be > 0"
msgstr ""
+#: shared-bindings/bleio/Scanner.c
+msgid "window must be <= interval"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "write_args must be a list, tuple, or None"
msgstr ""
diff --git a/locale/de_DE.po b/locale/de_DE.po
index 7b6687a20..3037a5369 100644
--- a/locale/de_DE.po
+++ b/locale/de_DE.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-05-09 01:06-0400\n"
+"POT-Creation-Date: 2019-08-05 17:52-0700\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: Pascal Deneaux\n"
"Language-Team: Sebastian Plamauer, Pascal Deneaux\n"
@@ -54,8 +54,8 @@ msgstr "Der Index %q befindet sich außerhalb der Reihung"
msgid "%q indices must be integers, not %s"
msgstr "%q Indizes müssen ganze Zahlen sein, nicht %s"
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
msgid "%q must be >= 1"
msgstr "%q muss >= 1 sein"
@@ -221,14 +221,13 @@ msgstr "Ein Hardware Interrupt Kanal wird schon benutzt"
#: shared-bindings/bleio/Address.c
#, c-format
-msgid "Address is not %d bytes long or is in wrong format"
-msgstr "Die Adresse ist nicht %d Bytes lang oder das Format ist falsch"
-
-#: shared-bindings/bleio/Address.c
-#, c-format
msgid "Address must be %d bytes long"
msgstr "Die Adresse muss %d Bytes lang sein"
+#: shared-bindings/bleio/Address.c
+msgid "Address type out of range"
+msgstr ""
+
#: ports/nrf/common-hal/busio/I2C.c
msgid "All I2C peripherals are in use"
msgstr "Alle I2C-Peripheriegeräte sind in Benutzung"
@@ -253,9 +252,10 @@ msgstr "Alle sync event Kanäle werden benutzt"
msgid "All timers for this pin are in use"
msgstr "Alle timer für diesen Pin werden bereits benutzt"
-#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c
#: shared-module/_pew/PewPew.c
msgid "All timers in use"
@@ -313,6 +313,10 @@ msgstr "Bit depth muss ein Vielfaches von 8 sein."
msgid "Both pins must support hardware interrupts"
msgstr "Beide pins müssen Hardware Interrupts unterstützen"
+#: shared-bindings/displayio/Display.c
+msgid "Brightness must be 0-1.0"
+msgstr ""
+
#: shared-bindings/supervisor/__init__.c
msgid "Brightness must be between 0 and 255"
msgstr "Die Helligkeit muss zwischen 0 und 255 liegen"
@@ -326,6 +330,11 @@ msgstr "Die Helligkeit ist nicht einstellbar"
msgid "Buffer incorrect size. Should be %d bytes."
msgstr "Der Puffergröße ist inkorrekt. Sie sollte %d bytes haben."
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
+#, c-format
+msgid "Buffer length %d too big. It must be less than %d"
+msgstr ""
+
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
msgstr "Der Puffer muss eine Mindestenslänge von 1 haben"
@@ -344,26 +353,18 @@ msgstr "Der Puffer muss 16 Bytes lang sein"
msgid "Bytes must be between 0 and 255."
msgstr "Ein Bytes kann nur Werte zwischen 0 und 255 annehmen."
+#: py/objtype.c
+msgid "Call super().__init__() before accessing native object."
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Can not use dotstar with %s"
msgstr "Kann dotstar nicht mit %s verwenden"
-#: shared-bindings/bleio/Device.c
-msgid "Can't add services in Central mode"
-msgstr "Im Central mode können Dienste nicht hinzugefügt werden"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't advertise in Central mode"
-msgstr "Im Central mode kann advertise nicht gemacht werden"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't change the name in Central mode"
-msgstr "Im Central mode kann name nicht geändert werden"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't connect in Peripheral mode"
-msgstr "Im Peripheral mode kann keine Verbindung hergestellt werden"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Can't set CCCD for local Characteristic"
+msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
msgid "Cannot delete values"
@@ -446,10 +447,22 @@ msgstr "Clock unit wird benutzt"
msgid "Column entry must be digitalio.DigitalInOut"
msgstr ""
+#: shared-bindings/displayio/I2CDisplay.c
+msgid "Command must be 0-255"
+msgstr ""
+
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
msgid "Command must be an int between 0 and 255"
msgstr "Der Befehl muss ein int zwischen 0 und 255 sein"
+#: py/persistentcode.c
+msgid "Corrupt .mpy file"
+msgstr ""
+
+#: py/emitglue.c
+msgid "Corrupt raw code"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/UUID.c
#, c-format
msgid "Could not decode ble_uuid, err 0x%04x"
@@ -459,11 +472,11 @@ msgstr "Konnte ble_uuid nicht decodieren. Status: 0x%04x"
msgid "Could not initialize UART"
msgstr "Konnte UART nicht initialisieren"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate first buffer"
msgstr "Konnte first buffer nicht zuteilen"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate second buffer"
msgstr "Konnte second buffer nicht zuteilen"
@@ -480,19 +493,14 @@ msgstr "DAC wird schon benutzt"
msgid "Data 0 pin must be byte aligned"
msgstr "Data 0 pin muss am Byte ausgerichtet sein"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Data chunk must follow fmt chunk"
msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
msgid "Data too large for advertisement packet"
msgstr "Zu vielen Daten für das advertisement packet"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Data too large for the advertisement packet"
-msgstr "Daten sind zu groß für das advertisement packet"
-
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr "Die Zielkapazität ist kleiner als destination_length."
@@ -506,6 +514,7 @@ msgid "Drive mode not used when direction is input."
msgstr "Drive mode wird nicht verwendet, wenn die Richtung input ist."
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "EXTINT channel already in use"
msgstr "EXTINT Kanal ist schon in Benutzung"
@@ -529,16 +538,20 @@ msgstr "Characteristic wird erwartet"
msgid "Expected a UUID"
msgstr "Eine UUID wird erwartet"
+#: shared-bindings/bleio/Central.c
+msgid "Expected an Address"
+msgstr ""
+
#: shared-module/_pixelbuf/PixelBuf.c
#, c-format
msgid "Expected tuple of length %d, got %d"
msgstr "Habe ein Tupel der Länge %d erwartet aber %d erhalten"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to acquire mutex"
-msgstr "Akquirieren des Mutex gescheitert"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Failed sending command."
+msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, c-format
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Mutex konnte nicht akquiriert werden. Status: 0x%04x"
@@ -548,10 +561,6 @@ msgstr "Mutex konnte nicht akquiriert werden. Status: 0x%04x"
msgid "Failed to add characteristic, err 0x%04x"
msgstr "Hinzufügen des Characteristic ist gescheitert. Status: 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to add service"
-msgstr "Dienst konnte nicht hinzugefügt werden"
-
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to add service, err 0x%04x"
@@ -571,24 +580,21 @@ msgstr "Konnte keine RX Buffer mit %d allozieren"
msgid "Failed to change softdevice state"
msgstr "Fehler beim Ändern des Softdevice-Status"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to connect:"
-msgstr "Verbindung fehlgeschlagen:"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to configure advertising, err 0x%04x"
+msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to continue scanning"
-msgstr "Der Scanvorgang kann nicht fortgesetzt werden"
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "Failed to connect: timeout"
+msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
#, c-format
msgid "Failed to continue scanning, err 0x%04x"
msgstr "Der Scanvorgang kann nicht fortgesetzt werden. Status: 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to create mutex"
-msgstr "Erstellen des Mutex ist fehlgeschlagen"
-
-#: ports/nrf/common-hal/bleio/Device.c
+#: ports/nrf/common-hal/bleio/Central.c
msgid "Failed to discover services"
msgstr "Es konnten keine Dienste gefunden werden"
@@ -625,39 +631,31 @@ msgstr "gatts value konnte nicht gelesen werden. Status: 0x%04x"
msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
msgstr "Kann keine herstellerspezifische UUID hinzufügen. Status: 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to release mutex"
-msgstr "Loslassen des Mutex gescheitert"
-
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "Mutex konnte nicht freigegeben werden. Status: 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to start advertising"
-msgstr "Kann advertisement nicht starten"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to set device name, err 0x%04x"
+msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to start advertising, err 0x%04x"
msgstr "Kann advertisement nicht starten. Status: 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to start scanning"
-msgstr "Der Scanvorgang kann nicht gestartet werden"
+#: ports/nrf/common-hal/bleio/Central.c
+#, c-format
+msgid "Failed to start connecting, error 0x%04x"
+msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to stop advertising"
-msgstr "Kann advertisement nicht stoppen"
-
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to stop advertising, err 0x%04x"
@@ -665,6 +663,11 @@ msgstr "Kann advertisement nicht stoppen. Status: 0x%04x"
#: ports/nrf/common-hal/bleio/Characteristic.c
#, c-format
+msgid "Failed to write CCCD, err 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "Kann den Attributwert nicht schreiben. Status: 0x%04x"
@@ -704,6 +707,10 @@ msgstr ""
msgid "Function requires lock"
msgstr "Die Funktion erwartet, dass der 'lock'-Befehl zuvor ausgeführt wurde"
+#: shared-bindings/displayio/Display.c
+msgid "Group already used"
+msgstr ""
+
#: shared-module/displayio/Group.c
msgid "Group full"
msgstr "Gruppe voll"
@@ -732,8 +739,8 @@ msgstr ""
msgid "Input/output error"
msgstr "Eingabe-/Ausgabefehler"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
msgstr "Ungültiger %q pin"
@@ -762,7 +769,7 @@ msgstr "Ungültige Puffergröße"
msgid "Invalid capture period. Valid range: 1 - 500"
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid channel count"
msgstr "Ungültige Anzahl von Kanälen"
@@ -770,11 +777,11 @@ msgstr "Ungültige Anzahl von Kanälen"
msgid "Invalid direction."
msgstr "Ungültige Richtung"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid file"
msgstr "Ungültige Datei"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid format chunk size"
msgstr "Ungültige format chunk size"
@@ -816,11 +823,11 @@ msgstr "Ungültige Polarität"
msgid "Invalid run mode."
msgstr "Ungültiger Ausführungsmodus"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr "Ungültige Anzahl von Stimmen"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid wave file"
msgstr "Ungültige wave Datei"
@@ -829,6 +836,10 @@ msgid "LHS of keyword arg must be an id"
msgstr "LHS des Schlüsselwortarguments muss eine id sein"
#: shared-module/displayio/Group.c
+msgid "Layer already in a group."
+msgstr ""
+
+#: shared-module/displayio/Group.c
msgid "Layer must be a Group or TileGrid subclass."
msgstr "Layer muss eine Group- oder TileGrid-Unterklasse sein."
@@ -879,8 +890,12 @@ msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr ""
"Die Startverzögerung des Mikrofons muss im Bereich von 0,0 bis 1,0 liegen"
-#: shared-bindings/displayio/Display.c
-msgid "Must be a Group subclass."
+#: shared-bindings/displayio/Group.c
+msgid "Must be a %q subclass."
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "No CCCD for this Characteristic"
msgstr ""
#: ports/atmel-samd/common-hal/analogio/AnalogOut.c
@@ -916,6 +931,10 @@ msgstr "Keine freien GCLKs"
msgid "No hardware random available"
msgstr "Kein hardware random verfügbar"
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
+msgid "No hardware support on clk pin"
+msgstr ""
+
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "No hardware support on pin"
@@ -929,11 +948,13 @@ msgstr "Kein Speicherplatz auf Gerät"
msgid "No such file/directory"
msgstr "Keine solche Datei/Verzeichnis"
+#: ports/nrf/common-hal/bleio/Characteristic.c
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "Not connected"
msgstr "Nicht verbunden"
#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c
+#: shared-bindings/audiopwmio/PWMAudioOut.c
msgid "Not playing"
msgstr "Spielt nicht"
@@ -1000,6 +1021,10 @@ msgstr "Pixel außerhalb der Puffergrenzen"
msgid "Plus any modules on the filesystem\n"
msgstr "und alle Module im Dateisystem \n"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Pop from an empty Ps2 buffer"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1054,17 +1079,18 @@ msgstr "Sicherheitsmodus aktiv! Gespeicherter Code wird nicht ausgeführt\n"
msgid "SDA or SCL needs a pull up"
msgstr "SDA oder SCL brauchen pull up"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Sample rate must be positive"
msgstr "Abtastrate muss positiv sein"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#, c-format
msgid "Sample rate too high. It must be less than %d"
msgstr "Abtastrate zu hoch. Wert muss unter %d liegen"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
msgstr "Serializer wird benutzt"
@@ -1135,19 +1161,19 @@ msgstr ""
"Die Reset-Taste wurde beim Booten von CircuitPython gedrückt. Drücke sie "
"erneut um den abgesicherten Modus zu verlassen. \n"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's bits_per_sample does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's channel count does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's sample rate does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's signedness does not match the mixer's"
msgstr ""
@@ -1156,7 +1182,11 @@ msgid "Tile height must exactly divide bitmap height"
msgstr ""
#: shared-bindings/displayio/TileGrid.c
-msgid "Tile indices must be 0 - 255"
+msgid "Tile index out of bounds"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
+msgid "Tile value out of bounds"
msgstr ""
#: shared-bindings/displayio/TileGrid.c
@@ -1171,7 +1201,8 @@ msgstr "Zum beenden, resette bitte das board ohne "
msgid "Too many channels in sample."
msgstr "Zu viele Kanäle im sample"
-#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
+#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
+#: shared-bindings/displayio/ParallelBus.c
msgid "Too many display busses"
msgstr ""
@@ -1196,8 +1227,8 @@ msgid "USB Error"
msgstr "USB Fehler"
#: shared-bindings/bleio/UUID.c
-msgid "UUID integer value not in range 0 to 0xffff"
-msgstr "UUID-Integer nicht im Bereich 0 bis 0xffff"
+msgid "UUID integer value must be 0-0xffff"
+msgstr ""
#: shared-bindings/bleio/UUID.c
msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'"
@@ -1212,8 +1243,13 @@ msgstr "Der UUID-Wert ist kein str-, int- oder Byte-Puffer"
msgid "Unable to allocate buffers for signed conversion"
msgstr "Konnte keine Buffer für Vorzeichenumwandlung allozieren"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+#: shared-module/displayio/I2CDisplay.c
+#, c-format
+msgid "Unable to find I2C Display at %x"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Unable to find free GCLK"
msgstr "Konnte keinen freien GCLK finden"
@@ -1248,7 +1284,7 @@ msgstr "Baudrate wird nicht unterstützt"
msgid "Unsupported display bus type"
msgstr "Nicht unterstützter display bus type"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Unsupported format"
msgstr "Nicht unterstütztes Format"
@@ -1264,7 +1300,7 @@ msgstr "Nicht unterstützter Pull-Wert"
msgid "Viper functions don't currently support more than 4 arguments"
msgstr "Viper-Funktionen unterstützen derzeit nicht mehr als 4 Argumente"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "Voice index too high"
msgstr "Voice index zu hoch"
@@ -1391,7 +1427,7 @@ msgstr "bits muss 7, 8 oder 9 sein"
msgid "bits must be 8"
msgstr "bits müssen 8 sein"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "bits_per_sample must be 8 or 16"
msgstr "Es müssen 8 oder 16 bits_per_sample sein"
@@ -1404,7 +1440,7 @@ msgstr "Zweig ist außerhalb der Reichweite"
msgid "buf is too small. need %d bytes"
msgstr "buf ist zu klein. brauche %d Bytes"
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr "Puffer muss ein bytes-artiges Objekt sein"
@@ -1705,7 +1741,7 @@ msgstr "Division durch Null"
msgid "empty"
msgstr "leer"
-#: extmod/modutimeq.c extmod/moduheapq.c
+#: extmod/moduheapq.c extmod/modutimeq.c
msgid "empty heap"
msgstr "leerer heap"
@@ -1766,7 +1802,8 @@ msgstr "Es wurden zusätzliche Keyword-Argumente angegeben"
msgid "extra positional arguments given"
msgstr "Es wurden zusätzliche Argumente ohne Keyword angegeben"
-#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c
+#: shared-bindings/audiocore/WaveFile.c
+#: shared-bindings/displayio/OnDiskBitmap.c
msgid "file must be a file opened in byte mode"
msgstr "Die Datei muss eine im Byte-Modus geöffnete Datei sein"
@@ -1896,9 +1933,10 @@ msgstr "int() arg 2 muss >= 2 und <= 36 sein"
msgid "integer required"
msgstr "integer erforderlich"
-#: ports/nrf/common-hal/bleio/Broadcaster.c
-msgid "interval not in range 0.0020 to 10.24"
-msgstr "Das Interval ist nicht im Bereich 0.0020 bis 10.24"
+#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c
+#, c-format
+msgid "interval must be in range %s-%s"
+msgstr ""
#: extmod/machine_i2c.c
msgid "invalid I2C peripheral"
@@ -2117,6 +2155,14 @@ msgstr "Kein Modul mit dem Namen '%q'"
msgid "no such attribute"
msgstr ""
+#: shared-bindings/bleio/Peripheral.c
+msgid "non-Service found in services"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "non-UUID found in service_uuids"
+msgstr ""
+
#: py/compile.c
msgid "non-default argument follows default argument"
msgstr "ein non-default argument folgt auf ein default argument"
@@ -2174,7 +2220,7 @@ msgstr "Objekt ist kein Iterator"
msgid "object not callable"
msgstr ""
-#: py/sequence.c
+#: py/sequence.c shared-bindings/displayio/Group.c
msgid "object not in sequence"
msgstr "Objekt ist nicht in sequence"
@@ -2309,7 +2355,7 @@ msgstr ""
msgid "rsplit(None,n)"
msgstr ""
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid ""
"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or "
"'B'"
@@ -2329,10 +2375,6 @@ msgstr "Der schedule stack ist voll"
msgid "script compilation not supported"
msgstr "kompilieren von Skripten ist nicht unterstützt"
-#: shared-bindings/bleio/Peripheral.c
-msgid "services includes an object that is not a Service"
-msgstr ""
-
#: py/objstr.c
msgid "sign not allowed in string format specifier"
msgstr ""
@@ -2431,10 +2473,6 @@ msgstr "Syntaxfehler in uctypes Deskriptor"
msgid "threshold must be in the range 0-65536"
msgstr "threshold muss im Intervall 0-65536 liegen"
-#: shared-bindings/displayio/TileGrid.c
-msgid "tile index out of bounds"
-msgstr ""
-
#: shared-bindings/time/__init__.c
msgid "time.struct_time() takes a 9-sequence"
msgstr ""
@@ -2597,13 +2635,17 @@ msgstr "nicht unterstützte Typen für %q: '%s', '%s'"
#: py/objint.c
#, c-format
-msgid "value would overflow a %d byte buffer"
+msgid "value must fit in %d byte(s)"
msgstr ""
#: shared-bindings/displayio/Bitmap.c
msgid "value_count must be > 0"
msgstr ""
+#: shared-bindings/bleio/Scanner.c
+msgid "window must be <= interval"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "write_args must be a list, tuple, or None"
msgstr "write_args muss eine Liste, ein Tupel oder None sein"
@@ -2635,9 +2677,24 @@ msgstr ""
#~ msgid "AP required"
#~ msgstr "AP erforderlich"
+#~ msgid "Address is not %d bytes long or is in wrong format"
+#~ msgstr "Die Adresse ist nicht %d Bytes lang oder das Format ist falsch"
+
#~ msgid "C-level assert"
#~ msgstr "C-Level Assert"
+#~ msgid "Can't add services in Central mode"
+#~ msgstr "Im Central mode können Dienste nicht hinzugefügt werden"
+
+#~ msgid "Can't advertise in Central mode"
+#~ msgstr "Im Central mode kann advertise nicht gemacht werden"
+
+#~ msgid "Can't change the name in Central mode"
+#~ msgstr "Im Central mode kann name nicht geändert werden"
+
+#~ msgid "Can't connect in Peripheral mode"
+#~ msgstr "Im Peripheral mode kann keine Verbindung hergestellt werden"
+
#~ msgid "Cannot connect to AP"
#~ msgstr "Kann nicht zu AP verbinden"
@@ -2650,6 +2707,9 @@ msgstr ""
#~ msgid "Cannot update i/f status"
#~ msgstr "Kann i/f Status nicht updaten"
+#~ msgid "Data too large for the advertisement packet"
+#~ msgstr "Daten sind zu groß für das advertisement packet"
+
#~ msgid "Don't know how to pass object to native function"
#~ msgstr ""
#~ "Ich weiß nicht, wie man das Objekt an die native Funktion übergeben kann"
@@ -2663,12 +2723,39 @@ msgstr ""
#~ msgid "Error in ffi_prep_cif"
#~ msgstr "Fehler in ffi_prep_cif"
+#~ msgid "Failed to acquire mutex"
+#~ msgstr "Akquirieren des Mutex gescheitert"
+
+#~ msgid "Failed to add service"
+#~ msgstr "Dienst konnte nicht hinzugefügt werden"
+
+#~ msgid "Failed to connect:"
+#~ msgstr "Verbindung fehlgeschlagen:"
+
+#~ msgid "Failed to continue scanning"
+#~ msgstr "Der Scanvorgang kann nicht fortgesetzt werden"
+
+#~ msgid "Failed to create mutex"
+#~ msgstr "Erstellen des Mutex ist fehlgeschlagen"
+
#~ msgid "Failed to notify or indicate attribute value, err %0x04x"
#~ msgstr "Kann den Attributwert nicht mitteilen. Status: 0x%04x"
#~ msgid "Failed to read attribute value, err %0x04x"
#~ msgstr "Kann den Attributwert nicht lesen. Status: 0x%04x"
+#~ msgid "Failed to release mutex"
+#~ msgstr "Loslassen des Mutex gescheitert"
+
+#~ msgid "Failed to start advertising"
+#~ msgstr "Kann advertisement nicht starten"
+
+#~ msgid "Failed to start scanning"
+#~ msgstr "Der Scanvorgang kann nicht gestartet werden"
+
+#~ msgid "Failed to stop advertising"
+#~ msgstr "Kann advertisement nicht stoppen"
+
#~ msgid "Function requires lock."
#~ msgstr ""
#~ "Die Funktion erwartet, dass der 'lock'-Befehl zuvor ausgeführt wurde"
@@ -2740,6 +2827,9 @@ msgstr ""
#~ msgid "UART(1) can't read"
#~ msgstr "UART(1) kann nicht lesen"
+#~ msgid "UUID integer value not in range 0 to 0xffff"
+#~ msgstr "UUID-Integer nicht im Bereich 0 bis 0xffff"
+
#~ msgid "Unable to remount filesystem"
#~ msgstr "Dateisystem konnte nicht wieder eingebunden werden."
@@ -2771,6 +2861,9 @@ msgstr ""
#~ msgid "impossible baudrate"
#~ msgstr "Unmögliche Baudrate"
+#~ msgid "interval not in range 0.0020 to 10.24"
+#~ msgstr "Das Interval ist nicht im Bereich 0.0020 bis 10.24"
+
#~ msgid "invalid alarm"
#~ msgstr "ungültiger Alarm"
diff --git a/locale/en_US.po b/locale/en_US.po
index 67a225561..6d15af4dd 100644
--- a/locale/en_US.po
+++ b/locale/en_US.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-05-09 01:06-0400\n"
+"POT-Creation-Date: 2019-08-05 17:52-0700\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -52,8 +52,8 @@ msgstr ""
msgid "%q indices must be integers, not %s"
msgstr ""
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
msgid "%q must be >= 1"
msgstr ""
@@ -219,12 +219,11 @@ msgstr ""
#: shared-bindings/bleio/Address.c
#, c-format
-msgid "Address is not %d bytes long or is in wrong format"
+msgid "Address must be %d bytes long"
msgstr ""
#: shared-bindings/bleio/Address.c
-#, c-format
-msgid "Address must be %d bytes long"
+msgid "Address type out of range"
msgstr ""
#: ports/nrf/common-hal/busio/I2C.c
@@ -251,9 +250,10 @@ msgstr ""
msgid "All timers for this pin are in use"
msgstr ""
-#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c
#: shared-module/_pew/PewPew.c
msgid "All timers in use"
@@ -309,6 +309,10 @@ msgstr ""
msgid "Both pins must support hardware interrupts"
msgstr ""
+#: shared-bindings/displayio/Display.c
+msgid "Brightness must be 0-1.0"
+msgstr ""
+
#: shared-bindings/supervisor/__init__.c
msgid "Brightness must be between 0 and 255"
msgstr ""
@@ -322,6 +326,11 @@ msgstr ""
msgid "Buffer incorrect size. Should be %d bytes."
msgstr ""
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
+#, c-format
+msgid "Buffer length %d too big. It must be less than %d"
+msgstr ""
+
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
msgstr ""
@@ -340,25 +349,17 @@ msgstr ""
msgid "Bytes must be between 0 and 255."
msgstr ""
+#: py/objtype.c
+msgid "Call super().__init__() before accessing native object."
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Can not use dotstar with %s"
msgstr ""
-#: shared-bindings/bleio/Device.c
-msgid "Can't add services in Central mode"
-msgstr ""
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't advertise in Central mode"
-msgstr ""
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't change the name in Central mode"
-msgstr ""
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't connect in Peripheral mode"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Can't set CCCD for local Characteristic"
msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
@@ -442,10 +443,22 @@ msgstr ""
msgid "Column entry must be digitalio.DigitalInOut"
msgstr ""
+#: shared-bindings/displayio/I2CDisplay.c
+msgid "Command must be 0-255"
+msgstr ""
+
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
msgid "Command must be an int between 0 and 255"
msgstr ""
+#: py/persistentcode.c
+msgid "Corrupt .mpy file"
+msgstr ""
+
+#: py/emitglue.c
+msgid "Corrupt raw code"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/UUID.c
#, c-format
msgid "Could not decode ble_uuid, err 0x%04x"
@@ -455,11 +468,11 @@ msgstr ""
msgid "Could not initialize UART"
msgstr ""
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate first buffer"
msgstr ""
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate second buffer"
msgstr ""
@@ -476,19 +489,14 @@ msgstr ""
msgid "Data 0 pin must be byte aligned"
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Data chunk must follow fmt chunk"
msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
msgid "Data too large for advertisement packet"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Data too large for the advertisement packet"
-msgstr ""
-
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr ""
@@ -502,6 +510,7 @@ msgid "Drive mode not used when direction is input."
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "EXTINT channel already in use"
msgstr ""
@@ -525,16 +534,20 @@ msgstr ""
msgid "Expected a UUID"
msgstr ""
+#: shared-bindings/bleio/Central.c
+msgid "Expected an Address"
+msgstr ""
+
#: shared-module/_pixelbuf/PixelBuf.c
#, c-format
msgid "Expected tuple of length %d, got %d"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to acquire mutex"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Failed sending command."
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, c-format
msgid "Failed to acquire mutex, err 0x%04x"
msgstr ""
@@ -544,10 +557,6 @@ msgstr ""
msgid "Failed to add characteristic, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to add service"
-msgstr ""
-
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to add service, err 0x%04x"
@@ -567,12 +576,13 @@ msgstr ""
msgid "Failed to change softdevice state"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to connect:"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to configure advertising, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to continue scanning"
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "Failed to connect: timeout"
msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
@@ -580,11 +590,7 @@ msgstr ""
msgid "Failed to continue scanning, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to create mutex"
-msgstr ""
-
-#: ports/nrf/common-hal/bleio/Device.c
+#: ports/nrf/common-hal/bleio/Central.c
msgid "Failed to discover services"
msgstr ""
@@ -621,27 +627,24 @@ msgstr ""
msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to release mutex"
-msgstr ""
-
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to start advertising"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to set device name, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to start advertising, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to start scanning"
+#: ports/nrf/common-hal/bleio/Central.c
+#, c-format
+msgid "Failed to start connecting, error 0x%04x"
msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
@@ -649,11 +652,6 @@ msgstr ""
msgid "Failed to start scanning, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to stop advertising"
-msgstr ""
-
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to stop advertising, err 0x%04x"
@@ -661,6 +659,11 @@ msgstr ""
#: ports/nrf/common-hal/bleio/Characteristic.c
#, c-format
+msgid "Failed to write CCCD, err 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr ""
@@ -700,6 +703,10 @@ msgstr ""
msgid "Function requires lock"
msgstr ""
+#: shared-bindings/displayio/Display.c
+msgid "Group already used"
+msgstr ""
+
#: shared-module/displayio/Group.c
msgid "Group full"
msgstr ""
@@ -726,8 +733,8 @@ msgstr ""
msgid "Input/output error"
msgstr ""
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
msgstr ""
@@ -756,7 +763,7 @@ msgstr ""
msgid "Invalid capture period. Valid range: 1 - 500"
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid channel count"
msgstr ""
@@ -764,11 +771,11 @@ msgstr ""
msgid "Invalid direction."
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid file"
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid format chunk size"
msgstr ""
@@ -810,11 +817,11 @@ msgstr ""
msgid "Invalid run mode."
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid wave file"
msgstr ""
@@ -823,6 +830,10 @@ msgid "LHS of keyword arg must be an id"
msgstr ""
#: shared-module/displayio/Group.c
+msgid "Layer already in a group."
+msgstr ""
+
+#: shared-module/displayio/Group.c
msgid "Layer must be a Group or TileGrid subclass."
msgstr ""
@@ -866,8 +877,12 @@ msgstr ""
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr ""
-#: shared-bindings/displayio/Display.c
-msgid "Must be a Group subclass."
+#: shared-bindings/displayio/Group.c
+msgid "Must be a %q subclass."
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "No CCCD for this Characteristic"
msgstr ""
#: ports/atmel-samd/common-hal/analogio/AnalogOut.c
@@ -903,6 +918,10 @@ msgstr ""
msgid "No hardware random available"
msgstr ""
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
+msgid "No hardware support on clk pin"
+msgstr ""
+
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "No hardware support on pin"
@@ -916,11 +935,13 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
+#: ports/nrf/common-hal/bleio/Characteristic.c
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "Not connected"
msgstr ""
#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c
+#: shared-bindings/audiopwmio/PWMAudioOut.c
msgid "Not playing"
msgstr ""
@@ -985,6 +1006,10 @@ msgstr ""
msgid "Plus any modules on the filesystem\n"
msgstr ""
+#: shared-bindings/ps2io/Ps2.c
+msgid "Pop from an empty Ps2 buffer"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1037,17 +1062,18 @@ msgstr ""
msgid "SDA or SCL needs a pull up"
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Sample rate must be positive"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#, c-format
msgid "Sample rate too high. It must be less than %d"
msgstr ""
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
msgstr ""
@@ -1106,19 +1132,19 @@ msgid ""
"exit safe mode.\n"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's bits_per_sample does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's channel count does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's sample rate does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's signedness does not match the mixer's"
msgstr ""
@@ -1127,7 +1153,11 @@ msgid "Tile height must exactly divide bitmap height"
msgstr ""
#: shared-bindings/displayio/TileGrid.c
-msgid "Tile indices must be 0 - 255"
+msgid "Tile index out of bounds"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
+msgid "Tile value out of bounds"
msgstr ""
#: shared-bindings/displayio/TileGrid.c
@@ -1142,7 +1172,8 @@ msgstr ""
msgid "Too many channels in sample."
msgstr ""
-#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
+#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
+#: shared-bindings/displayio/ParallelBus.c
msgid "Too many display busses"
msgstr ""
@@ -1167,7 +1198,7 @@ msgid "USB Error"
msgstr ""
#: shared-bindings/bleio/UUID.c
-msgid "UUID integer value not in range 0 to 0xffff"
+msgid "UUID integer value must be 0-0xffff"
msgstr ""
#: shared-bindings/bleio/UUID.c
@@ -1183,8 +1214,13 @@ msgstr ""
msgid "Unable to allocate buffers for signed conversion"
msgstr ""
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+#: shared-module/displayio/I2CDisplay.c
+#, c-format
+msgid "Unable to find I2C Display at %x"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Unable to find free GCLK"
msgstr ""
@@ -1217,7 +1253,7 @@ msgstr ""
msgid "Unsupported display bus type"
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Unsupported format"
msgstr ""
@@ -1233,7 +1269,7 @@ msgstr ""
msgid "Viper functions don't currently support more than 4 arguments"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "Voice index too high"
msgstr ""
@@ -1351,7 +1387,7 @@ msgstr ""
msgid "bits must be 8"
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "bits_per_sample must be 8 or 16"
msgstr ""
@@ -1364,7 +1400,7 @@ msgstr ""
msgid "buf is too small. need %d bytes"
msgstr ""
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr ""
@@ -1665,7 +1701,7 @@ msgstr ""
msgid "empty"
msgstr ""
-#: extmod/modutimeq.c extmod/moduheapq.c
+#: extmod/moduheapq.c extmod/modutimeq.c
msgid "empty heap"
msgstr ""
@@ -1726,7 +1762,8 @@ msgstr ""
msgid "extra positional arguments given"
msgstr ""
-#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c
+#: shared-bindings/audiocore/WaveFile.c
+#: shared-bindings/displayio/OnDiskBitmap.c
msgid "file must be a file opened in byte mode"
msgstr ""
@@ -1855,8 +1892,9 @@ msgstr ""
msgid "integer required"
msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
-msgid "interval not in range 0.0020 to 10.24"
+#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c
+#, c-format
+msgid "interval must be in range %s-%s"
msgstr ""
#: extmod/machine_i2c.c
@@ -2070,6 +2108,14 @@ msgstr ""
msgid "no such attribute"
msgstr ""
+#: shared-bindings/bleio/Peripheral.c
+msgid "non-Service found in services"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "non-UUID found in service_uuids"
+msgstr ""
+
#: py/compile.c
msgid "non-default argument follows default argument"
msgstr ""
@@ -2127,7 +2173,7 @@ msgstr ""
msgid "object not callable"
msgstr ""
-#: py/sequence.c
+#: py/sequence.c shared-bindings/displayio/Group.c
msgid "object not in sequence"
msgstr ""
@@ -2260,7 +2306,7 @@ msgstr ""
msgid "rsplit(None,n)"
msgstr ""
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid ""
"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or "
"'B'"
@@ -2278,10 +2324,6 @@ msgstr ""
msgid "script compilation not supported"
msgstr ""
-#: shared-bindings/bleio/Peripheral.c
-msgid "services includes an object that is not a Service"
-msgstr ""
-
#: py/objstr.c
msgid "sign not allowed in string format specifier"
msgstr ""
@@ -2379,10 +2421,6 @@ msgstr ""
msgid "threshold must be in the range 0-65536"
msgstr ""
-#: shared-bindings/displayio/TileGrid.c
-msgid "tile index out of bounds"
-msgstr ""
-
#: shared-bindings/time/__init__.c
msgid "time.struct_time() takes a 9-sequence"
msgstr ""
@@ -2541,13 +2579,17 @@ msgstr ""
#: py/objint.c
#, c-format
-msgid "value would overflow a %d byte buffer"
+msgid "value must fit in %d byte(s)"
msgstr ""
#: shared-bindings/displayio/Bitmap.c
msgid "value_count must be > 0"
msgstr ""
+#: shared-bindings/bleio/Scanner.c
+msgid "window must be <= interval"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "write_args must be a list, tuple, or None"
msgstr ""
diff --git a/locale/en_x_pirate.po b/locale/en_x_pirate.po
index 01286bf0c..57bb45380 100644
--- a/locale/en_x_pirate.po
+++ b/locale/en_x_pirate.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-05-09 01:06-0400\n"
+"POT-Creation-Date: 2019-08-05 17:52-0700\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: @sommersoft, @MrCertainly\n"
@@ -54,8 +54,8 @@ msgstr ""
msgid "%q indices must be integers, not %s"
msgstr ""
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
msgid "%q must be >= 1"
msgstr ""
@@ -221,12 +221,11 @@ msgstr "Avast! A hardware interrupt channel be used already"
#: shared-bindings/bleio/Address.c
#, c-format
-msgid "Address is not %d bytes long or is in wrong format"
+msgid "Address must be %d bytes long"
msgstr ""
#: shared-bindings/bleio/Address.c
-#, c-format
-msgid "Address must be %d bytes long"
+msgid "Address type out of range"
msgstr ""
#: ports/nrf/common-hal/busio/I2C.c
@@ -253,9 +252,10 @@ msgstr ""
msgid "All timers for this pin are in use"
msgstr ""
-#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c
#: shared-module/_pew/PewPew.c
msgid "All timers in use"
@@ -313,6 +313,10 @@ msgstr ""
msgid "Both pins must support hardware interrupts"
msgstr ""
+#: shared-bindings/displayio/Display.c
+msgid "Brightness must be 0-1.0"
+msgstr ""
+
#: shared-bindings/supervisor/__init__.c
msgid "Brightness must be between 0 and 255"
msgstr ""
@@ -326,6 +330,11 @@ msgstr ""
msgid "Buffer incorrect size. Should be %d bytes."
msgstr ""
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
+#, c-format
+msgid "Buffer length %d too big. It must be less than %d"
+msgstr ""
+
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
msgstr ""
@@ -344,25 +353,17 @@ msgstr ""
msgid "Bytes must be between 0 and 255."
msgstr ""
+#: py/objtype.c
+msgid "Call super().__init__() before accessing native object."
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Can not use dotstar with %s"
msgstr ""
-#: shared-bindings/bleio/Device.c
-msgid "Can't add services in Central mode"
-msgstr ""
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't advertise in Central mode"
-msgstr ""
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't change the name in Central mode"
-msgstr ""
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't connect in Peripheral mode"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Can't set CCCD for local Characteristic"
msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
@@ -446,10 +447,22 @@ msgstr ""
msgid "Column entry must be digitalio.DigitalInOut"
msgstr ""
+#: shared-bindings/displayio/I2CDisplay.c
+msgid "Command must be 0-255"
+msgstr ""
+
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
msgid "Command must be an int between 0 and 255"
msgstr ""
+#: py/persistentcode.c
+msgid "Corrupt .mpy file"
+msgstr ""
+
+#: py/emitglue.c
+msgid "Corrupt raw code"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/UUID.c
#, c-format
msgid "Could not decode ble_uuid, err 0x%04x"
@@ -459,11 +472,11 @@ msgstr ""
msgid "Could not initialize UART"
msgstr ""
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate first buffer"
msgstr ""
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate second buffer"
msgstr ""
@@ -480,19 +493,14 @@ msgstr ""
msgid "Data 0 pin must be byte aligned"
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Data chunk must follow fmt chunk"
msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
msgid "Data too large for advertisement packet"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Data too large for the advertisement packet"
-msgstr ""
-
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr ""
@@ -506,6 +514,7 @@ msgid "Drive mode not used when direction is input."
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "EXTINT channel already in use"
msgstr "Avast! EXTINT channel already in use"
@@ -529,16 +538,20 @@ msgstr ""
msgid "Expected a UUID"
msgstr ""
+#: shared-bindings/bleio/Central.c
+msgid "Expected an Address"
+msgstr ""
+
#: shared-module/_pixelbuf/PixelBuf.c
#, c-format
msgid "Expected tuple of length %d, got %d"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to acquire mutex"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Failed sending command."
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, c-format
msgid "Failed to acquire mutex, err 0x%04x"
msgstr ""
@@ -548,10 +561,6 @@ msgstr ""
msgid "Failed to add characteristic, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to add service"
-msgstr ""
-
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to add service, err 0x%04x"
@@ -571,12 +580,13 @@ msgstr ""
msgid "Failed to change softdevice state"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to connect:"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to configure advertising, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to continue scanning"
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "Failed to connect: timeout"
msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
@@ -584,11 +594,7 @@ msgstr ""
msgid "Failed to continue scanning, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to create mutex"
-msgstr ""
-
-#: ports/nrf/common-hal/bleio/Device.c
+#: ports/nrf/common-hal/bleio/Central.c
msgid "Failed to discover services"
msgstr ""
@@ -625,27 +631,24 @@ msgstr ""
msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to release mutex"
-msgstr ""
-
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to start advertising"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to set device name, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to start advertising, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to start scanning"
+#: ports/nrf/common-hal/bleio/Central.c
+#, c-format
+msgid "Failed to start connecting, error 0x%04x"
msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
@@ -653,11 +656,6 @@ msgstr ""
msgid "Failed to start scanning, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to stop advertising"
-msgstr ""
-
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to stop advertising, err 0x%04x"
@@ -665,6 +663,11 @@ msgstr ""
#: ports/nrf/common-hal/bleio/Characteristic.c
#, c-format
+msgid "Failed to write CCCD, err 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr ""
@@ -704,6 +707,10 @@ msgstr ""
msgid "Function requires lock"
msgstr ""
+#: shared-bindings/displayio/Display.c
+msgid "Group already used"
+msgstr ""
+
#: shared-module/displayio/Group.c
msgid "Group full"
msgstr ""
@@ -730,8 +737,8 @@ msgstr ""
msgid "Input/output error"
msgstr ""
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
msgstr "Avast! %q pin be invalid"
@@ -760,7 +767,7 @@ msgstr ""
msgid "Invalid capture period. Valid range: 1 - 500"
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid channel count"
msgstr ""
@@ -768,11 +775,11 @@ msgstr ""
msgid "Invalid direction."
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid file"
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid format chunk size"
msgstr ""
@@ -814,11 +821,11 @@ msgstr ""
msgid "Invalid run mode."
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid wave file"
msgstr ""
@@ -827,6 +834,10 @@ msgid "LHS of keyword arg must be an id"
msgstr ""
#: shared-module/displayio/Group.c
+msgid "Layer already in a group."
+msgstr ""
+
+#: shared-module/displayio/Group.c
msgid "Layer must be a Group or TileGrid subclass."
msgstr ""
@@ -870,8 +881,12 @@ msgstr ""
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr ""
-#: shared-bindings/displayio/Display.c
-msgid "Must be a Group subclass."
+#: shared-bindings/displayio/Group.c
+msgid "Must be a %q subclass."
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "No CCCD for this Characteristic"
msgstr ""
#: ports/atmel-samd/common-hal/analogio/AnalogOut.c
@@ -907,6 +922,10 @@ msgstr ""
msgid "No hardware random available"
msgstr ""
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
+msgid "No hardware support on clk pin"
+msgstr ""
+
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "No hardware support on pin"
@@ -920,11 +939,13 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
+#: ports/nrf/common-hal/bleio/Characteristic.c
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "Not connected"
msgstr ""
#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c
+#: shared-bindings/audiopwmio/PWMAudioOut.c
msgid "Not playing"
msgstr ""
@@ -989,6 +1010,10 @@ msgstr ""
msgid "Plus any modules on the filesystem\n"
msgstr ""
+#: shared-bindings/ps2io/Ps2.c
+msgid "Pop from an empty Ps2 buffer"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1041,17 +1066,18 @@ msgstr "Runnin' in safe mode! Nay runnin' saved code.\n"
msgid "SDA or SCL needs a pull up"
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Sample rate must be positive"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#, c-format
msgid "Sample rate too high. It must be less than %d"
msgstr ""
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
msgstr ""
@@ -1110,19 +1136,19 @@ msgid ""
"exit safe mode.\n"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's bits_per_sample does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's channel count does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's sample rate does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's signedness does not match the mixer's"
msgstr ""
@@ -1131,7 +1157,11 @@ msgid "Tile height must exactly divide bitmap height"
msgstr ""
#: shared-bindings/displayio/TileGrid.c
-msgid "Tile indices must be 0 - 255"
+msgid "Tile index out of bounds"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
+msgid "Tile value out of bounds"
msgstr ""
#: shared-bindings/displayio/TileGrid.c
@@ -1146,7 +1176,8 @@ msgstr ""
msgid "Too many channels in sample."
msgstr ""
-#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
+#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
+#: shared-bindings/displayio/ParallelBus.c
msgid "Too many display busses"
msgstr ""
@@ -1171,7 +1202,7 @@ msgid "USB Error"
msgstr ""
#: shared-bindings/bleio/UUID.c
-msgid "UUID integer value not in range 0 to 0xffff"
+msgid "UUID integer value must be 0-0xffff"
msgstr ""
#: shared-bindings/bleio/UUID.c
@@ -1187,8 +1218,13 @@ msgstr ""
msgid "Unable to allocate buffers for signed conversion"
msgstr ""
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+#: shared-module/displayio/I2CDisplay.c
+#, c-format
+msgid "Unable to find I2C Display at %x"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Unable to find free GCLK"
msgstr "Arr! No free GCLK be in sight"
@@ -1221,7 +1257,7 @@ msgstr ""
msgid "Unsupported display bus type"
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Unsupported format"
msgstr ""
@@ -1237,7 +1273,7 @@ msgstr ""
msgid "Viper functions don't currently support more than 4 arguments"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "Voice index too high"
msgstr ""
@@ -1355,7 +1391,7 @@ msgstr ""
msgid "bits must be 8"
msgstr "pieces must be of 8"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "bits_per_sample must be 8 or 16"
msgstr ""
@@ -1368,7 +1404,7 @@ msgstr ""
msgid "buf is too small. need %d bytes"
msgstr ""
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr ""
@@ -1669,7 +1705,7 @@ msgstr ""
msgid "empty"
msgstr ""
-#: extmod/modutimeq.c extmod/moduheapq.c
+#: extmod/moduheapq.c extmod/modutimeq.c
msgid "empty heap"
msgstr ""
@@ -1730,7 +1766,8 @@ msgstr ""
msgid "extra positional arguments given"
msgstr ""
-#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c
+#: shared-bindings/audiocore/WaveFile.c
+#: shared-bindings/displayio/OnDiskBitmap.c
msgid "file must be a file opened in byte mode"
msgstr ""
@@ -1859,8 +1896,9 @@ msgstr ""
msgid "integer required"
msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
-msgid "interval not in range 0.0020 to 10.24"
+#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c
+#, c-format
+msgid "interval must be in range %s-%s"
msgstr ""
#: extmod/machine_i2c.c
@@ -2074,6 +2112,14 @@ msgstr ""
msgid "no such attribute"
msgstr ""
+#: shared-bindings/bleio/Peripheral.c
+msgid "non-Service found in services"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "non-UUID found in service_uuids"
+msgstr ""
+
#: py/compile.c
msgid "non-default argument follows default argument"
msgstr ""
@@ -2131,7 +2177,7 @@ msgstr ""
msgid "object not callable"
msgstr ""
-#: py/sequence.c
+#: py/sequence.c shared-bindings/displayio/Group.c
msgid "object not in sequence"
msgstr ""
@@ -2264,7 +2310,7 @@ msgstr ""
msgid "rsplit(None,n)"
msgstr ""
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid ""
"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or "
"'B'"
@@ -2282,10 +2328,6 @@ msgstr ""
msgid "script compilation not supported"
msgstr ""
-#: shared-bindings/bleio/Peripheral.c
-msgid "services includes an object that is not a Service"
-msgstr ""
-
#: py/objstr.c
msgid "sign not allowed in string format specifier"
msgstr ""
@@ -2383,10 +2425,6 @@ msgstr ""
msgid "threshold must be in the range 0-65536"
msgstr ""
-#: shared-bindings/displayio/TileGrid.c
-msgid "tile index out of bounds"
-msgstr ""
-
#: shared-bindings/time/__init__.c
msgid "time.struct_time() takes a 9-sequence"
msgstr ""
@@ -2545,13 +2583,17 @@ msgstr ""
#: py/objint.c
#, c-format
-msgid "value would overflow a %d byte buffer"
+msgid "value must fit in %d byte(s)"
msgstr ""
#: shared-bindings/displayio/Bitmap.c
msgid "value_count must be > 0"
msgstr ""
+#: shared-bindings/bleio/Scanner.c
+msgid "window must be <= interval"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "write_args must be a list, tuple, or None"
msgstr ""
diff --git a/locale/es.po b/locale/es.po
index 07825785c..a3ffe5799 100644
--- a/locale/es.po
+++ b/locale/es.po
@@ -3,12 +3,11 @@
# This file is distributed under the same license as the PACKAGE package.
# Carlos Diaz <carlos.santiago.diaz@gmail.com>, 2018.
# Juan Biondi <juanernestobiondi@gmail.com>, 2018.
-#
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-05-09 01:06-0400\n"
+"POT-Creation-Date: 2019-07-31 16:30-0500\n"
"PO-Revision-Date: 2018-08-24 22:56-0500\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -24,7 +23,7 @@ msgid ""
"Code done running. Waiting for reload.\n"
msgstr ""
"\n"
-"Código en ejecución. Esperando para recargar.\n"
+"El código terminó su ejecución. Esperando para recargar.\n"
#: py/obj.c
msgid " File \"%q\""
@@ -55,16 +54,14 @@ msgstr "%q indice fuera de rango"
msgid "%q indices must be integers, not %s"
msgstr "%q indices deben ser enteros, no %s"
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
#: shared-bindings/bleio/CharacteristicBuffer.c
-#, fuzzy
+#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
msgid "%q must be >= 1"
msgstr "%q debe ser >= 1"
#: shared-bindings/fontio/BuiltinFont.c
-#, fuzzy
msgid "%q should be an int"
-msgstr "%q deberia ser un int"
+msgstr "%q debe ser un int"
#: py/bc.c py/objnamedtuple.c
msgid "%q() takes %d positional arguments but %d were given"
@@ -200,8 +197,7 @@ msgstr "'return' fuera de una función"
#: py/compile.c
msgid "'yield' outside function"
-msgstr ""
-"No es posible reiniciar en modo bootloader porque no hay bootloader presente."
+msgstr "'yield' fuera de una función"
#: py/compile.c
msgid "*x must be assignment target"
@@ -225,13 +221,12 @@ msgstr "El canal EXTINT ya está siendo utilizado"
#: shared-bindings/bleio/Address.c
#, c-format
-msgid "Address is not %d bytes long or is in wrong format"
-msgstr "Direción no es %d bytes largo o esta en el formato incorrecto"
+msgid "Address must be %d bytes long"
+msgstr "La dirección debe ser %d bytes de largo"
#: shared-bindings/bleio/Address.c
-#, fuzzy, c-format
-msgid "Address must be %d bytes long"
-msgstr "Direción debe ser %d bytes de largo"
+msgid "Address type out of range"
+msgstr ""
#: ports/nrf/common-hal/busio/I2C.c
msgid "All I2C peripherals are in use"
@@ -242,31 +237,31 @@ msgid "All SPI peripherals are in use"
msgstr "Todos los periféricos SPI están siendo usados"
#: ports/nrf/common-hal/busio/UART.c
-#, fuzzy
msgid "All UART peripherals are in use"
msgstr "Todos los periféricos UART están siendo usados"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "All event channels in use"
-msgstr "Todos los canales de eventos estan en uso"
+msgstr "Todos los canales de eventos estan siendo usados"
#: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "All sync event channels in use"
msgstr ""
-"Todos los canales de eventos de sincronización(sync event channels) están "
+"Todos los canales de eventos de sincronización (sync event channels) están "
"siendo utilizados"
#: shared-bindings/pulseio/PWMOut.c
msgid "All timers for this pin are in use"
msgstr "Todos los timers para este pin están siendo utilizados"
-#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c
#: shared-module/_pew/PewPew.c
msgid "All timers in use"
-msgstr "Todos los timers estan en uso"
+msgstr "Todos los timers en uso"
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
@@ -274,7 +269,7 @@ msgstr "Funcionalidad AnalogOut no soportada"
#: shared-bindings/analogio/AnalogOut.c
msgid "AnalogOut is only 16 bits. Value must be less than 65536."
-msgstr "AnalogOut solo toma 16 bits. El valor debe ser menos de 65536."
+msgstr "AnalogOut es solo de 16 bits. Value debe ser menos a 65536."
#: ports/atmel-samd/common-hal/analogio/AnalogOut.c
msgid "AnalogOut not supported on given pin"
@@ -286,7 +281,7 @@ msgstr "Otro envío ya está activo"
#: shared-bindings/pulseio/PulseOut.c
msgid "Array must contain halfwords (type 'H')"
-msgstr "La matriz debe contener palabras medias (tipo 'H')"
+msgstr "Array debe contener media palabra (type 'H')"
#: shared-bindings/nvm/ByteArray.c
msgid "Array values should be single bytes."
@@ -295,8 +290,8 @@ msgstr "Valores del array deben ser bytes individuales."
#: supervisor/shared/safe_mode.c
msgid "Attempted heap allocation when MicroPython VM not running.\n"
msgstr ""
-"Se intentó la asignación del heap cuando el VM de"
-" MicroPython no estaba corriendo.\n"
+"Intento de allocation de heap cuando la VM de MicroPython no estaba "
+"corriendo.\n"
#: main.c
msgid "Auto-reload is off.\n"
@@ -316,64 +311,64 @@ msgstr "Bit clock y word select deben compartir una unidad de reloj"
#: shared-bindings/audiobusio/PDMIn.c
msgid "Bit depth must be multiple of 8."
-msgstr "La profundidad de bits debe ser múltiplo de 8."
+msgstr "Bits depth debe ser múltiplo de 8."
#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
msgid "Both pins must support hardware interrupts"
msgstr "Ambos pines deben soportar interrupciones por hardware"
+#: shared-bindings/displayio/Display.c
+msgid "Brightness must be 0-1.0"
+msgstr ""
+
#: shared-bindings/supervisor/__init__.c
msgid "Brightness must be between 0 and 255"
-msgstr "Brillo debe estar entro 0 y 255"
+msgstr "El brillo debe estar entro 0 y 255"
#: shared-bindings/displayio/Display.c
msgid "Brightness not adjustable"
-msgstr "Brillo no adjustable"
+msgstr "El brillo no se puede ajustar"
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
msgstr "Tamaño de buffer incorrecto. Debe ser de %d bytes."
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
+#, c-format
+msgid "Buffer length %d too big. It must be less than %d"
+msgstr ""
+
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
msgstr "Buffer debe ser de longitud 1 como minimo"
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
#: ports/nrf/common-hal/displayio/ParallelBus.c
-#, fuzzy, c-format
+#, c-format
msgid "Bus pin %d is already in use"
-msgstr "DAC ya está siendo utilizado"
+msgstr "Bus pin %d ya está siendo utilizado"
#: shared-bindings/bleio/UUID.c
-#, fuzzy
msgid "Byte buffer must be 16 bytes."
-msgstr "buffer debe de ser un objeto bytes-like"
+msgstr "Byte buffer debe de ser 16 bytes"
#: shared-bindings/nvm/ByteArray.c
msgid "Bytes must be between 0 and 255."
msgstr "Bytes debe estar entre 0 y 255."
+#: py/objtype.c
+msgid "Call super().__init__() before accessing native object."
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Can not use dotstar with %s"
msgstr "No se puede usar dotstar con %s"
-#: shared-bindings/bleio/Device.c
-msgid "Can't add services in Central mode"
-msgstr "No se pueden agregar servicio en modo Central"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't advertise in Central mode"
-msgstr "No se puede anunciar en modo Central"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't change the name in Central mode"
-msgstr "No se puede cambiar el nombre en modo Central"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't connect in Peripheral mode"
-msgstr "No se puede conectar en modo Peripheral"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Can't set CCCD for local Characteristic"
+msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
msgid "Cannot delete values"
@@ -385,9 +380,8 @@ msgid "Cannot get pull while in output mode"
msgstr "No puede ser pull mientras este en modo de salida"
#: ports/nrf/common-hal/microcontroller/Processor.c
-#, fuzzy
msgid "Cannot get temperature"
-msgstr "No se puede obtener la temperatura. status: 0x%02x"
+msgstr "No se puede obtener la temperatura."
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Cannot output both channels on the same pin"
@@ -415,11 +409,11 @@ msgstr "No se puede asignar un valor cuando la dirección es input."
#: py/objslice.c
msgid "Cannot subclass slice"
-msgstr ""
+msgstr "Cannot subclass slice"
#: shared-module/bitbangio/SPI.c
msgid "Cannot transfer without MOSI and MISO pins."
-msgstr "No se puede transferir sin pines MOSI y MISO."
+msgstr "No se puede transmitir sin pines MOSI y MISO."
#: extmod/moductypes.c
msgid "Cannot unambiguously get sizeof scalar"
@@ -431,15 +425,15 @@ msgstr "No se puede escribir sin pin MOSI."
#: shared-bindings/bleio/Service.c
msgid "Characteristic UUID doesn't match Service UUID"
-msgstr "Characteristic UUID no iguala al Service UUID"
+msgstr "Características UUID no concide con el Service UUID"
#: ports/nrf/common-hal/bleio/Service.c
msgid "Characteristic already in use by another Service."
-msgstr "Characteristic esta en uso por otro servicio"
+msgstr "Características ya esta en uso por otro Serivice"
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "CharacteristicBuffer writing not provided"
-msgstr ""
+msgstr "CharateristicBuffer escritura no proporcionada"
#: shared-module/bitbangio/SPI.c
msgid "Clock pin init failed."
@@ -447,7 +441,7 @@ msgstr "Clock pin init fallido"
#: shared-module/bitbangio/I2C.c
msgid "Clock stretch too long"
-msgstr ""
+msgstr "Clock stretch demasiado largo "
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Clock unit in use"
@@ -455,33 +449,44 @@ msgstr "Clock unit está siendo utilizado"
#: shared-bindings/_pew/PewPew.c
msgid "Column entry must be digitalio.DigitalInOut"
-msgstr "La entrada en la columna debe ser digitalio.DigitalInOut"
+msgstr "Entrada de columna debe ser digitalio.DigitalInOut"
+
+#: shared-bindings/displayio/I2CDisplay.c
+msgid "Command must be 0-255"
+msgstr ""
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
-#, fuzzy
msgid "Command must be an int between 0 and 255"
-msgstr "Bytes debe estar entre 0 y 255."
+msgstr "Command debe estar entre 0 y 255."
+
+#: py/persistentcode.c
+msgid "Corrupt .mpy file"
+msgstr ""
+
+#: py/emitglue.c
+msgid "Corrupt raw code"
+msgstr ""
#: ports/nrf/common-hal/bleio/UUID.c
#, c-format
msgid "Could not decode ble_uuid, err 0x%04x"
-msgstr "No pudo descodificar ble_uuid, err 0x%04x"
+msgstr "No se puede descodificar ble_uuid, err 0x%04x"
#: ports/atmel-samd/common-hal/busio/UART.c
msgid "Could not initialize UART"
msgstr "No se puede inicializar la UART"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate first buffer"
msgstr "No se pudo asignar el primer buffer"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate second buffer"
msgstr "No se pudo asignar el segundo buffer"
#: supervisor/shared/safe_mode.c
msgid "Crash into the HardFault_Handler.\n"
-msgstr ""
+msgstr "Choque en el HardFault_Handler.\n"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "DAC already in use"
@@ -489,24 +494,16 @@ msgstr "DAC ya está siendo utilizado"
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
#: ports/nrf/common-hal/displayio/ParallelBus.c
-#, fuzzy
msgid "Data 0 pin must be byte aligned"
-msgstr ""
+msgstr "El pin Data 0 debe estar alineado a bytes"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Data chunk must follow fmt chunk"
-msgstr "El Data Chunk debe seguir el fmt chunk"
+msgstr "Trozo de datos debe seguir fmt chunk"
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
-#, fuzzy
msgid "Data too large for advertisement packet"
-msgstr "Los datos no caben en el paquete de anuncio."
-
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Data too large for the advertisement packet"
-msgstr "Los datos no caben en el paquete de anuncio."
+msgstr "Data es muy grande para el paquete de advertisement."
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
@@ -521,6 +518,7 @@ msgid "Drive mode not used when direction is input."
msgstr "Modo Drive no se usa cuando la dirección es input."
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "EXTINT channel already in use"
msgstr "El canal EXTINT ya está siendo utilizado"
@@ -536,27 +534,28 @@ msgid "Expected a %q"
msgstr "Se espera un %q"
#: shared-bindings/bleio/CharacteristicBuffer.c
-#, fuzzy
msgid "Expected a Characteristic"
-msgstr "No se puede agregar la Característica."
+msgstr "Se esperaba una Característica."
#: shared-bindings/bleio/Characteristic.c shared-bindings/bleio/Descriptor.c
#: shared-bindings/bleio/Service.c
-#, fuzzy
msgid "Expected a UUID"
-msgstr "Se espera un %q"
+msgstr "Se esperaba un UUID"
+
+#: shared-bindings/bleio/Central.c
+msgid "Expected an Address"
+msgstr ""
#: shared-module/_pixelbuf/PixelBuf.c
#, c-format
msgid "Expected tuple of length %d, got %d"
msgstr "Se esperaba un tuple de %d, se obtuvo %d"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to acquire mutex"
-msgstr "No se puede adquirir el mutex, status: 0x%08lX"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Failed sending command."
+msgstr "Fallo enviando comando"
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, fuzzy, c-format
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "No se puede adquirir el mutex, status: 0x%08lX"
@@ -564,17 +563,12 @@ msgstr "No se puede adquirir el mutex, status: 0x%08lX"
#: ports/nrf/common-hal/bleio/Service.c
#, fuzzy, c-format
msgid "Failed to add characteristic, err 0x%04x"
-msgstr "No se puede añadir caracteristica, status: 0x%08lX"
-
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to add service"
-msgstr "No se puede detener el anuncio. status: 0x%02x"
+msgstr "Fallo al añadir caracteristica, err: 0x%08lX"
#: ports/nrf/common-hal/bleio/Peripheral.c
-#, fuzzy, c-format
+#, c-format
msgid "Failed to add service, err 0x%04x"
-msgstr "No se puede detener el anuncio. status: 0x%02x"
+msgstr "Fallo al agregar servicio. err: 0x%02x"
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
@@ -587,44 +581,35 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Falló la asignación del buffer RX de %d bytes"
#: ports/nrf/common-hal/bleio/Adapter.c
-#, fuzzy
msgid "Failed to change softdevice state"
-msgstr "No se puede cambiar el estado del softdevice, error: 0x%08lX"
+msgstr "No se puede cambiar el estado del softdevice"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to connect:"
-msgstr "No se puede conectar. status: 0x%02x"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to configure advertising, err 0x%04x"
+msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to continue scanning"
-msgstr "No se puede iniciar el escaneo. status: 0x%02x"
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "Failed to connect: timeout"
+msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
-#, fuzzy, c-format
+#, c-format
msgid "Failed to continue scanning, err 0x%04x"
-msgstr "No se puede iniciar el escaneo. status: 0x%02x"
-
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to create mutex"
-msgstr "No se puede leer el valor del atributo. status 0x%02x"
+msgstr "No se puede iniciar el escaneo. err: 0x%02x"
-#: ports/nrf/common-hal/bleio/Device.c
+#: ports/nrf/common-hal/bleio/Central.c
#, fuzzy
msgid "Failed to discover services"
-msgstr "No se puede descubrir servicios, status: 0x%08lX"
+msgstr "No se puede descubrir servicios"
#: ports/nrf/common-hal/bleio/Adapter.c
-#, fuzzy
msgid "Failed to get local address"
-msgstr "No se puede obtener la dirección local, error: 0x%08lX"
+msgstr "No se puede obtener la dirección local"
#: ports/nrf/common-hal/bleio/Adapter.c
-#, fuzzy
msgid "Failed to get softdevice state"
-msgstr "No se puede obtener el estado del softdevice, error: 0x%08lX"
+msgstr "No se puede obtener el estado del softdevice"
#: ports/nrf/common-hal/bleio/Characteristic.c
#, c-format
@@ -632,9 +617,9 @@ msgid "Failed to notify or indicate attribute value, err 0x%04x"
msgstr "Error al notificar o indicar el valor del atributo, err 0x%04x"
#: ports/nrf/common-hal/bleio/Characteristic.c
-#, fuzzy, c-format
+#, c-format
msgid "Failed to read CCCD value, err 0x%04x"
-msgstr "No se puede leer el valor del atributo. status 0x%02x"
+msgstr "No se puede leer el valor del atributo. err 0x%02x"
#: ports/nrf/common-hal/bleio/Characteristic.c
#, c-format
@@ -642,66 +627,59 @@ msgid "Failed to read attribute value, err 0x%04x"
msgstr "Error al leer valor del atributo, err 0x%04"
#: ports/nrf/common-hal/bleio/Characteristic.c
-#, fuzzy, c-format
+#, c-format
msgid "Failed to read gatts value, err 0x%04x"
msgstr "No se puede escribir el valor del atributo. status: 0x%02x"
#: ports/nrf/common-hal/bleio/UUID.c
-#, fuzzy, c-format
+#, c-format
msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
-msgstr "No se puede agregar el Vendor Specific 128-bit UUID."
+msgstr "Fallo al registrar el Vendor-Specific UUID, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to release mutex"
-msgstr "No se puede liberar el mutex, status: 0x%08lX"
-
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
-#, fuzzy, c-format
+#: ports/nrf/sd_mutex.c
+#, c-format
msgid "Failed to release mutex, err 0x%04x"
-msgstr "No se puede liberar el mutex, status: 0x%08lX"
+msgstr "No se puede liberar el mutex, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to start advertising"
-msgstr "No se puede inicar el anuncio. status: 0x%02x"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to set device name, err 0x%04x"
+msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
-#, fuzzy, c-format
+#, c-format
msgid "Failed to start advertising, err 0x%04x"
-msgstr "No se puede inicar el anuncio. status: 0x%02x"
+msgstr "No se puede inicar el anuncio. err: 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to start scanning"
-msgstr "No se puede iniciar el escaneo. status: 0x%02x"
+#: ports/nrf/common-hal/bleio/Central.c
+#, c-format
+msgid "Failed to start connecting, error 0x%04x"
+msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
-#, fuzzy, c-format
+#, c-format
msgid "Failed to start scanning, err 0x%04x"
-msgstr "No se puede iniciar el escaneo. status: 0x%02x"
-
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to stop advertising"
-msgstr "No se puede detener el anuncio. status: 0x%02x"
+msgstr "No se puede iniciar el escaneo. err 0x%04x"
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
-#, fuzzy, c-format
+#, c-format
msgid "Failed to stop advertising, err 0x%04x"
-msgstr "No se puede detener el anuncio. status: 0x%02x"
+msgstr "No se puede detener el anuncio. err: 0x%04x"
#: ports/nrf/common-hal/bleio/Characteristic.c
-#, fuzzy, c-format
+#, c-format
+msgid "Failed to write CCCD, err 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#, c-format
msgid "Failed to write attribute value, err 0x%04x"
-msgstr "No se puede escribir el valor del atributo. status: 0x%02x"
+msgstr "No se puede escribir el valor del atributo. err: 0x%04x"
#: ports/nrf/common-hal/bleio/Characteristic.c
-#, fuzzy, c-format
+#, c-format
msgid "Failed to write gatts value, err 0x%04x"
-msgstr "No se puede escribir el valor del atributo. status: 0x%02x"
+msgstr "No se puede escribir el valor del atributo. err: 0x%04x"
#: py/moduerrno.c
msgid "File exists"
@@ -734,6 +712,10 @@ msgstr "Frecuencia capturada por encima de la capacidad. Captura en pausa."
msgid "Function requires lock"
msgstr "La función requiere lock"
+#: shared-bindings/displayio/Display.c
+msgid "Group already used"
+msgstr ""
+
#: shared-module/displayio/Group.c
msgid "Group full"
msgstr "Group lleno"
@@ -762,8 +744,8 @@ msgstr "Tamaño incorrecto del buffer"
msgid "Input/output error"
msgstr "error Input/output"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
msgstr "Pin %q inválido"
@@ -782,7 +764,7 @@ msgstr "Argumento inválido"
#: shared-module/displayio/Bitmap.c
msgid "Invalid bits per value"
-msgstr "Bits no válidos por valor"
+msgstr "Inválido bits por valor"
#: ports/nrf/common-hal/busio/UART.c
msgid "Invalid buffer size"
@@ -790,9 +772,9 @@ msgstr "Tamaño de buffer inválido"
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
msgid "Invalid capture period. Valid range: 1 - 500"
-msgstr "Período de captura no válido. Rango válido: 1 - 500"
+msgstr "Inválido periodo de captura. Rango válido: 1 - 500"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid channel count"
msgstr "Cuenta de canales inválida"
@@ -800,13 +782,13 @@ msgstr "Cuenta de canales inválida"
msgid "Invalid direction."
msgstr "Dirección inválida."
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid file"
msgstr "Archivo inválido"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid format chunk size"
-msgstr ""
+msgstr "Formato de fragmento de formato no válido"
#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c
msgid "Invalid number of bits"
@@ -846,11 +828,11 @@ msgstr "Polaridad inválida"
msgid "Invalid run mode."
msgstr "Modo de ejecución inválido."
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr "Cuenta de voces inválida"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid wave file"
msgstr "Archivo wave inválido"
@@ -859,6 +841,10 @@ msgid "LHS of keyword arg must be an id"
msgstr "LHS del agumento por palabra clave deberia ser un identificador"
#: shared-module/displayio/Group.c
+msgid "Layer already in a group."
+msgstr "Layer ya pertenece a un grupo"
+
+#: shared-module/displayio/Group.c
msgid "Layer must be a Group or TileGrid subclass."
msgstr "Layer debe ser una subclase de Group o TileGrid."
@@ -896,7 +882,7 @@ msgstr "Valor máximo de x cuando se refleja es %d"
#: supervisor/shared/safe_mode.c
msgid "MicroPython NLR jump failed. Likely memory corruption.\n"
-msgstr ""
+msgstr "MicroPython NLR salto fallido. Probable corrupción de memoria.\n"
#: supervisor/shared/safe_mode.c
msgid "MicroPython fatal error.\n"
@@ -904,11 +890,15 @@ msgstr "Error fatal de MicroPython.\n"
#: shared-bindings/audiobusio/PDMIn.c
msgid "Microphone startup delay must be in range 0.0 to 1.0"
-msgstr ""
+msgstr "Micrófono demora de inicio debe estar en el rango 0.0 a 1.0"
-#: shared-bindings/displayio/Display.c
-msgid "Must be a Group subclass."
-msgstr "Debe ser una subclase de Group."
+#: shared-bindings/displayio/Group.c
+msgid "Must be a %q subclass."
+msgstr "Debe de ser una subclase de %q"
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "No CCCD for this Characteristic"
+msgstr ""
#: ports/atmel-samd/common-hal/analogio/AnalogOut.c
msgid "No DAC on chip"
@@ -943,6 +933,10 @@ msgstr "Sin GCLKs libres"
msgid "No hardware random available"
msgstr "No hay hardware random disponible"
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
+msgid "No hardware support on clk pin"
+msgstr "Sin soporte de hardware en el pin clk"
+
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "No hardware support on pin"
@@ -956,14 +950,15 @@ msgstr "No queda espacio en el dispositivo"
msgid "No such file/directory"
msgstr "No existe el archivo/directorio"
+#: ports/nrf/common-hal/bleio/Characteristic.c
#: shared-bindings/bleio/CharacteristicBuffer.c
-#, fuzzy
msgid "Not connected"
-msgstr "No se puede conectar a AP"
+msgstr "No conectado"
#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c
+#: shared-bindings/audiopwmio/PWMAudioOut.c
msgid "Not playing"
-msgstr ""
+msgstr "No reproduciendo"
#: shared-bindings/util.c
msgid ""
@@ -978,15 +973,15 @@ msgstr "Paridad impar no soportada"
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Only 8 or 16 bit mono with "
-msgstr ""
+msgstr "Solo mono de 8 ó 16 bit con "
#: shared-module/displayio/OnDiskBitmap.c
#, c-format
msgid ""
"Only Windows format, uncompressed BMP supported: given header size is %d"
msgstr ""
-"Solo formato de Windows, BMP sin compresión soportado: el tamaño del "
-"encabezado dado es %d"
+"Solo formato de Windows, sin comprimir BMP soportado: tamaño de encabezado "
+"dado es %d"
#: shared-module/displayio/OnDiskBitmap.c
#, c-format
@@ -994,6 +989,8 @@ msgid ""
"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp "
"given"
msgstr ""
+"Solo se admiten BMP monocromos, indexados de 8bpp y 16bpp o superiores:% d "
+"bppdado"
#: shared-bindings/_pixelbuf/PixelBuf.c
#, fuzzy
@@ -1002,17 +999,19 @@ msgstr "solo se admiten segmentos con step=1 (alias None)"
#: shared-bindings/audiobusio/PDMIn.c
msgid "Oversample must be multiple of 8."
-msgstr ""
+msgstr "El sobremuestreo debe ser un múltiplo de 8"
#: shared-bindings/pulseio/PWMOut.c
msgid ""
"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
-msgstr ""
+msgstr "PWM duty_cycle debe ser entre 0 y 65535 inclusivo (16 bit resolution)"
#: shared-bindings/pulseio/PWMOut.c
msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
msgstr ""
+"PWM frecuencia no esta escrito cuando el variable_frequency es falso en "
+"construcion"
#: py/moduerrno.c
msgid "Permission denied"
@@ -1025,13 +1024,17 @@ msgstr "Pin no tiene capacidad ADC"
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "Pixel beyond bounds of buffer"
-msgstr ""
+msgstr "Pixel beyond bounds of buffer"
#: py/builtinhelp.c
#, fuzzy
msgid "Plus any modules on the filesystem\n"
msgstr "Incapaz de montar de nuevo el sistema de archivos"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Pop from an empty Ps2 buffer"
+msgstr "Pop de un buffer Ps2 vacio"
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1073,7 +1076,7 @@ msgstr "Canal derecho no soportado"
#: shared-bindings/_pew/PewPew.c
msgid "Row entry must be digitalio.DigitalInOut"
-msgstr ""
+msgstr "La entrada de la fila debe ser digitalio.DigitalInOut"
#: main.c
msgid "Running in safe mode! Auto-reload is off.\n"
@@ -1087,33 +1090,34 @@ msgstr "Ejecutando en modo seguro! No se esta ejecutando el código guardado.\n"
msgid "SDA or SCL needs a pull up"
msgstr "SDA o SCL necesitan una pull up"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Sample rate must be positive"
msgstr "Sample rate debe ser positivo"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#, c-format
msgid "Sample rate too high. It must be less than %d"
msgstr "Frecuencia de muestreo demasiado alta. Debe ser menor a %d"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
msgstr "Serializer está siendo utilizado"
#: shared-bindings/nvm/ByteArray.c
msgid "Slice and value different lengths."
-msgstr "Cortes y valores son de diferentes longitudes."
+msgstr "Slice y value tienen diferentes longitudes"
#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c
#: shared-bindings/displayio/TileGrid.c shared-bindings/pulseio/PulseIn.c
msgid "Slices not supported"
-msgstr "No se soportan los cortes"
+msgstr "Rebanadas no soportadas"
#: ports/nrf/common-hal/bleio/Adapter.c
#, c-format
msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr ""
+msgstr "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
#: extmod/modure.c
msgid "Splitting with sub-captures"
@@ -1135,6 +1139,12 @@ msgid ""
"If you didn't change the stack, then file an issue here with the contents of "
"your CIRCUITPY drive:\n"
msgstr ""
+"El heap de CircuitPython estaba corrupto porque el stack era demasiado "
+"pequeño.\n"
+"Aumente los límites del tamaño del stacj y presione reset (después de "
+"expulsarCIRCUITPY).\n"
+"Si no cambió el stack, entonces reporte un issue aquí con el contenido desu "
+"unidad CIRCUITPY:\n"
#: supervisor/shared/safe_mode.c
msgid ""
@@ -1143,7 +1153,6 @@ msgid ""
msgstr ""
#: supervisor/shared/safe_mode.c
-#, fuzzy
msgid ""
"The microcontroller's power dipped. Please make sure your power supply "
"provides\n"
@@ -1163,19 +1172,19 @@ msgstr ""
"El botón reset fue presionado mientras arrancaba CircuitPython. Presiona "
"otra vez para salir del modo seguro.\n"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's bits_per_sample does not match the mixer's"
msgstr "Los bits_per_sample del sample no igualan a los del mixer"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's channel count does not match the mixer's"
msgstr "La cuenta de canales del sample no iguala a las del mixer"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's sample rate does not match the mixer's"
msgstr "El sample rate del sample no iguala al del mixer"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's signedness does not match the mixer's"
msgstr "El signo del sample no iguala al del mixer"
@@ -1184,12 +1193,16 @@ msgid "Tile height must exactly divide bitmap height"
msgstr "La altura del Tile debe dividir exacto la altura del bitmap"
#: shared-bindings/displayio/TileGrid.c
-msgid "Tile indices must be 0 - 255"
-msgstr "Los índices de Tile deben ser 0 - 255"
+msgid "Tile index out of bounds"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
+msgid "Tile value out of bounds"
+msgstr ""
#: shared-bindings/displayio/TileGrid.c
msgid "Tile width must exactly divide bitmap width"
-msgstr ""
+msgstr "Ancho del Tile debe dividir exactamente el ancho de mapa de bits"
#: supervisor/shared/safe_mode.c
msgid "To exit, please reset the board without "
@@ -1199,9 +1212,10 @@ msgstr "Para salir, por favor reinicia la tarjeta sin "
msgid "Too many channels in sample."
msgstr "Demasiados canales en sample."
-#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
+#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
+#: shared-bindings/displayio/ParallelBus.c
msgid "Too many display busses"
-msgstr ""
+msgstr "Demasiados buses de pantalla"
#: shared-bindings/displayio/Display.c
msgid "Too many displays"
@@ -1224,24 +1238,29 @@ msgid "USB Error"
msgstr "Error USB"
#: shared-bindings/bleio/UUID.c
-msgid "UUID integer value not in range 0 to 0xffff"
-msgstr "El valor integer UUID no está en el rango 0 a 0xffff"
+msgid "UUID integer value must be 0-0xffff"
+msgstr ""
#: shared-bindings/bleio/UUID.c
msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'"
-msgstr "El string UUID no es 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxx'"
+msgstr "UUID string no es 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'"
#: shared-bindings/bleio/UUID.c
msgid "UUID value is not str, int or byte buffer"
-msgstr "El valor UUID no es str, int, or buffer byte"
+msgstr "UUID valor no es un str, int o byte buffer"
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Unable to allocate buffers for signed conversion"
msgstr "No se pudieron asignar buffers para la conversión con signo"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+#: shared-module/displayio/I2CDisplay.c
+#, c-format
+msgid "Unable to find I2C Display at %x"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Unable to find free GCLK"
msgstr "No se pudo encontrar un GCLK libre"
@@ -1259,12 +1278,12 @@ msgstr "Imposible escribir en nvm"
#: ports/nrf/common-hal/bleio/UUID.c
msgid "Unexpected nrfx uuid type"
-msgstr "Tipo nrfx uuid inesperado"
+msgstr "Tipo de uuid nrfx inesperado"
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Unmatched number of items on RHS (expected %d, got %d)."
-msgstr ""
+msgstr "Número incomparable de elementos en RHS (%d esperado,%d obtenido)"
#: ports/atmel-samd/common-hal/busio/I2C.c
msgid "Unsupported baudrate"
@@ -1275,7 +1294,7 @@ msgstr "Baudrate no soportado"
msgid "Unsupported display bus type"
msgstr "tipo de bitmap no soportado"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Unsupported format"
msgstr "Formato no soportado"
@@ -1291,7 +1310,7 @@ msgstr "valor pull no soportado."
msgid "Viper functions don't currently support more than 4 arguments"
msgstr "funciones Viper actualmente no soportan más de 4 argumentos."
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "Voice index too high"
msgstr "Index de voz demasiado alto"
@@ -1316,7 +1335,6 @@ msgstr ""
"Para listar los módulos incorporados por favor haga `help(\"modules\")`.\n"
#: supervisor/shared/safe_mode.c
-#, fuzzy
msgid ""
"You are running in safe mode which means something unanticipated happened.\n"
msgstr ""
@@ -1388,7 +1406,7 @@ msgstr "atributos aún no soportados"
#: ports/nrf/common-hal/bleio/Characteristic.c
msgid "bad GATT role"
-msgstr "Rol GATT malo"
+msgstr "mal GATT role"
#: py/builtinevex.c
msgid "bad compile mode"
@@ -1418,7 +1436,7 @@ msgstr "bits deben ser 7, 8 ó 9"
msgid "bits must be 8"
msgstr "bits debe ser 8"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "bits_per_sample must be 8 or 16"
msgstr "bits_per_sample debe ser 8 ó 16"
@@ -1429,20 +1447,19 @@ msgstr "El argumento de chr() no esta en el rango(256)"
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "buf is too small. need %d bytes"
-msgstr "buf es demasiado pequeño. necesita %d bytes."
+msgstr "buf es demasiado pequeño. necesita %d bytes"
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr "buffer debe de ser un objeto bytes-like"
#: shared-module/struct/__init__.c
-#, fuzzy
msgid "buffer size must match format"
-msgstr "los buffers deben de tener la misma longitud"
+msgstr "el tamaño del buffer debe de coincidir con el formato"
#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c
msgid "buffer slices must be of equal length"
-msgstr "cortes del buffer necesitan ser de tamaño igual"
+msgstr "Las secciones del buffer necesitan tener longitud igual"
#: py/modstruct.c shared-bindings/struct/__init__.c
#: shared-module/struct/__init__.c
@@ -1455,7 +1472,7 @@ msgstr "los buffers deben de tener la misma longitud"
#: shared-bindings/_pew/PewPew.c
msgid "buttons must be digitalio.DigitalInOut"
-msgstr "botones deben ser digitalio.DigitalInOut"
+msgstr "los botones necesitan ser digitalio.DigitalInOut"
#: py/vm.c
msgid "byte code not implemented"
@@ -1464,7 +1481,7 @@ msgstr "codigo byte no implementado"
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "byteorder is not an instance of ByteOrder (got a %s)"
-msgstr "byteorder no es instancia de ByteOrder (encontramos un %s)"
+msgstr "byteorder no es instancia de ByteOrder (encontarmos un %s)"
#: ports/atmel-samd/common-hal/busio/UART.c
msgid "bytes > 8 bits not supported"
@@ -1646,15 +1663,15 @@ msgstr "no se puedo realizar importación relativa"
#: py/emitnative.c
msgid "casting"
-msgstr "emitiendo (casting)"
+msgstr ""
#: shared-bindings/bleio/Service.c
msgid "characteristics includes an object that is not a Characteristic"
-msgstr "charactericas incluye un objeto que no es Characteristic"
+msgstr "characteristics incluye un objeto que no es una Characteristica"
#: shared-bindings/_stage/Text.c
msgid "chars buffer too small"
-msgstr "chars buffer muy pequeño"
+msgstr "chars buffer es demasiado pequeño"
#: py/modbuiltins.c
msgid "chr() arg not in range(0x110000)"
@@ -1666,7 +1683,7 @@ msgstr "El argumento de chr() no esta en el rango(256)"
#: shared-bindings/displayio/Palette.c
msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)"
-msgstr "El burrer de color debe ser 3 bytes (RGB) ó 4 bytes (RGB + pad byte)"
+msgstr "color buffer debe ser 3 bytes (RGB) ó 4 bytes (RGB + pad byte)"
#: shared-bindings/displayio/Palette.c
msgid "color buffer must be a buffer or int"
@@ -1740,7 +1757,7 @@ msgstr "división por cero"
msgid "empty"
msgstr "vacío"
-#: extmod/modutimeq.c extmod/moduheapq.c
+#: extmod/moduheapq.c extmod/modutimeq.c
msgid "empty heap"
msgstr "heap vacío"
@@ -1757,9 +1774,8 @@ msgid "end of format while looking for conversion specifier"
msgstr "el final del formato mientras se busca el especificador de conversión"
#: shared-bindings/displayio/Shape.c
-#, fuzzy
msgid "end_x should be an int"
-msgstr "y deberia ser un int"
+msgstr "end_x debe ser un int"
#: ports/nrf/common-hal/busio/UART.c
#, c-format
@@ -1772,11 +1788,11 @@ msgstr "las excepciones deben derivar de BaseException"
#: py/objstr.c
msgid "expected ':' after format specifier"
-msgstr "se espera ':' despues de un especificaro de tipo format"
+msgstr "se esperaba ':' después de un especificador de tipo format"
#: py/obj.c
msgid "expected tuple/list"
-msgstr "tupla/lista esperada"
+msgstr "se esperaba una tupla/lista"
#: py/modthread.c
msgid "expecting a dict for keyword args"
@@ -1802,7 +1818,8 @@ msgstr "argumento(s) por palabra clave adicionales fueron dados"
msgid "extra positional arguments given"
msgstr "argumento posicional adicional dado"
-#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c
+#: shared-bindings/audiocore/WaveFile.c
+#: shared-bindings/displayio/OnDiskBitmap.c
msgid "file must be a file opened in byte mode"
msgstr "el archivo deberia ser una archivo abierto en modo byte"
@@ -1820,7 +1837,7 @@ msgstr "firstbit debe ser MSB"
#: py/objint.c
msgid "float too big"
-msgstr "float es demasiado grande"
+msgstr ""
#: shared-bindings/_stage/Text.c
msgid "font must be 2048 bytes long"
@@ -1904,7 +1921,7 @@ msgstr "formato incompleto"
#: py/objstr.c
msgid "incomplete format key"
-msgstr "llave de formato incompleto"
+msgstr ""
#: extmod/modubinascii.c
msgid "incorrect padding"
@@ -1931,9 +1948,10 @@ msgstr "int() arg 2 debe ser >= 2 y <= 36"
msgid "integer required"
msgstr "Entero requerido"
-#: ports/nrf/common-hal/bleio/Broadcaster.c
-msgid "interval not in range 0.0020 to 10.24"
-msgstr "El intervalo está fuera del rango de 0.0020 a 10.24"
+#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c
+#, c-format
+msgid "interval must be in range %s-%s"
+msgstr ""
#: extmod/machine_i2c.c
msgid "invalid I2C peripheral"
@@ -1973,7 +1991,7 @@ msgstr "decorador de micropython inválido"
#: shared-bindings/random/__init__.c
msgid "invalid step"
-msgstr "paso invalido"
+msgstr ""
#: py/compile.c py/parse.c
msgid "invalid syntax"
@@ -2078,7 +2096,7 @@ msgstr "múltiples *x en la asignación"
#: py/objtype.c
msgid "multiple bases have instance lay-out conflict"
-msgstr "múltiples bases tienen conflicto de diseño"
+msgstr "multiple bases tienen una instancia conel conflicto diseño"
#: py/objtype.c
msgid "multiple inheritance not supported"
@@ -2101,9 +2119,8 @@ msgid "name '%q' is not defined"
msgstr "name '%q' no esta definido"
#: shared-bindings/bleio/Peripheral.c
-#, fuzzy
msgid "name must be a string"
-msgstr "palabras clave deben ser strings"
+msgstr "name debe de ser un string"
#: py/runtime.c
msgid "name not defined"
@@ -2111,11 +2128,11 @@ msgstr "name no definido"
#: py/compile.c
msgid "name reused for argument"
-msgstr "nombre reusado para argumento"
+msgstr "name reusado para argumento"
#: py/emitnative.c
msgid "native yield"
-msgstr "rendimiento nativo"
+msgstr "yield nativo"
#: py/runtime.c
#, c-format
@@ -2128,7 +2145,7 @@ msgstr "potencia negativa sin float support"
#: py/objint_mpz.c py/runtime.c
msgid "negative shift count"
-msgstr "cuenta negativa de turnos"
+msgstr "cuenta de corrimientos negativo"
#: py/vm.c
msgid "no active exception to reraise"
@@ -2150,6 +2167,14 @@ msgstr "ningún módulo se llama '%q'"
msgid "no such attribute"
msgstr "no hay tal atributo"
+#: shared-bindings/bleio/Peripheral.c
+msgid "non-Service found in services"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "non-UUID found in service_uuids"
+msgstr ""
+
#: py/compile.c
msgid "non-default argument follows default argument"
msgstr "argumento no predeterminado sigue argumento predeterminado"
@@ -2170,7 +2195,7 @@ msgstr ""
#: shared-bindings/bleio/UUID.c
msgid "not a 128-bit UUID"
-msgstr "no es un UUID de 128-bits"
+msgstr "no es 128-bit UUID"
#: py/objstr.c
msgid "not all arguments converted during string formatting"
@@ -2210,7 +2235,7 @@ msgstr "objeto no es un iterator"
msgid "object not callable"
msgstr "objeto no puede ser llamado"
-#: py/sequence.c
+#: py/sequence.c shared-bindings/displayio/Group.c
msgid "object not in sequence"
msgstr "objeto no en secuencia"
@@ -2275,13 +2300,12 @@ msgid "parameters must be registers in sequence r0 to r3"
msgstr "los parametros deben ser registros en secuencia del r0 al r3"
#: shared-bindings/displayio/Bitmap.c
-#, fuzzy
msgid "pixel coordinates out of bounds"
-msgstr "address fuera de límites"
+msgstr "coordenadas del pixel fuera de límites"
#: shared-bindings/displayio/Bitmap.c
msgid "pixel value requires too many bits"
-msgstr "valor de píxel requiere demasiado bits"
+msgstr "valor del pixel require demasiado bits"
#: shared-bindings/displayio/TileGrid.c
msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter"
@@ -2318,7 +2342,7 @@ msgstr "desbordamiento de cola(queue)"
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "rawbuf is not the same size as buf"
-msgstr "rawbuf no es el miso tamaño que buf"
+msgstr "rawbuf no es el mismo tamaño que buf"
#: shared-bindings/_pixelbuf/__init__.c
#, fuzzy
@@ -2344,9 +2368,9 @@ msgstr "retorno esperado '%q' pero se obtuvo '%q'"
#: py/objstr.c
msgid "rsplit(None,n)"
-msgstr ""
+msgstr "rsplit(None,n)"
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid ""
"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or "
"'B'"
@@ -2366,10 +2390,6 @@ msgstr ""
msgid "script compilation not supported"
msgstr "script de compilación no soportado"
-#: shared-bindings/bleio/Peripheral.c
-msgid "services includes an object that is not a Service"
-msgstr "services incluye un objeto que no es servicio"
-
#: py/objstr.c
msgid "sign not allowed in string format specifier"
msgstr "signo no permitido en el espeficador de string format"
@@ -2409,7 +2429,7 @@ msgstr "y deberia ser un int"
#: shared-bindings/random/__init__.c
msgid "step must be non-zero"
-msgstr "paso debe ser numero no-cero"
+msgstr "paso debe ser numero no cero"
#: shared-bindings/busio/UART.c
msgid "stop must be 1 or 2"
@@ -2417,7 +2437,7 @@ msgstr "stop debe ser 1 ó 2"
#: shared-bindings/random/__init__.c
msgid "stop not reachable from start"
-msgstr ""
+msgstr "stop no se puede alcanzar del principio"
#: py/stream.c
msgid "stream operation not supported"
@@ -2466,15 +2486,11 @@ msgstr "error de sintaxis en el descriptor uctypes"
#: shared-bindings/touchio/TouchIn.c
msgid "threshold must be in the range 0-65536"
-msgstr "threshold debe estar en el rango 0 a 65536"
-
-#: shared-bindings/displayio/TileGrid.c
-msgid "tile index out of bounds"
-msgstr ""
+msgstr "limite debe ser en el rango 0-65536"
#: shared-bindings/time/__init__.c
msgid "time.struct_time() takes a 9-sequence"
-msgstr ""
+msgstr "time.struct_time() toma un sequencio 9"
#: shared-bindings/time/__init__.c
msgid "time.struct_time() takes exactly 1 argument"
@@ -2482,16 +2498,15 @@ msgstr "time.struct_time() acepta exactamente 1 argumento"
#: shared-bindings/busio/UART.c
msgid "timeout >100 (units are now seconds, not msecs)"
-msgstr "tiempo muerto >100 (unidades en segundos)"
+msgstr "timepo muerto >100 (unidades en segundos)"
#: shared-bindings/bleio/CharacteristicBuffer.c
-#, fuzzy
msgid "timeout must be >= 0.0"
-msgstr "tiempo muerto debe ser 8"
+msgstr "tiempo muerto debe ser >= 0.0"
#: shared-bindings/time/__init__.c
msgid "timestamp out of range for platform time_t"
-msgstr ""
+msgstr "timestamp fuera de rango para plataform time_t"
#: shared-module/struct/__init__.c
msgid "too many arguments provided with the given format"
@@ -2512,7 +2527,7 @@ msgstr "tupla/lista tiene una longitud incorrecta"
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "tuple/list required on RHS"
-msgstr "tuple o lista se requiere en RHS"
+msgstr "tuple/lista se require en RHS"
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "tx and rx cannot both be None"
@@ -2556,7 +2571,7 @@ msgstr "argumento por palabra clave inesperado '%q'"
#: py/lexer.c
msgid "unicode name escapes"
-msgstr ""
+msgstr "nombre en unicode escapa"
#: py/parse.c
msgid "unindent does not match any outer indentation level"
@@ -2631,16 +2646,20 @@ msgstr "tipos no soportados para %q: '%s', '%s'"
#: py/objint.c
#, c-format
-msgid "value would overflow a %d byte buffer"
+msgid "value must fit in %d byte(s)"
msgstr ""
#: shared-bindings/displayio/Bitmap.c
msgid "value_count must be > 0"
-msgstr "value_count debe ser > 0"
+msgstr ""
+
+#: shared-bindings/bleio/Scanner.c
+msgid "window must be <= interval"
+msgstr ""
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "write_args must be a list, tuple, or None"
-msgstr "write_args debe ser lista, tuple, o None"
+msgstr ""
#: py/objstr.c
msgid "wrong number of arguments"
@@ -2671,6 +2690,21 @@ msgstr "paso cero"
#~ msgid "AP required"
#~ msgstr "AP requerido"
+#~ msgid "Address is not %d bytes long or is in wrong format"
+#~ msgstr "Direción no es %d bytes largo o esta en el formato incorrecto"
+
+#~ msgid "Can't add services in Central mode"
+#~ msgstr "No se pueden agregar servicio en modo Central"
+
+#~ msgid "Can't advertise in Central mode"
+#~ msgstr "No se puede anunciar en modo Central"
+
+#~ msgid "Can't change the name in Central mode"
+#~ msgstr "No se puede cambiar el nombre en modo Central"
+
+#~ msgid "Can't connect in Peripheral mode"
+#~ msgstr "No se puede conectar en modo Peripheral"
+
#~ msgid "Cannot connect to AP"
#~ msgstr "No se puede conectar a AP"
@@ -2683,6 +2717,10 @@ msgstr "paso cero"
#~ msgid "Cannot update i/f status"
#~ msgstr "No se puede actualizar i/f status"
+#, fuzzy
+#~ msgid "Data too large for the advertisement packet"
+#~ msgstr "Los datos no caben en el paquete de anuncio."
+
#~ msgid "Don't know how to pass object to native function"
#~ msgstr "No se sabe cómo pasar objeto a función nativa"
@@ -2696,6 +2734,26 @@ msgstr "paso cero"
#~ msgstr "Error en ffi_prep_cif"
#, fuzzy
+#~ msgid "Failed to acquire mutex"
+#~ msgstr "No se puede adquirir el mutex, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to add service"
+#~ msgstr "No se puede detener el anuncio. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to connect:"
+#~ msgstr "No se puede conectar. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to continue scanning"
+#~ msgstr "No se puede iniciar el escaneo. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to create mutex"
+#~ msgstr "No se puede leer el valor del atributo. status 0x%02x"
+
+#, fuzzy
#~ msgid "Failed to notify or indicate attribute value, err %0x04x"
#~ msgstr "No se puede notificar el valor del anuncio. status: 0x%02x"
@@ -2703,6 +2761,22 @@ msgstr "paso cero"
#~ msgid "Failed to read attribute value, err %0x04x"
#~ msgstr "No se puede leer el valor del atributo. status 0x%02x"
+#, fuzzy
+#~ msgid "Failed to release mutex"
+#~ msgstr "No se puede liberar el mutex, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to start advertising"
+#~ msgstr "No se puede inicar el anuncio. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to start scanning"
+#~ msgstr "No se puede iniciar el escaneo. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to stop advertising"
+#~ msgstr "No se puede detener el anuncio. status: 0x%02x"
+
#~ msgid "Function requires lock."
#~ msgstr "La función requiere lock"
@@ -2728,6 +2802,9 @@ msgstr "paso cero"
#~ msgstr ""
#~ "PWM de múltiples frecuencias no soportado. El PWM ya se estableció a %dhz"
+#~ msgid "Must be a Group subclass."
+#~ msgstr "Debe ser una subclase de Group."
+
#~ msgid "No PulseIn support for %q"
#~ msgstr "Sin soporte PulseIn para %q"
@@ -2737,13 +2814,6 @@ msgstr "paso cero"
#~ msgid "Not connected."
#~ msgstr "No conectado."
-#~ msgid ""
-#~ "Only 8 or 16 bit mono with MP_STRINGIFY(OVERSAMPLING) x oversampling is "
-#~ "supported."
-#~ msgstr ""
-#~ "Solo 8 ó 16 bit mono con MP_STRINGIFY(OVERSAMPLING) x de sobremuestreo es "
-#~ "soportado."
-
#~ msgid "Only Windows format, uncompressed BMP supported %d"
#~ msgstr "Solo formato Windows, BMP sin comprimir soportado %d"
@@ -2774,12 +2844,18 @@ msgstr "paso cero"
#~ msgid "STA required"
#~ msgstr "STA requerido"
+#~ msgid "Tile indices must be 0 - 255"
+#~ msgstr "Los índices de Tile deben ser 0 - 255"
+
#~ msgid "UART(%d) does not exist"
#~ msgstr "UART(%d) no existe"
#~ msgid "UART(1) can't read"
#~ msgstr "UART(1) no puede leer"
+#~ msgid "UUID integer value not in range 0 to 0xffff"
+#~ msgstr "El valor integer UUID no está en el rango 0 a 0xffff"
+
#~ msgid "Unable to remount filesystem"
#~ msgstr "Incapaz de montar de nuevo el sistema de archivos"
@@ -2829,6 +2905,9 @@ msgstr "paso cero"
#~ msgid "impossible baudrate"
#~ msgstr "baudrate imposible"
+#~ msgid "interval not in range 0.0020 to 10.24"
+#~ msgstr "El intervalo está fuera del rango de 0.0020 a 10.24"
+
#~ msgid "invalid alarm"
#~ msgstr "alarma inválida"
@@ -2866,6 +2945,12 @@ msgstr "paso cero"
#~ msgid "scan failed"
#~ msgstr "scan ha fallado"
+#~ msgid "services includes an object that is not a Service"
+#~ msgstr "services incluye un objeto que no es servicio"
+
+#~ msgid "tile index out of bounds"
+#~ msgstr "el indice del tile fuera de limite"
+
#~ msgid "too many arguments"
#~ msgstr "muchos argumentos"
diff --git a/locale/fil.po b/locale/fil.po
index bc9b80e78..f83429882 100644
--- a/locale/fil.po
+++ b/locale/fil.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-05-09 01:06-0400\n"
+"POT-Creation-Date: 2019-07-31 16:30-0500\n"
"PO-Revision-Date: 2018-12-20 22:15-0800\n"
"Last-Translator: Timothy <me@timothygarcia.ca>\n"
"Language-Team: fil\n"
@@ -52,8 +52,8 @@ msgstr "%q indeks wala sa sakop"
msgid "%q indices must be integers, not %s"
msgstr "%q indeks ay dapat integers, hindi %s"
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
#, fuzzy
msgid "%q must be >= 1"
msgstr "aarehas na haba dapat ang buffer slices"
@@ -221,15 +221,14 @@ msgid "A hardware interrupt channel is already in use"
msgstr "Isang channel ng hardware interrupt ay ginagamit na"
#: shared-bindings/bleio/Address.c
-#, c-format
-msgid "Address is not %d bytes long or is in wrong format"
-msgstr ""
-
-#: shared-bindings/bleio/Address.c
#, fuzzy, c-format
msgid "Address must be %d bytes long"
msgstr "ang palette ay dapat 32 bytes ang haba"
+#: shared-bindings/bleio/Address.c
+msgid "Address type out of range"
+msgstr ""
+
#: ports/nrf/common-hal/busio/I2C.c
msgid "All I2C peripherals are in use"
msgstr "Lahat ng I2C peripherals ginagamit"
@@ -255,9 +254,10 @@ msgstr "Lahat ng sync event channels ay ginagamit"
msgid "All timers for this pin are in use"
msgstr "Lahat ng timers para sa pin na ito ay ginagamit"
-#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c
#: shared-module/_pew/PewPew.c
msgid "All timers in use"
@@ -315,6 +315,10 @@ msgstr "Bit depth ay dapat multiple ng 8."
msgid "Both pins must support hardware interrupts"
msgstr "Ang parehong mga pin ay dapat na sumusuporta sa hardware interrupts"
+#: shared-bindings/displayio/Display.c
+msgid "Brightness must be 0-1.0"
+msgstr ""
+
#: shared-bindings/supervisor/__init__.c
msgid "Brightness must be between 0 and 255"
msgstr "Ang liwanag ay dapat sa gitna ng 0 o 255"
@@ -328,6 +332,11 @@ msgstr ""
msgid "Buffer incorrect size. Should be %d bytes."
msgstr "Mali ang size ng buffer. Dapat %d bytes."
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
+#, c-format
+msgid "Buffer length %d too big. It must be less than %d"
+msgstr ""
+
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
msgstr "Buffer dapat ay hindi baba sa 1 na haba"
@@ -347,26 +356,18 @@ msgstr "buffer ay dapat bytes-like object"
msgid "Bytes must be between 0 and 255."
msgstr "Sa gitna ng 0 o 255 dapat ang bytes."
+#: py/objtype.c
+msgid "Call super().__init__() before accessing native object."
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Can not use dotstar with %s"
msgstr ""
-#: shared-bindings/bleio/Device.c
-msgid "Can't add services in Central mode"
-msgstr "Hindi maarang maglagay ng service sa Central mode"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't advertise in Central mode"
-msgstr "Hindi ma advertise habang nasa Central mode"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't change the name in Central mode"
-msgstr "Hindi mapalitan ang pangalan sa Central mode"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't connect in Peripheral mode"
-msgstr "Hindi maconnect sa Peripheral mode"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Can't set CCCD for local Characteristic"
+msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
msgid "Cannot delete values"
@@ -450,11 +451,23 @@ msgstr "Clock unit ginagamit"
msgid "Column entry must be digitalio.DigitalInOut"
msgstr ""
+#: shared-bindings/displayio/I2CDisplay.c
+msgid "Command must be 0-255"
+msgstr ""
+
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
#, fuzzy
msgid "Command must be an int between 0 and 255"
msgstr "Sa gitna ng 0 o 255 dapat ang bytes."
+#: py/persistentcode.c
+msgid "Corrupt .mpy file"
+msgstr ""
+
+#: py/emitglue.c
+msgid "Corrupt raw code"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/UUID.c
#, c-format
msgid "Could not decode ble_uuid, err 0x%04x"
@@ -464,11 +477,11 @@ msgstr ""
msgid "Could not initialize UART"
msgstr "Hindi ma-initialize ang UART"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate first buffer"
msgstr "Hindi ma-iallocate ang first buffer"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate second buffer"
msgstr "Hindi ma-iallocate ang second buffer"
@@ -486,21 +499,15 @@ msgstr "Ginagamit na ang DAC"
msgid "Data 0 pin must be byte aligned"
msgstr "graphic ay dapat 2048 bytes ang haba"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Data chunk must follow fmt chunk"
msgstr "Dapat sunurin ng Data chunk ang fmt chunk"
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy
msgid "Data too large for advertisement packet"
msgstr "Hindi makasya ang data sa loob ng advertisement packet"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Data too large for the advertisement packet"
-msgstr "Hindi makasya ang data sa loob ng advertisement packet"
-
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr ""
@@ -515,6 +522,7 @@ msgid "Drive mode not used when direction is input."
msgstr "Drive mode ay hindi ginagamit kapag ang direksyon ay input."
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "EXTINT channel already in use"
msgstr "Ginagamit na ang EXTINT channel"
@@ -540,17 +548,20 @@ msgstr "Hindi mabasa and Characteristic."
msgid "Expected a UUID"
msgstr "Umasa ng %q"
+#: shared-bindings/bleio/Central.c
+msgid "Expected an Address"
+msgstr ""
+
#: shared-module/_pixelbuf/PixelBuf.c
#, c-format
msgid "Expected tuple of length %d, got %d"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to acquire mutex"
-msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Failed sending command."
+msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, fuzzy, c-format
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX"
@@ -560,11 +571,6 @@ msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX"
msgid "Failed to add characteristic, err 0x%04x"
msgstr "Nabigo sa paglagay ng characteristic, status: 0x%08lX"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to add service"
-msgstr "Hindi matagumpay ang paglagay ng service, status: 0x%08lX"
-
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy, c-format
msgid "Failed to add service, err 0x%04x"
@@ -585,27 +591,21 @@ msgstr "Nabigong ilaan ang RX buffer ng %d bytes"
msgid "Failed to change softdevice state"
msgstr "Nabigo sa pagbago ng softdevice state, error: 0x%08lX"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to connect:"
-msgstr "Hindi makaconnect, status: 0x%08lX"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to configure advertising, err 0x%04x"
+msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to continue scanning"
-msgstr "Hindi maituloy ang pag scan, status: 0x%0xlX"
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "Failed to connect: timeout"
+msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
#, fuzzy, c-format
msgid "Failed to continue scanning, err 0x%04x"
msgstr "Hindi maituloy ang pag scan, status: 0x%0xlX"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to create mutex"
-msgstr "Hindi matagumpay ang pagbuo ng mutex, status: 0x%0xlX"
-
-#: ports/nrf/common-hal/bleio/Device.c
+#: ports/nrf/common-hal/bleio/Central.c
#, fuzzy
msgid "Failed to discover services"
msgstr "Nabigo sa pagdiscover ng services, status: 0x%08lX"
@@ -645,49 +645,42 @@ msgstr "Hindi maisulat ang gatts value, status: 0x%08lX"
msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
msgstr "Hindi matagumpay ang paglagay ng Vender Specific UUID, status: 0x%08lX"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to release mutex"
-msgstr "Nabigo sa pagrelease ng mutex, status: 0x%08lX"
-
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, fuzzy, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "Nabigo sa pagrelease ng mutex, status: 0x%08lX"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to start advertising"
-msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to set device name, err 0x%04x"
+msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy, c-format
msgid "Failed to start advertising, err 0x%04x"
msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to start scanning"
-msgstr "Hindi masimulaan mag i-scan, status: 0x%0xlX"
+#: ports/nrf/common-hal/bleio/Central.c
+#, c-format
+msgid "Failed to start connecting, error 0x%04x"
+msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
#, fuzzy, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "Hindi masimulaan mag i-scan, status: 0x%0xlX"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to stop advertising"
-msgstr "Hindi mahinto ang advertisement, status: 0x%08lX"
-
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy, c-format
msgid "Failed to stop advertising, err 0x%04x"
msgstr "Hindi mahinto ang advertisement, status: 0x%08lX"
#: ports/nrf/common-hal/bleio/Characteristic.c
+#, c-format
+msgid "Failed to write CCCD, err 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
#, fuzzy, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "Hindi maisulat ang attribute value, status: 0x%08lX"
@@ -728,6 +721,10 @@ msgstr ""
msgid "Function requires lock"
msgstr "Function nangangailangan ng lock"
+#: shared-bindings/displayio/Display.c
+msgid "Group already used"
+msgstr ""
+
#: shared-module/displayio/Group.c
msgid "Group full"
msgstr "Puno ang group"
@@ -756,8 +753,8 @@ msgstr ""
msgid "Input/output error"
msgstr "May mali sa Input/Output"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
msgstr "Mali ang %q pin"
@@ -786,7 +783,7 @@ msgstr "Mali ang buffer size"
msgid "Invalid capture period. Valid range: 1 - 500"
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid channel count"
msgstr "Maling bilang ng channel"
@@ -794,11 +791,11 @@ msgstr "Maling bilang ng channel"
msgid "Invalid direction."
msgstr "Mali ang direksyon."
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid file"
msgstr "Mali ang file"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid format chunk size"
msgstr "Mali ang format ng chunk size"
@@ -840,11 +837,11 @@ msgstr "Mali ang polarity"
msgid "Invalid run mode."
msgstr "Mali ang run mode."
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr "Maling bilang ng voice"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid wave file"
msgstr "May hindi tama sa wave file"
@@ -853,6 +850,10 @@ msgid "LHS of keyword arg must be an id"
msgstr "LHS ng keyword arg ay dapat na id"
#: shared-module/displayio/Group.c
+msgid "Layer already in a group."
+msgstr ""
+
+#: shared-module/displayio/Group.c
msgid "Layer must be a Group or TileGrid subclass."
msgstr ""
@@ -900,8 +901,12 @@ msgstr "CircuitPython fatal na pagkakamali.\n"
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr "Ang delay ng startup ng mikropono ay dapat na nasa 0.0 hanggang 1.0"
-#: shared-bindings/displayio/Display.c
-msgid "Must be a Group subclass."
+#: shared-bindings/displayio/Group.c
+msgid "Must be a %q subclass."
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "No CCCD for this Characteristic"
msgstr ""
#: ports/atmel-samd/common-hal/analogio/AnalogOut.c
@@ -937,6 +942,10 @@ msgstr "Walang libreng GCLKs"
msgid "No hardware random available"
msgstr "Walang magagamit na hardware random"
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
+msgid "No hardware support on clk pin"
+msgstr ""
+
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "No hardware support on pin"
@@ -950,12 +959,14 @@ msgstr ""
msgid "No such file/directory"
msgstr "Walang file/directory"
+#: ports/nrf/common-hal/bleio/Characteristic.c
#: shared-bindings/bleio/CharacteristicBuffer.c
#, fuzzy
msgid "Not connected"
msgstr "Hindi maka connect sa AP"
#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c
+#: shared-bindings/audiopwmio/PWMAudioOut.c
msgid "Not playing"
msgstr "Hindi playing"
@@ -1024,6 +1035,10 @@ msgstr ""
msgid "Plus any modules on the filesystem\n"
msgstr "Kasama ang kung ano pang modules na sa filesystem\n"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Pop from an empty Ps2 buffer"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1080,17 +1095,18 @@ msgstr "Tumatakbo sa safe mode! Hindi tumatakbo ang nai-save na code.\n"
msgid "SDA or SCL needs a pull up"
msgstr "Kailangan ng pull up resistors ang SDA o SCL"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Sample rate must be positive"
msgstr "Sample rate ay dapat positibo"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#, c-format
msgid "Sample rate too high. It must be less than %d"
msgstr "Sample rate ay masyadong mataas. Ito ay dapat hindi hiigit sa %d"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
msgstr "Serializer ginagamit"
@@ -1159,19 +1175,19 @@ msgstr ""
"Ang reset button ay pinindot habang nag boot ang CircuitPython. Pindutin "
"ulit para lumabas sa safe mode.\n"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's bits_per_sample does not match the mixer's"
msgstr "Ang bits_per_sample ng sample ay hindi tugma sa mixer"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's channel count does not match the mixer's"
msgstr "Ang channel count ng sample ay hindi tugma sa mixer"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's sample rate does not match the mixer's"
msgstr "Ang sample rate ng sample ay hindi tugma sa mixer"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's signedness does not match the mixer's"
msgstr "Ang signedness ng sample hindi tugma sa mixer"
@@ -1180,7 +1196,11 @@ msgid "Tile height must exactly divide bitmap height"
msgstr ""
#: shared-bindings/displayio/TileGrid.c
-msgid "Tile indices must be 0 - 255"
+msgid "Tile index out of bounds"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
+msgid "Tile value out of bounds"
msgstr ""
#: shared-bindings/displayio/TileGrid.c
@@ -1195,7 +1215,8 @@ msgstr "Para lumabas, paki-reset ang board na wala ang "
msgid "Too many channels in sample."
msgstr "Sobra ang channels sa sample."
-#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
+#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
+#: shared-bindings/displayio/ParallelBus.c
msgid "Too many display busses"
msgstr ""
@@ -1220,7 +1241,7 @@ msgid "USB Error"
msgstr "May pagkakamali ang USB"
#: shared-bindings/bleio/UUID.c
-msgid "UUID integer value not in range 0 to 0xffff"
+msgid "UUID integer value must be 0-0xffff"
msgstr ""
#: shared-bindings/bleio/UUID.c
@@ -1236,8 +1257,13 @@ msgstr ""
msgid "Unable to allocate buffers for signed conversion"
msgstr "Hindi ma-allocate ang buffers para sa naka-sign na conversion"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+#: shared-module/displayio/I2CDisplay.c
+#, c-format
+msgid "Unable to find I2C Display at %x"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Unable to find free GCLK"
msgstr "Hindi mahanap ang libreng GCLK"
@@ -1272,7 +1298,7 @@ msgstr "Hindi supportadong baudrate"
msgid "Unsupported display bus type"
msgstr "Hindi supportadong tipo ng bitmap"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Unsupported format"
msgstr "Hindi supportadong format"
@@ -1290,7 +1316,7 @@ msgstr ""
"Ang mga function ng Viper ay kasalukuyang hindi sumusuporta sa higit sa 4 na "
"argumento"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "Voice index too high"
msgstr "Index ng Voice ay masyadong mataas"
@@ -1414,7 +1440,7 @@ msgstr "bits ay dapat 7, 8 o 9"
msgid "bits must be 8"
msgstr "bits ay dapat walo (8)"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "bits_per_sample must be 8 or 16"
msgstr "bits_per_sample ay dapat 8 o 16"
@@ -1427,7 +1453,7 @@ msgstr "branch wala sa range"
msgid "buf is too small. need %d bytes"
msgstr ""
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr "buffer ay dapat bytes-like object"
@@ -1739,7 +1765,7 @@ msgstr "dibisyon ng zero"
msgid "empty"
msgstr "walang laman"
-#: extmod/modutimeq.c extmod/moduheapq.c
+#: extmod/moduheapq.c extmod/modutimeq.c
msgid "empty heap"
msgstr "walang laman ang heap"
@@ -1801,7 +1827,8 @@ msgstr "dagdag na keyword argument na ibinigay"
msgid "extra positional arguments given"
msgstr "dagdag na positional argument na ibinigay"
-#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c
+#: shared-bindings/audiocore/WaveFile.c
+#: shared-bindings/displayio/OnDiskBitmap.c
msgid "file must be a file opened in byte mode"
msgstr "file ay dapat buksan sa byte mode"
@@ -1931,8 +1958,9 @@ msgstr "int() arg 2 ay dapat >=2 at <= 36"
msgid "integer required"
msgstr "kailangan ng int"
-#: ports/nrf/common-hal/bleio/Broadcaster.c
-msgid "interval not in range 0.0020 to 10.24"
+#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c
+#, c-format
+msgid "interval must be in range %s-%s"
msgstr ""
#: extmod/machine_i2c.c
@@ -2151,6 +2179,14 @@ msgstr "walang module na '%q'"
msgid "no such attribute"
msgstr "walang ganoon na attribute"
+#: shared-bindings/bleio/Peripheral.c
+msgid "non-Service found in services"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "non-UUID found in service_uuids"
+msgstr ""
+
#: py/compile.c
msgid "non-default argument follows default argument"
msgstr "non-default argument sumusunod sa default argument"
@@ -2208,7 +2244,7 @@ msgstr "object ay hindi iterator"
msgid "object not callable"
msgstr "hindi matatawag ang object"
-#: py/sequence.c
+#: py/sequence.c shared-bindings/displayio/Group.c
msgid "object not in sequence"
msgstr "object wala sa sequence"
@@ -2344,7 +2380,7 @@ msgstr "return umasa ng '%q' pero ang nakuha ay ‘%q’"
msgid "rsplit(None,n)"
msgstr "rsplit(None,n)"
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid ""
"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or "
"'B'"
@@ -2364,10 +2400,6 @@ msgstr "puno na ang schedule stack"
msgid "script compilation not supported"
msgstr "script kompilasyon hindi supportado"
-#: shared-bindings/bleio/Peripheral.c
-msgid "services includes an object that is not a Service"
-msgstr ""
-
#: py/objstr.c
msgid "sign not allowed in string format specifier"
msgstr "sign hindi maaring string format specifier"
@@ -2466,10 +2498,6 @@ msgstr "may pagkakamali sa sintaks sa uctypes descriptor"
msgid "threshold must be in the range 0-65536"
msgstr "ang threshold ay dapat sa range 0-65536"
-#: shared-bindings/displayio/TileGrid.c
-msgid "tile index out of bounds"
-msgstr ""
-
#: shared-bindings/time/__init__.c
msgid "time.struct_time() takes a 9-sequence"
msgstr "time.struct_time() kumukuha ng 9-sequence"
@@ -2629,13 +2657,17 @@ msgstr "hindi sinusuportahang type para sa %q: '%s', '%s'"
#: py/objint.c
#, c-format
-msgid "value would overflow a %d byte buffer"
+msgid "value must fit in %d byte(s)"
msgstr ""
#: shared-bindings/displayio/Bitmap.c
msgid "value_count must be > 0"
msgstr ""
+#: shared-bindings/bleio/Scanner.c
+msgid "window must be <= interval"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "write_args must be a list, tuple, or None"
msgstr ""
@@ -2672,6 +2704,18 @@ msgstr "zero step"
#~ msgid "C-level assert"
#~ msgstr "C-level assert"
+#~ msgid "Can't add services in Central mode"
+#~ msgstr "Hindi maarang maglagay ng service sa Central mode"
+
+#~ msgid "Can't advertise in Central mode"
+#~ msgstr "Hindi ma advertise habang nasa Central mode"
+
+#~ msgid "Can't change the name in Central mode"
+#~ msgstr "Hindi mapalitan ang pangalan sa Central mode"
+
+#~ msgid "Can't connect in Peripheral mode"
+#~ msgstr "Hindi maconnect sa Peripheral mode"
+
#~ msgid "Cannot connect to AP"
#~ msgstr "Hindi maka connect sa AP"
@@ -2684,6 +2728,10 @@ msgstr "zero step"
#~ msgid "Cannot update i/f status"
#~ msgstr "Hindi ma-update i/f status"
+#, fuzzy
+#~ msgid "Data too large for the advertisement packet"
+#~ msgstr "Hindi makasya ang data sa loob ng advertisement packet"
+
#~ msgid "Don't know how to pass object to native function"
#~ msgstr "Hindi alam ipasa ang object sa native function"
@@ -2697,6 +2745,26 @@ msgstr "zero step"
#~ msgstr "Pagkakamali sa ffi_prep_cif"
#, fuzzy
+#~ msgid "Failed to acquire mutex"
+#~ msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to add service"
+#~ msgstr "Hindi matagumpay ang paglagay ng service, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to connect:"
+#~ msgstr "Hindi makaconnect, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to continue scanning"
+#~ msgstr "Hindi maituloy ang pag scan, status: 0x%0xlX"
+
+#, fuzzy
+#~ msgid "Failed to create mutex"
+#~ msgstr "Hindi matagumpay ang pagbuo ng mutex, status: 0x%0xlX"
+
+#, fuzzy
#~ msgid "Failed to notify or indicate attribute value, err %0x04x"
#~ msgstr "Hindi mabalitaan ang attribute value, status: 0x%08lX"
@@ -2704,6 +2772,22 @@ msgstr "zero step"
#~ msgid "Failed to read attribute value, err %0x04x"
#~ msgstr "Hindi mabasa ang value ng attribute, status: 0x%08lX"
+#, fuzzy
+#~ msgid "Failed to release mutex"
+#~ msgstr "Nabigo sa pagrelease ng mutex, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to start advertising"
+#~ msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to start scanning"
+#~ msgstr "Hindi masimulaan mag i-scan, status: 0x%0xlX"
+
+#, fuzzy
+#~ msgid "Failed to stop advertising"
+#~ msgstr "Hindi mahinto ang advertisement, status: 0x%08lX"
+
#~ msgid "Function requires lock."
#~ msgstr "Kailangan ng lock ang function."
diff --git a/locale/fr.po b/locale/fr.po
index 1dec817d5..07355526f 100644
--- a/locale/fr.po
+++ b/locale/fr.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-05-09 01:06-0400\n"
+"POT-Creation-Date: 2019-07-31 16:30-0500\n"
"PO-Revision-Date: 2019-04-14 20:05+0100\n"
"Last-Translator: Pierrick Couturier <arofarn@arofarn.info>\n"
"Language-Team: fr\n"
@@ -54,8 +54,8 @@ msgstr "index %q hors gamme"
msgid "%q indices must be integers, not %s"
msgstr "les indices %q doivent être des entiers, pas %s"
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
#, fuzzy
msgid "%q must be >= 1"
msgstr "%d doit être >=1"
@@ -222,15 +222,14 @@ msgid "A hardware interrupt channel is already in use"
msgstr "Un canal d'interruptions matérielles est déjà utilisé"
#: shared-bindings/bleio/Address.c
-#, c-format
-msgid "Address is not %d bytes long or is in wrong format"
-msgstr "L'adresse n'est pas longue de %d octets ou est d'un format erroné"
-
-#: shared-bindings/bleio/Address.c
#, fuzzy, c-format
msgid "Address must be %d bytes long"
msgstr "L'adresse doit être longue de %d octets"
+#: shared-bindings/bleio/Address.c
+msgid "Address type out of range"
+msgstr ""
+
#: ports/nrf/common-hal/busio/I2C.c
#, fuzzy
msgid "All I2C peripherals are in use"
@@ -258,9 +257,10 @@ msgstr "Tous les canaux d'événements de synchro sont utilisés"
msgid "All timers for this pin are in use"
msgstr "Tous les timers pour cette broche sont utilisés"
-#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c
#: shared-module/_pew/PewPew.c
msgid "All timers in use"
@@ -320,6 +320,10 @@ msgstr "La profondeur de bit doit être un multiple de 8."
msgid "Both pins must support hardware interrupts"
msgstr "Les deux entrées doivent supporter les interruptions matérielles"
+#: shared-bindings/displayio/Display.c
+msgid "Brightness must be 0-1.0"
+msgstr ""
+
#: shared-bindings/supervisor/__init__.c
msgid "Brightness must be between 0 and 255"
msgstr "La luminosité doit être entre 0 et 255"
@@ -333,6 +337,11 @@ msgstr "Luminosité non-ajustable"
msgid "Buffer incorrect size. Should be %d bytes."
msgstr "Tampon de taille incorrect. Devrait être de %d octets."
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
+#, c-format
+msgid "Buffer length %d too big. It must be less than %d"
+msgstr ""
+
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
msgstr "Le tampon doit être de longueur au moins 1"
@@ -352,26 +361,18 @@ msgstr "Le tampon d'octets doit être de 16 octets."
msgid "Bytes must be between 0 and 255."
msgstr "Les octets 'bytes' doivent être entre 0 et 255"
+#: py/objtype.c
+msgid "Call super().__init__() before accessing native object."
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Can not use dotstar with %s"
msgstr "Impossible d'utiliser 'dotstar' avec %s"
-#: shared-bindings/bleio/Device.c
-msgid "Can't add services in Central mode"
-msgstr "Impossible d'ajouter des services en mode Central"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't advertise in Central mode"
-msgstr "Impossible de publier en mode Central"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't change the name in Central mode"
-msgstr "Modification du nom impossible en mode Central"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't connect in Peripheral mode"
-msgstr "Impossible de se connecter en mode 'Peripheral'"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Can't set CCCD for local Characteristic"
+msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
msgid "Cannot delete values"
@@ -456,11 +457,23 @@ msgstr "Horloge en cours d'utilisation"
msgid "Column entry must be digitalio.DigitalInOut"
msgstr "L'entrée 'Column' doit être un digitalio.DigitalInOut"
+#: shared-bindings/displayio/I2CDisplay.c
+msgid "Command must be 0-255"
+msgstr ""
+
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
#, fuzzy
msgid "Command must be an int between 0 and 255"
msgstr "La commande doit être un entier entre 0 et 255"
+#: py/persistentcode.c
+msgid "Corrupt .mpy file"
+msgstr ""
+
+#: py/emitglue.c
+msgid "Corrupt raw code"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/UUID.c
#, c-format
msgid "Could not decode ble_uuid, err 0x%04x"
@@ -470,11 +483,11 @@ msgstr "Impossible de décoder le 'ble_uuid', err 0x%04x"
msgid "Could not initialize UART"
msgstr "L'UART n'a pu être initialisé"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate first buffer"
msgstr "Impossible d'allouer le 1er tampon"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate second buffer"
msgstr "Impossible d'allouer le 2e tampon"
@@ -492,19 +505,14 @@ msgstr "DAC déjà utilisé"
msgid "Data 0 pin must be byte aligned"
msgstr "La broche 'Data 0' doit être aligné sur l'octet"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Data chunk must follow fmt chunk"
msgstr "Un bloc de données doit suivre un bloc de format"
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
msgid "Data too large for advertisement packet"
msgstr "Données trop volumineuses pour un paquet de diffusion"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Data too large for the advertisement packet"
-msgstr "Données trop volumineuses pour le paquet de diffusion"
-
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr "La capacité de destination est plus petite que 'destination_length'."
@@ -518,6 +526,7 @@ msgid "Drive mode not used when direction is input."
msgstr "Le mode Drive n'est pas utilisé quand la direction est 'input'."
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "EXTINT channel already in use"
msgstr "Canal EXTINT déjà utilisé"
@@ -543,17 +552,20 @@ msgstr "Une 'Characteristic' est attendue"
msgid "Expected a UUID"
msgstr "Un UUID est attendu"
+#: shared-bindings/bleio/Central.c
+msgid "Expected an Address"
+msgstr ""
+
#: shared-module/_pixelbuf/PixelBuf.c
#, c-format
msgid "Expected tuple of length %d, got %d"
msgstr "Tuple de longueur %d attendu, obtenu %d"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to acquire mutex"
-msgstr "Echec de l'obtention de mutex"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Failed sending command."
+msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, fuzzy, c-format
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Echec de l'obtention de mutex, err 0x%04x"
@@ -563,11 +575,6 @@ msgstr "Echec de l'obtention de mutex, err 0x%04x"
msgid "Failed to add characteristic, err 0x%04x"
msgstr "Echec de l'ajout de caractéristique, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to add service"
-msgstr "Echec de l'ajout de service"
-
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy, c-format
msgid "Failed to add service, err 0x%04x"
@@ -588,27 +595,21 @@ msgstr "Echec de l'allocation de %d octets du tampon RX"
msgid "Failed to change softdevice state"
msgstr "Echec de la modification de l'état du périphérique"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to connect:"
-msgstr "Echec de connection:"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to configure advertising, err 0x%04x"
+msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to continue scanning"
-msgstr "Impossible de poursuivre le scan"
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "Failed to connect: timeout"
+msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
#, fuzzy, c-format
msgid "Failed to continue scanning, err 0x%04x"
msgstr "Impossible de poursuivre le scan, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to create mutex"
-msgstr "Echec de la création de mutex"
-
-#: ports/nrf/common-hal/bleio/Device.c
+#: ports/nrf/common-hal/bleio/Central.c
#, fuzzy
msgid "Failed to discover services"
msgstr "Echec de la découverte de services"
@@ -649,49 +650,42 @@ msgstr "Impossible de lire la valeur de 'gatts', err 0x%04x"
msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
msgstr "Echec de l'ajout de l'UUID du fournisseur, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to release mutex"
-msgstr "Impossible de libérer mutex"
-
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, fuzzy, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "Impossible de libérer mutex, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to start advertising"
-msgstr "Echec du démarrage de la diffusion"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to set device name, err 0x%04x"
+msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy, c-format
msgid "Failed to start advertising, err 0x%04x"
msgstr "Impossible de commencer à diffuser, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to start scanning"
-msgstr "Impossible de commencer à scanner"
+#: ports/nrf/common-hal/bleio/Central.c
+#, c-format
+msgid "Failed to start connecting, error 0x%04x"
+msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
#, fuzzy, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "Impossible de commencer à scanner, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to stop advertising"
-msgstr "Echec de l'arrêt de diffusion"
-
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy, c-format
msgid "Failed to stop advertising, err 0x%04x"
msgstr "Echec de l'arrêt de diffusion, err 0x%04x"
#: ports/nrf/common-hal/bleio/Characteristic.c
+#, c-format
+msgid "Failed to write CCCD, err 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
#, fuzzy, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "Impossible d'écrire la valeur de l'attribut, err 0x%04x"
@@ -732,6 +726,10 @@ msgstr "La fréquence capturée est au delà des capacités. Capture en pause."
msgid "Function requires lock"
msgstr "La fonction nécessite un verrou"
+#: shared-bindings/displayio/Display.c
+msgid "Group already used"
+msgstr ""
+
#: shared-module/displayio/Group.c
msgid "Group full"
msgstr "Groupe plein"
@@ -760,8 +758,8 @@ msgstr "Taille de tampon incorrecte"
msgid "Input/output error"
msgstr "Erreur d'entrée/sortie"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
msgstr "Broche invalide pour '%q'"
@@ -792,7 +790,7 @@ msgstr "Longueur de tampon invalide"
msgid "Invalid capture period. Valid range: 1 - 500"
msgstr "Période de capture invalide. Gamme valide: 1 à 500"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
#, fuzzy
msgid "Invalid channel count"
msgstr "Nombre de canaux invalide"
@@ -801,11 +799,11 @@ msgstr "Nombre de canaux invalide"
msgid "Invalid direction."
msgstr "Direction invalide"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid file"
msgstr "Fichier invalide"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid format chunk size"
msgstr "Taille de bloc de formatage invalide"
@@ -847,12 +845,12 @@ msgstr "Polarité invalide"
msgid "Invalid run mode."
msgstr "Mode de lancement invalide."
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
#, fuzzy
msgid "Invalid voice count"
msgstr "Nombre de voix invalide"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid wave file"
msgstr "Fichier WAVE invalide"
@@ -861,6 +859,10 @@ msgid "LHS of keyword arg must be an id"
msgstr "La partie gauche de l'argument nommé doit être un identifiant"
#: shared-module/displayio/Group.c
+msgid "Layer already in a group."
+msgstr ""
+
+#: shared-module/displayio/Group.c
msgid "Layer must be a Group or TileGrid subclass."
msgstr "'Layer' doit être un 'Group' ou une sous-classe 'TileGrid'."
@@ -908,9 +910,13 @@ msgstr "Erreur fatale de MicroPython.\n"
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr "Le délais au démarrage du micro doit être entre 0.0 et 1.0"
-#: shared-bindings/displayio/Display.c
-msgid "Must be a Group subclass."
-msgstr "Doit être une sous-classe de 'Group'"
+#: shared-bindings/displayio/Group.c
+msgid "Must be a %q subclass."
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "No CCCD for this Characteristic"
+msgstr ""
#: ports/atmel-samd/common-hal/analogio/AnalogOut.c
msgid "No DAC on chip"
@@ -945,6 +951,10 @@ msgstr "Pas de GCLK libre"
msgid "No hardware random available"
msgstr "Pas de source matérielle d'aléa disponible"
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
+msgid "No hardware support on clk pin"
+msgstr ""
+
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "No hardware support on pin"
@@ -958,12 +968,14 @@ msgstr "Il n'y a plus d'espace libre sur le périphérique"
msgid "No such file/directory"
msgstr "Fichier/dossier introuvable"
+#: ports/nrf/common-hal/bleio/Characteristic.c
#: shared-bindings/bleio/CharacteristicBuffer.c
#, fuzzy
msgid "Not connected"
msgstr "Non connecté"
#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c
+#: shared-bindings/audiopwmio/PWMAudioOut.c
msgid "Not playing"
msgstr "Ne joue pas"
@@ -1041,6 +1053,10 @@ msgstr "Pixel au-delà des limites du tampon"
msgid "Plus any modules on the filesystem\n"
msgstr "Ainsi que tout autre module présent sur le système de fichiers\n"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Pop from an empty Ps2 buffer"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr "Appuyez sur une touche pour entrer sur REPL ou CTRL-D pour recharger."
@@ -1095,18 +1111,19 @@ msgstr "Mode sans-échec! Le code sauvegardé n'est pas éxecuté.\n"
msgid "SDA or SCL needs a pull up"
msgstr "SDA ou SCL a besoin d'une résistance de tirage ('pull up')"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
#, fuzzy
msgid "Sample rate must be positive"
msgstr "Le taux d'échantillonage doit être positif"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#, c-format
msgid "Sample rate too high. It must be less than %d"
msgstr "Taux d'échantillonage trop élevé. Doit être inf. à %d"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
msgstr "Sérialiseur en cours d'utilisation"
@@ -1178,20 +1195,20 @@ msgstr ""
"Le bouton 'reset' a été appuyé pendant le démarrage de CircuitPython. "
"Appuyer de nouveau pour quitter de le mode sans-échec.\n"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's bits_per_sample does not match the mixer's"
msgstr ""
"Le 'bits_per_sample' de l'échantillon ne correspond pas à celui du mixer"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's channel count does not match the mixer's"
msgstr "Le canal de l'échantillon ne correspond pas à celui du mixer"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's sample rate does not match the mixer's"
msgstr "L'échantillonage de l'échantillon ne correspond pas à celui du mixer"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's signedness does not match the mixer's"
msgstr "Le signe de l'échantillon ne correspond pas à celui du mixer"
@@ -1200,8 +1217,12 @@ msgid "Tile height must exactly divide bitmap height"
msgstr "La hauteur de la tuile doit diviser exactement la hauteur de l'image"
#: shared-bindings/displayio/TileGrid.c
-msgid "Tile indices must be 0 - 255"
-msgstr "Les indices des tuiles doivent être compris entre 0 et 255 "
+msgid "Tile index out of bounds"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
+msgid "Tile value out of bounds"
+msgstr ""
#: shared-bindings/displayio/TileGrid.c
msgid "Tile width must exactly divide bitmap width"
@@ -1215,7 +1236,8 @@ msgstr "Pour quitter, redémarrez la carte SVP sans "
msgid "Too many channels in sample."
msgstr "Trop de canaux dans l'échantillon."
-#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
+#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
+#: shared-bindings/displayio/ParallelBus.c
msgid "Too many display busses"
msgstr "Trop de bus d'affichage"
@@ -1240,8 +1262,8 @@ msgid "USB Error"
msgstr "Erreur USB"
#: shared-bindings/bleio/UUID.c
-msgid "UUID integer value not in range 0 to 0xffff"
-msgstr "valeur de l'entier UUID est hors-bornes 0 à 0xffff"
+msgid "UUID integer value must be 0-0xffff"
+msgstr ""
#: shared-bindings/bleio/UUID.c
msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'"
@@ -1259,8 +1281,13 @@ msgstr ""
msgid "Unable to allocate buffers for signed conversion"
msgstr "Impossible d'allouer des tampons pour une conversion signée"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+#: shared-module/displayio/I2CDisplay.c
+#, c-format
+msgid "Unable to find I2C Display at %x"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Unable to find free GCLK"
msgstr "Impossible de trouver un GCLK libre"
@@ -1296,7 +1323,7 @@ msgstr "Débit non supporté"
msgid "Unsupported display bus type"
msgstr "Type de bus d'affichage non supporté"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Unsupported format"
msgstr "Format non supporté"
@@ -1313,7 +1340,7 @@ msgid "Viper functions don't currently support more than 4 arguments"
msgstr ""
"les fonctions de Viper ne supportent pas plus de 4 arguments actuellement"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "Voice index too high"
msgstr "Index de la voix trop grand"
@@ -1438,7 +1465,7 @@ msgstr "bits doivent être 7, 8 ou 9"
msgid "bits must be 8"
msgstr "les bits doivent être 8"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
#, fuzzy
msgid "bits_per_sample must be 8 or 16"
msgstr "'bits_per_sample' doivent être 8 ou 16"
@@ -1453,7 +1480,7 @@ msgstr "branche hors-bornes"
msgid "buf is too small. need %d bytes"
msgstr "'buf' est trop petit. Besoin de %d octets"
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr "le tampon doit être un objet bytes-like"
@@ -1772,7 +1799,7 @@ msgstr "division par zéro"
msgid "empty"
msgstr "vide"
-#: extmod/modutimeq.c extmod/moduheapq.c
+#: extmod/moduheapq.c extmod/modutimeq.c
msgid "empty heap"
msgstr "tas vide"
@@ -1834,7 +1861,8 @@ msgstr "argument(s) nommé(s) supplémentaire(s) donné(s)"
msgid "extra positional arguments given"
msgstr "argument(s) positionnel(s) supplémentaire(s) donné(s)"
-#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c
+#: shared-bindings/audiocore/WaveFile.c
+#: shared-bindings/displayio/OnDiskBitmap.c
msgid "file must be a file opened in byte mode"
msgstr "le fichier doit être un fichier ouvert en mode 'byte'"
@@ -1963,9 +1991,10 @@ msgstr "l'argument 2 de int() doit être >=2 et <=36"
msgid "integer required"
msgstr "entier requis"
-#: ports/nrf/common-hal/bleio/Broadcaster.c
-msgid "interval not in range 0.0020 to 10.24"
-msgstr "intervalle hors bornes 0.0020 à 10.24"
+#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c
+#, c-format
+msgid "interval must be in range %s-%s"
+msgstr ""
#: extmod/machine_i2c.c
msgid "invalid I2C peripheral"
@@ -2184,6 +2213,14 @@ msgstr "pas de module '%q'"
msgid "no such attribute"
msgstr "pas de tel attribut"
+#: shared-bindings/bleio/Peripheral.c
+msgid "non-Service found in services"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "non-UUID found in service_uuids"
+msgstr ""
+
#: py/compile.c
msgid "non-default argument follows default argument"
msgstr ""
@@ -2243,7 +2280,7 @@ msgstr "l'objet n'est pas un itérateur"
msgid "object not callable"
msgstr "objet non appelable"
-#: py/sequence.c
+#: py/sequence.c shared-bindings/displayio/Group.c
msgid "object not in sequence"
msgstr "l'objet n'est pas dans la séquence"
@@ -2384,7 +2421,7 @@ msgstr "return attendait '%q' mais a reçu '%q'"
msgid "rsplit(None,n)"
msgstr ""
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid ""
"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or "
"'B'"
@@ -2404,10 +2441,6 @@ msgstr "pile de planification pleine"
msgid "script compilation not supported"
msgstr "compilation de script non supportée"
-#: shared-bindings/bleio/Peripheral.c
-msgid "services includes an object that is not a Service"
-msgstr "'services' inclut un object qui n'est pas un 'Service'"
-
#: py/objstr.c
msgid "sign not allowed in string format specifier"
msgstr "signe non autorisé dans les spéc. de formats de chaînes de caractères"
@@ -2507,10 +2540,6 @@ msgstr "erreur de syntaxe dans le descripteur d'uctypes"
msgid "threshold must be in the range 0-65536"
msgstr "le seuil doit être dans la gamme 0-65536"
-#: shared-bindings/displayio/TileGrid.c
-msgid "tile index out of bounds"
-msgstr "indice de tuile hors limites"
-
#: shared-bindings/time/__init__.c
msgid "time.struct_time() takes a 9-sequence"
msgstr "time.struct_time() prend une séquence de longueur 9"
@@ -2671,13 +2700,17 @@ msgstr "type non supporté pour %q: '%s', '%s'"
#: py/objint.c
#, c-format
-msgid "value would overflow a %d byte buffer"
+msgid "value must fit in %d byte(s)"
msgstr ""
#: shared-bindings/displayio/Bitmap.c
msgid "value_count must be > 0"
msgstr "'value_count' doit être > 0"
+#: shared-bindings/bleio/Scanner.c
+msgid "window must be <= interval"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "write_args must be a list, tuple, or None"
msgstr "'write_args' doit être une liste, un tuple ou 'None'"
@@ -2712,6 +2745,21 @@ msgstr "'step' nul"
#~ msgid "AP required"
#~ msgstr "'AP' requis"
+#~ msgid "Address is not %d bytes long or is in wrong format"
+#~ msgstr "L'adresse n'est pas longue de %d octets ou est d'un format erroné"
+
+#~ msgid "Can't add services in Central mode"
+#~ msgstr "Impossible d'ajouter des services en mode Central"
+
+#~ msgid "Can't advertise in Central mode"
+#~ msgstr "Impossible de publier en mode Central"
+
+#~ msgid "Can't change the name in Central mode"
+#~ msgstr "Modification du nom impossible en mode Central"
+
+#~ msgid "Can't connect in Peripheral mode"
+#~ msgstr "Impossible de se connecter en mode 'Peripheral'"
+
#~ msgid "Cannot connect to AP"
#~ msgstr "Impossible de se connecter à 'AP'"
@@ -2724,6 +2772,9 @@ msgstr "'step' nul"
#~ msgid "Cannot update i/f status"
#~ msgstr "le status i/f ne peut être mis à jour"
+#~ msgid "Data too large for the advertisement packet"
+#~ msgstr "Données trop volumineuses pour le paquet de diffusion"
+
#~ msgid "Don't know how to pass object to native function"
#~ msgstr "Ne sais pas comment passer l'objet à une fonction native"
@@ -2737,6 +2788,26 @@ msgstr "'step' nul"
#~ msgstr "Erreur dans ffi_prep_cif"
#, fuzzy
+#~ msgid "Failed to acquire mutex"
+#~ msgstr "Echec de l'obtention de mutex"
+
+#, fuzzy
+#~ msgid "Failed to add service"
+#~ msgstr "Echec de l'ajout de service"
+
+#, fuzzy
+#~ msgid "Failed to connect:"
+#~ msgstr "Echec de connection:"
+
+#, fuzzy
+#~ msgid "Failed to continue scanning"
+#~ msgstr "Impossible de poursuivre le scan"
+
+#, fuzzy
+#~ msgid "Failed to create mutex"
+#~ msgstr "Echec de la création de mutex"
+
+#, fuzzy
#~ msgid "Failed to notify or indicate attribute value, err %0x04x"
#~ msgstr "Impossible de notifier la valeur de l'attribut. status: 0x%08lX"
@@ -2744,6 +2815,22 @@ msgstr "'step' nul"
#~ msgid "Failed to read attribute value, err %0x04x"
#~ msgstr "Impossible de lire la valeur de l'attribut. status: 0x%08lX"
+#, fuzzy
+#~ msgid "Failed to release mutex"
+#~ msgstr "Impossible de libérer mutex"
+
+#, fuzzy
+#~ msgid "Failed to start advertising"
+#~ msgstr "Echec du démarrage de la diffusion"
+
+#, fuzzy
+#~ msgid "Failed to start scanning"
+#~ msgstr "Impossible de commencer à scanner"
+
+#, fuzzy
+#~ msgid "Failed to stop advertising"
+#~ msgstr "Echec de l'arrêt de diffusion"
+
#~ msgid "Function requires lock."
#~ msgstr "La fonction nécessite un verrou."
@@ -2769,6 +2856,9 @@ msgstr "'step' nul"
#~ msgstr ""
#~ "Les fréquences de PWM multiples ne sont pas supportées. PWM réglé à %dHz"
+#~ msgid "Must be a Group subclass."
+#~ msgstr "Doit être une sous-classe de 'Group'"
+
#~ msgid "No PulseIn support for %q"
#~ msgstr "Pas de support de PulseIn pour %q"
@@ -2805,12 +2895,18 @@ msgstr "'step' nul"
#~ msgid "STA required"
#~ msgstr "'STA' requis"
+#~ msgid "Tile indices must be 0 - 255"
+#~ msgstr "Les indices des tuiles doivent être compris entre 0 et 255 "
+
#~ msgid "UART(%d) does not exist"
#~ msgstr "UART(%d) n'existe pas"
#~ msgid "UART(1) can't read"
#~ msgstr "UART(1) ne peut pas lire"
+#~ msgid "UUID integer value not in range 0 to 0xffff"
+#~ msgstr "valeur de l'entier UUID est hors-bornes 0 à 0xffff"
+
#~ msgid "Unable to remount filesystem"
#~ msgstr "Impossible de remonter le système de fichiers"
@@ -2857,6 +2953,9 @@ msgstr "'step' nul"
#~ msgid "impossible baudrate"
#~ msgstr "débit impossible"
+#~ msgid "interval not in range 0.0020 to 10.24"
+#~ msgstr "intervalle hors bornes 0.0020 à 10.24"
+
#~ msgid "invalid alarm"
#~ msgstr "alarme invalide"
@@ -2892,6 +2991,12 @@ msgstr "'step' nul"
#~ msgid "scan failed"
#~ msgstr "échec du scan"
+#~ msgid "services includes an object that is not a Service"
+#~ msgstr "'services' inclut un object qui n'est pas un 'Service'"
+
+#~ msgid "tile index out of bounds"
+#~ msgstr "indice de tuile hors limites"
+
#~ msgid "too many arguments"
#~ msgstr "trop d'arguments"
diff --git a/locale/it_IT.po b/locale/it_IT.po
index 42abd3986..4360cd221 100644
--- a/locale/it_IT.po
+++ b/locale/it_IT.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-05-09 01:06-0400\n"
+"POT-Creation-Date: 2019-07-31 16:30-0500\n"
"PO-Revision-Date: 2018-10-02 16:27+0200\n"
"Last-Translator: Enrico Paganin <enrico.paganin@mail.com>\n"
"Language-Team: \n"
@@ -52,8 +52,8 @@ msgstr "indice %q fuori intervallo"
msgid "%q indices must be integers, not %s"
msgstr "gli indici %q devono essere interi, non %s"
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
#, fuzzy
msgid "%q must be >= 1"
msgstr "slice del buffer devono essere della stessa lunghezza"
@@ -220,15 +220,14 @@ msgid "A hardware interrupt channel is already in use"
msgstr "Un canale di interrupt hardware è già in uso"
#: shared-bindings/bleio/Address.c
-#, c-format
-msgid "Address is not %d bytes long or is in wrong format"
-msgstr ""
-
-#: shared-bindings/bleio/Address.c
#, fuzzy, c-format
msgid "Address must be %d bytes long"
msgstr "la palette deve essere lunga 32 byte"
+#: shared-bindings/bleio/Address.c
+msgid "Address type out of range"
+msgstr ""
+
#: ports/nrf/common-hal/busio/I2C.c
msgid "All I2C peripherals are in use"
msgstr "Tutte le periferiche I2C sono in uso"
@@ -254,9 +253,10 @@ msgstr "Tutti i canali di eventi sincronizzati in uso"
msgid "All timers for this pin are in use"
msgstr "Tutti i timer per questo pin sono in uso"
-#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c
#: shared-module/_pew/PewPew.c
msgid "All timers in use"
@@ -315,6 +315,10 @@ msgstr "La profondità di bit deve essere multipla di 8."
msgid "Both pins must support hardware interrupts"
msgstr "Entrambi i pin devono supportare gli interrupt hardware"
+#: shared-bindings/displayio/Display.c
+msgid "Brightness must be 0-1.0"
+msgstr ""
+
#: shared-bindings/supervisor/__init__.c
msgid "Brightness must be between 0 and 255"
msgstr "La luminosità deve essere compreso tra 0 e 255"
@@ -328,6 +332,11 @@ msgstr "Illiminazione non è regolabile"
msgid "Buffer incorrect size. Should be %d bytes."
msgstr "Buffer di lunghezza non valida. Dovrebbe essere di %d bytes."
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
+#, c-format
+msgid "Buffer length %d too big. It must be less than %d"
+msgstr ""
+
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
msgstr "Il buffer deve essere lungo almeno 1"
@@ -347,26 +356,18 @@ msgstr "i buffer devono essere della stessa lunghezza"
msgid "Bytes must be between 0 and 255."
msgstr "I byte devono essere compresi tra 0 e 255"
+#: py/objtype.c
+msgid "Call super().__init__() before accessing native object."
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Can not use dotstar with %s"
msgstr "dotstar non può essere usato con %s"
-#: shared-bindings/bleio/Device.c
-msgid "Can't add services in Central mode"
-msgstr "non si può aggiungere servizi in Central mode"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't advertise in Central mode"
-msgstr "non si può pubblicizzare in Central mode"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't change the name in Central mode"
-msgstr "non si può cambiare il nome in Central mode"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't connect in Peripheral mode"
-msgstr "non si può connettere in Periferal mode"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Can't set CCCD for local Characteristic"
+msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
msgid "Cannot delete values"
@@ -451,11 +452,23 @@ msgstr "Unità di clock in uso"
msgid "Column entry must be digitalio.DigitalInOut"
msgstr ""
+#: shared-bindings/displayio/I2CDisplay.c
+msgid "Command must be 0-255"
+msgstr ""
+
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
#, fuzzy
msgid "Command must be an int between 0 and 255"
msgstr "I byte devono essere compresi tra 0 e 255"
+#: py/persistentcode.c
+msgid "Corrupt .mpy file"
+msgstr ""
+
+#: py/emitglue.c
+msgid "Corrupt raw code"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/UUID.c
#, c-format
msgid "Could not decode ble_uuid, err 0x%04x"
@@ -465,11 +478,11 @@ msgstr ""
msgid "Could not initialize UART"
msgstr "Impossibile inizializzare l'UART"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate first buffer"
msgstr "Impossibile allocare il primo buffer"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate second buffer"
msgstr "Impossibile allocare il secondo buffer"
@@ -487,21 +500,15 @@ msgstr "DAC già in uso"
msgid "Data 0 pin must be byte aligned"
msgstr "graphic deve essere lunga 2048 byte"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Data chunk must follow fmt chunk"
msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy
msgid "Data too large for advertisement packet"
msgstr "Impossibile inserire dati nel pacchetto di advertisement."
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Data too large for the advertisement packet"
-msgstr "Impossibile inserire dati nel pacchetto di advertisement."
-
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr "La capacità di destinazione è più piccola di destination_length."
@@ -515,6 +522,7 @@ msgid "Drive mode not used when direction is input."
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "EXTINT channel already in use"
msgstr "Canale EXTINT già in uso"
@@ -540,17 +548,20 @@ msgstr "Non è possibile aggiungere Characteristic."
msgid "Expected a UUID"
msgstr "Atteso un %q"
+#: shared-bindings/bleio/Central.c
+msgid "Expected an Address"
+msgstr ""
+
#: shared-module/_pixelbuf/PixelBuf.c
#, c-format
msgid "Expected tuple of length %d, got %d"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to acquire mutex"
-msgstr "Impossibile allocare buffer RX"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Failed sending command."
+msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, fuzzy, c-format
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
@@ -560,11 +571,6 @@ msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
msgid "Failed to add characteristic, err 0x%04x"
msgstr "Impossibile fermare advertisement. status: 0x%02x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to add service"
-msgstr "Impossibile fermare advertisement. status: 0x%02x"
-
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy, c-format
msgid "Failed to add service, err 0x%04x"
@@ -585,27 +591,21 @@ msgstr "Fallita allocazione del buffer RX di %d byte"
msgid "Failed to change softdevice state"
msgstr "Impossibile fermare advertisement. status: 0x%02x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to connect:"
-msgstr "Impossibile connettersi. status: 0x%02x"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to configure advertising, err 0x%04x"
+msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to continue scanning"
-msgstr "Impossible iniziare la scansione. status: 0x%02x"
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "Failed to connect: timeout"
+msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
#, fuzzy, c-format
msgid "Failed to continue scanning, err 0x%04x"
msgstr "Impossible iniziare la scansione. status: 0x%02x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to create mutex"
-msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
-
-#: ports/nrf/common-hal/bleio/Device.c
+#: ports/nrf/common-hal/bleio/Central.c
#, fuzzy
msgid "Failed to discover services"
msgstr "Impossibile fermare advertisement. status: 0x%02x"
@@ -644,49 +644,42 @@ msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x"
msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
msgstr "Non è possibile aggiungere l'UUID del vendor specifico da 128-bit"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to release mutex"
-msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
-
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, fuzzy, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to start advertising"
-msgstr "Impossibile avviare advertisement. status: 0x%02x"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to set device name, err 0x%04x"
+msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy, c-format
msgid "Failed to start advertising, err 0x%04x"
msgstr "Impossibile avviare advertisement. status: 0x%02x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to start scanning"
-msgstr "Impossible iniziare la scansione. status: 0x%02x"
+#: ports/nrf/common-hal/bleio/Central.c
+#, c-format
+msgid "Failed to start connecting, error 0x%04x"
+msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
#, fuzzy, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "Impossible iniziare la scansione. status: 0x%02x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to stop advertising"
-msgstr "Impossibile fermare advertisement. status: 0x%02x"
-
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy, c-format
msgid "Failed to stop advertising, err 0x%04x"
msgstr "Impossibile fermare advertisement. status: 0x%02x"
#: ports/nrf/common-hal/bleio/Characteristic.c
+#, c-format
+msgid "Failed to write CCCD, err 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
#, fuzzy, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x"
@@ -727,6 +720,10 @@ msgstr ""
msgid "Function requires lock"
msgstr ""
+#: shared-bindings/displayio/Display.c
+msgid "Group already used"
+msgstr ""
+
#: shared-module/displayio/Group.c
msgid "Group full"
msgstr "Gruppo pieno"
@@ -755,8 +752,8 @@ msgstr ""
msgid "Input/output error"
msgstr "Errore input/output"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
msgstr "Pin %q non valido"
@@ -786,7 +783,7 @@ msgstr "lunghezza del buffer non valida"
msgid "Invalid capture period. Valid range: 1 - 500"
msgstr "periodo di cattura invalido. Zona valida: 1 - 500"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
#, fuzzy
msgid "Invalid channel count"
msgstr "Argomento non valido"
@@ -795,11 +792,11 @@ msgstr "Argomento non valido"
msgid "Invalid direction."
msgstr "Direzione non valida."
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid file"
msgstr "File non valido"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid format chunk size"
msgstr ""
@@ -841,12 +838,12 @@ msgstr "Polarità non valida"
msgid "Invalid run mode."
msgstr "Modalità di esecuzione non valida."
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
#, fuzzy
msgid "Invalid voice count"
msgstr "Tipo di servizio non valido"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid wave file"
msgstr "File wave non valido"
@@ -855,6 +852,10 @@ msgid "LHS of keyword arg must be an id"
msgstr ""
#: shared-module/displayio/Group.c
+msgid "Layer already in a group."
+msgstr ""
+
+#: shared-module/displayio/Group.c
msgid "Layer must be a Group or TileGrid subclass."
msgstr "Layer deve essere un Group o TileGrid subclass"
@@ -899,9 +900,13 @@ msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr ""
"Il ritardo di avvio del microfono deve essere nell'intervallo tra 0.0 e 1.0"
-#: shared-bindings/displayio/Display.c
-msgid "Must be a Group subclass."
-msgstr "Deve essere un Group subclass"
+#: shared-bindings/displayio/Group.c
+msgid "Must be a %q subclass."
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "No CCCD for this Characteristic"
+msgstr ""
#: ports/atmel-samd/common-hal/analogio/AnalogOut.c
msgid "No DAC on chip"
@@ -936,6 +941,10 @@ msgstr "Nessun GCLK libero"
msgid "No hardware random available"
msgstr "Nessun generatore hardware di numeri casuali disponibile"
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
+msgid "No hardware support on clk pin"
+msgstr ""
+
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "No hardware support on pin"
@@ -949,12 +958,14 @@ msgstr "Non che spazio sul dispositivo"
msgid "No such file/directory"
msgstr "Nessun file/directory esistente"
+#: ports/nrf/common-hal/bleio/Characteristic.c
#: shared-bindings/bleio/CharacteristicBuffer.c
#, fuzzy
msgid "Not connected"
msgstr "Impossible connettersi all'AP"
#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c
+#: shared-bindings/audiopwmio/PWMAudioOut.c
msgid "Not playing"
msgstr "In pausa"
@@ -1029,6 +1040,10 @@ msgstr ""
msgid "Plus any modules on the filesystem\n"
msgstr "Imposssibile rimontare il filesystem"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Pop from an empty Ps2 buffer"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1084,19 +1099,20 @@ msgstr "Modalità sicura in esecuzione! Codice salvato non in esecuzione.\n"
msgid "SDA or SCL needs a pull up"
msgstr "SDA o SCL necessitano un pull-up"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
#, fuzzy
msgid "Sample rate must be positive"
msgstr "STA deve essere attiva"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#, c-format
msgid "Sample rate too high. It must be less than %d"
msgstr ""
"Frequenza di campionamento troppo alta. Il valore deve essere inferiore a %d"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
msgstr "Serializer in uso"
@@ -1158,19 +1174,19 @@ msgid ""
"exit safe mode.\n"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's bits_per_sample does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's channel count does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's sample rate does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's signedness does not match the mixer's"
msgstr ""
@@ -1179,7 +1195,11 @@ msgid "Tile height must exactly divide bitmap height"
msgstr ""
#: shared-bindings/displayio/TileGrid.c
-msgid "Tile indices must be 0 - 255"
+msgid "Tile index out of bounds"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
+msgid "Tile value out of bounds"
msgstr ""
#: shared-bindings/displayio/TileGrid.c
@@ -1194,7 +1214,8 @@ msgstr "Per uscire resettare la scheda senza "
msgid "Too many channels in sample."
msgstr ""
-#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
+#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
+#: shared-bindings/displayio/ParallelBus.c
msgid "Too many display busses"
msgstr ""
@@ -1219,7 +1240,7 @@ msgid "USB Error"
msgstr "Errore USB"
#: shared-bindings/bleio/UUID.c
-msgid "UUID integer value not in range 0 to 0xffff"
+msgid "UUID integer value must be 0-0xffff"
msgstr ""
#: shared-bindings/bleio/UUID.c
@@ -1235,8 +1256,13 @@ msgstr ""
msgid "Unable to allocate buffers for signed conversion"
msgstr "Ipossibilitato ad allocare buffer per la conversione con segno"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+#: shared-module/displayio/I2CDisplay.c
+#, c-format
+msgid "Unable to find I2C Display at %x"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Unable to find free GCLK"
msgstr "Impossibile trovare un GCLK libero"
@@ -1271,7 +1297,7 @@ msgstr "baudrate non supportato"
msgid "Unsupported display bus type"
msgstr "tipo di bitmap non supportato"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Unsupported format"
msgstr "Formato non supportato"
@@ -1287,7 +1313,7 @@ msgstr "Valore di pull non supportato."
msgid "Viper functions don't currently support more than 4 arguments"
msgstr "Le funzioni Viper non supportano più di 4 argomenti al momento"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "Voice index too high"
msgstr ""
@@ -1408,7 +1434,7 @@ msgstr "i bit devono essere 7, 8 o 9"
msgid "bits must be 8"
msgstr "i bit devono essere 8"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
#, fuzzy
msgid "bits_per_sample must be 8 or 16"
msgstr "i bit devono essere 7, 8 o 9"
@@ -1423,7 +1449,7 @@ msgstr "argomento di chr() non è in range(256)"
msgid "buf is too small. need %d bytes"
msgstr ""
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr ""
@@ -1731,7 +1757,7 @@ msgstr "divisione per zero"
msgid "empty"
msgstr "vuoto"
-#: extmod/modutimeq.c extmod/moduheapq.c
+#: extmod/moduheapq.c extmod/modutimeq.c
msgid "empty heap"
msgstr "heap vuoto"
@@ -1793,7 +1819,8 @@ msgstr "argomento nominato aggiuntivo fornito"
msgid "extra positional arguments given"
msgstr "argomenti posizonali extra dati"
-#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c
+#: shared-bindings/audiocore/WaveFile.c
+#: shared-bindings/displayio/OnDiskBitmap.c
msgid "file must be a file opened in byte mode"
msgstr ""
@@ -1923,8 +1950,9 @@ msgstr "il secondo argomanto di int() deve essere >= 2 e <= 36"
msgid "integer required"
msgstr "intero richiesto"
-#: ports/nrf/common-hal/bleio/Broadcaster.c
-msgid "interval not in range 0.0020 to 10.24"
+#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c
+#, c-format
+msgid "interval must be in range %s-%s"
msgstr ""
#: extmod/machine_i2c.c
@@ -2145,6 +2173,14 @@ msgstr "nessun modulo chiamato '%q'"
msgid "no such attribute"
msgstr "attributo inesistente"
+#: shared-bindings/bleio/Peripheral.c
+msgid "non-Service found in services"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "non-UUID found in service_uuids"
+msgstr ""
+
#: py/compile.c
msgid "non-default argument follows default argument"
msgstr "argomento non predefinito segue argmoento predfinito"
@@ -2204,7 +2240,7 @@ msgstr "l'oggetto non è un iteratore"
msgid "object not callable"
msgstr ""
-#: py/sequence.c
+#: py/sequence.c shared-bindings/displayio/Group.c
msgid "object not in sequence"
msgstr "oggetto non in sequenza"
@@ -2342,7 +2378,7 @@ msgstr "return aspettava '%q' ma ha ottenuto '%q'"
msgid "rsplit(None,n)"
msgstr ""
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid ""
"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or "
"'B'"
@@ -2362,10 +2398,6 @@ msgstr ""
msgid "script compilation not supported"
msgstr "compilazione dello scrip non suportata"
-#: shared-bindings/bleio/Peripheral.c
-msgid "services includes an object that is not a Service"
-msgstr ""
-
#: py/objstr.c
msgid "sign not allowed in string format specifier"
msgstr "segno non permesso nello spcificatore di formato della stringa"
@@ -2464,10 +2496,6 @@ msgstr "errore di sintassi nel descrittore uctypes"
msgid "threshold must be in the range 0-65536"
msgstr "la soglia deve essere nell'intervallo 0-65536"
-#: shared-bindings/displayio/TileGrid.c
-msgid "tile index out of bounds"
-msgstr ""
-
#: shared-bindings/time/__init__.c
msgid "time.struct_time() takes a 9-sequence"
msgstr ""
@@ -2627,13 +2655,17 @@ msgstr "tipi non supportati per %q: '%s', '%s'"
#: py/objint.c
#, c-format
-msgid "value would overflow a %d byte buffer"
+msgid "value must fit in %d byte(s)"
msgstr ""
#: shared-bindings/displayio/Bitmap.c
msgid "value_count must be > 0"
msgstr ""
+#: shared-bindings/bleio/Scanner.c
+msgid "window must be <= interval"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "write_args must be a list, tuple, or None"
msgstr ""
@@ -2670,6 +2702,18 @@ msgstr "zero step"
#~ msgid "C-level assert"
#~ msgstr "assert a livello C"
+#~ msgid "Can't add services in Central mode"
+#~ msgstr "non si può aggiungere servizi in Central mode"
+
+#~ msgid "Can't advertise in Central mode"
+#~ msgstr "non si può pubblicizzare in Central mode"
+
+#~ msgid "Can't change the name in Central mode"
+#~ msgstr "non si può cambiare il nome in Central mode"
+
+#~ msgid "Can't connect in Peripheral mode"
+#~ msgstr "non si può connettere in Periferal mode"
+
#~ msgid "Cannot connect to AP"
#~ msgstr "Impossible connettersi all'AP"
@@ -2682,6 +2726,10 @@ msgstr "zero step"
#~ msgid "Cannot update i/f status"
#~ msgstr "Impossibile aggiornare status di i/f"
+#, fuzzy
+#~ msgid "Data too large for the advertisement packet"
+#~ msgstr "Impossibile inserire dati nel pacchetto di advertisement."
+
#~ msgid "Don't know how to pass object to native function"
#~ msgstr "Non so come passare l'oggetto alla funzione nativa"
@@ -2695,6 +2743,26 @@ msgstr "zero step"
#~ msgstr "Errore in ffi_prep_cif"
#, fuzzy
+#~ msgid "Failed to acquire mutex"
+#~ msgstr "Impossibile allocare buffer RX"
+
+#, fuzzy
+#~ msgid "Failed to add service"
+#~ msgstr "Impossibile fermare advertisement. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to connect:"
+#~ msgstr "Impossibile connettersi. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to continue scanning"
+#~ msgstr "Impossible iniziare la scansione. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to create mutex"
+#~ msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
+
+#, fuzzy
#~ msgid "Failed to notify or indicate attribute value, err %0x04x"
#~ msgstr "Impossibile notificare valore dell'attributo. status: 0x%02x"
@@ -2702,6 +2770,22 @@ msgstr "zero step"
#~ msgid "Failed to read attribute value, err %0x04x"
#~ msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
+#, fuzzy
+#~ msgid "Failed to release mutex"
+#~ msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to start advertising"
+#~ msgstr "Impossibile avviare advertisement. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to start scanning"
+#~ msgstr "Impossible iniziare la scansione. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to stop advertising"
+#~ msgstr "Impossibile fermare advertisement. status: 0x%02x"
+
#~ msgid "GPIO16 does not support pull up."
#~ msgstr "GPIO16 non supporta pull-up"
@@ -2723,6 +2807,9 @@ msgstr "zero step"
#~ msgid "Multiple PWM frequencies not supported. PWM already set to %dhz."
#~ msgstr "Frequenze PWM multiple non supportate. PWM già impostato a %shz."
+#~ msgid "Must be a Group subclass."
+#~ msgstr "Deve essere un Group subclass"
+
#~ msgid "No PulseIn support for %q"
#~ msgstr "Nessun supporto per PulseIn per %q"
diff --git a/locale/pl.po b/locale/pl.po
index 918292a89..0a38aa914 100644
--- a/locale/pl.po
+++ b/locale/pl.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-05-09 01:06-0400\n"
+"POT-Creation-Date: 2019-08-05 17:52-0700\n"
"PO-Revision-Date: 2019-03-19 18:37-0700\n"
"Last-Translator: Radomir Dopieralski <circuitpython@sheep.art.pl>\n"
"Language-Team: pl\n"
@@ -53,8 +53,8 @@ msgstr "%q poza zakresem"
msgid "%q indices must be integers, not %s"
msgstr "%q indeks musi być liczbą całkowitą, a nie %s"
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
msgid "%q must be >= 1"
msgstr "%q musi być >= 1"
@@ -220,14 +220,13 @@ msgstr "Kanał przerwań sprzętowych w użyciu"
#: shared-bindings/bleio/Address.c
#, c-format
-msgid "Address is not %d bytes long or is in wrong format"
-msgstr "Adres nie ma długości %d bajtów lub zły format"
-
-#: shared-bindings/bleio/Address.c
-#, c-format
msgid "Address must be %d bytes long"
msgstr "Adres musi mieć %d bajtów"
+#: shared-bindings/bleio/Address.c
+msgid "Address type out of range"
+msgstr ""
+
#: ports/nrf/common-hal/busio/I2C.c
msgid "All I2C peripherals are in use"
msgstr "Wszystkie peryferia I2C w użyciu"
@@ -252,9 +251,10 @@ msgstr "Wszystkie kanały zdarzeń synchronizacji w użyciu"
msgid "All timers for this pin are in use"
msgstr "Wszystkie timery tej nóżki w użyciu"
-#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c
#: shared-module/_pew/PewPew.c
msgid "All timers in use"
@@ -312,6 +312,10 @@ msgstr "Głębia musi być wielokrotnością 8."
msgid "Both pins must support hardware interrupts"
msgstr "Obie nóżki muszą wspierać przerwania sprzętowe"
+#: shared-bindings/displayio/Display.c
+msgid "Brightness must be 0-1.0"
+msgstr ""
+
#: shared-bindings/supervisor/__init__.c
msgid "Brightness must be between 0 and 255"
msgstr "Jasność musi być pomiędzy 0 a 255"
@@ -325,6 +329,11 @@ msgstr "Jasność nie jest regulowana"
msgid "Buffer incorrect size. Should be %d bytes."
msgstr "Zła wielkość bufora. Powinno być %d bajtów."
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
+#, c-format
+msgid "Buffer length %d too big. It must be less than %d"
+msgstr ""
+
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
msgstr "Bufor musi mieć długość 1 lub więcej"
@@ -343,26 +352,18 @@ msgstr "Bufor musi mieć 16 bajtów."
msgid "Bytes must be between 0 and 255."
msgstr "Bytes musi być między 0 a 255."
+#: py/objtype.c
+msgid "Call super().__init__() before accessing native object."
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Can not use dotstar with %s"
msgstr "Nie można używać dotstar z %s"
-#: shared-bindings/bleio/Device.c
-msgid "Can't add services in Central mode"
-msgstr "Nie można dodać serwisów w trybie Central"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't advertise in Central mode"
-msgstr "Nie można rozgłaszać w trybie Central"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't change the name in Central mode"
-msgstr "Nie można zmienić nazwy w trybie Central"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't connect in Peripheral mode"
-msgstr "Nie można się łączyć w trybie Peripheral"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Can't set CCCD for local Characteristic"
+msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
msgid "Cannot delete values"
@@ -445,10 +446,22 @@ msgstr "Jednostka zegara w użyciu"
msgid "Column entry must be digitalio.DigitalInOut"
msgstr "Kolumny muszą być typu digitalio.DigitalInOut"
+#: shared-bindings/displayio/I2CDisplay.c
+msgid "Command must be 0-255"
+msgstr ""
+
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
msgid "Command must be an int between 0 and 255"
msgstr "Komenda musi być int pomiędzy 0 a 255"
+#: py/persistentcode.c
+msgid "Corrupt .mpy file"
+msgstr ""
+
+#: py/emitglue.c
+msgid "Corrupt raw code"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/UUID.c
#, c-format
msgid "Could not decode ble_uuid, err 0x%04x"
@@ -458,11 +471,11 @@ msgstr "Nie można zdekodować ble_uuid, błąd 0x%04x"
msgid "Could not initialize UART"
msgstr "Ustawienie UART nie powiodło się"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate first buffer"
msgstr "Nie udała się alokacja pierwszego bufora"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate second buffer"
msgstr "Nie udała się alokacja drugiego bufora"
@@ -479,19 +492,14 @@ msgstr "DAC w użyciu"
msgid "Data 0 pin must be byte aligned"
msgstr "Nóżka data 0 musi być wyrównana do bajtu"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Data chunk must follow fmt chunk"
msgstr "Fragment danych musi następować po fragmencie fmt"
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
msgid "Data too large for advertisement packet"
msgstr "Zbyt dużo danych pakietu rozgłoszeniowego"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Data too large for the advertisement packet"
-msgstr "Zbyt dużo danych pakietu rozgłoszeniowego"
-
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr "Pojemność celu mniejsza od destination_length."
@@ -505,6 +513,7 @@ msgid "Drive mode not used when direction is input."
msgstr "Tryb sterowania nieużywany w trybie wejścia."
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "EXTINT channel already in use"
msgstr "Kanał EXTINT w użyciu"
@@ -528,16 +537,20 @@ msgstr "Oczekiwano charakterystyki"
msgid "Expected a UUID"
msgstr "Oczekiwano UUID"
+#: shared-bindings/bleio/Central.c
+msgid "Expected an Address"
+msgstr ""
+
#: shared-module/_pixelbuf/PixelBuf.c
#, c-format
msgid "Expected tuple of length %d, got %d"
msgstr "Oczekiwano krotkę długości %d, otrzymano %d"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to acquire mutex"
-msgstr "Nie udało się uzyskać blokady"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Failed sending command."
+msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, c-format
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Nie udało się uzyskać blokady, błąd 0x$04x"
@@ -547,10 +560,6 @@ msgstr "Nie udało się uzyskać blokady, błąd 0x$04x"
msgid "Failed to add characteristic, err 0x%04x"
msgstr "Nie udało się dodać charakterystyki, błąd 0x$04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to add service"
-msgstr "Nie udało się dodać serwisu"
-
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to add service, err 0x%04x"
@@ -570,24 +579,21 @@ msgstr "Nie udała się alokacja %d bajtów na bufor RX"
msgid "Failed to change softdevice state"
msgstr "Nie udało się zmienić stanu softdevice"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to connect:"
-msgstr "Nie udało się połączenie:"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to configure advertising, err 0x%04x"
+msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to continue scanning"
-msgstr "Nie udała się kontynuacja skanowania"
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "Failed to connect: timeout"
+msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
#, c-format
msgid "Failed to continue scanning, err 0x%04x"
msgstr "Nie udała się kontynuacja skanowania, błąd 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to create mutex"
-msgstr "Nie udało się stworzyć blokady"
-
-#: ports/nrf/common-hal/bleio/Device.c
+#: ports/nrf/common-hal/bleio/Central.c
msgid "Failed to discover services"
msgstr "Nie udało się odkryć serwisów"
@@ -624,39 +630,31 @@ msgstr "Nie udało się odczytać gatts, błąd 0x%04x"
msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
msgstr "Nie udało się zarejestrować UUID dostawcy, błąd 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to release mutex"
-msgstr "Nie udało się zwolnić blokady"
-
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "Nie udało się zwolnić blokady, błąd 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to start advertising"
-msgstr "Nie udało się rozpocząć rozgłaszania"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to set device name, err 0x%04x"
+msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to start advertising, err 0x%04x"
msgstr "Nie udało się rozpocząć rozgłaszania, błąd 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to start scanning"
-msgstr "Nie udało się rozpocząć skanowania"
+#: ports/nrf/common-hal/bleio/Central.c
+#, c-format
+msgid "Failed to start connecting, error 0x%04x"
+msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "Nie udało się rozpocząć skanowania, błąd 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to stop advertising"
-msgstr "Nie udało się zatrzymać rozgłaszania"
-
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to stop advertising, err 0x%04x"
@@ -664,6 +662,11 @@ msgstr "Nie udało się zatrzymać rozgłaszania, błąd 0x%04x"
#: ports/nrf/common-hal/bleio/Characteristic.c
#, c-format
+msgid "Failed to write CCCD, err 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "Nie udało się zapisać atrybutu, błąd 0x%04x"
@@ -703,6 +706,10 @@ msgstr "Uzyskana częstotliwość jest niemożliwa. Spauzowano."
msgid "Function requires lock"
msgstr "Funkcja wymaga blokady"
+#: shared-bindings/displayio/Display.c
+msgid "Group already used"
+msgstr ""
+
#: shared-module/displayio/Group.c
msgid "Group full"
msgstr "Grupa pełna"
@@ -731,8 +738,8 @@ msgstr "Niewłaściwa wielkość bufora"
msgid "Input/output error"
msgstr "Błąd I/O"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
msgstr "Zła nóżka %q"
@@ -761,7 +768,7 @@ msgstr "Zła wielkość bufora"
msgid "Invalid capture period. Valid range: 1 - 500"
msgstr "Zły okres. Poprawny zakres to: 1 - 500"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid channel count"
msgstr "Zła liczba kanałów"
@@ -769,11 +776,11 @@ msgstr "Zła liczba kanałów"
msgid "Invalid direction."
msgstr "Zły tryb"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid file"
msgstr "Zły plik"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid format chunk size"
msgstr "Zła wielkość fragmentu formatu"
@@ -815,11 +822,11 @@ msgstr "Zła polaryzacja"
msgid "Invalid run mode."
msgstr "Zły tryb uruchomienia"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr "Zła liczba głosów"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid wave file"
msgstr "Zły plik wave"
@@ -828,6 +835,10 @@ msgid "LHS of keyword arg must be an id"
msgstr "Lewa strona argumentu nazwanego musi być nazwą"
#: shared-module/displayio/Group.c
+msgid "Layer already in a group."
+msgstr ""
+
+#: shared-module/displayio/Group.c
msgid "Layer must be a Group or TileGrid subclass."
msgstr "Layer musi dziedziczyć z Group albo TileGrid"
@@ -876,9 +887,13 @@ msgstr "Krytyczny błąd MicroPythona.\n"
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr "Opóźnienie włączenia mikrofonu musi być w zakresie od 0.0 do 1.0"
-#: shared-bindings/displayio/Display.c
-msgid "Must be a Group subclass."
-msgstr "Musi dziedziczyć z Group."
+#: shared-bindings/displayio/Group.c
+msgid "Must be a %q subclass."
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "No CCCD for this Characteristic"
+msgstr ""
#: ports/atmel-samd/common-hal/analogio/AnalogOut.c
msgid "No DAC on chip"
@@ -913,6 +928,10 @@ msgstr "Brak wolnych GLCK"
msgid "No hardware random available"
msgstr "Brak generatora liczb losowych"
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
+msgid "No hardware support on clk pin"
+msgstr ""
+
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "No hardware support on pin"
@@ -926,11 +945,13 @@ msgstr "Brak miejsca"
msgid "No such file/directory"
msgstr "Brak pliku/katalogu"
+#: ports/nrf/common-hal/bleio/Characteristic.c
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "Not connected"
msgstr "Nie podłączono"
#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c
+#: shared-bindings/audiopwmio/PWMAudioOut.c
msgid "Not playing"
msgstr "Nic nie jest odtwarzane"
@@ -995,6 +1016,10 @@ msgstr "Piksel poza granicami bufora"
msgid "Plus any modules on the filesystem\n"
msgstr "Oraz moduły w systemie plików\n"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Pop from an empty Ps2 buffer"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr "Dowolny klawisz aby uruchomić konsolę. CTRL-D aby przeładować."
@@ -1047,17 +1072,18 @@ msgstr "Uruchomiony tryb bezpieczeństwa! Zapisany kod nie jest uruchamiany.\n"
msgid "SDA or SCL needs a pull up"
msgstr "SDA lub SCL wymagają podciągnięcia"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Sample rate must be positive"
msgstr "Częstotliwość próbkowania musi być dodatnia"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#, c-format
msgid "Sample rate too high. It must be less than %d"
msgstr "Zbyt wysoka częstotliwość próbkowania. Musi być mniejsza niż %d"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
msgstr "Serializator w użyciu"
@@ -1126,19 +1152,19 @@ msgstr ""
"Przycisk reset został wciśnięty podczas startu CircuitPythona. Wciśnij go "
"ponownie aby wyjść z trybu bezpieczeństwa.\n"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's bits_per_sample does not match the mixer's"
msgstr "Wartość bits_per_sample nie pasuje do miksera"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's channel count does not match the mixer's"
msgstr "Liczba kanałów nie pasuje do miksera "
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's sample rate does not match the mixer's"
msgstr "Sample rate nie pasuje do miksera"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's signedness does not match the mixer's"
msgstr "Znak nie pasuje do miksera"
@@ -1147,8 +1173,12 @@ msgid "Tile height must exactly divide bitmap height"
msgstr "Wysokość bitmapy musi być wielokrotnością wysokości kafelka"
#: shared-bindings/displayio/TileGrid.c
-msgid "Tile indices must be 0 - 255"
-msgstr "Indeks kafelka musi być pomiędzy 0 a 255 włącznie"
+msgid "Tile index out of bounds"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
+msgid "Tile value out of bounds"
+msgstr ""
#: shared-bindings/displayio/TileGrid.c
msgid "Tile width must exactly divide bitmap width"
@@ -1162,7 +1192,8 @@ msgstr "By wyjść, proszę zresetować płytkę bez "
msgid "Too many channels in sample."
msgstr "Zbyt wiele kanałów."
-#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
+#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
+#: shared-bindings/displayio/ParallelBus.c
msgid "Too many display busses"
msgstr "Zbyt wiele magistrali"
@@ -1187,8 +1218,8 @@ msgid "USB Error"
msgstr "Błąd USB"
#: shared-bindings/bleio/UUID.c
-msgid "UUID integer value not in range 0 to 0xffff"
-msgstr "Wartość UUID poza zakresem 0 do 0xffff"
+msgid "UUID integer value must be 0-0xffff"
+msgstr ""
#: shared-bindings/bleio/UUID.c
msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'"
@@ -1203,8 +1234,13 @@ msgstr "UUID nie jest typu str, int lub bytes"
msgid "Unable to allocate buffers for signed conversion"
msgstr "Nie udała się alokacja buforów do konwersji ze znakiem"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+#: shared-module/displayio/I2CDisplay.c
+#, c-format
+msgid "Unable to find I2C Display at %x"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Unable to find free GCLK"
msgstr "Brak wolnego GCLK"
@@ -1237,7 +1273,7 @@ msgstr "Zła szybkość transmisji"
msgid "Unsupported display bus type"
msgstr "Zły typ magistrali wyświetlaczy"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Unsupported format"
msgstr "Zły format"
@@ -1253,7 +1289,7 @@ msgstr "Zła wartość podciągnięcia."
msgid "Viper functions don't currently support more than 4 arguments"
msgstr "Funkcje Viper nie obsługują obecnie więcej niż 4 argumentów"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "Voice index too high"
msgstr "Zbyt wysoki indeks głosu"
@@ -1375,7 +1411,7 @@ msgstr "bits musi być 7, 8 lub 9"
msgid "bits must be 8"
msgstr "bits musi być 8"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "bits_per_sample must be 8 or 16"
msgstr "bits_per_sample musi być 8 lub 16"
@@ -1388,7 +1424,7 @@ msgstr "skok poza zakres"
msgid "buf is too small. need %d bytes"
msgstr "buf zbyt mały. Wymagane %d bajtów"
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr "bufor mysi być typu bytes"
@@ -1690,7 +1726,7 @@ msgstr "dzielenie przez zero"
msgid "empty"
msgstr "puste"
-#: extmod/modutimeq.c extmod/moduheapq.c
+#: extmod/moduheapq.c extmod/modutimeq.c
msgid "empty heap"
msgstr "pusta sterta"
@@ -1751,7 +1787,8 @@ msgstr "nadmiarowe argumenty nazwane"
msgid "extra positional arguments given"
msgstr "nadmiarowe argumenty pozycyjne"
-#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c
+#: shared-bindings/audiocore/WaveFile.c
+#: shared-bindings/displayio/OnDiskBitmap.c
msgid "file must be a file opened in byte mode"
msgstr "file musi być otwarte w trybie bajtowym"
@@ -1880,9 +1917,10 @@ msgstr "argument 2 do int() busi być pomiędzy 2 a 36"
msgid "integer required"
msgstr "wymagana liczba całkowita"
-#: ports/nrf/common-hal/bleio/Broadcaster.c
-msgid "interval not in range 0.0020 to 10.24"
-msgstr "przedział poza zakresem 0.0020 do 10.24"
+#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c
+#, c-format
+msgid "interval must be in range %s-%s"
+msgstr ""
#: extmod/machine_i2c.c
msgid "invalid I2C peripheral"
@@ -2095,6 +2133,14 @@ msgstr "brak modułu o nazwie '%q'"
msgid "no such attribute"
msgstr "nie ma takiego atrybutu"
+#: shared-bindings/bleio/Peripheral.c
+msgid "non-Service found in services"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "non-UUID found in service_uuids"
+msgstr ""
+
#: py/compile.c
msgid "non-default argument follows default argument"
msgstr "argument z wartością domyślną przed argumentem bez"
@@ -2152,7 +2198,7 @@ msgstr "obiekt nie jest iteratorem"
msgid "object not callable"
msgstr "obiekt nie jest wywoływalny"
-#: py/sequence.c
+#: py/sequence.c shared-bindings/displayio/Group.c
msgid "object not in sequence"
msgstr "obiektu nie ma sekwencji"
@@ -2286,7 +2332,7 @@ msgstr "return oczekiwał '%q', a jest '%q'"
msgid "rsplit(None,n)"
msgstr "rsplit(None,n)"
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid ""
"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or "
"'B'"
@@ -2305,10 +2351,6 @@ msgstr "stos planu pełen"
msgid "script compilation not supported"
msgstr "kompilowanie skryptów nieobsługiwane"
-#: shared-bindings/bleio/Peripheral.c
-msgid "services includes an object that is not a Service"
-msgstr "obiekt typu innego niż Service w services"
-
#: py/objstr.c
msgid "sign not allowed in string format specifier"
msgstr "znak jest niedopuszczalny w specyfikacji formatu łańcucha"
@@ -2406,10 +2448,6 @@ msgstr "błąd składni w deskryptorze uctypes"
msgid "threshold must be in the range 0-65536"
msgstr "threshold musi być w zakresie 0-65536"
-#: shared-bindings/displayio/TileGrid.c
-msgid "tile index out of bounds"
-msgstr "indeks kafelka poza zakresem"
-
#: shared-bindings/time/__init__.c
msgid "time.struct_time() takes a 9-sequence"
msgstr "time.struct_time() wymaga 9-elementowej sekwencji"
@@ -2568,13 +2606,17 @@ msgstr "złe typy dla %q: '%s', '%s'"
#: py/objint.c
#, c-format
-msgid "value would overflow a %d byte buffer"
+msgid "value must fit in %d byte(s)"
msgstr ""
#: shared-bindings/displayio/Bitmap.c
msgid "value_count must be > 0"
msgstr "value_count musi być > 0"
+#: shared-bindings/bleio/Scanner.c
+msgid "window must be <= interval"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "write_args must be a list, tuple, or None"
msgstr "write_args musi być listą, krotką lub None"
@@ -2603,6 +2645,51 @@ msgstr "y poza zakresem"
msgid "zero step"
msgstr "zerowy krok"
+#~ msgid "Address is not %d bytes long or is in wrong format"
+#~ msgstr "Adres nie ma długości %d bajtów lub zły format"
+
+#~ msgid "Can't add services in Central mode"
+#~ msgstr "Nie można dodać serwisów w trybie Central"
+
+#~ msgid "Can't advertise in Central mode"
+#~ msgstr "Nie można rozgłaszać w trybie Central"
+
+#~ msgid "Can't change the name in Central mode"
+#~ msgstr "Nie można zmienić nazwy w trybie Central"
+
+#~ msgid "Can't connect in Peripheral mode"
+#~ msgstr "Nie można się łączyć w trybie Peripheral"
+
+#~ msgid "Data too large for the advertisement packet"
+#~ msgstr "Zbyt dużo danych pakietu rozgłoszeniowego"
+
+#~ msgid "Failed to acquire mutex"
+#~ msgstr "Nie udało się uzyskać blokady"
+
+#~ msgid "Failed to add service"
+#~ msgstr "Nie udało się dodać serwisu"
+
+#~ msgid "Failed to connect:"
+#~ msgstr "Nie udało się połączenie:"
+
+#~ msgid "Failed to continue scanning"
+#~ msgstr "Nie udała się kontynuacja skanowania"
+
+#~ msgid "Failed to create mutex"
+#~ msgstr "Nie udało się stworzyć blokady"
+
+#~ msgid "Failed to release mutex"
+#~ msgstr "Nie udało się zwolnić blokady"
+
+#~ msgid "Failed to start advertising"
+#~ msgstr "Nie udało się rozpocząć rozgłaszania"
+
+#~ msgid "Failed to start scanning"
+#~ msgstr "Nie udało się rozpocząć skanowania"
+
+#~ msgid "Failed to stop advertising"
+#~ msgstr "Nie udało się zatrzymać rozgłaszania"
+
#~ msgid "Invalid bit clock pin"
#~ msgstr "Zła nóżka zegara"
@@ -2611,3 +2698,21 @@ msgstr "zerowy krok"
#~ msgid "Invalid data pin"
#~ msgstr "Zła nóżka danych"
+
+#~ msgid "Must be a Group subclass."
+#~ msgstr "Musi dziedziczyć z Group."
+
+#~ msgid "Tile indices must be 0 - 255"
+#~ msgstr "Indeks kafelka musi być pomiędzy 0 a 255 włącznie"
+
+#~ msgid "UUID integer value not in range 0 to 0xffff"
+#~ msgstr "Wartość UUID poza zakresem 0 do 0xffff"
+
+#~ msgid "interval not in range 0.0020 to 10.24"
+#~ msgstr "przedział poza zakresem 0.0020 do 10.24"
+
+#~ msgid "services includes an object that is not a Service"
+#~ msgstr "obiekt typu innego niż Service w services"
+
+#~ msgid "tile index out of bounds"
+#~ msgstr "indeks kafelka poza zakresem"
diff --git a/locale/pt_BR.po b/locale/pt_BR.po
index c951cec9b..defeb3e44 100644
--- a/locale/pt_BR.po
+++ b/locale/pt_BR.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-05-09 01:06-0400\n"
+"POT-Creation-Date: 2019-07-31 16:30-0500\n"
"PO-Revision-Date: 2018-10-02 21:14-0000\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -52,8 +52,8 @@ msgstr ""
msgid "%q indices must be integers, not %s"
msgstr ""
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
#, fuzzy
msgid "%q must be >= 1"
msgstr "buffers devem ser o mesmo tamanho"
@@ -220,15 +220,14 @@ msgid "A hardware interrupt channel is already in use"
msgstr "Um canal de interrupção de hardware já está em uso"
#: shared-bindings/bleio/Address.c
-#, c-format
-msgid "Address is not %d bytes long or is in wrong format"
-msgstr ""
-
-#: shared-bindings/bleio/Address.c
#, fuzzy, c-format
msgid "Address must be %d bytes long"
msgstr "buffers devem ser o mesmo tamanho"
+#: shared-bindings/bleio/Address.c
+msgid "Address type out of range"
+msgstr ""
+
#: ports/nrf/common-hal/busio/I2C.c
msgid "All I2C peripherals are in use"
msgstr "Todos os periféricos I2C estão em uso"
@@ -254,9 +253,10 @@ msgstr ""
msgid "All timers for this pin are in use"
msgstr "Todos os temporizadores para este pino estão em uso"
-#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c
#: shared-module/_pew/PewPew.c
msgid "All timers in use"
@@ -312,6 +312,10 @@ msgstr ""
msgid "Both pins must support hardware interrupts"
msgstr "Ambos os pinos devem suportar interrupções de hardware"
+#: shared-bindings/displayio/Display.c
+msgid "Brightness must be 0-1.0"
+msgstr ""
+
#: shared-bindings/supervisor/__init__.c
msgid "Brightness must be between 0 and 255"
msgstr "O brilho deve estar entre 0 e 255"
@@ -325,6 +329,11 @@ msgstr ""
msgid "Buffer incorrect size. Should be %d bytes."
msgstr "Buffer de tamanho incorreto. Deve ser %d bytes."
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
+#, c-format
+msgid "Buffer length %d too big. It must be less than %d"
+msgstr ""
+
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
msgstr ""
@@ -344,25 +353,17 @@ msgstr "buffers devem ser o mesmo tamanho"
msgid "Bytes must be between 0 and 255."
msgstr "Os bytes devem estar entre 0 e 255."
+#: py/objtype.c
+msgid "Call super().__init__() before accessing native object."
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Can not use dotstar with %s"
msgstr ""
-#: shared-bindings/bleio/Device.c
-msgid "Can't add services in Central mode"
-msgstr ""
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't advertise in Central mode"
-msgstr ""
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't change the name in Central mode"
-msgstr ""
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't connect in Peripheral mode"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Can't set CCCD for local Characteristic"
msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
@@ -447,11 +448,23 @@ msgstr "Unidade de Clock em uso"
msgid "Column entry must be digitalio.DigitalInOut"
msgstr ""
+#: shared-bindings/displayio/I2CDisplay.c
+msgid "Command must be 0-255"
+msgstr ""
+
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
#, fuzzy
msgid "Command must be an int between 0 and 255"
msgstr "Os bytes devem estar entre 0 e 255."
+#: py/persistentcode.c
+msgid "Corrupt .mpy file"
+msgstr ""
+
+#: py/emitglue.c
+msgid "Corrupt raw code"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/UUID.c
#, c-format
msgid "Could not decode ble_uuid, err 0x%04x"
@@ -461,11 +474,11 @@ msgstr ""
msgid "Could not initialize UART"
msgstr "Não foi possível inicializar o UART"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate first buffer"
msgstr "Não pôde alocar primeiro buffer"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate second buffer"
msgstr "Não pôde alocar segundo buffer"
@@ -482,21 +495,15 @@ msgstr "DAC em uso"
msgid "Data 0 pin must be byte aligned"
msgstr ""
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Data chunk must follow fmt chunk"
msgstr "Pedaço de dados deve seguir o pedaço de cortes"
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy
msgid "Data too large for advertisement packet"
msgstr "Não é possível ajustar dados no pacote de anúncios."
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Data too large for the advertisement packet"
-msgstr "Não é possível ajustar dados no pacote de anúncios."
-
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr ""
@@ -510,6 +517,7 @@ msgid "Drive mode not used when direction is input."
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "EXTINT channel already in use"
msgstr "Canal EXTINT em uso"
@@ -535,17 +543,20 @@ msgstr "Não é possível adicionar Característica."
msgid "Expected a UUID"
msgstr "Esperado um"
+#: shared-bindings/bleio/Central.c
+msgid "Expected an Address"
+msgstr ""
+
#: shared-module/_pixelbuf/PixelBuf.c
#, c-format
msgid "Expected tuple of length %d, got %d"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to acquire mutex"
-msgstr "Falha ao alocar buffer RX"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Failed sending command."
+msgstr "Falha ao enviar comando."
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, fuzzy, c-format
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
@@ -555,11 +566,6 @@ msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
msgid "Failed to add characteristic, err 0x%04x"
msgstr "Não pode parar propaganda. status: 0x%02x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to add service"
-msgstr "Não pode parar propaganda. status: 0x%02x"
-
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy, c-format
msgid "Failed to add service, err 0x%04x"
@@ -580,12 +586,13 @@ msgstr "Falha ao alocar buffer RX de %d bytes"
msgid "Failed to change softdevice state"
msgstr "Não pode parar propaganda. status: 0x%02x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to connect:"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to configure advertising, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to continue scanning"
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "Failed to connect: timeout"
msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
@@ -593,12 +600,7 @@ msgstr ""
msgid "Failed to continue scanning, err 0x%04x"
msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to create mutex"
-msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
-
-#: ports/nrf/common-hal/bleio/Device.c
+#: ports/nrf/common-hal/bleio/Central.c
#, fuzzy
msgid "Failed to discover services"
msgstr "Não pode parar propaganda. status: 0x%02x"
@@ -637,49 +639,42 @@ msgstr "Não é possível gravar o valor do atributo. status: 0x%02x"
msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
msgstr "Não é possível adicionar o UUID de 128 bits específico do fornecedor."
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to release mutex"
-msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
-
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, fuzzy, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to start advertising"
-msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to set device name, err 0x%04x"
+msgstr ""
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy, c-format
msgid "Failed to start advertising, err 0x%04x"
msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to start scanning"
-msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
+#: ports/nrf/common-hal/bleio/Central.c
+#, c-format
+msgid "Failed to start connecting, error 0x%04x"
+msgstr ""
#: ports/nrf/common-hal/bleio/Scanner.c
#, fuzzy, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
-#: ports/nrf/common-hal/bleio/Device.c
-#, fuzzy
-msgid "Failed to stop advertising"
-msgstr "Não pode parar propaganda. status: 0x%02x"
-
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, fuzzy, c-format
msgid "Failed to stop advertising, err 0x%04x"
msgstr "Não pode parar propaganda. status: 0x%02x"
#: ports/nrf/common-hal/bleio/Characteristic.c
+#, c-format
+msgid "Failed to write CCCD, err 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
#, fuzzy, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "Não é possível gravar o valor do atributo. status: 0x%02x"
@@ -720,6 +715,10 @@ msgstr ""
msgid "Function requires lock"
msgstr ""
+#: shared-bindings/displayio/Display.c
+msgid "Group already used"
+msgstr ""
+
#: shared-module/displayio/Group.c
msgid "Group full"
msgstr "Grupo cheio"
@@ -746,8 +745,8 @@ msgstr ""
msgid "Input/output error"
msgstr ""
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
msgstr "Pino do %q inválido"
@@ -777,7 +776,7 @@ msgstr "Arquivo inválido"
msgid "Invalid capture period. Valid range: 1 - 500"
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
#, fuzzy
msgid "Invalid channel count"
msgstr "certificado inválido"
@@ -786,11 +785,11 @@ msgstr "certificado inválido"
msgid "Invalid direction."
msgstr "Direção inválida"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid file"
msgstr "Arquivo inválido"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid format chunk size"
msgstr "Tamanho do pedaço de formato inválido"
@@ -832,12 +831,12 @@ msgstr ""
msgid "Invalid run mode."
msgstr ""
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
#, fuzzy
msgid "Invalid voice count"
msgstr "certificado inválido"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid wave file"
msgstr "Aqruivo de ondas inválido"
@@ -846,6 +845,10 @@ msgid "LHS of keyword arg must be an id"
msgstr ""
#: shared-module/displayio/Group.c
+msgid "Layer already in a group."
+msgstr ""
+
+#: shared-module/displayio/Group.c
msgid "Layer must be a Group or TileGrid subclass."
msgstr ""
@@ -889,8 +892,12 @@ msgstr ""
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr ""
-#: shared-bindings/displayio/Display.c
-msgid "Must be a Group subclass."
+#: shared-bindings/displayio/Group.c
+msgid "Must be a %q subclass."
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "No CCCD for this Characteristic"
msgstr ""
#: ports/atmel-samd/common-hal/analogio/AnalogOut.c
@@ -926,6 +933,10 @@ msgstr "Não há GCLKs livre"
msgid "No hardware random available"
msgstr ""
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
+msgid "No hardware support on clk pin"
+msgstr "Sem suporte de hardware no pino de clock"
+
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "No hardware support on pin"
@@ -939,12 +950,14 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
+#: ports/nrf/common-hal/bleio/Characteristic.c
#: shared-bindings/bleio/CharacteristicBuffer.c
#, fuzzy
msgid "Not connected"
msgstr "Não é possível conectar-se ao AP"
#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c
+#: shared-bindings/audiopwmio/PWMAudioOut.c
msgid "Not playing"
msgstr ""
@@ -1012,6 +1025,10 @@ msgstr ""
msgid "Plus any modules on the filesystem\n"
msgstr "Não é possível remontar o sistema de arquivos"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Pop from an empty Ps2 buffer"
+msgstr "Buffer Ps2 vazio"
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1065,17 +1082,18 @@ msgstr "Rodando em modo seguro! Não está executando o código salvo.\n"
msgid "SDA or SCL needs a pull up"
msgstr "SDA ou SCL precisa de um pull up"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Sample rate must be positive"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#, c-format
msgid "Sample rate too high. It must be less than %d"
msgstr "Taxa de amostragem muito alta. Deve ser menor que %d"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
msgstr "Serializer em uso"
@@ -1134,19 +1152,19 @@ msgid ""
"exit safe mode.\n"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's bits_per_sample does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's channel count does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's sample rate does not match the mixer's"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's signedness does not match the mixer's"
msgstr ""
@@ -1155,7 +1173,11 @@ msgid "Tile height must exactly divide bitmap height"
msgstr ""
#: shared-bindings/displayio/TileGrid.c
-msgid "Tile indices must be 0 - 255"
+msgid "Tile index out of bounds"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
+msgid "Tile value out of bounds"
msgstr ""
#: shared-bindings/displayio/TileGrid.c
@@ -1170,7 +1192,8 @@ msgstr "Para sair, por favor, reinicie a placa sem "
msgid "Too many channels in sample."
msgstr "Muitos canais na amostra."
-#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
+#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
+#: shared-bindings/displayio/ParallelBus.c
msgid "Too many display busses"
msgstr ""
@@ -1195,7 +1218,7 @@ msgid "USB Error"
msgstr "Erro na USB"
#: shared-bindings/bleio/UUID.c
-msgid "UUID integer value not in range 0 to 0xffff"
+msgid "UUID integer value must be 0-0xffff"
msgstr ""
#: shared-bindings/bleio/UUID.c
@@ -1211,8 +1234,13 @@ msgstr ""
msgid "Unable to allocate buffers for signed conversion"
msgstr "Não é possível alocar buffers para conversão assinada"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+#: shared-module/displayio/I2CDisplay.c
+#, c-format
+msgid "Unable to find I2C Display at %x"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Unable to find free GCLK"
msgstr "Não é possível encontrar GCLK livre"
@@ -1246,7 +1274,7 @@ msgstr "Taxa de transmissão não suportada"
msgid "Unsupported display bus type"
msgstr "Taxa de transmissão não suportada"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Unsupported format"
msgstr "Formato não suportado"
@@ -1262,7 +1290,7 @@ msgstr ""
msgid "Viper functions don't currently support more than 4 arguments"
msgstr ""
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "Voice index too high"
msgstr ""
@@ -1380,7 +1408,7 @@ msgstr ""
msgid "bits must be 8"
msgstr "bits devem ser 8"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
#, fuzzy
msgid "bits_per_sample must be 8 or 16"
msgstr "bits devem ser 8"
@@ -1395,7 +1423,7 @@ msgstr "Calibração está fora do intervalo"
msgid "buf is too small. need %d bytes"
msgstr ""
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr ""
@@ -1697,7 +1725,7 @@ msgstr "divisão por zero"
msgid "empty"
msgstr "vazio"
-#: extmod/modutimeq.c extmod/moduheapq.c
+#: extmod/moduheapq.c extmod/modutimeq.c
msgid "empty heap"
msgstr "heap vazia"
@@ -1759,7 +1787,8 @@ msgstr "argumentos extras de palavras-chave passados"
msgid "extra positional arguments given"
msgstr "argumentos extra posicionais passados"
-#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c
+#: shared-bindings/audiocore/WaveFile.c
+#: shared-bindings/displayio/OnDiskBitmap.c
msgid "file must be a file opened in byte mode"
msgstr ""
@@ -1888,8 +1917,9 @@ msgstr ""
msgid "integer required"
msgstr "inteiro requerido"
-#: ports/nrf/common-hal/bleio/Broadcaster.c
-msgid "interval not in range 0.0020 to 10.24"
+#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c
+#, c-format
+msgid "interval must be in range %s-%s"
msgstr ""
#: extmod/machine_i2c.c
@@ -2104,6 +2134,14 @@ msgstr ""
msgid "no such attribute"
msgstr ""
+#: shared-bindings/bleio/Peripheral.c
+msgid "non-Service found in services"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "non-UUID found in service_uuids"
+msgstr ""
+
#: py/compile.c
msgid "non-default argument follows default argument"
msgstr ""
@@ -2161,7 +2199,7 @@ msgstr ""
msgid "object not callable"
msgstr ""
-#: py/sequence.c
+#: py/sequence.c shared-bindings/displayio/Group.c
msgid "object not in sequence"
msgstr "objeto não em seqüência"
@@ -2295,7 +2333,7 @@ msgstr ""
msgid "rsplit(None,n)"
msgstr ""
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid ""
"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or "
"'B'"
@@ -2313,10 +2351,6 @@ msgstr ""
msgid "script compilation not supported"
msgstr "compilação de script não suportada"
-#: shared-bindings/bleio/Peripheral.c
-msgid "services includes an object that is not a Service"
-msgstr ""
-
#: py/objstr.c
msgid "sign not allowed in string format specifier"
msgstr ""
@@ -2415,10 +2449,6 @@ msgstr ""
msgid "threshold must be in the range 0-65536"
msgstr "Limite deve estar no alcance de 0-65536"
-#: shared-bindings/displayio/TileGrid.c
-msgid "tile index out of bounds"
-msgstr ""
-
#: shared-bindings/time/__init__.c
msgid "time.struct_time() takes a 9-sequence"
msgstr ""
@@ -2578,13 +2608,17 @@ msgstr ""
#: py/objint.c
#, c-format
-msgid "value would overflow a %d byte buffer"
+msgid "value must fit in %d byte(s)"
msgstr ""
#: shared-bindings/displayio/Bitmap.c
msgid "value_count must be > 0"
msgstr ""
+#: shared-bindings/bleio/Scanner.c
+msgid "window must be <= interval"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "write_args must be a list, tuple, or None"
msgstr ""
@@ -2628,6 +2662,10 @@ msgstr "passo zero"
#~ msgid "Cannot update i/f status"
#~ msgstr "Não é possível atualizar o status i/f"
+#, fuzzy
+#~ msgid "Data too large for the advertisement packet"
+#~ msgstr "Não é possível ajustar dados no pacote de anúncios."
+
#~ msgid "Don't know how to pass object to native function"
#~ msgstr "Não sabe como passar o objeto para a função nativa"
@@ -2641,6 +2679,18 @@ msgstr "passo zero"
#~ msgstr "Erro no ffi_prep_cif"
#, fuzzy
+#~ msgid "Failed to acquire mutex"
+#~ msgstr "Falha ao alocar buffer RX"
+
+#, fuzzy
+#~ msgid "Failed to add service"
+#~ msgstr "Não pode parar propaganda. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to create mutex"
+#~ msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
+
+#, fuzzy
#~ msgid "Failed to notify or indicate attribute value, err %0x04x"
#~ msgstr "Não é possível gravar o valor do atributo. status: 0x%02x"
@@ -2648,6 +2698,22 @@ msgstr "passo zero"
#~ msgid "Failed to read attribute value, err %0x04x"
#~ msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
+#, fuzzy
+#~ msgid "Failed to release mutex"
+#~ msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to start advertising"
+#~ msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to start scanning"
+#~ msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to stop advertising"
+#~ msgstr "Não pode parar propaganda. status: 0x%02x"
+
#~ msgid "GPIO16 does not support pull up."
#~ msgstr "GPIO16 não suporta pull up."
diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po
index 2d7b5f766..c0537202c 100644
--- a/locale/zh_Latn_pinyin.po
+++ b/locale/zh_Latn_pinyin.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: circuitpython-cn\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-05-09 01:06-0400\n"
+"POT-Creation-Date: 2019-08-05 17:52-0700\n"
"PO-Revision-Date: 2019-04-13 10:10-0700\n"
"Last-Translator: hexthat\n"
"Language-Team: Chinese Hanyu Pinyin\n"
@@ -54,8 +54,8 @@ msgstr "%q suǒyǐn chāochū fànwéi"
msgid "%q indices must be integers, not %s"
msgstr "%q suǒyǐn bìxū shì zhěngshù, ér bùshì %s"
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
msgid "%q must be >= 1"
msgstr "%q bìxū dàyú huò děngyú 1"
@@ -221,14 +221,13 @@ msgstr "Yìngjiàn zhōngduàn tōngdào yǐ zài shǐyòng zhōng"
#: shared-bindings/bleio/Address.c
#, c-format
-msgid "Address is not %d bytes long or is in wrong format"
-msgstr "Dìzhǐ bùshì %d zì jié zhǎng, huòzhě géshì cuòwù"
-
-#: shared-bindings/bleio/Address.c
-#, c-format
msgid "Address must be %d bytes long"
msgstr "Dìzhǐ bìxū shì %d zì jié zhǎng"
+#: shared-bindings/bleio/Address.c
+msgid "Address type out of range"
+msgstr ""
+
#: ports/nrf/common-hal/busio/I2C.c
msgid "All I2C peripherals are in use"
msgstr "Suǒyǒu I2C wàiwéi qì zhèngzài shǐyòng"
@@ -253,9 +252,10 @@ msgstr "Suǒyǒu tóngbù shìjiàn píndào shǐyòng"
msgid "All timers for this pin are in use"
msgstr "Cǐ yǐn jiǎo de suǒyǒu jìshí qì zhèngzài shǐyòng"
-#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c
#: shared-module/_pew/PewPew.c
msgid "All timers in use"
@@ -313,6 +313,10 @@ msgstr "Bǐtè shēndù bìxū shì 8 bèi yǐshàng."
msgid "Both pins must support hardware interrupts"
msgstr "Liǎng gè yǐn jiǎo dōu bìxū zhīchí yìngjiàn zhōngduàn"
+#: shared-bindings/displayio/Display.c
+msgid "Brightness must be 0-1.0"
+msgstr ""
+
#: shared-bindings/supervisor/__init__.c
msgid "Brightness must be between 0 and 255"
msgstr "Liàngdù bìxū jiè yú 0 dào 255 zhī jiān"
@@ -326,6 +330,11 @@ msgstr "Liàngdù wúfǎ tiáozhěng"
msgid "Buffer incorrect size. Should be %d bytes."
msgstr "Huǎnchōng qū dàxiǎo bù zhèngquè. Yīnggāi shì %d zì jié."
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
+#, c-format
+msgid "Buffer length %d too big. It must be less than %d"
+msgstr ""
+
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
msgstr "Huǎnchōng qū bìxū zhìshǎo chángdù 1"
@@ -344,26 +353,18 @@ msgstr "Zì jié huǎnchōng qū bìxū shì 16 zì jié."
msgid "Bytes must be between 0 and 255."
msgstr "Zì jié bìxū jiè yú 0 dào 255 zhī jiān."
+#: py/objtype.c
+msgid "Call super().__init__() before accessing native object."
+msgstr "Zài fǎngwèn běn jī wùjiàn zhīqián diàoyòng super().__init__()"
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Can not use dotstar with %s"
msgstr "Wúfǎ yǔ dotstar yīqǐ shǐyòng %s"
-#: shared-bindings/bleio/Device.c
-msgid "Can't add services in Central mode"
-msgstr "Wúfǎ zài zhōngyāng móshì xià tiānjiā fúwù"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't advertise in Central mode"
-msgstr "Wúfǎ zài zhōngyāng móshì zhōng guǎnggào"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't change the name in Central mode"
-msgstr "Wúfǎ gēnggǎi zhōngyāng móshì de míngchēng"
-
-#: shared-bindings/bleio/Device.c
-msgid "Can't connect in Peripheral mode"
-msgstr "Wúfǎ zài biānyuán móshì zhōng liánjiē"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Can't set CCCD for local Characteristic"
+msgstr "Wúfǎ wéi běndì tèzhēng shèzhì CCCD"
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
msgid "Cannot delete values"
@@ -446,10 +447,22 @@ msgstr "Shǐyòng shízhōng dānwèi"
msgid "Column entry must be digitalio.DigitalInOut"
msgstr "Liè tiáomù bìxū shì digitalio.DigitalInOut"
+#: shared-bindings/displayio/I2CDisplay.c
+msgid "Command must be 0-255"
+msgstr "Mìnglìng bìxū wèi 0-255"
+
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
msgid "Command must be an int between 0 and 255"
msgstr "Mìnglìng bìxū shì 0 dào 255 zhī jiān de int"
+#: py/persistentcode.c
+msgid "Corrupt .mpy file"
+msgstr "Fǔbài de .mpy wénjiàn"
+
+#: py/emitglue.c
+msgid "Corrupt raw code"
+msgstr "Sǔnhuài de yuánshǐ dàimǎ"
+
#: ports/nrf/common-hal/bleio/UUID.c
#, c-format
msgid "Could not decode ble_uuid, err 0x%04x"
@@ -459,11 +472,11 @@ msgstr "Wúfǎ jiěmǎ kě dú_uuid, err 0x%04x"
msgid "Could not initialize UART"
msgstr "Wúfǎ chūshǐhuà UART"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate first buffer"
msgstr "Wúfǎ fēnpèi dì yī gè huǎnchōng qū"
-#: shared-module/audioio/Mixer.c shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c
msgid "Couldn't allocate second buffer"
msgstr "Wúfǎ fēnpèi dì èr gè huǎnchōng qū"
@@ -480,19 +493,14 @@ msgstr "Fā yuán huì yǐjīng shǐyòng"
msgid "Data 0 pin must be byte aligned"
msgstr "Shùjù 0 de yǐn jiǎo bìxū shì zì jié duìqí"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Data chunk must follow fmt chunk"
msgstr "Shùjù kuài bìxū zūnxún fmt qū kuài"
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
msgid "Data too large for advertisement packet"
msgstr "Guǎnggào bāo de shùjù tài dà"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Data too large for the advertisement packet"
-msgstr "Guǎnggào bāo de shùjù tài dà"
-
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr "Mùbiāo róngliàng xiǎoyú mùdì de_chángdù."
@@ -506,6 +514,7 @@ msgid "Drive mode not used when direction is input."
msgstr "Fāngxiàng shūrù shí qūdòng móshì méiyǒu shǐyòng."
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "EXTINT channel already in use"
msgstr "EXTINT píndào yǐjīng shǐyòng"
@@ -529,16 +538,20 @@ msgstr "Yùqí de tèdiǎn"
msgid "Expected a UUID"
msgstr "Yùqí UUID"
+#: shared-bindings/bleio/Central.c
+msgid "Expected an Address"
+msgstr "Qídài yīgè dìzhǐ"
+
#: shared-module/_pixelbuf/PixelBuf.c
#, c-format
msgid "Expected tuple of length %d, got %d"
msgstr "Qīwàng de chángdù wèi %d de yuán zǔ, dédào %d"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to acquire mutex"
-msgstr "Wúfǎ huòdé mutex"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Failed sending command."
+msgstr "Fāsòng mìnglìng shībài."
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, c-format
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Wúfǎ huòdé mutex, err 0x%04x"
@@ -548,10 +561,6 @@ msgstr "Wúfǎ huòdé mutex, err 0x%04x"
msgid "Failed to add characteristic, err 0x%04x"
msgstr "Tiānjiā tèxìng shībài, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to add service"
-msgstr "Tiānjiā fúwù shībài"
-
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to add service, err 0x%04x"
@@ -571,24 +580,21 @@ msgstr "Fēnpèi RX huǎnchōng qū%d zì jié shībài"
msgid "Failed to change softdevice state"
msgstr "Gēnggǎi ruǎn shèbèi zhuàngtài shībài"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to connect:"
-msgstr "Liánjiē shībài:"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to configure advertising, err 0x%04x"
+msgstr "Wúfǎ pèizhì guǎnggào, cuòwù 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to continue scanning"
-msgstr "Jìxù sǎomiáo shībài"
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "Failed to connect: timeout"
+msgstr "Liánjiē shībài: Chāoshí"
#: ports/nrf/common-hal/bleio/Scanner.c
#, c-format
msgid "Failed to continue scanning, err 0x%04x"
msgstr "Jìxù sǎomiáo shībài, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to create mutex"
-msgstr "Wúfǎ chuàngjiàn hù chì suǒ"
-
-#: ports/nrf/common-hal/bleio/Device.c
+#: ports/nrf/common-hal/bleio/Central.c
msgid "Failed to discover services"
msgstr "Fāxiàn fúwù shībài"
@@ -625,39 +631,31 @@ msgstr "Wúfǎ dòu qǔ gatts zhí, err 0x%04x"
msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
msgstr "Wúfǎ zhùcè màizhǔ tèdìng de UUID, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to release mutex"
-msgstr "Wúfǎ shìfàng mutex"
-
-#: ports/nrf/common-hal/bleio/Characteristic.c ports/nrf/sd_mutex.c
+#: ports/nrf/sd_mutex.c
#, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "Wúfǎ shìfàng mutex, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to start advertising"
-msgstr "Qǐdòng guǎnggào shībài"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to set device name, err 0x%04x"
+msgstr "Wúfǎ shèzhì shèbèi míngchēng, cuòwù 0x%04x"
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to start advertising, err 0x%04x"
msgstr "Qǐdòng guǎnggào shībài, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to start scanning"
-msgstr "Qǐdòng sǎomiáo shībài"
+#: ports/nrf/common-hal/bleio/Central.c
+#, c-format
+msgid "Failed to start connecting, error 0x%04x"
+msgstr "Wúfǎ kāishǐ liánjiē, cuòwù 0x%04x"
#: ports/nrf/common-hal/bleio/Scanner.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "Qǐdòng sǎomiáo shībài, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Device.c
-msgid "Failed to stop advertising"
-msgstr "Wúfǎ tíngzhǐ guǎnggào"
-
-#: ports/nrf/common-hal/bleio/Broadcaster.c
#: ports/nrf/common-hal/bleio/Peripheral.c
#, c-format
msgid "Failed to stop advertising, err 0x%04x"
@@ -665,6 +663,11 @@ msgstr "Wúfǎ tíngzhǐ guǎnggào, err 0x%04x"
#: ports/nrf/common-hal/bleio/Characteristic.c
#, c-format
+msgid "Failed to write CCCD, err 0x%04x"
+msgstr "Wúfǎ xiě rù CCCD, cuòwù 0x%04x"
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "Xiě rù shǔxìng zhí shībài, err 0x%04x"
@@ -704,6 +707,10 @@ msgstr "Pínlǜ bǔhuò gāo yú nénglì. Bǔhuò zàntíng."
msgid "Function requires lock"
msgstr "Hánshù xūyào suǒdìng"
+#: shared-bindings/displayio/Display.c
+msgid "Group already used"
+msgstr ""
+
#: shared-module/displayio/Group.c
msgid "Group full"
msgstr "Fēnzǔ yǐ mǎn"
@@ -732,8 +739,8 @@ msgstr "Huǎnchōng qū dàxiǎo bù zhèngquè"
msgid "Input/output error"
msgstr "Shūrù/shūchū cuòwù"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
msgstr "Wúxiào de %q yǐn jiǎo"
@@ -762,7 +769,7 @@ msgstr "Wúxiào de huǎnchōng qū dàxiǎo"
msgid "Invalid capture period. Valid range: 1 - 500"
msgstr "Wúxiào de bǔhuò zhōuqí. Yǒuxiào fànwéi: 1-500"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid channel count"
msgstr "Wúxiào de tōngdào jìshù"
@@ -770,11 +777,11 @@ msgstr "Wúxiào de tōngdào jìshù"
msgid "Invalid direction."
msgstr "Wúxiào de fāngxiàng."
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid file"
msgstr "Wúxiào de wénjiàn"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid format chunk size"
msgstr "Géshì kuài dàxiǎo wúxiào"
@@ -816,11 +823,11 @@ msgstr "Wúxiào liǎng jí zhí"
msgid "Invalid run mode."
msgstr "Wúxiào de yùnxíng móshì."
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr "Wúxiào de yǔyīn jìshù"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Invalid wave file"
msgstr "Wúxiào de làng làngcháo wénjiàn"
@@ -829,6 +836,10 @@ msgid "LHS of keyword arg must be an id"
msgstr "Guānjiàn zì arg de LHS bìxū shì id"
#: shared-module/displayio/Group.c
+msgid "Layer already in a group."
+msgstr ""
+
+#: shared-module/displayio/Group.c
msgid "Layer must be a Group or TileGrid subclass."
msgstr "Layer bìxū shì Group huò TileGrid zi lèi."
@@ -876,9 +887,13 @@ msgstr "MicroPython zhìmìng cuòwù.\n"
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr "Màikèfēng qǐdòng yánchí bìxū zài 0.0 Dào 1.0 De fànwéi nèi"
-#: shared-bindings/displayio/Display.c
-msgid "Must be a Group subclass."
-msgstr "Bìxū shì fēnzǔ zi lèi."
+#: shared-bindings/displayio/Group.c
+msgid "Must be a %q subclass."
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "No CCCD for this Characteristic"
+msgstr ""
#: ports/atmel-samd/common-hal/analogio/AnalogOut.c
msgid "No DAC on chip"
@@ -913,6 +928,10 @@ msgstr "Méiyǒu miǎnfèi de GCLKs"
msgid "No hardware random available"
msgstr "Méiyǒu kěyòng de yìngjiàn suíjī"
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
+msgid "No hardware support on clk pin"
+msgstr ""
+
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "No hardware support on pin"
@@ -926,11 +945,13 @@ msgstr "Shèbèi shàng méiyǒu kònggé"
msgid "No such file/directory"
msgstr "Méiyǒu cǐ lèi wénjiàn/mùlù"
+#: ports/nrf/common-hal/bleio/Characteristic.c
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "Not connected"
msgstr "Wèi liánjiē"
#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c
+#: shared-bindings/audiopwmio/PWMAudioOut.c
msgid "Not playing"
msgstr "Wèi bòfàng"
@@ -1000,6 +1021,10 @@ msgstr "Xiàngsù chāochū huǎnchōng qū biānjiè"
msgid "Plus any modules on the filesystem\n"
msgstr "Zài wénjiàn xìtǒng shàng tiānjiā rènhé mókuài\n"
+#: shared-bindings/ps2io/Ps2.c
+msgid "Pop from an empty Ps2 buffer"
+msgstr "Cóng kōng de Ps2 huǎnchōng qū dànchū"
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr "Àn xià rènhé jiàn jìnrù REPL. Shǐyòng CTRL-D chóngxīn jiāzài."
@@ -1052,17 +1077,18 @@ msgstr "Zài ānquán móshì xià yùnxíng! Bù yùnxíng yǐ bǎocún de dài
msgid "SDA or SCL needs a pull up"
msgstr "SDA huò SCL xūyào lādòng"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "Sample rate must be positive"
msgstr "Cǎiyàng lǜ bìxū wèi zhèng shù"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#, c-format
msgid "Sample rate too high. It must be less than %d"
msgstr "Cǎiyàng lǜ tài gāo. Tā bìxū xiǎoyú %d"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
msgstr "Xùliè huà yǐjīng shǐyòngguò"
@@ -1111,6 +1137,8 @@ msgid ""
"The `microcontroller` module was used to boot into safe mode. Press reset to "
"exit safe mode.\n"
msgstr ""
+"“Wēi kòngzhì qì” mókuài yòng yú qǐdòng ānquán móshì. Àn chóng zhì kě tuìchū "
+"ānquán móshì.\n"
#: supervisor/shared/safe_mode.c
msgid ""
@@ -1131,19 +1159,19 @@ msgstr ""
"Qǐdòng CircuitPython shí, chóng zhì ànniǔ bèi àn xià. Zàicì àn xià yǐ tuìchū "
"ānquán móshì\n"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's bits_per_sample does not match the mixer's"
msgstr "Yàngběn de bits_per_sample yǔ hǔn yīn qì bù pǐpèi"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's channel count does not match the mixer's"
msgstr "Yàngběn de píndào jìshù yǔ hǔn yīn qì bù xiāngfú"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's sample rate does not match the mixer's"
msgstr "Yàngběn de yàngběn sùdù yǔ hǔn yīn qì de xiāngchà bù pǐpèi"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "The sample's signedness does not match the mixer's"
msgstr "Yàngběn de qiānmíng yǔ hǔn yīn qì de qiānmíng bù pǐpèi"
@@ -1152,8 +1180,12 @@ msgid "Tile height must exactly divide bitmap height"
msgstr "Píng pū gāodù bìxū huàfēn wèi tú gāodù"
#: shared-bindings/displayio/TileGrid.c
-msgid "Tile indices must be 0 - 255"
-msgstr "Píng pū zhǐshù bìxū wèi 0 - 255"
+msgid "Tile index out of bounds"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
+msgid "Tile value out of bounds"
+msgstr ""
#: shared-bindings/displayio/TileGrid.c
msgid "Tile width must exactly divide bitmap width"
@@ -1167,7 +1199,8 @@ msgstr "Yào tuìchū, qǐng chóng zhì bǎnkuài ér bùyòng "
msgid "Too many channels in sample."
msgstr "Chōuyàng zhōng de píndào tài duō."
-#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
+#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
+#: shared-bindings/displayio/ParallelBus.c
msgid "Too many display busses"
msgstr "Xiǎnshì zǒngxiàn tài duōle"
@@ -1192,8 +1225,8 @@ msgid "USB Error"
msgstr "USB Cuòwù"
#: shared-bindings/bleio/UUID.c
-msgid "UUID integer value not in range 0 to 0xffff"
-msgstr "UUID zhěngshù zhí bùzài fànwéi 0 zhì 0xffff"
+msgid "UUID integer value must be 0-0xffff"
+msgstr "UUID zhěngshù zhí bìxū wèi 0-0xffff"
#: shared-bindings/bleio/UUID.c
msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'"
@@ -1208,8 +1241,13 @@ msgstr "UUID zhí bùshì str,int huò zì jié huǎnchōng qū"
msgid "Unable to allocate buffers for signed conversion"
msgstr "Wúfǎ fēnpèi huǎnchōng qū yòng yú qiānmíng zhuǎnhuàn"
-#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+#: shared-module/displayio/I2CDisplay.c
+#, c-format
+msgid "Unable to find I2C Display at %x"
+msgstr "Wúfǎ zài%x zhǎodào I2C xiǎnshìqì"
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Unable to find free GCLK"
msgstr "Wúfǎ zhǎodào miǎnfèi de GCLK"
@@ -1242,7 +1280,7 @@ msgstr "Bù zhīchí de baudrate"
msgid "Unsupported display bus type"
msgstr "Bù zhīchí de gōnggòng qìchē lèixíng"
-#: shared-module/audioio/WaveFile.c
+#: shared-module/audiocore/WaveFile.c
msgid "Unsupported format"
msgstr "Bù zhīchí de géshì"
@@ -1258,7 +1296,7 @@ msgstr "Bù zhīchí de lādòng zhí."
msgid "Viper functions don't currently support more than 4 arguments"
msgstr "Viper hánshù mùqián bù zhīchí chāoguò 4 gè cānshù"
-#: shared-module/audioio/Mixer.c
+#: shared-module/audiocore/Mixer.c
msgid "Voice index too high"
msgstr "Yǔyīn suǒyǐn tài gāo"
@@ -1383,7 +1421,7 @@ msgstr "bǐtè bìxū shì 7,8 huò 9"
msgid "bits must be 8"
msgstr "bǐtè bìxū shì 8"
-#: shared-bindings/audioio/Mixer.c
+#: shared-bindings/audiocore/Mixer.c
msgid "bits_per_sample must be 8 or 16"
msgstr "měi jiàn yàngběn bìxū wèi 8 huò 16"
@@ -1396,7 +1434,7 @@ msgstr "fēnzhī bùzài fànwéi nèi"
msgid "buf is too small. need %d bytes"
msgstr "huǎnchōng tài xiǎo. Xūyào%d zì jié"
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr "huǎnchōng qū bìxū shì zì jié lèi duìxiàng"
@@ -1700,7 +1738,7 @@ msgstr "bèi líng chú"
msgid "empty"
msgstr "kòngxián"
-#: extmod/modutimeq.c extmod/moduheapq.c
+#: extmod/moduheapq.c extmod/modutimeq.c
msgid "empty heap"
msgstr "kōng yīn yīnxiào"
@@ -1761,7 +1799,8 @@ msgstr "éwài de guānjiàn cí cānshù"
msgid "extra positional arguments given"
msgstr "gěi chūle éwài de wèizhì cānshù"
-#: shared-bindings/audioio/WaveFile.c shared-bindings/displayio/OnDiskBitmap.c
+#: shared-bindings/audiocore/WaveFile.c
+#: shared-bindings/displayio/OnDiskBitmap.c
msgid "file must be a file opened in byte mode"
msgstr "wénjiàn bìxū shì zài zì jié móshì xià dǎkāi de wénjiàn"
@@ -1890,9 +1929,10 @@ msgstr "zhěngshù() cānshù 2 bìxū > = 2 qiě <= 36"
msgid "integer required"
msgstr "xūyào zhěngshù"
-#: ports/nrf/common-hal/bleio/Broadcaster.c
-msgid "interval not in range 0.0020 to 10.24"
-msgstr "jùlí 0.0020 Zhì 10.24 Zhī jiān de jiàngé shíjiān"
+#: shared-bindings/bleio/Peripheral.c shared-bindings/bleio/Scanner.c
+#, c-format
+msgid "interval must be in range %s-%s"
+msgstr "Jiàngé bìxū zài %s-%s fànwéi nèi"
#: extmod/machine_i2c.c
msgid "invalid I2C peripheral"
@@ -2107,6 +2147,14 @@ msgstr "méiyǒu mókuài '%q'"
msgid "no such attribute"
msgstr "méiyǒu cǐ shǔxìng"
+#: shared-bindings/bleio/Peripheral.c
+msgid "non-Service found in services"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Central.c
+msgid "non-UUID found in service_uuids"
+msgstr ""
+
#: py/compile.c
msgid "non-default argument follows default argument"
msgstr "bùshì mòrèn cānshù zūnxún mòrèn cānshù"
@@ -2164,7 +2212,7 @@ msgstr "duìxiàng bùshì diédài qì"
msgid "object not callable"
msgstr "duìxiàng wúfǎ diàoyòng"
-#: py/sequence.c
+#: py/sequence.c shared-bindings/displayio/Group.c
msgid "object not in sequence"
msgstr "duìxiàng bùshì xùliè"
@@ -2297,7 +2345,7 @@ msgstr "fǎnhuí yùqí de '%q' dàn huòdéle '%q'"
msgid "rsplit(None,n)"
msgstr ""
-#: shared-bindings/audioio/RawSample.c
+#: shared-bindings/audiocore/RawSample.c
msgid ""
"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or "
"'B'"
@@ -2317,10 +2365,6 @@ msgstr "jìhuà duīzhàn yǐ mǎn"
msgid "script compilation not supported"
msgstr "bù zhīchí jiǎoběn biānyì"
-#: shared-bindings/bleio/Peripheral.c
-msgid "services includes an object that is not a Service"
-msgstr "fúwù bāokuò yīgè bùshì fúwù de wùjiàn"
-
#: py/objstr.c
msgid "sign not allowed in string format specifier"
msgstr "zìfú chuàn géshì shuōmíng fú zhōng bù yǔnxǔ shǐyòng fúhào"
@@ -2418,10 +2462,6 @@ msgstr "uctypes miáoshù fú zhōng de yǔfǎ cuòwù"
msgid "threshold must be in the range 0-65536"
msgstr "yùzhí bìxū zài fànwéi 0-65536"
-#: shared-bindings/displayio/TileGrid.c
-msgid "tile index out of bounds"
-msgstr "kuài suǒyǐn chāochū fànwéi"
-
#: shared-bindings/time/__init__.c
msgid "time.struct_time() takes a 9-sequence"
msgstr "time.struct_time() xūyào 9 xùliè"
@@ -2580,13 +2620,17 @@ msgstr "bù zhīchí de lèixíng wèi %q: '%s', '%s'"
#: py/objint.c
#, c-format
-msgid "value would overflow a %d byte buffer"
-msgstr ""
+msgid "value must fit in %d byte(s)"
+msgstr "Zhí bìxū fúhé %d zì jié"
#: shared-bindings/displayio/Bitmap.c
msgid "value_count must be > 0"
msgstr "zhí jìshù bìxū wèi > 0"
+#: shared-bindings/bleio/Scanner.c
+msgid "window must be <= interval"
+msgstr "Chuāngkǒu bìxū shì <= jiàngé"
+
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "write_args must be a list, tuple, or None"
msgstr "xiě cānshù bìxū shì yuán zǔ, lièbiǎo huò None"
@@ -2615,6 +2659,51 @@ msgstr "y zhí chāochū biānjiè"
msgid "zero step"
msgstr "líng bù"
+#~ msgid "Address is not %d bytes long or is in wrong format"
+#~ msgstr "Dìzhǐ bùshì %d zì jié zhǎng, huòzhě géshì cuòwù"
+
+#~ msgid "Can't add services in Central mode"
+#~ msgstr "Wúfǎ zài zhōngyāng móshì xià tiānjiā fúwù"
+
+#~ msgid "Can't advertise in Central mode"
+#~ msgstr "Wúfǎ zài zhōngyāng móshì zhōng guǎnggào"
+
+#~ msgid "Can't change the name in Central mode"
+#~ msgstr "Wúfǎ gēnggǎi zhōngyāng móshì de míngchēng"
+
+#~ msgid "Can't connect in Peripheral mode"
+#~ msgstr "Wúfǎ zài biānyuán móshì zhōng liánjiē"
+
+#~ msgid "Data too large for the advertisement packet"
+#~ msgstr "Guǎnggào bāo de shùjù tài dà"
+
+#~ msgid "Failed to acquire mutex"
+#~ msgstr "Wúfǎ huòdé mutex"
+
+#~ msgid "Failed to add service"
+#~ msgstr "Tiānjiā fúwù shībài"
+
+#~ msgid "Failed to connect:"
+#~ msgstr "Liánjiē shībài:"
+
+#~ msgid "Failed to continue scanning"
+#~ msgstr "Jìxù sǎomiáo shībài"
+
+#~ msgid "Failed to create mutex"
+#~ msgstr "Wúfǎ chuàngjiàn hù chì suǒ"
+
+#~ msgid "Failed to release mutex"
+#~ msgstr "Wúfǎ shìfàng mutex"
+
+#~ msgid "Failed to start advertising"
+#~ msgstr "Qǐdòng guǎnggào shībài"
+
+#~ msgid "Failed to start scanning"
+#~ msgstr "Qǐdòng sǎomiáo shībài"
+
+#~ msgid "Failed to stop advertising"
+#~ msgstr "Wúfǎ tíngzhǐ guǎnggào"
+
#~ msgid "Invalid bit clock pin"
#~ msgstr "Wúxiào de wèi shízhōng yǐn jiǎo"
@@ -2624,6 +2713,9 @@ msgstr "líng bù"
#~ msgid "Invalid data pin"
#~ msgstr "Wúxiào de shùjù yǐn jiǎo"
+#~ msgid "Must be a Group subclass."
+#~ msgstr "Bìxū shì fēnzǔ zi lèi."
+
#~ msgid "No default I2C bus"
#~ msgstr "Méiyǒu mòrèn I2C gōnggòng qìchē"
@@ -2636,12 +2728,27 @@ msgstr "líng bù"
#~ msgid "Only bit maps of 8 bit color or less are supported"
#~ msgstr "Jǐn zhīchí 8 wèi yánsè huò xiǎoyú"
+#~ msgid "Tile indices must be 0 - 255"
+#~ msgstr "Píng pū zhǐshù bìxū wèi 0 - 255"
+
+#~ msgid "UUID integer value not in range 0 to 0xffff"
+#~ msgstr "UUID zhěngshù zhí bùzài fànwéi 0 zhì 0xffff"
+
#~ msgid "expected a DigitalInOut"
#~ msgstr "qídài de DigitalInOut"
+#~ msgid "interval not in range 0.0020 to 10.24"
+#~ msgstr "jùlí 0.0020 Zhì 10.24 Zhī jiān de jiàngé shíjiān"
+
#~ msgid "row must be packed and word aligned"
#~ msgstr "xíng bìxū dǎbāo bìngqiě zì duìqí"
+#~ msgid "services includes an object that is not a Service"
+#~ msgstr "fúwù bāokuò yīgè bùshì fúwù de wùjiàn"
+
+#~ msgid "tile index out of bounds"
+#~ msgstr "kuài suǒyǐn chāochū fànwéi"
+
#~ msgid "too many arguments"
#~ msgstr "tài duō cānshù"
diff --git a/main.c b/main.c
index 107b5b3c2..6ab50fc3c 100755
--- a/main.c
+++ b/main.c
@@ -45,7 +45,6 @@
#include "background.h"
#include "mpconfigboard.h"
-#include "shared-module/displayio/__init__.h"
#include "supervisor/cpu.h"
#include "supervisor/memory.h"
#include "supervisor/port.h"
@@ -58,6 +57,10 @@
#include "supervisor/shared/stack.h"
#include "supervisor/serial.h"
+#if CIRCUITPY_DISPLAYIO
+#include "shared-module/displayio/__init__.h"
+#endif
+
#if CIRCUITPY_NETWORK
#include "shared-module/network/__init__.h"
#endif
@@ -187,7 +190,9 @@ void cleanup_after_vm(supervisor_allocation* heap) {
supervisor_move_memory();
reset_port();
+ #if CIRCUITPY_BOARD
reset_board_busses();
+ #endif
reset_board();
reset_status_led();
}
@@ -455,6 +460,11 @@ 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
+
// This naively collects all object references from an approximate stack
// range.
gc_collect_root((void**)sp, ((uint32_t)&_estack - sp) / sizeof(uint32_t));
diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile
index 9b110c1bb..8e3fe9460 100644
--- a/ports/atmel-samd/Makefile
+++ b/ports/atmel-samd/Makefile
@@ -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,18 @@ 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
endif
CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT)
diff --git a/ports/atmel-samd/README.rst b/ports/atmel-samd/README.rst
index 167373b26..9afa19b83 100644
--- a/ports/atmel-samd/README.rst
+++ b/ports/atmel-samd/README.rst
@@ -124,15 +124,20 @@ Setup
-----
An ARM compiler is required for the build, along with the associated binary
-utilities. On Ubuntu, these can be installed as follows:
+utilities. They can be installed as follows:
-.. code-block:: shell
+- Ubuntu
+
+ .. code-block:: shell
+
+ sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa
+ sudo apt-get install gcc-arm-embedded
+
+- Arch Linux
- 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 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.
diff --git a/ports/atmel-samd/audio_dma.c b/ports/atmel-samd/audio_dma.c
index 68d6f182d..6b5eeddcc 100644
--- a/ports/atmel-samd/audio_dma.c
+++ b/ports/atmel-samd/audio_dma.c
@@ -29,8 +29,8 @@
#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"
diff --git a/ports/atmel-samd/audio_dma.h b/ports/atmel-samd/audio_dma.h
index 041d675a2..53173c277 100644
--- a/ports/atmel-samd/audio_dma.h
+++ b/ports/atmel-samd/audio_dma.h
@@ -29,8 +29,8 @@
#include "extmod/vfs_fat.h"
#include "py/obj.h"
-#include "shared-module/audioio/RawSample.h"
-#include "shared-module/audioio/WaveFile.h"
+#include "shared-module/audiocore/RawSample.h"
+#include "shared-module/audiocore/WaveFile.h"
typedef struct {
mp_obj_t sample;
diff --git a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk
index bafb8a96c..a543468e5 100644
--- a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk
@@ -4,9 +4,10 @@ USB_PID = 0x8053
USB_PRODUCT = "Arduino MKR1300"
USB_MANUFACTURER = "Arduino"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
-
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk
index b6df8d6e2..5612eb88d 100644
--- a/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk
@@ -1,12 +1,14 @@
LD_FILE = boards/samd21x18-bootloader.ld
USB_VID = 0x239A
-USB_PID = 0x8035
+USB_PID = 0x8050
USB_PRODUCT = "Arduino MKRZero"
USB_MANUFACTURER = "Arduino"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk
index af953e8c2..cbbf15a3e 100644
--- a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk
@@ -4,9 +4,11 @@ USB_PID = 0x824D
USB_PRODUCT = "Arduino Zero"
USB_MANUFACTURER = "Arduino"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.mk b/ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.mk
index 0e9bf7b45..08e42aa4e 100644
--- a/ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.mk
@@ -4,9 +4,9 @@ USB_PID = 0xBAB3
USB_PRODUCT = "Bast Pro Mini M0"
USB_MANUFACTURER = "Electronic Cats"
+CHIP_VARIANT = SAMD21E18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
-
-CHIP_VARIANT = SAMD21E18A
-CHIP_FAMILY = samd21
diff --git a/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk b/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk
index 88a059dcf..97c8eb863 100644
--- a/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk
@@ -4,6 +4,9 @@ USB_PID = 0xEDB3
USB_PRODUCT = "Programmable USB Hub"
USB_MANUFACTURER = "Capable Robot Components"
+CHIP_VARIANT = SAMD51G19A
+CHIP_FAMILY = samd51
+
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = GD25Q16C
@@ -13,6 +16,3 @@ LONGINT_IMPL = MPZ
CIRCUITPY_AUDIOBUSIO = 0
# No touch on SAMD51 yet
CIRCUITPY_TOUCHIO = 0
-
-CHIP_VARIANT = SAMD51G19A
-CHIP_FAMILY = samd51
diff --git a/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.mk b/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.mk
index 9cdfca5b1..2399aad5c 100644
--- a/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.mk
@@ -4,9 +4,9 @@ USB_PID = 0xBAB2
USB_PRODUCT = "CatWAN USBStick"
USB_MANUFACTURER = "Electronic Cats"
+CHIP_VARIANT = SAMD21E18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
-
-CHIP_VARIANT = SAMD21E18A
-CHIP_FAMILY = samd21
diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk
index 652d20137..3c43776f5 100644
--- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk
@@ -4,6 +4,9 @@ USB_PID = 0x8019
USB_PRODUCT = "CircuitPlayground Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
@@ -14,8 +17,8 @@ CIRCUITPY_DISPLAYIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CSLAVE = 0
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
+SUPEROPT_GC = 0
+CFLAGS_INLINE_LIMIT = 55
# Include these Python libraries in firmware.
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
@@ -24,10 +27,3 @@ FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Thermistor
-
-# Tweak inlining depending on language.
-ifeq ($(TRANSLATION), zh_Latn_pinyin)
-CFLAGS_INLINE_LIMIT = 35
-else
-CFLAGS_INLINE_LIMIT = 55
-endif
diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk
index bdcb4d350..f456515f9 100644
--- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk
@@ -4,26 +4,23 @@ USB_PID = 0x8019
USB_PRODUCT = "CircuitPlayground Express with Crickit libraries"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
-# Turn off longints for Crickit build to make room for additional frozen libs.
-LONGINT_IMPL = NONE
+# Turn off features and optimizations for Crickit build to make room for additional frozen libs.
+LONGINT_IMPL = NONE
CIRCUITPY_DISPLAYIO = 0
CIRCUITPY_PIXELBUF = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CSLAVE = 0
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
-
-# Tweak inlining depending on language.
-ifeq ($(TRANSLATION), zh_Latn_pinyin)
-CFLAGS_INLINE_LIMIT = 35
-else
+SUPEROPT_GC = 0
CFLAGS_INLINE_LIMIT = 55
-endif
+
# Include these Python libraries in firmware.
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
diff --git a/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk b/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk
index 0444a37b9..72a191044 100644
--- a/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk
@@ -4,14 +4,15 @@ USB_PID = 0x8021
USB_PRODUCT = "CP32-M4"
USB_MANUFACTURER = "Nadda-Reel Company LLC"
+CHIP_VARIANT = SAMD51J20A
+CHIP_FAMILY = samd51
+
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "W25Q128JV_PM"
-# No I2S on SAMD51G
+CIRCUITPY_PS2IO = 1
+# No I2S on SAMD51G.
CIRCUITPY_AUDIOBUSIO = 0
-# No touch on SAMD51 yet
+# No touch on SAMD51 yet.
CIRCUITPY_TOUCHIO = 0
-
-CHIP_VARIANT = SAMD51J20A
-CHIP_FAMILY = samd51
diff --git a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk
index e6b21e25b..794920fe3 100644
--- a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk
@@ -4,17 +4,16 @@ USB_PID = 0x0001
USB_PRODUCT = "Datalore IP M4"
USB_MANUFACTURER = "TG-Boards"
+CHIP_VARIANT = SAMD51J19A
+CHIP_FAMILY = samd51
+
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 3
EXTERNAL_FLASH_DEVICES = "GD25Q16C, W25Q16JV_IQ, W25Q16JV_IM"
-
LONGINT_IMPL = MPZ
-CHIP_VARIANT = SAMD51J19A
-CHIP_FAMILY = samd51
-
-# No touch on SAMD51 yet
-CIRCUITPY_TOUCHIO = 0
-
CIRCUITPY_NETWORK = 1
MICROPY_PY_WIZNET5K = 5500
+CIRCUITPY_PS2IO = 1
+# No touch on SAMD51 yet
+CIRCUITPY_TOUCHIO = 0
diff --git a/ports/atmel-samd/boards/robohatmm1/board.c b/ports/atmel-samd/boards/datum_distance/board.c
index c8e20206a..c8e20206a 100644
--- a/ports/atmel-samd/boards/robohatmm1/board.c
+++ b/ports/atmel-samd/boards/datum_distance/board.c
diff --git a/ports/atmel-samd/boards/datum_distance/mpconfigboard.h b/ports/atmel-samd/boards/datum_distance/mpconfigboard.h
new file mode 100644
index 000000000..e02e43780
--- /dev/null
+++ b/ports/atmel-samd/boards/datum_distance/mpconfigboard.h
@@ -0,0 +1,29 @@
+// LEDs
+#define MICROPY_HW_LED_STATUS (&pin_PA17)
+#define MICROPY_HW_LED_TX &pin_PA27
+#define MICROPY_HW_LED_RX &pin_PA17
+
+#define MICROPY_HW_BOARD_NAME "J&J Studios datum-Distance"
+#define MICROPY_HW_MCU_NAME "samd21g18"
+
+#define MICROPY_PORT_A (0)
+#define MICROPY_PORT_B (0)
+#define MICROPY_PORT_C (0)
+
+#define CIRCUITPY_INTERNAL_NVM_SIZE 256
+
+#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PA23)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA22)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PB11)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PB10)
+#define DEFAULT_SPI_BUS_MISO (&pin_PA12)
+
+#define DEFAULT_UART_BUS_RX (&pin_PA11)
+#define DEFAULT_UART_BUS_TX (&pin_PA10)
+
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
diff --git a/ports/atmel-samd/boards/datum_distance/mpconfigboard.mk b/ports/atmel-samd/boards/datum_distance/mpconfigboard.mk
new file mode 100644
index 000000000..a7bb8293d
--- /dev/null
+++ b/ports/atmel-samd/boards/datum_distance/mpconfigboard.mk
@@ -0,0 +1,14 @@
+LD_FILE = boards/samd21x18-bootloader.ld
+USB_VID = 0x04D8
+USB_PID = 0xEE8C
+USB_PRODUCT = "datum-Distance"
+USB_MANUFACTURER = "J&J Studios LLC"
+
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
+INTERNAL_FLASH_FILESYSTEM = 1
+LONGINT_IMPL = NONE
+CIRCUITPY_SMALL_BUILD = 1
+
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/datum_distance/pins.c b/ports/atmel-samd/boards/datum_distance/pins.c
new file mode 100644
index 000000000..b29a859b6
--- /dev/null
+++ b/ports/atmel-samd/boards/datum_distance/pins.c
@@ -0,0 +1,27 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) },
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) },
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) },
+ { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) },
+ { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) },
+ { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) },
+ { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/datum_imu/board.c b/ports/atmel-samd/boards/datum_imu/board.c
new file mode 100644
index 000000000..c8e20206a
--- /dev/null
+++ b/ports/atmel-samd/boards/datum_imu/board.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+
+void board_init(void)
+{
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/datum_imu/mpconfigboard.h b/ports/atmel-samd/boards/datum_imu/mpconfigboard.h
new file mode 100644
index 000000000..b87739dd0
--- /dev/null
+++ b/ports/atmel-samd/boards/datum_imu/mpconfigboard.h
@@ -0,0 +1,29 @@
+// LEDs
+#define MICROPY_HW_LED_STATUS (&pin_PA17)
+#define MICROPY_HW_LED_TX &pin_PA27
+#define MICROPY_HW_LED_RX &pin_PA17
+
+#define MICROPY_HW_BOARD_NAME "J&J Studios datum-IMU"
+#define MICROPY_HW_MCU_NAME "samd21g18"
+
+#define MICROPY_PORT_A (0)
+#define MICROPY_PORT_B (0)
+#define MICROPY_PORT_C (0)
+
+#define CIRCUITPY_INTERNAL_NVM_SIZE 256
+
+#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PA23)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA22)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PB11)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PB10)
+#define DEFAULT_SPI_BUS_MISO (&pin_PA12)
+
+#define DEFAULT_UART_BUS_RX (&pin_PA11)
+#define DEFAULT_UART_BUS_TX (&pin_PA10)
+
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
diff --git a/ports/atmel-samd/boards/datum_imu/mpconfigboard.mk b/ports/atmel-samd/boards/datum_imu/mpconfigboard.mk
new file mode 100644
index 000000000..507c83b04
--- /dev/null
+++ b/ports/atmel-samd/boards/datum_imu/mpconfigboard.mk
@@ -0,0 +1,14 @@
+LD_FILE = boards/samd21x18-bootloader.ld
+USB_VID = 0x04D8
+USB_PID = 0xEE8D
+USB_PRODUCT = "datum-IMU"
+USB_MANUFACTURER = "J&J Studios LLC"
+
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
+INTERNAL_FLASH_FILESYSTEM = 1
+LONGINT_IMPL = NONE
+CIRCUITPY_SMALL_BUILD = 1
+
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/datum_imu/pins.c b/ports/atmel-samd/boards/datum_imu/pins.c
new file mode 100644
index 000000000..237b5774e
--- /dev/null
+++ b/ports/atmel-samd/boards/datum_imu/pins.c
@@ -0,0 +1,29 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA03) },
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) },
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) },
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) },
+ { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) },
+ { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) },
+ { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) },
+ { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/datum_light/board.c b/ports/atmel-samd/boards/datum_light/board.c
new file mode 100644
index 000000000..c8e20206a
--- /dev/null
+++ b/ports/atmel-samd/boards/datum_light/board.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+
+void board_init(void)
+{
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/datum_light/mpconfigboard.h b/ports/atmel-samd/boards/datum_light/mpconfigboard.h
new file mode 100644
index 000000000..2a91c112d
--- /dev/null
+++ b/ports/atmel-samd/boards/datum_light/mpconfigboard.h
@@ -0,0 +1,29 @@
+// LEDs
+#define MICROPY_HW_LED_STATUS (&pin_PA17)
+#define MICROPY_HW_LED_TX &pin_PA27
+#define MICROPY_HW_LED_RX &pin_PA17
+
+#define MICROPY_HW_BOARD_NAME "J&J Studios datum-Light"
+#define MICROPY_HW_MCU_NAME "samd21g18"
+
+#define MICROPY_PORT_A (0)
+#define MICROPY_PORT_B (0)
+#define MICROPY_PORT_C (0)
+
+#define CIRCUITPY_INTERNAL_NVM_SIZE 256
+
+#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PA23)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA22)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PB11)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PB10)
+#define DEFAULT_SPI_BUS_MISO (&pin_PA12)
+
+#define DEFAULT_UART_BUS_RX (&pin_PA11)
+#define DEFAULT_UART_BUS_TX (&pin_PA10)
+
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
diff --git a/ports/atmel-samd/boards/datum_light/mpconfigboard.mk b/ports/atmel-samd/boards/datum_light/mpconfigboard.mk
new file mode 100644
index 000000000..4bb227ba4
--- /dev/null
+++ b/ports/atmel-samd/boards/datum_light/mpconfigboard.mk
@@ -0,0 +1,14 @@
+LD_FILE = boards/samd21x18-bootloader.ld
+USB_VID = 0x04D8
+USB_PID = 0xEE8E
+USB_PRODUCT = "datum-Light"
+USB_MANUFACTURER = "J&J Studios LLC"
+
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
+INTERNAL_FLASH_FILESYSTEM = 1
+LONGINT_IMPL = NONE
+CIRCUITPY_SMALL_BUILD = 1
+
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/datum_light/pins.c b/ports/atmel-samd/boards/datum_light/pins.c
new file mode 100644
index 000000000..b29a859b6
--- /dev/null
+++ b/ports/atmel-samd/boards/datum_light/pins.c
@@ -0,0 +1,27 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) },
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) },
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) },
+ { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) },
+ { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) },
+ { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) },
+ { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/datum_weather/board.c b/ports/atmel-samd/boards/datum_weather/board.c
new file mode 100644
index 000000000..c8e20206a
--- /dev/null
+++ b/ports/atmel-samd/boards/datum_weather/board.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+
+void board_init(void)
+{
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/datum_weather/mpconfigboard.h b/ports/atmel-samd/boards/datum_weather/mpconfigboard.h
new file mode 100644
index 000000000..45619197b
--- /dev/null
+++ b/ports/atmel-samd/boards/datum_weather/mpconfigboard.h
@@ -0,0 +1,29 @@
+// LEDs
+#define MICROPY_HW_LED_STATUS (&pin_PA17)
+#define MICROPY_HW_LED_TX &pin_PA27
+#define MICROPY_HW_LED_RX &pin_PA17
+
+#define MICROPY_HW_BOARD_NAME "J&J Studios datum-Weather"
+#define MICROPY_HW_MCU_NAME "samd21g18"
+
+#define MICROPY_PORT_A (0)
+#define MICROPY_PORT_B (0)
+#define MICROPY_PORT_C (0)
+
+#define CIRCUITPY_INTERNAL_NVM_SIZE 256
+
+#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PA23)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA22)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PB11)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PB10)
+#define DEFAULT_SPI_BUS_MISO (&pin_PA12)
+
+#define DEFAULT_UART_BUS_RX (&pin_PA11)
+#define DEFAULT_UART_BUS_TX (&pin_PA10)
+
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
diff --git a/ports/atmel-samd/boards/datum_weather/mpconfigboard.mk b/ports/atmel-samd/boards/datum_weather/mpconfigboard.mk
new file mode 100644
index 000000000..411aee625
--- /dev/null
+++ b/ports/atmel-samd/boards/datum_weather/mpconfigboard.mk
@@ -0,0 +1,14 @@
+LD_FILE = boards/samd21x18-bootloader.ld
+USB_VID = 0x04D8
+USB_PID = 0xEE8F
+USB_PRODUCT = "datum-Weather"
+USB_MANUFACTURER = "J&J Studios LLC"
+
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
+INTERNAL_FLASH_FILESYSTEM = 1
+LONGINT_IMPL = NONE
+CIRCUITPY_SMALL_BUILD = 1
+
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/datum_weather/pins.c b/ports/atmel-samd/boards/datum_weather/pins.c
new file mode 100644
index 000000000..b29a859b6
--- /dev/null
+++ b/ports/atmel-samd/boards/datum_weather/pins.c
@@ -0,0 +1,27 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) },
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) },
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) },
+ { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) },
+ { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) },
+ { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) },
+ { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.mk b/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.mk
index 4d4649506..a2c182e68 100644
--- a/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.mk
@@ -4,9 +4,11 @@ USB_PID = 0xBAB6
USB_PRODUCT = "Escornabot Makech"
USB_MANUFACTURER = "Electronic Cats"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/escornabot_makech/pins.c b/ports/atmel-samd/boards/escornabot_makech/pins.c
index d92e9f373..d43d254e7 100644
--- a/ports/atmel-samd/boards/escornabot_makech/pins.c
+++ b/ports/atmel-samd/boards/escornabot_makech/pins.c
@@ -5,9 +5,10 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA04) },
{ MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA05) },
-
- // Buttons
{ MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA10) },
+
+ // Buttons
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA03) },
{ MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA00) },
diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk
index 26e3b7d4d..a88dbd563 100644
--- a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk
@@ -4,9 +4,11 @@ USB_PID = 0x8015
USB_PRODUCT = "Feather M0 Adalogger"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk
index 102cb656f..076f1f8ff 100644
--- a/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk
@@ -4,9 +4,11 @@ USB_PID = 0x8015
USB_PRODUCT = "Feather M0"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk
index a6190267d..756c293ad 100644
--- a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk
@@ -4,15 +4,13 @@ USB_PID = 0x8023
USB_PRODUCT = "Feather M0 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
LONGINT_IMPL = MPZ
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
-
-# Tweak inlining depending on language.
-ifeq ($(TRANSLATION), zh_Latn_pinyin)
CFLAGS_INLINE_LIMIT = 60
-endif
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk
index 620a0d505..5793d82e5 100644
--- a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk
@@ -4,6 +4,9 @@ USB_PID = 0x8023
USB_PRODUCT = "Feather M0 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
@@ -14,13 +17,8 @@ CIRCUITPY_BITBANGIO = 0
CIRCUITPY_DISPLAYIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CSLAVE = 0
-
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
-
-CFLAGS_INLINE_LIMIT = 50
-
CIRCUITPY_GAMEPAD = 0
+CFLAGS_INLINE_LIMIT = 50
# Include these Python libraries in firmware.
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk
index ce3f8668c..83d794d04 100644
--- a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk
@@ -4,9 +4,11 @@ USB_PID = 0x8015
USB_PRODUCT = "Feather M0 RFM69"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk
index 282977338..a84e14f55 100644
--- a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk
@@ -4,9 +4,11 @@ USB_PID = 0x8015
USB_PRODUCT = "Feather M0 RFM9x"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk
index 4bae6ffa7..e34d06962 100644
--- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk
@@ -4,10 +4,13 @@ USB_PID = 0x8023
USB_PRODUCT = "Feather M0 Supersized"
USB_MANUFACTURER = "Dave Astels"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "S25FL064L"
LONGINT_IMPL = MPZ
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
+CFLAGS_INLINE_LIMIT = 60
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk
index 4fddcffc1..8169345f5 100644
--- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk
@@ -4,17 +4,16 @@ USB_PID = 0x8026
USB_PRODUCT = "Feather M4 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
-QSPI_FLASH_FILESYSTEM = 1
+CHIP_VARIANT = SAMD51J19A
+CHIP_FAMILY = samd51
+QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = GD25Q16C
LONGINT_IMPL = MPZ
-# No touch on SAMD51 yet
-CIRCUITPY_TOUCHIO = 0
-
-CHIP_VARIANT = SAMD51J19A
-CHIP_FAMILY = samd51
-
CIRCUITPY_NETWORK = 1
MICROPY_PY_WIZNET5K = 5500
+CIRCUITPY_PS2IO = 1
+# No touch on SAMD51 yet
+CIRCUITPY_TOUCHIO = 0
diff --git a/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk
index d9350ea22..c4a3a5a19 100755
--- a/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk
@@ -4,6 +4,9 @@ USB_PID = 0x8023
USB_PRODUCT = "Feather RadioFruit Zigbee"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMR21G18A
+CHIP_FAMILY = samd21
+
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
@@ -13,6 +16,3 @@ LONGINT_IMPL = MPZ
CIRCUITPY_AUDIOBUSIO = 0
# No DAC on SAMR21G
CIRCUITPY_AUDIOIO = 0
-
-CHIP_VARIANT = SAMR21G18A
-CHIP_FAMILY = samd21
diff --git a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk
index 9f4a9fe83..6f44a22f8 100644
--- a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk
@@ -4,9 +4,11 @@ USB_PID = 0x801D
USB_PRODUCT = "Gemma M0"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD21E18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
-CHIP_VARIANT = SAMD21E18A
-CHIP_FAMILY = samd21
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk
index 63158681b..13631a736 100644
--- a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk
@@ -4,14 +4,14 @@ USB_PID = 0x8032
USB_PRODUCT = "Grand Central M4 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
-QSPI_FLASH_FILESYSTEM = 1
+CHIP_VARIANT = SAMD51P20A
+CHIP_FAMILY = samd51
+QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C"
LONGINT_IMPL = MPZ
+CIRCUITPY_PS2IO = 1
# No touch on SAMD51 yet
CIRCUITPY_TOUCHIO = 0
-
-CHIP_VARIANT = SAMD51P20A
-CHIP_FAMILY = samd51
diff --git a/ports/atmel-samd/boards/hallowing_m0_express/board.c b/ports/atmel-samd/boards/hallowing_m0_express/board.c
index 6e0328e95..c12431f8b 100644
--- a/ports/atmel-samd/boards/hallowing_m0_express/board.c
+++ b/ports/atmel-samd/boards/hallowing_m0_express/board.c
@@ -74,12 +74,12 @@ void board_init(void) {
displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
bus->base.type = &displayio_fourwire_type;
busio_spi_obj_t *spi = common_hal_board_create_spi();
- common_hal_busio_spi_configure(spi, 12000000, 0, 0, 8);
common_hal_displayio_fourwire_construct(bus,
spi,
&pin_PA28, // Command or data
&pin_PA01, // Chip select
- &pin_PA27); // Reset
+ &pin_PA27, // Reset
+ 12000000);
displayio_display_obj_t* display = &displays[0].display;
display->base.type = &displayio_display_type;
@@ -91,6 +91,10 @@ void board_init(void) {
1, // row start
0, // rotation
16, // Color depth
+ false, // Grayscale
+ false, // Pixels in a byte share a row. Only used for depth < 8
+ 1, // bytes per cell. Only valid for depths < 8
+ false, // reverse_pixels_in_byte. Only valid for depths < 8
MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command
MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command
MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command
@@ -98,6 +102,7 @@ void board_init(void) {
display_init_sequence,
sizeof(display_init_sequence),
&pin_PA00,
+ NO_BRIGHTNESS_COMMAND,
1.0f, // brightness (ignored)
true, // auto_brightness
false, // single_byte_bounds
diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk
index 1df82ff44..92374721f 100644
--- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk
@@ -4,6 +4,9 @@ USB_PID = 0xD1ED
USB_PRODUCT = "HalloWing M0 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C"
@@ -13,11 +16,8 @@ LONGINT_IMPL = MPZ
CIRCUITPY_I2CSLAVE = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_AUDIOBUSIO = 0
-
-CFLAGS_INLINE_LIMIT = 50
-
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
+CIRCUITPY_BITBANGIO = 0
+SUPEROPT_GC = 0
# Include these Python libraries in firmware.
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk
index 4f3e1ca66..e427e9430 100644
--- a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk
@@ -4,17 +4,13 @@ USB_PID = 0x8012
USB_PRODUCT = "ItsyBitsy M0 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "W25Q16FW, GD25Q16C"
LONGINT_IMPL = MPZ
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
-
-# Tweak inlining depending on language.
-ifeq ($(TRANSLATION), zh_Latn_pinyin)
-CFLAGS_INLINE_LIMIT = 45
-else
-CFLAGS_INLINE_LIMIT = 70
-endif
+CFLAGS_INLINE_LIMIT = 60
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk
index d4d674d9d..31bb38e20 100644
--- a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk
@@ -4,15 +4,16 @@ USB_PID = 0x802C
USB_PRODUCT = "ItsyBitsy M4 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD51G19A
+CHIP_FAMILY = samd51
+
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = GD25Q16C
LONGINT_IMPL = MPZ
+CIRCUITPY_PS2IO = 1
# No I2S on SAMD51G
CIRCUITPY_AUDIOBUSIO = 0
# No touch on SAMD51 yet
CIRCUITPY_TOUCHIO = 0
-
-CHIP_VARIANT = SAMD51G19A
-CHIP_FAMILY = samd51
diff --git a/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk
index e97a70105..5871cca2a 100644
--- a/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk
@@ -4,14 +4,15 @@ USB_PID = 0xED94
USB_PRODUCT = "kicksat-sprite"
USB_MANUFACTURER = "maholli"
+CHIP_VARIANT = SAMD51G19A
+CHIP_FAMILY = samd51
+
QSPI_FLASH_FILESYSTEM = 0
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = MPZ
# No touch on SAMD51 yet
CIRCUITPY_TOUCHIO = 0
+# Not needed.
CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_DISPLAYIO = 0
-
-CHIP_VARIANT = SAMD51G19A
-CHIP_FAMILY = samd51 \ No newline at end of file
diff --git a/ports/atmel-samd/boards/meowmeow/mpconfigboard.mk b/ports/atmel-samd/boards/meowmeow/mpconfigboard.mk
index 3f9601d32..894e19a6b 100644
--- a/ports/atmel-samd/boards/meowmeow/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/meowmeow/mpconfigboard.mk
@@ -4,9 +4,11 @@ USB_PID = 0xBAB1
USB_PRODUCT = "Meow Meow"
USB_MANUFACTURER = "Electronic Cats"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk
index ce9c4baba..93a8ffc11 100644
--- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk
@@ -4,16 +4,13 @@ USB_PID = 0x8014
USB_PRODUCT = "Metro M0 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
-
LONGINT_IMPL = MPZ
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
-
-# Tweak inlining depending on language.
-ifeq ($(TRANSLATION), zh_Latn_pinyin)
-CFLAGS_INLINE_LIMIT = 50
-endif
+CFLAGS_INLINE_LIMIT = 60
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk
index 654a84eb8..d7d0c1d6e 100644
--- a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk
@@ -4,17 +4,16 @@ USB_PID = 0x8038
USB_PRODUCT = "Metro M4 Airlift Lite"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD51J19A
+CHIP_FAMILY = samd51
+
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 3
EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C"
-
LONGINT_IMPL = MPZ
-# No touch on SAMD51 yet
-CIRCUITPY_TOUCHIO = 0
-
-CHIP_VARIANT = SAMD51J19A
-CHIP_FAMILY = samd51
-
CIRCUITPY_NETWORK = 1
MICROPY_PY_WIZNET5K = 5500
+CIRCUITPY_PS2IO = 1
+# No touch on SAMD51 yet
+CIRCUITPY_TOUCHIO = 0
diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk
index 35162b678..829bf749f 100644
--- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk
@@ -4,17 +4,16 @@ USB_PID = 0x8021
USB_PRODUCT = "Metro M4 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD51J19A
+CHIP_FAMILY = samd51
+
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 3
EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C"
-
LONGINT_IMPL = MPZ
-# No touch on SAMD51 yet
-CIRCUITPY_TOUCHIO = 0
-
-CHIP_VARIANT = SAMD51J19A
-CHIP_FAMILY = samd51
-
CIRCUITPY_NETWORK = 1
MICROPY_PY_WIZNET5K = 5500
+CIRCUITPY_PS2IO = 1
+# No touch on SAMD51 yet
+CIRCUITPY_TOUCHIO = 0
diff --git a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk
index 27bad2693..a8f47dced 100644
--- a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk
@@ -4,16 +4,16 @@ USB_PID = 0x2017
USB_PRODUCT = "Mini SAM M4"
USB_MANUFACTURER = "Benjamin Shockley"
+CHIP_VARIANT = SAMD51G19A
+CHIP_FAMILY = samd51
+
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "W25Q16JV_IM"
-
LONGINT_IMPL = MPZ
+CIRCUITPY_PS2IO = 1
# No I2S on SAMD51G
CIRCUITPY_AUDIOBUSIO = 0
# No touch on SAMD51 yet
CIRCUITPY_TOUCHIO = 0
-
-CHIP_VARIANT = SAMD51G19A
-CHIP_FAMILY = samd51
diff --git a/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk b/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk
index b36a21368..e24a29051 100644
--- a/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk
@@ -4,13 +4,12 @@ USB_PID = 0x801D
USB_PRODUCT = "PewPew 10.2"
USB_MANUFACTURER = "Radomir Dopieralski"
-INTERNAL_FLASH_FILESYSTEM = 1
-LONGINT_IMPL = NONE
-
CHIP_VARIANT = SAMD21E18A
CHIP_FAMILY = samd21
-FROZEN_MPY_DIRS += $(TOP)/frozen/pew-pewpew-standalone-10.x
+INTERNAL_FLASH_FILESYSTEM = 1
+LONGINT_IMPL = NONE
+CIRCUITPY_SMALL_BUILD = 1
CIRCUITPY_PEW = 1
CIRCUITPY_ANALOGIO = 1
@@ -20,9 +19,7 @@ CIRCUITPY_ROTARYIO = 0
CIRCUITPY_RTC = 0
CIRCUITPY_SAMD = 0
CIRCUITPY_USB_MIDI = 0
-CIRCUITPY_SMALL_BUILD = 1
-# Tweak inlining depending on language.
-ifeq ($(TRANSLATION), zh_Latn_pinyin)
-CFLAGS_INLINE_LIMIT = 40
-endif
+SUPEROPT_GC = 0
+
+FROZEN_MPY_DIRS += $(TOP)/frozen/pew-pewpew-standalone-10.x
diff --git a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk
index 4405b7a35..686c9099f 100644
--- a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk
@@ -4,6 +4,9 @@ USB_PID = 0x8028
USB_PRODUCT = "pIRKey M0"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD21E18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
@@ -19,11 +22,8 @@ CIRCUITPY_SAMD = 0
CIRCUITPY_USB_MIDI = 1
CIRCUITPY_TOUCHIO = 0
CIRCUITPY_SMALL_BUILD = 1
-
-CHIP_VARIANT = SAMD21E18A
-CHIP_FAMILY = samd21
-
-CFLAGS_INLINE_LIMIT = 25
+# Make more room.
+SUPEROPT_GC = 0
# Include these Python libraries in firmware.
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar
diff --git a/ports/atmel-samd/boards/pirkey_m0/pins.c b/ports/atmel-samd/boards/pirkey_m0/pins.c
index e1f43c83c..41d02e329 100644
--- a/ports/atmel-samd/boards/pirkey_m0/pins.c
+++ b/ports/atmel-samd/boards/pirkey_m0/pins.c
@@ -5,8 +5,5 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA00) },
{ MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA01) },
- { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
- { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
- { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
};
MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/pybadge/board.c b/ports/atmel-samd/boards/pybadge/board.c
index 2b0e334fa..e30b901b0 100644
--- a/ports/atmel-samd/boards/pybadge/board.c
+++ b/ports/atmel-samd/boards/pybadge/board.c
@@ -73,7 +73,6 @@ void board_init(void) {
busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus;
common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL);
common_hal_busio_spi_never_reset(spi);
- common_hal_busio_spi_configure(spi, 24000000, 0, 0, 8);
displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
bus->base.type = &displayio_fourwire_type;
@@ -81,18 +80,23 @@ void board_init(void) {
spi,
&pin_PB05, // TFT_DC Command or data
&pin_PB07, // TFT_CS Chip select
- &pin_PA00); // TFT_RST Reset
+ &pin_PA00, // TFT_RST Reset
+ 60000000);
displayio_display_obj_t* display = &displays[0].display;
display->base.type = &displayio_display_type;
common_hal_displayio_display_construct(display,
bus,
- 160, // Width
- 128, // Height
+ 160, // Width (after rotation)
+ 128, // Height (after rotation)
0, // column start
0, // row start
270, // rotation
16, // Color depth
+ false, // grayscale
+ false, // pixels in byte share row. only used for depth < 8
+ 1, // bytes per cell. Only valid for depths < 8
+ false, // reverse_pixels_in_byte. Only valid for depths < 8
MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command
MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command
MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command
@@ -100,6 +104,7 @@ void board_init(void) {
display_init_sequence,
sizeof(display_init_sequence),
&pin_PA01, // backlight pin
+ NO_BRIGHTNESS_COMMAND,
1.0f, // brightness (ignored)
true, // auto_brightness
false, // single_byte_bounds
diff --git a/ports/atmel-samd/boards/pybadge/mpconfigboard.mk b/ports/atmel-samd/boards/pybadge/mpconfigboard.mk
index aba0e333d..b8d10387b 100644
--- a/ports/atmel-samd/boards/pybadge/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pybadge/mpconfigboard.mk
@@ -1,25 +1,23 @@
LD_FILE = boards/samd51x19-bootloader-external-flash.ld
USB_VID = 0x239A
-USB_PID = 0x802C
+USB_PID = 0x8034
USB_PRODUCT = "PyBadge"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD51J19A
+CHIP_FAMILY = samd51
+
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = GD25Q16C
LONGINT_IMPL = MPZ
-# No touch on SAMD51 yet
-CIRCUITPY_TOUCHIO = 0
-
+CIRCUITPY_AUDIOIO = 1
+CIRCUITPY_DISPLAYIO = 1
+CIRCUITPY_GAMEPAD = 1
CIRCUITPY_GAMEPADSHIFT = 1
-
-CHIP_VARIANT = SAMD51J19A
-CHIP_FAMILY = samd51
-
CIRCUITPY_STAGE = 1
-CIRCUITPY_GAMEPAD = 1
-CIRCUITPY_DISPLAYIO = 1
-CIRCUITPY_AUDIOIO = 1
+# No touch on SAMD51 yet
+CIRCUITPY_TOUCHIO = 0
FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pybadge
diff --git a/ports/atmel-samd/boards/pybadge_airlift/board.c b/ports/atmel-samd/boards/pybadge_airlift/board.c
new file mode 100644
index 000000000..38fb33886
--- /dev/null
+++ b/ports/atmel-samd/boards/pybadge_airlift/board.c
@@ -0,0 +1,97 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+#include "mpconfigboard.h"
+#include "hal/include/hal_gpio.h"
+#include "shared-bindings/busio/SPI.h"
+#include "shared-bindings/displayio/FourWire.h"
+#include "shared-module/displayio/__init__.h"
+#include "shared-module/displayio/mipi_constants.h"
+#include "tick.h"
+
+displayio_fourwire_obj_t board_display_obj;
+
+#define DELAY 0x80
+
+uint8_t display_init_sequence[] = {
+ 0x01, 0 | DELAY, 150, // SWRESET
+ 0x11, 0 | DELAY, 255, // SLPOUT
+ 0x36, 1, 0x08, // _MADCTL bottom to top refresh in vsync aligned order.
+ 0x3a, 1, 0x55, // COLMOD - 16bit color
+ 0x21, 0 | DELAY, 10, // _INVON
+ 0x13, 0 | DELAY, 10, // _NORON
+ 0x29, 0 | DELAY, 255, // _DISPON
+};
+
+void board_init(void) {
+ busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus;
+ common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL);
+ common_hal_busio_spi_never_reset(spi);
+
+ displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
+ bus->base.type = &displayio_fourwire_type;
+ common_hal_displayio_fourwire_construct(bus,
+ spi,
+ &pin_PB05, // TFT_DC Command or data
+ &pin_PB06, // TFT_CS Chip select
+ &pin_PB07, // TFT_RST Reset
+ 60000000);
+
+ displayio_display_obj_t* display = &displays[0].display;
+ display->base.type = &displayio_display_type;
+ common_hal_displayio_display_construct(display,
+ bus,
+ 320, // Width (after rotation)
+ 240, // Height (after rotation)
+ 0, // column start
+ 0, // row start
+ 90, // rotation
+ 16, // Color depth
+ false, // grayscale
+ false, // pixels in byte share row. Only used for depth < 8
+ 1, // bytes per cell. Only valid for depths < 8
+ false, // reverse_pixels_in_byte. Only valid for depths < 8
+ MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command
+ MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command
+ MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command
+ 0x37, // set vertical scroll command
+ display_init_sequence,
+ sizeof(display_init_sequence),
+ &pin_PA01, // backlight pin
+ NO_BRIGHTNESS_COMMAND,
+ 1.0f, // brightness (ignored)
+ true, // auto_brightness
+ false, // single_byte_bounds
+ false); // data_as_commands
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.h b/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.h
new file mode 100644
index 000000000..ade74786d
--- /dev/null
+++ b/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.h
@@ -0,0 +1,37 @@
+#define MICROPY_HW_BOARD_NAME "Adafruit Pybadge Airlift"
+#define MICROPY_HW_MCU_NAME "samd51j20"
+
+#define CIRCUITPY_MCU_FAMILY samd51
+
+// This is for Rev B
+#define MICROPY_HW_LED_STATUS (&pin_PA23)
+
+// These are pins not to reset.
+// QSPI Data pins
+#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11)
+// DotStar pins, QSPI CS, and QSPI SCK
+#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11)
+#define MICROPY_PORT_C (0)
+#define MICROPY_PORT_D (0)
+
+#define AUTORESET_DELAY_MS 500
+
+// If you change this, then make sure to update the linker scripts as well to
+// make sure you don't overwrite code
+#define CIRCUITPY_INTERNAL_NVM_SIZE 8192
+
+#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PA13)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA12)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PA17)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PB23)
+#define DEFAULT_SPI_BUS_MISO (&pin_PB22)
+
+#define DEFAULT_UART_BUS_RX (&pin_PB17)
+#define DEFAULT_UART_BUS_TX (&pin_PB16)
+
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
diff --git a/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.mk b/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.mk
new file mode 100644
index 000000000..12683e995
--- /dev/null
+++ b/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.mk
@@ -0,0 +1,23 @@
+LD_FILE = boards/samd51x19-bootloader-external-flash.ld
+USB_VID = 0x239A
+USB_PID = 0x8043
+USB_PRODUCT = "PyBadge AirLift"
+USB_MANUFACTURER = "Adafruit Industries LLC"
+
+CHIP_VARIANT = SAMD51J20A
+CHIP_FAMILY = samd51
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = GD25Q16C
+LONGINT_IMPL = MPZ
+
+CIRCUITPY_AUDIOIO = 1
+CIRCUITPY_DISPLAYIO = 1
+CIRCUITPY_GAMEPAD = 1
+CIRCUITPY_GAMEPADSHIFT = 1
+CIRCUITPY_STAGE = 1
+# No touch on SAMD51 yet
+CIRCUITPY_TOUCHIO = 0
+
+FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pybadge
diff --git a/ports/atmel-samd/boards/pybadge_airlift/pins.c b/ports/atmel-samd/boards/pybadge_airlift/pins.c
new file mode 100644
index 000000000..d39650246
--- /dev/null
+++ b/ports/atmel-samd/boards/pybadge_airlift/pins.c
@@ -0,0 +1,75 @@
+#include "shared-bindings/board/__init__.h"
+
+#include "boards/board.h"
+#include "shared-module/displayio/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ {MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB08)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB09)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB01)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB04)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PB03)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PB02)},
+
+ {MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB17)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB16)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB03)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB02)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA14)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA16)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA18)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB14)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA15)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA19)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA20)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA21)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA22)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23)},
+
+ // UART
+ {MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB17)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB16)},
+
+ // I2C
+ {MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA12)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA13)},
+
+ // SPI
+ {MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB22)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB23)},
+
+ // Special named pins
+ {MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA15)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_PB04)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_PB14)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER_ENABLE), MP_ROM_PTR(&pin_PA27)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_LATCH), MP_ROM_PTR(&pin_PB00)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_OUT), MP_ROM_PTR(&pin_PB30)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_CLOCK), MP_ROM_PTR(&pin_PB31)},
+
+ // ESP control
+ {MP_OBJ_NEW_QSTR(MP_QSTR_ESP_CS), MP_ROM_PTR(&pin_PA14)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_ESP_GPIO0), MP_ROM_PTR(&pin_PA31)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_ESP_BUSY), MP_ROM_PTR(&pin_PA00)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RESET), MP_ROM_PTR(&pin_PB12)},
+
+ // TFT control pins
+ {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_LITE), MP_ROM_PTR(&pin_PA01)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_PB15)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_SCK), MP_ROM_PTR(&pin_PB13)},
+ {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RST), MP_ROM_PTR(&pin_PB07)},
+ {MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_PB06)},
+ {MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_PB05)},
+
+ {MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj)},
+ {MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj)},
+ {MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj)},
+
+ {MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/pygamer/board.c b/ports/atmel-samd/boards/pygamer/board.c
index c8a7b9c23..5ccf3fc50 100644
--- a/ports/atmel-samd/boards/pygamer/board.c
+++ b/ports/atmel-samd/boards/pygamer/board.c
@@ -73,7 +73,6 @@ void board_init(void) {
busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus;
common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL);
common_hal_busio_spi_never_reset(spi);
- common_hal_busio_spi_configure(spi, 24000000, 0, 0, 8);
displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
bus->base.type = &displayio_fourwire_type;
@@ -81,7 +80,8 @@ void board_init(void) {
spi,
&pin_PB05, // TFT_DC Command or data
&pin_PB12, // TFT_CS Chip select
- &pin_PA00); // TFT_RST Reset
+ &pin_PA00, // TFT_RST Reset
+ 60000000);
displayio_display_obj_t* display = &displays[0].display;
display->base.type = &displayio_display_type;
@@ -93,6 +93,10 @@ void board_init(void) {
0, // row start
270, // rotation
16, // Color depth
+ false, // Grayscale
+ false, // pixels in a byte share a row. Only valid for depths < 8
+ 1, // bytes per cell. Only valid for depths < 8
+ false, // reverse_pixels_in_byte. Only valid for depths < 8
MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command
MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command
MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command
@@ -100,6 +104,7 @@ void board_init(void) {
display_init_sequence,
sizeof(display_init_sequence),
&pin_PA01, // backlight pin
+ NO_BRIGHTNESS_COMMAND,
1.0f, // brightness (ignored)
true, // auto_brightness
false, // single_byte_bounds
diff --git a/ports/atmel-samd/boards/pygamer/mpconfigboard.mk b/ports/atmel-samd/boards/pygamer/mpconfigboard.mk
index 8523e31be..69fb14358 100644
--- a/ports/atmel-samd/boards/pygamer/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pygamer/mpconfigboard.mk
@@ -1,25 +1,23 @@
LD_FILE = boards/samd51x19-bootloader-external-flash.ld
USB_VID = 0x239A
-USB_PID = 0x802E
+USB_PID = 0x803E
USB_PRODUCT = "PyGamer"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD51J19A
+CHIP_FAMILY = samd51
+
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = GD25Q64C
LONGINT_IMPL = MPZ
-# No touch on SAMD51 yet
-CIRCUITPY_TOUCHIO = 0
-
+CIRCUITPY_AUDIOIO = 1
+CIRCUITPY_DISPLAYIO = 1
+CIRCUITPY_GAMEPAD = 1
CIRCUITPY_GAMEPADSHIFT = 1
-
-CHIP_VARIANT = SAMD51J19A
-CHIP_FAMILY = samd51
-
CIRCUITPY_STAGE = 1
-CIRCUITPY_GAMEPAD = 1
-CIRCUITPY_DISPLAYIO = 1
-CIRCUITPY_AUDIOIO = 1
+# No touch on SAMD51 yet
+CIRCUITPY_TOUCHIO = 0
-FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pybadge
+FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pygamer
diff --git a/ports/atmel-samd/boards/pygamer/pins.c b/ports/atmel-samd/boards/pygamer/pins.c
index aa0c3e39b..7e6eff43f 100644
--- a/ports/atmel-samd/boards/pygamer/pins.c
+++ b/ports/atmel-samd/boards/pygamer/pins.c
@@ -43,6 +43,9 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB22) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB23) },
+ // SDCS, dup of D4
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PA14) },
+
// Special named pins
{ MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA15) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_PB04) },
@@ -60,8 +63,8 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RST), MP_ROM_PTR(&pin_PA00) },
{ MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_PB12) },
{ MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_PB05) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_JOYSTICK_X), MP_ROM_PTR(&pin_PB06) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_JOYSTICK_Y), MP_ROM_PTR(&pin_PB07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_JOYSTICK_X), MP_ROM_PTR(&pin_PB07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_JOYSTICK_Y), MP_ROM_PTR(&pin_PB06) },
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
diff --git a/ports/atmel-samd/boards/pygamer_advance/board.c b/ports/atmel-samd/boards/pygamer_advance/board.c
new file mode 100644
index 000000000..72d4dda8d
--- /dev/null
+++ b/ports/atmel-samd/boards/pygamer_advance/board.c
@@ -0,0 +1,97 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+#include "mpconfigboard.h"
+#include "hal/include/hal_gpio.h"
+#include "shared-bindings/busio/SPI.h"
+#include "shared-bindings/displayio/FourWire.h"
+#include "shared-module/displayio/__init__.h"
+#include "shared-module/displayio/mipi_constants.h"
+#include "tick.h"
+
+displayio_fourwire_obj_t board_display_obj;
+
+#define DELAY 0x80
+
+uint8_t display_init_sequence[] = {
+ 0x01, 0 | DELAY, 150, // SWRESET
+ 0x11, 0 | DELAY, 255, // SLPOUT
+ 0x36, 1, 0x00, // _MADCTL bottom to top refresh in vsync aligned order.
+ 0x3a, 1, 0x55, // COLMOD - 16bit color
+ 0x21, 0 | DELAY, 10, // _INVON
+ 0x13, 0 | DELAY, 10, // _NORON
+ 0x29, 0 | DELAY, 255, // _DISPON
+};
+
+void board_init(void) {
+ busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus;
+ common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB12, NULL);
+ common_hal_busio_spi_never_reset(spi);
+
+ displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
+ bus->base.type = &displayio_fourwire_type;
+ common_hal_displayio_fourwire_construct(bus,
+ spi,
+ &pin_PA00, // TFT_DC Command or data
+ &pin_PB15, // TFT_CS Chip select
+ &pin_PB05, // TFT_RST Reset
+ 60000000);
+
+ displayio_display_obj_t* display = &displays[0].display;
+ display->base.type = &displayio_display_type;
+ common_hal_displayio_display_construct(display,
+ bus,
+ 320, // Width (after rotation)
+ 240, // Height (after rotation)
+ 0, // column start
+ 0, // row start
+ 90, // rotation
+ 16, // Color depth
+ false, // Grayscale
+ false, // pixels in a byte share a row. Only valid for depths < 8
+ 1, // bytes per cell. Only valid for depths < 8
+ false, // reverse_pixels_in_byte. Only valid for depths < 8
+ MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command
+ MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command
+ MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command
+ 0x37, // set vertical scroll command
+ display_init_sequence,
+ sizeof(display_init_sequence),
+ &pin_PA01, // backlight pin
+ NO_BRIGHTNESS_COMMAND,
+ 1.0f, // brightness (ignored)
+ true, // auto_brightness
+ false, // single_byte_bounds
+ false); // data_as_commands
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.h b/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.h
new file mode 100644
index 000000000..c05aa4f06
--- /dev/null
+++ b/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.h
@@ -0,0 +1,36 @@
+#define MICROPY_HW_BOARD_NAME "Adafruit PyGamer"
+#define MICROPY_HW_MCU_NAME "samd51j20"
+
+#define CIRCUITPY_MCU_FAMILY samd51
+
+#define MICROPY_HW_LED_STATUS (&pin_PA23)
+
+// These are pins not to reset.
+// QSPI Data pins
+#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11)
+// DotStar pins, QSPI CS, and QSPI SCK
+#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11)
+#define MICROPY_PORT_C (0)
+#define MICROPY_PORT_D (0)
+
+#define AUTORESET_DELAY_MS 500
+
+// If you change this, then make sure to update the linker scripts as well to
+// make sure you don't overwrite code
+#define CIRCUITPY_INTERNAL_NVM_SIZE 8192
+
+#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PA13)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA12)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PA17)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PB23)
+#define DEFAULT_SPI_BUS_MISO (&pin_PB22)
+
+#define DEFAULT_UART_BUS_RX (&pin_PB17)
+#define DEFAULT_UART_BUS_TX (&pin_PB16)
+
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
diff --git a/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.mk b/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.mk
new file mode 100644
index 000000000..1bb2c553d
--- /dev/null
+++ b/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.mk
@@ -0,0 +1,23 @@
+LD_FILE = boards/samd51x19-bootloader-external-flash.ld
+USB_VID = 0x239A
+USB_PID = 0x803E
+USB_PRODUCT = "PyGamer Advance"
+USB_MANUFACTURER = "Adafruit Industries LLC"
+
+CHIP_VARIANT = SAMD51J20A
+CHIP_FAMILY = samd51
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = GD25Q64C
+LONGINT_IMPL = MPZ
+
+CIRCUITPY_AUDIOIO = 1
+CIRCUITPY_DISPLAYIO = 1
+CIRCUITPY_GAMEPAD = 1
+CIRCUITPY_GAMEPADSHIFT = 1
+CIRCUITPY_STAGE = 1
+# No touch on SAMD51 yet
+CIRCUITPY_TOUCHIO = 0
+
+FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pybadge
diff --git a/ports/atmel-samd/boards/pygamer_advance/pins.c b/ports/atmel-samd/boards/pygamer_advance/pins.c
new file mode 100644
index 000000000..9c2284db1
--- /dev/null
+++ b/ports/atmel-samd/boards/pygamer_advance/pins.c
@@ -0,0 +1,75 @@
+#include "shared-bindings/board/__init__.h"
+
+#include "boards/board.h"
+#include "shared-module/displayio/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB09) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PB03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PB02) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB17) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB16) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA14) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA16) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA18) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB14) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA15) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA19) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA20) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA21) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA22) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23) },
+
+ // UART
+ { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB17) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB16) },
+
+ // I2C
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA13) },
+
+ // SPI
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB22) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB23) },
+
+ // SDCS, dup of D4
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PA14) },
+
+ // Special named pins
+ { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA15) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_PB04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_PB14) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER_ENABLE), MP_ROM_PTR(&pin_PA27) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_LATCH), MP_ROM_PTR(&pin_PB00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_OUT), MP_ROM_PTR(&pin_PB30) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_CLOCK), MP_ROM_PTR(&pin_PB31) },
+
+ // TFT control pins
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_LITE), MP_ROM_PTR(&pin_PA01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_PB12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_SCK), MP_ROM_PTR(&pin_PB13) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RST), MP_ROM_PTR(&pin_PB05) },
+ { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_PB15) },
+ { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_PA00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_JOYSTICK_X), MP_ROM_PTR(&pin_PB07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_JOYSTICK_Y), MP_ROM_PTR(&pin_PB06) },
+
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+
+ { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/pyportal/board.c b/ports/atmel-samd/boards/pyportal/board.c
index bb80c5b48..a5de1d145 100644
--- a/ports/atmel-samd/boards/pyportal/board.c
+++ b/ports/atmel-samd/boards/pyportal/board.c
@@ -83,13 +83,18 @@ void board_init(void) {
0, // row start
0, // rotation
16, // Color depth
+ false, // grayscale
+ false, // pixels_in_byte_share_row (unused for depths > 8)
+ 1, // bytes per cell. Only valid for depths < 8
+ false, // reverse_pixels_in_byte. Only valid for depths < 8
MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command
MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command
MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command
0x37, // Set vertical scroll command
display_init_sequence,
sizeof(display_init_sequence),
- &pin_PB31,
+ &pin_PB31, // Backlight pin
+ NO_BRIGHTNESS_COMMAND,
1.0f, // brightness (ignored)
true, // auto_brightness
false, // single_byte_bounds
diff --git a/ports/atmel-samd/boards/pyportal/mpconfigboard.mk b/ports/atmel-samd/boards/pyportal/mpconfigboard.mk
index 34a94ac2b..996b17b3b 100644
--- a/ports/atmel-samd/boards/pyportal/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pyportal/mpconfigboard.mk
@@ -1,17 +1,16 @@
LD_FILE = boards/samd51x20-bootloader-external-flash.ld
USB_VID = 0x239A
-USB_PID = 0x8032
+USB_PID = 0x8036
USB_PRODUCT = "PyPortal"
USB_MANUFACTURER = "Adafruit Industries LLC"
-QSPI_FLASH_FILESYSTEM = 1
+CHIP_VARIANT = SAMD51J20A
+CHIP_FAMILY = samd51
+QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C"
LONGINT_IMPL = MPZ
# No touch on SAMD51 yet
CIRCUITPY_TOUCHIO = 0
-
-CHIP_VARIANT = SAMD51J20A
-CHIP_FAMILY = samd51
diff --git a/ports/atmel-samd/boards/pyruler/board.c b/ports/atmel-samd/boards/pyruler/board.c
new file mode 100644
index 000000000..d7e856d61
--- /dev/null
+++ b/ports/atmel-samd/boards/pyruler/board.c
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/pyruler/mpconfigboard.h b/ports/atmel-samd/boards/pyruler/mpconfigboard.h
new file mode 100644
index 000000000..171873b47
--- /dev/null
+++ b/ports/atmel-samd/boards/pyruler/mpconfigboard.h
@@ -0,0 +1,63 @@
+#define MICROPY_HW_BOARD_NAME "Adafruit PyRuler"
+#define MICROPY_HW_MCU_NAME "samd21e18"
+
+#define MICROPY_HW_LED_STATUS (&pin_PA10)
+
+#define MICROPY_HW_APA102_MOSI (&pin_PA00)
+#define MICROPY_HW_APA102_SCK (&pin_PA01)
+
+#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01)
+#define MICROPY_PORT_B (0)
+#define MICROPY_PORT_C (0)
+
+#define CIRCUITPY_INTERNAL_NVM_SIZE 256
+
+#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define IGNORE_PIN_PA12 1
+#define IGNORE_PIN_PA13 1
+#define IGNORE_PIN_PA16 1
+#define IGNORE_PIN_PA17 1
+#define IGNORE_PIN_PA18 1
+#define IGNORE_PIN_PA19 1
+#define IGNORE_PIN_PA20 1
+#define IGNORE_PIN_PA21 1
+#define IGNORE_PIN_PA22 1
+#define IGNORE_PIN_PA23 1
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
+#define IGNORE_PIN_PA30 1
+#define IGNORE_PIN_PA31 1
+#define IGNORE_PIN_PB01 1
+#define IGNORE_PIN_PB02 1
+#define IGNORE_PIN_PB03 1
+#define IGNORE_PIN_PB04 1
+#define IGNORE_PIN_PB05 1
+#define IGNORE_PIN_PB06 1
+#define IGNORE_PIN_PB07 1
+#define IGNORE_PIN_PB08 1
+#define IGNORE_PIN_PB09 1
+#define IGNORE_PIN_PB10 1
+#define IGNORE_PIN_PB11 1
+#define IGNORE_PIN_PB12 1
+#define IGNORE_PIN_PB13 1
+#define IGNORE_PIN_PB14 1
+#define IGNORE_PIN_PB15 1
+#define IGNORE_PIN_PB16 1
+#define IGNORE_PIN_PB17 1
+#define IGNORE_PIN_PB22 1
+#define IGNORE_PIN_PB23 1
+#define IGNORE_PIN_PB30 1
+#define IGNORE_PIN_PB31 1
+#define IGNORE_PIN_PB00 1
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PA09)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA08)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PA07)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PA06)
+#define DEFAULT_SPI_BUS_MISO (&pin_PA09)
+
+#define DEFAULT_UART_BUS_RX (&pin_PA07)
+#define DEFAULT_UART_BUS_TX (&pin_PA06)
diff --git a/ports/atmel-samd/boards/pyruler/mpconfigboard.mk b/ports/atmel-samd/boards/pyruler/mpconfigboard.mk
new file mode 100644
index 000000000..9663944a3
--- /dev/null
+++ b/ports/atmel-samd/boards/pyruler/mpconfigboard.mk
@@ -0,0 +1,14 @@
+LD_FILE = boards/samd21x18-bootloader.ld
+USB_VID = 0x239A
+USB_PID = 0x804C
+USB_PRODUCT = "PyRuler"
+USB_MANUFACTURER = "Adafruit Industries LLC"
+
+CHIP_VARIANT = SAMD21E18A
+CHIP_FAMILY = samd21
+
+INTERNAL_FLASH_FILESYSTEM = 1
+LONGINT_IMPL = NONE
+CIRCUITPY_SMALL_BUILD = 1
+
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/pyruler/pins.c b/ports/atmel-samd/boards/pyruler/pins.c
new file mode 100644
index 000000000..315dbe630
--- /dev/null
+++ b/ports/atmel-samd/boards/pyruler/pins.c
@@ -0,0 +1,50 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) },
+
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
+
+ { MP_ROM_QSTR(MP_QSTR_CAP0), MP_ROM_PTR(&pin_PA11) },
+
+ { MP_ROM_QSTR(MP_QSTR_CAP1), MP_ROM_PTR(&pin_PA05) },
+
+ { MP_ROM_QSTR(MP_QSTR_CAP2), MP_ROM_PTR(&pin_PA04) },
+
+ { MP_ROM_QSTR(MP_QSTR_CAP3), MP_ROM_PTR(&pin_PA03) },
+
+ { MP_ROM_QSTR(MP_QSTR_LED4), MP_ROM_PTR(&pin_PA15) },
+
+ { MP_ROM_QSTR(MP_QSTR_LED5), MP_ROM_PTR(&pin_PA14) },
+
+ { MP_ROM_QSTR(MP_QSTR_LED6), MP_ROM_PTR(&pin_PA28) },
+
+ { MP_ROM_QSTR(MP_QSTR_LED7), MP_ROM_PTR(&pin_PA27) },
+
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA09) },
+
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA06) },
+
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA07) },
+
+ { MP_ROM_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA10) },
+
+ { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA00) },
+ { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA01) },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/robohatmm1/pins.c b/ports/atmel-samd/boards/robohatmm1/pins.c
deleted file mode 100644
index fc3db7a30..000000000
--- a/ports/atmel-samd/boards/robohatmm1/pins.c
+++ /dev/null
@@ -1,88 +0,0 @@
-#include "shared-bindings/board/__init__.h"
-
-STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
- // SERVO Pins
- { MP_ROM_QSTR(MP_QSTR_SERVO1), MP_ROM_PTR(&pin_PA16) },
- { MP_ROM_QSTR(MP_QSTR_SERVO2), MP_ROM_PTR(&pin_PA17) },
- { MP_ROM_QSTR(MP_QSTR_SERVO3), MP_ROM_PTR(&pin_PA18) },
- { MP_ROM_QSTR(MP_QSTR_SERVO4), MP_ROM_PTR(&pin_PA19) },
- { MP_ROM_QSTR(MP_QSTR_SERVO5), MP_ROM_PTR(&pin_PA11) },
- { MP_ROM_QSTR(MP_QSTR_SERVO6), MP_ROM_PTR(&pin_PA10) },
- { MP_ROM_QSTR(MP_QSTR_SERVO7), MP_ROM_PTR(&pin_PA09) },
- { MP_ROM_QSTR(MP_QSTR_SERVO8), MP_ROM_PTR(&pin_PA08) },
-
- // RC_CH Pins
- { MP_ROM_QSTR(MP_QSTR_RCH1), MP_ROM_PTR(&pin_PA07) },
- { MP_ROM_QSTR(MP_QSTR_RCH2), MP_ROM_PTR(&pin_PA06) },
- { MP_ROM_QSTR(MP_QSTR_RCH3), MP_ROM_PTR(&pin_PA05) },
- { MP_ROM_QSTR(MP_QSTR_RCH4), MP_ROM_PTR(&pin_PA04) },
-
- // Special Function
- { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA02) },
- { MP_ROM_QSTR(MP_QSTR_POWER_OFF), MP_ROM_PTR(&pin_PA03) },
- { MP_ROM_QSTR(MP_QSTR_POWER_ENABLE), MP_ROM_PTR(&pin_PA28) },
-
- { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA20) },
- { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA21) },
- { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) },
- { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) },
- { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB22) },
- { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB23) },
-
- // UART on SERCOM0
- { MP_ROM_QSTR(MP_QSTR_UART_TX), MP_ROM_PTR(&pin_PA04) },
- { MP_ROM_QSTR(MP_QSTR_UART_RX), MP_ROM_PTR(&pin_PA05) },
- { MP_ROM_QSTR(MP_QSTR_UART_CTS), MP_ROM_PTR(&pin_PA06) },
- { MP_ROM_QSTR(MP_QSTR_UART_RTS), MP_ROM_PTR(&pin_PA07) },
-
- // SPI Flash on SERCOM2
- { MP_ROM_QSTR(MP_QSTR_FLASH_SCK), MP_ROM_PTR(&pin_PA13) },
- { MP_ROM_QSTR(MP_QSTR_FLASH_MISO), MP_ROM_PTR(&pin_PA14) },
- { MP_ROM_QSTR(MP_QSTR_FLASH_MOSI), MP_ROM_PTR(&pin_PA12) },
- { MP_ROM_QSTR(MP_QSTR_FLASH_CS), MP_ROM_PTR(&pin_PA15) },
-
- // I2C on SERCOM3
- { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(&pin_PA00) },
- { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_PA01) },
-
- // SPI on SERCOM4
- { MP_ROM_QSTR(MP_QSTR_SPI_SCK), MP_ROM_PTR(&pin_PB11) },
- { MP_ROM_QSTR(MP_QSTR_SPI_MISO), MP_ROM_PTR(&pin_PB08) },
- { MP_ROM_QSTR(MP_QSTR_SPI_MOSI), MP_ROM_PTR(&pin_PB10) },
- { MP_ROM_QSTR(MP_QSTR_SPI_SS), MP_ROM_PTR(&pin_PB09) },
-
- // GPS on SERCOM5
- { MP_ROM_QSTR(MP_QSTR_GPS_TX), MP_ROM_PTR(&pin_PB02) },
- { MP_ROM_QSTR(MP_QSTR_GPS_RX), MP_ROM_PTR(&pin_PB03) },
- { MP_ROM_QSTR(MP_QSTR_GPS_SDA), MP_ROM_PTR(&pin_PA00) },
- { MP_ROM_QSTR(MP_QSTR_GPS_SCL), MP_ROM_PTR(&pin_PA01) },
-
- // Raspberry Pi
- { MP_ROM_QSTR(MP_QSTR_PI_GP25), MP_ROM_PTR(&pin_PA30) },
- { MP_ROM_QSTR(MP_QSTR_PI_GP24), MP_ROM_PTR(&pin_PA31) },
- { MP_ROM_QSTR(MP_QSTR_PI_GP5), MP_ROM_PTR(&pin_PA27) },
- { MP_ROM_QSTR(MP_QSTR_PI_RX), MP_ROM_PTR(&pin_PB22) },
- { MP_ROM_QSTR(MP_QSTR_PI_TX), MP_ROM_PTR(&pin_PB23) },
-
- // SIGNAL / Digital pins (for reference)
- { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB23) },
- { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB22) },
- { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB02) },
- { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB03) },
- { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA00) },
- { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA01) },
- { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA28) },
- { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA03) },
- { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA20) },
- { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB11) },
- { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PB09) },
- { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PB10) },
- { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PB08) },
- { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA21) },
- { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PA03) },
-
- { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
- { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
- { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
-};
-MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/robohatmm1_m0/board.c b/ports/atmel-samd/boards/robohatmm1_m0/board.c
new file mode 100644
index 000000000..c8e20206a
--- /dev/null
+++ b/ports/atmel-samd/boards/robohatmm1_m0/board.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+
+void board_init(void)
+{
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/robohatmm1/mpconfigboard.h b/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.h
index dd31e912a..dc122b6fa 100644
--- a/ports/atmel-samd/boards/robohatmm1/mpconfigboard.h
+++ b/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.h
@@ -1,7 +1,7 @@
#define MICROPY_HW_BOARD_NAME "Robo HAT MM1"
#define MICROPY_HW_MCU_NAME "samd21g18"
-#define MICROPY_HW_LED_STATUS (&pin_PA21)
+#define MICROPY_HW_LED_STATUS (&pin_PB22)
// Salae reads 12mhz which is the limit even though we set it to the safer 8mhz.
#define SPI_FLASH_BAUDRATE (8000000)
@@ -24,23 +24,19 @@
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-//#define BOARD_HAS_CRYSTAL 0
#define CALIBRATE_CRYSTALLESS 1
#define DEFAULT_I2C_BUS_SCL (&pin_PA23)
#define DEFAULT_I2C_BUS_SDA (&pin_PA22)
-#define DEFAULT_SPI_BUS_SCK (&pin_PB11)
-#define DEFAULT_SPI_BUS_MOSI (&pin_PB10)
-#define DEFAULT_SPI_BUS_MISO (&pin_PB08)
+#define DEFAULT_SPI_BUS_SCK (&pin_PB10)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PB08)
+#define DEFAULT_SPI_BUS_MISO (&pin_PB11)
-#define DEFAULT_UART_BUS_RX (&pin_PB23)
-#define DEFAULT_UART_BUS_TX (&pin_PB22)
+#define DEFAULT_UART_BUS_RX (&pin_PB03)
+#define DEFAULT_UART_BUS_TX (&pin_PB02)
// USB is always used internally so skip the pin objects for it.
#define IGNORE_PIN_PA24 1
#define IGNORE_PIN_PA25 1
-//#define CIRCUITPY_I2CSLAVE
-//#define CIRCUITPY_DISPLAYIO (0)
-
diff --git a/ports/atmel-samd/boards/robohatmm1/mpconfigboard.mk b/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.mk
index da7da2761..e4f688f1e 100644
--- a/ports/atmel-samd/boards/robohatmm1/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.mk
@@ -4,31 +4,26 @@ USB_PID = 0x4D43
USB_PRODUCT = "Robo HAT MM1"
USB_MANUFACTURER = "Robotics Masters"
-# Non-Flash Edition
-#INTERNAL_FLASH_FILESYSTEM = 1
-#LONGINT_IMPL = NONE
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
-# SPI-Flash Edition
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ"
LONGINT_IMPL = MPZ
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
+# Non-Flash Edition
+#INTERNAL_FLASH_FILESYSTEM = 1
+#LONGINT_IMPL = NONE
-# Make room for frozen Libraries
CIRCUITPY_DISPLAYIO = 0
CIRCUITPY_FREQUENCYIO = 0
+CFLAGS_INLINE_LIMIT = 60
+SUPEROPT_GC = 0
+
# Include these Python libraries in firmware.
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
+FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
#FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_INA219
#FROZEN_MPY_DIRS += $(TOP)/frozen/RoboticsMasters_CircuitPython_MPU9250
-FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
-#FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Crickit
-#FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Motor
-#FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_seesaw
-
-#Adding per @danh to reduce memory usage and get the latest changes in
-CFLAGS_INLINE_LIMIT = 55
diff --git a/ports/atmel-samd/boards/robohatmm1_m0/pins.c b/ports/atmel-samd/boards/robohatmm1_m0/pins.c
new file mode 100644
index 000000000..f50e8d15a
--- /dev/null
+++ b/ports/atmel-samd/boards/robohatmm1_m0/pins.c
@@ -0,0 +1,88 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ // SERVO Pins
+ { MP_ROM_QSTR(MP_QSTR_SERVO1), MP_ROM_PTR(&pin_PA18) },
+ { MP_ROM_QSTR(MP_QSTR_SERVO2), MP_ROM_PTR(&pin_PA19) },
+ { MP_ROM_QSTR(MP_QSTR_SERVO3), MP_ROM_PTR(&pin_PA20) },
+ { MP_ROM_QSTR(MP_QSTR_SERVO4), MP_ROM_PTR(&pin_PA21) },
+ { MP_ROM_QSTR(MP_QSTR_SERVO5), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_SERVO6), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_SERVO7), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_SERVO8), MP_ROM_PTR(&pin_PA08) },
+
+ // RCC Pins
+ { MP_ROM_QSTR(MP_QSTR_RCC1), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_RCC2), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_RCC3), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_RCC4), MP_ROM_PTR(&pin_PA04) },
+
+ // Special Function
+ { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_POWER_OFF), MP_ROM_PTR(&pin_PA03) },
+ { MP_ROM_QSTR(MP_QSTR_POWER_DISABLE), MP_ROM_PTR(&pin_PA03) },
+ { MP_ROM_QSTR(MP_QSTR_POWER_ON), MP_ROM_PTR(&pin_PA27) },
+ { MP_ROM_QSTR(MP_QSTR_POWER_ENABLE), MP_ROM_PTR(&pin_PA27) },
+ { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_PA27) },
+
+ { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB23) },
+ { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB22) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB02) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB03) },
+
+ // GROVE on SERCOM0
+ { MP_ROM_QSTR(MP_QSTR_GROVE_SCL), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_GROVE_SDA), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_GROVE_RX), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_GROVE_TX), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_GROVE_D1), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_GROVE_D0), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_GROVE_A1), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_GROVE_A0), MP_ROM_PTR(&pin_PA08) },
+
+ // UART on SERCOM0
+ { MP_ROM_QSTR(MP_QSTR_UART_TX), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_UART_RX), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_UART_CTS), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_UART_RTS), MP_ROM_PTR(&pin_PA07) },
+
+ // SPI Flash on SERCOM2
+ { MP_ROM_QSTR(MP_QSTR_FLASH_SCK), MP_ROM_PTR(&pin_PA13) },
+ { MP_ROM_QSTR(MP_QSTR_FLASH_MISO), MP_ROM_PTR(&pin_PA14) },
+ { MP_ROM_QSTR(MP_QSTR_FLASH_MOSI), MP_ROM_PTR(&pin_PA12) },
+ { MP_ROM_QSTR(MP_QSTR_FLASH_CS), MP_ROM_PTR(&pin_PA15) },
+
+ // I2C on SERCOM3
+ { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_PA00) },
+ { MP_ROM_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_PA01) },
+
+ // SPI on SERCOM4
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB11) },
+
+ // GPS on SERCOM5
+ { MP_ROM_QSTR(MP_QSTR_GPS_TX), MP_ROM_PTR(&pin_PB02) },
+ { MP_ROM_QSTR(MP_QSTR_GPS_RX), MP_ROM_PTR(&pin_PB03) },
+ { MP_ROM_QSTR(MP_QSTR_GPS_SDA), MP_ROM_PTR(&pin_PA00) },
+ { MP_ROM_QSTR(MP_QSTR_GPS_SCL), MP_ROM_PTR(&pin_PA01) },
+
+ // Raspberry Pi
+ { MP_ROM_QSTR(MP_QSTR_PI_GP25), MP_ROM_PTR(&pin_PA30) },
+ { MP_ROM_QSTR(MP_QSTR_SWCLK), MP_ROM_PTR(&pin_PA30) },
+ { MP_ROM_QSTR(MP_QSTR_PI_GP24), MP_ROM_PTR(&pin_PA31) },
+ { MP_ROM_QSTR(MP_QSTR_SWDIO), MP_ROM_PTR(&pin_PA31) },
+ { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_PA16) },
+ { MP_ROM_QSTR(MP_QSTR_PI_TX), MP_ROM_PTR(&pin_PA16) },
+ { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_PA17) },
+ { MP_ROM_QSTR(MP_QSTR_PI_RX), MP_ROM_PTR(&pin_PA17) },
+
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/robohatmm1_m4/board.c b/ports/atmel-samd/boards/robohatmm1_m4/board.c
new file mode 100644
index 000000000..0f60736a2
--- /dev/null
+++ b/ports/atmel-samd/boards/robohatmm1_m4/board.c
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+#include "mpconfigboard.h"
+#include "hal/include/hal_gpio.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.h b/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.h
new file mode 100644
index 000000000..ac3a3a0dd
--- /dev/null
+++ b/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.h
@@ -0,0 +1,44 @@
+#define MICROPY_HW_BOARD_NAME "Robo HAT MM1"
+#define MICROPY_HW_MCU_NAME "samd51g19"
+
+#define CIRCUITPY_MCU_FAMILY samd51
+
+#define MICROPY_HW_LED_STATUS (&pin_PB22)
+
+// Salae reads 12mhz which is the limit even though we set it to the safer 8mhz.
+#define SPI_FLASH_BAUDRATE (8000000)
+
+// On-board flash
+#define SPI_FLASH_MOSI_PIN &pin_PA12
+#define SPI_FLASH_MISO_PIN &pin_PA14
+#define SPI_FLASH_SCK_PIN &pin_PA13
+#define SPI_FLASH_CS_PIN &pin_PA15
+
+// These are pins not to reset.
+// SPI Data pins
+#define MICROPY_PORT_A (0)
+#define MICROPY_PORT_B (0)
+#define MICROPY_PORT_C (0)
+#define MICROPY_PORT_D (0)
+
+#define AUTORESET_DELAY_MS 500
+
+// If you change this, then make sure to update the linker scripts as well to
+// make sure you don't overwrite code
+#define CIRCUITPY_INTERNAL_NVM_SIZE 8192
+
+#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PA23)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA22)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PB10)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PB08)
+#define DEFAULT_SPI_BUS_MISO (&pin_PB11)
+
+#define DEFAULT_UART_BUS_RX (&pin_PB03)
+#define DEFAULT_UART_BUS_TX (&pin_PB02)
+
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
diff --git a/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk b/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk
new file mode 100644
index 000000000..afd15ad0a
--- /dev/null
+++ b/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk
@@ -0,0 +1,31 @@
+LD_FILE = boards/samd51x19-bootloader-external-flash.ld
+USB_VID = 0x1209
+USB_PID = 0x4D43
+USB_PRODUCT = "Robo HAT MM1"
+USB_MANUFACTURER = "Robotics Masters"
+
+CHIP_VARIANT = SAMD51G19A
+CHIP_FAMILY = samd51
+
+#QSPI_FLASH_FILESYSTEM = 0
+
+SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ"
+LONGINT_IMPL = MPZ
+
+CIRCUITPY_PS2IO = 1
+# No I2S on SAMD51G
+CIRCUITPY_AUDIOBUSIO = 0
+# No touch on SAMD51 yet
+CIRCUITPY_TOUCHIO = 0
+# Make room for more stuff
+CIRCUITPY_DISPLAYIO = 0
+CIRCUITPY_FREQUENCYIO = 0
+
+# Include these Python libraries in firmware.
+FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
+FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
+#FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_INA219
+#FROZEN_MPY_DIRS += $(TOP)/frozen/RoboticsMasters_CircuitPython_MPU9250
+
diff --git a/ports/atmel-samd/boards/robohatmm1_m4/pins.c b/ports/atmel-samd/boards/robohatmm1_m4/pins.c
new file mode 100644
index 000000000..e1204e343
--- /dev/null
+++ b/ports/atmel-samd/boards/robohatmm1_m4/pins.c
@@ -0,0 +1,89 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ // SERVO Pins
+ { MP_ROM_QSTR(MP_QSTR_SERVO1), MP_ROM_PTR(&pin_PA18) },
+ { MP_ROM_QSTR(MP_QSTR_SERVO2), MP_ROM_PTR(&pin_PA19) },
+ { MP_ROM_QSTR(MP_QSTR_SERVO3), MP_ROM_PTR(&pin_PA20) },
+ { MP_ROM_QSTR(MP_QSTR_SERVO4), MP_ROM_PTR(&pin_PA21) },
+ { MP_ROM_QSTR(MP_QSTR_SERVO5), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_SERVO6), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_SERVO7), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_SERVO8), MP_ROM_PTR(&pin_PA08) },
+
+ // RCC Pins
+ { MP_ROM_QSTR(MP_QSTR_RCC1), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_RCC2), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_RCC3), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_RCC4), MP_ROM_PTR(&pin_PA04) },
+
+ // Special Function
+ { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_POWER_OFF), MP_ROM_PTR(&pin_PA03) },
+ { MP_ROM_QSTR(MP_QSTR_POWER_DISABLE), MP_ROM_PTR(&pin_PA03) },
+ { MP_ROM_QSTR(MP_QSTR_POWER_ON), MP_ROM_PTR(&pin_PA27) },
+ { MP_ROM_QSTR(MP_QSTR_POWER_ENABLE), MP_ROM_PTR(&pin_PA27) },
+ { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_PA27) },
+
+ { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB23) },
+ { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB22) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB02) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB03) },
+
+ // GROVE on SERCOM0
+ { MP_ROM_QSTR(MP_QSTR_GROVE_SCL), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_GROVE_SDA), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_GROVE_RX), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_GROVE_TX), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_GROVE_D1), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_GROVE_D0), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_GROVE_A1), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_GROVE_A0), MP_ROM_PTR(&pin_PA08) },
+
+ // UART on SERCOM0
+ { MP_ROM_QSTR(MP_QSTR_UART_TX), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_UART_RX), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_UART_CTS), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_UART_RTS), MP_ROM_PTR(&pin_PA07) },
+
+ // SPI Flash on SERCOM2
+ { MP_ROM_QSTR(MP_QSTR_FLASH_SCK), MP_ROM_PTR(&pin_PA13) },
+ { MP_ROM_QSTR(MP_QSTR_FLASH_MISO), MP_ROM_PTR(&pin_PA14) },
+ { MP_ROM_QSTR(MP_QSTR_FLASH_MOSI), MP_ROM_PTR(&pin_PA12) },
+ { MP_ROM_QSTR(MP_QSTR_FLASH_CS), MP_ROM_PTR(&pin_PA15) },
+
+ // I2C on SERCOM3
+ { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_PA00) },
+ { MP_ROM_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_PA01) },
+
+ // SPI on SERCOM4
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB11) },
+
+ // GPS on SERCOM5
+ { MP_ROM_QSTR(MP_QSTR_GPS_TX), MP_ROM_PTR(&pin_PB02) },
+ { MP_ROM_QSTR(MP_QSTR_GPS_RX), MP_ROM_PTR(&pin_PB03) },
+ { MP_ROM_QSTR(MP_QSTR_GPS_SDA), MP_ROM_PTR(&pin_PA00) },
+ { MP_ROM_QSTR(MP_QSTR_GPS_SCL), MP_ROM_PTR(&pin_PA01) },
+
+ // Raspberry Pi
+ { MP_ROM_QSTR(MP_QSTR_PI_GP25), MP_ROM_PTR(&pin_PA30) },
+ { MP_ROM_QSTR(MP_QSTR_SWCLK), MP_ROM_PTR(&pin_PA30) },
+ { MP_ROM_QSTR(MP_QSTR_PI_GP24), MP_ROM_PTR(&pin_PA31) },
+ { MP_ROM_QSTR(MP_QSTR_SWDIO), MP_ROM_PTR(&pin_PA31) },
+ { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_PA16) },
+ { MP_ROM_QSTR(MP_QSTR_PI_TX), MP_ROM_PTR(&pin_PA16) },
+ { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_PA17) },
+ { MP_ROM_QSTR(MP_QSTR_PI_RX), MP_ROM_PTR(&pin_PA17) },
+
+
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/sam32/mpconfigboard.mk b/ports/atmel-samd/boards/sam32/mpconfigboard.mk
index d76696b39..ca1e11f01 100644
--- a/ports/atmel-samd/boards/sam32/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/sam32/mpconfigboard.mk
@@ -4,11 +4,11 @@ USB_PID = 0xEDBE
USB_PRODUCT = "SAM32"
USB_MANUFACTURER = "maholli"
+CHIP_VARIANT = SAMD51J20A
+CHIP_FAMILY = samd51
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = MPZ
# No touch on SAMD51 yet
CIRCUITPY_TOUCHIO = 0
-
-CHIP_VARIANT = SAMD51J20A
-CHIP_FAMILY = samd51
diff --git a/ports/atmel-samd/boards/snekboard/board.c b/ports/atmel-samd/boards/snekboard/board.c
new file mode 100644
index 000000000..c8e20206a
--- /dev/null
+++ b/ports/atmel-samd/boards/snekboard/board.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+
+void board_init(void)
+{
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/snekboard/mpconfigboard.h b/ports/atmel-samd/boards/snekboard/mpconfigboard.h
new file mode 100644
index 000000000..a349143d9
--- /dev/null
+++ b/ports/atmel-samd/boards/snekboard/mpconfigboard.h
@@ -0,0 +1,35 @@
+#define MICROPY_HW_BOARD_NAME "keithp.com snekboard"
+#define MICROPY_HW_MCU_NAME "samd21g18"
+
+#define MICROPY_HW_LED_STATUS (&pin_PA02)
+
+#define MICROPY_HW_NEOPIXEL (&pin_PB11)
+
+#define SPI_FLASH_MOSI_PIN &pin_PB22
+#define SPI_FLASH_MISO_PIN &pin_PB03
+#define SPI_FLASH_SCK_PIN &pin_PB23
+#define SPI_FLASH_CS_PIN &pin_PA27
+
+// These are pins not to reset.
+#define MICROPY_PORT_A (PORT_PB11)
+#define MICROPY_PORT_B ( 0 )
+#define MICROPY_PORT_C ( 0 )
+
+
+// If you change this, then make sure to update the linker scripts as well to
+// make sure you don't overwrite code.
+#define CIRCUITPY_INTERNAL_NVM_SIZE 256
+
+#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define BOARD_HAS_CRYSTAL 0
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PA08) /* ANALOG 5 */
+#define DEFAULT_I2C_BUS_SDA (&pin_PA09) /* ANALOG 6 */
+
+#define DEFAULT_UART_BUS_RX (&pin_PB08) /* ANALOG 1 */
+#define DEFAULT_UART_BUS_TX (&pin_PB09) /* ANALOG 2 */
+
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
diff --git a/ports/atmel-samd/boards/snekboard/mpconfigboard.mk b/ports/atmel-samd/boards/snekboard/mpconfigboard.mk
new file mode 100644
index 000000000..9892ade8f
--- /dev/null
+++ b/ports/atmel-samd/boards/snekboard/mpconfigboard.mk
@@ -0,0 +1,16 @@
+LD_FILE = boards/samd21x18-bootloader-external-flash.ld
+USB_VID = 0x239A
+USB_PID = 0x804E
+USB_PRODUCT = "snekboard"
+USB_MANUFACTURER = "keithp.com"
+
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
+SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "W25Q16JV_IQ"
+LONGINT_IMPL = MPZ
+
+CFLAGS_INLINE_LIMIT = 60
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/snekboard/pins.c b/ports/atmel-samd/boards/snekboard/pins.c
new file mode 100644
index 000000000..48bdc672e
--- /dev/null
+++ b/ports/atmel-samd/boards/snekboard/pins.c
@@ -0,0 +1,28 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_POWER1), MP_ROM_PTR(&pin_PA12) },
+ { MP_ROM_QSTR(MP_QSTR_DIR1), MP_ROM_PTR(&pin_PA16) },
+ { MP_ROM_QSTR(MP_QSTR_POWER2), MP_ROM_PTR(&pin_PA13) },
+ { MP_ROM_QSTR(MP_QSTR_DIR2), MP_ROM_PTR(&pin_PA17) },
+ { MP_ROM_QSTR(MP_QSTR_POWER3), MP_ROM_PTR(&pin_PA18) },
+ { MP_ROM_QSTR(MP_QSTR_DIR3), MP_ROM_PTR(&pin_PA20) },
+ { MP_ROM_QSTR(MP_QSTR_POWER4), MP_ROM_PTR(&pin_PA19) },
+ { MP_ROM_QSTR(MP_QSTR_DIR4), MP_ROM_PTR(&pin_PA21) },
+ { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB11) },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk
index 4da42c02d..9d0ef1c04 100755
--- a/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk
@@ -4,16 +4,15 @@ USB_PID = 0x0017
USB_PRODUCT = "LUMIDrive Board"
USB_MANUFACTURER = "SparkFun Electronics"
-SPI_FLASH_FILESYSTEM = 1
-LONGINT_IMPL = MPZ
-
CHIP_VARIANT = SAMD21G18A
CHIP_FAMILY = samd21
-CIRCUITPY_AUDIOIO = 0
-CIRCUITPY_AUDIOBUSIO = 0
-
+SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "W25Q32FV"
+LONGINT_IMPL = MPZ
+
+CIRCUITPY_AUDIOIO = 0
+CIRCUITPY_AUDIOBUSIO = 0
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar
diff --git a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk
index 9e45f8ad9..3be1a17d3 100755
--- a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk
@@ -4,16 +4,13 @@ USB_PID = 0x0015
USB_PRODUCT = "RedBoard Turbo Board"
USB_MANUFACTURER = "SparkFun Electronics"
-SPI_FLASH_FILESYSTEM = 1
-LONGINT_IMPL = MPZ
-
CHIP_VARIANT = SAMD21G18A
CHIP_FAMILY = samd21
+SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "W25Q32FV"
+LONGINT_IMPL = MPZ
-# Tweak inlining depending on language.
-ifeq ($(TRANSLATION), zh_Latn_pinyin)
-CFLAGS_INLINE_LIMIT = 50
-endif
+CFLAGS_INLINE_LIMIT = 60
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk
index c0238ce80..c9d0baf11 100644
--- a/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk
@@ -4,9 +4,11 @@ USB_PID = 0x8D23
USB_PRODUCT = "SparkFun SAMD21 Dev Breakout"
USB_MANUFACTURER = "SparkFun"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk
index 462e3e2ca..a6e216575 100644
--- a/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk
@@ -4,9 +4,11 @@ USB_PID = 0x8D22
USB_PRODUCT = "SparkFun SAMD21 Mini Breakout"
USB_MANUFACTURER = "SparkFun"
+CHIP_VARIANT = SAMD21G18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk
index 93b07bc76..6d108e649 100644
--- a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk
@@ -4,15 +4,16 @@ USB_PID = 0x8030
USB_PRODUCT = "Trellis M4 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD51G19A
+CHIP_FAMILY = samd51
+
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C"
LONGINT_IMPL = MPZ
+CIRCUITPY_PS2IO = 1
# No I2S on SAMD51G
CIRCUITPY_AUDIOBUSIO = 0
# No touch on SAMD51 yet
CIRCUITPY_TOUCHIO = 0
-
-CHIP_VARIANT = SAMD51G19A
-CHIP_FAMILY = samd51
diff --git a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk
index 1c6f6db05..b4a00b654 100644
--- a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk
@@ -4,9 +4,11 @@ USB_PID = 0x801F
USB_PRODUCT = "Trinket M0"
USB_MANUFACTURER = "Adafruit Industries LLC"
+CHIP_VARIANT = SAMD21E18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
-CHIP_VARIANT = SAMD21E18A
-CHIP_FAMILY = samd21
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk
index c9c196da7..76c33a333 100644
--- a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk
@@ -4,10 +4,12 @@ USB_PID = 0x801F
USB_PRODUCT="Trinket M0 Haxpress"
USB_MANUFACTURER="Radomir Dopieralski"
+CHIP_VARIANT = SAMD21E18A
+CHIP_FAMILY = samd21
+
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = W25Q32BV
LONGINT_IMPL = MPZ
-CHIP_VARIANT = SAMD21E18A
-CHIP_FAMILY = samd21
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/uchip/mpconfigboard.mk b/ports/atmel-samd/boards/uchip/mpconfigboard.mk
index b6710af6d..109492b76 100644
--- a/ports/atmel-samd/boards/uchip/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/uchip/mpconfigboard.mk
@@ -4,9 +4,9 @@ USB_PID = 0xED5F
USB_PRODUCT = "uChip CircuitPython"
USB_MANUFACTURER = "Itaca Innovation"
+CHIP_VARIANT = SAMD21E18A
+CHIP_FAMILY = samd21
+
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
-
-CHIP_VARIANT = SAMD21E18A
-CHIP_FAMILY = samd21
diff --git a/ports/atmel-samd/boards/ugame10/board.c b/ports/atmel-samd/boards/ugame10/board.c
index 38f63570a..72b0ed577 100644
--- a/ports/atmel-samd/boards/ugame10/board.c
+++ b/ports/atmel-samd/boards/ugame10/board.c
@@ -74,12 +74,12 @@ void board_init(void) {
displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
bus->base.type = &displayio_fourwire_type;
busio_spi_obj_t *spi = common_hal_board_create_spi();
- common_hal_busio_spi_configure(spi, 24000000, 0, 0, 8);
common_hal_displayio_fourwire_construct(bus,
spi,
&pin_PA09, // Command or data
&pin_PA08, // Chip select
- NULL); // Reset
+ NULL, // Reset
+ 24000000);
displayio_display_obj_t* display = &displays[0].display;
display->base.type = &displayio_display_type;
@@ -91,6 +91,10 @@ void board_init(void) {
2, // row start
0, // rotation
16, // Color depth
+ false, // grayscale
+ false, // pixels in byte share row. Only used with depth < 8
+ 1, // bytes per cell. Only valid for depths < 8
+ false, // reverse_pixels_in_byte. Only valid for depths < 8
MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command
MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command
MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command
@@ -98,6 +102,7 @@ void board_init(void) {
display_init_sequence,
sizeof(display_init_sequence),
NULL,
+ NO_BRIGHTNESS_COMMAND,
1.0f, // brightness
false, // auto_brightness
false, // single_byte_bounds
diff --git a/ports/atmel-samd/boards/ugame10/brutalist-6.bdf b/ports/atmel-samd/boards/ugame10/brutalist-6.bdf
new file mode 100644
index 000000000..f9e21e76a
--- /dev/null
+++ b/ports/atmel-samd/boards/ugame10/brutalist-6.bdf
@@ -0,0 +1,1147 @@
+STARTFONT 2.1
+FONT -FontForge-Brutalist-Regular-R-Normal--6-60-75-75-P-40-ISO8859-1
+SIZE 6 100 100
+FONTBOUNDINGBOX 4 6 0 0
+COMMENT "Generated by fontforge, http://fontforge.sourceforge.net"
+STARTPROPERTIES 17
+FAMILY_NAME "brutalist"
+WEIGHT_NAME "Regular"
+SLANT "R"
+SETWIDTH_NAME "Normal"
+PIXEL_SIZE 6
+POINT_SIZE 60
+RESOLUTION_X 100
+RESOLUTION_Y 100
+SPACING "C"
+AVERAGE_WIDTH 40
+CHARSET_REGISTRY "ISO8859"
+CHARSET_ENCODING "1"
+FONTNAME_REGISTRY ""
+FONT_ASCENT 4
+FONT_DESCENT 2
+MIN_SPACE 6
+FIGURE_WIDTH 4
+ENDPROPERTIES
+CHARS 96
+STARTCHAR space
+ENCODING 32
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 1 1 3 -2
+BITMAP
+00
+ENDCHAR
+STARTCHAR exclam
+ENCODING 33
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 1 6 0 -2
+BITMAP
+80
+80
+80
+80
+00
+80
+ENDCHAR
+STARTCHAR quotedbl
+ENCODING 34
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 2 0 2
+BITMAP
+A0
+A0
+ENDCHAR
+STARTCHAR numbersign
+ENCODING 35
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+A0
+E0
+A0
+A0
+E0
+A0
+ENDCHAR
+STARTCHAR dollar
+ENCODING 36
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+40
+E0
+C0
+60
+E0
+40
+ENDCHAR
+STARTCHAR percent
+ENCODING 37
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+A0
+20
+40
+40
+80
+A0
+ENDCHAR
+STARTCHAR ampersand
+ENCODING 38
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+40
+A0
+40
+A0
+A0
+60
+ENDCHAR
+STARTCHAR quotesingle
+ENCODING 39
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 1 2 0 2
+BITMAP
+80
+80
+ENDCHAR
+STARTCHAR parenleft
+ENCODING 40
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+60
+80
+80
+80
+80
+60
+ENDCHAR
+STARTCHAR parenright
+ENCODING 41
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+C0
+20
+20
+20
+20
+C0
+ENDCHAR
+STARTCHAR asterisk
+ENCODING 42
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 3 0 0
+BITMAP
+A0
+40
+A0
+ENDCHAR
+STARTCHAR plus
+ENCODING 43
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 3 0 0
+BITMAP
+40
+E0
+40
+ENDCHAR
+STARTCHAR comma
+ENCODING 44
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 2 3 0 -2
+BITMAP
+40
+40
+80
+ENDCHAR
+STARTCHAR hyphen
+ENCODING 45
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 1 0 1
+BITMAP
+E0
+ENDCHAR
+STARTCHAR period
+ENCODING 46
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 1 1 0 -1
+BITMAP
+80
+ENDCHAR
+STARTCHAR slash
+ENCODING 47
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+20
+20
+40
+40
+80
+80
+ENDCHAR
+STARTCHAR zero
+ENCODING 48
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+60
+A0
+A0
+A0
+C0
+ENDCHAR
+STARTCHAR one
+ENCODING 49
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 2 5 0 -1
+BITMAP
+40
+C0
+40
+40
+40
+ENDCHAR
+STARTCHAR two
+ENCODING 50
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+20
+E0
+80
+E0
+ENDCHAR
+STARTCHAR three
+ENCODING 51
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+20
+E0
+20
+E0
+ENDCHAR
+STARTCHAR four
+ENCODING 52
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+A0
+A0
+E0
+20
+20
+ENDCHAR
+STARTCHAR five
+ENCODING 53
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+80
+E0
+20
+E0
+ENDCHAR
+STARTCHAR six
+ENCODING 54
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+80
+E0
+A0
+E0
+ENDCHAR
+STARTCHAR seven
+ENCODING 55
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+20
+20
+20
+20
+ENDCHAR
+STARTCHAR eight
+ENCODING 56
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+A0
+E0
+A0
+E0
+ENDCHAR
+STARTCHAR nine
+ENCODING 57
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+A0
+E0
+20
+E0
+ENDCHAR
+STARTCHAR colon
+ENCODING 58
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 1 3 1 0
+BITMAP
+80
+00
+80
+ENDCHAR
+STARTCHAR semicolon
+ENCODING 59
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 2 5 0 -2
+BITMAP
+40
+00
+40
+40
+80
+ENDCHAR
+STARTCHAR less
+ENCODING 60
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+20
+40
+80
+40
+20
+ENDCHAR
+STARTCHAR equal
+ENCODING 61
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 3 0 0
+BITMAP
+E0
+00
+E0
+ENDCHAR
+STARTCHAR greater
+ENCODING 62
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+80
+40
+20
+40
+80
+ENDCHAR
+STARTCHAR question
+ENCODING 63
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+E0
+20
+60
+40
+00
+40
+ENDCHAR
+STARTCHAR at
+ENCODING 64
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+E0
+A0
+E0
+E0
+80
+E0
+ENDCHAR
+STARTCHAR A
+ENCODING 65
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+A0
+A0
+E0
+A0
+ENDCHAR
+STARTCHAR B
+ENCODING 66
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+C0
+A0
+C0
+A0
+E0
+ENDCHAR
+STARTCHAR C
+ENCODING 67
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+A0
+80
+A0
+E0
+ENDCHAR
+STARTCHAR D
+ENCODING 68
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+C0
+A0
+A0
+A0
+C0
+ENDCHAR
+STARTCHAR E
+ENCODING 69
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+80
+E0
+80
+E0
+ENDCHAR
+STARTCHAR F
+ENCODING 70
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+80
+80
+E0
+80
+ENDCHAR
+STARTCHAR G
+ENCODING 71
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+E0
+80
+A0
+A0
+E0
+20
+ENDCHAR
+STARTCHAR H
+ENCODING 72
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+A0
+A0
+E0
+A0
+A0
+ENDCHAR
+STARTCHAR I
+ENCODING 73
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+40
+40
+40
+E0
+ENDCHAR
+STARTCHAR J
+ENCODING 74
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+20
+20
+20
+A0
+E0
+ENDCHAR
+STARTCHAR K
+ENCODING 75
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+A0
+C0
+E0
+A0
+A0
+ENDCHAR
+STARTCHAR L
+ENCODING 76
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+80
+80
+80
+80
+E0
+ENDCHAR
+STARTCHAR M
+ENCODING 77
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+A0
+E0
+A0
+A0
+A0
+ENDCHAR
+STARTCHAR N
+ENCODING 78
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+A0
+E0
+E0
+E0
+A0
+ENDCHAR
+STARTCHAR O
+ENCODING 79
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+A0
+A0
+A0
+E0
+ENDCHAR
+STARTCHAR P
+ENCODING 80
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+A0
+A0
+E0
+80
+ENDCHAR
+STARTCHAR Q
+ENCODING 81
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+E0
+A0
+A0
+A0
+E0
+20
+ENDCHAR
+STARTCHAR R
+ENCODING 82
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+A0
+A0
+C0
+A0
+ENDCHAR
+STARTCHAR S
+ENCODING 83
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+80
+E0
+20
+E0
+ENDCHAR
+STARTCHAR T
+ENCODING 84
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+40
+40
+40
+40
+ENDCHAR
+STARTCHAR U
+ENCODING 85
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+A0
+A0
+A0
+A0
+E0
+ENDCHAR
+STARTCHAR V
+ENCODING 86
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+A0
+A0
+A0
+E0
+40
+ENDCHAR
+STARTCHAR W
+ENCODING 87
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+A0
+A0
+A0
+E0
+A0
+ENDCHAR
+STARTCHAR X
+ENCODING 88
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+A0
+A0
+40
+A0
+A0
+ENDCHAR
+STARTCHAR Y
+ENCODING 89
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+A0
+A0
+E0
+40
+40
+ENDCHAR
+STARTCHAR Z
+ENCODING 90
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+E0
+20
+40
+80
+E0
+ENDCHAR
+STARTCHAR bracketleft
+ENCODING 91
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+E0
+80
+80
+80
+80
+E0
+ENDCHAR
+STARTCHAR backslash
+ENCODING 92
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+80
+80
+40
+40
+20
+20
+ENDCHAR
+STARTCHAR bracketright
+ENCODING 93
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+E0
+20
+20
+20
+20
+E0
+ENDCHAR
+STARTCHAR asciicircum
+ENCODING 94
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 3 0 1
+BITMAP
+40
+E0
+A0
+ENDCHAR
+STARTCHAR underscore
+ENCODING 95
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 1 0 -1
+BITMAP
+E0
+ENDCHAR
+STARTCHAR grave
+ENCODING 96
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 2 2 1 2
+BITMAP
+80
+40
+ENDCHAR
+STARTCHAR a
+ENCODING 97
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 4 0 -1
+BITMAP
+E0
+60
+A0
+E0
+ENDCHAR
+STARTCHAR b
+ENCODING 98
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+80
+E0
+A0
+A0
+E0
+ENDCHAR
+STARTCHAR c
+ENCODING 99
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 4 0 -1
+BITMAP
+E0
+A0
+80
+E0
+ENDCHAR
+STARTCHAR d
+ENCODING 100
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+20
+E0
+A0
+A0
+E0
+ENDCHAR
+STARTCHAR e
+ENCODING 101
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 4 0 -1
+BITMAP
+E0
+A0
+C0
+E0
+ENDCHAR
+STARTCHAR f
+ENCODING 102
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+60
+40
+E0
+40
+40
+40
+ENDCHAR
+STARTCHAR g
+ENCODING 103
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -2
+BITMAP
+E0
+A0
+E0
+20
+E0
+ENDCHAR
+STARTCHAR h
+ENCODING 104
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+80
+E0
+A0
+A0
+A0
+ENDCHAR
+STARTCHAR i
+ENCODING 105
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 2 5 1 -1
+BITMAP
+80
+00
+80
+80
+C0
+ENDCHAR
+STARTCHAR j
+ENCODING 106
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+20
+00
+60
+20
+A0
+E0
+ENDCHAR
+STARTCHAR k
+ENCODING 107
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+80
+A0
+C0
+A0
+A0
+ENDCHAR
+STARTCHAR l
+ENCODING 108
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+C0
+40
+40
+40
+60
+ENDCHAR
+STARTCHAR m
+ENCODING 109
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 4 0 -1
+BITMAP
+E0
+E0
+E0
+A0
+ENDCHAR
+STARTCHAR n
+ENCODING 110
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 4 0 -1
+BITMAP
+E0
+A0
+A0
+A0
+ENDCHAR
+STARTCHAR o
+ENCODING 111
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 4 0 -1
+BITMAP
+E0
+A0
+A0
+E0
+ENDCHAR
+STARTCHAR p
+ENCODING 112
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -2
+BITMAP
+E0
+A0
+A0
+E0
+80
+ENDCHAR
+STARTCHAR q
+ENCODING 113
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -2
+BITMAP
+E0
+A0
+A0
+E0
+20
+ENDCHAR
+STARTCHAR r
+ENCODING 114
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 4 0 -1
+BITMAP
+E0
+A0
+80
+80
+ENDCHAR
+STARTCHAR s
+ENCODING 115
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 4 0 -1
+BITMAP
+E0
+80
+60
+E0
+ENDCHAR
+STARTCHAR t
+ENCODING 116
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -1
+BITMAP
+40
+E0
+40
+40
+60
+ENDCHAR
+STARTCHAR u
+ENCODING 117
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 4 0 -1
+BITMAP
+A0
+A0
+A0
+E0
+ENDCHAR
+STARTCHAR v
+ENCODING 118
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 4 0 -1
+BITMAP
+A0
+A0
+E0
+40
+ENDCHAR
+STARTCHAR w
+ENCODING 119
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 4 0 -1
+BITMAP
+A0
+A0
+E0
+A0
+ENDCHAR
+STARTCHAR x
+ENCODING 120
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 4 0 -1
+BITMAP
+A0
+40
+A0
+A0
+ENDCHAR
+STARTCHAR y
+ENCODING 121
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 5 0 -2
+BITMAP
+A0
+A0
+E0
+20
+E0
+ENDCHAR
+STARTCHAR z
+ENCODING 122
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 4 0 -1
+BITMAP
+E0
+40
+80
+E0
+ENDCHAR
+STARTCHAR braceleft
+ENCODING 123
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+60
+40
+C0
+40
+40
+60
+ENDCHAR
+STARTCHAR bar
+ENCODING 124
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 1 6 1 -2
+BITMAP
+80
+80
+80
+80
+80
+80
+ENDCHAR
+STARTCHAR braceright
+ENCODING 125
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+C0
+40
+60
+40
+40
+C0
+ENDCHAR
+STARTCHAR asciitilde
+ENCODING 126
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 4 3 0 1
+BITMAP
+50
+F0
+A0
+ENDCHAR
+STARTCHAR uni007F
+ENCODING 127
+SWIDTH 666 0
+DWIDTH 5 0
+BBX 3 6 0 -2
+BITMAP
+E0
+A0
+A0
+A0
+A0
+E0
+ENDCHAR
+ENDFONT
diff --git a/ports/atmel-samd/boards/ugame10/brutalist.sfd b/ports/atmel-samd/boards/ugame10/brutalist.sfd
new file mode 100644
index 000000000..2a48515aa
--- /dev/null
+++ b/ports/atmel-samd/boards/ugame10/brutalist.sfd
@@ -0,0 +1,1034 @@
+SplineFontDB: 3.0
+FontName: brutalistRegular
+FullName: brutalist Regular
+FamilyName: brutalist
+Weight: Regular
+Copyright: Copyright (c) 2019, sheep,,,
+UComments: "2019-6-28: Created with FontForge (http://fontforge.org)"
+Version: 001.000
+ItalicAngle: 0
+UnderlinePosition: -100
+UnderlineWidth: 50
+Ascent: 666
+Descent: 334
+InvalidEm: 0
+LayerCount: 2
+Layer: 0 0 "Back" 1
+Layer: 1 0 "Fore" 0
+XUID: [1021 455 -922482232 13638063]
+OS2Version: 0
+OS2_WeightWidthSlopeOnly: 0
+OS2_UseTypoMetrics: 1
+CreationTime: 1561742286
+ModificationTime: 1561742286
+OS2TypoAscent: 0
+OS2TypoAOffset: 1
+OS2TypoDescent: 0
+OS2TypoDOffset: 1
+OS2TypoLinegap: 0
+OS2WinAscent: 0
+OS2WinAOffset: 1
+OS2WinDescent: 0
+OS2WinDOffset: 1
+HheadAscent: 0
+HheadAOffset: 1
+HheadDescent: 0
+HheadDOffset: 1
+OS2Vendor: 'PfEd'
+DEI: 91125
+Encoding: ISO8859-1
+UnicodeInterp: none
+NameList: AGL For New Fonts
+DisplaySize: 6
+AntiAlias: 1
+FitToEm: 0
+WinInfo: 0 32 23
+OnlyBitmaps: 1
+BeginChars: 256 96
+
+StartChar: space
+Encoding: 32 32 0
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: exclam
+Encoding: 33 33 1
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: quotedbl
+Encoding: 34 34 2
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: numbersign
+Encoding: 35 35 3
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: dollar
+Encoding: 36 36 4
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: percent
+Encoding: 37 37 5
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: ampersand
+Encoding: 38 38 6
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: quotesingle
+Encoding: 39 39 7
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: parenleft
+Encoding: 40 40 8
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: parenright
+Encoding: 41 41 9
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: asterisk
+Encoding: 42 42 10
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: plus
+Encoding: 43 43 11
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: comma
+Encoding: 44 44 12
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: hyphen
+Encoding: 45 45 13
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: period
+Encoding: 46 46 14
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: slash
+Encoding: 47 47 15
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: zero
+Encoding: 48 48 16
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: one
+Encoding: 49 49 17
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: two
+Encoding: 50 50 18
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: three
+Encoding: 51 51 19
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: four
+Encoding: 52 52 20
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: five
+Encoding: 53 53 21
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: six
+Encoding: 54 54 22
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: seven
+Encoding: 55 55 23
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: eight
+Encoding: 56 56 24
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: nine
+Encoding: 57 57 25
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: colon
+Encoding: 58 58 26
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: semicolon
+Encoding: 59 59 27
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: less
+Encoding: 60 60 28
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: equal
+Encoding: 61 61 29
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: greater
+Encoding: 62 62 30
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: question
+Encoding: 63 63 31
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: at
+Encoding: 64 64 32
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: A
+Encoding: 65 65 33
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: B
+Encoding: 66 66 34
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: C
+Encoding: 67 67 35
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: D
+Encoding: 68 68 36
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: E
+Encoding: 69 69 37
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: F
+Encoding: 70 70 38
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: G
+Encoding: 71 71 39
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: H
+Encoding: 72 72 40
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: I
+Encoding: 73 73 41
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: J
+Encoding: 74 74 42
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: K
+Encoding: 75 75 43
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: L
+Encoding: 76 76 44
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: M
+Encoding: 77 77 45
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: N
+Encoding: 78 78 46
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: O
+Encoding: 79 79 47
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: P
+Encoding: 80 80 48
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: Q
+Encoding: 81 81 49
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: R
+Encoding: 82 82 50
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: S
+Encoding: 83 83 51
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: T
+Encoding: 84 84 52
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: U
+Encoding: 85 85 53
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: V
+Encoding: 86 86 54
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: W
+Encoding: 87 87 55
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: X
+Encoding: 88 88 56
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: Y
+Encoding: 89 89 57
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: Z
+Encoding: 90 90 58
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: bracketleft
+Encoding: 91 91 59
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: backslash
+Encoding: 92 92 60
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: bracketright
+Encoding: 93 93 61
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: asciicircum
+Encoding: 94 94 62
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: underscore
+Encoding: 95 95 63
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: grave
+Encoding: 96 96 64
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: a
+Encoding: 97 97 65
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: b
+Encoding: 98 98 66
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: c
+Encoding: 99 99 67
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: d
+Encoding: 100 100 68
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: e
+Encoding: 101 101 69
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: f
+Encoding: 102 102 70
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: g
+Encoding: 103 103 71
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: h
+Encoding: 104 104 72
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: i
+Encoding: 105 105 73
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: j
+Encoding: 106 106 74
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: k
+Encoding: 107 107 75
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: l
+Encoding: 108 108 76
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: m
+Encoding: 109 109 77
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: n
+Encoding: 110 110 78
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: o
+Encoding: 111 111 79
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: p
+Encoding: 112 112 80
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: q
+Encoding: 113 113 81
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: r
+Encoding: 114 114 82
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: s
+Encoding: 115 115 83
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: t
+Encoding: 116 116 84
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: u
+Encoding: 117 117 85
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: v
+Encoding: 118 118 86
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: w
+Encoding: 119 119 87
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: x
+Encoding: 120 120 88
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: y
+Encoding: 121 121 89
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: z
+Encoding: 122 122 90
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: braceleft
+Encoding: 123 123 91
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: bar
+Encoding: 124 124 92
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: braceright
+Encoding: 125 125 93
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: asciitilde
+Encoding: 126 126 94
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: uni007F
+Encoding: 127 127 95
+Width: 666
+VWidth: 0
+Flags: W
+LayerCount: 2
+EndChar
+EndChars
+BitmapFont: 6 96 4 2 1
+BDFStartProperties: 20
+FONT 1 "-FontForge-Brutalist-Regular-R-Normal--6-60-75-75-P-40-ISO8859-1"
+SIZE 1 "6 100 100"
+FONTBOUNDINGBOX 1 "4 6 0 -1"
+FAMILY_NAME 16 "brutalist"
+WEIGHT_NAME 16 "Regular"
+SLANT 16 "R"
+SETWIDTH_NAME 16 "Normal"
+PIXEL_SIZE 18 6
+POINT_SIZE 18 60
+RESOLUTION_X 19 100
+RESOLUTION_Y 19 100
+SPACING 16 "C"
+AVERAGE_WIDTH 18 40
+CHARSET_REGISTRY 16 "ISO8859"
+CHARSET_ENCODING 16 "1"
+FONTNAME_REGISTRY 16 ""
+FONT_ASCENT 18 4
+FONT_DESCENT 18 2
+MIN_SPACE 18 6
+FIGURE_WIDTH 18 4
+BDFEndProperties
+Resolution: 100
+BDFChar: 0 32 5 3 3 -2 -2
+z
+BDFChar: 1 33 5 0 0 -2 3
+J:N0#!.Y%L
+BDFChar: 2 34 5 0 2 2 3
+TV)8b
+BDFChar: 3 35 5 0 2 -2 3
+T\uK9i1L&M
+BDFChar: 4 36 5 0 2 -2 3
+5iBFci'78B
+BDFChar: 5 37 5 0 2 -2 3
+THHKbJ=llB
+BDFChar: 6 38 5 0 2 -2 3
+5bLB8TO7a"
+BDFChar: 7 39 5 0 0 2 3
+J:IV"
+BDFChar: 8 40 5 0 2 -2 3
+@"<cXJ7&?W
+BDFChar: 9 41 5 0 2 -2 3
+^`XaB+M[sW
+BDFChar: 10 42 5 0 2 0 2
+TKo.M
+BDFChar: 11 43 5 0 2 0 2
+5i=m-
+BDFChar: 12 44 5 0 1 -2 0
+5X9i"
+BDFChar: 13 45 5 0 2 1 1
+huE`W
+BDFChar: 14 46 5 0 0 -1 -1
+J,fQL
+BDFChar: 15 47 5 0 2 -2 3
++<Wp7J:IV"
+BDFChar: 16 48 5 0 2 -1 3
+@%a0c^]4?7
+BDFChar: 17 49 5 0 1 -1 3
+5eoWM5QCca
+BDFChar: 18 50 5 0 2 -1 3
+i#ps.huE`W
+BDFChar: 19 51 5 0 2 -1 3
+i#pr#huE`W
+BDFChar: 20 52 5 0 2 -1 3
+TV13c+92BA
+BDFChar: 21 53 5 0 2 -1 3
+i.0`.huE`W
+BDFChar: 22 54 5 0 2 -1 3
+i.0aYhuE`W
+BDFChar: 23 55 5 0 2 -1 3
+i#j-b+92BA
+BDFChar: 24 56 5 0 2 -1 3
+i1T#$huE`W
+BDFChar: 25 57 5 0 2 -1 3
+i1T!NhuE`W
+BDFChar: 26 58 5 1 1 0 2
+J,k*"
+BDFChar: 27 59 5 0 1 -2 2
+5QF&7J,fQL
+BDFChar: 28 60 5 0 2 -1 3
++@(HB+92BA
+BDFChar: 29 61 5 0 2 0 2
+huM[8
+BDFChar: 30 62 5 0 2 -1 3
+J3Y5BJ,fQL
+BDFChar: 31 63 5 0 2 -2 3
+i#lDm!'gMa
+BDFChar: 32 64 5 0 2 -2 3
+i1T#dJD^D-
+BDFChar: 33 65 5 0 2 -1 3
+i1Qb$TE"rl
+BDFChar: 34 66 5 0 2 -1 3
+^nAK9huE`W
+BDFChar: 35 67 5 0 2 -1 3
+i1PUnhuE`W
+BDFChar: 36 68 5 0 2 -1 3
+^n@?n^]4?7
+BDFChar: 37 69 5 0 2 -1 3
+i.0a9huE`W
+BDFChar: 38 70 5 0 2 -1 3
+i.-@9J,fQL
+BDFChar: 39 71 5 0 2 -2 3
+i..Jni#i""
+BDFChar: 40 72 5 0 2 -1 3
+TV159TE"rl
+BDFChar: 41 73 5 0 2 -1 3
+i'9OmhuE`W
+BDFChar: 42 74 5 0 2 -1 3
++<Vf"huE`W
+BDFChar: 43 75 5 0 2 -1 3
+TYTKYTE"rl
+BDFChar: 44 76 5 0 2 -1 3
+J:N0#huE`W
+BDFChar: 45 77 5 0 2 -1 3
+T\uK9TE"rl
+BDFChar: 46 78 5 0 2 -1 3
+T]"bdTE"rl
+BDFChar: 47 79 5 0 2 -1 3
+i1Qa9huE`W
+BDFChar: 48 80 5 0 2 -1 3
+i1Qb$J,fQL
+BDFChar: 49 81 5 0 2 -2 3
+i1Qa9i#i""
+BDFChar: 50 82 5 0 2 -1 3
+i1QaYTE"rl
+BDFChar: 51 83 5 0 2 -1 3
+i.0`.huE`W
+BDFChar: 52 84 5 0 2 -1 3
+i'9Om5QCca
+BDFChar: 53 85 5 0 2 -1 3
+TV.sNhuE`W
+BDFChar: 54 86 5 0 2 -1 3
+TV.t95QCca
+BDFChar: 55 87 5 0 2 -1 3
+TV.t9TE"rl
+BDFChar: 56 88 5 0 2 -1 3
+TV+QCTE"rl
+BDFChar: 57 89 5 0 2 -1 3
+TV14.5QCca
+BDFChar: 58 90 5 0 2 -1 3
+i#k:8huE`W
+BDFChar: 59 91 5 0 2 -2 3
+i.-?.JD^D-
+BDFChar: 60 92 5 0 2 -2 3
+J:KmM+<UXa
+BDFChar: 61 93 5 0 2 -2 3
+i#j-b+Q*5"
+BDFChar: 62 94 5 0 2 1 3
+5iA:8
+BDFChar: 63 95 5 0 2 -1 -1
+huE`W
+BDFChar: 64 96 5 1 2 2 3
+J3X)7
+BDFChar: 65 97 5 0 2 -1 2
+i*`59
+BDFChar: 66 98 5 0 2 -1 3
+JDd)nhuE`W
+BDFChar: 67 99 5 0 2 -1 2
+i1PVY
+BDFChar: 68 100 5 0 2 -1 3
++Q/ochuE`W
+BDFChar: 69 101 5 0 2 -1 2
+i1RmD
+BDFChar: 70 102 5 0 2 -2 3
+?pNX85X5;L
+BDFChar: 71 103 5 0 2 -2 2
+i1T!NhuE`W
+BDFChar: 72 104 5 0 2 -1 3
+JDd)nTE"rl
+BDFChar: 73 105 5 1 2 -1 3
+J,k+M^]4?7
+BDFChar: 74 106 5 0 2 -2 3
++95dlT\oeM
+BDFChar: 75 107 5 0 2 -1 3
+J=s]NTE"rl
+BDFChar: 76 108 5 0 2 -1 3
+^d(.M?iU0,
+BDFChar: 77 109 5 0 2 -1 2
+i8EOd
+BDFChar: 78 110 5 0 2 -1 2
+i1Qa9
+BDFChar: 79 111 5 0 2 -1 2
+i1Qb$
+BDFChar: 80 112 5 0 2 -2 2
+i1Qb$J,fQL
+BDFChar: 81 113 5 0 2 -2 2
+i1Qb$+92BA
+BDFChar: 82 114 5 0 2 -1 2
+i1PUN
+BDFChar: 83 115 5 0 2 -1 2
+i.,4n
+BDFChar: 84 116 5 0 2 -1 3
+5i=mm?iU0,
+BDFChar: 85 117 5 0 2 -1 2
+TV.t9
+BDFChar: 86 118 5 0 2 -1 2
+TV14.
+BDFChar: 87 119 5 0 2 -1 2
+TV159
+BDFChar: 88 120 5 0 2 -1 2
+TKo0C
+BDFChar: 89 121 5 0 2 -2 2
+TV13chuE`W
+BDFChar: 90 122 5 0 2 -1 2
+i';hN
+BDFChar: 91 123 5 0 2 -2 3
+?pMLm5[XQl
+BDFChar: 92 124 5 1 1 -2 3
+J:N0#J:IV"
+BDFChar: 93 125 5 0 2 -2 3
+^d)9m5em@"
+BDFChar: 94 126 5 0 3 -1 3
+;"1+Xz
+BDFChar: 95 127 5 0 2 -2 3
+i1Qa9T\oeM
+EndBitmapFont
+EndSplineFont
diff --git a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk
index cafd84b21..6361da2a6 100644
--- a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk
@@ -4,14 +4,14 @@ USB_PID = 0x801F
USB_PRODUCT = "uGame10"
USB_MANUFACTURER = "Radomir Dopieralski"
+CHIP_VARIANT = SAMD21E18A
+CHIP_FAMILY = samd21
+
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = S25FL216K
LONGINT_IMPL = MPZ
-CHIP_VARIANT = SAMD21E18A
-CHIP_FAMILY = samd21
-
CIRCUITPY_STAGE = 1
CIRCUITPY_MATH = 1
CIRCUITPY_AUDIOIO = 1
@@ -31,4 +31,4 @@ CIRCUITPY_PIXELBUF = 0
FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/ugame10
-CIRCUITPY_DISPLAY_FONT = "../../tools/Tecate-bitmap-fonts/bitmap/phallus/lemon.bdf"
+CIRCUITPY_DISPLAY_FONT = $(TOP)/ports/atmel-samd/boards/ugame10/brutalist-6.bdf
diff --git a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c
index 20934bed4..05a6aaf7b 100644
--- a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+++ b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c
@@ -33,7 +33,7 @@
#include "py/runtime.h"
#include "common-hal/audiobusio/I2SOut.h"
#include "shared-bindings/audiobusio/I2SOut.h"
-#include "shared-bindings/audioio/RawSample.h"
+#include "shared-bindings/audiocore/RawSample.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "supervisor/shared/translate.h"
diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c
index a0c04d65d..cdc616bbc 100644
--- a/ports/atmel-samd/common-hal/busio/I2C.c
+++ b/ports/atmel-samd/common-hal/busio/I2C.c
@@ -36,6 +36,8 @@
#include "shared-bindings/microcontroller/__init__.h"
#include "supervisor/shared/translate.h"
+#include "common-hal/busio/SPI.h" // for never_reset_sercom
+
// Number of times to try to send packet if failed.
#define ATTEMPTS 2
@@ -225,3 +227,10 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
}
return MP_EIO;
}
+
+void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
+ never_reset_sercom(self->i2c_desc.device.hw);
+
+ never_reset_pin_number(self->scl_pin);
+ never_reset_pin_number(self->sda_pin);
+}
diff --git a/ports/atmel-samd/common-hal/busio/SPI.h b/ports/atmel-samd/common-hal/busio/SPI.h
index 56d163a9d..a1c0e1517 100644
--- a/ports/atmel-samd/common-hal/busio/SPI.h
+++ b/ports/atmel-samd/common-hal/busio/SPI.h
@@ -43,6 +43,7 @@ typedef struct {
} busio_spi_obj_t;
void reset_sercoms(void);
+void never_reset_sercom(Sercom* sercom);
#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_SPI_H
diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c
index 10618d1ce..f04594842 100644
--- a/ports/atmel-samd/common-hal/busio/UART.c
+++ b/ports/atmel-samd/common-hal/busio/UART.c
@@ -55,7 +55,7 @@ static void usart_async_rxc_callback(const struct usart_async_descriptor *const
void common_hal_busio_uart_construct(busio_uart_obj_t *self,
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
- uint8_t receiver_buffer_size) {
+ uint16_t receiver_buffer_size) {
Sercom* sercom = NULL;
uint8_t sercom_index = 255; // Unset index
uint32_t rx_pinmux = 0;
@@ -88,11 +88,19 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
continue;
}
potential_sercom = sercom_insts[sercom_index];
- if (potential_sercom->USART.CTRLA.bit.ENABLE != 0 ||
+#ifdef SAMD21
+ if (potential_sercom->USART.CTRLA.bit.ENABLE != 0 ||
!(tx->sercom[i].pad == 0 ||
tx->sercom[i].pad == 2)) {
continue;
}
+#endif
+#ifdef SAMD51
+ if (potential_sercom->USART.CTRLA.bit.ENABLE != 0 ||
+ !(tx->sercom[i].pad == 0)) {
+ continue;
+ }
+#endif
tx_pinmux = PINMUX(tx->number, (i == 0) ? MUX_C : MUX_D);
tx_pad = tx->sercom[i].pad;
if (rx == mp_const_none) {
diff --git a/ports/atmel-samd/common-hal/displayio/ParallelBus.c b/ports/atmel-samd/common-hal/displayio/ParallelBus.c
index 7a5f61448..c370f7e52 100644
--- a/ports/atmel-samd/common-hal/displayio/ParallelBus.c
+++ b/ports/atmel-samd/common-hal/displayio/ParallelBus.c
@@ -31,6 +31,7 @@
#include "common-hal/microcontroller/Pin.h"
#include "py/runtime.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "shared-bindings/microcontroller/__init__.h"
#include "tick.h"
@@ -66,10 +67,6 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel
common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select);
common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL);
- self->reset.base.type = &digitalio_digitalinout_type;
- common_hal_digitalio_digitalinout_construct(&self->reset, reset);
- common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL);
-
self->write.base.type = &digitalio_digitalinout_type;
common_hal_digitalio_digitalinout_construct(&self->write, write);
common_hal_digitalio_digitalinout_switch_to_output(&self->write, true, DRIVE_MODE_PUSH_PULL);
@@ -82,11 +79,21 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel
self->write_group = &PORT->Group[write->number / 32];
self->write_mask = 1 << (write->number % 32);
+ if (reset != NULL) {
+ self->reset.base.type = &digitalio_digitalinout_type;
+ common_hal_digitalio_digitalinout_construct(&self->reset, reset);
+ common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL);
+ never_reset_pin_number(reset->number);
+
+ common_hal_digitalio_digitalinout_set_value(&self->reset, false);
+ common_hal_mcu_delay_us(4);
+ common_hal_digitalio_digitalinout_set_value(&self->reset, true);
+ }
+
never_reset_pin_number(command->number);
never_reset_pin_number(chip_select->number);
never_reset_pin_number(write->number);
never_reset_pin_number(read->number);
- never_reset_pin_number(reset->number);
for (uint8_t i = 0; i < 8; i++) {
never_reset_pin_number(data_pin + i);
}
diff --git a/ports/atmel-samd/common-hal/ps2io/Ps2.c b/ports/atmel-samd/common-hal/ps2io/Ps2.c
new file mode 100644
index 000000000..6a06864f2
--- /dev/null
+++ b/ports/atmel-samd/common-hal/ps2io/Ps2.c
@@ -0,0 +1,441 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017-2018 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Elvis Pfutzenreuter <epxx@epxx.co>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "common-hal/ps2io/Ps2.h"
+
+#include <stdint.h>
+
+#include "atmel_start_pins.h"
+#include "hal/include/hal_gpio.h"
+
+#include "background.h"
+#include "eic_handler.h"
+#include "mpconfigport.h"
+#include "py/gc.h"
+#include "py/runtime.h"
+#include "samd/external_interrupts.h"
+#include "samd/pins.h"
+#include "shared-bindings/microcontroller/__init__.h"
+#include "shared-bindings/ps2io/Ps2.h"
+#include "supervisor/shared/translate.h"
+
+#include "tick.h"
+
+#define STATE_IDLE 0
+#define STATE_RECV 1
+#define STATE_RECV_PARITY 2
+#define STATE_RECV_STOP 3
+#define STATE_RECV_ERR 10
+
+#define ERROR_STARTBIT 0x01
+#define ERROR_TIMEOUT 0x02
+#define ERROR_PARITY 0x04
+#define ERROR_STOPBIT 0x08
+#define ERROR_BUFFER 0x10
+
+#define ERROR_TX_CLKLO 0x100
+#define ERROR_TX_CLKHI 0x200
+#define ERROR_TX_ACKDATA 0x400
+#define ERROR_TX_ACKCLK 0x800
+#define ERROR_TX_RTS 0x1000
+#define ERROR_TX_NORESP 0x2000
+
+static void ps2_set_config(ps2io_ps2_obj_t* self) {
+ uint32_t sense_setting = EIC_CONFIG_SENSE0_FALL_Val;
+ set_eic_handler(self->channel, EIC_HANDLER_PS2);
+ turn_on_eic_channel(self->channel, sense_setting);
+}
+
+static void disable_interrupt(ps2io_ps2_obj_t* self) {
+ uint32_t mask = 1 << self->channel;
+ EIC->INTENCLR.reg = mask << EIC_INTENSET_EXTINT_Pos;
+}
+
+static void resume_interrupt(ps2io_ps2_obj_t* self) {
+ disable_interrupt(self);
+
+ self->state = STATE_IDLE;
+ gpio_set_pin_function(self->clk_pin, GPIO_PIN_FUNCTION_A);
+ uint32_t mask = 1 << self->channel;
+ EIC->INTFLAG.reg = mask << EIC_INTFLAG_EXTINT_Pos;
+ EIC->INTENSET.reg = mask << EIC_INTENSET_EXTINT_Pos;
+
+ ps2_set_config(self);
+}
+
+static void clk_hi(ps2io_ps2_obj_t* self) {
+ // External pull-up
+ // Must set pull after setting direction.
+ gpio_set_pin_direction(self->clk_pin, GPIO_DIRECTION_IN);
+ gpio_set_pin_pull_mode(self->clk_pin, GPIO_PULL_OFF);
+}
+
+static bool wait_clk_lo(ps2io_ps2_obj_t* self, uint32_t us) {
+ clk_hi(self);
+ common_hal_mcu_delay_us(1);
+ while (gpio_get_pin_level(self->clk_pin) && us) {
+ --us;
+ common_hal_mcu_delay_us(1);
+ }
+ return us;
+}
+
+static bool wait_clk_hi(ps2io_ps2_obj_t* self, uint32_t us) {
+ clk_hi(self);
+ common_hal_mcu_delay_us(1);
+ while (!gpio_get_pin_level(self->clk_pin) && us) {
+ --us;
+ common_hal_mcu_delay_us(1);
+ }
+ return us;
+}
+
+static void clk_lo(ps2io_ps2_obj_t* self) {
+ gpio_set_pin_pull_mode(self->clk_pin, GPIO_PULL_OFF);
+ gpio_set_pin_direction(self->clk_pin, GPIO_DIRECTION_OUT);
+ gpio_set_pin_level(self->clk_pin, 0);
+}
+
+static void data_hi(ps2io_ps2_obj_t* self) {
+ // External pull-up
+ gpio_set_pin_direction(self->data_pin, GPIO_DIRECTION_IN);
+ gpio_set_pin_pull_mode(self->data_pin, GPIO_PULL_OFF);
+}
+
+static bool wait_data_lo(ps2io_ps2_obj_t* self, uint32_t us) {
+ data_hi(self);
+ common_hal_mcu_delay_us(1);
+ while (gpio_get_pin_level(self->data_pin) && us) {
+ --us;
+ common_hal_mcu_delay_us(1);
+ }
+ return us;
+}
+
+static bool wait_data_hi(ps2io_ps2_obj_t* self, uint32_t us) {
+ data_hi(self);
+ common_hal_mcu_delay_us(1);
+ while (!gpio_get_pin_level(self->data_pin) && us) {
+ --us;
+ common_hal_mcu_delay_us(1);
+ }
+ return us;
+}
+
+static void data_lo(ps2io_ps2_obj_t* self) {
+ gpio_set_pin_pull_mode(self->data_pin, GPIO_PULL_OFF);
+ gpio_set_pin_direction(self->data_pin, GPIO_DIRECTION_OUT);
+ gpio_set_pin_level(self->data_pin, 0);
+}
+
+static void idle(ps2io_ps2_obj_t* self) {
+ clk_hi(self);
+ data_hi(self);
+}
+
+static void inhibit(ps2io_ps2_obj_t* self) {
+ clk_lo(self);
+ data_hi(self);
+}
+
+static void delay_us(uint32_t t) {
+ common_hal_mcu_delay_us(t);
+}
+
+void ps2_interrupt_handler(uint8_t channel) {
+ // Grab the current time first.
+ uint32_t current_us;
+ uint64_t current_ms;
+ current_tick(&current_ms, &current_us);
+
+ ps2io_ps2_obj_t* self = get_eic_channel_data(channel);
+ int data_bit = gpio_get_pin_level(self->data_pin) ? 1 : 0;
+
+ // test for timeout
+ if (self->state != STATE_IDLE) {
+ int64_t diff_ms = current_ms - self->last_int_ms;
+ if (diff_ms >= 2) { // a.k.a. > 1.001ms
+ self->last_errors |= ERROR_TIMEOUT;
+ self->state = STATE_IDLE;
+ }
+ }
+
+ self->last_int_us = current_us;
+ self->last_int_ms = current_ms;
+
+ if (self->state == STATE_IDLE) {
+ self->bits = 0;
+ self->parity = false;
+ self->bitcount = 0;
+ self->state = STATE_RECV;
+ if (data_bit) {
+ // start bit should be 0
+ self->last_errors |= ERROR_STARTBIT;
+ self->state = STATE_RECV_ERR;
+ } else {
+ self->state = STATE_RECV;
+ }
+
+ } else if (self->state == STATE_RECV) {
+ if (data_bit) {
+ self->bits |= data_bit << self->bitcount;
+ self->parity = !self->parity;
+ }
+ ++self->bitcount;
+ if (self->bitcount >= 8) {
+ self->state = STATE_RECV_PARITY;
+ }
+
+ } else if (self->state == STATE_RECV_PARITY) {
+ ++self->bitcount;
+ if (data_bit) {
+ self->parity = !self->parity;
+ }
+ if (!self->parity) {
+ self->last_errors |= ERROR_PARITY;
+ self->state = STATE_RECV_ERR;
+ } else {
+ self->state = STATE_RECV_STOP;
+ }
+
+ } else if (self->state == STATE_RECV_STOP) {
+ ++self->bitcount;
+ if (! data_bit) {
+ self->last_errors |= ERROR_STOPBIT;
+ } else if (self->waiting_cmd_response) {
+ self->cmd_response = self->bits;
+ self->waiting_cmd_response = false;
+ } else if (self->bufcount >= sizeof(self->buffer)) {
+ self->last_errors |= ERROR_BUFFER;
+ } else {
+ self->buffer[self->bufposw] = self->bits;
+ self->bufposw = (self->bufposw + 1) % sizeof(self->buffer);
+ self->bufcount++;
+ }
+ self->state = STATE_IDLE;
+
+ } else if (self->state == STATE_RECV_ERR) {
+ // just count the bits until idle
+ if (++self->bitcount >= 10) {
+ self->state = STATE_IDLE;
+ }
+ }
+}
+
+void common_hal_ps2io_ps2_construct(ps2io_ps2_obj_t* self,
+ const mcu_pin_obj_t* data_pin, const mcu_pin_obj_t* clk_pin) {
+ if (!clk_pin->has_extint) {
+ mp_raise_RuntimeError(translate("No hardware support on clk pin"));
+ }
+ if (eic_get_enable() && !eic_channel_free(clk_pin->extint_channel)) {
+ mp_raise_RuntimeError(translate("EXTINT channel already in use"));
+ }
+
+ clk_hi(self);
+ data_hi(self);
+
+ self->channel = clk_pin->extint_channel;
+ self->clk_pin = clk_pin->number;
+ self->data_pin = data_pin->number;
+ self->state = STATE_IDLE;
+ self->bufcount = 0;
+ self->bufposr = 0;
+ self->bufposw = 0;
+ self->waiting_cmd_response = false;
+
+ set_eic_channel_data(clk_pin->extint_channel, (void*) self);
+
+ // Check to see if the EIC is enabled and start it up if its not.'
+ if (eic_get_enable() == 0) {
+ turn_on_external_interrupt_controller();
+ }
+
+ gpio_set_pin_function(clk_pin->number, GPIO_PIN_FUNCTION_A);
+ gpio_set_pin_function(data_pin->number, GPIO_PIN_FUNCTION_A);
+
+ turn_on_cpu_interrupt(self->channel);
+
+ claim_pin(clk_pin);
+ claim_pin(data_pin);
+
+ // Set config will enable the EIC.
+ ps2_set_config(self);
+}
+
+bool common_hal_ps2io_ps2_deinited(ps2io_ps2_obj_t* self) {
+ return self->clk_pin == NO_PIN;
+}
+
+void common_hal_ps2io_ps2_deinit(ps2io_ps2_obj_t* self) {
+ if (common_hal_ps2io_ps2_deinited(self)) {
+ return;
+ }
+ set_eic_handler(self->channel, EIC_HANDLER_NO_INTERRUPT);
+ turn_off_eic_channel(self->channel);
+ reset_pin_number(self->clk_pin);
+ reset_pin_number(self->data_pin);
+ self->clk_pin = NO_PIN;
+ self->data_pin = NO_PIN;
+}
+
+uint16_t common_hal_ps2io_ps2_get_len(ps2io_ps2_obj_t* self) {
+ return self->bufcount;
+}
+
+bool common_hal_ps2io_ps2_get_paused(ps2io_ps2_obj_t* self) {
+ uint32_t mask = 1 << self->channel;
+ return (EIC->INTENSET.reg & (mask << EIC_INTENSET_EXTINT_Pos)) == 0;
+}
+
+int16_t common_hal_ps2io_ps2_popleft(ps2io_ps2_obj_t* self)
+{
+ common_hal_mcu_disable_interrupts();
+ if (self->bufcount <= 0) {
+ common_hal_mcu_enable_interrupts();
+ return -1;
+ }
+ uint8_t b = self->buffer[self->bufposr];
+ self->bufposr = (self->bufposr + 1) % sizeof(self->buffer);
+ self->bufcount -= 1;
+ common_hal_mcu_enable_interrupts();
+ return b;
+}
+
+uint16_t common_hal_ps2io_ps2_clear_errors(ps2io_ps2_obj_t* self)
+{
+ common_hal_mcu_disable_interrupts();
+ uint16_t errors = self->last_errors;
+ self->last_errors = 0;
+ common_hal_mcu_enable_interrupts();
+ return errors;
+}
+
+// Based upon TMK implementation of PS/2 protocol
+// https://github.com/tmk/tmk_keyboard/blob/master/tmk_core/protocol/ps2_interrupt.c
+
+int16_t common_hal_ps2io_ps2_sendcmd(ps2io_ps2_obj_t* self, uint8_t b)
+{
+ disable_interrupt(self);
+ inhibit(self);
+ delay_us(100);
+
+ /* RTS and start bit */
+ data_lo(self);
+ clk_hi(self);
+ if (!wait_clk_lo(self, 10000)) {
+ self->last_errors |= ERROR_TX_RTS;
+ goto ERROR;
+ }
+
+ bool parity = true;
+ for (uint8_t i = 0; i < 8; i++) {
+ delay_us(15);
+ if (b & (1 << i)) {
+ parity = !parity;
+ data_hi(self);
+ } else {
+ data_lo(self);
+ }
+ if (!wait_clk_hi(self, 50)) {
+ self->last_errors |= ERROR_TX_CLKHI;
+ goto ERROR;
+ }
+ if (!wait_clk_lo(self, 50)) {
+ self->last_errors |= ERROR_TX_CLKLO;
+ goto ERROR;
+ }
+ }
+
+ delay_us(15);
+ if (parity) {
+ data_hi(self);
+ } else {
+ data_lo(self);
+ }
+ if (!wait_clk_hi(self, 50)) {
+ self->last_errors |= ERROR_TX_CLKHI;
+ goto ERROR;
+ }
+ if (!wait_clk_lo(self, 50)) {
+ self->last_errors |= ERROR_TX_CLKLO;
+ goto ERROR;
+ }
+
+ /* Stop bit */
+ delay_us(15);
+ data_hi(self);
+
+ /* Ack */
+ if (!wait_data_lo(self, 50)) {
+ self->last_errors |= ERROR_TX_ACKDATA;
+ goto ERROR;
+ }
+ if (!wait_clk_lo(self, 50)) {
+ self->last_errors |= ERROR_TX_ACKCLK;
+ goto ERROR;
+ }
+
+ /* wait for idle state */
+ if (!wait_clk_hi(self, 50)) {
+ self->last_errors |= ERROR_TX_ACKCLK;
+ goto ERROR;
+ }
+ if (!wait_data_hi(self, 50)) {
+ self->last_errors |= ERROR_TX_ACKDATA;
+ goto ERROR;
+ }
+
+ /* Wait for response byte */
+ self->waiting_cmd_response = true;
+ idle(self);
+ resume_interrupt(self);
+
+ for (int i = 0; i < 25; ++i) {
+ delay_us(1000);
+ common_hal_mcu_disable_interrupts();
+ bool has_response = !self->waiting_cmd_response;
+ uint8_t response = self->cmd_response;
+ common_hal_mcu_enable_interrupts();
+
+ if (has_response) {
+ return response;
+ }
+ }
+
+ /* No response */
+ common_hal_mcu_disable_interrupts();
+ self->waiting_cmd_response = false;
+ self->last_errors |= ERROR_TX_NORESP;
+ common_hal_mcu_enable_interrupts();
+ return -1;
+
+ /* Other errors */
+ERROR:
+ idle(self);
+ resume_interrupt(self);
+ return -1;
+}
diff --git a/ports/atmel-samd/common-hal/ps2io/Ps2.h b/ports/atmel-samd/common-hal/ps2io/Ps2.h
new file mode 100644
index 000000000..cce6ae474
--- /dev/null
+++ b/ports/atmel-samd/common-hal/ps2io/Ps2.h
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Elvis Pfutzenreuter <epxx@epxx.co>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PS2IO_PS2_H
+#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PS2IO_PS2_H
+
+#include "common-hal/microcontroller/Pin.h"
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ uint8_t channel;
+ uint8_t clk_pin;
+ uint8_t data_pin;
+
+ uint8_t state;
+ uint64_t last_int_ms;
+ uint32_t last_int_us;
+
+ uint16_t bits;
+ bool parity;
+ uint8_t bitcount;
+
+ uint8_t buffer[16];
+ uint8_t bufcount;
+ uint8_t bufposr;
+ uint8_t bufposw;
+
+ uint16_t last_errors;
+
+ bool waiting_cmd_response;
+ uint8_t cmd_response;
+} ps2io_ps2_obj_t;
+
+void ps2_interrupt_handler(uint8_t channel);
+
+#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PS2IO_PS2_H
diff --git a/ports/atmel-samd/common-hal/ps2io/__init__.c b/ports/atmel-samd/common-hal/ps2io/__init__.c
new file mode 100644
index 000000000..ba4b4249f
--- /dev/null
+++ b/ports/atmel-samd/common-hal/ps2io/__init__.c
@@ -0,0 +1 @@
+// No ps2io module functions.
diff --git a/ports/atmel-samd/eic_handler.c b/ports/atmel-samd/eic_handler.c
index db5f260e5..30ecaa7ca 100644
--- a/ports/atmel-samd/eic_handler.c
+++ b/ports/atmel-samd/eic_handler.c
@@ -25,6 +25,7 @@
*/
#include "common-hal/pulseio/PulseIn.h"
+#include "common-hal/ps2io/Ps2.h"
#include "common-hal/rotaryio/IncrementalEncoder.h"
#include "shared-bindings/microcontroller/__init__.h"
//#include "samd/external_interrupts.h"
@@ -46,6 +47,12 @@ void shared_eic_handler(uint8_t channel) {
break;
#endif
+#if CIRCUITPY_PS2IO
+ case EIC_HANDLER_PS2:
+ ps2_interrupt_handler(channel);
+ break;
+#endif
+
#if CIRCUITPY_ROTARYIO
case EIC_HANDLER_INCREMENTAL_ENCODER:
incrementalencoder_interrupt_handler(channel);
diff --git a/ports/atmel-samd/eic_handler.h b/ports/atmel-samd/eic_handler.h
index 2f9ccd67f..71b0fce67 100644
--- a/ports/atmel-samd/eic_handler.h
+++ b/ports/atmel-samd/eic_handler.h
@@ -29,6 +29,7 @@
#define EIC_HANDLER_NO_INTERRUPT 0x0
#define EIC_HANDLER_PULSEIN 0x1
#define EIC_HANDLER_INCREMENTAL_ENCODER 0x2
+#define EIC_HANDLER_PS2 0x3
void set_eic_handler(uint8_t channel, uint8_t eic_handler);
void shared_eic_handler(uint8_t channel);
diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk
index 66ee92e6b..4ddd097f0 100644
--- a/ports/atmel-samd/mpconfigport.mk
+++ b/ports/atmel-samd/mpconfigport.mk
@@ -17,7 +17,7 @@ endif
# Put samd21-only choices here.
ifeq ($(CHIP_FAMILY),samd21)
# frequencyio not yet verified as working on SAMD21.
-CIRCUITPY_FRQUENCYIO = 0
+CIRCUITPY_FREQUENCYIO = 0
endif
# Put samd51-only choices here.
diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c
index 4f53d30f9..37360deb0 100644
--- a/ports/atmel-samd/supervisor/port.c
+++ b/ports/atmel-samd/supervisor/port.c
@@ -52,6 +52,7 @@
#include "common-hal/pulseio/PulseIn.h"
#include "common-hal/pulseio/PulseOut.h"
#include "common-hal/pulseio/PWMOut.h"
+#include "common-hal/ps2io/Ps2.h"
#include "common-hal/rtc/RTC.h"
#include "common-hal/touchio/TouchIn.h"
#include "samd/cache.h"
diff --git a/ports/atmel-samd/tools/gen_pin_name_table.py b/ports/atmel-samd/tools/gen_pin_name_table.py
index 76c9cf255..ded64e5f6 100644
--- a/ports/atmel-samd/tools/gen_pin_name_table.py
+++ b/ports/atmel-samd/tools/gen_pin_name_table.py
@@ -156,6 +156,9 @@ capabilities = {
"PA14", "PA15", "PA16", "PA17", "PA18", "PA19", "PA20",
"PA21", "PA22", "PA23", "PA30", "PA31"]
},
+ "ps2io": {
+ "Ps2": ALL_BUT_USB,
+ },
"touchio": {
"TouchIn": ["PA02", "PA03", "PB08", "PB09", "PA04", "PA05", "PA06",
"PA07", "PB02", "PB03"]
diff --git a/ports/esp8266/common-hal/busio/UART.c b/ports/esp8266/common-hal/busio/UART.c
index f10e3dc55..e72dce639 100644
--- a/ports/esp8266/common-hal/busio/UART.c
+++ b/ports/esp8266/common-hal/busio/UART.c
@@ -40,7 +40,7 @@ extern UartDevice UartDev;
void common_hal_busio_uart_construct(busio_uart_obj_t *self,
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
- uint8_t receiver_buffer_size) {
+ uint16_t receiver_buffer_size) {
if (rx != mp_const_none || tx != &pin_GPIO2) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("Only tx supported on UART1 (GPIO2).")));
}
diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile
index d947ab34c..9da2c498d 100755
--- a/ports/nrf/Makefile
+++ b/ports/nrf/Makefile
@@ -81,6 +81,7 @@ INC += -I./nrfx
INC += -I./nrfx/hal
INC += -I./nrfx/mdk
INC += -I./nrfx/drivers/include
+INC += -I./nrfx/drivers/src
INC += -I./bluetooth
INC += -I./peripherals
INC += -I../../lib/mp-readline
@@ -159,7 +160,6 @@ SRC_C += \
boards/$(BOARD)/pins.c \
device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \
bluetooth/ble_drv.c \
- bluetooth/ble_uart.c \
lib/libc/string0.c \
lib/mp-readline/readline.c \
lib/oofatfs/ff.c \
diff --git a/ports/nrf/README.md b/ports/nrf/README.md
index 65a66b7b0..5f6d03720 100644
--- a/ports/nrf/README.md
+++ b/ports/nrf/README.md
@@ -79,6 +79,7 @@ feather_nrf52840_express | s140 | Peripheral and Scanner | UF
makerdiary_nrf52840_mdk | s140 | Peripheral and Scanner | pyocd or ARM mbed DAPLink
makerdiary_nrf52840_mdk_usb_dongle | s140 | Peripheral and Scanner | DFU bootloader & nrfutil
electronut_labs_papyr | s140 | Peripheral and Scanner | UF2 bootloader
+electronut_labs_blip | s140 | Peripheral and Scanner | Black Magic Probe
## Segger Targets
diff --git a/ports/nrf/background.c b/ports/nrf/background.c
index 3fb5febd3..453bc96df 100644
--- a/ports/nrf/background.c
+++ b/ports/nrf/background.c
@@ -29,10 +29,14 @@
#include "supervisor/usb.h"
#include "supervisor/shared/stack.h"
-#ifdef CIRCUITPY_DISPLAYIO
+#if CIRCUITPY_DISPLAYIO
#include "shared-module/displayio/__init__.h"
#endif
+#if CIRCUITPY_AUDIOPWMIO
+#include "common-hal/audiopwmio/PWMAudioOut.h"
+#endif
+
static bool running_background_tasks = false;
void background_tasks_reset(void) {
@@ -47,8 +51,11 @@ void run_background_tasks(void) {
running_background_tasks = true;
filesystem_background();
usb_background();
+#if CIRCUITPY_AUDIOPWMIO
+ audiopwmout_background();
+#endif
- #ifdef CIRCUITPY_DISPLAYIO
+ #if CIRCUITPY_DISPLAYIO
displayio_refresh_displays();
#endif
running_background_tasks = false;
diff --git a/ports/nrf/bluetooth/ble_drv.c b/ports/nrf/bluetooth/ble_drv.c
index f6e575a8c..6b17e7af2 100644
--- a/ports/nrf/bluetooth/ble_drv.c
+++ b/ports/nrf/bluetooth/ble_drv.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/ports/nrf/bluetooth/ble_drv.h b/ports/nrf/bluetooth/ble_drv.h
index cdb4c9b03..a066f588f 100644
--- a/ports/nrf/bluetooth/ble_drv.h
+++ b/ports/nrf/bluetooth/ble_drv.h
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,10 +31,6 @@
#include "ble.h"
-#if (BLUETOOTH_SD == 132) && (BLE_API_VERSION == 2)
-#define NRF52
-#endif
-
#define MAX_TX_IN_PROGRESS 10
#ifndef BLE_GATT_ATT_MTU_DEFAULT
@@ -43,9 +40,12 @@
#define BLE_CONN_CFG_TAG_CUSTOM 1
#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION))
+#define SEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000000) / (RESOLUTION))
// 0.625 msecs (625 usecs)
#define ADV_INTERVAL_UNIT_FLOAT_SECS (0.000625)
+// Microseconds is the base unit. The macros above know that.
#define UNIT_0_625_MS (625)
+#define UNIT_1_25_MS (1250)
#define UNIT_10_MS (10000)
typedef void (*ble_drv_evt_handler_t)(ble_evt_t*, void*);
diff --git a/ports/nrf/bluetooth/ble_uart.c b/ports/nrf/bluetooth/ble_uart.c
index 7faaafb0e..91d10cff1 100644
--- a/ports/nrf/bluetooth/ble_uart.c
+++ b/ports/nrf/bluetooth/ble_uart.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/ports/nrf/boards/electronut_labs_blip/README.md b/ports/nrf/boards/electronut_labs_blip/README.md
new file mode 100644
index 000000000..c34ef16f8
--- /dev/null
+++ b/ports/nrf/boards/electronut_labs_blip/README.md
@@ -0,0 +1,67 @@
+# Setup
+
+The `Electronut Labs Blip` board is a development board based on the `nRF52840` SoC from
+Nordic Semiconductors. It has a Black Magic Probe compatible programmer and debugger
+built in, along with temperature/humidity sensor, ambient light intensity sensor, and
+a 3-axis accelerometer. It can be used to prototype very low power devices. It also has
+provision for an SD card slot, which makes it a complete and versatile development board.
+
+Schematic, datasheet, pin mapping etc. can be found over [here](https://docs.electronut.in/blip/).
+
+Features:
+
+* Raytac MDBT50Q-1M module based on Nordic Semiconductor's nRF52840
+* LIS2DDH12 High-performance 3-axis "femto" accelerometer
+* Optical Sensor LTR-329ALS-01
+* Si7006-A20 I2C humidity and temperature sensor
+* On board STM32F103CBT6 as Black magic probe debugger
+* NFC Antenna
+* MicroSD slot
+* Power Supply: USB, JST connector for Li-ion/Li-po
+* BQ24079 battery charging and power management IC
+
+## Installing CircuitPython submodules
+
+Before you can build, you will need to run the following commands once, which
+will install the submodules that are part of the CircuitPython ecosystem, and
+build the `mpy-cross` tool:
+
+```
+$ cd circuitpython
+$ git submodule update --init
+$ make -C mpy-cross
+```
+
+## Building and Flashing CircuitPython
+
+No special notes for this, follow `ports/nrf` generic `README.md`.
+
+### Flashing CircuitPython with GDB using on board Black magic probe debugger
+
+```
+$ cd ports/nrf
+$ make V=1 SD=s140 SERIAL=/dev/ttyACM0 BOARD=electronut_labs_blip all
+...
+...
+LINK build-electronut_labs_blip-s140/firmware.elf
+
+778588 bytes free in flash out of 1048576 bytes ( 1024.0 kb ).
+228320 bytes free in ram for stack out of 245760 bytes ( 240.0 kb ).
+
+Create build-electronut_labs_blip-s140/firmware.bin
+Create build-electronut_labs_blip-s140/firmware.hex
+Create build-electronut_labs_blip-s140/firmware.uf2
+python3 ../../tools/uf2/utils/uf2conv.py -f 0xADA52840 -c -o "build-electronut_labs_blip-s140/firmware.uf2" build-electronut_labs_blip-s140/firmware.hex
+Converting to uf2, output size: 540160, start address: 0x26000
+Wrote 540160 bytes to build-electronut_labs_blip-s140/firmware.uf2.
+```
+
+Now you can use either `.hex` or `.elf` from the generated files inside
+`build-electronut_labs_blip-s140` directory. Now you can use `arm-none-eabi-gdb`
+to flash circuitpython on Blip.
+
+### Other tips
+
+Once circuitpython is running on your board, it will come up as a mass storage
+device named `CIRCUITPY`, where you can drop in your python code. The file names
+it looks for are `main.py`, `main.txt`, `code.py` or `code.txt`.
diff --git a/supervisor/shared/usb/usb_desc.h b/ports/nrf/boards/electronut_labs_blip/board.c
index 250147aa6..4421970ee 100644
--- a/supervisor/shared/usb/usb_desc.h
+++ b/ports/nrf/boards/electronut_labs_blip/board.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2018 hathach for Adafruit Industries
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,20 +24,15 @@
* THE SOFTWARE.
*/
-#ifndef USB_DESC_H_
-#define USB_DESC_H_
+#include "boards/board.h"
-#include "lib/tinyusb/src/tusb.h"
+void board_init(void) {
+}
-#ifdef __cplusplus
- extern "C" {
-#endif
+bool board_requests_safe_mode(void) {
+ return false;
+}
-// Descriptors set used by tinyusb stack
-extern tud_desc_set_t tud_desc_set;
+void reset_board(void) {
-#ifdef __cplusplus
- }
-#endif
-
-#endif /* USB_DESC_H_ */
+}
diff --git a/ports/nrf/boards/electronut_labs_blip/mpconfigboard.h b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.h
new file mode 100644
index 000000000..21e8c3ef6
--- /dev/null
+++ b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2019 tavish@electronut.in
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "nrfx/hal/nrf_gpio.h"
+
+#define ELECTRONUT_LABS_PAPYR
+
+#define MICROPY_HW_BOARD_NAME "Electronut Labs Blip"
+#define MICROPY_HW_MCU_NAME "nRF52840"
+#define MICROPY_PY_SYS_PLATFORM "ElectronutLabsPapyr"
+
+#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
+
+// TODO #define CIRCUITPY_INTERNAL_NVM_SIZE 8192
+
+#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define BOARD_HAS_CRYSTAL 1
+
+#define DEFAULT_I2C_BUS_SCL (&pin_P0_11)
+#define DEFAULT_I2C_BUS_SDA (&pin_P0_12)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_P0_25)
+#define DEFAULT_SPI_BUS_MOSI (&pin_P1_02)
+#define DEFAULT_SPI_BUS_MISO (&pin_P0_24)
+
+#define DEFAULT_UART_BUS_RX (&pin_P0_08)
+#define DEFAULT_UART_BUS_TX (&pin_P0_06)
diff --git a/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk
new file mode 100644
index 000000000..9cddd96ee
--- /dev/null
+++ b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk
@@ -0,0 +1,30 @@
+USB_VID = 0x239A
+USB_PID = 0x803C
+USB_PRODUCT = "Blip"
+USB_MANUFACTURER = "Electronut Labs"
+
+MCU_SERIES = m4
+MCU_VARIANT = nrf52
+MCU_SUB_VARIANT = nrf52840
+MCU_CHIP = nrf52840
+SD ?= s140
+SOFTDEV_VERSION ?= 6.1.0
+
+BOOT_SETTING_ADDR = 0xFF000
+
+ifeq ($(SD),)
+ LD_FILE = boards/nrf52840_1M_256k.ld
+else
+ LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld
+ CIRCUITPY_BLEIO = 1
+endif
+
+NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
+
+QSPI_FLASH_FILESYSTEM = 0
+INTERNAL_FLASH_FILESYSTEM = 1
+CIRCUITPY_AUDIOIO = 0
+CIRCUITPY_DISPLAYIO = 1
+CIRCUITPY_GAMEPAD = 1
+CIRCUITPY_STAGE = 1
+
diff --git a/ports/nrf/boards/electronut_labs_blip/pins.c b/ports/nrf/boards/electronut_labs_blip/pins.c
new file mode 100644
index 000000000..a8f9af1cd
--- /dev/null
+++ b/ports/nrf/boards/electronut_labs_blip/pins.c
@@ -0,0 +1,72 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_03) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_04) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_28) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_29) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_30) },
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_31) },
+
+ { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) },
+ { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) },
+
+ // odd row
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P0_02) },
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P0_04) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_06) },
+ { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P0_08) },
+ { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_P0_19) },
+ { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_P0_21) },
+ { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_P0_26) },
+ { MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_P0_27) },
+ { MP_ROM_QSTR(MP_QSTR_D29), MP_ROM_PTR(&pin_P0_29) },
+ { MP_ROM_QSTR(MP_QSTR_D31), MP_ROM_PTR(&pin_P0_31) },
+ { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_P1_01) },
+ { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_P1_04) },
+ { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_P1_06) },
+
+ // even row
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P0_03) },
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P0_05) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P0_07) },
+ { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_P0_16) },
+ { MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_P0_20) },
+ { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_P0_22) },
+ { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_P0_23) },
+ { MP_ROM_QSTR(MP_QSTR_D28), MP_ROM_PTR(&pin_P0_28) },
+ { MP_ROM_QSTR(MP_QSTR_D30), MP_ROM_PTR(&pin_P0_30) },
+ { MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_P1_00) },
+ { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_P1_03) },
+ { MP_ROM_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_P1_05) },
+ { MP_ROM_QSTR(MP_QSTR_D40), MP_ROM_PTR(&pin_P1_08) },
+
+ // SCL SDA as pins also
+ { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_11) },
+ { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_12) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_12) },
+
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_25) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_24) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P1_02) },
+ { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_P0_17) },
+
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_06) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_08) },
+
+ { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P0_14) },
+ { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P0_14) },
+
+ { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P0_15) },
+ { MP_ROM_QSTR(MP_QSTR_GREEN_LED), MP_ROM_PTR(&pin_P0_13) },
+
+ { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_P1_07) },
+ { MP_ROM_QSTR(MP_QSTR_RESET), MP_ROM_PTR(&pin_P0_18) },
+
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+};
+
+MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h
index e1f43e3c9..70ccffc3f 100644
--- a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h
+++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h
@@ -27,8 +27,6 @@
#include "nrfx/hal/nrf_gpio.h"
-#define FEATHER52840
-
#define MICROPY_HW_BOARD_NAME "Adafruit Feather nRF52840 Express"
#define MICROPY_HW_MCU_NAME "nRF52840"
#define MICROPY_PY_SYS_PLATFORM "Feather52840Express"
diff --git a/ports/nrf/boards/metro_nrf52840_express/board.c b/ports/nrf/boards/metro_nrf52840_express/board.c
new file mode 100644
index 000000000..4421970ee
--- /dev/null
+++ b/ports/nrf/boards/metro_nrf52840_express/board.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+
+}
diff --git a/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.h b/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.h
new file mode 100644
index 000000000..520eef90d
--- /dev/null
+++ b/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.h
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "nrfx/hal/nrf_gpio.h"
+
+#define MICROPY_HW_BOARD_NAME "Adafruit Metro nRF52840 Express"
+#define MICROPY_HW_MCU_NAME "nRF52840"
+#define MICROPY_PY_SYS_PLATFORM "Metro52840Express"
+
+#define FLASH_SIZE (0x100000)
+#define FLASH_PAGE_SIZE (4096)
+
+#define MICROPY_HW_NEOPIXEL (&pin_P0_13)
+
+#define MICROPY_HW_LED_STATUS (&pin_P1_13)
+
+#if QSPI_FLASH_FILESYSTEM
+#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 17)
+#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 23)
+#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 22)
+#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 21)
+#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19)
+#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 20)
+#endif
+
+#if SPI_FLASH_FILESYSTEM
+#define SPI_FLASH_MOSI_PIN &pin_P0_17
+#define SPI_FLASH_MISO_PIN &pin_P0_23
+#define SPI_FLASH_SCK_PIN &pin_P0_19
+#define SPI_FLASH_CS_PIN &pin_P0_20
+#endif
+
+#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
+
+#define CIRCUITPY_INTERNAL_NVM_SIZE (4096)
+
+#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define BOARD_HAS_CRYSTAL 1
+
+#define DEFAULT_I2C_BUS_SCL (&pin_P0_16)
+#define DEFAULT_I2C_BUS_SDA (&pin_P0_15)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_P0_07)
+#define DEFAULT_SPI_BUS_MOSI (&pin_P1_08)
+#define DEFAULT_SPI_BUS_MISO (&pin_P0_11)
+
+#define DEFAULT_UART_BUS_RX (&pin_P0_24)
+#define DEFAULT_UART_BUS_TX (&pin_P0_25)
diff --git a/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk b/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk
new file mode 100644
index 000000000..4c1c93c10
--- /dev/null
+++ b/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk
@@ -0,0 +1,26 @@
+USB_VID = 0x239A
+USB_PID = 0x8040
+USB_PRODUCT = "Metro nRF52840 Express"
+USB_MANUFACTURER = "Adafruit Industries LLC"
+
+MCU_SERIES = m4
+MCU_VARIANT = nrf52
+MCU_SUB_VARIANT = nrf52840
+MCU_CHIP = nrf52840
+SD ?= s140
+SOFTDEV_VERSION ?= 6.1.0
+
+BOOT_SETTING_ADDR = 0xFF000
+
+ifeq ($(SD),)
+ LD_FILE = boards/nrf52840_1M_256k.ld
+else
+ LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld
+ CIRCUITPY_BLEIO = 1
+endif
+
+NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "GD25Q16C"
diff --git a/ports/nrf/boards/metro_nrf52840_express/pins.c b/ports/nrf/boards/metro_nrf52840_express/pins.c
new file mode 100644
index 000000000..452e31202
--- /dev/null
+++ b/ports/nrf/boards/metro_nrf52840_express/pins.c
@@ -0,0 +1,56 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_04) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_05) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_28) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_30) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_02) },
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_03) },
+
+ { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_31) },
+
+ { MP_ROM_QSTR(MP_QSTR_SWITCH), MP_ROM_PTR(&pin_P1_02) },
+
+ { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) },
+ { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) },
+
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P0_24) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_24) },
+
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P0_25) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_25) },
+
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P1_10) },
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_04) },
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P1_11) },
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_12) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P1_14) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P0_26) },
+ { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P0_27) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_12) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_06) },
+ { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_08) },
+ { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P1_09) },
+ { MP_ROM_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_P0_14) },
+
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_15) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_16) },
+
+ { MP_ROM_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_P0_13) },
+
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_07) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P1_08) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_11) },
+
+ { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P1_13) },
+ { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_13) },
+
+ { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_15) },
+
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+};
+
+MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/nrf/boards/particle_argon/mpconfigboard.h b/ports/nrf/boards/particle_argon/mpconfigboard.h
index 0ee785c31..a4ecb2bb4 100644
--- a/ports/nrf/boards/particle_argon/mpconfigboard.h
+++ b/ports/nrf/boards/particle_argon/mpconfigboard.h
@@ -27,8 +27,6 @@
#include "nrfx/hal/nrf_gpio.h"
-#define FEATHER52840
-
#define MICROPY_HW_BOARD_NAME "Particle Argon"
#define MICROPY_HW_MCU_NAME "nRF52840"
#define MICROPY_PY_SYS_PLATFORM "Particle Argon"
diff --git a/ports/nrf/boards/particle_boron/mpconfigboard.h b/ports/nrf/boards/particle_boron/mpconfigboard.h
index b814fc694..5e817311f 100644
--- a/ports/nrf/boards/particle_boron/mpconfigboard.h
+++ b/ports/nrf/boards/particle_boron/mpconfigboard.h
@@ -27,8 +27,6 @@
#include "nrfx/hal/nrf_gpio.h"
-#define FEATHER52840
-
#define MICROPY_HW_BOARD_NAME "Particle Boron"
#define MICROPY_HW_MCU_NAME "nRF52840"
#define MICROPY_PY_SYS_PLATFORM "Particle Boron"
diff --git a/ports/nrf/boards/particle_xenon/mpconfigboard.h b/ports/nrf/boards/particle_xenon/mpconfigboard.h
index 41551d2e1..6c8cc7cef 100644
--- a/ports/nrf/boards/particle_xenon/mpconfigboard.h
+++ b/ports/nrf/boards/particle_xenon/mpconfigboard.h
@@ -27,17 +27,15 @@
#include "nrfx/hal/nrf_gpio.h"
-#define FEATHER52840
-
#define MICROPY_HW_BOARD_NAME "Particle Xenon"
#define MICROPY_HW_MCU_NAME "nRF52840"
#define MICROPY_PY_SYS_PLATFORM "Particle Xenon"
#define MICROPY_HW_LED_STATUS (&pin_P1_12)
-#define MICROPY_HW_RGB_LED_RED (&pin_P0_13)
-#define MICROPY_HW_RGB_LED_GREEN (&pin_P0_14)
-#define MICROPY_HW_RGB_LED_BLUE (&pin_P0_15)
+#define CP_RGB_STATUS_R (&pin_P0_13)
+#define CP_RGB_STATUS_G (&pin_P0_14)
+#define CP_RGB_STATUS_B (&pin_P0_15)
#if QSPI_FLASH_FILESYSTEM
#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 20)
diff --git a/ports/nrf/common-hal/analogio/AnalogIn.c b/ports/nrf/common-hal/analogio/AnalogIn.c
index 1e572f7cb..f20802ac9 100644
--- a/ports/nrf/common-hal/analogio/AnalogIn.c
+++ b/ports/nrf/common-hal/analogio/AnalogIn.c
@@ -3,8 +3,8 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/ports/nrf/common-hal/audiopwmio/PWMAudioOut.c b/ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
new file mode 100644
index 000000000..0321b751c
--- /dev/null
+++ b/ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
@@ -0,0 +1,316 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Jeff Epler for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#include "extmod/vfs_fat.h"
+#include "py/gc.h"
+#include "py/mperrno.h"
+#include "py/runtime.h"
+#include "common-hal/audiopwmio/PWMAudioOut.h"
+#include "common-hal/pulseio/PWMOut.h"
+#include "shared-bindings/audiopwmio/PWMAudioOut.h"
+#include "shared-bindings/microcontroller/__init__.h"
+#include "shared-bindings/microcontroller/Pin.h"
+#include "supervisor/shared/translate.h"
+
+// TODO: This should be the same size as PWMOut.c:pwms[], but there's no trivial way to accomplish that
+STATIC audiopwmio_pwmaudioout_obj_t* active_audio[4];
+
+#define F_TARGET (62500)
+#define F_PWM (16000000)
+// return the REFRESH value, store the TOP value in an out-parameter
+// Tested for key values (worst relative error = 0.224% = 3.84 cents)
+// 8000: top = 250 refresh = 7 [ 8000.0]
+// 22050: top = 242 refresh = 2 [22038.5]
+// 24000: top = 222 refresh = 2 [24024.0]
+// 44100: top = 181 refresh = 1 [44198.8]
+// 48000: top = 167 refresh = 1 [47904.1]
+STATIC uint32_t calculate_pwm_parameters(uint32_t sample_rate, uint32_t *top_out) {
+ // the desired frequency is the closest integer multiple of sample_rate not less than F_TARGET
+ uint32_t desired_frequency = (F_TARGET + sample_rate - 1) / sample_rate * sample_rate;
+ // The top value is the PWM frequency divided by the desired frequency (round to nearest)
+ uint32_t top = (F_PWM + desired_frequency/2) / desired_frequency;
+ // The actual frequency is the PWM frequency divided by the top value (round to nearest)
+ uint32_t actual_frequency = (F_PWM + top/2) / top;
+ // The multiplier is the actual frequency divided by the sample rate (round to nearest)
+ uint32_t multiplier = (actual_frequency + sample_rate/2) / sample_rate;
+ *top_out = top;
+ return multiplier - 1;
+}
+
+STATIC void activate_audiopwmout_obj(audiopwmio_pwmaudioout_obj_t *self) {
+ for(size_t i=0; i < MP_ARRAY_SIZE(active_audio); i++) {
+ if(!active_audio[i]) {
+ active_audio[i] = self;
+ break;
+ }
+ }
+}
+STATIC void deactivate_audiopwmout_obj(audiopwmio_pwmaudioout_obj_t *self) {
+ for(size_t i=0; i < MP_ARRAY_SIZE(active_audio); i++) {
+ if(active_audio[i] == self)
+ active_audio[i] = NULL;
+ }
+}
+
+void audiopwmout_reset() {
+ for(size_t i=0; i < MP_ARRAY_SIZE(active_audio); i++)
+ active_audio[i] = NULL;
+}
+
+STATIC void fill_buffers(audiopwmio_pwmaudioout_obj_t *self, int buf) {
+ self->pwm->EVENTS_SEQSTARTED[1-buf] = 0;
+ uint16_t *dev_buffer = self->buffers[buf];
+ uint8_t *buffer;
+ uint32_t buffer_length;
+ audioio_get_buffer_result_t get_buffer_result =
+ audiosample_get_buffer(self->sample, false, 0,
+ &buffer, &buffer_length);
+ if (get_buffer_result == GET_BUFFER_ERROR) {
+ common_hal_audiopwmio_pwmaudioout_stop(self);
+ return;
+ }
+ uint32_t num_samples = buffer_length / self->bytes_per_sample / self->spacing;
+
+ if(self->bytes_per_sample == 1) {
+ uint8_t offset = self->signed_to_unsigned ? 0x80 : 0;
+ uint16_t scale = self->scale;
+ for(uint32_t i=0; i<buffer_length/self->spacing; i++) {
+ uint8_t rawval = (*buffer++ + offset);
+ uint16_t val = (uint16_t)(((uint32_t)rawval * (uint32_t)scale) >> 8);
+ *dev_buffer++ = val;
+ if(self->spacing == 1)
+ *dev_buffer++ = val;
+ }
+ } else {
+ uint16_t offset = self->signed_to_unsigned ? 0x8000 : 0;
+ uint16_t scale = self->scale;
+ uint16_t *buffer16 = (uint16_t*)buffer;
+ for(uint32_t i=0; i<buffer_length/2/self->spacing; i++) {
+ uint16_t rawval = (*buffer16++ + offset);
+ uint16_t val = (uint16_t)((rawval * (uint32_t)scale) >> 16);
+ *dev_buffer++ = val;
+ if(self->spacing == 1)
+ *dev_buffer++ = val;
+ }
+ }
+ self->pwm->SEQ[buf].PTR = (intptr_t)self->buffers[buf];
+ self->pwm->SEQ[buf].CNT = num_samples*2;
+
+ if (self->loop && get_buffer_result == GET_BUFFER_DONE) {
+ audiosample_reset_buffer(self->sample, false, 0);
+ } else if(get_buffer_result == GET_BUFFER_DONE) {
+ self->pwm->SHORTS = NRF_PWM_SHORT_SEQEND0_STOP_MASK | NRF_PWM_SHORT_SEQEND1_STOP_MASK;
+ self->stopping = true;
+ }
+}
+
+STATIC void audiopwmout_background_obj(audiopwmio_pwmaudioout_obj_t *self) {
+ if(!common_hal_audiopwmio_pwmaudioout_get_playing(self))
+ return;
+ if(self->stopping) {
+ bool stopped =
+ (self->pwm->EVENTS_SEQEND[0] || !self->pwm->EVENTS_SEQSTARTED[0]) &&
+ (self->pwm->EVENTS_SEQEND[1] || !self->pwm->EVENTS_SEQSTARTED[1]);
+ if(stopped)
+ self->pwm->TASKS_STOP = 1;
+ } else if(!self->paused && !self->single_buffer) {
+ if(self->pwm->EVENTS_SEQSTARTED[0]) fill_buffers(self, 1);
+ if(self->pwm->EVENTS_SEQSTARTED[1]) fill_buffers(self, 0);
+ }
+}
+
+void audiopwmout_background() {
+ for(size_t i=0; i < MP_ARRAY_SIZE(active_audio); i++) {
+ if(!active_audio[i]) continue;
+ audiopwmout_background_obj(active_audio[i]);
+ }
+}
+
+void common_hal_audiopwmio_pwmaudioout_construct(audiopwmio_pwmaudioout_obj_t* self,
+ const mcu_pin_obj_t* left_channel, const mcu_pin_obj_t* right_channel, uint16_t quiescent_value) {
+ assert_pin_free(left_channel);
+ assert_pin_free(right_channel);
+ self->pwm = pwmout_allocate(256, PWM_PRESCALER_PRESCALER_DIV_1, true, NULL, NULL);
+ if(!self->pwm) {
+ mp_raise_RuntimeError(translate("All timers in use"));
+ }
+
+ self->pwm->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_1;
+ // two uint16_t values per sample when Grouped
+ // n.b. SEQ[#].CNT "counts" are 2 per sample (left and right channels)
+ self->pwm->DECODER = PWM_DECODER_LOAD_Grouped;
+
+ // we use channels 0 and 2 because these are GROUPED; it lets us save half
+ // the space for sample data (no additional optimization is possible for
+ // single channel)
+ self->pwm->PSEL.OUT[0] = self->left_channel_number = left_channel->number;
+ claim_pin(left_channel);
+
+ if(right_channel)
+ {
+ self->pwm->PSEL.OUT[2] = self->right_channel_number = right_channel->number;
+ claim_pin(right_channel);
+ }
+
+ self->quiescent_value = quiescent_value >> 8;
+
+ self->pwm->ENABLE = 1;
+ // TODO: Ramp from 0 to quiescent value
+}
+
+bool common_hal_audiopwmio_pwmaudioout_deinited(audiopwmio_pwmaudioout_obj_t* self) {
+ return !self->pwm;
+}
+
+void common_hal_audiopwmio_pwmaudioout_deinit(audiopwmio_pwmaudioout_obj_t* self) {
+ if (common_hal_audiopwmio_pwmaudioout_deinited(self)) {
+ return;
+ }
+ // TODO: ramp the pwm down from quiescent value to 0
+ self->pwm->ENABLE = 0;
+
+ if(self->left_channel_number)
+ reset_pin_number(self->left_channel_number);
+ if(self->right_channel_number)
+ reset_pin_number(self->right_channel_number);
+
+ pwmout_free_channel(self->pwm, 0);
+ pwmout_free_channel(self->pwm, 2);
+
+ self->pwm = NULL;
+
+ m_free(self->buffers[0]);
+ self->buffers[0] = NULL;
+
+ m_free(self->buffers[1]);
+ self->buffers[1] = NULL;
+}
+
+void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t* self, mp_obj_t sample, bool loop) {
+ if (common_hal_audiopwmio_pwmaudioout_get_playing(self)) {
+ common_hal_audiopwmio_pwmaudioout_stop(self);
+ }
+ self->sample = sample;
+ self->loop = loop;
+
+ uint32_t sample_rate = audiosample_sample_rate(sample);
+ uint32_t max_sample_rate = 62500;
+ if (sample_rate > max_sample_rate) {
+ mp_raise_ValueError_varg(translate("Sample rate too high. It must be less than %d"), max_sample_rate);
+ }
+ self->bytes_per_sample = audiosample_bits_per_sample(sample) / 8;
+
+ uint32_t max_buffer_length;
+ audiosample_get_buffer_structure(sample, /* single channel */ false,
+ &self->single_buffer, &self->signed_to_unsigned, &max_buffer_length,
+ &self->spacing);
+ if(max_buffer_length > UINT16_MAX) {
+ mp_raise_ValueError_varg(translate("Buffer length %d too big. It must be less than %d"), max_buffer_length, UINT16_MAX);
+ }
+ self->buffer_length = (uint16_t)max_buffer_length;
+ self->buffers[0] = m_malloc(self->buffer_length * 2 * sizeof(uint16_t), false);
+ if(!self->single_buffer)
+ self->buffers[1] = m_malloc(self->buffer_length * 2 * sizeof(uint16_t), false);
+
+
+ uint32_t top;
+ self->pwm->SEQ[0].REFRESH = self->pwm->SEQ[1].REFRESH = calculate_pwm_parameters(sample_rate, &top);
+ self->scale = top-1;
+ self->pwm->COUNTERTOP = top;
+
+ self->pwm->LOOP = 1;
+ audiosample_reset_buffer(self->sample, false, 0);
+ activate_audiopwmout_obj(self);
+ fill_buffers(self, 0);
+ self->pwm->SEQ[1].PTR = self->pwm->SEQ[0].PTR;
+ self->pwm->SEQ[1].CNT = self->pwm->SEQ[0].CNT;
+ self->pwm->EVENTS_SEQSTARTED[0] = 0;
+ self->pwm->EVENTS_SEQSTARTED[1] = 0;
+ self->pwm->EVENTS_STOPPED = 0;
+ self->pwm->SHORTS = NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK;
+ self->pwm->TASKS_SEQSTART[0] = 1;
+ self->playing = true;
+ self->stopping = false;
+ self->paused = false;
+}
+
+void common_hal_audiopwmio_pwmaudioout_stop(audiopwmio_pwmaudioout_obj_t* self) {
+ deactivate_audiopwmout_obj(self);
+ self->pwm->TASKS_STOP = 1;
+ self->stopping = false;
+ self->paused = false;
+
+ m_free(self->buffers[0]);
+ self->buffers[0] = NULL;
+
+ m_free(self->buffers[1]);
+ self->buffers[1] = NULL;
+}
+
+bool common_hal_audiopwmio_pwmaudioout_get_playing(audiopwmio_pwmaudioout_obj_t* self) {
+ if(!self->paused && self->pwm->EVENTS_STOPPED) {
+ self->playing = false;
+ self->pwm->EVENTS_STOPPED = 0;
+ }
+ return self->playing;
+}
+
+/* pause/resume present difficulties for the NRF PWM audio module.
+ *
+ * A PWM sequence can be stopped in its tracks by sending a TASKS_STOP event,
+ * but there's no way to pick up the sequence where it was stopped; you could
+ * start at the start of one of the two sequences, but especially for "single buffer"
+ * sample, this seems undesirable.
+ *
+ * Or, you can stop at the end of a sequence so that you don't duplicate anything
+ * when restarting, but again this is unsatisfactory for a "single buffer" sample.
+ *
+ * For now, I've taken the coward's way and left these methods unimplemented.
+ * Perhaps the way forward is to divide even "single buffer" samples into tasks of
+ * only a few ms long, so that they can be stopped/restarted quickly enough that it
+ * feels instant. (This also saves on memory, for long in-memory "single buffer"
+ * samples, since we have to locally take a resampled copy!)
+ */
+void common_hal_audiopwmio_pwmaudioout_pause(audiopwmio_pwmaudioout_obj_t* self) {
+ self->paused = true;
+ self->pwm->SHORTS = NRF_PWM_SHORT_SEQEND1_STOP_MASK;
+}
+
+void common_hal_audiopwmio_pwmaudioout_resume(audiopwmio_pwmaudioout_obj_t* self) {
+ self->paused = false;
+ self->pwm->SHORTS = NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK;
+ if (self->pwm->EVENTS_STOPPED) {
+ self->pwm->EVENTS_STOPPED = 0;
+ self->pwm->TASKS_SEQSTART[0] = 1;
+ }
+}
+
+bool common_hal_audiopwmio_pwmaudioout_get_paused(audiopwmio_pwmaudioout_obj_t* self) {
+ return self->paused;
+}
diff --git a/ports/nrf/common-hal/bleio/Broadcaster.h b/ports/nrf/common-hal/audiopwmio/PWMAudioOut.h
index 72f93a443..8deff5d34 100644
--- a/ports/nrf/common-hal/bleio/Broadcaster.h
+++ b/ports/nrf/common-hal/audiopwmio/PWMAudioOut.h
@@ -3,8 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2018 Artur Pacholec
- * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2019 Jeff Epler for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -25,23 +24,36 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_COMMON_HAL_BLEIO_BROADCASTER_H
-#define MICROPY_INCLUDED_COMMON_HAL_BLEIO_BROADCASTER_H
+#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_AUDIOPWM_AUDIOOUT_H
+#define MICROPY_INCLUDED_NRF_COMMON_HAL_AUDIOPWM_AUDIOOUT_H
-#include "ble.h"
-
-#include "shared-module/bleio/__init__.h"
-#include "shared-module/bleio/Address.h"
+#include "common-hal/microcontroller/Pin.h"
typedef struct {
mp_obj_base_t base;
- // In seconds.
- mp_float_t interval;
- // The advertising data buffer is held by us, not by the SD, so we must
- // maintain it and not change it. If we need to change its contents during advertising,
- // there are tricks to get the SD to notice (see DevZone - TBS).
- uint8_t adv_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX];
+ mp_obj_t *sample;
+ NRF_PWM_Type *pwm;
+ uint16_t *buffers[2];
+
+ uint16_t buffer_length;
+ uint16_t quiescent_value;
+ uint16_t scale;
+
+ uint8_t left_channel_number;
+ uint8_t right_channel_number;
+ uint8_t spacing;
+ uint8_t bytes_per_sample;
+
+ bool playing;
+ bool stopping;
+ bool paused;
+ bool loop;
+ bool signed_to_unsigned;
+ bool single_buffer;
+} audiopwmio_pwmaudioout_obj_t;
+
+void audiopwmout_reset(void);
-} bleio_broadcaster_obj_t;
+void audiopwmout_background(void);
-#endif // MICROPY_INCLUDED_COMMON_HAL_BLEIO_BROADCASTER_H
+#endif
diff --git a/ports/nrf/common-hal/audiopwmio/__init__.c b/ports/nrf/common-hal/audiopwmio/__init__.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ports/nrf/common-hal/audiopwmio/__init__.c
diff --git a/ports/nrf/common-hal/bleio/Adapter.c b/ports/nrf/common-hal/bleio/Adapter.c
index 540659aa1..9d0912930 100644
--- a/ports/nrf/common-hal/bleio/Adapter.c
+++ b/ports/nrf/common-hal/bleio/Adapter.c
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
* Copyright (c) 2016 Glenn Ruben Bakke
* Copyright (c) 2018 Artur Pacholec
*
@@ -136,17 +137,15 @@ void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address) {
uint32_t err_code;
common_hal_bleio_adapter_set_enabled(true);
-
-#if (BLE_API_VERSION == 2)
- err_code = sd_ble_gap_address_get(&local_address);
-#else
err_code = sd_ble_gap_addr_get(&local_address);
-#endif
if (err_code != NRF_SUCCESS) {
mp_raise_OSError_msg(translate("Failed to get local address"));
}
address->type = local_address.addr_type;
- memcpy(address->value, local_address.addr, BLEIO_ADDRESS_BYTES);
+
+ mp_buffer_info_t buf_info;
+ mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ);
+ memcpy(address->bytes, buf_info.buf, NUM_BLEIO_ADDRESS_BYTES);
}
diff --git a/ports/nrf/common-hal/bleio/Adapter.h b/ports/nrf/common-hal/bleio/Adapter.h
index 0497f9ac9..5dcc62540 100644
--- a/ports/nrf/common-hal/bleio/Adapter.h
+++ b/ports/nrf/common-hal/bleio/Adapter.h
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/ports/nrf/common-hal/bleio/Broadcaster.c b/ports/nrf/common-hal/bleio/Broadcaster.c
deleted file mode 100644
index a70209a7f..000000000
--- a/ports/nrf/common-hal/bleio/Broadcaster.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 Dan Halbert for Adafruit Industries
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <string.h>
-
-#include "ble.h"
-#include "ble_drv.h"
-#include "ble_hci.h"
-#include "nrf_soc.h"
-#include "py/runtime.h"
-
-#include "common-hal/bleio/Broadcaster.h"
-#include "shared-bindings/bleio/Adapter.h"
-#include "shared-bindings/bleio/Broadcaster.h"
-
-static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
-
-void common_hal_bleio_broadcaster_construct(bleio_broadcaster_obj_t *self, mp_float_t interval) {
- common_hal_bleio_adapter_set_enabled(true); // TODO -- Do this somewhere else maybe bleio __init__
- const mp_float_t min = BLE_GAP_ADV_INTERVAL_MIN * ADV_INTERVAL_UNIT_FLOAT_SECS;
- const mp_float_t max = BLE_GAP_ADV_INTERVAL_MAX * ADV_INTERVAL_UNIT_FLOAT_SECS;
-
- if (interval < min || interval > max) {
- // Would like to print range using the constants above, but vargs would convert to double.
- mp_raise_ValueError(translate("interval not in range 0.0020 to 10.24"));
- }
- self->interval = interval;
-}
-
-
-void common_hal_bleio_broadcaster_start_advertising(bleio_broadcaster_obj_t *self, mp_buffer_info_t *data) {
- uint32_t err_code;
-
- if (data->len >= BLE_GAP_ADV_SET_DATA_SIZE_MAX) {
- mp_raise_ValueError(translate("Data too large for advertisement packet"));
- }
- memcpy(self->adv_data, data->buf, data->len);
-
- ble_gap_adv_params_t m_adv_params = {
- .interval = (uint32_t) (self->interval / ADV_INTERVAL_UNIT_FLOAT_SECS),
- .properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED,
- .duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED,
- .filter_policy = BLE_GAP_ADV_FP_ANY,
- .primary_phy = BLE_GAP_PHY_1MBPS,
- };
-
- common_hal_bleio_broadcaster_stop_advertising(self);
-
- const ble_gap_adv_data_t ble_gap_adv_data = {
- .adv_data.p_data = self->adv_data,
- .adv_data.len = data->len,
- };
-
- err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &ble_gap_adv_data, &m_adv_params);
- if (err_code == NRF_SUCCESS) {
- err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_CONN_CFG_TAG_CUSTOM);
- }
-
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to start advertising, err 0x%04x"), err_code);
- }
-}
-
-void common_hal_bleio_broadcaster_stop_advertising(bleio_broadcaster_obj_t *self) {
-
- if (m_adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET) {
- return;
- }
-
- const uint32_t err_code = sd_ble_gap_adv_stop(m_adv_handle);
-
- if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) {
- mp_raise_OSError_msg_varg(translate("Failed to stop advertising, err 0x%04x"), err_code);
- }
-}
diff --git a/ports/nrf/common-hal/bleio/Central.c b/ports/nrf/common-hal/bleio/Central.c
new file mode 100644
index 000000000..d90737411
--- /dev/null
+++ b/ports/nrf/common-hal/bleio/Central.c
@@ -0,0 +1,463 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include "ble.h"
+#include "ble_drv.h"
+#include "ble_hci.h"
+#include "nrf_soc.h"
+#include "py/objstr.h"
+#include "py/runtime.h"
+#include "shared-bindings/bleio/Adapter.h"
+#include "shared-bindings/bleio/Characteristic.h"
+#include "shared-bindings/bleio/Central.h"
+#include "shared-bindings/bleio/Descriptor.h"
+#include "shared-bindings/bleio/Service.h"
+#include "shared-bindings/bleio/UUID.h"
+
+static bleio_service_obj_t *m_char_discovery_service;
+static bleio_characteristic_obj_t *m_desc_discovery_characteristic;
+
+static volatile bool m_discovery_in_process;
+static volatile bool m_discovery_successful;
+
+// service_uuid may be NULL, to discover all services.
+STATIC bool discover_next_services(bleio_central_obj_t *self, uint16_t start_handle, ble_uuid_t *service_uuid) {
+ m_discovery_successful = false;
+ m_discovery_in_process = true;
+
+ uint32_t err_code = sd_ble_gattc_primary_services_discover(self->conn_handle, start_handle, service_uuid);
+
+ if (err_code != NRF_SUCCESS) {
+ mp_raise_OSError_msg(translate("Failed to discover services"));
+ }
+
+ // Wait for a discovery event.
+ while (m_discovery_in_process) {
+ MICROPY_VM_HOOK_LOOP;
+ }
+ return m_discovery_successful;
+}
+
+STATIC bool discover_next_characteristics(bleio_central_obj_t *self, bleio_service_obj_t *service, uint16_t start_handle) {
+ m_char_discovery_service = service;
+
+ ble_gattc_handle_range_t handle_range;
+ handle_range.start_handle = start_handle;
+ handle_range.end_handle = service->end_handle;
+
+ m_discovery_successful = false;
+ m_discovery_in_process = true;
+
+ uint32_t err_code = sd_ble_gattc_characteristics_discover(self->conn_handle, &handle_range);
+ if (err_code != NRF_SUCCESS) {
+ return false;
+ }
+
+ // Wait for a discovery event.
+ while (m_discovery_in_process) {
+ MICROPY_VM_HOOK_LOOP;
+ }
+ return m_discovery_successful;
+}
+
+STATIC bool discover_next_descriptors(bleio_central_obj_t *self, bleio_characteristic_obj_t *characteristic, uint16_t start_handle, uint16_t end_handle) {
+ m_desc_discovery_characteristic = characteristic;
+
+ ble_gattc_handle_range_t handle_range;
+ handle_range.start_handle = start_handle;
+ handle_range.end_handle = end_handle;
+
+ m_discovery_successful = false;
+ m_discovery_in_process = true;
+
+ uint32_t err_code = sd_ble_gattc_descriptors_discover(self->conn_handle, &handle_range);
+ if (err_code != NRF_SUCCESS) {
+ return false;
+ }
+
+ // Wait for a discovery event.
+ while (m_discovery_in_process) {
+ MICROPY_VM_HOOK_LOOP;
+ }
+ return m_discovery_successful;
+}
+
+STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, bleio_central_obj_t *central) {
+ for (size_t i = 0; i < response->count; ++i) {
+ ble_gattc_service_t *gattc_service = &response->services[i];
+
+ bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t);
+ service->base.type = &bleio_service_type;
+
+ // Initialize several fields at once.
+ common_hal_bleio_service_construct(service, NULL, mp_obj_new_list(0, NULL), false);
+
+ service->device = MP_OBJ_FROM_PTR(central);
+ service->start_handle = gattc_service->handle_range.start_handle;
+ service->end_handle = gattc_service->handle_range.end_handle;
+ service->handle = gattc_service->handle_range.start_handle;
+
+ if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
+ // Known service UUID.
+ bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t);
+ uuid->base.type = &bleio_uuid_type;
+ bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid);
+ service->uuid = uuid;
+ service->device = MP_OBJ_FROM_PTR(central);
+ } else {
+ // The discovery response contained a 128-bit UUID that has not yet been registered with the
+ // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
+ // For now, just set the UUID to NULL.
+ service->uuid = NULL;
+ }
+
+ mp_obj_list_append(central->service_list, service);
+ }
+
+ if (response->count > 0) {
+ m_discovery_successful = true;
+ }
+ m_discovery_in_process = false;
+}
+
+STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio_central_obj_t *central) {
+ for (size_t i = 0; i < response->count; ++i) {
+ ble_gattc_char_t *gattc_char = &response->chars[i];
+
+ bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t);
+ characteristic->base.type = &bleio_characteristic_type;
+
+ characteristic->descriptor_list = mp_obj_new_list(0, NULL);
+
+ bleio_uuid_obj_t *uuid = NULL;
+
+ if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
+ // Known characteristic UUID.
+ uuid = m_new_obj(bleio_uuid_obj_t);
+ uuid->base.type = &bleio_uuid_type;
+ bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid);
+ } else {
+ // The discovery response contained a 128-bit UUID that has not yet been registered with the
+ // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
+ // For now, just leave the UUID as NULL.
+ }
+
+ bleio_characteristic_properties_t props;
+
+ props.broadcast = gattc_char->char_props.broadcast;
+ props.indicate = gattc_char->char_props.indicate;
+ props.notify = gattc_char->char_props.notify;
+ props.read = gattc_char->char_props.read;
+ props.write = gattc_char->char_props.write;
+ props.write_no_response = gattc_char->char_props.write_wo_resp;
+
+ // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler.
+ common_hal_bleio_characteristic_construct(characteristic, uuid, props, mp_obj_new_list(0, NULL));
+ characteristic->handle = gattc_char->handle_value;
+ characteristic->service = m_char_discovery_service;
+
+ mp_obj_list_append(m_char_discovery_service->characteristic_list, MP_OBJ_FROM_PTR(characteristic));
+ }
+
+ if (response->count > 0) {
+ m_discovery_successful = true;
+ }
+ m_discovery_in_process = false;
+}
+
+STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, bleio_central_obj_t *central) {
+ for (size_t i = 0; i < response->count; ++i) {
+ ble_gattc_desc_t *gattc_desc = &response->descs[i];
+
+ // Remember handles for certain well-known descriptors.
+ switch (gattc_desc->uuid.uuid) {
+ case DESCRIPTOR_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION:
+ m_desc_discovery_characteristic->cccd_handle = gattc_desc->handle;
+ break;
+
+ case DESCRIPTOR_UUID_SERVER_CHARACTERISTIC_CONFIGURATION:
+ m_desc_discovery_characteristic->sccd_handle = gattc_desc->handle;
+ break;
+
+ case DESCRIPTOR_UUID_CHARACTERISTIC_USER_DESCRIPTION:
+ m_desc_discovery_characteristic->user_desc_handle = gattc_desc->handle;
+ break;
+
+ default:
+ // TODO: sd_ble_gattc_descriptors_discover() can return things that are not descriptors,
+ // so ignore those.
+ // https://devzone.nordicsemi.com/f/nordic-q-a/49500/sd_ble_gattc_descriptors_discover-is-returning-attributes-that-are-not-descriptors
+ break;
+ }
+
+ bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t);
+ descriptor->base.type = &bleio_descriptor_type;
+
+ bleio_uuid_obj_t *uuid = NULL;
+
+ if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
+ // Known descriptor UUID.
+ uuid = m_new_obj(bleio_uuid_obj_t);
+ uuid->base.type = &bleio_uuid_type;
+ bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid);
+ } else {
+ // The discovery response contained a 128-bit UUID that has not yet been registered with the
+ // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
+ // For now, just leave the UUID as NULL.
+ }
+
+ common_hal_bleio_descriptor_construct(descriptor, uuid);
+ descriptor->handle = gattc_desc->handle;
+ descriptor->characteristic = m_desc_discovery_characteristic;
+
+ mp_obj_list_append(m_desc_discovery_characteristic->descriptor_list, MP_OBJ_FROM_PTR(descriptor));
+ }
+
+ if (response->count > 0) {
+ m_discovery_successful = true;
+ }
+ m_discovery_in_process = false;
+}
+
+STATIC void central_on_ble_evt(ble_evt_t *ble_evt, void *central_in) {
+ bleio_central_obj_t *central = (bleio_central_obj_t*)central_in;
+
+ switch (ble_evt->header.evt_id) {
+ case BLE_GAP_EVT_CONNECTED:
+ central->conn_handle = ble_evt->evt.gap_evt.conn_handle;
+ central->waiting_to_connect = false;
+ break;
+
+ case BLE_GAP_EVT_TIMEOUT:
+ // Handle will be invalid.
+ central->waiting_to_connect = false;
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ central->conn_handle = BLE_CONN_HANDLE_INVALID;
+ m_discovery_successful = false;
+ m_discovery_in_process = false;
+ break;
+
+ case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
+ on_primary_srv_discovery_rsp(&ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp, central);
+ break;
+
+ case BLE_GATTC_EVT_CHAR_DISC_RSP:
+ on_char_discovery_rsp(&ble_evt->evt.gattc_evt.params.char_disc_rsp, central);
+ break;
+
+ case BLE_GATTC_EVT_DESC_DISC_RSP:
+ on_desc_discovery_rsp(&ble_evt->evt.gattc_evt.params.desc_disc_rsp, central);
+ break;
+
+ case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
+ sd_ble_gap_sec_params_reply(central->conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
+ break;
+
+ case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: {
+ ble_gap_evt_conn_param_update_request_t *request =
+ &ble_evt->evt.gap_evt.params.conn_param_update_request;
+ sd_ble_gap_conn_param_update(central->conn_handle, &request->conn_params);
+ break;
+ }
+
+ default:
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Unhandled central event: 0x%04x\n", ble_evt->header.evt_id);
+ break;
+ }
+}
+
+void common_hal_bleio_central_construct(bleio_central_obj_t *self) {
+ common_hal_bleio_adapter_set_enabled(true);
+
+ self->service_list = mp_obj_new_list(0, NULL);
+ self->gatt_role = GATT_ROLE_CLIENT;
+ self->conn_handle = BLE_CONN_HANDLE_INVALID;
+}
+
+void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout, mp_obj_t service_uuids) {
+ common_hal_bleio_adapter_set_enabled(true);
+ ble_drv_add_event_handler(central_on_ble_evt, self);
+
+ ble_gap_addr_t addr;
+
+ addr.addr_type = address->type;
+ mp_buffer_info_t address_buf_info;
+ mp_get_buffer_raise(address->bytes, &address_buf_info, MP_BUFFER_READ);
+ memcpy(addr.addr, (uint8_t *) address_buf_info.buf, NUM_BLEIO_ADDRESS_BYTES);
+
+ ble_gap_scan_params_t scan_params = {
+ .interval = MSEC_TO_UNITS(100, UNIT_0_625_MS),
+ .window = MSEC_TO_UNITS(100, UNIT_0_625_MS),
+ .scan_phys = BLE_GAP_PHY_1MBPS,
+ // timeout of 0 means no timeout
+ .timeout = SEC_TO_UNITS(timeout, UNIT_10_MS),
+ };
+
+ ble_gap_conn_params_t conn_params = {
+ .conn_sup_timeout = MSEC_TO_UNITS(4000, UNIT_10_MS),
+ .min_conn_interval = MSEC_TO_UNITS(15, UNIT_1_25_MS),
+ .max_conn_interval = MSEC_TO_UNITS(300, UNIT_1_25_MS),
+ .slave_latency = 0, // number of conn events
+ };
+
+ self->waiting_to_connect = true;
+
+ uint32_t err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_CUSTOM);
+
+ if (err_code != NRF_SUCCESS) {
+ mp_raise_OSError_msg_varg(translate("Failed to start connecting, error 0x%04x"), err_code);
+ }
+
+ while (self->waiting_to_connect) {
+ MICROPY_VM_HOOK_LOOP;
+ }
+
+ if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
+ mp_raise_OSError_msg(translate("Failed to connect: timeout"));
+ }
+
+ // Connection successful.
+ // Now discover services on the remote peripheral.
+
+ if (service_uuids == mp_const_none) {
+
+ // List of service UUID's not given, so discover all available services.
+
+ uint16_t next_service_start_handle = BLE_GATT_HANDLE_START;
+
+ while (discover_next_services(self, next_service_start_handle, MP_OBJ_NULL)) {
+ // discover_next_services() appends to service_list.
+
+ // Get the most recently discovered service, and then ask for services
+ // whose handles start after the last attribute handle inside that service.
+ const bleio_service_obj_t *service =
+ MP_OBJ_TO_PTR(self->service_list->items[self->service_list->len - 1]);
+ next_service_start_handle = service->end_handle + 1;
+ }
+ } else {
+ mp_obj_iter_buf_t iter_buf;
+ mp_obj_t iterable = mp_getiter(service_uuids, &iter_buf);
+ mp_obj_t uuid_obj;
+ while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
+ if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
+ mp_raise_ValueError(translate("non-UUID found in service_uuids"));
+ }
+ bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj);
+
+ ble_uuid_t nrf_uuid;
+ bleio_uuid_convert_to_nrf_ble_uuid(uuid, &nrf_uuid);
+
+ // Service might or might not be discovered; that's ok. Caller has to check
+ // Central.remote_services to find out.
+ // We only need to call this once for each service to discover.
+ discover_next_services(self, BLE_GATT_HANDLE_START, &nrf_uuid);
+ }
+ }
+
+
+ for (size_t service_idx = 0; service_idx < self->service_list->len; ++service_idx) {
+ bleio_service_obj_t *service = MP_OBJ_TO_PTR(self->service_list->items[service_idx]);
+
+ // Skip the service if it had an unknown (unregistered) UUID.
+ if (service->uuid == NULL) {
+ continue;
+ }
+
+ uint16_t next_char_start_handle = service->start_handle;
+
+ // Stop when we go past the end of the range of handles for this service or
+ // discovery call returns nothing.
+ // discover_next_characteristics() appends to the characteristic_list.
+ while (next_char_start_handle <= service->end_handle &&
+ discover_next_characteristics(self, service, next_char_start_handle)) {
+
+
+ // Get the most recently discovered characteristic, and then ask for characteristics
+ // whose handles start after the last attribute handle inside that characteristic.
+ const bleio_characteristic_obj_t *characteristic =
+ MP_OBJ_TO_PTR(service->characteristic_list->items[service->characteristic_list->len - 1]);
+ next_char_start_handle = characteristic->handle + 1;
+ }
+
+ // Got characteristics for this service. Now discover descriptors for each characteristic.
+ size_t char_list_len = service->characteristic_list->len;
+ for (size_t char_idx = 0; char_idx < char_list_len; ++char_idx) {
+ bleio_characteristic_obj_t *characteristic =
+ MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx]);
+ const bool last_characteristic = char_idx == char_list_len - 1;
+ bleio_characteristic_obj_t *next_characteristic = last_characteristic
+ ? NULL
+ : MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx + 1]);
+
+ // Skip the characteristic if it had an unknown (unregistered) UUID.
+ if (characteristic->uuid == NULL) {
+ continue;
+ }
+
+ uint16_t next_desc_start_handle = characteristic->handle + 1;
+
+ // Don't run past the end of this service or the beginning of the next characteristic.
+ uint16_t next_desc_end_handle = next_characteristic == NULL
+ ? service->end_handle
+ : next_characteristic->handle - 1;
+
+ // Stop when we go past the end of the range of handles for this service or
+ // discovery call returns nothing.
+ // discover_next_descriptors() appends to the descriptor_list.
+ while (next_desc_start_handle <= service->end_handle &&
+ next_desc_start_handle < next_desc_end_handle &&
+ discover_next_descriptors(self, characteristic,
+ next_desc_start_handle, next_desc_end_handle)) {
+
+ // Get the most recently discovered descriptor, and then ask for descriptors
+ // whose handles start after that descriptor's handle.
+ const bleio_descriptor_obj_t *descriptor =
+ MP_OBJ_TO_PTR(characteristic->descriptor_list->items[characteristic->descriptor_list->len - 1]);
+ next_desc_start_handle = descriptor->handle + 1;
+ }
+ }
+
+ }
+}
+
+void common_hal_bleio_central_disconnect(bleio_central_obj_t *self) {
+ sd_ble_gap_disconnect(self->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+}
+
+bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self) {
+ return self->conn_handle != BLE_CONN_HANDLE_INVALID;
+}
+
+mp_obj_list_t *common_hal_bleio_central_get_remote_services(bleio_central_obj_t *self) {
+ return self->service_list;
+}
diff --git a/shared-module/bleio/Device.h b/ports/nrf/common-hal/bleio/Central.h
index 8d9ece5ef..ac1670088 100644
--- a/shared-module/bleio/Device.h
+++ b/ports/nrf/common-hal/bleio/Central.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -24,22 +25,21 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_DEVICE_H
-#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_DEVICE_H
+#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CENTRAL_H
+#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CENTRAL_H
#include <stdbool.h>
+#include "py/objlist.h"
+#include "shared-module/bleio/__init__.h"
#include "shared-module/bleio/Address.h"
typedef struct {
mp_obj_base_t base;
- bool is_peripheral;
- mp_obj_t name;
- bleio_address_obj_t address;
+ gatt_role_t gatt_role;
+ volatile bool waiting_to_connect;
volatile uint16_t conn_handle;
- mp_obj_t service_list;
- mp_obj_t notif_handler;
- mp_obj_t conn_handler;
-} bleio_device_obj_t;
+ mp_obj_list_t *service_list;
+} bleio_central_obj_t;
-#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_DEVICE_H
+#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CENTRAL_H
diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c
index 9409b73ce..17417a5e6 100644
--- a/ports/nrf/common-hal/bleio/Characteristic.c
+++ b/ports/nrf/common-hal/bleio/Characteristic.c
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -34,12 +35,8 @@
#include "py/runtime.h"
#include "common-hal/bleio/__init__.h"
#include "common-hal/bleio/Characteristic.h"
-#include "shared-module/bleio/Characteristic.h"
STATIC volatile bleio_characteristic_obj_t *m_read_characteristic;
-STATIC volatile uint8_t m_tx_in_progress;
-// Serialize gattc writes that send a response. This might be done per object?
-STATIC nrf_mutex_t *m_write_mutex;
STATIC uint16_t get_cccd(bleio_characteristic_obj_t *characteristic) {
const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device);
@@ -63,7 +60,7 @@ STATIC uint16_t get_cccd(bleio_characteristic_obj_t *characteristic) {
}
STATIC void gatts_read(bleio_characteristic_obj_t *characteristic) {
- // This might be BLE_CONN_HANDLE_INVALID if we're not conected, but that's OK, because
+ // This might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because
// we can still read and write the local value.
const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device);
@@ -118,24 +115,35 @@ STATIC void gatts_notify_indicate(bleio_characteristic_obj_t *characteristic, mp
.p_data = bufinfo->buf,
};
- while (m_tx_in_progress >= MAX_TX_IN_PROGRESS) {
-#ifdef MICROPY_VM_HOOK_LOOP
- MICROPY_VM_HOOK_LOOP
-#endif
- }
-
const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device);
- m_tx_in_progress++;
- const uint32_t err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params);
- if (err_code != NRF_SUCCESS) {
- m_tx_in_progress--;
+
+ while (1) {
+ const uint32_t err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params);
+ if (err_code == NRF_SUCCESS) {
+ break;
+ }
+ // TX buffer is full
+ // We could wait for an event indicating the write is complete, but just retrying is easier.
+ if (err_code == NRF_ERROR_RESOURCES) {
+ MICROPY_VM_HOOK_LOOP;
+ continue;
+ }
+
+ // Some real error has occurred.
mp_raise_OSError_msg_varg(translate("Failed to notify or indicate attribute value, err 0x%04x"), err_code);
}
}
+STATIC void check_connected(uint16_t conn_handle) {
+ if (conn_handle == BLE_CONN_HANDLE_INVALID) {
+ mp_raise_OSError_msg(translate("Not connected"));
+ }
+}
+
STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) {
const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device);
+ check_connected(conn_handle);
m_read_characteristic = characteristic;
@@ -144,100 +152,79 @@ STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) {
mp_raise_OSError_msg_varg(translate("Failed to read attribute value, err 0x%04x"), err_code);
}
-//
while (m_read_characteristic != NULL) {
-#ifdef MICROPY_VM_HOOK_LOOP
- MICROPY_VM_HOOK_LOOP
-#endif
+ MICROPY_VM_HOOK_LOOP;
}
}
STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device);
- uint32_t err_code;
+ check_connected(conn_handle);
ble_gattc_write_params_t write_params = {
- .flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL,
- .write_op = BLE_GATT_OP_WRITE_REQ,
+ .write_op = characteristic->props.write_no_response ? BLE_GATT_OP_WRITE_CMD : BLE_GATT_OP_WRITE_REQ,
.handle = characteristic->handle,
.p_value = bufinfo->buf,
.len = bufinfo->len,
};
- if (characteristic->props.write_no_response) {
- write_params.write_op = BLE_GATT_OP_WRITE_CMD;
+ while (1) {
+ uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params);
+ if (err_code == NRF_SUCCESS) {
+ break;
+ }
- err_code = sd_mutex_acquire(m_write_mutex);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to acquire mutex, err 0x%04x"), err_code);
+ // Write with response will return NRF_ERROR_BUSY if the response has not been received.
+ // Write without reponse will return NRF_ERROR_RESOURCES if too many writes are pending.
+ if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES) {
+ // We could wait for an event indicating the write is complete, but just retrying is easier.
+ MICROPY_VM_HOOK_LOOP;
+ continue;
}
- }
- err_code = sd_ble_gattc_write(conn_handle, &write_params);
- if (err_code != NRF_SUCCESS) {
+ // Some real error occurred.
mp_raise_OSError_msg_varg(translate("Failed to write attribute value, err 0x%04x"), err_code);
}
- while (sd_mutex_acquire(m_write_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) {
-#ifdef MICROPY_VM_HOOK_LOOP
- MICROPY_VM_HOOK_LOOP
-#endif
- }
-
- err_code = sd_mutex_release(m_write_mutex);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to release mutex, err 0x%04x"), err_code);
- }
}
STATIC void characteristic_on_ble_evt(ble_evt_t *ble_evt, void *param) {
switch (ble_evt->header.evt_id) {
- case BLE_GATTS_EVT_HVN_TX_COMPLETE:
- {
- uint8_t count = ble_evt->evt.gatts_evt.params.hvn_tx_complete.count;
- // Don't underflow the count.
- if (count >= m_tx_in_progress) {
- m_tx_in_progress = 0;
- } else {
- m_tx_in_progress -= count;
- }
- break;
- }
- case BLE_GATTC_EVT_READ_RSP:
- {
- ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp;
- m_read_characteristic->value_data = mp_obj_new_bytearray(response->len, response->data);
- // Flag to busy-wait loop that we've read the characteristic.
- m_read_characteristic = NULL;
- break;
- }
+ // More events may be handled later, so keep this as a switch.
- case BLE_GATTC_EVT_WRITE_RSP:
- // Someone else can write now.
- sd_mutex_release(m_write_mutex);
- break;
+ case BLE_GATTC_EVT_READ_RSP: {
+ ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp;
+ m_read_characteristic->value_data = mp_obj_new_bytearray(response->len, response->data);
+ // Indicate to busy-wait loop that we've read the characteristic.
+ m_read_characteristic = NULL;
+ break;
+ }
- // For debugging.
- default:
- // mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id);
- break;
+ // For debugging.
+ default:
+ // mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id);
+ break;
}
}
-void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props) {
- self->service = NULL;
+void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, mp_obj_list_t *descriptor_list) {
+ self->service = mp_const_none;
self->uuid = uuid;
- self->value_data = NULL;
+ self->value_data = mp_const_none;
self->props = props;
+ self->descriptor_list = descriptor_list;
self->handle = BLE_GATT_HANDLE_INVALID;
ble_drv_add_event_handler(characteristic_on_ble_evt, self);
+}
+mp_obj_list_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self) {
+ return self->descriptor_list;
}
-void common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self) {
+mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self) {
switch (common_hal_bleio_device_get_gatt_role(self->service->device)) {
case GATT_ROLE_CLIENT:
gattc_read(self);
@@ -251,6 +238,8 @@ void common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self)
mp_raise_RuntimeError(translate("bad GATT role"));
break;
}
+
+ return self->value_data;
}
void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) {
@@ -258,30 +247,83 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self,
uint16_t cccd = 0;
switch (common_hal_bleio_device_get_gatt_role(self->service->device)) {
- case GATT_ROLE_SERVER:
- if (self->props.notify || self->props.indicate) {
- cccd = get_cccd(self);
- }
- // It's possible that both notify and indicate are set.
- if (self->props.notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) {
- gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_NOTIFICATION);
- sent = true;
- }
- if (self->props.indicate && (cccd & BLE_GATT_HVX_INDICATION)) {
- gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_INDICATION);
- sent = true;
- }
- if (!sent) {
- gatts_write(self, bufinfo);
+ case GATT_ROLE_SERVER:
+ if (self->props.notify || self->props.indicate) {
+ cccd = get_cccd(self);
+ }
+ // It's possible that both notify and indicate are set.
+ if (self->props.notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) {
+ gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_NOTIFICATION);
+ sent = true;
+ }
+ if (self->props.indicate && (cccd & BLE_GATT_HVX_INDICATION)) {
+ gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_INDICATION);
+ sent = true;
+ }
+ if (!sent) {
+ gatts_write(self, bufinfo);
+ }
+ break;
+
+ case GATT_ROLE_CLIENT:
+ gattc_write(self, bufinfo);
+ break;
+
+ default:
+ mp_raise_RuntimeError(translate("bad GATT role"));
+ break;
+ }
+}
+
+
+bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self) {
+ return self->uuid;
+}
+
+bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties(bleio_characteristic_obj_t *self) {
+ return self->props;
+}
+
+void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate) {
+ if (self->cccd_handle == BLE_GATT_HANDLE_INVALID) {
+ mp_raise_ValueError(translate("No CCCD for this Characteristic"));
+ }
+
+ if (common_hal_bleio_device_get_gatt_role(self->service->device) != GATT_ROLE_CLIENT) {
+ mp_raise_ValueError(translate("Can't set CCCD for local Characteristic"));
+ }
+
+ uint16_t cccd_value =
+ (notify ? BLE_GATT_HVX_NOTIFICATION : 0) |
+ (indicate ? BLE_GATT_HVX_INDICATION : 0);
+
+ const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device);
+ check_connected(conn_handle);
+
+
+ ble_gattc_write_params_t write_params = {
+ .write_op = BLE_GATT_OP_WRITE_REQ,
+ .handle = self->cccd_handle,
+ .p_value = (uint8_t *) &cccd_value,
+ .len = 2,
+ };
+
+ while (1) {
+ uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params);
+ if (err_code == NRF_SUCCESS) {
+ break;
}
- break;
- case GATT_ROLE_CLIENT:
- gattc_write(self, bufinfo);
- break;
+ // Write with response will return NRF_ERROR_BUSY if the response has not been received.
+ // Write without reponse will return NRF_ERROR_RESOURCES if too many writes are pending.
+ if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES) {
+ // We could wait for an event indicating the write is complete, but just retrying is easier.
+ MICROPY_VM_HOOK_LOOP;
+ continue;
+ }
- default:
- mp_raise_RuntimeError(translate("bad GATT role"));
- break;
+ // Some real error occurred.
+ mp_raise_OSError_msg_varg(translate("Failed to write CCCD, err 0x%04x"), err_code);
}
+
}
diff --git a/ports/nrf/common-hal/bleio/Characteristic.h b/ports/nrf/common-hal/bleio/Characteristic.h
index bce1eec1d..7cb227596 100644
--- a/ports/nrf/common-hal/bleio/Characteristic.h
+++ b/ports/nrf/common-hal/bleio/Characteristic.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -24,23 +25,24 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_COMMON_HAL_BLEIO_CHARACTERISTIC_H
-#define MICROPY_INCLUDED_COMMON_HAL_BLEIO_CHARACTERISTIC_H
+#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTIC_H
+#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTIC_H
-#include "shared-module/bleio/Characteristic.h"
-#include "shared-module/bleio/Service.h"
+#include "common-hal/bleio/Service.h"
#include "common-hal/bleio/UUID.h"
+#include "shared-module/bleio/Characteristic.h"
typedef struct {
mp_obj_base_t base;
bleio_service_obj_t *service;
bleio_uuid_obj_t *uuid;
- mp_obj_t value_data;
+ volatile mp_obj_t value_data;
uint16_t handle;
bleio_characteristic_properties_t props;
+ mp_obj_list_t *descriptor_list;
uint16_t user_desc_handle;
uint16_t cccd_handle;
uint16_t sccd_handle;
} bleio_characteristic_obj_t;
-#endif // MICROPY_INCLUDED_COMMON_HAL_BLEIO_CHARACTERISTIC_H
+#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTIC_H
diff --git a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/bleio/CharacteristicBuffer.c
index 19b3b85ea..59eaaf02b 100644
--- a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c
+++ b/ports/nrf/common-hal/bleio/CharacteristicBuffer.c
@@ -40,25 +40,42 @@
#include "common-hal/bleio/__init__.h"
#include "common-hal/bleio/CharacteristicBuffer.h"
+STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *data, uint16_t len) {
+ // Push all the data onto the ring buffer.
+ uint8_t is_nested_critical_region;
+ sd_nvic_critical_region_enter(&is_nested_critical_region);
+ for (size_t i = 0; i < len; i++) {
+ ringbuf_put(&self->ringbuf, data[i]);
+ }
+ sd_nvic_critical_region_exit(is_nested_critical_region);
+}
+
STATIC void characteristic_buffer_on_ble_evt(ble_evt_t *ble_evt, void *param) {
bleio_characteristic_buffer_obj_t *self = (bleio_characteristic_buffer_obj_t *) param;
switch (ble_evt->header.evt_id) {
- case BLE_GATTS_EVT_WRITE: {
- ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write;
- // Event handle must match the handle for my characteristic.
- if (evt_write->handle == self->characteristic->handle) {
- // Push all the data onto the ring buffer.
- uint8_t is_nested_critical_region;
- sd_nvic_critical_region_enter(&is_nested_critical_region);
- for (size_t i = 0; i < evt_write->len; i++) {
- ringbuf_put(&self->ringbuf, evt_write->data[i]);
+ case BLE_GATTS_EVT_WRITE: {
+ // A client wrote to this server characteristic.
+
+ ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write;
+ // Event handle must match the handle for my characteristic.
+ if (evt_write->handle == self->characteristic->handle) {
+ write_to_ringbuf(self, evt_write->data, evt_write->len);
}
- sd_nvic_critical_region_exit(is_nested_critical_region);
break;
}
- }
- }
+ case BLE_GATTC_EVT_HVX: {
+ // A remote service wrote to this characteristic.
+
+ ble_gattc_evt_hvx_t* evt_hvx = &ble_evt->evt.gattc_evt.params.hvx;
+ // Must be a notification, and event handle must match the handle for my characteristic.
+ if (evt_hvx->type == BLE_GATT_HVX_NOTIFICATION &&
+ evt_hvx->handle == self->characteristic->handle) {
+ write_to_ringbuf(self, evt_hvx->data, evt_hvx->len);
+ }
+ break;
+ }
+ }
}
// Assumes that timeout and buffer_size have been validated before call.
@@ -82,13 +99,11 @@ int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_
// Wait for all bytes received or timeout
while ( (ringbuf_count(&self->ringbuf) < len) && (ticks_ms - start_ticks < self->timeout_ms) ) {
-#ifdef MICROPY_VM_HOOK_LOOP
- MICROPY_VM_HOOK_LOOP ;
+ MICROPY_VM_HOOK_LOOP;
// Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) {
return 0;
}
-#endif
}
// Copy received data. Lock out write interrupt handler while copying.
diff --git a/ports/nrf/common-hal/bleio/CharacteristicBuffer.h b/ports/nrf/common-hal/bleio/CharacteristicBuffer.h
index b36f63fec..db8fd2fad 100644
--- a/ports/nrf/common-hal/bleio/CharacteristicBuffer.h
+++ b/ports/nrf/common-hal/bleio/CharacteristicBuffer.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,8 +24,8 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H
-#define MICROPY_INCLUDED_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H
+#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H
+#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H
#include "nrf_soc.h"
@@ -40,4 +40,4 @@ typedef struct {
ringbuf_t ringbuf;
} bleio_characteristic_buffer_obj_t;
-#endif // MICROPY_INCLUDED_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H
+#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H
diff --git a/ports/nrf/common-hal/bleio/Descriptor.c b/ports/nrf/common-hal/bleio/Descriptor.c
index 8282be8f2..005af6eaa 100644
--- a/ports/nrf/common-hal/bleio/Descriptor.c
+++ b/ports/nrf/common-hal/bleio/Descriptor.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -29,7 +30,6 @@
#include "shared-bindings/bleio/UUID.h"
void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid) {
- // TODO: set handle ???
self->uuid = uuid;
}
@@ -37,6 +37,6 @@ mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self) {
return self->handle;
}
-mp_obj_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) {
- return MP_OBJ_FROM_PTR(self->uuid);
+bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) {
+ return self->uuid;
}
diff --git a/ports/nrf/common-hal/bleio/Descriptor.h b/ports/nrf/common-hal/bleio/Descriptor.h
index ee0886c22..b7af6a42f 100644
--- a/ports/nrf/common-hal/bleio/Descriptor.h
+++ b/ports/nrf/common-hal/bleio/Descriptor.h
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -29,11 +30,13 @@
#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H
#include "py/obj.h"
+#include "common-hal/bleio/Characteristic.h"
#include "common-hal/bleio/UUID.h"
typedef struct {
mp_obj_base_t base;
uint16_t handle;
+ bleio_characteristic_obj_t *characteristic;
bleio_uuid_obj_t *uuid;
} bleio_descriptor_obj_t;
diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c
deleted file mode 100644
index 5f625829e..000000000
--- a/ports/nrf/common-hal/bleio/Device.c
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 Artur Pacholec
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include "ble.h"
-#include "ble_drv.h"
-#include "ble_hci.h"
-#include "nrf_soc.h"
-#include "py/objstr.h"
-#include "py/runtime.h"
-#include "shared-bindings/bleio/Adapter.h"
-#include "shared-bindings/bleio/Characteristic.h"
-#include "shared-bindings/bleio/Device.h"
-#include "shared-bindings/bleio/Service.h"
-#include "shared-bindings/bleio/UUID.h"
-
-#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS)
-#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(300, UNIT_0_625_MS)
-#define BLE_SLAVE_LATENCY 0
-#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS)
-
-#define BLE_ADV_LENGTH_FIELD_SIZE 1
-#define BLE_ADV_AD_TYPE_FIELD_SIZE 1
-#define BLE_AD_TYPE_FLAGS_DATA_SIZE 1
-
-#ifndef BLE_GAP_ADV_MAX_SIZE
-#define BLE_GAP_ADV_MAX_SIZE 31
-#endif
-
-static bleio_service_obj_t *m_char_discovery_service;
-static volatile bool m_discovery_successful;
-static nrf_mutex_t *m_discovery_mutex;
-
-#if (BLUETOOTH_SD == 140)
-static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
-
-static uint8_t m_scan_buffer_data[BLE_GAP_SCAN_BUFFER_MIN];
-
-static ble_data_t m_scan_buffer = {
- .p_data = m_scan_buffer_data,
- .len = BLE_GAP_SCAN_BUFFER_MIN
-};
-#endif
-
-STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connectable, mp_buffer_info_t *raw_data) {
- common_hal_bleio_adapter_set_enabled(true);
-
- uint8_t adv_data[BLE_GAP_ADV_MAX_SIZE];
- uint8_t byte_pos = 0;
- uint32_t err_code;
-
-#define ADD_FIELD(field, len) \
- do { \
- if (byte_pos + (len) > BLE_GAP_ADV_MAX_SIZE) { \
- mp_raise_ValueError(translate("Data too large for the advertisement packet")); \
- } \
- adv_data[byte_pos] = (field); \
- byte_pos += (len); \
- } while (0)
-
- GET_STR_DATA_LEN(device->name, name_data, name_len);
- if (name_len > 0) {
- ble_gap_conn_sec_mode_t sec_mode;
- BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
-
- err_code = sd_ble_gap_device_name_set(&sec_mode, name_data, name_len);
- if (err_code != NRF_SUCCESS) {
- return err_code;
- }
-
- // TODO: Shorten if too long
-
- ADD_FIELD(BLE_ADV_AD_TYPE_FIELD_SIZE + name_len, BLE_ADV_LENGTH_FIELD_SIZE);
- ADD_FIELD(BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, BLE_ADV_AD_TYPE_FIELD_SIZE);
-
- memcpy(&adv_data[byte_pos], name_data, name_len);
- byte_pos += name_len;
- }
-
- // set flags, default to disc mode
- if (raw_data->len == 0) {
- ADD_FIELD(BLE_ADV_AD_TYPE_FIELD_SIZE + BLE_AD_TYPE_FLAGS_DATA_SIZE, BLE_ADV_LENGTH_FIELD_SIZE);
- ADD_FIELD(BLE_GAP_AD_TYPE_FLAGS, BLE_AD_TYPE_FLAGS_DATA_SIZE);
- ADD_FIELD(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE, BLE_AD_TYPE_FLAGS_DATA_SIZE);
- } else {
- if (byte_pos + raw_data->len > BLE_GAP_ADV_MAX_SIZE) {
- mp_raise_ValueError(translate("Data too large for the advertisement packet"));
- }
-
- memcpy(&adv_data[byte_pos], raw_data->buf, raw_data->len);
- byte_pos += raw_data->len;
- }
-
- const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(device->service_list);
- if (service_list->len > 0) {
- bool has_128bit_services = false;
- bool has_16bit_services = false;
-
- for (size_t i = 0; i < service_list->len; ++i) {
- const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]);
-
- if (service->is_secondary) {
- continue;
- }
-
- switch (common_hal_bleio_uuid_get_size(service->uuid)) {
- case 16:
- has_16bit_services = true;
- break;
- case 128:
- has_128bit_services = true;
- break;
- }
- }
-
- if (has_16bit_services) {
- const uint8_t size_byte_pos = byte_pos;
- uint8_t uuid_total_size = 0;
-
- // skip length byte for now, apply total length post calculation
- byte_pos += BLE_ADV_LENGTH_FIELD_SIZE;
-
- ADD_FIELD(BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE, BLE_ADV_AD_TYPE_FIELD_SIZE);
-
- for (size_t i = 0; i < service_list->len; ++i) {
- const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]);
- uint8_t encoded_size = 0;
-
- if (common_hal_bleio_uuid_get_size(service->uuid) != 16 || service->is_secondary) {
- continue;
- }
-
- ble_uuid_t uuid;
- bleio_uuid_convert_to_nrf_ble_uuid(service->uuid, &uuid);
-
- err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]);
- if (err_code != NRF_SUCCESS) {
- return err_code;
- }
-
- uuid_total_size += encoded_size;
- byte_pos += encoded_size;
- }
-
- adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size);
- }
-
- if (has_128bit_services) {
- const uint8_t size_byte_pos = byte_pos;
- uint8_t uuid_total_size = 0;
-
- // skip length byte for now, apply total length post calculation
- byte_pos += BLE_ADV_LENGTH_FIELD_SIZE;
-
- ADD_FIELD(BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE, BLE_ADV_AD_TYPE_FIELD_SIZE);
-
- for (size_t i = 0; i < service_list->len; ++i) {
- const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]);
- uint8_t encoded_size = 0;
-
- if (common_hal_bleio_uuid_get_size(service->uuid) != 16 || service->is_secondary) {
- continue;
- }
-
- ble_uuid_t uuid;
- bleio_uuid_convert_to_nrf_ble_uuid(service->uuid, &uuid);
-
- err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]);
- if (err_code != NRF_SUCCESS) {
- return err_code;
- }
-
- uuid_total_size += encoded_size;
- byte_pos += encoded_size;
- }
-
- adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size);
- }
- }
-
-#if (BLUETOOTH_SD == 132)
- err_code = sd_ble_gap_adv_data_set(adv_data, byte_pos, NULL, 0);
- if (err_code != NRF_SUCCESS) {
- return err_code;
- }
-#endif
-
- static ble_gap_adv_params_t m_adv_params = {
- .interval = MSEC_TO_UNITS(100, UNIT_0_625_MS),
-#if (BLUETOOTH_SD == 140)
- .properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED,
- .duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED,
- .filter_policy = BLE_GAP_ADV_FP_ANY,
- .primary_phy = BLE_GAP_PHY_1MBPS,
-#else
- .type = BLE_GAP_ADV_TYPE_ADV_IND,
- .fp = BLE_GAP_ADV_FP_ANY,
-#endif
- };
-
- if (!connectable) {
-#if (BLUETOOTH_SD == 140)
- m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
-#else
- m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND;
-#endif
- }
-
- common_hal_bleio_device_stop_advertising(device);
-
-#if (BLUETOOTH_SD == 140)
- const ble_gap_adv_data_t ble_gap_adv_data = {
- .adv_data.p_data = adv_data,
- .adv_data.len = byte_pos,
- };
-
- err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &ble_gap_adv_data, &m_adv_params);
- if (err_code != NRF_SUCCESS) {
- return err_code;
- }
-
- err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_CONN_CFG_TAG_CUSTOM);
-#elif (BLUETOOTH_SD == 132 && BLE_API_VERSION == 4)
- err_code = sd_ble_gap_adv_start(&m_adv_params, BLE_CONN_CFG_TAG_CUSTOM);
-#else
- err_code = sd_ble_gap_adv_start(&m_adv_params);
-#endif
-
- return err_code;
-}
-
-STATIC bool discover_services(bleio_device_obj_t *device, uint16_t start_handle) {
- m_discovery_successful = false;
-
- uint32_t err_code = sd_ble_gattc_primary_services_discover(device->conn_handle, start_handle, NULL);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to discover services"));
- }
-
- // Serialize discovery.
- err_code = sd_mutex_acquire(m_discovery_mutex);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to acquire mutex"));
- }
-
- // Wait for someone else to release m_discovery_mutex.
- while (sd_mutex_acquire(m_discovery_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) {
-#ifdef MICROPY_VM_HOOK_LOOP
- MICROPY_VM_HOOK_LOOP
-#endif
- }
-
- err_code = sd_mutex_release(m_discovery_mutex);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to release mutex"));
- }
-
- return m_discovery_successful;
-}
-
-STATIC bool discover_characteristics(bleio_device_obj_t *device, bleio_service_obj_t *service, uint16_t start_handle) {
- m_char_discovery_service = service;
-
- ble_gattc_handle_range_t handle_range;
- handle_range.start_handle = start_handle;
- handle_range.end_handle = service->end_handle;
-
- m_discovery_successful = false;
-
- uint32_t err_code = sd_ble_gattc_characteristics_discover(device->conn_handle, &handle_range);
- if (err_code != NRF_SUCCESS) {
- return false;
- }
-
- err_code = sd_mutex_acquire(m_discovery_mutex);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to acquire mutex"));
- }
-
- while (sd_mutex_acquire(m_discovery_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) {
-#ifdef MICROPY_VM_HOOK_LOOP
- MICROPY_VM_HOOK_LOOP
-#endif
- }
-
- err_code = sd_mutex_release(m_discovery_mutex);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to release mutex"));
- }
-
- return m_discovery_successful;
-}
-
-STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, bleio_device_obj_t *device) {
- for (size_t i = 0; i < response->count; ++i) {
- ble_gattc_service_t *gattc_service = &response->services[i];
-
- bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t);
- service->base.type = &bleio_service_type;
- service->device = device;
- service->char_list = mp_obj_new_list(0, NULL);
- service->start_handle = gattc_service->handle_range.start_handle;
- service->end_handle = gattc_service->handle_range.end_handle;
- service->handle = gattc_service->handle_range.start_handle;
-
- bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t);
- bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid);
- service->uuid = uuid;
-
- mp_obj_list_append(device->service_list, service);
- }
-
- if (response->count > 0) {
- m_discovery_successful = true;
- }
-
- const uint32_t err_code = sd_mutex_release(m_discovery_mutex);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to release mutex"));
- }
-}
-
-STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio_device_obj_t *device) {
- for (size_t i = 0; i < response->count; ++i) {
- ble_gattc_char_t *gattc_char = &response->chars[i];
-
- bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t);
- characteristic->base.type = &bleio_characteristic_type;
-
- bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t);
- uuid->base.type = &bleio_uuid_type;
- bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid);
- characteristic->uuid = uuid;
-
- characteristic->props.broadcast = gattc_char->char_props.broadcast;
- characteristic->props.indicate = gattc_char->char_props.indicate;
- characteristic->props.notify = gattc_char->char_props.notify;
- characteristic->props.read = gattc_char->char_props.read;
- characteristic->props.write = gattc_char->char_props.write;
- characteristic->props.write_no_response = gattc_char->char_props.write_wo_resp;
- characteristic->handle = gattc_char->handle_value;
- characteristic->service = m_char_discovery_service;
-
- mp_obj_list_append(m_char_discovery_service->char_list, MP_OBJ_FROM_PTR(characteristic));
- }
-
- if (response->count > 0) {
- m_discovery_successful = true;
- }
-
- const uint32_t err_code = sd_mutex_release(m_discovery_mutex);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to release mutex"));
- }
-}
-
-STATIC void on_adv_report(ble_gap_evt_adv_report_t *report, bleio_device_obj_t *device) {
- uint32_t err_code;
-
- if (memcmp(report->peer_addr.addr, device->address.value, BLEIO_ADDRESS_BYTES) != 0) {
-#if (BLUETOOTH_SD == 140)
- err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to continue scanning"));
- }
-#endif
- return;
- }
-
- ble_gap_scan_params_t scan_params = {
- .active = 1,
- .interval = MSEC_TO_UNITS(100, UNIT_0_625_MS),
- .window = MSEC_TO_UNITS(100, UNIT_0_625_MS),
- };
-
- ble_gap_addr_t addr;
- memset(&addr, 0, sizeof(addr));
-
- addr.addr_type = report->peer_addr.addr_type;
- memcpy(addr.addr, report->peer_addr.addr, BLEIO_ADDRESS_BYTES);
-
- ble_gap_conn_params_t conn_params = {
- .min_conn_interval = BLE_MIN_CONN_INTERVAL,
- .max_conn_interval = BLE_MAX_CONN_INTERVAL,
- .conn_sup_timeout = BLE_CONN_SUP_TIMEOUT,
- .slave_latency = BLE_SLAVE_LATENCY,
- };
-
-#if (BLE_API_VERSION == 2)
- err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params);
-#else
- err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_CUSTOM);
-#endif
-
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to connect:"));
- }
-}
-
-STATIC void on_ble_evt(ble_evt_t *ble_evt, void *device_in) {
- bleio_device_obj_t *device = (bleio_device_obj_t*)device_in;
-
- switch (ble_evt->header.evt_id) {
- case BLE_GAP_EVT_CONNECTED:
- {
- ble_gap_conn_params_t conn_params;
- device->conn_handle = ble_evt->evt.gap_evt.conn_handle;
-
- sd_ble_gap_ppcp_get(&conn_params);
- sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params);
- break;
- }
-
- case BLE_GAP_EVT_DISCONNECTED:
- device->conn_handle = BLE_CONN_HANDLE_INVALID;
- break;
-
- case BLE_GAP_EVT_ADV_REPORT:
- on_adv_report(&ble_evt->evt.gap_evt.params.adv_report, device);
- break;
-
- case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
- on_primary_srv_discovery_rsp(&ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp, device);
- break;
-
- case BLE_GATTC_EVT_CHAR_DISC_RSP:
- on_char_discovery_rsp(&ble_evt->evt.gattc_evt.params.char_disc_rsp, device);
- break;
-
- case BLE_GATTS_EVT_SYS_ATTR_MISSING:
- sd_ble_gatts_sys_attr_set(ble_evt->evt.gatts_evt.conn_handle, NULL, 0, 0);
- break;
-
-#if (BLE_API_VERSION == 4)
- case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
- sd_ble_gatts_exchange_mtu_reply(device->conn_handle, BLE_GATT_ATT_MTU_DEFAULT);
- break;
-#endif
-
- case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
- sd_ble_gap_sec_params_reply(device->conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
- break;
-
- case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
- {
- ble_gap_evt_conn_param_update_request_t *request = &ble_evt->evt.gap_evt.params.conn_param_update_request;
- sd_ble_gap_conn_param_update(device->conn_handle, &request->conn_params);
- break;
- }
- }
-}
-
-void common_hal_bleio_device_add_service(bleio_device_obj_t *device, bleio_service_obj_t *service) {
- ble_uuid_t uuid;
- bleio_uuid_convert_to_nrf_ble_uuid(service->uuid, &uuid);
-
- uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY;
- if (service->is_secondary) {
- service_type = BLE_GATTS_SRVC_TYPE_SECONDARY;
- }
-
- common_hal_bleio_adapter_set_enabled(true);
-
- const uint32_t err_code = sd_ble_gatts_service_add(service_type, &uuid, &service->handle);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to add service"));
- }
-
- const mp_obj_list_t *char_list = MP_OBJ_TO_PTR(service->char_list);
- for (size_t i = 0; i < char_list->len; ++i) {
- bleio_characteristic_obj_t *characteristic = char_list->items[i];
- common_hal_bleio_service_add_characteristic(service, characteristic);
- }
-}
-
-void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bool connectable, mp_buffer_info_t *raw_data) {
- if (connectable) {
- ble_drv_add_event_handler(on_ble_evt, device);
- }
-
- const uint32_t err_code = set_advertisement_data(device, connectable, raw_data);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to start advertising"));
- }
-}
-
-void common_hal_bleio_device_stop_advertising(bleio_device_obj_t *device) {
- uint32_t err_code;
-
-#if (BLUETOOTH_SD == 140)
- if (m_adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET)
- return;
-
- err_code = sd_ble_gap_adv_stop(m_adv_handle);
-#else
- err_code = sd_ble_gap_adv_stop();
-#endif
-
- if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) {
- mp_raise_OSError_msg(translate("Failed to stop advertising"));
- }
-}
-
-void common_hal_bleio_device_connect(bleio_device_obj_t *device) {
- ble_drv_add_event_handler(on_ble_evt, device);
-
- ble_gap_scan_params_t scan_params = {
- .interval = MSEC_TO_UNITS(100, UNIT_0_625_MS),
- .window = MSEC_TO_UNITS(100, UNIT_0_625_MS),
-#if (BLUETOOTH_SD == 140)
- .scan_phys = BLE_GAP_PHY_1MBPS,
-#endif
- };
-
- common_hal_bleio_adapter_set_enabled(true);
-
- uint32_t err_code;
-#if (BLUETOOTH_SD == 140)
- err_code = sd_ble_gap_scan_start(&scan_params, &m_scan_buffer);
-#else
- err_code = sd_ble_gap_scan_start(&scan_params);
-#endif
-
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to start scanning"));
- }
-
- while (device->conn_handle == BLE_CONN_HANDLE_INVALID) {
-#ifdef MICROPY_VM_HOOK_LOOP
- MICROPY_VM_HOOK_LOOP
-#endif
- }
-
- // TODO: read name
-
- if (m_discovery_mutex == NULL) {
- m_discovery_mutex = m_new_ll(nrf_mutex_t, 1);
-
- err_code = sd_mutex_new(m_discovery_mutex);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to create mutex"));
- }
- }
-
- // find services
- bool found_service = discover_services(device, BLE_GATT_HANDLE_START);
- while (found_service) {
- const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(device->service_list);
- const bleio_service_obj_t *service = service_list->items[service_list->len - 1];
-
- found_service = discover_services(device, service->end_handle + 1);
- }
-
- // find characteristics in each service
- const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(device->service_list);
- for (size_t i = 0; i < service_list->len; ++i) {
- bleio_service_obj_t *service = service_list->items[i];
-
- bool found_char = discover_characteristics(device, service, service->start_handle);
- while (found_char) {
- const mp_obj_list_t *char_list = MP_OBJ_TO_PTR(service->char_list);
- const bleio_characteristic_obj_t *characteristic = char_list->items[char_list->len - 1];
-
- const uint16_t next_handle = characteristic->handle + 1;
- if (next_handle >= service->end_handle) {
- break;
- }
-
- found_char = discover_characteristics(device, service, next_handle);
- }
- }
-}
-
-void common_hal_bleio_device_disconnect(bleio_device_obj_t *device) {
- sd_ble_gap_disconnect(device->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
-}
diff --git a/ports/nrf/common-hal/bleio/Peripheral.c b/ports/nrf/common-hal/bleio/Peripheral.c
index 0a5a8069d..608bd1342 100644
--- a/ports/nrf/common-hal/bleio/Peripheral.c
+++ b/ports/nrf/common-hal/bleio/Peripheral.c
@@ -3,8 +3,8 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2018 Artur Pacholec
* Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -32,6 +32,8 @@
#include "ble_drv.h"
#include "ble_hci.h"
#include "nrf_soc.h"
+#include "py/gc.h"
+#include "py/objlist.h"
#include "py/objstr.h"
#include "py/runtime.h"
#include "shared-bindings/bleio/Adapter.h"
@@ -39,6 +41,7 @@
#include "shared-bindings/bleio/Peripheral.h"
#include "shared-bindings/bleio/Service.h"
#include "shared-bindings/bleio/UUID.h"
+#include "common-hal/bleio/Service.h"
#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS)
#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(300, UNIT_0_625_MS)
@@ -49,261 +52,96 @@
#define BLE_ADV_AD_TYPE_FIELD_SIZE 1
#define BLE_AD_TYPE_FLAGS_DATA_SIZE 1
-static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
-
-STATIC void check_data_fit(size_t pos, size_t data_len) {
- if (pos + data_len >= BLE_GAP_ADV_SET_DATA_SIZE_MAX) {
+STATIC void check_data_fit(size_t data_len) {
+ if (data_len > BLE_GAP_ADV_SET_DATA_SIZE_MAX) {
mp_raise_ValueError(translate("Data too large for advertisement packet"));
}
}
-STATIC uint32_t add_services_to_advertisement(bleio_peripheral_obj_t *self, size_t* adv_data_pos_p, size_t uuid_len) {
- uint32_t uuids_total_size = 0;
- const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list);
- uint32_t err_code = NRF_SUCCESS;
-
- check_data_fit(*adv_data_pos_p, 1 + 1);
-
- // Remember where length byte is; fill in later when we know the size.
- const size_t length_pos = *adv_data_pos_p;
- (*adv_data_pos_p)++;
-
- self->adv_data[(*adv_data_pos_p)++] = (uuid_len == 16)
- ? BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE
- : BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE;
-
- for (size_t i = 0; i < service_list->len; ++i) {
- const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]);
- uint8_t encoded_size = 0;
-
- // Skip services of the wrong length and secondary services.
- if (common_hal_bleio_uuid_get_size(service->uuid) != uuid_len || service->is_secondary) {
- continue;
- }
-
- ble_uuid_t uuid;
- bleio_uuid_convert_to_nrf_ble_uuid(service->uuid, &uuid);
-
- err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &(self->adv_data[*adv_data_pos_p]));
- if (err_code != NRF_SUCCESS) {
- return err_code;
- }
-
- check_data_fit(*adv_data_pos_p, encoded_size);
- uuids_total_size += encoded_size;
- (*adv_data_pos_p) += encoded_size;
- }
-
- self->adv_data[length_pos] = 1 + uuids_total_size; // 1 for the field type.
- return err_code;
-}
-
-
-
-// if raw_data is a zero-length buffer, generate an advertising packet that advertises the
-// services passed in when this Peripheral was created.
-// If raw_data contains some bytes, use those bytes as the advertising packet.
-// TODO: Generate the advertising packet in Python, not here.
-STATIC uint32_t set_advertisement_data(bleio_peripheral_obj_t *self, bool connectable, mp_buffer_info_t *raw_data) {
- common_hal_bleio_adapter_set_enabled(true);
-
- size_t adv_data_pos = 0;
- uint32_t err_code;
-
- GET_STR_DATA_LEN(self->name, name_data, name_len);
- if (name_len > 0) {
- ble_gap_conn_sec_mode_t sec_mode;
- BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
-
- // We'll add the name after everything else, shortening it if necessary.
- err_code = sd_ble_gap_device_name_set(&sec_mode, name_data, name_len);
- if (err_code != NRF_SUCCESS) {
- return err_code;
- }
- }
-
- if (raw_data->len != 0) {
- // User-supplied advertising packet.
- check_data_fit(adv_data_pos, raw_data->len);
- memcpy(&(self->adv_data[adv_data_pos]), raw_data->buf, raw_data->len);
- adv_data_pos += raw_data->len;
- } else {
- // Build up advertising packet.
- check_data_fit(adv_data_pos, 1 + 1 + 1);
- self->adv_data[adv_data_pos++] = 2;
- self->adv_data[adv_data_pos++] = BLE_GAP_AD_TYPE_FLAGS;
- self->adv_data[adv_data_pos++] = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
-
- // The 16-bit ids and 128-bit ids are grouped together by length, so find it whether we have
- // 16 and/or 128-bit service UUIDs.
-
- const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list);
- if (service_list->len > 0) {
- bool has_128bit_services = false;
- bool has_16bit_services = false;
-
- for (size_t i = 0; i < service_list->len; ++i) {
- const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]);
-
- if (service->is_secondary) {
- continue;
- }
-
- switch (common_hal_bleio_uuid_get_size(service->uuid)) {
- case 16:
- has_16bit_services = true;
- break;
- case 128:
- has_128bit_services = true;
- break;
- }
- }
-
- // Add 16-bit service UUID's in a group, then 128-bit service UUID's.
-
- if (has_16bit_services) {
- err_code = add_services_to_advertisement(self, &adv_data_pos, 16);
- if (err_code != NRF_SUCCESS) {
- return err_code;
- }
- }
-
- if (has_128bit_services) {
- err_code = add_services_to_advertisement(self, &adv_data_pos, 128);
- if (err_code != NRF_SUCCESS) {
- return err_code;
- }
- }
- }
-
- // Always include TX power.
- check_data_fit(adv_data_pos, 1 + 1 + 1);
- self->adv_data[adv_data_pos++] = 1 + 1;
- self->adv_data[adv_data_pos++] = BLE_GAP_AD_TYPE_TX_POWER_LEVEL;
- self->adv_data[adv_data_pos++] = 0; // TODO - allow power level to be set later.
-
- // We need room for at least a one-character name.
- check_data_fit(adv_data_pos, 1 + 1 + 1);
-
- // How big a name can we fit?
- size_t bytes_left = BLE_GAP_ADV_SET_DATA_SIZE_MAX - adv_data_pos - 1 - 1;
- size_t partial_name_len = MIN(bytes_left, name_len);
- self->adv_data[adv_data_pos++] = 1 + partial_name_len;
- self->adv_data[adv_data_pos++] = (partial_name_len == name_len)
- ? BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME
- : BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME;
- memcpy(&(self->adv_data[adv_data_pos]), name_data, partial_name_len);
- adv_data_pos += partial_name_len;
- } // end of advertising packet construction
-
- static ble_gap_adv_params_t m_adv_params = {
- .interval = MSEC_TO_UNITS(1000, UNIT_0_625_MS),
- .properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED,
- .duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED,
- .filter_policy = BLE_GAP_ADV_FP_ANY,
- .primary_phy = BLE_GAP_PHY_1MBPS,
- };
-
- if (!connectable) {
- m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
- }
-
- common_hal_bleio_peripheral_stop_advertising(self);
-
- const ble_gap_adv_data_t ble_gap_adv_data = {
- .adv_data.p_data = self->adv_data,
- .adv_data.len = adv_data_pos,
- };
-
- err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &ble_gap_adv_data, &m_adv_params);
- if (err_code != NRF_SUCCESS) {
- return err_code;
- }
-
- err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_CONN_CFG_TAG_CUSTOM);
-
- return err_code;
-}
-
STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
bleio_peripheral_obj_t *self = (bleio_peripheral_obj_t*)self_in;
switch (ble_evt->header.evt_id) {
- case BLE_GAP_EVT_CONNECTED: {
- // Central has connected.
- ble_gap_conn_params_t conn_params;
- self->conn_handle = ble_evt->evt.gap_evt.conn_handle;
- sd_ble_gap_ppcp_get(&conn_params);
- sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params);
- break;
- }
+ case BLE_GAP_EVT_CONNECTED: {
+ // Central has connected.
+ ble_gap_conn_params_t conn_params;
+ self->conn_handle = ble_evt->evt.gap_evt.conn_handle;
+ sd_ble_gap_ppcp_get(&conn_params);
+ sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params);
+ break;
+ }
- case BLE_GAP_EVT_DISCONNECTED:
- // Central has disconnected.
- self->conn_handle = BLE_CONN_HANDLE_INVALID;
- break;
-
- case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
- ble_gap_phys_t const phys = {
- .rx_phys = BLE_GAP_PHY_AUTO,
- .tx_phys = BLE_GAP_PHY_AUTO,
- };
- sd_ble_gap_phy_update(ble_evt->evt.gap_evt.conn_handle, &phys);
- break;
- }
+ case BLE_GAP_EVT_DISCONNECTED:
+ // Central has disconnected.
+ self->conn_handle = BLE_CONN_HANDLE_INVALID;
+ break;
+
+ case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
+ ble_gap_phys_t const phys = {
+ .rx_phys = BLE_GAP_PHY_AUTO,
+ .tx_phys = BLE_GAP_PHY_AUTO,
+ };
+ sd_ble_gap_phy_update(ble_evt->evt.gap_evt.conn_handle, &phys);
+ break;
+ }
- case BLE_GAP_EVT_ADV_SET_TERMINATED:
- // Someday may handle timeouts or limit reached.
- break;
+ case BLE_GAP_EVT_ADV_SET_TERMINATED:
+ // Someday may handle timeouts or limit reached.
+ break;
- case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
- sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
- break;
+ case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
+ sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
+ break;
- case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: {
- ble_gap_evt_conn_param_update_request_t *request = &ble_evt->evt.gap_evt.params.conn_param_update_request;
- sd_ble_gap_conn_param_update(self->conn_handle, &request->conn_params);
- break;
- }
+ case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: {
+ ble_gap_evt_conn_param_update_request_t *request =
+ &ble_evt->evt.gap_evt.params.conn_param_update_request;
+ sd_ble_gap_conn_param_update(self->conn_handle, &request->conn_params);
+ break;
+ }
- case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
- sd_ble_gap_data_length_update(self->conn_handle, NULL, NULL);
- break;
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
+ sd_ble_gap_data_length_update(self->conn_handle, NULL, NULL);
+ break;
- case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: {
- sd_ble_gatts_exchange_mtu_reply(self->conn_handle, BLE_GATT_ATT_MTU_DEFAULT);
- break;
- }
+ case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: {
+ sd_ble_gatts_exchange_mtu_reply(self->conn_handle, BLE_GATT_ATT_MTU_DEFAULT);
+ break;
+ }
- case BLE_GATTS_EVT_SYS_ATTR_MISSING:
- sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
- break;
+ case BLE_GATTS_EVT_SYS_ATTR_MISSING:
+ sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
+ break;
- default:
- // For debugging.
- // mp_printf(&mp_plat_print, "Unhandled peripheral event: 0x%04x\n", ble_evt->header.evt_id);
- break;
+ default:
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Unhandled peripheral event: 0x%04x\n", ble_evt->header.evt_id);
+ break;
}
}
+void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_list_t *service_list, mp_obj_t name) {
+ common_hal_bleio_adapter_set_enabled(true);
-void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self) {
- common_hal_bleio_adapter_set_enabled(true); // TODO -- Do this somewhere else maybe bleio __init__
+ self->service_list = service_list;
+ self->name = name;
self->gatt_role = GATT_ROLE_SERVER;
self->conn_handle = BLE_CONN_HANDLE_INVALID;
+ self->adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
// Add all the services.
- mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list);
for (size_t service_idx = 0; service_idx < service_list->len; ++service_idx) {
bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[service_idx]);
+ service->device = MP_OBJ_FROM_PTR(self);
+
ble_uuid_t uuid;
bleio_uuid_convert_to_nrf_ble_uuid(service->uuid, &uuid);
uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY;
- if (service->is_secondary) {
+ if (common_hal_bleio_service_get_is_secondary(service)) {
service_type = BLE_GATTS_SRVC_TYPE_SECONDARY;
}
@@ -318,29 +156,94 @@ void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self) {
}
+mp_obj_list_t *common_hal_bleio_peripheral_get_service_list(bleio_peripheral_obj_t *self) {
+ return self->service_list;
+}
+
bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self) {
return self->conn_handle != BLE_CONN_HANDLE_INVALID;
}
-void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *self, bool connectable, mp_buffer_info_t *raw_data) {
+mp_obj_t common_hal_bleio_peripheral_get_name(bleio_peripheral_obj_t *self) {
+ return self->name;
+}
+
+void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *self, bool connectable, mp_float_t interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo) {
+
+ // interval value has already been validated.
+
if (connectable) {
ble_drv_add_event_handler(peripheral_on_ble_evt, self);
}
- const uint32_t err_code = set_advertisement_data(self, connectable, raw_data);
+ common_hal_bleio_adapter_set_enabled(true);
+
+ uint32_t err_code;
+
+ GET_STR_DATA_LEN(self->name, name_data, name_len);
+ if (name_len > 0) {
+ ble_gap_conn_sec_mode_t sec_mode;
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
+
+ err_code = sd_ble_gap_device_name_set(&sec_mode, name_data, name_len);
+ if (err_code != NRF_SUCCESS) {
+ mp_raise_OSError_msg_varg(translate("Failed to set device name, err 0x%04x"), err_code);
+
+ }
+ }
+
+ check_data_fit(advertising_data_bufinfo->len);
+ // The advertising data buffers must not move, because the SoftDevice depends on them.
+ // So make them long-lived.
+ self->advertising_data = (uint8_t *) gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_MAX * sizeof(uint8_t), false, true);
+ memcpy(self->advertising_data, advertising_data_bufinfo->buf, advertising_data_bufinfo->len);
+
+ check_data_fit(scan_response_data_bufinfo->len);
+ self->scan_response_data = (uint8_t *) gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_MAX * sizeof(uint8_t), false, true);
+ memcpy(self->scan_response_data, scan_response_data_bufinfo->buf, scan_response_data_bufinfo->len);
+
+
+ ble_gap_adv_params_t adv_params = {
+ .interval = SEC_TO_UNITS(interval, UNIT_0_625_MS),
+ .properties.type = connectable ? BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED
+ : BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED,
+ .duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED,
+ .filter_policy = BLE_GAP_ADV_FP_ANY,
+ .primary_phy = BLE_GAP_PHY_1MBPS,
+ };
+
+ common_hal_bleio_peripheral_stop_advertising(self);
+
+ const ble_gap_adv_data_t ble_gap_adv_data = {
+ .adv_data.p_data = self->advertising_data,
+ .adv_data.len = advertising_data_bufinfo->len,
+ .scan_rsp_data.p_data = scan_response_data_bufinfo-> len > 0 ? self->scan_response_data : NULL,
+ .scan_rsp_data.len = scan_response_data_bufinfo->len,
+ };
+
+ err_code = sd_ble_gap_adv_set_configure(&self->adv_handle, &ble_gap_adv_data, &adv_params);
+ if (err_code != NRF_SUCCESS) {
+ mp_raise_OSError_msg_varg(translate("Failed to configure advertising, err 0x%04x"), err_code);
+ }
+
+ err_code = sd_ble_gap_adv_start(self->adv_handle, BLE_CONN_CFG_TAG_CUSTOM);
+
if (err_code != NRF_SUCCESS) {
mp_raise_OSError_msg_varg(translate("Failed to start advertising, err 0x%04x"), err_code);
}
}
void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *self) {
-
- if (m_adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET)
+ if (self->adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET)
return;
- const uint32_t err_code = sd_ble_gap_adv_stop(m_adv_handle);
+ const uint32_t err_code = sd_ble_gap_adv_stop(self->adv_handle);
if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) {
mp_raise_OSError_msg_varg(translate("Failed to stop advertising, err 0x%04x"), err_code);
}
}
+
+void common_hal_bleio_peripheral_disconnect(bleio_peripheral_obj_t *self) {
+ sd_ble_gap_disconnect(self->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+}
diff --git a/ports/nrf/common-hal/bleio/Peripheral.h b/ports/nrf/common-hal/bleio/Peripheral.h
index b255fe9f4..2a1251715 100644
--- a/ports/nrf/common-hal/bleio/Peripheral.h
+++ b/ports/nrf/common-hal/bleio/Peripheral.h
@@ -3,8 +3,8 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
- * Copyright (c) 2018 Dan Halbert for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -25,13 +25,16 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_COMMON_HAL_BLEIO_PERIPHERAL_H
-#define MICROPY_INCLUDED_COMMON_HAL_BLEIO_PERIPHERAL_H
+#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PERIPHERAL_H
+#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PERIPHERAL_H
#include <stdbool.h>
#include "ble.h"
+#include "py/obj.h"
+#include "py/objlist.h"
+
#include "shared-module/bleio/__init__.h"
#include "shared-module/bleio/Address.h"
@@ -40,14 +43,14 @@ typedef struct {
mp_obj_t name;
gatt_role_t gatt_role;
volatile uint16_t conn_handle;
- mp_obj_t service_list;
- mp_obj_t notif_handler;
- mp_obj_t conn_handler;
- // The advertising data buffer is held by us, not by the SD, so we must
- // maintain it and not change it. If we need to change its contents during advertising,
+ mp_obj_list_t *service_list;
+ // The advertising data and scan response buffers are held by us, not by the SD, so we must
+ // maintain them and not change it. If we need to change the contents during advertising,
// there are tricks to get the SD to notice (see DevZone - TBS).
- uint8_t adv_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX];
+ uint8_t* advertising_data;
+ uint8_t* scan_response_data;
+ uint8_t adv_handle;
} bleio_peripheral_obj_t;
-#endif // MICROPY_INCLUDED_COMMON_HAL_BLEIO_PERIPHERAL_H
+#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PERIPHERAL_H
diff --git a/ports/nrf/common-hal/bleio/Scanner.c b/ports/nrf/common-hal/bleio/Scanner.c
index d2e19b5f9..57ce940ab 100644
--- a/ports/nrf/common-hal/bleio/Scanner.c
+++ b/ports/nrf/common-hal/bleio/Scanner.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,22 +31,21 @@
#include "ble_drv.h"
#include "ble_gap.h"
#include "py/mphal.h"
+#include "py/objlist.h"
#include "py/runtime.h"
#include "shared-bindings/bleio/Adapter.h"
#include "shared-bindings/bleio/ScanEntry.h"
#include "shared-bindings/bleio/Scanner.h"
#include "shared-module/bleio/ScanEntry.h"
-#if (BLUETOOTH_SD == 140)
static uint8_t m_scan_buffer_data[BLE_GAP_SCAN_BUFFER_MIN];
static ble_data_t m_scan_buffer = {
m_scan_buffer_data,
BLE_GAP_SCAN_BUFFER_MIN
};
-#endif
-STATIC void on_ble_evt(ble_evt_t *ble_evt, void *scanner_in) {
+STATIC void scanner_on_ble_evt(ble_evt_t *ble_evt, void *scanner_in) {
bleio_scanner_obj_t *scanner = (bleio_scanner_obj_t*)scanner_in;
ble_gap_evt_adv_report_t *report = &ble_evt->evt.gap_evt.params.adv_report;
@@ -53,56 +53,53 @@ STATIC void on_ble_evt(ble_evt_t *ble_evt, void *scanner_in) {
return;
}
- // TODO: Don't add new entry for each item, group by address and update
bleio_scanentry_obj_t *entry = m_new_obj(bleio_scanentry_obj_t);
entry->base.type = &bleio_scanentry_type;
entry->rssi = report->rssi;
- entry->address.type = report->peer_addr.addr_type;
- memcpy(entry->address.value, report->peer_addr.addr, BLEIO_ADDRESS_BYTES);
+ bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t);
+ address->base.type = &bleio_address_type;
+ common_hal_bleio_address_construct(MP_OBJ_TO_PTR(address),
+ report->peer_addr.addr, report->peer_addr.addr_type);
+ entry->address = address;
-#if (BLUETOOTH_SD == 140)
- entry->data = mp_obj_new_bytearray(report->data.len, report->data.p_data);
-#else
- entry->data = mp_obj_new_bytearray(report->dlen, report->data);
-#endif
+ entry->data = mp_obj_new_bytes(report->data.p_data, report->data.len);
- mp_obj_list_append(scanner->adv_reports, entry);
+ mp_obj_list_append(scanner->scan_entries, MP_OBJ_FROM_PTR(entry));
-#if (BLUETOOTH_SD == 140)
const uint32_t err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer);
if (err_code != NRF_SUCCESS) {
mp_raise_OSError_msg_varg(translate("Failed to continue scanning, err 0x%04x"), err_code);
}
-#endif
}
-void common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_int_t timeout) {
- ble_drv_add_event_handler(on_ble_evt, self);
+void common_hal_bleio_scanner_construct(bleio_scanner_obj_t *self) {
+}
+
+mp_obj_t common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_float_t timeout, mp_float_t interval, mp_float_t window) {
+ common_hal_bleio_adapter_set_enabled(true);
+ ble_drv_add_event_handler(scanner_on_ble_evt, self);
ble_gap_scan_params_t scan_params = {
- .interval = MSEC_TO_UNITS(self->interval, UNIT_0_625_MS),
- .window = MSEC_TO_UNITS(self->window, UNIT_0_625_MS),
-#if (BLUETOOTH_SD == 140)
+ .interval = SEC_TO_UNITS(interval, UNIT_0_625_MS),
+ .window = SEC_TO_UNITS(window, UNIT_0_625_MS),
.scan_phys = BLE_GAP_PHY_1MBPS,
-#endif
};
- common_hal_bleio_adapter_set_enabled(true);
+ self->scan_entries = mp_obj_new_list(0, NULL);
uint32_t err_code;
-#if (BLUETOOTH_SD == 140)
err_code = sd_ble_gap_scan_start(&scan_params, &m_scan_buffer);
-#else
- err_code = sd_ble_gap_scan_start(&scan_params);
-#endif
if (err_code != NRF_SUCCESS) {
mp_raise_OSError_msg_varg(translate("Failed to start scanning, err 0x%04x"), err_code);
}
- if (timeout > 0) {
- mp_hal_delay_ms(timeout);
- sd_ble_gap_scan_stop();
- }
+ mp_hal_delay_ms(timeout * 1000);
+ sd_ble_gap_scan_stop();
+
+ // Return list, and don't hang on to it, so it can be GC'd.
+ mp_obj_t entries = self->scan_entries;
+ self->scan_entries = MP_OBJ_NULL;
+ return entries;
}
diff --git a/shared-module/bleio/Scanner.h b/ports/nrf/common-hal/bleio/Scanner.h
index 76f5e5866..3768a52cb 100644
--- a/shared-module/bleio/Scanner.h
+++ b/ports/nrf/common-hal/bleio/Scanner.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -24,16 +25,16 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANNER_H
-#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANNER_H
+#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SCANNER_H
+#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SCANNER_H
#include "py/obj.h"
typedef struct {
mp_obj_base_t base;
- mp_obj_t adv_reports;
+ mp_obj_t scan_entries;
uint16_t interval;
uint16_t window;
} bleio_scanner_obj_t;
-#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANNER_H
+#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SCANNER_H
diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c
index 26a1f1cff..b6fcde827 100644
--- a/ports/nrf/common-hal/bleio/Service.c
+++ b/ports/nrf/common-hal/bleio/Service.c
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -29,18 +30,43 @@
#include "py/runtime.h"
#include "common-hal/bleio/__init__.h"
#include "common-hal/bleio/Characteristic.h"
+#include "shared-bindings/bleio/Characteristic.h"
#include "shared-bindings/bleio/Service.h"
#include "shared-bindings/bleio/Adapter.h"
-void common_hal_bleio_service_construct(bleio_service_obj_t *self) {
+void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, mp_obj_list_t *characteristic_list, bool is_secondary) {
+ self->device = mp_const_none;
+ self->handle = 0xFFFF;
+ self->uuid = uuid;
+ self->characteristic_list = characteristic_list;
+ self->is_secondary = is_secondary;
+
+ for (size_t characteristic_idx = 0; characteristic_idx < characteristic_list->len; ++characteristic_idx) {
+ bleio_characteristic_obj_t *characteristic =
+ MP_OBJ_TO_PTR(characteristic_list->items[characteristic_idx]);
+ characteristic->service = self;
+ }
+
+}
+
+bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self) {
+ return self->uuid;
+}
+
+mp_obj_list_t *common_hal_bleio_service_get_characteristic_list(bleio_service_obj_t *self) {
+ return self->characteristic_list;
+}
+
+bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self) {
+ return self->is_secondary;
}
// Call this after the Service has been added to the Peripheral.
void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self) {
// Add all the characteristics.
- const mp_obj_list_t *char_list = MP_OBJ_TO_PTR(self->char_list);
- for (size_t char_idx = 0; char_idx < char_list->len; ++char_idx) {
- bleio_characteristic_obj_t *characteristic = char_list->items[char_idx];
+ for (size_t characteristic_idx = 0; characteristic_idx < self->characteristic_list->len; ++characteristic_idx) {
+ bleio_characteristic_obj_t *characteristic =
+ MP_OBJ_TO_PTR(self->characteristic_list->items[characteristic_idx]);
ble_gatts_char_md_t char_md = {
.char_props.broadcast = characteristic->props.broadcast,
diff --git a/shared-module/bleio/Service.h b/ports/nrf/common-hal/bleio/Service.h
index 828d4cdc8..583593fb8 100644
--- a/shared-module/bleio/Service.h
+++ b/ports/nrf/common-hal/bleio/Service.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -24,21 +25,24 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SERVICE_H
-#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SERVICE_H
+#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SERVICE_H
+#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SERVICE_H
+#include "py/objlist.h"
#include "common-hal/bleio/UUID.h"
typedef struct {
mp_obj_base_t base;
+ // Handle for this service.
uint16_t handle;
bool is_secondary;
bleio_uuid_obj_t *uuid;
// May be a Peripheral, Central, etc.
- mp_obj_t *device;
- mp_obj_t char_list;
+ mp_obj_t device;
+ mp_obj_list_t *characteristic_list;
+ // Range of attribute handles of this service.
uint16_t start_handle;
uint16_t end_handle;
} bleio_service_obj_t;
-#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SERVICE_H
+#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SERVICE_H
diff --git a/ports/nrf/common-hal/bleio/UUID.c b/ports/nrf/common-hal/bleio/UUID.c
index 23e643433..ebd6b6d1f 100644
--- a/ports/nrf/common-hal/bleio/UUID.c
+++ b/ports/nrf/common-hal/bleio/UUID.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/ports/nrf/common-hal/bleio/UUID.h b/ports/nrf/common-hal/bleio/UUID.h
index b464093ea..7d3a6204e 100644
--- a/ports/nrf/common-hal/bleio/UUID.h
+++ b/ports/nrf/common-hal/bleio/UUID.h
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/ports/nrf/common-hal/bleio/__init__.c b/ports/nrf/common-hal/bleio/__init__.c
index cfb701019..2dba5780c 100644
--- a/ports/nrf/common-hal/bleio/__init__.c
+++ b/ports/nrf/common-hal/bleio/__init__.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -27,6 +28,7 @@
#include "shared-bindings/bleio/__init__.h"
#include "shared-bindings/bleio/Adapter.h"
+#include "shared-bindings/bleio/Central.h"
#include "shared-bindings/bleio/Peripheral.h"
#include "common-hal/bleio/__init__.h"
@@ -48,9 +50,8 @@ const super_adapter_obj_t common_hal_bleio_adapter_obj = {
gatt_role_t common_hal_bleio_device_get_gatt_role(mp_obj_t device) {
if (MP_OBJ_IS_TYPE(device, &bleio_peripheral_type)) {
return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->gatt_role;
-// Does not exist yet.
-// } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) {
-// return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->gatt_role;
+ } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) {
+ return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->gatt_role;
} else {
return GATT_ROLE_NONE;
}
@@ -59,9 +60,8 @@ gatt_role_t common_hal_bleio_device_get_gatt_role(mp_obj_t device) {
uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device) {
if (MP_OBJ_IS_TYPE(device, &bleio_peripheral_type)) {
return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle;
-// Does not exist yet.
-// } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) {
-// return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle;
+ } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) {
+ return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle;
} else {
return 0;
}
diff --git a/ports/nrf/common-hal/bleio/__init__.h b/ports/nrf/common-hal/bleio/__init__.h
index 9e044f37c..0c46b631f 100644
--- a/ports/nrf/common-hal/bleio/__init__.h
+++ b/ports/nrf/common-hal/bleio/__init__.h
@@ -24,8 +24,8 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_COMMON_HAL_BLEIO_INIT_H
-#define MICROPY_INCLUDED_COMMON_HAL_BLEIO_INIT_H
+#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H
+#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H
#include "shared-bindings/bleio/__init__.h"
#include "shared-bindings/bleio/Adapter.h"
@@ -39,4 +39,4 @@
gatt_role_t common_hal_bleio_device_get_gatt_role(mp_obj_t device);
uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device);
-#endif // MICROPY_INCLUDED_COMMON_HAL_BLEIO_INIT_H
+#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H
diff --git a/ports/nrf/common-hal/busio/I2C.c b/ports/nrf/common-hal/busio/I2C.c
index 05106d490..71835d16a 100644
--- a/ports/nrf/common-hal/busio/I2C.c
+++ b/ports/nrf/common-hal/busio/I2C.c
@@ -3,9 +3,10 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Sandeep Mistry All right reserved.
- * Copyright (c) 2017 hathach
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 hathach
+ * Copyright (c) 2016 Sandeep Mistry All right reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -56,13 +57,30 @@ STATIC twim_peripheral_t twim_peripherals[] = {
#endif
};
+STATIC bool never_reset[MP_ARRAY_SIZE(twim_peripherals)];
+
void i2c_reset(void) {
for (size_t i = 0 ; i < MP_ARRAY_SIZE(twim_peripherals); i++) {
+ if (never_reset[i]) {
+ continue;
+ }
nrf_twim_disable(twim_peripherals[i].twim.p_twim);
twim_peripherals[i].in_use = false;
}
}
+void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
+ for (size_t i = 0 ; i < MP_ARRAY_SIZE(twim_peripherals); i++) {
+ if (self->twim_peripheral == &twim_peripherals[i]) {
+ never_reset[i] = true;
+
+ never_reset_pin_number(self->scl_pin_number);
+ never_reset_pin_number(self->sda_pin_number);
+ break;
+ }
+ }
+}
+
static uint8_t twi_error_to_mp(const nrfx_err_t err) {
switch (err) {
case NRFX_ERROR_DRV_TWI_ERR_ANACK:
diff --git a/ports/nrf/common-hal/busio/SPI.c b/ports/nrf/common-hal/busio/SPI.c
index 8881bdc6b..5f1aac193 100644
--- a/ports/nrf/common-hal/busio/SPI.c
+++ b/ports/nrf/common-hal/busio/SPI.c
@@ -1,9 +1,11 @@
/*
* SPI Master library for nRF5x.
- * Copyright (c) 2015 Arduino LLC
- * Copyright (c) 2016 Sandeep Mistry All right reserved.
- * Copyright (c) 2017 hathach
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 hathach
+ * Copyright (c) 2016 Sandeep Mistry All right reserved.
+ * Copyright (c) 2015 Arduino LLC
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -59,7 +61,7 @@ STATIC spim_peripheral_t spim_peripherals[] = {
#endif
};
-STATIC bool never_reset[4];
+STATIC bool never_reset[MP_ARRAY_SIZE(spim_peripherals)];
void spi_reset(void) {
for (size_t i = 0 ; i < MP_ARRAY_SIZE(spim_peripherals); i++) {
diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c
index 593914afc..b9e9e5538 100644
--- a/ports/nrf/common-hal/busio/UART.c
+++ b/ports/nrf/common-hal/busio/UART.c
@@ -131,7 +131,7 @@ void uart_reset(void) {
void common_hal_busio_uart_construct (busio_uart_obj_t *self,
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
- uint8_t receiver_buffer_size) {
+ uint16_t receiver_buffer_size) {
// Find a free UART peripheral.
self->uarte = NULL;
for (size_t i = 0 ; i < MP_ARRAY_SIZE(nrfx_uartes); i++) {
diff --git a/ports/nrf/common-hal/microcontroller/Pin.c b/ports/nrf/common-hal/microcontroller/Pin.c
index b9c0ecaca..3cee784b6 100644
--- a/ports/nrf/common-hal/microcontroller/Pin.c
+++ b/ports/nrf/common-hal/microcontroller/Pin.c
@@ -105,7 +105,7 @@ void reset_pin_number(uint8_t pin_number) {
#ifdef SPEAKER_ENABLE_PIN
if (pin_number == SPEAKER_ENABLE_PIN->number) {
speaker_enable_in_use = false;
- common_hal_digitalio_digitalinout_switch_to_output(
+ common_hal_digitalio_digitalinout_switch_to_output(SPEAKER_ENABLE_PIN, true, DRIVE_MODE_PUSH_PULL);
nrf_gpio_pin_dir_set(pin_number, NRF_GPIO_PIN_DIR_OUTPUT);
nrf_gpio_pin_write(pin_number, false);
}
diff --git a/ports/nrf/common-hal/microcontroller/__init__.c b/ports/nrf/common-hal/microcontroller/__init__.c
index ab7b5d5d6..a6b1c4ba3 100644
--- a/ports/nrf/common-hal/microcontroller/__init__.c
+++ b/ports/nrf/common-hal/microcontroller/__init__.c
@@ -37,6 +37,7 @@
#include "shared-bindings/microcontroller/Processor.h"
#include "supervisor/filesystem.h"
+#include "supervisor/shared/safe_mode.h"
#include "nrfx_glue.h"
// This routine should work even when interrupts are disabled. Used by OneWire
@@ -52,7 +53,13 @@ void common_hal_mcu_enable_interrupts() {
}
void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
- // TODO: see atmel-samd for functionality
+ enum { DFU_MAGIC_UF2_RESET = 0x57 };
+ if(runmode == RUNMODE_BOOTLOADER)
+ NRF_POWER->GPREGRET = DFU_MAGIC_UF2_RESET;
+ else
+ NRF_POWER->GPREGRET = 0;
+ if(runmode == RUNMODE_SAFE_MODE)
+ safe_mode_on_next_reset(PROGRAMMATIC_SAFE_MODE);
}
void common_hal_mcu_reset(void) {
diff --git a/ports/nrf/common-hal/neopixel_write/__init__.c b/ports/nrf/common-hal/neopixel_write/__init__.c
index fe2bab999..78e0038e8 100644
--- a/ports/nrf/common-hal/neopixel_write/__init__.c
+++ b/ports/nrf/common-hal/neopixel_write/__init__.c
@@ -111,18 +111,23 @@ void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout
//
// If there is not enough memory, we will fall back to cycle counter
// using DWT
- uint32_t pattern_size = numBytes * 8 * sizeof(uint16_t) + 2 * sizeof(uint16_t);
+
+#define PATTERN_SIZE(numBytes) (numBytes * 8 * sizeof(uint16_t) + 2 * sizeof(uint16_t))
+
+ uint32_t pattern_size = PATTERN_SIZE(numBytes);
uint16_t* pixels_pattern = NULL;
bool pattern_on_heap = false;
// Use the stack to store 1 pixels worth of PWM data for the status led. uint32_t to ensure alignment.
- uint32_t one_pixel[8 * sizeof(uint16_t) + 1];
+ // Make it at least as big as PATTERN_SIZE(3), for one pixel of RGB data.
+ // PATTERN_SIZE is a multiple of 4, so we don't need round up to make sure one_pixel is large enough.
+ uint32_t one_pixel[PATTERN_SIZE(3)/sizeof(uint32_t)];
NRF_PWM_Type* pwm = find_free_pwm();
// only malloc if there is PWM device available
if ( pwm != NULL ) {
- if (pattern_size <= sizeof(one_pixel) * sizeof(uint32_t)) {
+ if (pattern_size <= sizeof(one_pixel)) {
pixels_pattern = (uint16_t *) one_pixel;
} else {
pixels_pattern = (uint16_t *) m_malloc_maybe(pattern_size, false);
diff --git a/ports/nrf/common-hal/pulseio/PWMOut.c b/ports/nrf/common-hal/pulseio/PWMOut.c
index 5485a75d0..b827470d3 100644
--- a/ports/nrf/common-hal/pulseio/PWMOut.c
+++ b/ports/nrf/common-hal/pulseio/PWMOut.c
@@ -57,6 +57,12 @@ STATIC uint16_t pwm_seq[MP_ARRAY_SIZE(pwms)][CHANNELS_PER_PWM];
static uint8_t never_reset_pwm[MP_ARRAY_SIZE(pwms)];
+STATIC int pwm_idx(NRF_PWM_Type *pwm) {
+ for(size_t i=0; i < MP_ARRAY_SIZE(pwms); i++)
+ if(pwms[i] == pwm) return i;
+ return -1;
+}
+
void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) {
for(size_t i=0; i < MP_ARRAY_SIZE(pwms); i++) {
NRF_PWM_Type* pwm = pwms[i];
@@ -77,33 +83,37 @@ void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self) {
}
}
+void reset_single_pwmout(uint8_t i) {
+ NRF_PWM_Type* pwm = pwms[i];
+
+ pwm->ENABLE = 0;
+ pwm->MODE = PWM_MODE_UPDOWN_Up;
+ pwm->DECODER = PWM_DECODER_LOAD_Individual;
+ pwm->LOOP = 0;
+ pwm->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_1; // default is 500 hz
+ pwm->COUNTERTOP = (PWM_MAX_FREQ/500); // default is 500 hz
+
+ pwm->SEQ[0].PTR = (uint32_t) pwm_seq[i];
+ pwm->SEQ[0].CNT = CHANNELS_PER_PWM; // default mode is Individual --> count must be 4
+ pwm->SEQ[0].REFRESH = 0;
+ pwm->SEQ[0].ENDDELAY = 0;
+
+ pwm->SEQ[1].PTR = 0;
+ pwm->SEQ[1].CNT = 0;
+ pwm->SEQ[1].REFRESH = 0;
+ pwm->SEQ[1].ENDDELAY = 0;
+
+ for(int ch =0; ch < CHANNELS_PER_PWM; ch++) {
+ pwm_seq[i][ch] = (1 << 15); // polarity = 0
+ }
+}
+
void pwmout_reset(void) {
for(size_t i=0; i < MP_ARRAY_SIZE(pwms); i++) {
if (never_reset_pwm[i] > 0) {
continue;
}
- NRF_PWM_Type* pwm = pwms[i];
-
- pwm->ENABLE = 0;
- pwm->MODE = PWM_MODE_UPDOWN_Up;
- pwm->DECODER = PWM_DECODER_LOAD_Individual;
- pwm->LOOP = 0;
- pwm->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_1; // default is 500 hz
- pwm->COUNTERTOP = (PWM_MAX_FREQ/500); // default is 500 hz
-
- pwm->SEQ[0].PTR = (uint32_t) pwm_seq[i];
- pwm->SEQ[0].CNT = CHANNELS_PER_PWM; // default mode is Individual --> count must be 4
- pwm->SEQ[0].REFRESH = 0;
- pwm->SEQ[0].ENDDELAY = 0;
-
- pwm->SEQ[1].PTR = 0;
- pwm->SEQ[1].CNT = 0;
- pwm->SEQ[1].REFRESH = 0;
- pwm->SEQ[1].ENDDELAY = 0;
-
- for(int ch =0; ch < CHANNELS_PER_PWM; ch++) {
- pwm_seq[i][ch] = (1 << 15); // polarity = 0
- }
+ reset_single_pwmout(i);
}
}
@@ -129,29 +139,11 @@ bool convert_frequency(uint32_t frequency, uint16_t *countertop, nrf_pwm_clk_t *
return false;
}
-pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
- const mcu_pin_obj_t* pin,
- uint16_t duty,
- uint32_t frequency,
- bool variable_frequency) {
-
- // We don't use the nrfx driver here because we want to dynamically allocate channels
- // as needed in an already-enabled PWM.
-
- uint16_t countertop;
- nrf_pwm_clk_t base_clock;
- if (frequency == 0 || !convert_frequency(frequency, &countertop, &base_clock)) {
- return PWMOUT_INVALID_FREQUENCY;
- }
-
- self->pwm = NULL;
- self->channel = CHANNELS_PER_PWM; // out-of-range value.
- bool pwm_already_in_use;
- NRF_PWM_Type* pwm;
-
- for (size_t i = 0 ; i < MP_ARRAY_SIZE(pwms); i++) {
- pwm = pwms[i];
- pwm_already_in_use = pwm->ENABLE & SPIM_ENABLE_ENABLE_Msk;
+NRF_PWM_Type *pwmout_allocate(uint16_t countertop, nrf_pwm_clk_t base_clock,
+ bool variable_frequency, int8_t *channel_out, bool *pwm_already_in_use_out) {
+ for (size_t pwm_index = 0; pwm_index < MP_ARRAY_SIZE(pwms); pwm_index++) {
+ NRF_PWM_Type *pwm = pwms[pwm_index];
+ bool pwm_already_in_use = pwm->ENABLE & SPIM_ENABLE_ENABLE_Msk;
if (pwm_already_in_use) {
if (variable_frequency) {
// Variable frequency requires exclusive use of a PWM, so try the next one.
@@ -164,28 +156,65 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
for (size_t chan = 0; chan < CHANNELS_PER_PWM; chan++) {
if (pwm->PSEL.OUT[chan] == 0xFFFFFFFF) {
// Channel is free.
- self->pwm = pwm;
- self->channel = chan;
- break;
+ if(channel_out)
+ *channel_out = chan;
+ if(pwm_already_in_use_out)
+ *pwm_already_in_use_out = pwm_already_in_use;
+ return pwm;
}
}
- // Did we find a channel? If not, loop and check the next pwm.
- if (self->pwm != NULL) {
- break;
- }
}
} else {
// PWM not yet in use, so we can start to use it. Use channel 0.
- self->pwm = pwm;
- self->channel = 0;
- break;
+ if(channel_out)
+ *channel_out = 0;
+ if(pwm_already_in_use_out)
+ *pwm_already_in_use_out = pwm_already_in_use;
+ return pwm;
+ }
+ }
+ return NULL;
+}
+
+void pwmout_free_channel(NRF_PWM_Type *pwm, int8_t channel) {
+ // Disconnect pin from channel.
+ pwm->PSEL.OUT[channel] = 0xFFFFFFFF;
+
+ for(int i=0; i < CHANNELS_PER_PWM; i++) {
+ if (pwm->PSEL.OUT[i] != 0xFFFFFFFF) {
+ // Some channel is still being used, so don't disable.
+ return;
}
}
+ nrf_pwm_disable(pwm);
+}
+
+pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
+ const mcu_pin_obj_t* pin,
+ uint16_t duty,
+ uint32_t frequency,
+ bool variable_frequency) {
+
+ // We don't use the nrfx driver here because we want to dynamically allocate channels
+ // as needed in an already-enabled PWM.
+
+ uint16_t countertop;
+ nrf_pwm_clk_t base_clock;
+ if (frequency == 0 || !convert_frequency(frequency, &countertop, &base_clock)) {
+ return PWMOUT_INVALID_FREQUENCY;
+ }
+
+ int8_t channel;
+ bool pwm_already_in_use;
+ self->pwm = pwmout_allocate(countertop, base_clock, variable_frequency,
+ &channel, &pwm_already_in_use);
+
if (self->pwm == NULL) {
return PWMOUT_ALL_TIMERS_IN_USE;
}
+ self->channel = channel;
self->pin_number = pin->number;
claim_pin(pin);
@@ -196,16 +225,17 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
nrf_gpio_cfg_output(self->pin_number);
// disable before mapping pin channel
- nrf_pwm_disable(pwm);
+ nrf_pwm_disable(self->pwm);
if (!pwm_already_in_use) {
- nrf_pwm_configure(pwm, base_clock, NRF_PWM_MODE_UP, countertop);
+ reset_single_pwmout(pwm_idx(self->pwm));
+ nrf_pwm_configure(self->pwm, base_clock, NRF_PWM_MODE_UP, countertop);
}
// Connect channel to pin, without disturbing other channels.
- pwm->PSEL.OUT[self->channel] = pin->number;
+ self->pwm->PSEL.OUT[self->channel] = pin->number;
- nrf_pwm_enable(pwm);
+ nrf_pwm_enable(self->pwm);
common_hal_pulseio_pwmout_set_duty_cycle(self, duty);
return PWMOUT_OK;
@@ -225,17 +255,7 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) {
NRF_PWM_Type* pwm = self->pwm;
self->pwm = NULL;
- // Disconnect pin from channel.
- pwm->PSEL.OUT[self->channel] = 0xFFFFFFFF;
-
- for(int i=0; i < CHANNELS_PER_PWM; i++) {
- if (self->pwm->PSEL.OUT[i] != 0xFFFFFFFF) {
- // Some channel is still being used, so don't disable.
- return;
- }
- }
-
- nrf_pwm_disable(pwm);
+ pwmout_free_channel(pwm, self->channel);
}
void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty_cycle) {
diff --git a/ports/nrf/common-hal/pulseio/PWMOut.h b/ports/nrf/common-hal/pulseio/PWMOut.h
index a4e58dc1a..b6798cb68 100644
--- a/ports/nrf/common-hal/pulseio/PWMOut.h
+++ b/ports/nrf/common-hal/pulseio/PWMOut.h
@@ -41,5 +41,8 @@ typedef struct {
} pulseio_pwmout_obj_t;
void pwmout_reset(void);
+NRF_PWM_Type *pwmout_allocate(uint16_t countertop, nrf_pwm_clk_t base_clock,
+ bool variable_frequency, int8_t *channel_out, bool *pwm_already_in_use_out);
+void pwmout_free_channel(NRF_PWM_Type *pwm, int8_t channel);
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_PULSEIO_PWMOUT_H
diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk
index 83166708a..57879bbaa 100644
--- a/ports/nrf/mpconfigport.mk
+++ b/ports/nrf/mpconfigport.mk
@@ -10,8 +10,10 @@ USB_SERIAL_NUMBER_LENGTH = 16
# All nRF ports have longints.
LONGINT_IMPL = MPZ
-# No DAC, so no regular audio.
+# Audio via PWM
+CIRCUITPY_AUDIOCORE = 1
CIRCUITPY_AUDIOIO = 0
+CIRCUITPY_AUDIOPWMIO = 1
# No I2S yet.
CIRCUITPY_AUDIOBUSIO = 0
diff --git a/ports/nrf/mphalport.c b/ports/nrf/mphalport.c
index ea864e7ce..7d9463d0b 100644
--- a/ports/nrf/mphalport.c
+++ b/ports/nrf/mphalport.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2015 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2015 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h
index d51739fac..a2b48065d 100644
--- a/ports/nrf/nrfx_config.h
+++ b/ports/nrf/nrfx_config.h
@@ -81,13 +81,13 @@
#define NRFX_TIMER1_ENABLED 1
#define NRFX_TIMER2_ENABLED 1
-#ifdef NRFX_TIMER3
+#ifdef NRF_TIMER3
#define NRFX_TIMER3_ENABLED 1
#else
#define NRFX_TIMER3_ENABLED 0
#endif
-#ifdef NRFX_TIMER4
+#ifdef NRF_TIMER4
#define NRFX_TIMER4_ENABLED 1
#else
#define NRFX_TIMER4_ENABLED 0
diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c
index 85ecd6afe..03f787624 100644
--- a/ports/nrf/supervisor/port.c
+++ b/ports/nrf/supervisor/port.c
@@ -50,6 +50,10 @@
#include "shared-bindings/rtc/__init__.h"
+#ifdef CIRCUITPY_AUDIOPWMIO
+#include "common-hal/audiopwmio/PWMAudioOut.h"
+#endif
+
static void power_warning_handler(void) {
reset_into_safe_mode(BROWNOUT);
}
@@ -93,16 +97,26 @@ void reset_port(void) {
i2c_reset();
spi_reset();
uart_reset();
+
+#ifdef CIRCUITPY_AUDIOPWMIO
+ audiopwmout_reset();
+#endif
+
+#if CIRCUITPY_PULSEIO
pwmout_reset();
pulseout_reset();
pulsein_reset();
+#endif
+
timers_reset();
- #if CIRCUITPY_RTC
+#if CIRCUITPY_RTC
rtc_reset();
- #endif
+#endif
+#if CIRCUITPY_BLEIO
bleio_reset();
+#endif
reset_all_pins();
}
diff --git a/ports/stm32f4/.gitignore b/ports/stm32f4/.gitignore
new file mode 100644
index 000000000..3080ece14
--- /dev/null
+++ b/ports/stm32f4/.gitignore
@@ -0,0 +1,9 @@
+# Build files
+#####################
+build-*/
+
+# Reference files
+#####################
+ref/
+
+.gdb_history \ No newline at end of file
diff --git a/ports/stm32f4/Makefile b/ports/stm32f4/Makefile
new file mode 100755
index 000000000..7f0744443
--- /dev/null
+++ b/ports/stm32f4/Makefile
@@ -0,0 +1,271 @@
+# This file is part of the MicroPython project, http://micropython.org/
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2019 Dan Halbert for Adafruit Industries
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+DEBUG = 1
+
+# Select the board to build for.
+ifeq ($(BOARD),)
+ $(error You must provide a BOARD parameter)
+else
+ ifeq ($(wildcard boards/$(BOARD)/.),)
+ $(error Invalid BOARD specified)
+ endif
+endif
+
+# If the build directory is not given, make it reflect the board name.
+BUILD ?= build-$(BOARD)
+
+include ../../py/mkenv.mk
+# Board-specific
+include boards/$(BOARD)/mpconfigboard.mk
+# Port-specific
+include mpconfigport.mk
+
+# CircuitPython-specific
+include $(TOP)/py/circuitpy_mpconfig.mk
+
+# qstr definitions (must come before including py.mk)
+QSTR_DEFS = qstrdefsport.h
+
+# include py core make definitions
+include $(TOP)/py/py.mk
+
+include $(TOP)/supervisor/supervisor.mk
+
+# Include make rules and variables common across CircuitPython builds.
+include $(TOP)/py/circuitpy_defns.mk
+
+CROSS_COMPILE = arm-none-eabi-
+
+#######################################
+# CFLAGS
+#######################################
+
+INC += -I.
+INC += -I../..
+INC += -I$(BUILD)
+INC += -I$(BUILD)/genhdr
+INC += -I./stm32f4/STM32F4xx_HAL_Driver/Inc
+INC += -I./stm32f4/STM32F4xx_HAL_Driver/Inc/Legacy
+INC += -I./stm32f4/CMSIS/Device/ST/STM32F4xx/Include
+INC += -I./stm32f4/CMSIS/Include
+INC += -I./boards
+INC += -I./boards/$(BOARD)
+INC += -I./peripherals
+INC += -I../../lib/mp-readline
+INC += -I../../lib/tinyusb/src
+INC += -I../../supervisor/shared/usb
+
+
+#Debugging/Optimization
+ifeq ($(DEBUG), 1)
+ CFLAGS += -ggdb
+ # You may want to enable these flags to make setting breakpoints easier.
+ CFLAGS += -fno-inline -fno-ipa-sra
+else
+ CFLAGS += -Os -DNDEBUG
+ # TODO: Test with -flto
+ ### CFLAGS += -flto
+endif
+
+# C defines and other board specifics
+ifeq ($(MCU_SUB_VARIANT), stm32f412zx)
+C_DEFS = \
+ -DUSE_FULL_LL_DRIVER \
+ -DUSE_HAL_DRIVER \
+ -DSTM32F412Zx
+endif
+
+ifeq ($(MCU_SUB_VARIANT), stm32f411xe)
+C_DEFS = \
+ -DUSE_HAL_DRIVER \
+ -DSTM32F411xE
+endif
+
+#TODO: Add ASM Flags? -Werror
+CFLAGS += $(INC) -Wall -std=gnu11 -nostdlib $(BASE_CFLAGS) $(C_DEFS) $(CFLAGS_MOD) $(COPT)
+
+# Undo some warnings.
+# STM32 apparently also uses undefined preprocessor variables quite casually,
+# so we can't do warning checks for these.
+CFLAGS += -Wno-undef
+# STM32 might do casts that increase alignment requirements.
+CFLAGS += -Wno-cast-align
+
+CFLAGS += \
+ -mthumb \
+ -mabi=aapcs-linux \
+ -mfloat-abi=hard \
+ -mcpu=cortex-m4 \
+ -mfpu=fpv4-sp-d16
+
+# TODO: check this
+CFLAGS += -D__START=main
+
+LDFLAGS = $(CFLAGS) -fshort-enums -Wl,-nostdlib -Wl,-T,$(LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections -specs=nano.specs
+LIBS := -lgcc -lc
+
+LDFLAGS += -mthumb -mcpu=cortex-m4
+
+# Use toolchain libm if we're not using our own.
+ifndef INTERNAL_LIBM
+LIBS += -lm
+endif
+
+# TinyUSB defines
+CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_STM32F4 -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_CDC_TX_BUFSIZE=1024 -DCFG_TUD_MSC_BUFSIZE=4096 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_MIDI_TX_BUFSIZE=128
+
+
+######################################
+# source
+######################################
+
+SRC_STM32 = \
+ boards/$(BOARD)/stm32f4xx_hal_msp.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_gpio.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_i2c.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_dma.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s_ex.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_qspi.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usart.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_rcc.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_utils.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_exti.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c \
+ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c \
+ system_stm32f4xx.c
+
+SRC_C += \
+ background.c \
+ fatfs_port.c \
+ mphalport.c \
+ tick.c \
+ boards/$(BOARD)/board.c \
+ peripherals/stm32f4/$(MCU_SUB_VARIANT)/clocks.c \
+ peripherals/stm32f4/$(MCU_SUB_VARIANT)/gpio.c \
+ lib/libc/string0.c \
+ lib/mp-readline/readline.c \
+ lib/oofatfs/ff.c \
+ lib/oofatfs/option/ccsbcs.c \
+ lib/timeutils/timeutils.c \
+ lib/utils/buffer_helper.c \
+ lib/utils/context_manager_helpers.c \
+ lib/utils/interrupt_char.c \
+ lib/utils/pyexec.c \
+ lib/utils/stdout_helpers.c \
+ lib/utils/sys_stdio_mphal.c \
+ supervisor/shared/memory.c
+
+ifneq ($(USB),FALSE)
+SRC_C += lib/tinyusb/src/portable/st/stm32f4/dcd_stm32f4.c
+endif
+
+ifeq ($(MCU_SUB_VARIANT), stm32f412zx)
+SRC_C += peripherals/stm32f4/stm32f412zx/pins.c
+SRC_C += boards/$(BOARD)/pins.c
+endif
+
+SRC_S = \
+ supervisor/cpu.s \
+ boards/startup_$(MCU_SUB_VARIANT).s
+
+SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
+ $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \
+ $(addprefix common-hal/, $(SRC_COMMON_HAL))
+
+SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \
+ $(addprefix shared-module/, $(SRC_SHARED_MODULE))
+
+
+
+FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py')
+FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy))
+
+OBJ += $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
+OBJ += $(addprefix $(BUILD)/, $(SRC_STM32:.c=.o))
+OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_EXPANDED:.c=.o))
+OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o))
+ifeq ($(INTERNAL_LIBM),1)
+OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o))
+endif
+OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
+OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
+
+$(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os
+$(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os
+
+# List of sources for qstr extraction
+SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_MOD) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)
+# Sources that only hold QSTRs after pre-processing.
+SRC_QSTR_PREPROCESSOR +=
+
+
+all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2
+
+$(BUILD)/firmware.elf: $(OBJ)
+ $(STEPECHO) "LINK $@"
+ $(Q)$(CC) -o $@ $(LDFLAGS) $^ -Wl,--start-group $(LIBS) -Wl,--end-group
+ $(Q)$(SIZE) $@ | $(PYTHON3) $(TOP)/tools/build_memory_info.py $(LD_FILE)
+
+$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
+ $(STEPECHO) "Create $@"
+ $(Q)$(OBJCOPY) -O binary $^ $@
+# $(Q)$(OBJCOPY) -O binary -j .vectors -j .text -j .data $^ $@
+
+$(BUILD)/firmware.hex: $(BUILD)/firmware.elf
+ $(STEPECHO) "Create $@"
+ $(Q)$(OBJCOPY) -O ihex $^ $@
+# $(Q)$(OBJCOPY) -O ihex -j .vectors -j .text -j .data $^ $@
+
+$(BUILD)/firmware.uf2: $(BUILD)/firmware.hex
+ $(ECHO) "Create $@"
+ $(PYTHON3) $(TOP)/tools/uf2/utils/uf2conv.py -f 0xADA52840 -c -o "$(BUILD)/firmware.uf2" $^
+
+include $(TOP)/py/mkrules.mk
+
+# Print out the value of a make variable.
+# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile
+print-%:
+ @echo $* = $($*)
diff --git a/ports/stm32f4/README.md b/ports/stm32f4/README.md
new file mode 100644
index 000000000..a860c01ce
--- /dev/null
+++ b/ports/stm32f4/README.md
@@ -0,0 +1,3 @@
+# CircuitPython Port To The ST Microelectronics STM32F4 Series
+
+This is a port of CircuitPython to the STM32F4 series of chips.
diff --git a/ports/stm32f4/background.c b/ports/stm32f4/background.c
new file mode 100644
index 000000000..e9872b045
--- /dev/null
+++ b/ports/stm32f4/background.c
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/runtime.h"
+#include "supervisor/filesystem.h"
+#include "supervisor/usb.h"
+#include "supervisor/shared/stack.h"
+
+#if CIRCUITPY_DISPLAYIO
+#include "shared-module/displayio/__init__.h"
+#endif
+
+static bool running_background_tasks = false;
+
+void background_tasks_reset(void) {
+ running_background_tasks = false;
+}
+
+void run_background_tasks(void) {
+ // Don't call ourselves recursively.
+ if (running_background_tasks) {
+ return;
+ }
+ running_background_tasks = true;
+ filesystem_background();
+ //usb_background();
+
+ #if CIRCUITPY_DISPLAYIO
+ displayio_refresh_displays();
+ #endif
+ running_background_tasks = false;
+
+ assert_heap_ok();
+}
diff --git a/ports/stm32f4/background.h b/ports/stm32f4/background.h
new file mode 100644
index 000000000..05a4f894a
--- /dev/null
+++ b/ports/stm32f4/background.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_STM32F4_BACKGROUND_H
+#define MICROPY_INCLUDED_STM32F4_BACKGROUND_H
+
+#include <stdbool.h>
+
+void background_tasks_reset(void);
+void run_background_tasks(void);
+
+#endif // MICROPY_INCLUDED_STM32F4_BACKGROUND_H
diff --git a/ports/stm32f4/boards/STM32F411VETx_FLASH.ld b/ports/stm32f4/boards/STM32F411VETx_FLASH.ld
new file mode 100644
index 000000000..a3c3594a9
--- /dev/null
+++ b/ports/stm32f4/boards/STM32F411VETx_FLASH.ld
@@ -0,0 +1,189 @@
+/*
+******************************************************************************
+**
+
+** File : LinkerScript.ld
+**
+** Author : Auto-generated by Ac6 System Workbench
+**
+** Abstract : Linker script for STM32F411VETx series
+** 512Kbytes FLASH and 128Kbytes RAM
+**
+** Set heap size, stack size and stack location according
+** to application requirements.
+**
+** Set memory bank area and size if external memory is used.
+**
+** Target : STMicroelectronics STM32
+**
+** Distribution: The file is distributed “as is,” without any warranty
+** of any kind.
+**
+*****************************************************************************
+** @attention
+**
+** <h2><center>&copy; COPYRIGHT(c) 2014 Ac6</center></h2>
+**
+** Redistribution and use in source and binary forms, with or without modification,
+** are permitted provided that the following conditions are met:
+** 1. Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+** 2. Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+** 3. Neither the name of Ac6 nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+*****************************************************************************
+*/
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+/* Highest address of the user mode stack */
+_estack = 0x20020000; /* end of RAM */
+/* Generate a link error if heap and stack don't fit into RAM */
+_Min_Heap_Size = 0x200; /* required amount of heap */
+_Min_Stack_Size = 0x400; /* required amount of stack */
+
+/* Specify the memory areas */
+MEMORY
+{
+RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
+FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K
+}
+
+/* Define output sections */
+SECTIONS
+{
+ /* The startup code goes first into FLASH */
+ .isr_vector :
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector)) /* Startup code */
+ . = ALIGN(4);
+ } >FLASH
+
+ /* The program code and other data goes into FLASH */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text) /* .text sections (code) */
+ *(.text*) /* .text* sections (code) */
+ *(.glue_7) /* glue arm to thumb code */
+ *(.glue_7t) /* glue thumb to arm code */
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ . = ALIGN(4);
+ _etext = .; /* define a global symbols at end of code */
+ } >FLASH
+
+ /* Constant data goes into FLASH */
+ .rodata :
+ {
+ . = ALIGN(4);
+ *(.rodata) /* .rodata sections (constants, strings, etc.) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ . = ALIGN(4);
+ } >FLASH
+
+ .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
+ .ARM : {
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ } >FLASH
+
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array*))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >FLASH
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array*))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } >FLASH
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array*))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } >FLASH
+
+ /* used by the startup to initialize data */
+ _sidata = LOADADDR(.data);
+
+ /* Initialized data sections goes into RAM, load LMA copy after code */
+ .data :
+ {
+ . = ALIGN(4);
+ _sdata = .; /* create a global symbol at data start */
+ *(.data) /* .data sections */
+ *(.data*) /* .data* sections */
+
+ . = ALIGN(4);
+ _edata = .; /* define a global symbol at data end */
+ } >RAM AT> FLASH
+
+
+ /* Uninitialized data section */
+ . = ALIGN(4);
+ .bss :
+ {
+ /* This is used by the startup in order to initialize the .bss secion */
+ _sbss = .; /* define a global symbol at bss start */
+ __bss_start__ = _sbss;
+ *(.bss)
+ *(.bss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .; /* define a global symbol at bss end */
+ __bss_end__ = _ebss;
+ } >RAM
+
+ /* User_heap_stack section, used to check that there is enough RAM left */
+ ._user_heap_stack :
+ {
+ . = ALIGN(8);
+ PROVIDE ( end = . );
+ PROVIDE ( _end = . );
+ . = . + _Min_Heap_Size;
+ . = . + _Min_Stack_Size;
+ . = ALIGN(8);
+ } >RAM
+
+
+
+ /* Remove information from the standard libraries */
+ /DISCARD/ :
+ {
+ libc.a ( * )
+ libm.a ( * )
+ libgcc.a ( * )
+ }
+
+ .ARM.attributes 0 : { *(.ARM.attributes) }
+}
+
+
diff --git a/ports/stm32f4/boards/STM32F412ZGTx_FLASH.ld b/ports/stm32f4/boards/STM32F412ZGTx_FLASH.ld
new file mode 100644
index 000000000..da1efdecc
--- /dev/null
+++ b/ports/stm32f4/boards/STM32F412ZGTx_FLASH.ld
@@ -0,0 +1,189 @@
+/*
+******************************************************************************
+**
+
+** File : LinkerScript.ld
+**
+** Author : Auto-generated by Ac6 System Workbench
+**
+** Abstract : Linker script for STM32F412ZGTx series
+** 1024Kbytes FLASH and 256Kbytes RAM
+**
+** Set heap size, stack size and stack location according
+** to application requirements.
+**
+** Set memory bank area and size if external memory is used.
+**
+** Target : STMicroelectronics STM32
+**
+** Distribution: The file is distributed “as is,” without any warranty
+** of any kind.
+**
+*****************************************************************************
+** @attention
+**
+** <h2><center>&copy; COPYRIGHT(c) 2014 Ac6</center></h2>
+**
+** Redistribution and use in source and binary forms, with or without modification,
+** are permitted provided that the following conditions are met:
+** 1. Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+** 2. Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+** 3. Neither the name of Ac6 nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+*****************************************************************************
+*/
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+/* Highest address of the user mode stack */
+_estack = 0x20040000; /* end of RAM */
+/* Generate a link error if heap and stack don't fit into RAM */
+_Min_Heap_Size = 0x200; /* required amount of heap */
+_Min_Stack_Size = 0x400; /* required amount of stack */
+
+/* Specify the memory areas */
+MEMORY
+{
+RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K
+FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
+}
+
+/* Define output sections */
+SECTIONS
+{
+ /* The startup code goes first into FLASH */
+ .isr_vector :
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector)) /* Startup code */
+ . = ALIGN(4);
+ } >FLASH
+
+ /* The program code and other data goes into FLASH */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text) /* .text sections (code) */
+ *(.text*) /* .text* sections (code) */
+ *(.glue_7) /* glue arm to thumb code */
+ *(.glue_7t) /* glue thumb to arm code */
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ . = ALIGN(4);
+ _etext = .; /* define a global symbols at end of code */
+ } >FLASH
+
+ /* Constant data goes into FLASH */
+ .rodata :
+ {
+ . = ALIGN(4);
+ *(.rodata) /* .rodata sections (constants, strings, etc.) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ . = ALIGN(4);
+ } >FLASH
+
+ .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
+ .ARM : {
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ } >FLASH
+
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array*))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >FLASH
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array*))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } >FLASH
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array*))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } >FLASH
+
+ /* used by the startup to initialize data */
+ _sidata = LOADADDR(.data);
+
+ /* Initialized data sections goes into RAM, load LMA copy after code */
+ .data :
+ {
+ . = ALIGN(4);
+ _sdata = .; /* create a global symbol at data start */
+ *(.data) /* .data sections */
+ *(.data*) /* .data* sections */
+
+ . = ALIGN(4);
+ _edata = .; /* define a global symbol at data end */
+ } >RAM AT> FLASH
+
+
+ /* Uninitialized data section */
+ . = ALIGN(4);
+ .bss :
+ {
+ /* This is used by the startup in order to initialize the .bss secion */
+ _sbss = .; /* define a global symbol at bss start */
+ __bss_start__ = _sbss;
+ *(.bss)
+ *(.bss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .; /* define a global symbol at bss end */
+ __bss_end__ = _ebss;
+ } >RAM
+
+ /* User_heap_stack section, used to check that there is enough RAM left */
+ ._user_heap_stack :
+ {
+ . = ALIGN(8);
+ PROVIDE ( end = . );
+ PROVIDE ( _end = . );
+ . = . + _Min_Heap_Size;
+ . = . + _Min_Stack_Size;
+ . = ALIGN(8);
+ } >RAM
+
+
+
+ /* Remove information from the standard libraries */
+ /DISCARD/ :
+ {
+ libc.a ( * )
+ libm.a ( * )
+ libgcc.a ( * )
+ }
+
+ .ARM.attributes 0 : { *(.ARM.attributes) }
+}
+
+
diff --git a/ports/stm32f4/boards/board.h b/ports/stm32f4/boards/board.h
new file mode 100644
index 000000000..22d9e99be
--- /dev/null
+++ b/ports/stm32f4/boards/board.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+// This file defines board specific functions.
+
+#ifndef MICROPY_INCLUDED_STM32F4_BOARDS_BOARD_H
+#define MICROPY_INCLUDED_STM32F4_BOARDS_BOARD_H
+
+#include <stdbool.h>
+
+// Initializes board related state once on start up.
+void board_init(void);
+
+// Returns true if the user initiates safe mode in a board specific way.
+// Also add BOARD_USER_SAFE_MODE in mpconfigboard.h to explain the board specific
+// way.
+bool board_requests_safe_mode(void);
+
+// Reset the state of off MCU components such as neopixels.
+void reset_board(void);
+
+#endif // MICROPY_INCLUDED_STM32F4_BOARDS_BOARD_H
diff --git a/ports/stm32f4/boards/startup_stm32f411xe.s b/ports/stm32f4/boards/startup_stm32f411xe.s
new file mode 100644
index 000000000..3aac640cb
--- /dev/null
+++ b/ports/stm32f4/boards/startup_stm32f411xe.s
@@ -0,0 +1,452 @@
+/**
+ ******************************************************************************
+ * @file startup_stm32f411xe.s
+ * @author MCD Application Team
+ * @brief STM32F411xExx Devices vector table for GCC based toolchains.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M4 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2017 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m4
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
+
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+ ldr sp, =_estack /* set stack pointer */
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+/* bl __libc_init_array */
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ * @param None
+ * @retval None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+*******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+g_pfnVectors:
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+
+ /* External Interrupts */
+ .word WWDG_IRQHandler /* Window WatchDog */
+ .word PVD_IRQHandler /* PVD through EXTI Line detection */
+ .word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */
+ .word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */
+ .word FLASH_IRQHandler /* FLASH */
+ .word RCC_IRQHandler /* RCC */
+ .word EXTI0_IRQHandler /* EXTI Line0 */
+ .word EXTI1_IRQHandler /* EXTI Line1 */
+ .word EXTI2_IRQHandler /* EXTI Line2 */
+ .word EXTI3_IRQHandler /* EXTI Line3 */
+ .word EXTI4_IRQHandler /* EXTI Line4 */
+ .word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */
+ .word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */
+ .word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */
+ .word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */
+ .word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */
+ .word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */
+ .word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */
+ .word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word EXTI9_5_IRQHandler /* External Line[9:5]s */
+ .word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */
+ .word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */
+ .word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */
+ .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
+ .word TIM2_IRQHandler /* TIM2 */
+ .word TIM3_IRQHandler /* TIM3 */
+ .word TIM4_IRQHandler /* TIM4 */
+ .word I2C1_EV_IRQHandler /* I2C1 Event */
+ .word I2C1_ER_IRQHandler /* I2C1 Error */
+ .word I2C2_EV_IRQHandler /* I2C2 Event */
+ .word I2C2_ER_IRQHandler /* I2C2 Error */
+ .word SPI1_IRQHandler /* SPI1 */
+ .word SPI2_IRQHandler /* SPI2 */
+ .word USART1_IRQHandler /* USART1 */
+ .word USART2_IRQHandler /* USART2 */
+ .word 0 /* Reserved */
+ .word EXTI15_10_IRQHandler /* External Line[15:10]s */
+ .word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */
+ .word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */
+ .word 0 /* Reserved */
+ .word SDIO_IRQHandler /* SDIO */
+ .word TIM5_IRQHandler /* TIM5 */
+ .word SPI3_IRQHandler /* SPI3 */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */
+ .word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */
+ .word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */
+ .word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */
+ .word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word OTG_FS_IRQHandler /* USB OTG FS */
+ .word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */
+ .word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */
+ .word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */
+ .word USART6_IRQHandler /* USART6 */
+ .word I2C3_EV_IRQHandler /* I2C3 event */
+ .word I2C3_ER_IRQHandler /* I2C3 error */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word FPU_IRQHandler /* FPU */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word SPI4_IRQHandler /* SPI4 */
+ .word SPI5_IRQHandler /* SPI5 */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMP_STAMP_IRQHandler
+ .thumb_set TAMP_STAMP_IRQHandler,Default_Handler
+
+ .weak RTC_WKUP_IRQHandler
+ .thumb_set RTC_WKUP_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream0_IRQHandler
+ .thumb_set DMA1_Stream0_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream1_IRQHandler
+ .thumb_set DMA1_Stream1_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream2_IRQHandler
+ .thumb_set DMA1_Stream2_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream3_IRQHandler
+ .thumb_set DMA1_Stream3_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream4_IRQHandler
+ .thumb_set DMA1_Stream4_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream5_IRQHandler
+ .thumb_set DMA1_Stream5_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream6_IRQHandler
+ .thumb_set DMA1_Stream6_IRQHandler,Default_Handler
+
+ .weak ADC_IRQHandler
+ .thumb_set ADC_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_TIM9_IRQHandler
+ .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_TIM10_IRQHandler
+ .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_TIM11_IRQHandler
+ .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak OTG_FS_WKUP_IRQHandler
+ .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream7_IRQHandler
+ .thumb_set DMA1_Stream7_IRQHandler,Default_Handler
+
+ .weak SDIO_IRQHandler
+ .thumb_set SDIO_IRQHandler,Default_Handler
+
+ .weak TIM5_IRQHandler
+ .thumb_set TIM5_IRQHandler,Default_Handler
+
+ .weak SPI3_IRQHandler
+ .thumb_set SPI3_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream0_IRQHandler
+ .thumb_set DMA2_Stream0_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream1_IRQHandler
+ .thumb_set DMA2_Stream1_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream2_IRQHandler
+ .thumb_set DMA2_Stream2_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream3_IRQHandler
+ .thumb_set DMA2_Stream3_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream4_IRQHandler
+ .thumb_set DMA2_Stream4_IRQHandler,Default_Handler
+
+ .weak OTG_FS_IRQHandler
+ .thumb_set OTG_FS_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream5_IRQHandler
+ .thumb_set DMA2_Stream5_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream6_IRQHandler
+ .thumb_set DMA2_Stream6_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream7_IRQHandler
+ .thumb_set DMA2_Stream7_IRQHandler,Default_Handler
+
+ .weak USART6_IRQHandler
+ .thumb_set USART6_IRQHandler,Default_Handler
+
+ .weak I2C3_EV_IRQHandler
+ .thumb_set I2C3_EV_IRQHandler,Default_Handler
+
+ .weak I2C3_ER_IRQHandler
+ .thumb_set I2C3_ER_IRQHandler,Default_Handler
+
+ .weak FPU_IRQHandler
+ .thumb_set FPU_IRQHandler,Default_Handler
+
+ .weak SPI4_IRQHandler
+ .thumb_set SPI4_IRQHandler,Default_Handler
+
+ .weak SPI5_IRQHandler
+ .thumb_set SPI5_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/ports/stm32f4/boards/startup_stm32f412zx.s b/ports/stm32f4/boards/startup_stm32f412zx.s
new file mode 100644
index 000000000..801220795
--- /dev/null
+++ b/ports/stm32f4/boards/startup_stm32f412zx.s
@@ -0,0 +1,524 @@
+/**
+ ******************************************************************************
+ * @file startup_stm32f412zx.s
+ * @author MCD Application Team
+ * @brief STM32F412Zx Devices vector table for GCC based toolchains.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M4 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2017 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m4
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
+
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+ ldr sp, =_estack /* set stack pointer */
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+/* bl __libc_init_array */
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ * @param None
+ * @retval None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+*******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+g_pfnVectors:
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+
+ /* External Interrupts */
+ .word WWDG_IRQHandler /* Window WatchDog */
+ .word PVD_IRQHandler /* PVD through EXTI Line detection */
+ .word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */
+ .word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */
+ .word FLASH_IRQHandler /* FLASH */
+ .word RCC_IRQHandler /* RCC */
+ .word EXTI0_IRQHandler /* EXTI Line0 */
+ .word EXTI1_IRQHandler /* EXTI Line1 */
+ .word EXTI2_IRQHandler /* EXTI Line2 */
+ .word EXTI3_IRQHandler /* EXTI Line3 */
+ .word EXTI4_IRQHandler /* EXTI Line4 */
+ .word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */
+ .word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */
+ .word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */
+ .word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */
+ .word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */
+ .word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */
+ .word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */
+ .word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */
+ .word CAN1_TX_IRQHandler /* CAN1 TX */
+ .word CAN1_RX0_IRQHandler /* CAN1 RX0 */
+ .word CAN1_RX1_IRQHandler /* CAN1 RX1 */
+ .word CAN1_SCE_IRQHandler /* CAN1 SCE */
+ .word EXTI9_5_IRQHandler /* External Line[9:5]s */
+ .word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */
+ .word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */
+ .word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */
+ .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
+ .word TIM2_IRQHandler /* TIM2 */
+ .word TIM3_IRQHandler /* TIM3 */
+ .word TIM4_IRQHandler /* TIM4 */
+ .word I2C1_EV_IRQHandler /* I2C1 Event */
+ .word I2C1_ER_IRQHandler /* I2C1 Error */
+ .word I2C2_EV_IRQHandler /* I2C2 Event */
+ .word I2C2_ER_IRQHandler /* I2C2 Error */
+ .word SPI1_IRQHandler /* SPI1 */
+ .word SPI2_IRQHandler /* SPI2 */
+ .word USART1_IRQHandler /* USART1 */
+ .word USART2_IRQHandler /* USART2 */
+ .word USART3_IRQHandler /* USART3 */
+ .word EXTI15_10_IRQHandler /* External Line[15:10]s */
+ .word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */
+ .word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */
+ .word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */
+ .word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */
+ .word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */
+ .word TIM8_CC_IRQHandler /* TIM8 Capture Compare */
+ .word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */
+ .word 0 /* Reserved */
+ .word SDIO_IRQHandler /* SDIO */
+ .word TIM5_IRQHandler /* TIM5 */
+ .word SPI3_IRQHandler /* SPI3 */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word TIM6_IRQHandler /* TIM6 */
+ .word TIM7_IRQHandler /* TIM7 */
+ .word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */
+ .word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */
+ .word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */
+ .word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */
+ .word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */
+ .word DFSDM1_FLT0_IRQHandler /* DFSDM1 Filter0 */
+ .word DFSDM1_FLT1_IRQHandler /* DFSDM1 Filter1 */
+ .word CAN2_TX_IRQHandler /* CAN2 TX */
+ .word CAN2_RX0_IRQHandler /* CAN2 RX0 */
+ .word CAN2_RX1_IRQHandler /* CAN2 RX1 */
+ .word CAN2_SCE_IRQHandler /* CAN2 SCE */
+ .word OTG_FS_IRQHandler /* USB OTG FS */
+ .word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */
+ .word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */
+ .word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */
+ .word USART6_IRQHandler /* USART6 */
+ .word I2C3_EV_IRQHandler /* I2C3 event */
+ .word I2C3_ER_IRQHandler /* I2C3 error */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word RNG_IRQHandler /* RNG */
+ .word FPU_IRQHandler /* FPU */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word SPI4_IRQHandler /* SPI4 */
+ .word SPI5_IRQHandler /* SPI5 */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word QUADSPI_IRQHandler /* QuadSPI */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word FMPI2C1_EV_IRQHandler /* FMPI2C1 Event */
+ .word FMPI2C1_ER_IRQHandler /* FMPI2C1 Error */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMP_STAMP_IRQHandler
+ .thumb_set TAMP_STAMP_IRQHandler,Default_Handler
+
+ .weak RTC_WKUP_IRQHandler
+ .thumb_set RTC_WKUP_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream0_IRQHandler
+ .thumb_set DMA1_Stream0_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream1_IRQHandler
+ .thumb_set DMA1_Stream1_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream2_IRQHandler
+ .thumb_set DMA1_Stream2_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream3_IRQHandler
+ .thumb_set DMA1_Stream3_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream4_IRQHandler
+ .thumb_set DMA1_Stream4_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream5_IRQHandler
+ .thumb_set DMA1_Stream5_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream6_IRQHandler
+ .thumb_set DMA1_Stream6_IRQHandler,Default_Handler
+
+ .weak ADC_IRQHandler
+ .thumb_set ADC_IRQHandler,Default_Handler
+
+ .weak CAN1_TX_IRQHandler
+ .thumb_set CAN1_TX_IRQHandler,Default_Handler
+
+ .weak CAN1_RX0_IRQHandler
+ .thumb_set CAN1_RX0_IRQHandler,Default_Handler
+
+ .weak CAN1_RX1_IRQHandler
+ .thumb_set CAN1_RX1_IRQHandler,Default_Handler
+
+ .weak CAN1_SCE_IRQHandler
+ .thumb_set CAN1_SCE_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_TIM9_IRQHandler
+ .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_TIM10_IRQHandler
+ .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_TIM11_IRQHandler
+ .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak OTG_FS_WKUP_IRQHandler
+ .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
+
+ .weak TIM8_BRK_TIM12_IRQHandler
+ .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler
+
+ .weak TIM8_UP_TIM13_IRQHandler
+ .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler
+
+ .weak TIM8_TRG_COM_TIM14_IRQHandler
+ .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler
+
+ .weak TIM8_CC_IRQHandler
+ .thumb_set TIM8_CC_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream7_IRQHandler
+ .thumb_set DMA1_Stream7_IRQHandler,Default_Handler
+
+ .weak SDIO_IRQHandler
+ .thumb_set SDIO_IRQHandler,Default_Handler
+
+ .weak TIM5_IRQHandler
+ .thumb_set TIM5_IRQHandler,Default_Handler
+
+ .weak SPI3_IRQHandler
+ .thumb_set SPI3_IRQHandler,Default_Handler
+
+ .weak TIM6_IRQHandler
+ .thumb_set TIM6_IRQHandler,Default_Handler
+
+ .weak TIM7_IRQHandler
+ .thumb_set TIM7_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream0_IRQHandler
+ .thumb_set DMA2_Stream0_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream1_IRQHandler
+ .thumb_set DMA2_Stream1_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream2_IRQHandler
+ .thumb_set DMA2_Stream2_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream3_IRQHandler
+ .thumb_set DMA2_Stream3_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream4_IRQHandler
+ .thumb_set DMA2_Stream4_IRQHandler,Default_Handler
+
+ .weak DFSDM1_FLT0_IRQHandler
+ .thumb_set DFSDM1_FLT0_IRQHandler,Default_Handler
+
+ .weak DFSDM1_FLT1_IRQHandler
+ .thumb_set DFSDM1_FLT1_IRQHandler,Default_Handler
+
+ .weak CAN2_TX_IRQHandler
+ .thumb_set CAN2_TX_IRQHandler,Default_Handler
+
+ .weak CAN2_RX0_IRQHandler
+ .thumb_set CAN2_RX0_IRQHandler,Default_Handler
+
+ .weak CAN2_RX1_IRQHandler
+ .thumb_set CAN2_RX1_IRQHandler,Default_Handler
+
+ .weak CAN2_SCE_IRQHandler
+ .thumb_set CAN2_SCE_IRQHandler,Default_Handler
+
+ .weak OTG_FS_IRQHandler
+ .thumb_set OTG_FS_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream5_IRQHandler
+ .thumb_set DMA2_Stream5_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream6_IRQHandler
+ .thumb_set DMA2_Stream6_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream7_IRQHandler
+ .thumb_set DMA2_Stream7_IRQHandler,Default_Handler
+
+ .weak USART6_IRQHandler
+ .thumb_set USART6_IRQHandler,Default_Handler
+
+ .weak I2C3_EV_IRQHandler
+ .thumb_set I2C3_EV_IRQHandler,Default_Handler
+
+ .weak I2C3_ER_IRQHandler
+ .thumb_set I2C3_ER_IRQHandler,Default_Handler
+
+ .weak RNG_IRQHandler
+ .thumb_set RNG_IRQHandler,Default_Handler
+
+ .weak FPU_IRQHandler
+ .thumb_set FPU_IRQHandler,Default_Handler
+
+ .weak SPI4_IRQHandler
+ .thumb_set SPI4_IRQHandler,Default_Handler
+
+ .weak SPI5_IRQHandler
+ .thumb_set SPI5_IRQHandler,Default_Handler
+
+ .weak QUADSPI_IRQHandler
+ .thumb_set QUADSPI_IRQHandler,Default_Handler
+
+ .weak FMPI2C1_EV_IRQHandler
+ .thumb_set FMPI2C1_EV_IRQHandler,Default_Handler
+
+ .weak FMPI2C1_ER_IRQHandler
+ .thumb_set FMPI2C1_ER_IRQHandler,Default_Handler
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/ports/stm32f4/boards/stm32f411.ld b/ports/stm32f4/boards/stm32f411.ld
new file mode 100644
index 000000000..f0d4804f9
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f411.ld
@@ -0,0 +1,189 @@
+/*
+******************************************************************************
+**
+
+** File : LinkerScript.ld
+**
+** Author : Auto-generated by Ac6 System Workbench
+**
+** Abstract : Linker script for STM32F411RETx series
+** 512Kbytes FLASH and 128Kbytes RAM
+**
+** Set heap size, stack size and stack location according
+** to application requirements.
+**
+** Set memory bank area and size if external memory is used.
+**
+** Target : STMicroelectronics STM32
+**
+** Distribution: The file is distributed “as is,” without any warranty
+** of any kind.
+**
+*****************************************************************************
+** @attention
+**
+** <h2><center>&copy; COPYRIGHT(c) 2014 Ac6</center></h2>
+**
+** Redistribution and use in source and binary forms, with or without modification,
+** are permitted provided that the following conditions are met:
+** 1. Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+** 2. Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+** 3. Neither the name of Ac6 nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+*****************************************************************************
+*/
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+/* Highest address of the user mode stack */
+_estack = 0x20020000; /* end of RAM */
+/* Generate a link error if heap and stack don't fit into RAM */
+_Min_Heap_Size = 0x200; /* required amount of heap */
+_Min_Stack_Size = 0x400; /* required amount of stack */
+
+/* Specify the memory areas */
+MEMORY
+{
+RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
+FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K
+}
+
+/* Define output sections */
+SECTIONS
+{
+ /* The startup code goes first into FLASH */
+ .isr_vector :
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector)) /* Startup code */
+ . = ALIGN(4);
+ } >FLASH
+
+ /* The program code and other data goes into FLASH */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text) /* .text sections (code) */
+ *(.text*) /* .text* sections (code) */
+ *(.glue_7) /* glue arm to thumb code */
+ *(.glue_7t) /* glue thumb to arm code */
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ . = ALIGN(4);
+ _etext = .; /* define a global symbols at end of code */
+ } >FLASH
+
+ /* Constant data goes into FLASH */
+ .rodata :
+ {
+ . = ALIGN(4);
+ *(.rodata) /* .rodata sections (constants, strings, etc.) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ . = ALIGN(4);
+ } >FLASH
+
+ .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
+ .ARM : {
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ } >FLASH
+
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array*))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >FLASH
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array*))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } >FLASH
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array*))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } >FLASH
+
+ /* used by the startup to initialize data */
+ _sidata = LOADADDR(.data);
+
+ /* Initialized data sections goes into RAM, load LMA copy after code */
+ .data :
+ {
+ . = ALIGN(4);
+ _sdata = .; /* create a global symbol at data start */
+ *(.data) /* .data sections */
+ *(.data*) /* .data* sections */
+
+ . = ALIGN(4);
+ _edata = .; /* define a global symbol at data end */
+ } >RAM AT> FLASH
+
+
+ /* Uninitialized data section */
+ . = ALIGN(4);
+ .bss :
+ {
+ /* This is used by the startup in order to initialize the .bss secion */
+ _sbss = .; /* define a global symbol at bss start */
+ __bss_start__ = _sbss;
+ *(.bss)
+ *(.bss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .; /* define a global symbol at bss end */
+ __bss_end__ = _ebss;
+ } >RAM
+
+ /* User_heap_stack section, used to check that there is enough RAM left */
+ ._user_heap_stack :
+ {
+ . = ALIGN(8);
+ PROVIDE ( end = . );
+ PROVIDE ( _end = . );
+ . = . + _Min_Heap_Size;
+ . = . + _Min_Stack_Size;
+ . = ALIGN(8);
+ } >RAM
+
+
+
+ /* Remove information from the standard libraries */
+ /DISCARD/ :
+ {
+ libc.a ( * )
+ libm.a ( * )
+ libgcc.a ( * )
+ }
+
+ .ARM.attributes 0 : { *(.ARM.attributes) }
+}
+
+
diff --git a/ports/stm32f4/boards/stm32f411re_discovery/board.c b/ports/stm32f4/boards/stm32f411re_discovery/board.c
new file mode 100644
index 000000000..4421970ee
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f411re_discovery/board.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+
+}
diff --git a/ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.h b/ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.h
new file mode 100644
index 000000000..675443282
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+//Micropython setup
+
+#define MICROPY_HW_BOARD_NAME "STM32F411E_DISCO"
+#define MICROPY_HW_MCU_NAME "STM32F411xE"
+
+#define FLASH_SIZE (0x7D000)
+#define FLASH_PAGE_SIZE (0x4000)
+
+#define CIRCUITPY_INTERNAL_NVM_SIZE (4096)
+#define AUTORESET_DELAY_MS 500
+#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) \ No newline at end of file
diff --git a/ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.mk b/ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.mk
new file mode 100644
index 000000000..7b865b57e
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.mk
@@ -0,0 +1,13 @@
+USB_VID = 0x239A
+USB_PID = 0x802A
+USB_PRODUCT = "STM32F411RE Discovery Board - CPy"
+USB_MANUFACTURER = "Adafruit Industries LLC"
+
+MCU_SERIES = m4
+MCU_VARIANT = stm32f4
+MCU_SUB_VARIANT = stm32f411xe
+CMSIS_MCU = STM32F411xE
+LD_FILE = boards/STM32F411VETx_FLASH.ld
+TEXT0_ADDR = 0x08000000
+TEXT1_ADDR = 0x08020000
+
diff --git a/ports/stm32f4/boards/stm32f411re_discovery/pins.c b/ports/stm32f4/boards/stm32f411re_discovery/pins.c
new file mode 100644
index 000000000..e3a4b5ed6
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f411re_discovery/pins.c
@@ -0,0 +1,90 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_PE02), MP_ROM_PTR(&pin_PE02) },
+ { MP_ROM_QSTR(MP_QSTR_PE03), MP_ROM_PTR(&pin_PE03) },
+ { MP_ROM_QSTR(MP_QSTR_PE04), MP_ROM_PTR(&pin_PE04) },
+ { MP_ROM_QSTR(MP_QSTR_PE05), MP_ROM_PTR(&pin_PE05) },
+ { MP_ROM_QSTR(MP_QSTR_PE06), MP_ROM_PTR(&pin_PE06) },
+ { MP_ROM_QSTR(MP_QSTR_PC13), MP_ROM_PTR(&pin_PC13) },
+ { MP_ROM_QSTR(MP_QSTR_PF02), MP_ROM_PTR(&pin_PF02) },
+ { MP_ROM_QSTR(MP_QSTR_PF03), MP_ROM_PTR(&pin_PF03) },
+ { MP_ROM_QSTR(MP_QSTR_PF10), MP_ROM_PTR(&pin_PF10) },
+ { MP_ROM_QSTR(MP_QSTR_PC00), MP_ROM_PTR(&pin_PC00) },
+ { MP_ROM_QSTR(MP_QSTR_PC01), MP_ROM_PTR(&pin_PC01) },
+ { MP_ROM_QSTR(MP_QSTR_PC02), MP_ROM_PTR(&pin_PC02) },
+ { MP_ROM_QSTR(MP_QSTR_PC03), MP_ROM_PTR(&pin_PC03) },
+ { MP_ROM_QSTR(MP_QSTR_PA01), MP_ROM_PTR(&pin_PA01) },
+ { MP_ROM_QSTR(MP_QSTR_PA02), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_PA03), MP_ROM_PTR(&pin_PA03) },
+ { MP_ROM_QSTR(MP_QSTR_PA04), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_PA05), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_PA06), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_PA07), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_PC04), MP_ROM_PTR(&pin_PC04) },
+ { MP_ROM_QSTR(MP_QSTR_PC05), MP_ROM_PTR(&pin_PC05) },
+ { MP_ROM_QSTR(MP_QSTR_PB00), MP_ROM_PTR(&pin_PB00) },
+ { MP_ROM_QSTR(MP_QSTR_PB01), MP_ROM_PTR(&pin_PB01) },
+ { MP_ROM_QSTR(MP_QSTR_PF11), MP_ROM_PTR(&pin_PF11) },
+ { MP_ROM_QSTR(MP_QSTR_PF13), MP_ROM_PTR(&pin_PF13) },
+ { MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_PB11), MP_ROM_PTR(&pin_PB11) },
+ { MP_ROM_QSTR(MP_QSTR_PB12), MP_ROM_PTR(&pin_PB12) },
+ { MP_ROM_QSTR(MP_QSTR_PB13), MP_ROM_PTR(&pin_PB13) },
+ { MP_ROM_QSTR(MP_QSTR_PB14), MP_ROM_PTR(&pin_PB14) },
+ { MP_ROM_QSTR(MP_QSTR_PB15), MP_ROM_PTR(&pin_PB15) },
+ { MP_ROM_QSTR(MP_QSTR_PD12), MP_ROM_PTR(&pin_PD12) },
+ { MP_ROM_QSTR(MP_QSTR_PD13), MP_ROM_PTR(&pin_PD13) },
+ { MP_ROM_QSTR(MP_QSTR_PG02), MP_ROM_PTR(&pin_PG02) },
+ { MP_ROM_QSTR(MP_QSTR_PC06), MP_ROM_PTR(&pin_PC06) },
+ { MP_ROM_QSTR(MP_QSTR_PC07), MP_ROM_PTR(&pin_PC07) },
+ { MP_ROM_QSTR(MP_QSTR_PC09), MP_ROM_PTR(&pin_PC09) },
+ { MP_ROM_QSTR(MP_QSTR_PA08), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_PA10), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_PA13), MP_ROM_PTR(&pin_PA13) },
+ { MP_ROM_QSTR(MP_QSTR_PA14), MP_ROM_PTR(&pin_PA14) },
+ { MP_ROM_QSTR(MP_QSTR_PA15), MP_ROM_PTR(&pin_PA15) },
+ { MP_ROM_QSTR(MP_QSTR_PD06), MP_ROM_PTR(&pin_PD06) },
+ { MP_ROM_QSTR(MP_QSTR_PG09), MP_ROM_PTR(&pin_PG09) },
+ { MP_ROM_QSTR(MP_QSTR_PG10), MP_ROM_PTR(&pin_PG10) },
+ { MP_ROM_QSTR(MP_QSTR_PG11), MP_ROM_PTR(&pin_PG11) },
+ { MP_ROM_QSTR(MP_QSTR_PG12), MP_ROM_PTR(&pin_PG12) },
+ { MP_ROM_QSTR(MP_QSTR_PG13), MP_ROM_PTR(&pin_PG13) },
+ { MP_ROM_QSTR(MP_QSTR_PG14), MP_ROM_PTR(&pin_PG14) },
+ { MP_ROM_QSTR(MP_QSTR_PB03), MP_ROM_PTR(&pin_PB03) },
+ { MP_ROM_QSTR(MP_QSTR_PB04), MP_ROM_PTR(&pin_PB04) },
+ { MP_ROM_QSTR(MP_QSTR_PB05), MP_ROM_PTR(&pin_PB05) },
+ { MP_ROM_QSTR(MP_QSTR_PB06), MP_ROM_PTR(&pin_PB06) },
+ { MP_ROM_QSTR(MP_QSTR_PB07), MP_ROM_PTR(&pin_PB07) },
+ { MP_ROM_QSTR(MP_QSTR_PB08), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_PB09), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_PE00), MP_ROM_PTR(&pin_PE00) },
+ { MP_ROM_QSTR(MP_QSTR_PE01), MP_ROM_PTR(&pin_PE01) },
+ { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA15) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PG10) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PG11) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PF03) },
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PF10) },
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PG12) },
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PF04) },
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PG13) },
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PG14) },
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PG09) },
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA01) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PC01) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PC03) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PC04) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PC05) }, //alt PB09, see F401ZG-DISCO manual
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB00) }, //alt PB10, see F401ZG-DISCO manual
+ { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_PE00) },
+ { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_PE01) },
+ { MP_ROM_QSTR(MP_QSTR_LED3), MP_ROM_PTR(&pin_PE02) },
+ { MP_ROM_QSTR(MP_QSTR_LED4), MP_ROM_PTR(&pin_PE03) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/stm32f4/boards/stm32f411re_discovery/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/stm32f411re_discovery/stm32f4xx_hal_conf.h
new file mode 100644
index 000000000..548c501dc
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f411re_discovery/stm32f4xx_hal_conf.h
@@ -0,0 +1,439 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_conf_template.h
+ * @author MCD Application Team
+ * @brief HAL configuration template file.
+ * This file should be copied to the application folder and renamed
+ * to stm32f4xx_hal_conf.h.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_HAL_CONF_H
+#define __STM32F4xx_HAL_CONF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* ########################## Module Selection ############################## */
+/**
+ * @brief This is the list of modules to be used in the HAL driver
+ */
+#define HAL_MODULE_ENABLED
+
+ /* #define HAL_ADC_MODULE_ENABLED */
+/* #define HAL_CRYP_MODULE_ENABLED */
+/* #define HAL_CAN_MODULE_ENABLED */
+/* #define HAL_CRC_MODULE_ENABLED */
+/* #define HAL_CRYP_MODULE_ENABLED */
+/* #define HAL_DAC_MODULE_ENABLED */
+/* #define HAL_DCMI_MODULE_ENABLED */
+/* #define HAL_DMA2D_MODULE_ENABLED */
+/* #define HAL_ETH_MODULE_ENABLED */
+/* #define HAL_NAND_MODULE_ENABLED */
+/* #define HAL_NOR_MODULE_ENABLED */
+/* #define HAL_PCCARD_MODULE_ENABLED */
+/* #define HAL_SRAM_MODULE_ENABLED */
+/* #define HAL_SDRAM_MODULE_ENABLED */
+/* #define HAL_HASH_MODULE_ENABLED */
+#define HAL_I2C_MODULE_ENABLED
+#define HAL_I2S_MODULE_ENABLED
+/* #define HAL_IWDG_MODULE_ENABLED */
+/* #define HAL_LTDC_MODULE_ENABLED */
+/* #define HAL_RNG_MODULE_ENABLED */
+/* #define HAL_RTC_MODULE_ENABLED */
+/* #define HAL_SAI_MODULE_ENABLED */
+/* #define HAL_SD_MODULE_ENABLED */
+/* #define HAL_MMC_MODULE_ENABLED */
+#define HAL_SPI_MODULE_ENABLED
+/* #define HAL_TIM_MODULE_ENABLED */
+#define HAL_UART_MODULE_ENABLED
+/* #define HAL_USART_MODULE_ENABLED */
+/* #define HAL_IRDA_MODULE_ENABLED */
+/* #define HAL_SMARTCARD_MODULE_ENABLED */
+/* #define HAL_WWDG_MODULE_ENABLED */
+#define HAL_PCD_MODULE_ENABLED
+/* #define HAL_HCD_MODULE_ENABLED */
+/* #define HAL_DSI_MODULE_ENABLED */
+/* #define HAL_QSPI_MODULE_ENABLED */
+/* #define HAL_QSPI_MODULE_ENABLED */
+/* #define HAL_CEC_MODULE_ENABLED */
+/* #define HAL_FMPI2C_MODULE_ENABLED */
+/* #define HAL_SPDIFRX_MODULE_ENABLED */
+/* #define HAL_DFSDM_MODULE_ENABLED */
+/* #define HAL_LPTIM_MODULE_ENABLED */
+/* #define HAL_EXTI_MODULE_ENABLED */
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_EXTI_MODULE_ENABLED
+#define HAL_DMA_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
+#define HAL_PWR_MODULE_ENABLED
+#define HAL_CORTEX_MODULE_ENABLED
+
+/* ########################## HSE/HSI Values adaptation ##################### */
+/**
+ * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSE is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined (HSE_STARTUP_TIMEOUT)
+ #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */
+#endif /* HSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief Internal High Speed oscillator (HSI) value.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSI is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+ * @brief Internal Low Speed oscillator (LSI) value.
+ */
+#if !defined (LSI_VALUE)
+ #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/
+#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
+ The real value may vary depending on the variations
+ in voltage and temperature.*/
+/**
+ * @brief External Low Speed oscillator (LSE) value.
+ */
+#if !defined (LSE_VALUE)
+ #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */
+#endif /* LSE_VALUE */
+
+#if !defined (LSE_STARTUP_TIMEOUT)
+ #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */
+#endif /* LSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief External clock source for I2S peripheral
+ * This value is used by the I2S HAL module to compute the I2S clock source
+ * frequency, this source is inserted directly through I2S_CKIN pad.
+ */
+#if !defined (EXTERNAL_CLOCK_VALUE)
+ #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the External audio frequency in Hz*/
+#endif /* EXTERNAL_CLOCK_VALUE */
+
+/* Tip: To avoid modifying this file each time you need to use different HSE,
+ === you can define the HSE value in your toolchain compiler preprocessor. */
+
+/* ########################### System Configuration ######################### */
+/**
+ * @brief This is the HAL system configuration section
+ */
+#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */
+#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */
+#define USE_RTOS 0U
+#define PREFETCH_ENABLE 1U
+#define INSTRUCTION_CACHE_ENABLE 1U
+#define DATA_CACHE_ENABLE 1U
+
+/* ########################## Assert Selection ############################## */
+/**
+ * @brief Uncomment the line below to expanse the "assert_param" macro in the
+ * HAL drivers code
+ */
+/* #define USE_FULL_ASSERT 1U */
+
+/* ################## Ethernet peripheral configuration ##################### */
+
+/* Section 1 : Ethernet peripheral configuration */
+
+/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
+#define MAC_ADDR0 2U
+#define MAC_ADDR1 0U
+#define MAC_ADDR2 0U
+#define MAC_ADDR3 0U
+#define MAC_ADDR4 0U
+#define MAC_ADDR5 0U
+
+/* Definition of the Ethernet driver buffers size and count */
+#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
+#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
+#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
+#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
+
+/* Section 2: PHY configuration section */
+
+/* DP83848_PHY_ADDRESS Address*/
+#define DP83848_PHY_ADDRESS 0x01U
+/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
+#define PHY_RESET_DELAY ((uint32_t)0x000000FFU)
+/* PHY Configuration delay */
+#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU)
+
+#define PHY_READ_TO ((uint32_t)0x0000FFFFU)
+#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU)
+
+/* Section 3: Common PHY Registers */
+
+#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */
+#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */
+
+#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
+#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */
+#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */
+#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */
+#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */
+#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */
+#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */
+#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */
+#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */
+#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */
+
+#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */
+#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
+#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */
+
+/* Section 4: Extended PHY Registers */
+#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
+
+#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
+#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
+
+/* ################## SPI peripheral configuration ########################## */
+
+/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
+* Activated: CRC code is present inside driver
+* Deactivated: CRC code cleaned from driver
+*/
+
+#define USE_SPI_CRC 0U
+
+/* Includes ------------------------------------------------------------------*/
+/**
+ * @brief Include module's header file
+ */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rcc.h"
+#endif /* HAL_RCC_MODULE_ENABLED */
+
+#ifdef HAL_EXTI_MODULE_ENABLED
+ #include "stm32f4xx_hal_exti.h"
+#endif /* HAL_EXTI_MODULE_ENABLED */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+ #include "stm32f4xx_hal_gpio.h"
+#endif /* HAL_GPIO_MODULE_ENABLED */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma.h"
+#endif /* HAL_DMA_MODULE_ENABLED */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+ #include "stm32f4xx_hal_cortex.h"
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+ #include "stm32f4xx_hal_adc.h"
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+#ifdef HAL_CAN_MODULE_ENABLED
+ #include "stm32f4xx_hal_can.h"
+#endif /* HAL_CAN_MODULE_ENABLED */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+ #include "stm32f4xx_hal_crc.h"
+#endif /* HAL_CRC_MODULE_ENABLED */
+
+#ifdef HAL_CRYP_MODULE_ENABLED
+ #include "stm32f4xx_hal_cryp.h"
+#endif /* HAL_CRYP_MODULE_ENABLED */
+
+#ifdef HAL_DMA2D_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma2d.h"
+#endif /* HAL_DMA2D_MODULE_ENABLED */
+
+#ifdef HAL_DAC_MODULE_ENABLED
+ #include "stm32f4xx_hal_dac.h"
+#endif /* HAL_DAC_MODULE_ENABLED */
+
+#ifdef HAL_DCMI_MODULE_ENABLED
+ #include "stm32f4xx_hal_dcmi.h"
+#endif /* HAL_DCMI_MODULE_ENABLED */
+
+#ifdef HAL_ETH_MODULE_ENABLED
+ #include "stm32f4xx_hal_eth.h"
+#endif /* HAL_ETH_MODULE_ENABLED */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_flash.h"
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+#ifdef HAL_SRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sram.h"
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
+#ifdef HAL_NOR_MODULE_ENABLED
+ #include "stm32f4xx_hal_nor.h"
+#endif /* HAL_NOR_MODULE_ENABLED */
+
+#ifdef HAL_NAND_MODULE_ENABLED
+ #include "stm32f4xx_hal_nand.h"
+#endif /* HAL_NAND_MODULE_ENABLED */
+
+#ifdef HAL_PCCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pccard.h"
+#endif /* HAL_PCCARD_MODULE_ENABLED */
+
+#ifdef HAL_SDRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sdram.h"
+#endif /* HAL_SDRAM_MODULE_ENABLED */
+
+#ifdef HAL_HASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_hash.h"
+#endif /* HAL_HASH_MODULE_ENABLED */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2c.h"
+#endif /* HAL_I2C_MODULE_ENABLED */
+
+#ifdef HAL_I2S_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2s.h"
+#endif /* HAL_I2S_MODULE_ENABLED */
+
+#ifdef HAL_IWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_iwdg.h"
+#endif /* HAL_IWDG_MODULE_ENABLED */
+
+#ifdef HAL_LTDC_MODULE_ENABLED
+ #include "stm32f4xx_hal_ltdc.h"
+#endif /* HAL_LTDC_MODULE_ENABLED */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+ #include "stm32f4xx_hal_pwr.h"
+#endif /* HAL_PWR_MODULE_ENABLED */
+
+#ifdef HAL_RNG_MODULE_ENABLED
+ #include "stm32f4xx_hal_rng.h"
+#endif /* HAL_RNG_MODULE_ENABLED */
+
+#ifdef HAL_RTC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rtc.h"
+#endif /* HAL_RTC_MODULE_ENABLED */
+
+#ifdef HAL_SAI_MODULE_ENABLED
+ #include "stm32f4xx_hal_sai.h"
+#endif /* HAL_SAI_MODULE_ENABLED */
+
+#ifdef HAL_SD_MODULE_ENABLED
+ #include "stm32f4xx_hal_sd.h"
+#endif /* HAL_SD_MODULE_ENABLED */
+
+#ifdef HAL_MMC_MODULE_ENABLED
+ #include "stm32f4xx_hal_mmc.h"
+#endif /* HAL_MMC_MODULE_ENABLED */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+ #include "stm32f4xx_hal_spi.h"
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+ #include "stm32f4xx_hal_tim.h"
+#endif /* HAL_TIM_MODULE_ENABLED */
+
+#ifdef HAL_UART_MODULE_ENABLED
+ #include "stm32f4xx_hal_uart.h"
+#endif /* HAL_UART_MODULE_ENABLED */
+
+#ifdef HAL_USART_MODULE_ENABLED
+ #include "stm32f4xx_hal_usart.h"
+#endif /* HAL_USART_MODULE_ENABLED */
+
+#ifdef HAL_IRDA_MODULE_ENABLED
+ #include "stm32f4xx_hal_irda.h"
+#endif /* HAL_IRDA_MODULE_ENABLED */
+
+#ifdef HAL_SMARTCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_smartcard.h"
+#endif /* HAL_SMARTCARD_MODULE_ENABLED */
+
+#ifdef HAL_WWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_wwdg.h"
+#endif /* HAL_WWDG_MODULE_ENABLED */
+
+#ifdef HAL_PCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pcd.h"
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+#ifdef HAL_HCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_hcd.h"
+#endif /* HAL_HCD_MODULE_ENABLED */
+
+#ifdef HAL_DSI_MODULE_ENABLED
+ #include "stm32f4xx_hal_dsi.h"
+#endif /* HAL_DSI_MODULE_ENABLED */
+
+#ifdef HAL_QSPI_MODULE_ENABLED
+ #include "stm32f4xx_hal_qspi.h"
+#endif /* HAL_QSPI_MODULE_ENABLED */
+
+#ifdef HAL_CEC_MODULE_ENABLED
+ #include "stm32f4xx_hal_cec.h"
+#endif /* HAL_CEC_MODULE_ENABLED */
+
+#ifdef HAL_FMPI2C_MODULE_ENABLED
+ #include "stm32f4xx_hal_fmpi2c.h"
+#endif /* HAL_FMPI2C_MODULE_ENABLED */
+
+#ifdef HAL_SPDIFRX_MODULE_ENABLED
+ #include "stm32f4xx_hal_spdifrx.h"
+#endif /* HAL_SPDIFRX_MODULE_ENABLED */
+
+#ifdef HAL_DFSDM_MODULE_ENABLED
+ #include "stm32f4xx_hal_dfsdm.h"
+#endif /* HAL_DFSDM_MODULE_ENABLED */
+
+#ifdef HAL_LPTIM_MODULE_ENABLED
+ #include "stm32f4xx_hal_lptim.h"
+#endif /* HAL_LPTIM_MODULE_ENABLED */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief The assert_param macro is used for function's parameters check.
+ * @param expr: If expr is false, it calls assert_failed function
+ * which reports the name of the source file and the source
+ * line number of the call that failed.
+ * If expr is true, it returns no value.
+ * @retval None
+ */
+ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+ void assert_failed(uint8_t* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0U)
+#endif /* USE_FULL_ASSERT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F4xx_HAL_CONF_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/ports/stm32f4/boards/stm32f411re_discovery/stm32f4xx_hal_msp.c b/ports/stm32f4/boards/stm32f411re_discovery/stm32f4xx_hal_msp.c
new file mode 100644
index 000000000..4989f9889
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f411re_discovery/stm32f4xx_hal_msp.c
@@ -0,0 +1,427 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * File Name : stm32f4xx_hal_msp.c
+ * Description : This file provides code for the MSP Initialization
+ * and de-Initialization codes.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+#include "stm32f4xx_hal.h"
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN TD */
+
+/* USER CODE END TD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN Define */
+#define DATA_Ready_Pin GPIO_PIN_2
+#define DATA_Ready_GPIO_Port GPIOE
+#define CS_I2C_SPI_Pin GPIO_PIN_3
+#define CS_I2C_SPI_GPIO_Port GPIOE
+#define INT1_Pin GPIO_PIN_4
+#define INT1_GPIO_Port GPIOE
+#define INT2_Pin GPIO_PIN_5
+#define INT2_GPIO_Port GPIOE
+#define PC14_OSC32_IN_Pin GPIO_PIN_14
+#define PC14_OSC32_IN_GPIO_Port GPIOC
+#define PC15_OSC32_OUT_Pin GPIO_PIN_15
+#define PC15_OSC32_OUT_GPIO_Port GPIOC
+#define PH0_OSC_IN_Pin GPIO_PIN_0
+#define PH0_OSC_IN_GPIO_Port GPIOH
+#define PH1_OSC_OUT_Pin GPIO_PIN_1
+#define PH1_OSC_OUT_GPIO_Port GPIOH
+#define OTG_FS_PowerSwitchOn_Pin GPIO_PIN_0
+#define OTG_FS_PowerSwitchOn_GPIO_Port GPIOC
+#define PDM_OUT_Pin GPIO_PIN_3
+#define PDM_OUT_GPIO_Port GPIOC
+#define I2S3_WS_Pin GPIO_PIN_4
+#define I2S3_WS_GPIO_Port GPIOA
+#define SPI1_SCK_Pin GPIO_PIN_5
+#define SPI1_SCK_GPIO_Port GPIOA
+#define SPI1_MISO_Pin GPIO_PIN_6
+#define SPI1_MISO_GPIO_Port GPIOA
+#define SPI1_MOSI_Pin GPIO_PIN_7
+#define SPI1_MOSI_GPIO_Port GPIOA
+#define CLK_IN_Pin GPIO_PIN_10
+#define CLK_IN_GPIO_Port GPIOB
+#define LD4_Pin GPIO_PIN_12
+#define LD4_GPIO_Port GPIOD
+#define LD3_Pin GPIO_PIN_13
+#define LD3_GPIO_Port GPIOD
+#define LD5_Pin GPIO_PIN_14
+#define LD5_GPIO_Port GPIOD
+#define LD6_Pin GPIO_PIN_15
+#define LD6_GPIO_Port GPIOD
+#define I2S3_MCK_Pin GPIO_PIN_7
+#define I2S3_MCK_GPIO_Port GPIOC
+#define VBUS_FS_Pin GPIO_PIN_9
+#define VBUS_FS_GPIO_Port GPIOA
+#define OTG_FS_ID_Pin GPIO_PIN_10
+#define OTG_FS_ID_GPIO_Port GPIOA
+#define OTG_FS_DM_Pin GPIO_PIN_11
+#define OTG_FS_DM_GPIO_Port GPIOA
+#define OTG_FS_DP_Pin GPIO_PIN_12
+#define OTG_FS_DP_GPIO_Port GPIOA
+#define SWDIO_Pin GPIO_PIN_13
+#define SWDIO_GPIO_Port GPIOA
+#define SWCLK_Pin GPIO_PIN_14
+#define SWCLK_GPIO_Port GPIOA
+#define I2S3_SCK_Pin GPIO_PIN_10
+#define I2S3_SCK_GPIO_Port GPIOC
+#define I2S3_SD_Pin GPIO_PIN_12
+#define I2S3_SD_GPIO_Port GPIOC
+#define Audio_RST_Pin GPIO_PIN_4
+#define Audio_RST_GPIO_Port GPIOD
+#define OTG_FS_OverCurrent_Pin GPIO_PIN_5
+#define OTG_FS_OverCurrent_GPIO_Port GPIOD
+#define SWO_Pin GPIO_PIN_3
+#define SWO_GPIO_Port GPIOB
+#define Audio_SCL_Pin GPIO_PIN_6
+#define Audio_SCL_GPIO_Port GPIOB
+#define Audio_SDA_Pin GPIO_PIN_9
+#define Audio_SDA_GPIO_Port GPIOB
+#define MEMS_INT2_Pin GPIO_PIN_1
+#define MEMS_INT2_GPIO_Port GPIOE
+
+/* USER CODE END Define */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN Macro */
+
+/* USER CODE END Macro */
+
+/* Private variables ---------------------------------------------------------*/
+/* USER CODE BEGIN PV */
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+/* USER CODE BEGIN PFP */
+
+/* USER CODE END PFP */
+
+/* External functions --------------------------------------------------------*/
+/* USER CODE BEGIN ExternalFunctions */
+
+/* USER CODE END ExternalFunctions */
+
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+/**
+ * Initializes the Global MSP.
+ */
+void HAL_MspInit(void)
+{
+ /* USER CODE BEGIN MspInit 0 */
+
+ /* USER CODE END MspInit 0 */
+
+ __HAL_RCC_SYSCFG_CLK_ENABLE();
+ __HAL_RCC_PWR_CLK_ENABLE();
+
+ HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
+
+ /* System interrupt init*/
+
+ /* USER CODE BEGIN MspInit 1 */
+
+ /* USER CODE END MspInit 1 */
+}
+
+/**
+* @brief I2C MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hi2c: I2C handle pointer
+* @retval None
+*/
+void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(hi2c->Instance==I2C1)
+ {
+ /* USER CODE BEGIN I2C1_MspInit 0 */
+
+ /* USER CODE END I2C1_MspInit 0 */
+
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ /**I2C1 GPIO Configuration
+ PB6 ------> I2C1_SCL
+ PB9 ------> I2C1_SDA
+ */
+ GPIO_InitStruct.Pin = Audio_SCL_Pin|Audio_SDA_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ /* Peripheral clock enable */
+ __HAL_RCC_I2C1_CLK_ENABLE();
+ /* USER CODE BEGIN I2C1_MspInit 1 */
+
+ /* USER CODE END I2C1_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief I2C MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hi2c: I2C handle pointer
+* @retval None
+*/
+void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
+{
+ if(hi2c->Instance==I2C1)
+ {
+ /* USER CODE BEGIN I2C1_MspDeInit 0 */
+
+ /* USER CODE END I2C1_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_I2C1_CLK_DISABLE();
+
+ /**I2C1 GPIO Configuration
+ PB6 ------> I2C1_SCL
+ PB9 ------> I2C1_SDA
+ */
+ HAL_GPIO_DeInit(GPIOB, Audio_SCL_Pin|Audio_SDA_Pin);
+
+ /* USER CODE BEGIN I2C1_MspDeInit 1 */
+
+ /* USER CODE END I2C1_MspDeInit 1 */
+ }
+
+}
+
+/**
+* @brief I2S MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hi2s: I2S handle pointer
+* @retval None
+*/
+void HAL_I2S_MspInit(I2S_HandleTypeDef* hi2s)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(hi2s->Instance==SPI2)
+ {
+ /* USER CODE BEGIN SPI2_MspInit 0 */
+
+ /* USER CODE END SPI2_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_SPI2_CLK_ENABLE();
+
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ /**I2S2 GPIO Configuration
+ PC2 ------> I2S2_ext_SD
+ PC3 ------> I2S2_SD
+ PB10 ------> I2S2_CK
+ PB12 ------> I2S2_WS
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_2;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Alternate = GPIO_AF6_I2S2ext;
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = PDM_OUT_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
+ HAL_GPIO_Init(PDM_OUT_GPIO_Port, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = CLK_IN_Pin|GPIO_PIN_12;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN SPI2_MspInit 1 */
+
+ /* USER CODE END SPI2_MspInit 1 */
+ }
+ else if(hi2s->Instance==SPI3)
+ {
+ /* USER CODE BEGIN SPI3_MspInit 0 */
+
+ /* USER CODE END SPI3_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_SPI3_CLK_ENABLE();
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ /**I2S3 GPIO Configuration
+ PA4 ------> I2S3_WS
+ PC7 ------> I2S3_MCK
+ PC10 ------> I2S3_CK
+ PC12 ------> I2S3_SD
+ */
+ GPIO_InitStruct.Pin = I2S3_WS_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
+ HAL_GPIO_Init(I2S3_WS_GPIO_Port, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = I2S3_MCK_Pin|I2S3_SCK_Pin|I2S3_SD_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN SPI3_MspInit 1 */
+
+ /* USER CODE END SPI3_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief I2S MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hi2s: I2S handle pointer
+* @retval None
+*/
+void HAL_I2S_MspDeInit(I2S_HandleTypeDef* hi2s)
+{
+ if(hi2s->Instance==SPI2)
+ {
+ /* USER CODE BEGIN SPI2_MspDeInit 0 */
+
+ /* USER CODE END SPI2_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_SPI2_CLK_DISABLE();
+
+ /**I2S2 GPIO Configuration
+ PC2 ------> I2S2_ext_SD
+ PC3 ------> I2S2_SD
+ PB10 ------> I2S2_CK
+ PB12 ------> I2S2_WS
+ */
+ HAL_GPIO_DeInit(GPIOC, GPIO_PIN_2|PDM_OUT_Pin);
+
+ HAL_GPIO_DeInit(GPIOB, CLK_IN_Pin|GPIO_PIN_12);
+
+ /* USER CODE BEGIN SPI2_MspDeInit 1 */
+
+ /* USER CODE END SPI2_MspDeInit 1 */
+ }
+ else if(hi2s->Instance==SPI3)
+ {
+ /* USER CODE BEGIN SPI3_MspDeInit 0 */
+
+ /* USER CODE END SPI3_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_SPI3_CLK_DISABLE();
+
+ /**I2S3 GPIO Configuration
+ PA4 ------> I2S3_WS
+ PC7 ------> I2S3_MCK
+ PC10 ------> I2S3_CK
+ PC12 ------> I2S3_SD
+ */
+ HAL_GPIO_DeInit(I2S3_WS_GPIO_Port, I2S3_WS_Pin);
+
+ HAL_GPIO_DeInit(GPIOC, I2S3_MCK_Pin|I2S3_SCK_Pin|I2S3_SD_Pin);
+
+ /* USER CODE BEGIN SPI3_MspDeInit 1 */
+
+ /* USER CODE END SPI3_MspDeInit 1 */
+ }
+
+}
+
+/**
+* @brief SPI MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hspi: SPI handle pointer
+* @retval None
+*/
+void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(hspi->Instance==SPI1)
+ {
+ /* USER CODE BEGIN SPI1_MspInit 0 */
+
+ /* USER CODE END SPI1_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_SPI1_CLK_ENABLE();
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ /**SPI1 GPIO Configuration
+ PA5 ------> SPI1_SCK
+ PA6 ------> SPI1_MISO
+ PA7 ------> SPI1_MOSI
+ */
+ GPIO_InitStruct.Pin = SPI1_SCK_Pin|SPI1_MISO_Pin|SPI1_MOSI_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN SPI1_MspInit 1 */
+
+ /* USER CODE END SPI1_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief SPI MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hspi: SPI handle pointer
+* @retval None
+*/
+void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
+{
+ if(hspi->Instance==SPI1)
+ {
+ /* USER CODE BEGIN SPI1_MspDeInit 0 */
+
+ /* USER CODE END SPI1_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_SPI1_CLK_DISABLE();
+
+ /**SPI1 GPIO Configuration
+ PA5 ------> SPI1_SCK
+ PA6 ------> SPI1_MISO
+ PA7 ------> SPI1_MOSI
+ */
+ HAL_GPIO_DeInit(GPIOA, SPI1_SCK_Pin|SPI1_MISO_Pin|SPI1_MOSI_Pin);
+
+ /* USER CODE BEGIN SPI1_MspDeInit 1 */
+
+ /* USER CODE END SPI1_MspDeInit 1 */
+ }
+
+}
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/board.c b/ports/stm32f4/boards/stm32f412zg_discovery/board.c
new file mode 100644
index 000000000..4421970ee
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f412zg_discovery/board.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+
+}
diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h
new file mode 100644
index 000000000..416944257
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+//Micropython setup
+
+#define MICROPY_HW_BOARD_NAME "STM32F412G_DISCO"
+#define MICROPY_HW_MCU_NAME "STM32F412xGS"
+
+#define FLASH_SIZE (0x100000)
+#define FLASH_PAGE_SIZE (0x4000)
+
+#define CIRCUITPY_INTERNAL_NVM_SIZE (4096)
+#define AUTORESET_DELAY_MS 500
+#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) \ No newline at end of file
diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk
new file mode 100644
index 000000000..444795874
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk
@@ -0,0 +1,13 @@
+USB_VID = 0x483
+USB_PID = 0x572B
+USB_PRODUCT = "STM32F412ZG Discovery Board - CPy"
+USB_MANUFACTURER = "STMicroelectronics"
+
+MCU_SERIES = m4
+MCU_VARIANT = stm32f4
+MCU_SUB_VARIANT = stm32f412zx
+CMSIS_MCU = STM32F412xG
+LD_FILE = boards/STM32F412ZGTx_FLASH.ld
+TEXT0_ADDR = 0x08000000
+TEXT1_ADDR = 0x08020000
+
diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/pins.c b/ports/stm32f4/boards/stm32f412zg_discovery/pins.c
new file mode 100644
index 000000000..e3a4b5ed6
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f412zg_discovery/pins.c
@@ -0,0 +1,90 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_PE02), MP_ROM_PTR(&pin_PE02) },
+ { MP_ROM_QSTR(MP_QSTR_PE03), MP_ROM_PTR(&pin_PE03) },
+ { MP_ROM_QSTR(MP_QSTR_PE04), MP_ROM_PTR(&pin_PE04) },
+ { MP_ROM_QSTR(MP_QSTR_PE05), MP_ROM_PTR(&pin_PE05) },
+ { MP_ROM_QSTR(MP_QSTR_PE06), MP_ROM_PTR(&pin_PE06) },
+ { MP_ROM_QSTR(MP_QSTR_PC13), MP_ROM_PTR(&pin_PC13) },
+ { MP_ROM_QSTR(MP_QSTR_PF02), MP_ROM_PTR(&pin_PF02) },
+ { MP_ROM_QSTR(MP_QSTR_PF03), MP_ROM_PTR(&pin_PF03) },
+ { MP_ROM_QSTR(MP_QSTR_PF10), MP_ROM_PTR(&pin_PF10) },
+ { MP_ROM_QSTR(MP_QSTR_PC00), MP_ROM_PTR(&pin_PC00) },
+ { MP_ROM_QSTR(MP_QSTR_PC01), MP_ROM_PTR(&pin_PC01) },
+ { MP_ROM_QSTR(MP_QSTR_PC02), MP_ROM_PTR(&pin_PC02) },
+ { MP_ROM_QSTR(MP_QSTR_PC03), MP_ROM_PTR(&pin_PC03) },
+ { MP_ROM_QSTR(MP_QSTR_PA01), MP_ROM_PTR(&pin_PA01) },
+ { MP_ROM_QSTR(MP_QSTR_PA02), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_PA03), MP_ROM_PTR(&pin_PA03) },
+ { MP_ROM_QSTR(MP_QSTR_PA04), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_PA05), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_PA06), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_PA07), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_PC04), MP_ROM_PTR(&pin_PC04) },
+ { MP_ROM_QSTR(MP_QSTR_PC05), MP_ROM_PTR(&pin_PC05) },
+ { MP_ROM_QSTR(MP_QSTR_PB00), MP_ROM_PTR(&pin_PB00) },
+ { MP_ROM_QSTR(MP_QSTR_PB01), MP_ROM_PTR(&pin_PB01) },
+ { MP_ROM_QSTR(MP_QSTR_PF11), MP_ROM_PTR(&pin_PF11) },
+ { MP_ROM_QSTR(MP_QSTR_PF13), MP_ROM_PTR(&pin_PF13) },
+ { MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_PB11), MP_ROM_PTR(&pin_PB11) },
+ { MP_ROM_QSTR(MP_QSTR_PB12), MP_ROM_PTR(&pin_PB12) },
+ { MP_ROM_QSTR(MP_QSTR_PB13), MP_ROM_PTR(&pin_PB13) },
+ { MP_ROM_QSTR(MP_QSTR_PB14), MP_ROM_PTR(&pin_PB14) },
+ { MP_ROM_QSTR(MP_QSTR_PB15), MP_ROM_PTR(&pin_PB15) },
+ { MP_ROM_QSTR(MP_QSTR_PD12), MP_ROM_PTR(&pin_PD12) },
+ { MP_ROM_QSTR(MP_QSTR_PD13), MP_ROM_PTR(&pin_PD13) },
+ { MP_ROM_QSTR(MP_QSTR_PG02), MP_ROM_PTR(&pin_PG02) },
+ { MP_ROM_QSTR(MP_QSTR_PC06), MP_ROM_PTR(&pin_PC06) },
+ { MP_ROM_QSTR(MP_QSTR_PC07), MP_ROM_PTR(&pin_PC07) },
+ { MP_ROM_QSTR(MP_QSTR_PC09), MP_ROM_PTR(&pin_PC09) },
+ { MP_ROM_QSTR(MP_QSTR_PA08), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_PA10), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_PA13), MP_ROM_PTR(&pin_PA13) },
+ { MP_ROM_QSTR(MP_QSTR_PA14), MP_ROM_PTR(&pin_PA14) },
+ { MP_ROM_QSTR(MP_QSTR_PA15), MP_ROM_PTR(&pin_PA15) },
+ { MP_ROM_QSTR(MP_QSTR_PD06), MP_ROM_PTR(&pin_PD06) },
+ { MP_ROM_QSTR(MP_QSTR_PG09), MP_ROM_PTR(&pin_PG09) },
+ { MP_ROM_QSTR(MP_QSTR_PG10), MP_ROM_PTR(&pin_PG10) },
+ { MP_ROM_QSTR(MP_QSTR_PG11), MP_ROM_PTR(&pin_PG11) },
+ { MP_ROM_QSTR(MP_QSTR_PG12), MP_ROM_PTR(&pin_PG12) },
+ { MP_ROM_QSTR(MP_QSTR_PG13), MP_ROM_PTR(&pin_PG13) },
+ { MP_ROM_QSTR(MP_QSTR_PG14), MP_ROM_PTR(&pin_PG14) },
+ { MP_ROM_QSTR(MP_QSTR_PB03), MP_ROM_PTR(&pin_PB03) },
+ { MP_ROM_QSTR(MP_QSTR_PB04), MP_ROM_PTR(&pin_PB04) },
+ { MP_ROM_QSTR(MP_QSTR_PB05), MP_ROM_PTR(&pin_PB05) },
+ { MP_ROM_QSTR(MP_QSTR_PB06), MP_ROM_PTR(&pin_PB06) },
+ { MP_ROM_QSTR(MP_QSTR_PB07), MP_ROM_PTR(&pin_PB07) },
+ { MP_ROM_QSTR(MP_QSTR_PB08), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_PB09), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_PE00), MP_ROM_PTR(&pin_PE00) },
+ { MP_ROM_QSTR(MP_QSTR_PE01), MP_ROM_PTR(&pin_PE01) },
+ { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA15) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PG10) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PG11) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PF03) },
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PF10) },
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PG12) },
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PF04) },
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PG13) },
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PG14) },
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PG09) },
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA01) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PC01) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PC03) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PC04) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PC05) }, //alt PB09, see F401ZG-DISCO manual
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB00) }, //alt PB10, see F401ZG-DISCO manual
+ { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_PE00) },
+ { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_PE01) },
+ { MP_ROM_QSTR(MP_QSTR_LED3), MP_ROM_PTR(&pin_PE02) },
+ { MP_ROM_QSTR(MP_QSTR_LED4), MP_ROM_PTR(&pin_PE03) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h
new file mode 100644
index 000000000..5d329c14f
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h
@@ -0,0 +1,439 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_conf_template.h
+ * @author MCD Application Team
+ * @brief HAL configuration template file.
+ * This file should be copied to the application folder and renamed
+ * to stm32f4xx_hal_conf.h.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_HAL_CONF_H
+#define __STM32F4xx_HAL_CONF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* ########################## Module Selection ############################## */
+/**
+ * @brief This is the list of modules to be used in the HAL driver
+ */
+#define HAL_MODULE_ENABLED
+
+ /* #define HAL_ADC_MODULE_ENABLED */
+/* #define HAL_CRYP_MODULE_ENABLED */
+/* #define HAL_CAN_MODULE_ENABLED */
+/* #define HAL_CRC_MODULE_ENABLED */
+/* #define HAL_CRYP_MODULE_ENABLED */
+/* #define HAL_DAC_MODULE_ENABLED */
+/* #define HAL_DCMI_MODULE_ENABLED */
+/* #define HAL_DMA2D_MODULE_ENABLED */
+/* #define HAL_ETH_MODULE_ENABLED */
+/* #define HAL_NAND_MODULE_ENABLED */
+/* #define HAL_NOR_MODULE_ENABLED */
+/* #define HAL_PCCARD_MODULE_ENABLED */
+#define HAL_SRAM_MODULE_ENABLED
+/* #define HAL_SDRAM_MODULE_ENABLED */
+/* #define HAL_HASH_MODULE_ENABLED */
+#define HAL_I2C_MODULE_ENABLED
+#define HAL_I2S_MODULE_ENABLED
+/* #define HAL_IWDG_MODULE_ENABLED */
+/* #define HAL_LTDC_MODULE_ENABLED */
+/* #define HAL_RNG_MODULE_ENABLED */
+/* #define HAL_RTC_MODULE_ENABLED */
+/* #define HAL_SAI_MODULE_ENABLED */
+#define HAL_SD_MODULE_ENABLED
+/* #define HAL_MMC_MODULE_ENABLED */
+/* #define HAL_SPI_MODULE_ENABLED */
+/* #define HAL_TIM_MODULE_ENABLED */
+#define HAL_UART_MODULE_ENABLED
+/* #define HAL_USART_MODULE_ENABLED */
+/* #define HAL_IRDA_MODULE_ENABLED */
+/* #define HAL_SMARTCARD_MODULE_ENABLED */
+/* #define HAL_WWDG_MODULE_ENABLED */
+#define HAL_PCD_MODULE_ENABLED
+/* #define HAL_HCD_MODULE_ENABLED */
+/* #define HAL_DSI_MODULE_ENABLED */
+/* #define HAL_QSPI_MODULE_ENABLED */
+#define HAL_QSPI_MODULE_ENABLED
+/* #define HAL_CEC_MODULE_ENABLED */
+/* #define HAL_FMPI2C_MODULE_ENABLED */
+/* #define HAL_SPDIFRX_MODULE_ENABLED */
+/* #define HAL_DFSDM_MODULE_ENABLED */
+/* #define HAL_LPTIM_MODULE_ENABLED */
+/* #define HAL_EXTI_MODULE_ENABLED */
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_EXTI_MODULE_ENABLED
+#define HAL_DMA_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
+#define HAL_PWR_MODULE_ENABLED
+#define HAL_CORTEX_MODULE_ENABLED
+
+/* ########################## HSE/HSI Values adaptation ##################### */
+/**
+ * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSE is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined (HSE_STARTUP_TIMEOUT)
+ #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */
+#endif /* HSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief Internal High Speed oscillator (HSI) value.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSI is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+ * @brief Internal Low Speed oscillator (LSI) value.
+ */
+#if !defined (LSI_VALUE)
+ #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/
+#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
+ The real value may vary depending on the variations
+ in voltage and temperature.*/
+/**
+ * @brief External Low Speed oscillator (LSE) value.
+ */
+#if !defined (LSE_VALUE)
+ #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */
+#endif /* LSE_VALUE */
+
+#if !defined (LSE_STARTUP_TIMEOUT)
+ #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */
+#endif /* LSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief External clock source for I2S peripheral
+ * This value is used by the I2S HAL module to compute the I2S clock source
+ * frequency, this source is inserted directly through I2S_CKIN pad.
+ */
+#if !defined (EXTERNAL_CLOCK_VALUE)
+ #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the External audio frequency in Hz*/
+#endif /* EXTERNAL_CLOCK_VALUE */
+
+/* Tip: To avoid modifying this file each time you need to use different HSE,
+ === you can define the HSE value in your toolchain compiler preprocessor. */
+
+/* ########################### System Configuration ######################### */
+/**
+ * @brief This is the HAL system configuration section
+ */
+#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */
+#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */
+#define USE_RTOS 0U
+#define PREFETCH_ENABLE 1U
+#define INSTRUCTION_CACHE_ENABLE 1U
+#define DATA_CACHE_ENABLE 1U
+
+/* ########################## Assert Selection ############################## */
+/**
+ * @brief Uncomment the line below to expanse the "assert_param" macro in the
+ * HAL drivers code
+ */
+/* #define USE_FULL_ASSERT 1U */
+
+/* ################## Ethernet peripheral configuration ##################### */
+
+/* Section 1 : Ethernet peripheral configuration */
+
+/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
+#define MAC_ADDR0 2U
+#define MAC_ADDR1 0U
+#define MAC_ADDR2 0U
+#define MAC_ADDR3 0U
+#define MAC_ADDR4 0U
+#define MAC_ADDR5 0U
+
+/* Definition of the Ethernet driver buffers size and count */
+#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
+#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
+#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
+#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
+
+/* Section 2: PHY configuration section */
+
+/* DP83848_PHY_ADDRESS Address*/
+#define DP83848_PHY_ADDRESS 0x01U
+/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
+#define PHY_RESET_DELAY ((uint32_t)0x000000FFU)
+/* PHY Configuration delay */
+#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU)
+
+#define PHY_READ_TO ((uint32_t)0x0000FFFFU)
+#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU)
+
+/* Section 3: Common PHY Registers */
+
+#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */
+#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */
+
+#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
+#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */
+#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */
+#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */
+#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */
+#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */
+#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */
+#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */
+#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */
+#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */
+
+#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */
+#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
+#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */
+
+/* Section 4: Extended PHY Registers */
+#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
+
+#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
+#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
+
+/* ################## SPI peripheral configuration ########################## */
+
+/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
+* Activated: CRC code is present inside driver
+* Deactivated: CRC code cleaned from driver
+*/
+
+#define USE_SPI_CRC 0U
+
+/* Includes ------------------------------------------------------------------*/
+/**
+ * @brief Include module's header file
+ */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rcc.h"
+#endif /* HAL_RCC_MODULE_ENABLED */
+
+#ifdef HAL_EXTI_MODULE_ENABLED
+ #include "stm32f4xx_hal_exti.h"
+#endif /* HAL_EXTI_MODULE_ENABLED */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+ #include "stm32f4xx_hal_gpio.h"
+#endif /* HAL_GPIO_MODULE_ENABLED */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma.h"
+#endif /* HAL_DMA_MODULE_ENABLED */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+ #include "stm32f4xx_hal_cortex.h"
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+ #include "stm32f4xx_hal_adc.h"
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+#ifdef HAL_CAN_MODULE_ENABLED
+ #include "stm32f4xx_hal_can.h"
+#endif /* HAL_CAN_MODULE_ENABLED */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+ #include "stm32f4xx_hal_crc.h"
+#endif /* HAL_CRC_MODULE_ENABLED */
+
+#ifdef HAL_CRYP_MODULE_ENABLED
+ #include "stm32f4xx_hal_cryp.h"
+#endif /* HAL_CRYP_MODULE_ENABLED */
+
+#ifdef HAL_DMA2D_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma2d.h"
+#endif /* HAL_DMA2D_MODULE_ENABLED */
+
+#ifdef HAL_DAC_MODULE_ENABLED
+ #include "stm32f4xx_hal_dac.h"
+#endif /* HAL_DAC_MODULE_ENABLED */
+
+#ifdef HAL_DCMI_MODULE_ENABLED
+ #include "stm32f4xx_hal_dcmi.h"
+#endif /* HAL_DCMI_MODULE_ENABLED */
+
+#ifdef HAL_ETH_MODULE_ENABLED
+ #include "stm32f4xx_hal_eth.h"
+#endif /* HAL_ETH_MODULE_ENABLED */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_flash.h"
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+#ifdef HAL_SRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sram.h"
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
+#ifdef HAL_NOR_MODULE_ENABLED
+ #include "stm32f4xx_hal_nor.h"
+#endif /* HAL_NOR_MODULE_ENABLED */
+
+#ifdef HAL_NAND_MODULE_ENABLED
+ #include "stm32f4xx_hal_nand.h"
+#endif /* HAL_NAND_MODULE_ENABLED */
+
+#ifdef HAL_PCCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pccard.h"
+#endif /* HAL_PCCARD_MODULE_ENABLED */
+
+#ifdef HAL_SDRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sdram.h"
+#endif /* HAL_SDRAM_MODULE_ENABLED */
+
+#ifdef HAL_HASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_hash.h"
+#endif /* HAL_HASH_MODULE_ENABLED */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2c.h"
+#endif /* HAL_I2C_MODULE_ENABLED */
+
+#ifdef HAL_I2S_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2s.h"
+#endif /* HAL_I2S_MODULE_ENABLED */
+
+#ifdef HAL_IWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_iwdg.h"
+#endif /* HAL_IWDG_MODULE_ENABLED */
+
+#ifdef HAL_LTDC_MODULE_ENABLED
+ #include "stm32f4xx_hal_ltdc.h"
+#endif /* HAL_LTDC_MODULE_ENABLED */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+ #include "stm32f4xx_hal_pwr.h"
+#endif /* HAL_PWR_MODULE_ENABLED */
+
+#ifdef HAL_RNG_MODULE_ENABLED
+ #include "stm32f4xx_hal_rng.h"
+#endif /* HAL_RNG_MODULE_ENABLED */
+
+#ifdef HAL_RTC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rtc.h"
+#endif /* HAL_RTC_MODULE_ENABLED */
+
+#ifdef HAL_SAI_MODULE_ENABLED
+ #include "stm32f4xx_hal_sai.h"
+#endif /* HAL_SAI_MODULE_ENABLED */
+
+#ifdef HAL_SD_MODULE_ENABLED
+ #include "stm32f4xx_hal_sd.h"
+#endif /* HAL_SD_MODULE_ENABLED */
+
+#ifdef HAL_MMC_MODULE_ENABLED
+ #include "stm32f4xx_hal_mmc.h"
+#endif /* HAL_MMC_MODULE_ENABLED */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+ #include "stm32f4xx_hal_spi.h"
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+ #include "stm32f4xx_hal_tim.h"
+#endif /* HAL_TIM_MODULE_ENABLED */
+
+#ifdef HAL_UART_MODULE_ENABLED
+ #include "stm32f4xx_hal_uart.h"
+#endif /* HAL_UART_MODULE_ENABLED */
+
+#ifdef HAL_USART_MODULE_ENABLED
+ #include "stm32f4xx_hal_usart.h"
+#endif /* HAL_USART_MODULE_ENABLED */
+
+#ifdef HAL_IRDA_MODULE_ENABLED
+ #include "stm32f4xx_hal_irda.h"
+#endif /* HAL_IRDA_MODULE_ENABLED */
+
+#ifdef HAL_SMARTCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_smartcard.h"
+#endif /* HAL_SMARTCARD_MODULE_ENABLED */
+
+#ifdef HAL_WWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_wwdg.h"
+#endif /* HAL_WWDG_MODULE_ENABLED */
+
+#ifdef HAL_PCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pcd.h"
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+#ifdef HAL_HCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_hcd.h"
+#endif /* HAL_HCD_MODULE_ENABLED */
+
+#ifdef HAL_DSI_MODULE_ENABLED
+ #include "stm32f4xx_hal_dsi.h"
+#endif /* HAL_DSI_MODULE_ENABLED */
+
+#ifdef HAL_QSPI_MODULE_ENABLED
+ #include "stm32f4xx_hal_qspi.h"
+#endif /* HAL_QSPI_MODULE_ENABLED */
+
+#ifdef HAL_CEC_MODULE_ENABLED
+ #include "stm32f4xx_hal_cec.h"
+#endif /* HAL_CEC_MODULE_ENABLED */
+
+#ifdef HAL_FMPI2C_MODULE_ENABLED
+ #include "stm32f4xx_hal_fmpi2c.h"
+#endif /* HAL_FMPI2C_MODULE_ENABLED */
+
+#ifdef HAL_SPDIFRX_MODULE_ENABLED
+ #include "stm32f4xx_hal_spdifrx.h"
+#endif /* HAL_SPDIFRX_MODULE_ENABLED */
+
+#ifdef HAL_DFSDM_MODULE_ENABLED
+ #include "stm32f4xx_hal_dfsdm.h"
+#endif /* HAL_DFSDM_MODULE_ENABLED */
+
+#ifdef HAL_LPTIM_MODULE_ENABLED
+ #include "stm32f4xx_hal_lptim.h"
+#endif /* HAL_LPTIM_MODULE_ENABLED */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief The assert_param macro is used for function's parameters check.
+ * @param expr: If expr is false, it calls assert_failed function
+ * which reports the name of the source file and the source
+ * line number of the call that failed.
+ * If expr is true, it returns no value.
+ * @retval None
+ */
+ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+ void assert_failed(uint8_t* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0U)
+#endif /* USE_FULL_ASSERT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F4xx_HAL_CONF_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_msp.c b/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_msp.c
new file mode 100644
index 000000000..9d29f3607
--- /dev/null
+++ b/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_msp.c
@@ -0,0 +1,832 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * File Name : stm32f4xx_hal_msp.c
+ * Description : This file provides code for the MSP Initialization
+ * and de-Initialization codes.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN TD */
+
+/* USER CODE END TD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN Define */
+#define LED3_Pin GPIO_PIN_2
+#define LED3_GPIO_Port GPIOE
+#define LED4_Pin GPIO_PIN_3
+#define LED4_GPIO_Port GPIOE
+#define DFSDM_DATIN3_Pin GPIO_PIN_4
+#define DFSDM_DATIN3_GPIO_Port GPIOE
+#define A0_Pin GPIO_PIN_0
+#define A0_GPIO_Port GPIOF
+#define LCD_BLCTRL_Pin GPIO_PIN_5
+#define LCD_BLCTRL_GPIO_Port GPIOF
+#define QSPI_BK1_IO3_Pin GPIO_PIN_6
+#define QSPI_BK1_IO3_GPIO_Port GPIOF
+#define QSPI_BK1_IO2_Pin GPIO_PIN_7
+#define QSPI_BK1_IO2_GPIO_Port GPIOF
+#define QSPI_BK1_IO0_Pin GPIO_PIN_8
+#define QSPI_BK1_IO0_GPIO_Port GPIOF
+#define QSPI_BK1_IO1_Pin GPIO_PIN_9
+#define QSPI_BK1_IO1_GPIO_Port GPIOF
+#define STLK_MCO_Pin GPIO_PIN_0
+#define STLK_MCO_GPIO_Port GPIOH
+#define DFSDM_CKOUT_Pin GPIO_PIN_2
+#define DFSDM_CKOUT_GPIO_Port GPIOC
+#define JOY_SEL_Pin GPIO_PIN_0
+#define JOY_SEL_GPIO_Port GPIOA
+#define STLINK_RX_Pin GPIO_PIN_2
+#define STLINK_RX_GPIO_Port GPIOA
+#define STLINK_TX_Pin GPIO_PIN_3
+#define STLINK_TX_GPIO_Port GPIOA
+#define CODEC_I2S3_WS_Pin GPIO_PIN_4
+#define CODEC_I2S3_WS_GPIO_Port GPIOA
+#define DFSDM_DATIN0_Pin GPIO_PIN_1
+#define DFSDM_DATIN0_GPIO_Port GPIOB
+#define QSPI_CLK_Pin GPIO_PIN_2
+#define QSPI_CLK_GPIO_Port GPIOB
+#define EXT_RESET_Pin GPIO_PIN_11
+#define EXT_RESET_GPIO_Port GPIOF
+#define CTP_RST_Pin GPIO_PIN_12
+#define CTP_RST_GPIO_Port GPIOF
+#define JOY_RIGHT_Pin GPIO_PIN_14
+#define JOY_RIGHT_GPIO_Port GPIOF
+#define JOY_LEFT_Pin GPIO_PIN_15
+#define JOY_LEFT_GPIO_Port GPIOF
+#define JOY_UP_Pin GPIO_PIN_0
+#define JOY_UP_GPIO_Port GPIOG
+#define JOY_DOWN_Pin GPIO_PIN_1
+#define JOY_DOWN_GPIO_Port GPIOG
+#define D4_Pin GPIO_PIN_7
+#define D4_GPIO_Port GPIOE
+#define D5_Pin GPIO_PIN_8
+#define D5_GPIO_Port GPIOE
+#define D6_Pin GPIO_PIN_9
+#define D6_GPIO_Port GPIOE
+#define D7_Pin GPIO_PIN_10
+#define D7_GPIO_Port GPIOE
+#define D8_Pin GPIO_PIN_11
+#define D8_GPIO_Port GPIOE
+#define D9_Pin GPIO_PIN_12
+#define D9_GPIO_Port GPIOE
+#define D10_Pin GPIO_PIN_13
+#define D10_GPIO_Port GPIOE
+#define D11_Pin GPIO_PIN_14
+#define D11_GPIO_Port GPIOE
+#define D12_Pin GPIO_PIN_15
+#define D12_GPIO_Port GPIOE
+#define I2C2_SCL_Pin GPIO_PIN_10
+#define I2C2_SCL_GPIO_Port GPIOB
+#define M2_CKIN_Pin GPIO_PIN_11
+#define M2_CKIN_GPIO_Port GPIOB
+#define CODEC_I2S3_SCK_Pin GPIO_PIN_12
+#define CODEC_I2S3_SCK_GPIO_Port GPIOB
+#define D13_Pin GPIO_PIN_8
+#define D13_GPIO_Port GPIOD
+#define D14_Pin GPIO_PIN_9
+#define D14_GPIO_Port GPIOD
+#define D15_Pin GPIO_PIN_10
+#define D15_GPIO_Port GPIOD
+#define LCD_RESET_Pin GPIO_PIN_11
+#define LCD_RESET_GPIO_Port GPIOD
+#define D0_Pin GPIO_PIN_14
+#define D0_GPIO_Port GPIOD
+#define D1_Pin GPIO_PIN_15
+#define D1_GPIO_Port GPIOD
+#define CODEC_INT_Pin GPIO_PIN_2
+#define CODEC_INT_GPIO_Port GPIOG
+#define LCD_TE_Pin GPIO_PIN_4
+#define LCD_TE_GPIO_Port GPIOG
+#define CTP_INT_Pin GPIO_PIN_5
+#define CTP_INT_GPIO_Port GPIOG
+#define QSPI_BK1_NCS_Pin GPIO_PIN_6
+#define QSPI_BK1_NCS_GPIO_Port GPIOG
+#define USB_OTGFS_OVRCR_Pin GPIO_PIN_7
+#define USB_OTGFS_OVRCR_GPIO_Port GPIOG
+#define USB_OTGFS_PPWR_EN_Pin GPIO_PIN_8
+#define USB_OTGFS_PPWR_EN_GPIO_Port GPIOG
+#define CODEC_I2S3_MCK_Pin GPIO_PIN_7
+#define CODEC_I2S3_MCK_GPIO_Port GPIOC
+#define uSD_D0_Pin GPIO_PIN_8
+#define uSD_D0_GPIO_Port GPIOC
+#define uSD_D1_Pin GPIO_PIN_9
+#define uSD_D1_GPIO_Port GPIOC
+#define M2_CKINA8_Pin GPIO_PIN_8
+#define M2_CKINA8_GPIO_Port GPIOA
+#define USB_OTGFS_VBUS_Pin GPIO_PIN_9
+#define USB_OTGFS_VBUS_GPIO_Port GPIOA
+#define USB_OTGFS_ID_Pin GPIO_PIN_10
+#define USB_OTGFS_ID_GPIO_Port GPIOA
+#define USB_OTGFS_DM_Pin GPIO_PIN_11
+#define USB_OTGFS_DM_GPIO_Port GPIOA
+#define USB_OTGFS_DP_Pin GPIO_PIN_12
+#define USB_OTGFS_DP_GPIO_Port GPIOA
+#define SWDIO_Pin GPIO_PIN_13
+#define SWDIO_GPIO_Port GPIOA
+#define SWCLK_Pin GPIO_PIN_14
+#define SWCLK_GPIO_Port GPIOA
+#define uSD_D2_Pin GPIO_PIN_10
+#define uSD_D2_GPIO_Port GPIOC
+#define uSD_D3_Pin GPIO_PIN_11
+#define uSD_D3_GPIO_Port GPIOC
+#define uSD_CLK_Pin GPIO_PIN_12
+#define uSD_CLK_GPIO_Port GPIOC
+#define D2_Pin GPIO_PIN_0
+#define D2_GPIO_Port GPIOD
+#define D3_Pin GPIO_PIN_1
+#define D3_GPIO_Port GPIOD
+#define uSD_CMD_Pin GPIO_PIN_2
+#define uSD_CMD_GPIO_Port GPIOD
+#define uSD_DETECT_Pin GPIO_PIN_3
+#define uSD_DETECT_GPIO_Port GPIOD
+#define FMC_NOE_Pin GPIO_PIN_4
+#define FMC_NOE_GPIO_Port GPIOD
+#define FMC_NWE_Pin GPIO_PIN_5
+#define FMC_NWE_GPIO_Port GPIOD
+#define FMC_NE1_Pin GPIO_PIN_7
+#define FMC_NE1_GPIO_Port GPIOD
+#define SWO_Pin GPIO_PIN_3
+#define SWO_GPIO_Port GPIOB
+#define CODEC_I2S3ext_SD_Pin GPIO_PIN_4
+#define CODEC_I2S3ext_SD_GPIO_Port GPIOB
+#define CODEC_I2S3_SD_Pin GPIO_PIN_5
+#define CODEC_I2S3_SD_GPIO_Port GPIOB
+#define I2C1_SCL_Pin GPIO_PIN_6
+#define I2C1_SCL_GPIO_Port GPIOB
+#define I2C1_SDA_Pin GPIO_PIN_7
+#define I2C1_SDA_GPIO_Port GPIOB
+#define I2C2_SDA_Pin GPIO_PIN_9
+#define I2C2_SDA_GPIO_Port GPIOB
+#define LED1_Pin GPIO_PIN_0
+#define LED1_GPIO_Port GPIOE
+#define LED2_Pin GPIO_PIN_1
+#define LED2_GPIO_Port GPIOE
+
+/* USER CODE END Define */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN Macro */
+
+/* USER CODE END Macro */
+
+/* Private variables ---------------------------------------------------------*/
+/* USER CODE BEGIN PV */
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+/* USER CODE BEGIN PFP */
+
+/* USER CODE END PFP */
+
+/* External functions --------------------------------------------------------*/
+/* USER CODE BEGIN ExternalFunctions */
+
+/* USER CODE END ExternalFunctions */
+
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+/**
+ * Initializes the Global MSP.
+ */
+void HAL_MspInit(void)
+{
+ /* USER CODE BEGIN MspInit 0 */
+
+ /* USER CODE END MspInit 0 */
+
+ __HAL_RCC_SYSCFG_CLK_ENABLE();
+ __HAL_RCC_PWR_CLK_ENABLE();
+
+ /* System interrupt init*/
+
+ /* USER CODE BEGIN MspInit 1 */
+
+ /* USER CODE END MspInit 1 */
+}
+
+/**
+* @brief I2C MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hi2c: I2C handle pointer
+* @retval None
+*/
+void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(hi2c->Instance==I2C1)
+ {
+ /* USER CODE BEGIN I2C1_MspInit 0 */
+
+ /* USER CODE END I2C1_MspInit 0 */
+
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ /**I2C1 GPIO Configuration
+ PB6 ------> I2C1_SCL
+ PB7 ------> I2C1_SDA
+ */
+ GPIO_InitStruct.Pin = I2C1_SCL_Pin|I2C1_SDA_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ /* Peripheral clock enable */
+ __HAL_RCC_I2C1_CLK_ENABLE();
+ /* USER CODE BEGIN I2C1_MspInit 1 */
+
+ /* USER CODE END I2C1_MspInit 1 */
+ }
+ else if(hi2c->Instance==I2C2)
+ {
+ /* USER CODE BEGIN I2C2_MspInit 0 */
+
+ /* USER CODE END I2C2_MspInit 0 */
+
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ /**I2C2 GPIO Configuration
+ PB10 ------> I2C2_SCL
+ PB9 ------> I2C2_SDA
+ */
+ GPIO_InitStruct.Pin = I2C2_SCL_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;
+ HAL_GPIO_Init(I2C2_SCL_GPIO_Port, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = I2C2_SDA_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF9_I2C2;
+ HAL_GPIO_Init(I2C2_SDA_GPIO_Port, &GPIO_InitStruct);
+
+ /* Peripheral clock enable */
+ __HAL_RCC_I2C2_CLK_ENABLE();
+ /* USER CODE BEGIN I2C2_MspInit 1 */
+
+ /* USER CODE END I2C2_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief I2C MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hi2c: I2C handle pointer
+* @retval None
+*/
+void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
+{
+ if(hi2c->Instance==I2C1)
+ {
+ /* USER CODE BEGIN I2C1_MspDeInit 0 */
+
+ /* USER CODE END I2C1_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_I2C1_CLK_DISABLE();
+
+ /**I2C1 GPIO Configuration
+ PB6 ------> I2C1_SCL
+ PB7 ------> I2C1_SDA
+ */
+ HAL_GPIO_DeInit(GPIOB, I2C1_SCL_Pin|I2C1_SDA_Pin);
+
+ /* USER CODE BEGIN I2C1_MspDeInit 1 */
+
+ /* USER CODE END I2C1_MspDeInit 1 */
+ }
+ else if(hi2c->Instance==I2C2)
+ {
+ /* USER CODE BEGIN I2C2_MspDeInit 0 */
+
+ /* USER CODE END I2C2_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_I2C2_CLK_DISABLE();
+
+ /**I2C2 GPIO Configuration
+ PB10 ------> I2C2_SCL
+ PB9 ------> I2C2_SDA
+ */
+ HAL_GPIO_DeInit(GPIOB, I2C2_SCL_Pin|I2C2_SDA_Pin);
+
+ /* USER CODE BEGIN I2C2_MspDeInit 1 */
+
+ /* USER CODE END I2C2_MspDeInit 1 */
+ }
+
+}
+
+/**
+* @brief I2S MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hi2s: I2S handle pointer
+* @retval None
+*/
+void HAL_I2S_MspInit(I2S_HandleTypeDef* hi2s)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(hi2s->Instance==SPI3)
+ {
+ /* USER CODE BEGIN SPI3_MspInit 0 */
+
+ /* USER CODE END SPI3_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_SPI3_CLK_ENABLE();
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ /**I2S3 GPIO Configuration
+ PA4 ------> I2S3_WS
+ PB12 ------> I2S3_CK
+ PC7 ------> I2S3_MCK
+ PB4 ------> I2S3_ext_SD
+ PB5 ------> I2S3_SD
+ */
+ GPIO_InitStruct.Pin = CODEC_I2S3_WS_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
+ HAL_GPIO_Init(CODEC_I2S3_WS_GPIO_Port, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = CODEC_I2S3_SCK_Pin|CODEC_I2S3ext_SD_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Alternate = GPIO_AF7_SPI3;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = CODEC_I2S3_MCK_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
+ HAL_GPIO_Init(CODEC_I2S3_MCK_GPIO_Port, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = CODEC_I2S3_SD_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
+ HAL_GPIO_Init(CODEC_I2S3_SD_GPIO_Port, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN SPI3_MspInit 1 */
+
+ /* USER CODE END SPI3_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief I2S MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hi2s: I2S handle pointer
+* @retval None
+*/
+void HAL_I2S_MspDeInit(I2S_HandleTypeDef* hi2s)
+{
+ if(hi2s->Instance==SPI3)
+ {
+ /* USER CODE BEGIN SPI3_MspDeInit 0 */
+
+ /* USER CODE END SPI3_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_SPI3_CLK_DISABLE();
+
+ /**I2S3 GPIO Configuration
+ PA4 ------> I2S3_WS
+ PB12 ------> I2S3_CK
+ PC7 ------> I2S3_MCK
+ PB4 ------> I2S3_ext_SD
+ PB5 ------> I2S3_SD
+ */
+ HAL_GPIO_DeInit(CODEC_I2S3_WS_GPIO_Port, CODEC_I2S3_WS_Pin);
+
+ HAL_GPIO_DeInit(GPIOB, CODEC_I2S3_SCK_Pin|CODEC_I2S3ext_SD_Pin|CODEC_I2S3_SD_Pin);
+
+ HAL_GPIO_DeInit(CODEC_I2S3_MCK_GPIO_Port, CODEC_I2S3_MCK_Pin);
+
+ /* USER CODE BEGIN SPI3_MspDeInit 1 */
+
+ /* USER CODE END SPI3_MspDeInit 1 */
+ }
+
+}
+
+/**
+* @brief QSPI MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hqspi: QSPI handle pointer
+* @retval None
+*/
+void HAL_QSPI_MspInit(QSPI_HandleTypeDef* hqspi)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(hqspi->Instance==QUADSPI)
+ {
+ /* USER CODE BEGIN QUADSPI_MspInit 0 */
+
+ /* USER CODE END QUADSPI_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_QSPI_CLK_ENABLE();
+
+ __HAL_RCC_GPIOF_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOG_CLK_ENABLE();
+ /**QUADSPI GPIO Configuration
+ PF6 ------> QUADSPI_BK1_IO3
+ PF7 ------> QUADSPI_BK1_IO2
+ PF8 ------> QUADSPI_BK1_IO0
+ PF9 ------> QUADSPI_BK1_IO1
+ PB2 ------> QUADSPI_CLK
+ PG6 ------> QUADSPI_BK1_NCS
+ */
+ GPIO_InitStruct.Pin = QSPI_BK1_IO3_Pin|QSPI_BK1_IO2_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF9_QSPI;
+ HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = QSPI_BK1_IO0_Pin|QSPI_BK1_IO1_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
+ HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = QSPI_CLK_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF9_QSPI;
+ HAL_GPIO_Init(QSPI_CLK_GPIO_Port, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = QSPI_BK1_NCS_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
+ HAL_GPIO_Init(QSPI_BK1_NCS_GPIO_Port, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN QUADSPI_MspInit 1 */
+
+ /* USER CODE END QUADSPI_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief QSPI MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hqspi: QSPI handle pointer
+* @retval None
+*/
+void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef* hqspi)
+{
+ if(hqspi->Instance==QUADSPI)
+ {
+ /* USER CODE BEGIN QUADSPI_MspDeInit 0 */
+
+ /* USER CODE END QUADSPI_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_QSPI_CLK_DISABLE();
+
+ /**QUADSPI GPIO Configuration
+ PF6 ------> QUADSPI_BK1_IO3
+ PF7 ------> QUADSPI_BK1_IO2
+ PF8 ------> QUADSPI_BK1_IO0
+ PF9 ------> QUADSPI_BK1_IO1
+ PB2 ------> QUADSPI_CLK
+ PG6 ------> QUADSPI_BK1_NCS
+ */
+ HAL_GPIO_DeInit(GPIOF, QSPI_BK1_IO3_Pin|QSPI_BK1_IO2_Pin|QSPI_BK1_IO0_Pin|QSPI_BK1_IO1_Pin);
+
+ HAL_GPIO_DeInit(QSPI_CLK_GPIO_Port, QSPI_CLK_Pin);
+
+ HAL_GPIO_DeInit(QSPI_BK1_NCS_GPIO_Port, QSPI_BK1_NCS_Pin);
+
+ /* USER CODE BEGIN QUADSPI_MspDeInit 1 */
+
+ /* USER CODE END QUADSPI_MspDeInit 1 */
+ }
+
+}
+
+/**
+* @brief SD MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hsd: SD handle pointer
+* @retval None
+*/
+void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(hsd->Instance==SDIO)
+ {
+ /* USER CODE BEGIN SDIO_MspInit 0 */
+
+ /* USER CODE END SDIO_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_SDIO_CLK_ENABLE();
+
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOD_CLK_ENABLE();
+ /**SDIO GPIO Configuration
+ PC8 ------> SDIO_D0
+ PC9 ------> SDIO_D1
+ PC10 ------> SDIO_D2
+ PC11 ------> SDIO_D3
+ PC12 ------> SDIO_CK
+ PD2 ------> SDIO_CMD
+ */
+ GPIO_InitStruct.Pin = uSD_D0_Pin|uSD_D1_Pin|uSD_D2_Pin|uSD_D3_Pin
+ |uSD_CLK_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = uSD_CMD_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
+ HAL_GPIO_Init(uSD_CMD_GPIO_Port, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN SDIO_MspInit 1 */
+
+ /* USER CODE END SDIO_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief SD MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hsd: SD handle pointer
+* @retval None
+*/
+void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd)
+{
+ if(hsd->Instance==SDIO)
+ {
+ /* USER CODE BEGIN SDIO_MspDeInit 0 */
+
+ /* USER CODE END SDIO_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_SDIO_CLK_DISABLE();
+
+ /**SDIO GPIO Configuration
+ PC8 ------> SDIO_D0
+ PC9 ------> SDIO_D1
+ PC10 ------> SDIO_D2
+ PC11 ------> SDIO_D3
+ PC12 ------> SDIO_CK
+ PD2 ------> SDIO_CMD
+ */
+ HAL_GPIO_DeInit(GPIOC, uSD_D0_Pin|uSD_D1_Pin|uSD_D2_Pin|uSD_D3_Pin
+ |uSD_CLK_Pin);
+
+ HAL_GPIO_DeInit(uSD_CMD_GPIO_Port, uSD_CMD_Pin);
+
+ /* USER CODE BEGIN SDIO_MspDeInit 1 */
+
+ /* USER CODE END SDIO_MspDeInit 1 */
+ }
+
+}
+
+/**
+* @brief UART MSP Initialization
+* This function configures the hardware resources used in this example
+* @param huart: UART handle pointer
+* @retval None
+*/
+void HAL_UART_MspInit(UART_HandleTypeDef* huart)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(huart->Instance==USART2)
+ {
+ /* USER CODE BEGIN USART2_MspInit 0 */
+
+ /* USER CODE END USART2_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_USART2_CLK_ENABLE();
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ /**USART2 GPIO Configuration
+ PA2 ------> USART2_TX
+ PA3 ------> USART2_RX
+ */
+ GPIO_InitStruct.Pin = STLINK_RX_Pin|STLINK_TX_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN USART2_MspInit 1 */
+
+ /* USER CODE END USART2_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief UART MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param huart: UART handle pointer
+* @retval None
+*/
+void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
+{
+ if(huart->Instance==USART2)
+ {
+ /* USER CODE BEGIN USART2_MspDeInit 0 */
+
+ /* USER CODE END USART2_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_USART2_CLK_DISABLE();
+
+ /**USART2 GPIO Configuration
+ PA2 ------> USART2_TX
+ PA3 ------> USART2_RX
+ */
+ HAL_GPIO_DeInit(GPIOA, STLINK_RX_Pin|STLINK_TX_Pin);
+
+ /* USER CODE BEGIN USART2_MspDeInit 1 */
+
+ /* USER CODE END USART2_MspDeInit 1 */
+ }
+
+}
+
+static uint32_t FSMC_Initialized = 0;
+
+static void HAL_FSMC_MspInit(void){
+ /* USER CODE BEGIN FSMC_MspInit 0 */
+
+ /* USER CODE END FSMC_MspInit 0 */
+ GPIO_InitTypeDef GPIO_InitStruct ={0};
+ if (FSMC_Initialized) {
+ return;
+ }
+ FSMC_Initialized = 1;
+ /* Peripheral clock enable */
+ __HAL_RCC_FSMC_CLK_ENABLE();
+
+ /** FSMC GPIO Configuration
+ PF0 ------> FSMC_A0
+ PE7 ------> FSMC_D4
+ PE8 ------> FSMC_D5
+ PE9 ------> FSMC_D6
+ PE10 ------> FSMC_D7
+ PE11 ------> FSMC_D8
+ PE12 ------> FSMC_D9
+ PE13 ------> FSMC_D10
+ PE14 ------> FSMC_D11
+ PE15 ------> FSMC_D12
+ PD8 ------> FSMC_D13
+ PD9 ------> FSMC_D14
+ PD10 ------> FSMC_D15
+ PD14 ------> FSMC_D0
+ PD15 ------> FSMC_D1
+ PD0 ------> FSMC_D2
+ PD1 ------> FSMC_D3
+ PD4 ------> FSMC_NOE
+ PD5 ------> FSMC_NWE
+ PD7 ------> FSMC_NE1
+ */
+ GPIO_InitStruct.Pin = A0_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;
+ HAL_GPIO_Init(A0_GPIO_Port, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = D4_Pin|D5_Pin|D6_Pin|D7_Pin
+ |D8_Pin|D9_Pin|D10_Pin|D11_Pin
+ |D12_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = D13_Pin|D14_Pin|D15_Pin|D0_Pin
+ |D1_Pin|D2_Pin|D3_Pin|FMC_NOE_Pin
+ |FMC_NWE_Pin|FMC_NE1_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;
+ HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN FSMC_MspInit 1 */
+
+ /* USER CODE END FSMC_MspInit 1 */
+}
+
+void HAL_SRAM_MspInit(SRAM_HandleTypeDef* hsram){
+ /* USER CODE BEGIN SRAM_MspInit 0 */
+
+ /* USER CODE END SRAM_MspInit 0 */
+ HAL_FSMC_MspInit();
+ /* USER CODE BEGIN SRAM_MspInit 1 */
+
+ /* USER CODE END SRAM_MspInit 1 */
+}
+
+static uint32_t FSMC_DeInitialized = 0;
+
+static void HAL_FSMC_MspDeInit(void){
+ /* USER CODE BEGIN FSMC_MspDeInit 0 */
+
+ /* USER CODE END FSMC_MspDeInit 0 */
+ if (FSMC_DeInitialized) {
+ return;
+ }
+ FSMC_DeInitialized = 1;
+ /* Peripheral clock enable */
+ __HAL_RCC_FSMC_CLK_DISABLE();
+
+ /** FSMC GPIO Configuration
+ PF0 ------> FSMC_A0
+ PE7 ------> FSMC_D4
+ PE8 ------> FSMC_D5
+ PE9 ------> FSMC_D6
+ PE10 ------> FSMC_D7
+ PE11 ------> FSMC_D8
+ PE12 ------> FSMC_D9
+ PE13 ------> FSMC_D10
+ PE14 ------> FSMC_D11
+ PE15 ------> FSMC_D12
+ PD8 ------> FSMC_D13
+ PD9 ------> FSMC_D14
+ PD10 ------> FSMC_D15
+ PD14 ------> FSMC_D0
+ PD15 ------> FSMC_D1
+ PD0 ------> FSMC_D2
+ PD1 ------> FSMC_D3
+ PD4 ------> FSMC_NOE
+ PD5 ------> FSMC_NWE
+ PD7 ------> FSMC_NE1
+ */
+ HAL_GPIO_DeInit(A0_GPIO_Port, A0_Pin);
+
+ HAL_GPIO_DeInit(GPIOE, D4_Pin|D5_Pin|D6_Pin|D7_Pin
+ |D8_Pin|D9_Pin|D10_Pin|D11_Pin
+ |D12_Pin);
+
+ HAL_GPIO_DeInit(GPIOD, D13_Pin|D14_Pin|D15_Pin|D0_Pin
+ |D1_Pin|D2_Pin|D3_Pin|FMC_NOE_Pin
+ |FMC_NWE_Pin|FMC_NE1_Pin);
+
+ /* USER CODE BEGIN FSMC_MspDeInit 1 */
+
+ /* USER CODE END FSMC_MspDeInit 1 */
+}
+
+void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef* hsram){
+ /* USER CODE BEGIN SRAM_MspDeInit 0 */
+
+ /* USER CODE END SRAM_MspDeInit 0 */
+ HAL_FSMC_MspDeInit();
+ /* USER CODE BEGIN SRAM_MspDeInit 1 */
+
+ /* USER CODE END SRAM_MspDeInit 1 */
+}
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/ports/stm32f4/common-hal/board/__init__.c b/ports/stm32f4/common-hal/board/__init__.c
new file mode 100644
index 000000000..880033ed6
--- /dev/null
+++ b/ports/stm32f4/common-hal/board/__init__.c
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
diff --git a/ports/stm32f4/common-hal/digitalio/DigitalInOut.c b/ports/stm32f4/common-hal/digitalio/DigitalInOut.c
new file mode 100644
index 000000000..0805779f4
--- /dev/null
+++ b/ports/stm32f4/common-hal/digitalio/DigitalInOut.c
@@ -0,0 +1,159 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "py/runtime.h"
+#include "supervisor/shared/translate.h"
+#include "stm32f4xx_hal.h"
+#include "stm32f4xx_ll_gpio.h"
+
+void common_hal_digitalio_digitalinout_never_reset(
+ digitalio_digitalinout_obj_t *self) {
+ never_reset_pin_number(self->pin->port_number, self->pin->number);
+}
+
+digitalinout_result_t common_hal_digitalio_digitalinout_construct(
+ digitalio_digitalinout_obj_t *self, const mcu_pin_obj_t *pin) {
+
+ claim_pin(pin);
+ self->pin = pin;
+
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ GPIO_InitStruct.Pin = (1 << pin->number);
+ GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ HAL_GPIO_Init(pin->port, &GPIO_InitStruct);
+
+ return DIGITALINOUT_OK;
+}
+
+bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t *self) {
+ return self->pin == mp_const_none;
+}
+
+void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self) {
+ if (common_hal_digitalio_digitalinout_deinited(self)) {
+ return;
+ }
+
+ reset_pin_number(self->pin->port_number, self->pin->number);
+ self->pin = mp_const_none;
+}
+
+void common_hal_digitalio_digitalinout_switch_to_input(
+ digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) {
+
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ GPIO_InitStruct.Pin = (1 << self->pin->number);
+ GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ HAL_GPIO_Init(self->pin->port, &GPIO_InitStruct);
+
+ common_hal_digitalio_digitalinout_set_pull(self, pull);
+}
+
+void common_hal_digitalio_digitalinout_switch_to_output(
+ digitalio_digitalinout_obj_t *self, bool value,
+ digitalio_drive_mode_t drive_mode) {
+
+ common_hal_digitalio_digitalinout_set_drive_mode(self, drive_mode);
+ common_hal_digitalio_digitalinout_set_value(self, value);
+}
+
+digitalio_direction_t common_hal_digitalio_digitalinout_get_direction(
+ digitalio_digitalinout_obj_t *self) {
+
+ return (LL_GPIO_GetPinMode(self->pin->port, (1 << self->pin->number))
+ == LL_GPIO_MODE_INPUT) ? DIRECTION_INPUT : DIRECTION_OUTPUT;
+}
+
+void common_hal_digitalio_digitalinout_set_value(
+ digitalio_digitalinout_obj_t *self, bool value) {
+ HAL_GPIO_WritePin(self->pin->port, 1 << self->pin->number, value);
+}
+
+bool common_hal_digitalio_digitalinout_get_value(
+ digitalio_digitalinout_obj_t *self) {
+ return (LL_GPIO_GetPinMode(self->pin->port, (1 << self->pin->number)) == LL_GPIO_MODE_INPUT)
+ ? HAL_GPIO_ReadPin(self->pin->port, (1 << self->pin->number))
+ : LL_GPIO_IsOutputPinSet(self->pin->port, (1 << self->pin->number));
+}
+
+void common_hal_digitalio_digitalinout_set_drive_mode(
+ digitalio_digitalinout_obj_t *self,
+ digitalio_drive_mode_t drive_mode) {
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ GPIO_InitStruct.Pin = (1 << self->pin->number);
+ GPIO_InitStruct.Mode = (drive_mode == DRIVE_MODE_OPEN_DRAIN ?
+ GPIO_MODE_OUTPUT_OD : GPIO_MODE_OUTPUT_PP);
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ HAL_GPIO_Init(self->pin->port, &GPIO_InitStruct);
+}
+
+digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode(
+ digitalio_digitalinout_obj_t *self) {
+
+ return LL_GPIO_GetPinOutputType(self->pin->port, (1 << self->pin->port_number))
+ == LL_GPIO_OUTPUT_OPENDRAIN ? DRIVE_MODE_OPEN_DRAIN : DRIVE_MODE_PUSH_PULL;
+}
+
+void common_hal_digitalio_digitalinout_set_pull(
+ digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) {
+
+ switch (pull) {
+ case PULL_UP:
+ LL_GPIO_SetPinPull(self->pin->port,(1 << self->pin->number),LL_GPIO_PULL_UP);
+ break;
+ case PULL_DOWN:
+ LL_GPIO_SetPinPull(self->pin->port,(1 << self->pin->number),LL_GPIO_PULL_DOWN);
+ break;
+ case PULL_NONE:
+ LL_GPIO_SetPinPull(self->pin->port,(1 << self->pin->number),LL_GPIO_PULL_NO);
+ break;
+ default:
+ break;
+ }
+}
+
+digitalio_pull_t common_hal_digitalio_digitalinout_get_pull(
+ digitalio_digitalinout_obj_t *self) {
+
+
+ switch (LL_GPIO_GetPinPull(self->pin->port,(1 << self->pin->number))) {
+ case LL_GPIO_PULL_UP:
+ return PULL_UP;
+ case LL_GPIO_PULL_DOWN:
+ return PULL_DOWN;
+ case LL_GPIO_PULL_NO:
+ return PULL_NONE;
+ default:
+ return PULL_NONE;
+ }
+}
diff --git a/ports/stm32f4/common-hal/digitalio/DigitalInOut.h b/ports/stm32f4/common-hal/digitalio/DigitalInOut.h
new file mode 100644
index 000000000..76aa2c855
--- /dev/null
+++ b/ports/stm32f4/common-hal/digitalio/DigitalInOut.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_STM32F4_COMMON_HAL_DIGITALIO_DIGITALINOUT_H
+#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_DIGITALIO_DIGITALINOUT_H
+
+#include "common-hal/microcontroller/Pin.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ const mcu_pin_obj_t *pin;
+} digitalio_digitalinout_obj_t;
+
+#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_DIGITALIO_DIGITALINOUT_H
diff --git a/ports/stm32f4/common-hal/digitalio/__init__.c b/ports/stm32f4/common-hal/digitalio/__init__.c
new file mode 100644
index 000000000..20fad4595
--- /dev/null
+++ b/ports/stm32f4/common-hal/digitalio/__init__.c
@@ -0,0 +1 @@
+// No digitalio module functions.
diff --git a/ports/stm32f4/common-hal/microcontroller/Pin.c b/ports/stm32f4/common-hal/microcontroller/Pin.c
new file mode 100644
index 000000000..6bfe56515
--- /dev/null
+++ b/ports/stm32f4/common-hal/microcontroller/Pin.c
@@ -0,0 +1,81 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "shared-bindings/microcontroller/Pin.h"
+
+#include "py/mphal.h"
+#include "stm32f4/pins.h"
+#include "stm32f4xx_hal.h"
+
+#define GPIO_PORT_COUNT 5
+
+STATIC uint16_t claimed_pins[GPIO_PORT_COUNT];
+STATIC uint16_t never_reset_pins[GPIO_PORT_COUNT];
+GPIO_TypeDef * ports[GPIO_PORT_COUNT] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE};
+
+void reset_all_pins(void) {
+ // Reset claimed pins
+ for (uint8_t i = 0; i < GPIO_PORT_COUNT; i++) {
+ claimed_pins[i] = never_reset_pins[i];
+ }
+ for (uint8_t i = 0; i < GPIO_PORT_COUNT; i++) {
+ HAL_GPIO_DeInit(ports[i], ~never_reset_pins[i]);
+ }
+}
+
+// Mark pin as free and return it to a quiescent state.
+void reset_pin_number(uint8_t pin_port, uint8_t pin_number) {
+ if (pin_number == NO_PIN) {
+ return;
+ }
+
+ // Clear claimed bit.
+ claimed_pins[pin_port] &= ~(1 << pin_number);
+ // Reset the pin
+ HAL_GPIO_DeInit(ports[pin_port], (1 << pin_number));
+}
+
+
+void never_reset_pin_number(uint8_t pin_port, uint8_t pin_number) {
+ never_reset_pins[pin_port] |= 1 << pin_number;
+}
+
+void claim_pin(const mcu_pin_obj_t* pin) {
+ // Set bit in claimed_pins bitmask.
+ claimed_pins[pin->port_number] |= 1 << pin->number;
+}
+
+
+bool pin_number_is_free(uint8_t pin_port, uint8_t pin_number) {
+ return !(claimed_pins[pin_port] & (1 << pin_number));
+}
+
+bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) {
+
+ return pin_number_is_free(pin->port_number, pin->number);
+
+}
diff --git a/ports/stm32f4/common-hal/microcontroller/Pin.h b/ports/stm32f4/common-hal/microcontroller/Pin.h
new file mode 100644
index 000000000..e5b1b9ceb
--- /dev/null
+++ b/ports/stm32f4/common-hal/microcontroller/Pin.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Scott Shawcroft
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_STM34F4_COMMON_HAL_MICROCONTROLLER_PIN_H
+#define MICROPY_INCLUDED_STM34F4_COMMON_HAL_MICROCONTROLLER_PIN_H
+
+#include "py/mphal.h"
+
+#include "peripherals/stm32f4/pins.h"
+
+void reset_all_pins(void);
+// reset_pin_number takes the pin number instead of the pointer so that objects don't
+// need to store a full pointer.
+void reset_pin_number(uint8_t pin_port, uint8_t pin);
+void claim_pin(const mcu_pin_obj_t* pin);
+bool pin_number_is_free(uint8_t pin_port, uint8_t pin_number);
+void never_reset_pin_number(uint8_t pin_port, uint8_t pin_number);
+
+#endif // MICROPY_INCLUDED_STM34F4_COMMON_HAL_MICROCONTROLLER_PIN_H
diff --git a/ports/stm32f4/common-hal/microcontroller/Processor.c b/ports/stm32f4/common-hal/microcontroller/Processor.c
new file mode 100644
index 000000000..c59c340c0
--- /dev/null
+++ b/ports/stm32f4/common-hal/microcontroller/Processor.c
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "common-hal/microcontroller/Processor.h"
+#include "py/runtime.h"
+#include "supervisor/shared/translate.h"
+
+
+float common_hal_mcu_processor_get_temperature(void) {
+ return 0;
+}
+
+uint32_t common_hal_mcu_processor_get_frequency(void) {
+ return 64000000ul;
+}
+
+void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) {
+ for (int i=0; i<2; i++) {
+ ((uint32_t*) raw_id)[i] = 0;
+ }
+}
diff --git a/ports/stm32f4/common-hal/microcontroller/Processor.h b/ports/stm32f4/common-hal/microcontroller/Processor.h
new file mode 100644
index 000000000..c3ca4efd5
--- /dev/null
+++ b/ports/stm32f4/common-hal/microcontroller/Processor.h
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_STM32F4_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H
+#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H
+
+#define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH 8
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ // Stores no state currently.
+} mcu_processor_obj_t;
+
+#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H
diff --git a/ports/stm32f4/common-hal/microcontroller/__init__.c b/ports/stm32f4/common-hal/microcontroller/__init__.c
new file mode 100644
index 000000000..871caa018
--- /dev/null
+++ b/ports/stm32f4/common-hal/microcontroller/__init__.c
@@ -0,0 +1,191 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/mphal.h"
+#include "py/obj.h"
+#include "py/runtime.h"
+
+#include "common-hal/microcontroller/Pin.h"
+#include "common-hal/microcontroller/Processor.h"
+
+#include "shared-bindings/nvm/ByteArray.h"
+#include "shared-bindings/microcontroller/__init__.h"
+#include "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/microcontroller/Processor.h"
+
+#include "supervisor/filesystem.h"
+
+// This routine should work even when interrupts are disabled. Used by OneWire
+// for precise timing.
+void common_hal_mcu_delay_us(uint32_t delay) {
+ //NRFX_DELAY_US(delay);
+}
+
+void common_hal_mcu_disable_interrupts() {
+}
+
+void common_hal_mcu_enable_interrupts() {
+}
+
+void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
+ // TODO: see atmel-samd for functionality
+}
+
+void common_hal_mcu_reset(void) {
+ // filesystem_flush();
+ // NVIC_SystemReset();
+}
+
+// The singleton microcontroller.Processor object, bound to microcontroller.cpu
+// It currently only has properties, and no state.
+const mcu_processor_obj_t common_hal_mcu_processor_obj = {
+ .base = {
+ .type = &mcu_processor_type,
+ },
+};
+
+#if CIRCUITPY_INTERNAL_NVM_SIZE > 0
+// The singleton nvm.ByteArray object.
+const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = {
+ .base = {
+ .type = &nvm_bytearray_type,
+ },
+};
+#endif
+
+STATIC const mp_rom_map_elem_t mcu_pin_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_PE02), MP_ROM_PTR(&pin_PE02) },
+ { MP_ROM_QSTR(MP_QSTR_PE03), MP_ROM_PTR(&pin_PE03) },
+ { MP_ROM_QSTR(MP_QSTR_PE04), MP_ROM_PTR(&pin_PE04) },
+ { MP_ROM_QSTR(MP_QSTR_PE05), MP_ROM_PTR(&pin_PE05) },
+ { MP_ROM_QSTR(MP_QSTR_PE06), MP_ROM_PTR(&pin_PE06) },
+ { MP_ROM_QSTR(MP_QSTR_PC13), MP_ROM_PTR(&pin_PC13) },
+ { MP_ROM_QSTR(MP_QSTR_PF00), MP_ROM_PTR(&pin_PF00) },
+ { MP_ROM_QSTR(MP_QSTR_PF01), MP_ROM_PTR(&pin_PF01) },
+ { MP_ROM_QSTR(MP_QSTR_PF02), MP_ROM_PTR(&pin_PF02) },
+ { MP_ROM_QSTR(MP_QSTR_PF03), MP_ROM_PTR(&pin_PF03) },
+ { MP_ROM_QSTR(MP_QSTR_PF04), MP_ROM_PTR(&pin_PF04) },
+ { MP_ROM_QSTR(MP_QSTR_PF05), MP_ROM_PTR(&pin_PF05) },
+ { MP_ROM_QSTR(MP_QSTR_PF06), MP_ROM_PTR(&pin_PF06) },
+ { MP_ROM_QSTR(MP_QSTR_PF07), MP_ROM_PTR(&pin_PF07) },
+ { MP_ROM_QSTR(MP_QSTR_PF08), MP_ROM_PTR(&pin_PF08) },
+ { MP_ROM_QSTR(MP_QSTR_PF09), MP_ROM_PTR(&pin_PF09) },
+ { MP_ROM_QSTR(MP_QSTR_PF10), MP_ROM_PTR(&pin_PF10) },
+ { MP_ROM_QSTR(MP_QSTR_PC00), MP_ROM_PTR(&pin_PC00) },
+ { MP_ROM_QSTR(MP_QSTR_PC01), MP_ROM_PTR(&pin_PC01) },
+ { MP_ROM_QSTR(MP_QSTR_PC02), MP_ROM_PTR(&pin_PC02) },
+ { MP_ROM_QSTR(MP_QSTR_PC03), MP_ROM_PTR(&pin_PC03) },
+ { MP_ROM_QSTR(MP_QSTR_PA00), MP_ROM_PTR(&pin_PA00) },
+ { MP_ROM_QSTR(MP_QSTR_PA01), MP_ROM_PTR(&pin_PA01) },
+ { MP_ROM_QSTR(MP_QSTR_PA02), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_PA03), MP_ROM_PTR(&pin_PA03) },
+ { MP_ROM_QSTR(MP_QSTR_PA04), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_PA05), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_PA06), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_PA07), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_PC04), MP_ROM_PTR(&pin_PC04) },
+ { MP_ROM_QSTR(MP_QSTR_PC05), MP_ROM_PTR(&pin_PC05) },
+ { MP_ROM_QSTR(MP_QSTR_PB00), MP_ROM_PTR(&pin_PB00) },
+ { MP_ROM_QSTR(MP_QSTR_PB01), MP_ROM_PTR(&pin_PB01) },
+ { MP_ROM_QSTR(MP_QSTR_PB02), MP_ROM_PTR(&pin_PB02) },
+ { MP_ROM_QSTR(MP_QSTR_PF11), MP_ROM_PTR(&pin_PF11) },
+ { MP_ROM_QSTR(MP_QSTR_PF12), MP_ROM_PTR(&pin_PF12) },
+ { MP_ROM_QSTR(MP_QSTR_PF13), MP_ROM_PTR(&pin_PF13) },
+ { MP_ROM_QSTR(MP_QSTR_PF14), MP_ROM_PTR(&pin_PF14) },
+ { MP_ROM_QSTR(MP_QSTR_PF15), MP_ROM_PTR(&pin_PF15) },
+ { MP_ROM_QSTR(MP_QSTR_PG00), MP_ROM_PTR(&pin_PG00) },
+ { MP_ROM_QSTR(MP_QSTR_PG01), MP_ROM_PTR(&pin_PG01) },
+ { MP_ROM_QSTR(MP_QSTR_PE07), MP_ROM_PTR(&pin_PE07) },
+ { MP_ROM_QSTR(MP_QSTR_PE08), MP_ROM_PTR(&pin_PE08) },
+ { MP_ROM_QSTR(MP_QSTR_PE09), MP_ROM_PTR(&pin_PE09) },
+ { MP_ROM_QSTR(MP_QSTR_PE10), MP_ROM_PTR(&pin_PE10) },
+ { MP_ROM_QSTR(MP_QSTR_PE11), MP_ROM_PTR(&pin_PE11) },
+ { MP_ROM_QSTR(MP_QSTR_PE12), MP_ROM_PTR(&pin_PE12) },
+ { MP_ROM_QSTR(MP_QSTR_PE13), MP_ROM_PTR(&pin_PE13) },
+ { MP_ROM_QSTR(MP_QSTR_PE14), MP_ROM_PTR(&pin_PE14) },
+ { MP_ROM_QSTR(MP_QSTR_PE15), MP_ROM_PTR(&pin_PE15) },
+ { MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_PB11), MP_ROM_PTR(&pin_PB11) },
+ { MP_ROM_QSTR(MP_QSTR_PB12), MP_ROM_PTR(&pin_PB12) },
+ { MP_ROM_QSTR(MP_QSTR_PB13), MP_ROM_PTR(&pin_PB13) },
+ { MP_ROM_QSTR(MP_QSTR_PB14), MP_ROM_PTR(&pin_PB14) },
+ { MP_ROM_QSTR(MP_QSTR_PB15), MP_ROM_PTR(&pin_PB15) },
+ { MP_ROM_QSTR(MP_QSTR_PD08), MP_ROM_PTR(&pin_PD08) },
+ { MP_ROM_QSTR(MP_QSTR_PD09), MP_ROM_PTR(&pin_PD09) },
+ { MP_ROM_QSTR(MP_QSTR_PD10), MP_ROM_PTR(&pin_PD10) },
+ { MP_ROM_QSTR(MP_QSTR_PD11), MP_ROM_PTR(&pin_PD11) },
+ { MP_ROM_QSTR(MP_QSTR_PD12), MP_ROM_PTR(&pin_PD12) },
+ { MP_ROM_QSTR(MP_QSTR_PD13), MP_ROM_PTR(&pin_PD13) },
+ { MP_ROM_QSTR(MP_QSTR_PD14), MP_ROM_PTR(&pin_PD14) },
+ { MP_ROM_QSTR(MP_QSTR_PD15), MP_ROM_PTR(&pin_PD15) },
+ { MP_ROM_QSTR(MP_QSTR_PG02), MP_ROM_PTR(&pin_PG02) },
+ { MP_ROM_QSTR(MP_QSTR_PG03), MP_ROM_PTR(&pin_PG03) },
+ { MP_ROM_QSTR(MP_QSTR_PG04), MP_ROM_PTR(&pin_PG04) },
+ { MP_ROM_QSTR(MP_QSTR_PG05), MP_ROM_PTR(&pin_PG05) },
+ { MP_ROM_QSTR(MP_QSTR_PG06), MP_ROM_PTR(&pin_PG06) },
+ { MP_ROM_QSTR(MP_QSTR_PG07), MP_ROM_PTR(&pin_PG07) },
+ { MP_ROM_QSTR(MP_QSTR_PG08), MP_ROM_PTR(&pin_PG08) },
+ { MP_ROM_QSTR(MP_QSTR_PC06), MP_ROM_PTR(&pin_PC06) },
+ { MP_ROM_QSTR(MP_QSTR_PC07), MP_ROM_PTR(&pin_PC07) },
+ { MP_ROM_QSTR(MP_QSTR_PC08), MP_ROM_PTR(&pin_PC08) },
+ { MP_ROM_QSTR(MP_QSTR_PC09), MP_ROM_PTR(&pin_PC09) },
+ { MP_ROM_QSTR(MP_QSTR_PA08), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_PA09), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_PA10), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_PA11), MP_ROM_PTR(&pin_PA11) },
+ { MP_ROM_QSTR(MP_QSTR_PA12), MP_ROM_PTR(&pin_PA12) },
+ { MP_ROM_QSTR(MP_QSTR_PA13), MP_ROM_PTR(&pin_PA13) },
+ { MP_ROM_QSTR(MP_QSTR_PA14), MP_ROM_PTR(&pin_PA14) },
+ { MP_ROM_QSTR(MP_QSTR_PA15), MP_ROM_PTR(&pin_PA15) },
+ { MP_ROM_QSTR(MP_QSTR_PC10), MP_ROM_PTR(&pin_PC10) },
+ { MP_ROM_QSTR(MP_QSTR_PC11), MP_ROM_PTR(&pin_PC11) },
+ { MP_ROM_QSTR(MP_QSTR_PC12), MP_ROM_PTR(&pin_PC12) },
+ { MP_ROM_QSTR(MP_QSTR_PD00), MP_ROM_PTR(&pin_PD00) },
+ { MP_ROM_QSTR(MP_QSTR_PD01), MP_ROM_PTR(&pin_PD01) },
+ { MP_ROM_QSTR(MP_QSTR_PD02), MP_ROM_PTR(&pin_PD02) },
+ { MP_ROM_QSTR(MP_QSTR_PD03), MP_ROM_PTR(&pin_PD03) },
+ { MP_ROM_QSTR(MP_QSTR_PD04), MP_ROM_PTR(&pin_PD04) },
+ { MP_ROM_QSTR(MP_QSTR_PD05), MP_ROM_PTR(&pin_PD05) },
+ { MP_ROM_QSTR(MP_QSTR_PD06), MP_ROM_PTR(&pin_PD06) },
+ { MP_ROM_QSTR(MP_QSTR_PD07), MP_ROM_PTR(&pin_PD07) },
+ { MP_ROM_QSTR(MP_QSTR_PG09), MP_ROM_PTR(&pin_PG09) },
+ { MP_ROM_QSTR(MP_QSTR_PG10), MP_ROM_PTR(&pin_PG10) },
+ { MP_ROM_QSTR(MP_QSTR_PG11), MP_ROM_PTR(&pin_PG11) },
+ { MP_ROM_QSTR(MP_QSTR_PG12), MP_ROM_PTR(&pin_PG12) },
+ { MP_ROM_QSTR(MP_QSTR_PG13), MP_ROM_PTR(&pin_PG13) },
+ { MP_ROM_QSTR(MP_QSTR_PG14), MP_ROM_PTR(&pin_PG14) },
+ { MP_ROM_QSTR(MP_QSTR_PG15), MP_ROM_PTR(&pin_PG15) },
+ { MP_ROM_QSTR(MP_QSTR_PB03), MP_ROM_PTR(&pin_PB03) },
+ { MP_ROM_QSTR(MP_QSTR_PB04), MP_ROM_PTR(&pin_PB04) },
+ { MP_ROM_QSTR(MP_QSTR_PB05), MP_ROM_PTR(&pin_PB05) },
+ { MP_ROM_QSTR(MP_QSTR_PB06), MP_ROM_PTR(&pin_PB06) },
+ { MP_ROM_QSTR(MP_QSTR_PB07), MP_ROM_PTR(&pin_PB07) },
+ { MP_ROM_QSTR(MP_QSTR_PB08), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_PB09), MP_ROM_PTR(&pin_PB09) },
+ { MP_ROM_QSTR(MP_QSTR_PE00), MP_ROM_PTR(&pin_PE00) },
+ { MP_ROM_QSTR(MP_QSTR_PE01), MP_ROM_PTR(&pin_PE01) },
+};
+MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_globals_table);
diff --git a/ports/stm32f4/common-hal/nvm/ByteArray.c b/ports/stm32f4/common-hal/nvm/ByteArray.c
new file mode 100644
index 000000000..ef70744ad
--- /dev/null
+++ b/ports/stm32f4/common-hal/nvm/ByteArray.c
@@ -0,0 +1,81 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Nick Moore for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+//TODO: Implement for STM32. File required by Microcontroller Init
+
+#include "common-hal/nvm/ByteArray.h"
+
+#include <stdio.h>
+#include <string.h>
+
+// defined in linker
+extern uint32_t __fatfs_flash_start_addr[];
+extern uint32_t __fatfs_flash_length[];
+
+#define NVM_START_ADDR ((uint32_t)__fatfs_flash_start_addr + \
+ (uint32_t)__fatfs_flash_length - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+uint32_t common_hal_nvm_bytearray_get_length(nvm_bytearray_obj_t *self) {
+ return CIRCUITPY_INTERNAL_NVM_SIZE;
+}
+
+static void write_page(uint32_t page_addr, uint32_t offset, uint32_t len, uint8_t *bytes) {
+ //
+ // Write a whole page to flash, buffering it first and then erasing and rewriting
+ // it since we can only clear a whole page at a time.
+
+ // if (offset == 0 && len == FLASH_PAGE_SIZE) {
+ // nrf_nvm_safe_flash_page_write(page_addr, bytes);
+ // } else {
+ // uint8_t buffer[FLASH_PAGE_SIZE];
+ // memcpy(buffer, (uint8_t *)page_addr, FLASH_PAGE_SIZE);
+ // memcpy(buffer + offset, bytes, len);
+ // nrf_nvm_safe_flash_page_write(page_addr, buffer);
+ // }
+}
+
+bool common_hal_nvm_bytearray_set_bytes(nvm_bytearray_obj_t *self,
+ // uint32_t start_index, uint8_t* values, uint32_t len) {
+
+ // uint32_t address = NVM_START_ADDR + start_index;
+ // uint32_t offset = address % FLASH_PAGE_SIZE;
+ // uint32_t page_addr = address - offset;
+
+ // while (len) {
+ // uint32_t write_len = MIN(len, FLASH_PAGE_SIZE - offset);
+ // write_page(page_addr, offset, write_len, values);
+ // len -= write_len;
+ // values += write_len;
+ // page_addr += FLASH_PAGE_SIZE;
+ // offset = 0;
+ // }
+ return true;
+}
+
+void common_hal_nvm_bytearray_get_bytes(nvm_bytearray_obj_t *self,
+ uint32_t start_index, uint32_t len, uint8_t* values) {
+ memcpy(values, (uint8_t *)(NVM_START_ADDR + start_index), len);
+}
diff --git a/ports/stm32f4/common-hal/nvm/ByteArray.h b/ports/stm32f4/common-hal/nvm/ByteArray.h
new file mode 100644
index 000000000..ed00df9ff
--- /dev/null
+++ b/ports/stm32f4/common-hal/nvm/ByteArray.h
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Nick Moore for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_STM32F4_COMMON_HAL_NVM_BYTEARRAY_H
+#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_NVM_BYTEARRAY_H
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+} nvm_bytearray_obj_t;
+
+#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_NVM_BYTEARRAY_H
diff --git a/ports/stm32f4/common-hal/nvm/__init__.c b/ports/stm32f4/common-hal/nvm/__init__.c
new file mode 100644
index 000000000..3cdc9d3a4
--- /dev/null
+++ b/ports/stm32f4/common-hal/nvm/__init__.c
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Nick Moore for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+// No nvm module functions.
diff --git a/ports/stm32f4/common-hal/supervisor/Runtime.c b/ports/stm32f4/common-hal/supervisor/Runtime.c
new file mode 100755
index 000000000..feab6987d
--- /dev/null
+++ b/ports/stm32f4/common-hal/supervisor/Runtime.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Michael Schroeder
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdbool.h>
+#include "shared-bindings/supervisor/Runtime.h"
+#include "supervisor/serial.h"
+
+bool common_hal_get_serial_connected(void) {
+ return (bool) serial_connected();
+}
+
+bool common_hal_get_serial_bytes_available(void) {
+ return (bool) serial_bytes_available();
+}
+
diff --git a/ports/stm32f4/common-hal/supervisor/Runtime.h b/ports/stm32f4/common-hal/supervisor/Runtime.h
new file mode 100755
index 000000000..9a798e056
--- /dev/null
+++ b/ports/stm32f4/common-hal/supervisor/Runtime.h
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Michael Schroeder
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_STM32F4_COMMON_HAL_SUPERVISOR_RUNTIME_H
+#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_SUPERVISOR_RUNTIME_H
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ // Stores no state currently.
+} super_runtime_obj_t;
+
+#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_SUPERVISOR_RUNTIME_H
diff --git a/ports/stm32f4/common-hal/supervisor/__init__.c b/ports/stm32f4/common-hal/supervisor/__init__.c
new file mode 100755
index 000000000..ac88556b4
--- /dev/null
+++ b/ports/stm32f4/common-hal/supervisor/__init__.c
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Michael Schroeder
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+#include "py/obj.h"
+
+#include "shared-bindings/supervisor/__init__.h"
+#include "shared-bindings/supervisor/Runtime.h"
+
+
+// The singleton supervisor.Runtime object, bound to supervisor.runtime
+// It currently only has properties, and no state.
+const super_runtime_obj_t common_hal_supervisor_runtime_obj = {
+ .base = {
+ .type = &supervisor_runtime_type,
+ },
+}; \ No newline at end of file
diff --git a/ports/stm32f4/common-hal/time/__init__.c b/ports/stm32f4/common-hal/time/__init__.c
new file mode 100644
index 000000000..e3cb481ef
--- /dev/null
+++ b/ports/stm32f4/common-hal/time/__init__.c
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/mphal.h"
+
+#include "tick.h"
+
+uint64_t common_hal_time_monotonic(void) {
+ return ticks_ms;
+}
+
+void common_hal_time_delay_ms(uint32_t delay) {
+ mp_hal_delay_ms(delay);
+}
diff --git a/ports/stm32f4/fatfs_port.c b/ports/stm32f4/fatfs_port.c
new file mode 100644
index 000000000..13ac21fb1
--- /dev/null
+++ b/ports/stm32f4/fatfs_port.c
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013, 2014 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/runtime.h"
+#include "lib/oofatfs/ff.h"
+
+DWORD get_fattime(void) {
+ // TODO: Implement this function. For now, fake it.
+ return ((2016 - 1980) << 25) | ((12) << 21) | ((4) << 16) | ((00) << 11) | ((18) << 5) | (23 / 2);
+}
diff --git a/ports/stm32f4/mpconfigport.h b/ports/stm32f4/mpconfigport.h
new file mode 100644
index 000000000..543a55942
--- /dev/null
+++ b/ports/stm32f4/mpconfigport.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef STM32F4_MPCONFIGPORT_H__
+#define STM32F4_MPCONFIGPORT_H__
+
+#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1)
+#define MICROPY_PY_FUNCTION_ATTRS (1)
+#define MICROPY_PY_IO (1)
+#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1)
+#define MICROPY_PY_UJSON (1)
+
+// 24kiB stack
+#define CIRCUITPY_DEFAULT_STACK_SIZE 0x6000
+
+#include "py/circuitpy_mpconfig.h"
+
+#define MICROPY_PORT_ROOT_POINTERS \
+ CIRCUITPY_COMMON_ROOT_POINTERS
+
+#endif // __INCLUDED_MPCONFIGPORT_H
diff --git a/ports/stm32f4/mpconfigport.mk b/ports/stm32f4/mpconfigport.mk
new file mode 100644
index 000000000..814bb2b20
--- /dev/null
+++ b/ports/stm32f4/mpconfigport.mk
@@ -0,0 +1,22 @@
+# Define an equivalent for MICROPY_LONGINT_IMPL, to pass to $(MPY-TOOL) in py/mkrules.mk
+# $(MPY-TOOL) needs to know what kind of longint to use (if any) to freeze long integers.
+# This should correspond to the MICROPY_LONGINT_IMPL definition in mpconfigport.h.
+MPY_TOOL_LONGINT_IMPL = -mlongint-impl=mpz
+
+# Internal math library is substantially smaller than toolchain one
+INTERNAL_LIBM = 1
+
+# Chip supplied serial number, in bytes
+USB_SERIAL_NUMBER_LENGTH = 16
+
+# Longints can be implemented as mpz, as longlong, or not
+LONGINT_IMPL = MPZ
+
+#Reduced feature set for early port
+CIRCUITPY_MINIMAL_BUILD = 1
+
+ifeq ($(MCU_SUB_VARIANT), stm32f412zx)
+ CIRCUITPY_BOARD = 1
+ CIRCUITPY_DIGITALIO = 1
+ CIRCUITPY_MICROCONTROLLER = 1
+endif
diff --git a/ports/stm32f4/mphalport.c b/ports/stm32f4/mphalport.c
new file mode 100644
index 000000000..ea864e7ce
--- /dev/null
+++ b/ports/stm32f4/mphalport.c
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Glenn Ruben Bakke
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+
+#include "py/mphal.h"
+#include "py/mpstate.h"
+#include "py/gc.h"
+
+/*------------------------------------------------------------------*/
+/* delay
+ *------------------------------------------------------------------*/
+void mp_hal_delay_ms(mp_uint_t delay) {
+ uint64_t start_tick = ticks_ms;
+ uint64_t duration = 0;
+ while (duration < delay) {
+ #ifdef MICROPY_VM_HOOK_LOOP
+ MICROPY_VM_HOOK_LOOP
+ #endif
+ // Check to see if we've been CTRL-Ced by autoreload or the user.
+ if(MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) ||
+ MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
+ break;
+ }
+ duration = (ticks_ms - start_tick);
+ // TODO(tannewt): Go to sleep for a little while while we wait.
+ }
+}
diff --git a/ports/stm32f4/mphalport.h b/ports/stm32f4/mphalport.h
new file mode 100644
index 000000000..131f2751d
--- /dev/null
+++ b/ports/stm32f4/mphalport.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Glenn Ruben Bakke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef __STM32F4_HAL
+#define __STM32F4_HAL
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "lib/utils/interrupt_char.h"
+#include "py/mpconfig.h"
+
+//extern nrfx_uarte_t serial_instance;
+
+extern volatile uint64_t ticks_ms;
+
+#define mp_hal_ticks_ms() ((mp_uint_t) ticks_ms)
+//#define mp_hal_delay_us(us) NRFX_DELAY_US((uint32_t) (us))
+
+bool mp_hal_stdin_any(void);
+
+#endif
diff --git a/ports/stm32f4/peripherals/stm32f4/clocks.h b/ports/stm32f4/peripherals/stm32f4/clocks.h
new file mode 100644
index 000000000..c7ba84662
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/clocks.h
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+void stm32f4_peripherals_clocks_init(void);
diff --git a/ports/stm32f4/peripherals/stm32f4/gpio.h b/ports/stm32f4/peripherals/stm32f4/gpio.h
new file mode 100644
index 000000000..251cdb814
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/gpio.h
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+void stm32f4_peripherals_gpio_init(void);
diff --git a/ports/stm32f4/peripherals/stm32f4/pins.h b/ports/stm32f4/peripherals/stm32f4/pins.h
new file mode 100644
index 000000000..1b48cc192
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/pins.h
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+// DO NOT include this file directly. Use shared-bindings/microcontroller/Pin.h instead to ensure
+// that all necessary includes are already included.
+
+#ifndef __MICROPY_INCLUDED_STM32F4_PERIPHERALS_PINS_H__
+#define __MICROPY_INCLUDED_STM32F4_PERIPHERALS_PINS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "stm32f4xx_hal.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ //uint8_t number; //(3)port,(5)pin
+ uint8_t port_number;
+ GPIO_TypeDef * port;
+ uint8_t number;
+} mcu_pin_obj_t;
+
+// extern GPIO_TypeDef *port_lookup_table[];
+
+// static inline GPIO_TypeDef * get_GPIO_ptr(const mcu_pin_obj_t *p)
+// {
+// return port_lookup_table[0x7&( (p->number) >> 5)];
+// }
+
+extern const mp_obj_type_t mcu_pin_type;
+
+// Used in device-specific pins.c
+#define PIN(p_port_num, p_port, p_number) \
+{ \
+ { &mcu_pin_type }, \
+ .port_number = (p_port_num), \
+ .port = (p_port), \
+ .number = (p_number), \
+}
+
+// Use illegal pin value to mark unassigned pins.
+#define NO_PIN 0xff
+
+// Choose based on chip
+#ifdef STM32F412Zx
+#include "stm32f412zx/pins.h"
+#endif
+
+#endif // __MICROPY_INCLUDED_STM32F4_PERIPHERALS_PINS_H__
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/clocks.c b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/clocks.c
new file mode 100644
index 000000000..5b7a1e298
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/clocks.c
@@ -0,0 +1,63 @@
+
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "stm32f4xx_hal.h"
+
+void stm32f4_peripherals_clocks_init(void) {
+ //System clock init
+ RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
+ /** Configure the main internal regulator output voltage
+ */
+ __HAL_RCC_PWR_CLK_ENABLE();
+ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
+ /** Initializes the CPU, AHB and APB busses clocks
+ */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+ RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+ RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
+ RCC_OscInitStruct.PLL.PLLM = 4;
+ RCC_OscInitStruct.PLL.PLLN = 192;
+ RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
+ RCC_OscInitStruct.PLL.PLLQ = 8;
+ HAL_RCC_OscConfig(&RCC_OscInitStruct);
+ /** Initializes the CPU, AHB and APB busses clocks
+ */
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
+ |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+ HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3);
+ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S;
+ PeriphClkInitStruct.PLLI2S.PLLI2SN = 200;
+ PeriphClkInitStruct.PLLI2S.PLLI2SM = 5;
+ PeriphClkInitStruct.PLLI2S.PLLI2SR = 2;
+ HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
+}
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/gpio.c b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/gpio.c
new file mode 100644
index 000000000..a9ac97bae
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/gpio.c
@@ -0,0 +1,137 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* GPIO PIN REFERENCE
+#define DATA_Ready_Pin GPIO_PIN_2
+#define DATA_Ready_GPIO_Port GPIOE
+#define CS_I2C_SPI_Pin GPIO_PIN_3
+#define CS_I2C_SPI_GPIO_Port GPIOE
+#define INT1_Pin GPIO_PIN_4
+#define INT1_GPIO_Port GPIOE
+#define INT2_Pin GPIO_PIN_5
+#define INT2_GPIO_Port GPIOE
+#define PC14_OSC32_IN_Pin GPIO_PIN_14
+#define PC14_OSC32_IN_GPIO_Port GPIOC
+#define PC15_OSC32_OUT_Pin GPIO_PIN_15
+#define PC15_OSC32_OUT_GPIO_Port GPIOC
+#define PH0_OSC_IN_Pin GPIO_PIN_0
+#define PH0_OSC_IN_GPIO_Port GPIOH
+#define PH1_OSC_OUT_Pin GPIO_PIN_1
+#define PH1_OSC_OUT_GPIO_Port GPIOH
+#define OTG_FS_PowerSwitchOn_Pin GPIO_PIN_0
+#define OTG_FS_PowerSwitchOn_GPIO_Port GPIOC
+#define PDM_OUT_Pin GPIO_PIN_3
+#define PDM_OUT_GPIO_Port GPIOC
+#define I2S3_WS_Pin GPIO_PIN_4
+#define I2S3_WS_GPIO_Port GPIOA
+#define SPI1_SCK_Pin GPIO_PIN_5
+#define SPI1_SCK_GPIO_Port GPIOA
+#define SPI1_MISO_Pin GPIO_PIN_6
+#define SPI1_MISO_GPIO_Port GPIOA
+#define SPI1_MOSI_Pin GPIO_PIN_7
+#define SPI1_MOSI_GPIO_Port GPIOA
+#define CLK_IN_Pin GPIO_PIN_10
+#define CLK_IN_GPIO_Port GPIOB
+#define LD4_Pin GPIO_PIN_12
+#define LD4_GPIO_Port GPIOD
+#define LD3_Pin GPIO_PIN_13
+#define LD3_GPIO_Port GPIOD
+#define LD5_Pin GPIO_PIN_14
+#define LD5_GPIO_Port GPIOD
+#define LD6_Pin GPIO_PIN_15
+#define LD6_GPIO_Port GPIOD
+#define I2S3_MCK_Pin GPIO_PIN_7
+#define I2S3_MCK_GPIO_Port GPIOC
+#define VBUS_FS_Pin GPIO_PIN_9
+#define VBUS_FS_GPIO_Port GPIOA
+#define OTG_FS_ID_Pin GPIO_PIN_10
+#define OTG_FS_ID_GPIO_Port GPIOA
+#define OTG_FS_DM_Pin GPIO_PIN_11
+#define OTG_FS_DM_GPIO_Port GPIOA
+#define OTG_FS_DP_Pin GPIO_PIN_12
+#define OTG_FS_DP_GPIO_Port GPIOA
+#define SWDIO_Pin GPIO_PIN_13
+#define SWDIO_GPIO_Port GPIOA
+#define SWCLK_Pin GPIO_PIN_14
+#define SWCLK_GPIO_Port GPIOA
+#define I2S3_SCK_Pin GPIO_PIN_10
+#define I2S3_SCK_GPIO_Port GPIOC
+#define I2S3_SD_Pin GPIO_PIN_12
+#define I2S3_SD_GPIO_Port GPIOC
+#define Audio_RST_Pin GPIO_PIN_4
+#define Audio_RST_GPIO_Port GPIOD
+#define OTG_FS_OverCurrent_Pin GPIO_PIN_5
+#define OTG_FS_OverCurrent_GPIO_Port GPIOD
+#define SWO_Pin GPIO_PIN_3
+#define SWO_GPIO_Port GPIOB
+#define Audio_SCL_Pin GPIO_PIN_6
+#define Audio_SCL_GPIO_Port GPIOB
+#define Audio_SDA_Pin GPIO_PIN_9
+#define Audio_SDA_GPIO_Port GPIOB
+#define MEMS_INT2_Pin GPIO_PIN_1
+#define MEMS_INT2_GPIO_Port GPIOE
+*/
+
+#define LD4_Pin GPIO_PIN_12
+#define LD4_GPIO_Port GPIOD
+#define LD3_Pin GPIO_PIN_13
+#define LD3_GPIO_Port GPIOD
+#define LD5_Pin GPIO_PIN_14
+#define LD5_GPIO_Port GPIOD
+#define LD6_Pin GPIO_PIN_15
+#define LD6_GPIO_Port GPIOD
+
+#include "stm32f4xx_hal.h"
+
+void stm32f4_peripherals_gpio_init(void) {
+ //Enable all GPIO for now
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ /* GPIO Ports Clock Enable */
+ __HAL_RCC_GPIOE_CLK_ENABLE();
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOH_CLK_ENABLE();
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOD_CLK_ENABLE();
+
+ /*Configure GPIO pin Output Level */
+ HAL_GPIO_WritePin(GPIOD, LD4_Pin|LD3_Pin|LD5_Pin|LD6_Pin, GPIO_PIN_RESET);
+
+ /*Configure GPIO pins : LD4_Pin LD3_Pin LD5_Pin LD6_Pin */
+ GPIO_InitStruct.Pin = LD4_Pin|LD3_Pin|LD5_Pin|LD6_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+ //Status LED chain
+ HAL_GPIO_WritePin(GPIOD, LD4_Pin, GPIO_PIN_RESET); //LED 1
+ HAL_GPIO_WritePin(GPIOD, LD3_Pin, GPIO_PIN_SET); //LED 2
+ HAL_GPIO_WritePin(GPIOD, LD5_Pin, GPIO_PIN_SET); //LED 3
+ HAL_GPIO_WritePin(GPIOD, LD6_Pin, GPIO_PIN_SET); //LED 4
+}
+
+
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.c b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.c
new file mode 100644
index 000000000..04502d714
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.c
@@ -0,0 +1,33 @@
+ /*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/obj.h"
+#include "py/mphal.h"
+#include "stm32f4/pins.h"
+
+
+//TODO
+//const mcu_pin_obj_t pin_PE02 = PIN(4, GPIOE, 2); \ No newline at end of file
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.h b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.h
new file mode 100644
index 000000000..b060d9ed0
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.h
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411RE_PINS_H
+#define MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411RE_PINS_H
+
+//TODO
+//Pins in datasheet order: DocID028087 Rev 7 page 50. LQFP100 only
+//pg 50
+//extern const mcu_pin_obj_t pin_PE02;
+
+
+#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411RE_PINS_H
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/clocks.c b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/clocks.c
new file mode 100644
index 000000000..0ccd9cb48
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/clocks.c
@@ -0,0 +1,75 @@
+
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "stm32f4xx_hal.h"
+
+void stm32f4_peripherals_clocks_init(void) {
+ //System clock init
+ RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
+ /** Configure the main internal regulator output voltage
+ */
+ __HAL_RCC_PWR_CLK_ENABLE();
+ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
+ /** Initializes the CPU, AHB and APB busses clocks
+ */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;
+ RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+ RCC_OscInitStruct.HSIState = RCC_HSI_ON;
+ RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+ RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
+ RCC_OscInitStruct.PLL.PLLM = 4;
+ RCC_OscInitStruct.PLL.PLLN = 72;
+ RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
+ RCC_OscInitStruct.PLL.PLLQ = 3;
+ RCC_OscInitStruct.PLL.PLLR = 2;
+ HAL_RCC_OscConfig(&RCC_OscInitStruct);
+ /** Initializes the CPU, AHB and APB busses clocks
+ */
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
+ |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+ HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
+
+ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1|RCC_PERIPHCLK_SDIO
+ |RCC_PERIPHCLK_CLK48;
+ PeriphClkInitStruct.PLLI2S.PLLI2SN = 50;
+ PeriphClkInitStruct.PLLI2S.PLLI2SM = 4;
+ PeriphClkInitStruct.PLLI2S.PLLI2SR = 2;
+ PeriphClkInitStruct.PLLI2S.PLLI2SQ = 2;
+ PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48CLKSOURCE_PLLQ;
+ PeriphClkInitStruct.SdioClockSelection = RCC_SDIOCLKSOURCE_CLK48;
+ PeriphClkInitStruct.PLLI2SSelection = RCC_PLLI2SCLKSOURCE_PLLSRC;
+ PeriphClkInitStruct.I2sApb1ClockSelection = RCC_I2SAPB1CLKSOURCE_PLLI2S;
+ HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
+
+ HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI, RCC_MCODIV_1);
+}
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/gpio.c b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/gpio.c
new file mode 100644
index 000000000..de783bafe
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/gpio.c
@@ -0,0 +1,218 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* GPIO PIN REFERENCE
+#define LED3_Pin GPIO_PIN_2
+#define LED3_GPIO_Port GPIOE
+#define LED4_Pin GPIO_PIN_3
+#define LED4_GPIO_Port GPIOE
+#define DFSDM_DATIN3_Pin GPIO_PIN_4
+#define DFSDM_DATIN3_GPIO_Port GPIOE
+#define A0_Pin GPIO_PIN_0
+#define A0_GPIO_Port GPIOF
+#define LCD_BLCTRL_Pin GPIO_PIN_5
+#define LCD_BLCTRL_GPIO_Port GPIOF
+#define QSPI_BK1_IO3_Pin GPIO_PIN_6
+#define QSPI_BK1_IO3_GPIO_Port GPIOF
+#define QSPI_BK1_IO2_Pin GPIO_PIN_7
+#define QSPI_BK1_IO2_GPIO_Port GPIOF
+#define QSPI_BK1_IO0_Pin GPIO_PIN_8
+#define QSPI_BK1_IO0_GPIO_Port GPIOF
+#define QSPI_BK1_IO1_Pin GPIO_PIN_9
+#define QSPI_BK1_IO1_GPIO_Port GPIOF
+#define STLK_MCO_Pin GPIO_PIN_0
+#define STLK_MCO_GPIO_Port GPIOH
+#define DFSDM_CKOUT_Pin GPIO_PIN_2
+#define DFSDM_CKOUT_GPIO_Port GPIOC
+#define JOY_SEL_Pin GPIO_PIN_0
+#define JOY_SEL_GPIO_Port GPIOA
+#define STLINK_RX_Pin GPIO_PIN_2
+#define STLINK_RX_GPIO_Port GPIOA
+#define STLINK_TX_Pin GPIO_PIN_3
+#define STLINK_TX_GPIO_Port GPIOA
+#define CODEC_I2S3_WS_Pin GPIO_PIN_4
+#define CODEC_I2S3_WS_GPIO_Port GPIOA
+#define DFSDM_DATIN0_Pin GPIO_PIN_1
+#define DFSDM_DATIN0_GPIO_Port GPIOB
+#define QSPI_CLK_Pin GPIO_PIN_2
+#define QSPI_CLK_GPIO_Port GPIOB
+#define EXT_RESET_Pin GPIO_PIN_11
+#define EXT_RESET_GPIO_Port GPIOF
+#define CTP_RST_Pin GPIO_PIN_12
+#define CTP_RST_GPIO_Port GPIOF
+#define JOY_RIGHT_Pin GPIO_PIN_14
+#define JOY_RIGHT_GPIO_Port GPIOF
+#define JOY_LEFT_Pin GPIO_PIN_15
+#define JOY_LEFT_GPIO_Port GPIOF
+#define JOY_UP_Pin GPIO_PIN_0
+#define JOY_UP_GPIO_Port GPIOG
+#define JOY_DOWN_Pin GPIO_PIN_1
+#define JOY_DOWN_GPIO_Port GPIOG
+#define D4_Pin GPIO_PIN_7
+#define D4_GPIO_Port GPIOE
+#define D5_Pin GPIO_PIN_8
+#define D5_GPIO_Port GPIOE
+#define D6_Pin GPIO_PIN_9
+#define D6_GPIO_Port GPIOE
+#define D7_Pin GPIO_PIN_10
+#define D7_GPIO_Port GPIOE
+#define D8_Pin GPIO_PIN_11
+#define D8_GPIO_Port GPIOE
+#define D9_Pin GPIO_PIN_12
+#define D9_GPIO_Port GPIOE
+#define D10_Pin GPIO_PIN_13
+#define D10_GPIO_Port GPIOE
+#define D11_Pin GPIO_PIN_14
+#define D11_GPIO_Port GPIOE
+#define D12_Pin GPIO_PIN_15
+#define D12_GPIO_Port GPIOE
+#define I2C2_SCL_Pin GPIO_PIN_10
+#define I2C2_SCL_GPIO_Port GPIOB
+#define M2_CKIN_Pin GPIO_PIN_11
+#define M2_CKIN_GPIO_Port GPIOB
+#define CODEC_I2S3_SCK_Pin GPIO_PIN_12
+#define CODEC_I2S3_SCK_GPIO_Port GPIOB
+#define D13_Pin GPIO_PIN_8
+#define D13_GPIO_Port GPIOD
+#define D14_Pin GPIO_PIN_9
+#define D14_GPIO_Port GPIOD
+#define D15_Pin GPIO_PIN_10
+#define D15_GPIO_Port GPIOD
+#define LCD_RESET_Pin GPIO_PIN_11
+#define LCD_RESET_GPIO_Port GPIOD
+#define D0_Pin GPIO_PIN_14
+#define D0_GPIO_Port GPIOD
+#define D1_Pin GPIO_PIN_15
+#define D1_GPIO_Port GPIOD
+#define CODEC_INT_Pin GPIO_PIN_2
+#define CODEC_INT_GPIO_Port GPIOG
+#define LCD_TE_Pin GPIO_PIN_4
+#define LCD_TE_GPIO_Port GPIOG
+#define CTP_INT_Pin GPIO_PIN_5
+#define CTP_INT_GPIO_Port GPIOG
+#define QSPI_BK1_NCS_Pin GPIO_PIN_6
+#define QSPI_BK1_NCS_GPIO_Port GPIOG
+#define USB_OTGFS_OVRCR_Pin GPIO_PIN_7
+#define USB_OTGFS_OVRCR_GPIO_Port GPIOG
+#define USB_OTGFS_PPWR_EN_Pin GPIO_PIN_8
+#define USB_OTGFS_PPWR_EN_GPIO_Port GPIOG
+#define CODEC_I2S3_MCK_Pin GPIO_PIN_7
+#define CODEC_I2S3_MCK_GPIO_Port GPIOC
+#define uSD_D0_Pin GPIO_PIN_8
+#define uSD_D0_GPIO_Port GPIOC
+#define uSD_D1_Pin GPIO_PIN_9
+#define uSD_D1_GPIO_Port GPIOC
+#define M2_CKINA8_Pin GPIO_PIN_8
+#define M2_CKINA8_GPIO_Port GPIOA
+#define USB_OTGFS_VBUS_Pin GPIO_PIN_9
+#define USB_OTGFS_VBUS_GPIO_Port GPIOA
+#define USB_OTGFS_ID_Pin GPIO_PIN_10
+#define USB_OTGFS_ID_GPIO_Port GPIOA
+#define USB_OTGFS_DM_Pin GPIO_PIN_11
+#define USB_OTGFS_DM_GPIO_Port GPIOA
+#define USB_OTGFS_DP_Pin GPIO_PIN_12
+#define USB_OTGFS_DP_GPIO_Port GPIOA
+#define SWDIO_Pin GPIO_PIN_13
+#define SWDIO_GPIO_Port GPIOA
+#define SWCLK_Pin GPIO_PIN_14
+#define SWCLK_GPIO_Port GPIOA
+#define uSD_D2_Pin GPIO_PIN_10
+#define uSD_D2_GPIO_Port GPIOC
+#define uSD_D3_Pin GPIO_PIN_11
+#define uSD_D3_GPIO_Port GPIOC
+#define uSD_CLK_Pin GPIO_PIN_12
+#define uSD_CLK_GPIO_Port GPIOC
+#define D2_Pin GPIO_PIN_0
+#define D2_GPIO_Port GPIOD
+#define D3_Pin GPIO_PIN_1
+#define D3_GPIO_Port GPIOD
+#define uSD_CMD_Pin GPIO_PIN_2
+#define uSD_CMD_GPIO_Port GPIOD
+#define uSD_DETECT_Pin GPIO_PIN_3
+#define uSD_DETECT_GPIO_Port GPIOD
+#define FMC_NOE_Pin GPIO_PIN_4
+#define FMC_NOE_GPIO_Port GPIOD
+#define FMC_NWE_Pin GPIO_PIN_5
+#define FMC_NWE_GPIO_Port GPIOD
+#define FMC_NE1_Pin GPIO_PIN_7
+#define FMC_NE1_GPIO_Port GPIOD
+#define SWO_Pin GPIO_PIN_3
+#define SWO_GPIO_Port GPIOB
+#define CODEC_I2S3ext_SD_Pin GPIO_PIN_4
+#define CODEC_I2S3ext_SD_GPIO_Port GPIOB
+#define CODEC_I2S3_SD_Pin GPIO_PIN_5
+#define CODEC_I2S3_SD_GPIO_Port GPIOB
+#define I2C1_SCL_Pin GPIO_PIN_6
+#define I2C1_SCL_GPIO_Port GPIOB
+#define I2C1_SDA_Pin GPIO_PIN_7
+#define I2C1_SDA_GPIO_Port GPIOB
+#define I2C2_SDA_Pin GPIO_PIN_9
+#define I2C2_SDA_GPIO_Port GPIOB
+#define LED1_Pin GPIO_PIN_0
+#define LED1_GPIO_Port GPIOE
+#define LED2_Pin GPIO_PIN_1
+#define LED2_GPIO_Port GPIOE
+*/
+
+#include "stm32f4xx_hal.h"
+
+void stm32f4_peripherals_gpio_init(void) {
+ //Enable all GPIO for now
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ __HAL_RCC_GPIOE_CLK_ENABLE();
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOF_CLK_ENABLE();
+ __HAL_RCC_GPIOH_CLK_ENABLE();
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOG_CLK_ENABLE();
+ __HAL_RCC_GPIOD_CLK_ENABLE();
+
+ HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_RESET);
+ //HAL_GPIO_WritePin(USB_OTGFS_PPWR_EN_GPIO_Port, USB_OTGFS_PPWR_EN_Pin, GPIO_PIN_SET);
+
+ //Configure LED pins
+ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+ //Status LED chain
+ HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0, GPIO_PIN_RESET); //LED 1
+ HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_SET); //LED 2
+ HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_SET); //LED 3
+ HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET); //LED 4
+
+ //TBD, USB power
+ // GPIO_InitStruct.Pin = USB_OTGFS_PPWR_EN_Pin;
+ // GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
+ // GPIO_InitStruct.Pull = GPIO_NOPULL;
+ // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ // HAL_GPIO_Init(USB_OTGFS_PPWR_EN_GPIO_Port, &GPIO_InitStruct);
+}
+
+
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.c b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.c
new file mode 100644
index 000000000..5a4703bea
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.c
@@ -0,0 +1,159 @@
+ /*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/obj.h"
+#include "py/mphal.h"
+#include "stm32f4/pins.h"
+
+const mcu_pin_obj_t pin_PE02 = PIN(4, GPIOE, 2);
+const mcu_pin_obj_t pin_PE03 = PIN(4, GPIOE, 3);
+const mcu_pin_obj_t pin_PE04 = PIN(4, GPIOE, 4);
+const mcu_pin_obj_t pin_PE05 = PIN(4, GPIOE, 5);
+const mcu_pin_obj_t pin_PE06 = PIN(4, GPIOE, 6);
+
+const mcu_pin_obj_t pin_PC13 = PIN(2, GPIOC, 13);
+
+const mcu_pin_obj_t pin_PF00 = PIN(5, GPIOF, 0); // 144 only
+const mcu_pin_obj_t pin_PF01 = PIN(5, GPIOF, 1); // 144 only
+const mcu_pin_obj_t pin_PF02 = PIN(5, GPIOF, 2); // 144 only
+const mcu_pin_obj_t pin_PF03 = PIN(5, GPIOF, 3); // 144 only
+const mcu_pin_obj_t pin_PF04 = PIN(5, GPIOF, 4); // 144 only
+const mcu_pin_obj_t pin_PF05 = PIN(5, GPIOF, 5); // 144 only
+const mcu_pin_obj_t pin_PF06 = PIN(5, GPIOF, 6); // 144 only
+const mcu_pin_obj_t pin_PF07 = PIN(5, GPIOF, 7); // 144 only
+const mcu_pin_obj_t pin_PF08 = PIN(5, GPIOF, 8); // 144 only
+const mcu_pin_obj_t pin_PF09 = PIN(5, GPIOF, 9); // 144 only
+const mcu_pin_obj_t pin_PF10 = PIN(5, GPIOF, 10); // 144 only
+
+const mcu_pin_obj_t pin_PC00 = PIN(2, GPIOC, 0);
+const mcu_pin_obj_t pin_PC01 = PIN(2, GPIOC, 1);
+const mcu_pin_obj_t pin_PC02 = PIN(2, GPIOC, 2);
+const mcu_pin_obj_t pin_PC03 = PIN(2, GPIOC, 3);
+
+const mcu_pin_obj_t pin_PA00 = PIN(0, GPIOA, 0);
+const mcu_pin_obj_t pin_PA01 = PIN(0, GPIOA, 1);
+const mcu_pin_obj_t pin_PA02 = PIN(0, GPIOA, 2);
+const mcu_pin_obj_t pin_PA03 = PIN(0, GPIOA, 3);
+const mcu_pin_obj_t pin_PA04 = PIN(0, GPIOA, 4);
+const mcu_pin_obj_t pin_PA05 = PIN(0, GPIOA, 5);
+const mcu_pin_obj_t pin_PA06 = PIN(0, GPIOA, 6);
+const mcu_pin_obj_t pin_PA07 = PIN(0, GPIOA, 7);
+
+const mcu_pin_obj_t pin_PC04 = PIN(2, GPIOC, 4);
+const mcu_pin_obj_t pin_PC05 = PIN(2, GPIOC, 5);
+
+const mcu_pin_obj_t pin_PB00 = PIN(1, GPIOB, 0);
+const mcu_pin_obj_t pin_PB01 = PIN(1, GPIOB, 1);
+const mcu_pin_obj_t pin_PB02 = PIN(1, GPIOB, 2);
+
+const mcu_pin_obj_t pin_PF11 = PIN(5, GPIOF, 11); // 144 only
+const mcu_pin_obj_t pin_PF12 = PIN(5, GPIOF, 12); // 144 only
+const mcu_pin_obj_t pin_PF13 = PIN(5, GPIOF, 13); // 144 only
+const mcu_pin_obj_t pin_PF14 = PIN(5, GPIOF, 14); // 144 only
+const mcu_pin_obj_t pin_PF15 = PIN(5, GPIOF, 15); // 144 only
+
+const mcu_pin_obj_t pin_PG00 = PIN(6, GPIOG, 0); // 144 only
+const mcu_pin_obj_t pin_PG01 = PIN(6, GPIOG, 1); // 144 only
+
+const mcu_pin_obj_t pin_PE07 = PIN(4, GPIOE, 7);
+const mcu_pin_obj_t pin_PE08 = PIN(4, GPIOE, 8);
+const mcu_pin_obj_t pin_PE09 = PIN(4, GPIOE, 9);
+const mcu_pin_obj_t pin_PE10 = PIN(4, GPIOE, 10);
+const mcu_pin_obj_t pin_PE11 = PIN(4, GPIOE, 11);
+const mcu_pin_obj_t pin_PE12 = PIN(4, GPIOE, 12);
+const mcu_pin_obj_t pin_PE13 = PIN(4, GPIOE, 13);
+const mcu_pin_obj_t pin_PE14 = PIN(4, GPIOE, 14);
+const mcu_pin_obj_t pin_PE15 = PIN(4, GPIOE, 15);
+
+const mcu_pin_obj_t pin_PB10 = PIN(1, GPIOB, 10);
+const mcu_pin_obj_t pin_PB12 = PIN(1, GPIOB, 12);
+const mcu_pin_obj_t pin_PB11 = PIN(1, GPIOB, 11); // 144 only
+const mcu_pin_obj_t pin_PB13 = PIN(1, GPIOB, 13);
+const mcu_pin_obj_t pin_PB14 = PIN(1, GPIOB, 14);
+const mcu_pin_obj_t pin_PB15 = PIN(1, GPIOB, 15);
+
+const mcu_pin_obj_t pin_PD08 = PIN(3, GPIOD, 8);
+const mcu_pin_obj_t pin_PD09 = PIN(3, GPIOD, 9);
+const mcu_pin_obj_t pin_PD10 = PIN(3, GPIOD, 10);
+const mcu_pin_obj_t pin_PD11 = PIN(3, GPIOD, 11);
+const mcu_pin_obj_t pin_PD12 = PIN(3, GPIOD, 12);
+const mcu_pin_obj_t pin_PD13 = PIN(3, GPIOD, 13);
+const mcu_pin_obj_t pin_PD14 = PIN(3, GPIOD, 14);
+const mcu_pin_obj_t pin_PD15 = PIN(3, GPIOD, 15);
+
+const mcu_pin_obj_t pin_PG02 = PIN(6, GPIOG, 2); // 144 only
+const mcu_pin_obj_t pin_PG03 = PIN(6, GPIOG, 3); // 144 only
+const mcu_pin_obj_t pin_PG04 = PIN(6, GPIOG, 4); // 144 only
+const mcu_pin_obj_t pin_PG05 = PIN(6, GPIOG, 5); // 144 only
+const mcu_pin_obj_t pin_PG06 = PIN(6, GPIOG, 6); // 144 only
+const mcu_pin_obj_t pin_PG07 = PIN(6, GPIOG, 7); // 144 only
+const mcu_pin_obj_t pin_PG08 = PIN(6, GPIOG, 8); // 144 only
+
+const mcu_pin_obj_t pin_PC06 = PIN(2, GPIOC, 6);
+const mcu_pin_obj_t pin_PC07 = PIN(2, GPIOC, 7);
+const mcu_pin_obj_t pin_PC08 = PIN(2, GPIOC, 8);
+const mcu_pin_obj_t pin_PC09 = PIN(2, GPIOC, 9);
+
+const mcu_pin_obj_t pin_PA08 = PIN(0, GPIOA, 8);
+const mcu_pin_obj_t pin_PA09 = PIN(0, GPIOA, 9);
+const mcu_pin_obj_t pin_PA10 = PIN(0, GPIOA, 10);
+const mcu_pin_obj_t pin_PA11 = PIN(0, GPIOA, 11);
+const mcu_pin_obj_t pin_PA12 = PIN(0, GPIOA, 12);
+const mcu_pin_obj_t pin_PA13 = PIN(0, GPIOA, 13);
+const mcu_pin_obj_t pin_PA14 = PIN(0, GPIOA, 14);
+const mcu_pin_obj_t pin_PA15 = PIN(0, GPIOA, 15);
+
+const mcu_pin_obj_t pin_PC10 = PIN(2, GPIOC, 10);
+const mcu_pin_obj_t pin_PC11 = PIN(2, GPIOC, 11);
+const mcu_pin_obj_t pin_PC12 = PIN(2, GPIOC, 12);
+
+const mcu_pin_obj_t pin_PD00 = PIN(3, GPIOD, 0);
+const mcu_pin_obj_t pin_PD01 = PIN(3, GPIOD, 1);
+const mcu_pin_obj_t pin_PD02 = PIN(3, GPIOD, 2);
+const mcu_pin_obj_t pin_PD03 = PIN(3, GPIOD, 3);
+const mcu_pin_obj_t pin_PD04 = PIN(3, GPIOD, 4);
+const mcu_pin_obj_t pin_PD05 = PIN(3, GPIOD, 5);
+const mcu_pin_obj_t pin_PD06 = PIN(3, GPIOD, 6);
+const mcu_pin_obj_t pin_PD07 = PIN(3, GPIOD, 7);
+
+const mcu_pin_obj_t pin_PG09 = PIN(6, GPIOG, 9); // 144 only
+const mcu_pin_obj_t pin_PG10 = PIN(6, GPIOG, 10); // 144 only
+const mcu_pin_obj_t pin_PG11 = PIN(6, GPIOG, 11); // 144 only
+const mcu_pin_obj_t pin_PG12 = PIN(6, GPIOG, 12); // 144 only
+const mcu_pin_obj_t pin_PG13 = PIN(6, GPIOG, 13); // 144 only
+const mcu_pin_obj_t pin_PG14 = PIN(6, GPIOG, 14); // 144 only
+const mcu_pin_obj_t pin_PG15 = PIN(6, GPIOG, 15); // 144 only
+
+const mcu_pin_obj_t pin_PB03 = PIN(1, GPIOB, 3);
+const mcu_pin_obj_t pin_PB04 = PIN(1, GPIOB, 4);
+const mcu_pin_obj_t pin_PB05 = PIN(1, GPIOB, 5);
+const mcu_pin_obj_t pin_PB06 = PIN(1, GPIOB, 6);
+const mcu_pin_obj_t pin_PB07 = PIN(1, GPIOB, 7);
+const mcu_pin_obj_t pin_PB08 = PIN(1, GPIOB, 8);
+const mcu_pin_obj_t pin_PB09 = PIN(1, GPIOB, 9);
+
+const mcu_pin_obj_t pin_PE00 = PIN(4, GPIOE, 0);
+const mcu_pin_obj_t pin_PE01 = PIN(4, GPIOE, 1); \ No newline at end of file
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.h b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.h
new file mode 100644
index 000000000..a74bf7c5d
--- /dev/null
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.h
@@ -0,0 +1,156 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F412ZG_PINS_H
+#define MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F412ZG_PINS_H
+
+//Pins in datasheet order: DocID028087 Rev 7 page 50. LQFP100 only
+//pg 50
+extern const mcu_pin_obj_t pin_PE02;
+extern const mcu_pin_obj_t pin_PE03;
+extern const mcu_pin_obj_t pin_PE04;
+extern const mcu_pin_obj_t pin_PE05;
+extern const mcu_pin_obj_t pin_PE06;
+extern const mcu_pin_obj_t pin_PC13;
+//pg 51
+extern const mcu_pin_obj_t pin_PF00; // 144 only
+extern const mcu_pin_obj_t pin_PF01; // 144 only
+extern const mcu_pin_obj_t pin_PF02; // 144 only
+extern const mcu_pin_obj_t pin_PF03; // 144 only
+extern const mcu_pin_obj_t pin_PF04; // 144 only
+extern const mcu_pin_obj_t pin_PF05; // 144 only
+extern const mcu_pin_obj_t pin_PF06; // 144 only
+extern const mcu_pin_obj_t pin_PF07; // 144 only
+extern const mcu_pin_obj_t pin_PF08; // 144 only
+extern const mcu_pin_obj_t pin_PF09; // 144 only
+extern const mcu_pin_obj_t pin_PF10; // 144 only
+//pg 52
+extern const mcu_pin_obj_t pin_PC00;
+extern const mcu_pin_obj_t pin_PC01;
+extern const mcu_pin_obj_t pin_PC02;
+extern const mcu_pin_obj_t pin_PC03;
+extern const mcu_pin_obj_t pin_PA00;
+extern const mcu_pin_obj_t pin_PA01;
+extern const mcu_pin_obj_t pin_PA02;
+//pg 53
+extern const mcu_pin_obj_t pin_PA03;
+extern const mcu_pin_obj_t pin_PA04;
+extern const mcu_pin_obj_t pin_PA05;
+extern const mcu_pin_obj_t pin_PA06;
+extern const mcu_pin_obj_t pin_PA07;
+extern const mcu_pin_obj_t pin_PC04;
+//pg 54
+extern const mcu_pin_obj_t pin_PC05;
+extern const mcu_pin_obj_t pin_PB00;
+extern const mcu_pin_obj_t pin_PB01;
+extern const mcu_pin_obj_t pin_PB02;
+extern const mcu_pin_obj_t pin_PF11; // 144 only
+extern const mcu_pin_obj_t pin_PF12; // 144 only
+extern const mcu_pin_obj_t pin_PF13; // 144 only
+extern const mcu_pin_obj_t pin_PF14; // 144 only
+extern const mcu_pin_obj_t pin_PF15; // 144 only
+extern const mcu_pin_obj_t pin_PG00; // 144 only
+extern const mcu_pin_obj_t pin_PG01; // 144 only
+//pg 55
+extern const mcu_pin_obj_t pin_PE07;
+extern const mcu_pin_obj_t pin_PE08;
+extern const mcu_pin_obj_t pin_PE09;
+extern const mcu_pin_obj_t pin_PE10;
+extern const mcu_pin_obj_t pin_PE11;
+extern const mcu_pin_obj_t pin_PE12;
+extern const mcu_pin_obj_t pin_PE13;
+extern const mcu_pin_obj_t pin_PE14;
+//pg 56
+extern const mcu_pin_obj_t pin_PE15;
+extern const mcu_pin_obj_t pin_PB10;
+extern const mcu_pin_obj_t pin_PB11; // 144 only
+extern const mcu_pin_obj_t pin_PB12;
+extern const mcu_pin_obj_t pin_PB13;
+//pg 57
+extern const mcu_pin_obj_t pin_PB14;
+extern const mcu_pin_obj_t pin_PB15;
+extern const mcu_pin_obj_t pin_PD08;
+extern const mcu_pin_obj_t pin_PD09;
+extern const mcu_pin_obj_t pin_PD10;
+extern const mcu_pin_obj_t pin_PD11;
+extern const mcu_pin_obj_t pin_PD12;
+//pg 58
+extern const mcu_pin_obj_t pin_PD13;
+extern const mcu_pin_obj_t pin_PD14;
+extern const mcu_pin_obj_t pin_PD15;
+extern const mcu_pin_obj_t pin_PG02; // 144 only
+extern const mcu_pin_obj_t pin_PG03; // 144 only
+extern const mcu_pin_obj_t pin_PG04; // 144 only
+extern const mcu_pin_obj_t pin_PG05; // 144 only
+extern const mcu_pin_obj_t pin_PG06; // 144 only
+extern const mcu_pin_obj_t pin_PG07; // 144 only
+extern const mcu_pin_obj_t pin_PG08; // 144 only
+//pg 59
+extern const mcu_pin_obj_t pin_PC06;
+extern const mcu_pin_obj_t pin_PC07;
+extern const mcu_pin_obj_t pin_PC08;
+extern const mcu_pin_obj_t pin_PC09;
+extern const mcu_pin_obj_t pin_PA08;
+extern const mcu_pin_obj_t pin_PA09;
+extern const mcu_pin_obj_t pin_PA10;
+//pg 60
+extern const mcu_pin_obj_t pin_PA11;
+extern const mcu_pin_obj_t pin_PA12;
+extern const mcu_pin_obj_t pin_PA13;
+extern const mcu_pin_obj_t pin_PA14;
+extern const mcu_pin_obj_t pin_PA15;
+extern const mcu_pin_obj_t pin_PC10;
+extern const mcu_pin_obj_t pin_PC11;
+//pg 61
+extern const mcu_pin_obj_t pin_PC12;
+extern const mcu_pin_obj_t pin_PD00;
+extern const mcu_pin_obj_t pin_PD01;
+extern const mcu_pin_obj_t pin_PD02;
+extern const mcu_pin_obj_t pin_PD03;
+extern const mcu_pin_obj_t pin_PD04;
+extern const mcu_pin_obj_t pin_PD05;
+extern const mcu_pin_obj_t pin_PD06;
+extern const mcu_pin_obj_t pin_PD07;
+//pg 62
+extern const mcu_pin_obj_t pin_PG09; // 144 only
+extern const mcu_pin_obj_t pin_PG10; // 144 only
+extern const mcu_pin_obj_t pin_PG11; // 144 only
+extern const mcu_pin_obj_t pin_PG12; // 144 only
+extern const mcu_pin_obj_t pin_PG13; // 144 only
+extern const mcu_pin_obj_t pin_PG14; // 144 only
+extern const mcu_pin_obj_t pin_PG15; // 144 only
+extern const mcu_pin_obj_t pin_PB03;
+extern const mcu_pin_obj_t pin_PB04;
+//pg 63
+extern const mcu_pin_obj_t pin_PB05;
+extern const mcu_pin_obj_t pin_PB06;
+extern const mcu_pin_obj_t pin_PB07;
+extern const mcu_pin_obj_t pin_PB08;
+extern const mcu_pin_obj_t pin_PB09;
+extern const mcu_pin_obj_t pin_PE00;
+extern const mcu_pin_obj_t pin_PE01;
+
+#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F412ZG_PINS_H
diff --git a/ports/stm32f4/qstrdefsport.h b/ports/stm32f4/qstrdefsport.h
new file mode 100644
index 000000000..3ba897069
--- /dev/null
+++ b/ports/stm32f4/qstrdefsport.h
@@ -0,0 +1 @@
+// qstrs specific to this port
diff --git a/ports/stm32f4/stm32f4 b/ports/stm32f4/stm32f4
new file mode 160000
+Subproject 12411ade32aeec4e49c969d8d095463b0c2fb1f
diff --git a/ports/stm32f4/supervisor/cpu.s b/ports/stm32f4/supervisor/cpu.s
new file mode 100755
index 000000000..9e6807a5e
--- /dev/null
+++ b/ports/stm32f4/supervisor/cpu.s
@@ -0,0 +1,27 @@
+.syntax unified
+.cpu cortex-m4
+.thumb
+.text
+.align 2
+
+@ uint cpu_get_regs_and_sp(r0=uint regs[10])
+.global cpu_get_regs_and_sp
+.thumb
+.thumb_func
+.type cpu_get_regs_and_sp, %function
+cpu_get_regs_and_sp:
+@ store registers into given array
+str r4, [r0], #4
+str r5, [r0], #4
+str r6, [r0], #4
+str r7, [r0], #4
+str r8, [r0], #4
+str r9, [r0], #4
+str r10, [r0], #4
+str r11, [r0], #4
+str r12, [r0], #4
+str r13, [r0], #4
+
+@ return the sp
+mov r0, sp
+bx lr
diff --git a/ports/stm32f4/supervisor/internal_flash.c b/ports/stm32f4/supervisor/internal_flash.c
new file mode 100644
index 000000000..fa776ae1d
--- /dev/null
+++ b/ports/stm32f4/supervisor/internal_flash.c
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013, 2014 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "supervisor/flash.h"
+
+#include <stdint.h>
+#include <string.h>
+
+#include "extmod/vfs.h"
+#include "extmod/vfs_fat.h"
+#include "py/mphal.h"
+#include "py/obj.h"
+#include "py/runtime.h"
+#include "lib/oofatfs/ff.h"
+
+
+/*------------------------------------------------------------------*/
+/* Internal Flash API
+ *------------------------------------------------------------------*/
+static inline uint32_t lba2addr(uint32_t block) {
+}
+
+void supervisor_flash_init(void) {
+}
+
+uint32_t supervisor_flash_get_block_size(void) {
+ return FILESYSTEM_BLOCK_SIZE;
+}
+
+uint32_t supervisor_flash_get_block_count(void) {
+ return false;
+}
+
+void supervisor_flash_flush(void) {
+
+}
+
+mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
+
+ return 0; // success
+}
+
+mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) {
+
+
+ return 0; // success
+}
+
+void supervisor_flash_release_cache(void) {
+}
+
diff --git a/ports/stm32f4/supervisor/internal_flash.h b/ports/stm32f4/supervisor/internal_flash.h
new file mode 100644
index 000000000..8c015a3e4
--- /dev/null
+++ b/ports/stm32f4/supervisor/internal_flash.h
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013, 2014 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef MICROPY_INCLUDED_STM32F4_INTERNAL_FLASH_H
+#define MICROPY_INCLUDED_STM32F4_INTERNAL_FLASH_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "py/mpconfig.h"
+
+#define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms
+#define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2)
+
+#endif // MICROPY_INCLUDED_STM32F4_INTERNAL_FLASH_H
diff --git a/ports/stm32f4/supervisor/internal_flash_root_pointers.h b/ports/stm32f4/supervisor/internal_flash_root_pointers.h
new file mode 100644
index 000000000..7a8681bd9
--- /dev/null
+++ b/ports/stm32f4/supervisor/internal_flash_root_pointers.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef MICROPY_INCLUDED_STM32F4_INTERNAL_FLASH_ROOT_POINTERS_H
+#define MICROPY_INCLUDED_STM32F4_INTERNAL_FLASH_ROOT_POINTERS_H
+
+#define FLASH_ROOT_POINTERS
+
+#endif // MICROPY_INCLUDED_STM32F4_INTERNAL_FLASH_ROOT_POINTERS_H
diff --git a/ports/stm32f4/supervisor/port.c b/ports/stm32f4/supervisor/port.c
new file mode 100644
index 000000000..af4d1b8d8
--- /dev/null
+++ b/ports/stm32f4/supervisor/port.c
@@ -0,0 +1,80 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdint.h>
+#include "supervisor/port.h"
+#include "boards/board.h"
+#include "tick.h"
+
+#include "stm32f4/clocks.h"
+#include "stm32f4/gpio.h"
+
+#include "stm32f4xx_hal.h"
+
+//#include "shared-bindings/rtc/__init__.h"
+
+static void power_warning_handler(void) {
+ reset_into_safe_mode(BROWNOUT);
+}
+
+safe_mode_t port_init(void) {
+ HAL_Init();
+
+ stm32f4_peripherals_clocks_init();
+ stm32f4_peripherals_gpio_init();
+
+ tick_init();
+ board_init();
+
+ return NO_SAFE_MODE;
+}
+
+void reset_port(void) {
+
+}
+
+void reset_to_bootloader(void) {
+
+}
+
+void reset_cpu(void) {
+
+}
+
+extern uint32_t _ebss;
+// Place the word to save just after our BSS section that gets blanked.
+void port_set_saved_word(uint32_t value) {
+ _ebss = value;
+}
+
+uint32_t port_get_saved_word(void) {
+ return _ebss;
+}
+
+// void HardFault_Handler(void) {
+
+// }
diff --git a/ports/stm32f4/supervisor/qspi_flash.c b/ports/stm32f4/supervisor/qspi_flash.c
new file mode 100644
index 000000000..f3915273b
--- /dev/null
+++ b/ports/stm32f4/supervisor/qspi_flash.c
@@ -0,0 +1,162 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 hathach for Adafruit Industries
+ * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "supervisor/spi_flash_api.h"
+
+#include <stdint.h>
+#include <string.h>
+
+#include "py/mpconfig.h" // for EXTERNAL_FLASH_QSPI_DUAL
+//#include "nrfx_qspi.h"
+
+//#include "shared-bindings/microcontroller/__init__.h"
+
+#include "supervisor/shared/external_flash/common_commands.h"
+#include "supervisor/shared/external_flash/qspi_flash.h"
+
+bool spi_flash_command(uint8_t command) {
+ // nrf_qspi_cinstr_conf_t cinstr_cfg = {
+ // .opcode = command,
+ // .length = 1,
+ // .io2_level = true,
+ // .io3_level = true,
+ // .wipwait = false,
+ // .wren = false
+ // };
+ return false; //nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL) == NRFX_SUCCESS;
+}
+
+bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length) {
+ // nrf_qspi_cinstr_conf_t cinstr_cfg = {
+ // .opcode = command,
+ // .length = length + 1,
+ // .io2_level = true,
+ // .io3_level = true,
+ // .wipwait = false,
+ // .wren = false
+ // };
+ // return nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, response) == NRFX_SUCCESS;
+ return false;
+
+}
+
+bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) {
+ // nrf_qspi_cinstr_conf_t cinstr_cfg = {
+ // .opcode = command,
+ // .length = length + 1,
+ // .io2_level = true,
+ // .io3_level = true,
+ // .wipwait = false,
+ // .wren = false // We do this manually.
+ // };
+ // return nrfx_qspi_cinstr_xfer(&cinstr_cfg, data, NULL) == NRFX_SUCCESS;
+ return false;
+}
+
+bool spi_flash_sector_command(uint8_t command, uint32_t address) {
+ // if (command != CMD_SECTOR_ERASE) {
+ // return false;
+ // }
+ // return nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, address) == NRFX_SUCCESS;
+ return false;
+}
+
+bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) {
+ // return nrfx_qspi_write(data, length, address) == NRFX_SUCCESS;
+ return false;
+}
+
+bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) {
+ // return nrfx_qspi_read(data, length, address) == NRFX_SUCCESS;
+ return false;
+}
+
+void spi_flash_init(void) {
+ // Init QSPI flash
+// nrfx_qspi_config_t qspi_cfg = {
+// .xip_offset = 0,
+// .pins = {
+// .sck_pin = MICROPY_QSPI_SCK,
+// .csn_pin = MICROPY_QSPI_CS,
+// .io0_pin = MICROPY_QSPI_DATA0,
+// .io1_pin = NRF_QSPI_PIN_NOT_CONNECTED,
+// .io2_pin = NRF_QSPI_PIN_NOT_CONNECTED,
+// .io3_pin = NRF_QSPI_PIN_NOT_CONNECTED,
+
+// },
+// .prot_if = {
+// .readoc = NRF_QSPI_READOC_FASTREAD,
+// .writeoc = NRF_QSPI_WRITEOC_PP,
+// .addrmode = NRF_QSPI_ADDRMODE_24BIT,
+// .dpmconfig = false
+// },
+// .phy_if = {
+// .sck_freq = NRF_QSPI_FREQ_32MDIV16, // Start at a slow 2MHz and speed up once we know what we're talking to.
+// .sck_delay = 10, // min time CS must stay high before going low again. in unit of 62.5 ns
+// .spi_mode = NRF_QSPI_MODE_0,
+// .dpmen = false
+// },
+// .irq_priority = 7,
+// };
+
+// #if EXTERNAL_FLASH_QSPI_DUAL
+// qspi_cfg.pins.io1_pin = MICROPY_QSPI_DATA1;
+// qspi_cfg.prot_if.readoc = NRF_QSPI_READOC_READ2O;
+// qspi_cfg.prot_if.writeoc = NRF_QSPI_WRITEOC_PP2O;
+// #else
+// qspi_cfg.pins.io1_pin = MICROPY_QSPI_DATA1;
+// qspi_cfg.pins.io2_pin = MICROPY_QSPI_DATA2;
+// qspi_cfg.pins.io3_pin = MICROPY_QSPI_DATA3;
+// qspi_cfg.prot_if.readoc = NRF_QSPI_READOC_READ4IO;
+// qspi_cfg.prot_if.writeoc = NRF_QSPI_WRITEOC_PP4O;
+// #endif
+
+// // No callback for blocking API
+// nrfx_qspi_init(&qspi_cfg, NULL, NULL);
+}
+
+void spi_flash_init_device(const external_flash_device* device) {
+ // check_quad_enable(device);
+
+ // // Switch to single output line if the device doesn't support quad programs.
+ // if (!device->supports_qspi_writes) {
+ // NRF_QSPI->IFCONFIG0 &= ~QSPI_IFCONFIG0_WRITEOC_Msk;
+ // NRF_QSPI->IFCONFIG0 |= QSPI_IFCONFIG0_WRITEOC_PP << QSPI_IFCONFIG0_WRITEOC_Pos;
+ // }
+
+ // // Speed up as much as we can.
+ // // Start at 16 MHz and go down.
+ // // At 32 MHz GD25Q16C doesn't work reliably on Feather 52840, even though it should work up to 104 MHz.
+ // // sckfreq = 0 is 32 Mhz
+ // // sckfreq = 1 is 16 MHz, etc.
+ // uint8_t sckfreq = 1;
+ // while (32000000 / (sckfreq + 1) > device->max_clock_speed_mhz * 1000000 && sckfreq < 16) {
+ // sckfreq += 1;
+ // }
+ // NRF_QSPI->IFCONFIG1 &= ~QSPI_IFCONFIG1_SCKFREQ_Msk;
+ // NRF_QSPI->IFCONFIG1 |= sckfreq << QSPI_IFCONFIG1_SCKFREQ_Pos;
+}
diff --git a/ports/stm32f4/supervisor/serial.c b/ports/stm32f4/supervisor/serial.c
new file mode 100644
index 000000000..3154dc3e5
--- /dev/null
+++ b/ports/stm32f4/supervisor/serial.c
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/mphal.h"
+#include <string.h>
+#include "supervisor/serial.h"
+#include "stm32f4xx_hal.h"
+
+UART_HandleTypeDef huart2;
+
+void serial_init(void) {
+ huart2.Instance = USART2;
+ huart2.Init.BaudRate = 9600;
+ huart2.Init.WordLength = UART_WORDLENGTH_8B;
+ huart2.Init.StopBits = UART_STOPBITS_1;
+ huart2.Init.Parity = UART_PARITY_NONE;
+ huart2.Init.Mode = UART_MODE_TX_RX;
+ huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+ huart2.Init.OverSampling = UART_OVERSAMPLING_16;
+ if (HAL_UART_Init(&huart2) == HAL_OK)
+ {
+ //HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET);
+ }
+ //HAL_UART_Transmit(&huart2, (uint8_t*)"Serial On", 9, 5000);
+ //HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET);
+}
+
+bool serial_connected(void) {
+ return true;
+}
+
+char serial_read(void) {
+ uint8_t data;
+ HAL_UART_Receive(&huart2, &data, 1,5000);
+ return data;
+}
+
+bool serial_bytes_available(void) {
+ return __HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE);
+}
+
+void serial_write(const char* text) {
+ serial_write_substring(text, strlen(text));
+}
+
+void serial_write_substring(const char *text, uint32_t len) {
+ if (len == 0) {
+ return;
+ }
+ HAL_UART_Transmit(&huart2, (uint8_t*)text, len, 5000);
+}
+
diff --git a/ports/stm32f4/supervisor/usb.c b/ports/stm32f4/supervisor/usb.c
new file mode 100644
index 000000000..913523523
--- /dev/null
+++ b/ports/stm32f4/supervisor/usb.c
@@ -0,0 +1,80 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 hathach for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+#include "tick.h"
+#include "supervisor/usb.h"
+#include "lib/utils/interrupt_char.h"
+#include "lib/mp-readline/readline.h"
+#include "stm32f4xx_hal.h"
+
+#define USB_OTGFS_VBUS_Pin GPIO_PIN_9
+#define USB_OTGFS_VBUS_GPIO_Port GPIOA
+#define USB_OTGFS_ID_Pin GPIO_PIN_10
+#define USB_OTGFS_ID_GPIO_Port GPIOA
+#define USB_OTGFS_DM_Pin GPIO_PIN_11
+#define USB_OTGFS_DM_GPIO_Port GPIOA
+#define USB_OTGFS_DP_Pin GPIO_PIN_12
+#define USB_OTGFS_DP_GPIO_Port GPIOA
+
+
+void init_usb_hardware(void) {
+ // HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET); //LED 2
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ /**USB_OTG_FS GPIO Configuration
+ PA10 ------> USB_OTG_FS_ID
+ PA11 ------> USB_OTG_FS_DM
+ PA12 ------> USB_OTG_FS_DP
+ */
+ GPIO_InitStruct.Pin = USB_OTGFS_VBUS_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ HAL_GPIO_Init(USB_OTGFS_VBUS_GPIO_Port, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = USB_OTGFS_DM_Pin|USB_OTGFS_DP_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ //TinyUSB suggestion
+ GPIO_InitStruct.Pin = USB_OTGFS_ID_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /* Peripheral clock enable */
+ __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
+
+ /* Peripheral interrupt init */
+ HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0);
+ HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
+
+ //HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET); //LED 3
+}
diff --git a/ports/stm32f4/system_stm32f4xx.c b/ports/stm32f4/system_stm32f4xx.c
new file mode 100644
index 000000000..3303f969d
--- /dev/null
+++ b/ports/stm32f4/system_stm32f4xx.c
@@ -0,0 +1,761 @@
+/**
+ ******************************************************************************
+ * @file system_stm32f4xx.c
+ * @author MCD Application Team
+ * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
+ *
+ * This file provides two functions and one global variable to be called from
+ * user application:
+ * - SystemInit(): This function is called at startup just after reset and
+ * before branch to main program. This call is made inside
+ * the "startup_stm32f4xx.s" file.
+ *
+ * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+ * by the user application to setup the SysTick
+ * timer or configure other parameters.
+ *
+ * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+ * be called whenever the core clock is changed
+ * during program execution.
+ *
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2017 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup stm32f4xx_system
+ * @{
+ */
+
+/** @addtogroup STM32F4xx_System_Private_Includes
+ * @{
+ */
+
+
+#include "stm32f4xx.h"
+
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_Defines
+ * @{
+ */
+
+/************************* Miscellaneous Configuration ************************/
+/*!< Uncomment the following line if you need to use external SRAM or SDRAM as data memory */
+#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\
+ || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
+ || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
+/* #define DATA_IN_ExtSRAM */
+#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || STM32F469xx || STM32F479xx ||\
+ STM32F412Zx || STM32F412Vx */
+
+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
+ || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
+/* #define DATA_IN_ExtSDRAM */
+#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx ||\
+ STM32F479xx */
+
+/*!< Uncomment the following line if you need to relocate your vector Table in
+ Internal SRAM. */
+/* #define VECT_TAB_SRAM */
+#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
+ This value must be a multiple of 0x200. */
+/******************************************************************************/
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_Variables
+ * @{
+ */
+ /* This variable is updated in three ways:
+ 1) by calling CMSIS function SystemCoreClockUpdate()
+ 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
+ 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
+ Note: If you use this function to configure the system clock; then there
+ is no need to call the 2 first functions listed above, since SystemCoreClock
+ variable is updated automatically.
+ */
+uint32_t SystemCoreClock = 16000000;
+const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes
+ * @{
+ */
+
+#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
+ static void SystemInit_ExtMemCtl(void);
+#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Setup the microcontroller system
+ * Initialize the FPU setting, vector table location and External memory
+ * configuration.
+ * @param None
+ * @retval None
+ */
+void SystemInit(void)
+{
+ /* FPU settings ------------------------------------------------------------*/
+ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+ SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
+ #endif
+ /* Reset the RCC clock configuration to the default reset state ------------*/
+ /* Set HSION bit */
+ RCC->CR |= (uint32_t)0x00000001;
+
+ /* Reset CFGR register */
+ RCC->CFGR = 0x00000000;
+
+ /* Reset HSEON, CSSON and PLLON bits */
+ RCC->CR &= (uint32_t)0xFEF6FFFF;
+
+ /* Reset PLLCFGR register */
+ RCC->PLLCFGR = 0x24003010;
+
+ /* Reset HSEBYP bit */
+ RCC->CR &= (uint32_t)0xFFFBFFFF;
+
+ /* Disable all interrupts */
+ RCC->CIR = 0x00000000;
+
+#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
+ SystemInit_ExtMemCtl();
+#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
+
+ /* Configure the Vector Table location add offset address ------------------*/
+#ifdef VECT_TAB_SRAM
+ SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
+#else
+ SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
+#endif
+}
+
+/**
+ * @brief Update SystemCoreClock variable according to Clock Register Values.
+ * The SystemCoreClock variable contains the core clock (HCLK), it can
+ * be used by the user application to setup the SysTick timer or configure
+ * other parameters.
+ *
+ * @note Each time the core clock (HCLK) changes, this function must be called
+ * to update SystemCoreClock variable value. Otherwise, any configuration
+ * based on this variable will be incorrect.
+ *
+ * @note - The system frequency computed by this function is not the real
+ * frequency in the chip. It is calculated based on the predefined
+ * constant and the selected clock source:
+ *
+ * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
+ *
+ * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
+ *
+ * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
+ * or HSI_VALUE(*) multiplied/divided by the PLL factors.
+ *
+ * (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
+ * 16 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ *
+ * (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (its value
+ * depends on the application requirements), user has to ensure that HSE_VALUE
+ * is same as the real frequency of the crystal used. Otherwise, this function
+ * may have wrong result.
+ *
+ * - The result of this function could be not correct when using fractional
+ * value for HSE crystal.
+ *
+ * @param None
+ * @retval None
+ */
+void SystemCoreClockUpdate(void)
+{
+ uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ tmp = RCC->CFGR & RCC_CFGR_SWS;
+
+ switch (tmp)
+ {
+ case 0x00: /* HSI used as system clock source */
+ SystemCoreClock = HSI_VALUE;
+ break;
+ case 0x04: /* HSE used as system clock source */
+ SystemCoreClock = HSE_VALUE;
+ break;
+ case 0x08: /* PLL used as system clock source */
+
+ /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
+ SYSCLK = PLL_VCO / PLL_P
+ */
+ pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
+ pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
+
+ if (pllsource != 0)
+ {
+ /* HSE used as PLL clock source */
+ pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
+ }
+ else
+ {
+ /* HSI used as PLL clock source */
+ pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
+ }
+
+ pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
+ SystemCoreClock = pllvco/pllp;
+ break;
+ default:
+ SystemCoreClock = HSI_VALUE;
+ break;
+ }
+ /* Compute HCLK frequency --------------------------------------------------*/
+ /* Get HCLK prescaler */
+ tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
+ /* HCLK frequency */
+ SystemCoreClock >>= tmp;
+}
+
+#if defined (DATA_IN_ExtSRAM) && defined (DATA_IN_ExtSDRAM)
+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
+ || defined(STM32F469xx) || defined(STM32F479xx)
+/**
+ * @brief Setup the external memory controller.
+ * Called in startup_stm32f4xx.s before jump to main.
+ * This function configures the external memories (SRAM/SDRAM)
+ * This SRAM/SDRAM will be used as program data memory (including heap and stack).
+ * @param None
+ * @retval None
+ */
+void SystemInit_ExtMemCtl(void)
+{
+ __IO uint32_t tmp = 0x00;
+
+ register uint32_t tmpreg = 0, timeout = 0xFFFF;
+ register __IO uint32_t index;
+
+ /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */
+ RCC->AHB1ENR |= 0x000001F8;
+
+ /* Delay after an RCC peripheral clock enabling */
+ tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
+
+ /* Connect PDx pins to FMC Alternate function */
+ GPIOD->AFR[0] = 0x00CCC0CC;
+ GPIOD->AFR[1] = 0xCCCCCCCC;
+ /* Configure PDx pins in Alternate function mode */
+ GPIOD->MODER = 0xAAAA0A8A;
+ /* Configure PDx pins speed to 100 MHz */
+ GPIOD->OSPEEDR = 0xFFFF0FCF;
+ /* Configure PDx pins Output type to push-pull */
+ GPIOD->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PDx pins */
+ GPIOD->PUPDR = 0x00000000;
+
+ /* Connect PEx pins to FMC Alternate function */
+ GPIOE->AFR[0] = 0xC00CC0CC;
+ GPIOE->AFR[1] = 0xCCCCCCCC;
+ /* Configure PEx pins in Alternate function mode */
+ GPIOE->MODER = 0xAAAA828A;
+ /* Configure PEx pins speed to 100 MHz */
+ GPIOE->OSPEEDR = 0xFFFFC3CF;
+ /* Configure PEx pins Output type to push-pull */
+ GPIOE->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PEx pins */
+ GPIOE->PUPDR = 0x00000000;
+
+ /* Connect PFx pins to FMC Alternate function */
+ GPIOF->AFR[0] = 0xCCCCCCCC;
+ GPIOF->AFR[1] = 0xCCCCCCCC;
+ /* Configure PFx pins in Alternate function mode */
+ GPIOF->MODER = 0xAA800AAA;
+ /* Configure PFx pins speed to 50 MHz */
+ GPIOF->OSPEEDR = 0xAA800AAA;
+ /* Configure PFx pins Output type to push-pull */
+ GPIOF->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PFx pins */
+ GPIOF->PUPDR = 0x00000000;
+
+ /* Connect PGx pins to FMC Alternate function */
+ GPIOG->AFR[0] = 0xCCCCCCCC;
+ GPIOG->AFR[1] = 0xCCCCCCCC;
+ /* Configure PGx pins in Alternate function mode */
+ GPIOG->MODER = 0xAAAAAAAA;
+ /* Configure PGx pins speed to 50 MHz */
+ GPIOG->OSPEEDR = 0xAAAAAAAA;
+ /* Configure PGx pins Output type to push-pull */
+ GPIOG->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PGx pins */
+ GPIOG->PUPDR = 0x00000000;
+
+ /* Connect PHx pins to FMC Alternate function */
+ GPIOH->AFR[0] = 0x00C0CC00;
+ GPIOH->AFR[1] = 0xCCCCCCCC;
+ /* Configure PHx pins in Alternate function mode */
+ GPIOH->MODER = 0xAAAA08A0;
+ /* Configure PHx pins speed to 50 MHz */
+ GPIOH->OSPEEDR = 0xAAAA08A0;
+ /* Configure PHx pins Output type to push-pull */
+ GPIOH->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PHx pins */
+ GPIOH->PUPDR = 0x00000000;
+
+ /* Connect PIx pins to FMC Alternate function */
+ GPIOI->AFR[0] = 0xCCCCCCCC;
+ GPIOI->AFR[1] = 0x00000CC0;
+ /* Configure PIx pins in Alternate function mode */
+ GPIOI->MODER = 0x0028AAAA;
+ /* Configure PIx pins speed to 50 MHz */
+ GPIOI->OSPEEDR = 0x0028AAAA;
+ /* Configure PIx pins Output type to push-pull */
+ GPIOI->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PIx pins */
+ GPIOI->PUPDR = 0x00000000;
+
+/*-- FMC Configuration -------------------------------------------------------*/
+ /* Enable the FMC interface clock */
+ RCC->AHB3ENR |= 0x00000001;
+ /* Delay after an RCC peripheral clock enabling */
+ tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
+
+ FMC_Bank5_6->SDCR[0] = 0x000019E4;
+ FMC_Bank5_6->SDTR[0] = 0x01115351;
+
+ /* SDRAM initialization sequence */
+ /* Clock enable command */
+ FMC_Bank5_6->SDCMR = 0x00000011;
+ tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
+ while((tmpreg != 0) && (timeout-- > 0))
+ {
+ tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
+ }
+
+ /* Delay */
+ for (index = 0; index<1000; index++);
+
+ /* PALL command */
+ FMC_Bank5_6->SDCMR = 0x00000012;
+ timeout = 0xFFFF;
+ while((tmpreg != 0) && (timeout-- > 0))
+ {
+ tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
+ }
+
+ /* Auto refresh command */
+ FMC_Bank5_6->SDCMR = 0x00000073;
+ timeout = 0xFFFF;
+ while((tmpreg != 0) && (timeout-- > 0))
+ {
+ tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
+ }
+
+ /* MRD register program */
+ FMC_Bank5_6->SDCMR = 0x00046014;
+ timeout = 0xFFFF;
+ while((tmpreg != 0) && (timeout-- > 0))
+ {
+ tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
+ }
+
+ /* Set refresh count */
+ tmpreg = FMC_Bank5_6->SDRTR;
+ FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
+
+ /* Disable write protection */
+ tmpreg = FMC_Bank5_6->SDCR[0];
+ FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
+
+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
+ /* Configure and enable Bank1_SRAM2 */
+ FMC_Bank1->BTCR[2] = 0x00001011;
+ FMC_Bank1->BTCR[3] = 0x00000201;
+ FMC_Bank1E->BWTR[2] = 0x0fffffff;
+#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
+#if defined(STM32F469xx) || defined(STM32F479xx)
+ /* Configure and enable Bank1_SRAM2 */
+ FMC_Bank1->BTCR[2] = 0x00001091;
+ FMC_Bank1->BTCR[3] = 0x00110212;
+ FMC_Bank1E->BWTR[2] = 0x0fffffff;
+#endif /* STM32F469xx || STM32F479xx */
+
+ (void)(tmp);
+}
+#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
+#elif defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
+/**
+ * @brief Setup the external memory controller.
+ * Called in startup_stm32f4xx.s before jump to main.
+ * This function configures the external memories (SRAM/SDRAM)
+ * This SRAM/SDRAM will be used as program data memory (including heap and stack).
+ * @param None
+ * @retval None
+ */
+void SystemInit_ExtMemCtl(void)
+{
+ __IO uint32_t tmp = 0x00;
+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
+ || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
+#if defined (DATA_IN_ExtSDRAM)
+ register uint32_t tmpreg = 0, timeout = 0xFFFF;
+ register __IO uint32_t index;
+
+#if defined(STM32F446xx)
+ /* Enable GPIOA, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG interface
+ clock */
+ RCC->AHB1ENR |= 0x0000007D;
+#else
+ /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface
+ clock */
+ RCC->AHB1ENR |= 0x000001F8;
+#endif /* STM32F446xx */
+ /* Delay after an RCC peripheral clock enabling */
+ tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
+
+#if defined(STM32F446xx)
+ /* Connect PAx pins to FMC Alternate function */
+ GPIOA->AFR[0] |= 0xC0000000;
+ GPIOA->AFR[1] |= 0x00000000;
+ /* Configure PDx pins in Alternate function mode */
+ GPIOA->MODER |= 0x00008000;
+ /* Configure PDx pins speed to 50 MHz */
+ GPIOA->OSPEEDR |= 0x00008000;
+ /* Configure PDx pins Output type to push-pull */
+ GPIOA->OTYPER |= 0x00000000;
+ /* No pull-up, pull-down for PDx pins */
+ GPIOA->PUPDR |= 0x00000000;
+
+ /* Connect PCx pins to FMC Alternate function */
+ GPIOC->AFR[0] |= 0x00CC0000;
+ GPIOC->AFR[1] |= 0x00000000;
+ /* Configure PDx pins in Alternate function mode */
+ GPIOC->MODER |= 0x00000A00;
+ /* Configure PDx pins speed to 50 MHz */
+ GPIOC->OSPEEDR |= 0x00000A00;
+ /* Configure PDx pins Output type to push-pull */
+ GPIOC->OTYPER |= 0x00000000;
+ /* No pull-up, pull-down for PDx pins */
+ GPIOC->PUPDR |= 0x00000000;
+#endif /* STM32F446xx */
+
+ /* Connect PDx pins to FMC Alternate function */
+ GPIOD->AFR[0] = 0x000000CC;
+ GPIOD->AFR[1] = 0xCC000CCC;
+ /* Configure PDx pins in Alternate function mode */
+ GPIOD->MODER = 0xA02A000A;
+ /* Configure PDx pins speed to 50 MHz */
+ GPIOD->OSPEEDR = 0xA02A000A;
+ /* Configure PDx pins Output type to push-pull */
+ GPIOD->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PDx pins */
+ GPIOD->PUPDR = 0x00000000;
+
+ /* Connect PEx pins to FMC Alternate function */
+ GPIOE->AFR[0] = 0xC00000CC;
+ GPIOE->AFR[1] = 0xCCCCCCCC;
+ /* Configure PEx pins in Alternate function mode */
+ GPIOE->MODER = 0xAAAA800A;
+ /* Configure PEx pins speed to 50 MHz */
+ GPIOE->OSPEEDR = 0xAAAA800A;
+ /* Configure PEx pins Output type to push-pull */
+ GPIOE->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PEx pins */
+ GPIOE->PUPDR = 0x00000000;
+
+ /* Connect PFx pins to FMC Alternate function */
+ GPIOF->AFR[0] = 0xCCCCCCCC;
+ GPIOF->AFR[1] = 0xCCCCCCCC;
+ /* Configure PFx pins in Alternate function mode */
+ GPIOF->MODER = 0xAA800AAA;
+ /* Configure PFx pins speed to 50 MHz */
+ GPIOF->OSPEEDR = 0xAA800AAA;
+ /* Configure PFx pins Output type to push-pull */
+ GPIOF->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PFx pins */
+ GPIOF->PUPDR = 0x00000000;
+
+ /* Connect PGx pins to FMC Alternate function */
+ GPIOG->AFR[0] = 0xCCCCCCCC;
+ GPIOG->AFR[1] = 0xCCCCCCCC;
+ /* Configure PGx pins in Alternate function mode */
+ GPIOG->MODER = 0xAAAAAAAA;
+ /* Configure PGx pins speed to 50 MHz */
+ GPIOG->OSPEEDR = 0xAAAAAAAA;
+ /* Configure PGx pins Output type to push-pull */
+ GPIOG->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PGx pins */
+ GPIOG->PUPDR = 0x00000000;
+
+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
+ || defined(STM32F469xx) || defined(STM32F479xx)
+ /* Connect PHx pins to FMC Alternate function */
+ GPIOH->AFR[0] = 0x00C0CC00;
+ GPIOH->AFR[1] = 0xCCCCCCCC;
+ /* Configure PHx pins in Alternate function mode */
+ GPIOH->MODER = 0xAAAA08A0;
+ /* Configure PHx pins speed to 50 MHz */
+ GPIOH->OSPEEDR = 0xAAAA08A0;
+ /* Configure PHx pins Output type to push-pull */
+ GPIOH->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PHx pins */
+ GPIOH->PUPDR = 0x00000000;
+
+ /* Connect PIx pins to FMC Alternate function */
+ GPIOI->AFR[0] = 0xCCCCCCCC;
+ GPIOI->AFR[1] = 0x00000CC0;
+ /* Configure PIx pins in Alternate function mode */
+ GPIOI->MODER = 0x0028AAAA;
+ /* Configure PIx pins speed to 50 MHz */
+ GPIOI->OSPEEDR = 0x0028AAAA;
+ /* Configure PIx pins Output type to push-pull */
+ GPIOI->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PIx pins */
+ GPIOI->PUPDR = 0x00000000;
+#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
+
+/*-- FMC Configuration -------------------------------------------------------*/
+ /* Enable the FMC interface clock */
+ RCC->AHB3ENR |= 0x00000001;
+ /* Delay after an RCC peripheral clock enabling */
+ tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
+
+ /* Configure and enable SDRAM bank1 */
+#if defined(STM32F446xx)
+ FMC_Bank5_6->SDCR[0] = 0x00001954;
+#else
+ FMC_Bank5_6->SDCR[0] = 0x000019E4;
+#endif /* STM32F446xx */
+ FMC_Bank5_6->SDTR[0] = 0x01115351;
+
+ /* SDRAM initialization sequence */
+ /* Clock enable command */
+ FMC_Bank5_6->SDCMR = 0x00000011;
+ tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
+ while((tmpreg != 0) && (timeout-- > 0))
+ {
+ tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
+ }
+
+ /* Delay */
+ for (index = 0; index<1000; index++);
+
+ /* PALL command */
+ FMC_Bank5_6->SDCMR = 0x00000012;
+ timeout = 0xFFFF;
+ while((tmpreg != 0) && (timeout-- > 0))
+ {
+ tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
+ }
+
+ /* Auto refresh command */
+#if defined(STM32F446xx)
+ FMC_Bank5_6->SDCMR = 0x000000F3;
+#else
+ FMC_Bank5_6->SDCMR = 0x00000073;
+#endif /* STM32F446xx */
+ timeout = 0xFFFF;
+ while((tmpreg != 0) && (timeout-- > 0))
+ {
+ tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
+ }
+
+ /* MRD register program */
+#if defined(STM32F446xx)
+ FMC_Bank5_6->SDCMR = 0x00044014;
+#else
+ FMC_Bank5_6->SDCMR = 0x00046014;
+#endif /* STM32F446xx */
+ timeout = 0xFFFF;
+ while((tmpreg != 0) && (timeout-- > 0))
+ {
+ tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
+ }
+
+ /* Set refresh count */
+ tmpreg = FMC_Bank5_6->SDRTR;
+#if defined(STM32F446xx)
+ FMC_Bank5_6->SDRTR = (tmpreg | (0x0000050C<<1));
+#else
+ FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
+#endif /* STM32F446xx */
+
+ /* Disable write protection */
+ tmpreg = FMC_Bank5_6->SDCR[0];
+ FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
+#endif /* DATA_IN_ExtSDRAM */
+#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */
+
+#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\
+ || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
+ || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
+
+#if defined(DATA_IN_ExtSRAM)
+/*-- GPIOs Configuration -----------------------------------------------------*/
+ /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
+ RCC->AHB1ENR |= 0x00000078;
+ /* Delay after an RCC peripheral clock enabling */
+ tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);
+
+ /* Connect PDx pins to FMC Alternate function */
+ GPIOD->AFR[0] = 0x00CCC0CC;
+ GPIOD->AFR[1] = 0xCCCCCCCC;
+ /* Configure PDx pins in Alternate function mode */
+ GPIOD->MODER = 0xAAAA0A8A;
+ /* Configure PDx pins speed to 100 MHz */
+ GPIOD->OSPEEDR = 0xFFFF0FCF;
+ /* Configure PDx pins Output type to push-pull */
+ GPIOD->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PDx pins */
+ GPIOD->PUPDR = 0x00000000;
+
+ /* Connect PEx pins to FMC Alternate function */
+ GPIOE->AFR[0] = 0xC00CC0CC;
+ GPIOE->AFR[1] = 0xCCCCCCCC;
+ /* Configure PEx pins in Alternate function mode */
+ GPIOE->MODER = 0xAAAA828A;
+ /* Configure PEx pins speed to 100 MHz */
+ GPIOE->OSPEEDR = 0xFFFFC3CF;
+ /* Configure PEx pins Output type to push-pull */
+ GPIOE->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PEx pins */
+ GPIOE->PUPDR = 0x00000000;
+
+ /* Connect PFx pins to FMC Alternate function */
+ GPIOF->AFR[0] = 0x00CCCCCC;
+ GPIOF->AFR[1] = 0xCCCC0000;
+ /* Configure PFx pins in Alternate function mode */
+ GPIOF->MODER = 0xAA000AAA;
+ /* Configure PFx pins speed to 100 MHz */
+ GPIOF->OSPEEDR = 0xFF000FFF;
+ /* Configure PFx pins Output type to push-pull */
+ GPIOF->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PFx pins */
+ GPIOF->PUPDR = 0x00000000;
+
+ /* Connect PGx pins to FMC Alternate function */
+ GPIOG->AFR[0] = 0x00CCCCCC;
+ GPIOG->AFR[1] = 0x000000C0;
+ /* Configure PGx pins in Alternate function mode */
+ GPIOG->MODER = 0x00085AAA;
+ /* Configure PGx pins speed to 100 MHz */
+ GPIOG->OSPEEDR = 0x000CAFFF;
+ /* Configure PGx pins Output type to push-pull */
+ GPIOG->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PGx pins */
+ GPIOG->PUPDR = 0x00000000;
+
+/*-- FMC/FSMC Configuration --------------------------------------------------*/
+ /* Enable the FMC/FSMC interface clock */
+ RCC->AHB3ENR |= 0x00000001;
+
+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
+ /* Delay after an RCC peripheral clock enabling */
+ tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
+ /* Configure and enable Bank1_SRAM2 */
+ FMC_Bank1->BTCR[2] = 0x00001011;
+ FMC_Bank1->BTCR[3] = 0x00000201;
+ FMC_Bank1E->BWTR[2] = 0x0fffffff;
+#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
+#if defined(STM32F469xx) || defined(STM32F479xx)
+ /* Delay after an RCC peripheral clock enabling */
+ tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
+ /* Configure and enable Bank1_SRAM2 */
+ FMC_Bank1->BTCR[2] = 0x00001091;
+ FMC_Bank1->BTCR[3] = 0x00110212;
+ FMC_Bank1E->BWTR[2] = 0x0fffffff;
+#endif /* STM32F469xx || STM32F479xx */
+#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx)\
+ || defined(STM32F412Zx) || defined(STM32F412Vx)
+ /* Delay after an RCC peripheral clock enabling */
+ tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN);
+ /* Configure and enable Bank1_SRAM2 */
+ FSMC_Bank1->BTCR[2] = 0x00001011;
+ FSMC_Bank1->BTCR[3] = 0x00000201;
+ FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF;
+#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F412Zx || STM32F412Vx */
+
+#endif /* DATA_IN_ExtSRAM */
+#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\
+ STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx */
+ (void)(tmp);
+}
+#endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/ports/stm32f4/tick.c b/ports/stm32f4/tick.c
new file mode 100644
index 000000000..5bd2da6ed
--- /dev/null
+++ b/ports/stm32f4/tick.c
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "tick.h"
+
+#include "supervisor/shared/autoreload.h"
+#include "supervisor/filesystem.h"
+#include "shared-module/gamepad/__init__.h"
+#include "shared-bindings/microcontroller/Processor.h"
+
+#include "stm32f4xx.h"
+
+// Global millisecond tick count
+volatile uint64_t ticks_ms = 0;
+
+void SysTick_Handler(void) {
+ // SysTick interrupt handler called when the SysTick timer reaches zero
+ // (every millisecond).
+ ticks_ms += 1;
+
+#if CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS > 0
+ filesystem_tick();
+#endif
+#ifdef CIRCUITPY_AUTORELOAD_DELAY_MS
+ autoreload_tick();
+#endif
+#ifdef CIRCUITPY_GAMEPAD_TICKS
+ if (!(ticks_ms & CIRCUITPY_GAMEPAD_TICKS)) {
+ gamepad_tick();
+ }
+#endif
+}
+
+void tick_init() {
+ uint32_t ticks_per_ms = SystemCoreClock/ 1000;
+ SysTick_Config(ticks_per_ms); // interrupt is enabled
+}
+
+void tick_delay(uint32_t us) {
+ uint32_t ticks_per_us = SystemCoreClock / 1000 / 1000;
+ uint32_t us_between_ticks = SysTick->VAL / ticks_per_us;
+ uint64_t start_ms = ticks_ms;
+ while (us > 1000) {
+ while (ticks_ms == start_ms) {}
+ us -= us_between_ticks;
+ start_ms = ticks_ms;
+ us_between_ticks = 1000;
+ }
+ while (SysTick->VAL > ((us_between_ticks - us) * ticks_per_us)) {}
+}
+
+// us counts down!
+void current_tick(uint64_t* ms, uint32_t* us_until_ms) {
+ uint32_t ticks_per_us = SystemCoreClock / 1000 / 1000;
+ *ms = ticks_ms;
+ *us_until_ms = SysTick->VAL / ticks_per_us;
+}
+
+void wait_until(uint64_t ms, uint32_t us_until_ms) {
+ uint32_t ticks_per_us = SystemCoreClock / 1000 / 1000;
+ while(ticks_ms <= ms && SysTick->VAL / ticks_per_us >= us_until_ms) {}
+}
diff --git a/ports/stm32f4/tick.h b/ports/stm32f4/tick.h
new file mode 100644
index 000000000..e4772fa2c
--- /dev/null
+++ b/ports/stm32f4/tick.h
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef MICROPY_INCLUDED_STM32F4_TICK_H
+#define MICROPY_INCLUDED_STM32F4_TICK_H
+
+#include "py/mpconfig.h"
+
+#include <stdint.h>
+
+extern volatile uint64_t ticks_ms;
+
+extern struct timer_descriptor ms_timer;
+
+void tick_init(void);
+
+void tick_delay(uint32_t us);
+
+void current_tick(uint64_t* ms, uint32_t* us_until_ms);
+// Do not call this with interrupts disabled because it may be waiting for
+// ticks_ms to increment.
+void wait_until(uint64_t ms, uint32_t us_until_ms);
+
+#endif // MICROPY_INCLUDED_STM32F4_TICK_H
diff --git a/py/binary.c b/py/binary.c
index 0e4a1d5f6..6b46425cf 100644
--- a/py/binary.c
+++ b/py/binary.c
@@ -308,6 +308,7 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte **
bool signed_type = is_signed(val_type);
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
if (MP_OBJ_IS_TYPE(val_in, &mp_type_int)) {
+ // It's a longint.
mp_obj_int_buffer_overflow_check(val_in, size, signed_type);
mp_obj_int_to_bytes_impl(val_in, struct_type == '>', size, p);
return;
@@ -315,7 +316,8 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte **
#endif
{
val = mp_obj_get_int(val_in);
- mp_obj_int_buffer_overflow_check(val_in, size, signed_type);
+ // Small int checking is separate, to be fast.
+ mp_small_int_buffer_overflow_check(val, size, signed_type);
// zero/sign extend if needed
if (BYTES_PER_WORD < 8 && size > sizeof(val)) {
int c = (is_signed(val_type) && (mp_int_t)val < 0) ? 0xff : 0x00;
@@ -353,6 +355,7 @@ void mp_binary_set_val_array(char typecode, void *p, mp_uint_t index, mp_obj_t v
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
if (MP_OBJ_IS_TYPE(val_in, &mp_type_int)) {
+ // It's a long int.
mp_obj_int_buffer_overflow_check(val_in, size, signed_type);
mp_obj_int_to_bytes_impl(val_in, MP_ENDIANNESS_BIG,
size, (uint8_t*)p + index * size);
@@ -360,7 +363,8 @@ void mp_binary_set_val_array(char typecode, void *p, mp_uint_t index, mp_obj_t v
}
#endif
mp_int_t val = mp_obj_get_int(val_in);
- mp_obj_int_buffer_overflow_check(val_in, size, signed_type);
+ // Small int checking is separate, to be fast.
+ mp_small_int_buffer_overflow_check(val, size, signed_type);
mp_binary_set_val_array_from_int(typecode, p, index, val);
}
}
diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk
index 1aca33901..a6dde61da 100644
--- a/py/circuitpy_defns.mk
+++ b/py/circuitpy_defns.mk
@@ -108,6 +108,12 @@ endif
ifeq ($(CIRCUITPY_AUDIOIO),1)
SRC_PATTERNS += audioio/%
endif
+ifeq ($(CIRCUITPY_AUDIOPWMIO),1)
+SRC_PATTERNS += audiopwmio/%
+endif
+ifeq ($(CIRCUITPY_AUDIOCORE),1)
+SRC_PATTERNS += audiocore/%
+endif
ifeq ($(CIRCUITPY_BITBANGIO),1)
SRC_PATTERNS += bitbangio/%
endif
@@ -162,6 +168,9 @@ endif
ifeq ($(CIRCUITPY_PULSEIO),1)
SRC_PATTERNS += pulseio/%
endif
+ifeq ($(CIRCUITPY_PS2IO),1)
+SRC_PATTERNS += ps2io/%
+endif
ifeq ($(CIRCUITPY_RANDOM),1)
SRC_PATTERNS += random/%
endif
@@ -217,11 +226,13 @@ $(filter $(SRC_PATTERNS), \
audiobusio/__init__.c \
audiobusio/I2SOut.c \
audiobusio/PDMIn.c \
+ audiopwmio/__init__.c \
+ audiopwmio/PWMAudioOut.c \
audioio/__init__.c \
audioio/AudioOut.c \
bleio/__init__.c \
bleio/Adapter.c \
- bleio/Broadcaster.c \
+ bleio/Central.c \
bleio/Characteristic.c \
bleio/CharacteristicBuffer.c \
bleio/Descriptor.c \
@@ -252,6 +263,8 @@ $(filter $(SRC_PATTERNS), \
pulseio/PulseIn.c \
pulseio/PulseOut.c \
pulseio/__init__.c \
+ ps2io/Ps2.c \
+ ps2io/__init__.c \
rotaryio/IncrementalEncoder.c \
rotaryio/__init__.c \
rtc/RTC.c \
@@ -284,8 +297,6 @@ SRC_BINDINGS_ENUMS += \
SRC_BINDINGS_ENUMS += \
$(filter $(SRC_PATTERNS), \
bleio/Address.c \
- bleio/AddressType.c \
- bleio/AdvertisementData.c \
bleio/ScanEntry.c \
)
@@ -297,21 +308,26 @@ $(filter $(SRC_PATTERNS), \
_stage/Layer.c \
_stage/Text.c \
_stage/__init__.c \
+ audiopwmio/__init__.c \
audioio/__init__.c \
- audioio/Mixer.c \
- audioio/RawSample.c \
- audioio/WaveFile.c \
+ audiocore/__init__.c \
+ audiocore/Mixer.c \
+ audiocore/RawSample.c \
+ audiocore/WaveFile.c \
bitbangio/I2C.c \
bitbangio/OneWire.c \
bitbangio/SPI.c \
bitbangio/__init__.c \
board/__init__.c \
+ bleio/Address.c \
+ bleio/ScanEntry.c \
busio/OneWire.c \
displayio/Bitmap.c \
displayio/ColorConverter.c \
displayio/Display.c \
displayio/FourWire.c \
displayio/Group.c \
+ displayio/I2CDisplay.c \
displayio/OnDiskBitmap.c \
displayio/Palette.c \
displayio/Shape.c \
@@ -361,3 +377,8 @@ $(addprefix lib/,\
libm/atan2f.c \
)
endif
+
+.PHONY: check-release-needs-clean-build
+
+check-release-needs-clean-build:
+ @echo "RELEASE_NEEDS_CLEAN_BUILD = $(RELEASE_NEEDS_CLEAN_BUILD)"
diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h
index f957886f4..d88d6538e 100644
--- a/py/circuitpy_mpconfig.h
+++ b/py/circuitpy_mpconfig.h
@@ -72,6 +72,7 @@
#define MICROPY_KBD_EXCEPTION (1)
#define MICROPY_MEM_STATS (0)
#define MICROPY_NONSTANDARD_TYPECODES (0)
+#define MICROPY_OPT_COMPUTED_GOTO (1)
#define MICROPY_PERSISTENT_CODE_LOAD (1)
#define MICROPY_PY_ARRAY (1)
@@ -89,6 +90,7 @@
#define MICROPY_PY_BUILTINS_MIN_MAX (1)
#define MICROPY_PY_BUILTINS_PROPERTY (1)
#define MICROPY_PY_BUILTINS_REVERSED (1)
+#define MICROPY_PY_BUILTINS_ROUND_INT (1)
#define MICROPY_PY_BUILTINS_SET (1)
#define MICROPY_PY_BUILTINS_SLICE (1)
#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1)
@@ -228,6 +230,13 @@ extern const struct _mp_obj_module_t audiobusio_module;
#define AUDIOBUSIO_MODULE
#endif
+#if CIRCUITPY_AUDIOCORE
+#define AUDIOCORE_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_audiocore), (mp_obj_t)&audiocore_module },
+extern const struct _mp_obj_module_t audiocore_module;
+#else
+#define AUDIOCORE_MODULE
+#endif
+
#if CIRCUITPY_AUDIOIO
#define AUDIOIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_audioio), (mp_obj_t)&audioio_module },
extern const struct _mp_obj_module_t audioio_module;
@@ -235,6 +244,13 @@ extern const struct _mp_obj_module_t audioio_module;
#define AUDIOIO_MODULE
#endif
+#if CIRCUITPY_AUDIOPWMIO
+#define AUDIOPWMIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_audiopwmio), (mp_obj_t)&audiopwmio_module },
+extern const struct _mp_obj_module_t audiopwmio_module;
+#else
+#define AUDIOPWMIO_MODULE
+#endif
+
#if CIRCUITPY_BITBANGIO
#define BITBANGIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module },
extern const struct _mp_obj_module_t bitbangio_module;
@@ -415,6 +431,13 @@ extern const struct _mp_obj_module_t pulseio_module;
#define PULSEIO_MODULE
#endif
+#if CIRCUITPY_PS2IO
+extern const struct _mp_obj_module_t ps2io_module;
+#define PS2IO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_ps2io), (mp_obj_t)&ps2io_module },
+#else
+#define PS2IO_MODULE
+#endif
+
#if CIRCUITPY_RANDOM
extern const struct _mp_obj_module_t random_module;
#define RANDOM_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module },
@@ -555,7 +578,9 @@ extern const struct _mp_obj_module_t ustack_module;
#define MICROPY_PORT_BUILTIN_MODULES_STRONG_LINKS \
ANALOGIO_MODULE \
AUDIOBUSIO_MODULE \
+ AUDIOCORE_MODULE \
AUDIOIO_MODULE \
+ AUDIOPWMIO_MODULE \
BITBANGIO_MODULE \
BLEIO_MODULE \
BOARD_MODULE \
@@ -579,6 +604,7 @@ extern const struct _mp_obj_module_t ustack_module;
PEW_MODULE \
PIXELBUF_MODULE \
PULSEIO_MODULE \
+ PS2IO_MODULE \
RANDOM_MODULE \
RE_MODULE \
ROTARYIO_MODULE \
diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk
index b436929e0..a408cd7ac 100644
--- a/py/circuitpy_mpconfig.mk
+++ b/py/circuitpy_mpconfig.mk
@@ -32,22 +32,35 @@
# CIRCUITPY_FULL_BUILD = 0
ifndef CIRCUITPY_FULL_BUILD
-ifeq ($(CIRCUITPY_SMALL_BUILD),1)
-CIRCUITPY_FULL_BUILD = 0
-CFLAGS += -DCIRCUITPY_FULL_BUILD=0
-else
-CIRCUITPY_FULL_BUILD = 1
-CFLAGS += -DCIRCUITPY_FULL_BUILD=1
+ ifeq ($(CIRCUITPY_SMALL_BUILD),1)
+ CIRCUITPY_FULL_BUILD = 0
+ CFLAGS += -DCIRCUITPY_FULL_BUILD=0
+ else
+ CIRCUITPY_FULL_BUILD = 1
+ CFLAGS += -DCIRCUITPY_FULL_BUILD=1
+ endif
endif
+
+# Setting CIRCUITPY_MINIMAL_BUILD = 1 will disable all features
+# Use for for early stage or highly restricted ports
+ifndef CIRCUITPY_DEFAULT_BUILD
+ ifeq ($(CIRCUITPY_MINIMAL_BUILD),1)
+ CIRCUITPY_FULL_BUILD = 0
+ CIRCUITPY_DEFAULT_BUILD = 0
+ else
+ CIRCUITPY_DEFAULT_BUILD = 1
+ endif
endif
+
+
# All builtin modules are listed below, with default values (0 for off, 1 for on)
# Some are always on, some are always off, and some depend on CIRCUITPY_FULL_BUILD.
#
# *** You can override any of the defaults by defining them in your mpconfigboard.mk.
ifndef CIRCUITPY_ANALOGIO
-CIRCUITPY_ANALOGIO = 1
+CIRCUITPY_ANALOGIO = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_ANALOGIO=$(CIRCUITPY_ANALOGIO)
@@ -61,6 +74,20 @@ CIRCUITPY_AUDIOIO = $(CIRCUITPY_FULL_BUILD)
endif
CFLAGS += -DCIRCUITPY_AUDIOIO=$(CIRCUITPY_AUDIOIO)
+ifndef CIRCUITPY_AUDIOPWMIO
+CIRCUITPY_AUDIOPWMIO = 0
+endif
+CFLAGS += -DCIRCUITPY_AUDIOPWMIO=$(CIRCUITPY_AUDIOPWMIO)
+
+ifndef CIRCUITPY_AUDIOCORE
+ifeq ($(CIRCUITPY_AUDIOPWMIO),1)
+CIRCUITPY_AUDIOCORE = $(CIRCUITPY_AUDIOPWMIO)
+else
+CIRCUITPY_AUDIOCORE = $(CIRCUITPY_AUDIOIO)
+endif
+endif
+CFLAGS += -DCIRCUITPY_AUDIOCORE=$(CIRCUITPY_AUDIOCORE)
+
ifndef CIRCUITPY_BITBANGIO
CIRCUITPY_BITBANGIO = $(CIRCUITPY_FULL_BUILD)
endif
@@ -73,17 +100,17 @@ endif
CFLAGS += -DCIRCUITPY_BLEIO=$(CIRCUITPY_BLEIO)
ifndef CIRCUITPY_BOARD
-CIRCUITPY_BOARD = 1
+CIRCUITPY_BOARD = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_BOARD=$(CIRCUITPY_BOARD)
ifndef CIRCUITPY_BUSIO
-CIRCUITPY_BUSIO = 1
+CIRCUITPY_BUSIO = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_BUSIO=$(CIRCUITPY_BUSIO)
ifndef CIRCUITPY_DIGITALIO
-CIRCUITPY_DIGITALIO = 1
+CIRCUITPY_DIGITALIO = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_DIGITALIO=$(CIRCUITPY_DIGITALIO)
@@ -113,17 +140,17 @@ endif
CFLAGS += -DCIRCUITPY_I2CSLAVE=$(CIRCUITPY_I2CSLAVE)
ifndef CIRCUITPY_MATH
-CIRCUITPY_MATH = 1
+CIRCUITPY_MATH = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH)
ifndef CIRCUITPY_MICROCONTROLLER
-CIRCUITPY_MICROCONTROLLER = 1
+CIRCUITPY_MICROCONTROLLER = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_MICROCONTROLLER=$(CIRCUITPY_MICROCONTROLLER)
ifndef CIRCUITPY_NEOPIXEL_WRITE
-CIRCUITPY_NEOPIXEL_WRITE = 1
+CIRCUITPY_NEOPIXEL_WRITE = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_NEOPIXEL_WRITE=$(CIRCUITPY_NEOPIXEL_WRITE)
@@ -134,12 +161,12 @@ endif
CFLAGS += -DCIRCUITPY_NETWORK=$(CIRCUITPY_NETWORK)
ifndef CIRCUITPY_NVM
-CIRCUITPY_NVM = 1
+CIRCUITPY_NVM = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_NVM=$(CIRCUITPY_NVM)
ifndef CIRCUITPY_OS
-CIRCUITPY_OS = 1
+CIRCUITPY_OS = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_OS=$(CIRCUITPY_OS)
@@ -149,22 +176,28 @@ endif
CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF)
ifndef CIRCUITPY_PULSEIO
-CIRCUITPY_PULSEIO = 1
+CIRCUITPY_PULSEIO = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_PULSEIO=$(CIRCUITPY_PULSEIO)
+# Only for SAMD boards for the moment
+ifndef CIRCUITPY_PS2IO
+CIRCUITPY_PS2IO = 0
+endif
+CFLAGS += -DCIRCUITPY_PS2IO=$(CIRCUITPY_PS2IO)
+
ifndef CIRCUITPY_RANDOM
-CIRCUITPY_RANDOM = 1
+CIRCUITPY_RANDOM = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_RANDOM=$(CIRCUITPY_RANDOM)
ifndef CIRCUITPY_ROTARYIO
-CIRCUITPY_ROTARYIO = 1
+CIRCUITPY_ROTARYIO = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_ROTARYIO=$(CIRCUITPY_ROTARYIO)
ifndef CIRCUITPY_RTC
-CIRCUITPY_RTC = 1
+CIRCUITPY_RTC = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_RTC=$(CIRCUITPY_RTC)
@@ -183,27 +216,27 @@ endif
CFLAGS += -DCIRCUITPY_STAGE=$(CIRCUITPY_STAGE)
ifndef CIRCUITPY_STORAGE
-CIRCUITPY_STORAGE = 1
+CIRCUITPY_STORAGE = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_STORAGE=$(CIRCUITPY_STORAGE)
ifndef CIRCUITPY_STRUCT
-CIRCUITPY_STRUCT = 1
+CIRCUITPY_STRUCT = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_STRUCT=$(CIRCUITPY_STRUCT)
ifndef CIRCUITPY_SUPERVISOR
-CIRCUITPY_SUPERVISOR = 1
+CIRCUITPY_SUPERVISOR = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_SUPERVISOR=$(CIRCUITPY_SUPERVISOR)
ifndef CIRCUITPY_TIME
-CIRCUITPY_TIME = 1
+CIRCUITPY_TIME = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_TIME=$(CIRCUITPY_TIME)
ifndef CIRCUITPY_TOUCHIO
-CIRCUITPY_TOUCHIO = 1
+CIRCUITPY_TOUCHIO = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_TOUCHIO=$(CIRCUITPY_TOUCHIO)
@@ -214,12 +247,12 @@ endif
CFLAGS += -DCIRCUITPY_UHEAP=$(CIRCUITPY_UHEAP)
ifndef CIRCUITPY_USB_HID
-CIRCUITPY_USB_HID = 1
+CIRCUITPY_USB_HID = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_USB_HID=$(CIRCUITPY_USB_HID)
ifndef CIRCUITPY_USB_MIDI
-CIRCUITPY_USB_MIDI = 1
+CIRCUITPY_USB_MIDI = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_USB_MIDI=$(CIRCUITPY_USB_MIDI)
diff --git a/py/emitglue.c b/py/emitglue.c
index 74bf8ddca..7708689dd 100644
--- a/py/emitglue.c
+++ b/py/emitglue.c
@@ -142,11 +142,12 @@ mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, mp_obj_t def_ar
fun = mp_obj_new_fun_asm(rc->n_pos_args, rc->data.u_native.fun_data, rc->data.u_native.type_sig);
break;
#endif
- default:
- // rc->kind should always be set and BYTECODE is the only remaining case
- assert(rc->kind == MP_CODE_BYTECODE);
+ case MP_CODE_BYTECODE:
fun = mp_obj_new_fun_bc(def_args, def_kw_args, rc->data.u_byte.bytecode, rc->data.u_byte.const_table);
break;
+ default:
+ // All other kinds are invalid.
+ mp_raise_RuntimeError(translate("Corrupt raw code"));
}
// check for generator functions and if so wrap in generator object
diff --git a/py/gc.c b/py/gc.c
index e9b85fa7c..10b36950c 100755
--- a/py/gc.c
+++ b/py/gc.c
@@ -383,6 +383,10 @@ void gc_collect_start(void) {
#endif
}
+void gc_collect_ptr(void *ptr) {
+ gc_mark(ptr);
+}
+
void gc_collect_root(void **ptrs, size_t len) {
for (size_t i = 0; i < len; i++) {
void *ptr = ptrs[i];
diff --git a/py/gc.h b/py/gc.h
index 757a2a6e0..02bf45158 100644
--- a/py/gc.h
+++ b/py/gc.h
@@ -43,6 +43,7 @@ bool gc_is_locked(void);
// A given port must implement gc_collect by using the other collect functions.
void gc_collect(void);
void gc_collect_start(void);
+void gc_collect_ptr(void *ptr);
void gc_collect_root(void **ptrs, size_t len);
void gc_collect_end(void);
diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py
index 5b5ec1c37..8e3835d86 100644
--- a/py/makeqstrdata.py
+++ b/py/makeqstrdata.py
@@ -180,7 +180,7 @@ def compress(encoding_table, decompressed):
if not isinstance(decompressed, bytes):
raise TypeError()
values, lengths = encoding_table
- enc = bytearray(len(decompressed))
+ enc = bytearray(len(decompressed) * 2)
#print(decompressed)
#print(lengths)
current_bit = 7
@@ -227,6 +227,8 @@ def compress(encoding_table, decompressed):
current_bit -= 1
if current_bit != 7:
current_byte += 1
+ if current_byte > len(decompressed):
+ print("Note: compression increased length", repr(decompressed.decode('utf-8')), len(decompressed), current_byte, file=sys.stderr)
return enc[:current_byte]
def qstr_escape(qst):
diff --git a/py/modbuiltins.c b/py/modbuiltins.c
index 124dcd05a..e764f1987 100644
--- a/py/modbuiltins.c
+++ b/py/modbuiltins.c
@@ -455,13 +455,13 @@ STATIC mp_obj_t mp_builtin_round(size_t n_args, const mp_obj_t *args) {
return o_in;
}
- #if !MICROPY_PY_BUILTINS_ROUND_INT
- mp_raise_NotImplementedError(NULL);
- #else
mp_int_t num_dig = mp_obj_get_int(args[1]);
if (num_dig >= 0) {
return o_in;
}
+ #if !MICROPY_PY_BUILTINS_ROUND_INT
+ mp_raise_NotImplementedError(NULL);
+ #else
mp_obj_t mult = mp_binary_op(MP_BINARY_OP_POWER, MP_OBJ_NEW_SMALL_INT(10), MP_OBJ_NEW_SMALL_INT(-num_dig));
mp_obj_t half_mult = mp_binary_op(MP_BINARY_OP_FLOOR_DIVIDE, mult, MP_OBJ_NEW_SMALL_INT(2));
diff --git a/py/obj.c b/py/obj.c
index fb59eec82..322a302f9 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -531,6 +531,36 @@ mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf) {
return self;
}
+typedef struct {
+ mp_obj_base_t base;
+ mp_fun_1_t iternext;
+ mp_obj_t obj;
+ mp_int_t cur;
+} mp_obj_generic_it_t;
+
+STATIC mp_obj_t generic_it_iternext(mp_obj_t self_in) {
+ mp_obj_generic_it_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_obj_type_t *type = mp_obj_get_type(self->obj);
+ mp_obj_t current_length = type->unary_op(MP_UNARY_OP_LEN, self->obj);
+ if (self->cur < MP_OBJ_SMALL_INT_VALUE(current_length)) {
+ mp_obj_t o_out = type->subscr(self->obj, MP_OBJ_NEW_SMALL_INT(self->cur), MP_OBJ_SENTINEL);
+ self->cur += 1;
+ return o_out;
+ } else {
+ return MP_OBJ_STOP_ITERATION;
+ }
+}
+
+mp_obj_t mp_obj_new_generic_iterator(mp_obj_t obj, mp_obj_iter_buf_t *iter_buf) {
+ assert(sizeof(mp_obj_generic_it_t) <= sizeof(mp_obj_iter_buf_t));
+ mp_obj_generic_it_t *o = (mp_obj_generic_it_t*)iter_buf;
+ o->base.type = &mp_type_polymorph_iter;
+ o->iternext = generic_it_iternext;
+ o->obj = obj;
+ o->cur = 0;
+ return MP_OBJ_FROM_PTR(o);
+}
+
bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
mp_obj_type_t *type = mp_obj_get_type(obj);
if (type->buffer_p.get_buffer == NULL) {
diff --git a/py/obj.h b/py/obj.h
index ae2bff190..6eead377d 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -763,6 +763,7 @@ void mp_obj_tuple_del(mp_obj_t self_in);
mp_int_t mp_obj_tuple_hash(mp_obj_t self_in);
// list
+mp_obj_t mp_obj_list_clear(mp_obj_t self_in);
mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg);
mp_obj_t mp_obj_list_remove(mp_obj_t self_in, mp_obj_t value);
void mp_obj_list_get(mp_obj_t self_in, size_t *len, mp_obj_t **items);
@@ -819,6 +820,10 @@ mp_obj_t mp_identity(mp_obj_t self);
MP_DECLARE_CONST_FUN_OBJ_1(mp_identity_obj);
mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf);
+// Generic iterator that uses unary op and subscr to iterate over a native type. It will be slower
+// than a custom iterator but applies broadly.
+mp_obj_t mp_obj_new_generic_iterator(mp_obj_t self, mp_obj_iter_buf_t *iter_buf);
+
// module
typedef struct _mp_obj_module_t {
mp_obj_base_t base;
diff --git a/py/objint.c b/py/objint.c
index 80f6dfe55..9e11871f1 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -300,6 +300,8 @@ char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_co
return b;
}
+#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
+
void mp_obj_int_buffer_overflow_check(mp_obj_t self_in, size_t nbytes, bool is_signed)
{
if (is_signed) {
@@ -329,7 +331,43 @@ void mp_obj_int_buffer_overflow_check(mp_obj_t self_in, size_t nbytes, bool is_s
}
}
- mp_raise_OverflowError_varg(translate("value would overflow a %d byte buffer"), nbytes);
+ mp_raise_OverflowError_varg(translate("value must fit in %d byte(s)"), nbytes);
+}
+
+#endif // MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
+
+void mp_small_int_buffer_overflow_check(mp_int_t val, size_t nbytes, bool is_signed) {
+ // Fast path for zero.
+ if (val == 0) {
+ return;
+ }
+
+ // Trying to store negative values in unsigned bytes falls through to failure.
+ if (is_signed || val >= 0) {
+
+ if (nbytes >= sizeof(val)) {
+ // All non-negative N bit signed integers fit in an unsigned N bit integer.
+ // This case prevents shifting too far below.
+ return;
+ }
+
+ if (is_signed) {
+ mp_int_t edge = ((mp_int_t)1 << (nbytes * 8 - 1));
+ if (-edge <= val && val < edge) {
+ return;
+ }
+ // Out of range, fall through to failure.
+ } else {
+ // Unsigned. We already know val >= 0.
+ mp_int_t edge = ((mp_int_t)1 << (nbytes * 8));
+ if (val < edge) {
+ return;
+ }
+ }
+ // Fall through to failure.
+ }
+
+ mp_raise_OverflowError_varg(translate("value must fit in %d byte(s)"), nbytes);
}
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
@@ -467,15 +505,16 @@ STATIC mp_obj_t int_to_bytes(size_t n_args, const mp_obj_t *args) {
byte *data = (byte*)vstr.buf;
memset(data, 0, len);
- mp_obj_int_buffer_overflow_check(args[0], len, false);
-
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
if (!MP_OBJ_IS_SMALL_INT(args[0])) {
+ mp_obj_int_buffer_overflow_check(args[0], len, false);
mp_obj_int_to_bytes_impl(args[0], big_endian, len, data);
} else
#endif
{
mp_int_t val = MP_OBJ_SMALL_INT_VALUE(args[0]);
+ // Small int checking is separate, to be fast.
+ mp_small_int_buffer_overflow_check(val, len, false);
size_t l = MIN((size_t)len, sizeof(val));
mp_binary_set_int(l, big_endian, data + (big_endian ? (len - l) : 0), val);
}
diff --git a/py/objint.h b/py/objint.h
index 654404ac9..e8c9bc3e0 100644
--- a/py/objint.h
+++ b/py/objint.h
@@ -53,7 +53,12 @@ char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_co
int base, const char *prefix, char base_char, char comma);
char *mp_obj_int_formatted_impl(char **buf, size_t *buf_size, size_t *fmt_size, mp_const_obj_t self_in,
int base, const char *prefix, char base_char, char comma);
+#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
void mp_obj_int_buffer_overflow_check(mp_obj_t self_in, size_t nbytes, bool is_signed);
+#endif
+
+void mp_small_int_buffer_overflow_check(mp_int_t val, size_t nbytes, bool is_signed);
+
mp_int_t mp_obj_int_hash(mp_obj_t self_in);
mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf);
void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf);
diff --git a/py/objlist.c b/py/objlist.c
index 16ca4b353..558c4c611 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -340,7 +340,7 @@ mp_obj_t mp_obj_list_sort(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_
return mp_const_none;
}
-STATIC mp_obj_t list_clear(mp_obj_t self_in) {
+mp_obj_t mp_obj_list_clear(mp_obj_t self_in) {
mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_list));
mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in);
self->len = 0;
@@ -418,7 +418,7 @@ STATIC mp_obj_t list_reverse(mp_obj_t self_in) {
STATIC MP_DEFINE_CONST_FUN_OBJ_2(list_append_obj, mp_obj_list_append);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(list_extend_obj, list_extend);
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(list_clear_obj, list_clear);
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(list_clear_obj, mp_obj_list_clear);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(list_copy_obj, list_copy);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(list_count_obj, list_count);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(list_index_obj, 2, 4, list_index);
diff --git a/py/objtype.c b/py/objtype.c
index 88e918827..5133d849f 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -117,6 +117,16 @@ mp_obj_instance_t *mp_obj_new_instance(const mp_obj_type_t *class, const mp_obj_
return o;
}
+// When instances are first created they have the base_init wrapper as their native parent's
+// instance because make_new combines __new__ and __init__. This object is invalid for the native
+// code so it must call this method to ensure that the given object has been __init__'d and is
+// valid.
+void mp_obj_assert_native_inited(mp_obj_t native_object) {
+ if (native_object == MP_OBJ_FROM_PTR(&native_base_init_wrapper_obj)) {
+ mp_raise_NotImplementedError(translate("Call super().__init__() before accessing native object."));
+ }
+}
+
// TODO
// This implements depth-first left-to-right MRO, which is not compliant with Python3 MRO
// http://python-history.blogspot.com/2010/06/method-resolution-order.html
diff --git a/py/objtype.h b/py/objtype.h
index 13613f01f..a32c87496 100644
--- a/py/objtype.h
+++ b/py/objtype.h
@@ -37,6 +37,8 @@ typedef struct _mp_obj_instance_t {
// TODO maybe cache __getattr__ and __setattr__ for efficient lookup of them
} mp_obj_instance_t;
+void mp_obj_assert_native_inited(mp_obj_t native_object);
+
#if MICROPY_CPYTHON_COMPAT
// this is needed for object.__new__
mp_obj_instance_t *mp_obj_new_instance(const mp_obj_type_t *cls, const mp_obj_type_t **native_base);
diff --git a/py/persistentcode.c b/py/persistentcode.c
index f6de782ed..eb69bd407 100644
--- a/py/persistentcode.c
+++ b/py/persistentcode.c
@@ -102,20 +102,35 @@ STATIC void extract_prelude(const byte **ip, const byte **ip2, bytecode_prelude_
#include "py/parsenum.h"
+STATIC void raise_corrupt_mpy(void) {
+ mp_raise_RuntimeError(translate("Corrupt .mpy file"));
+}
+
STATIC int read_byte(mp_reader_t *reader) {
- return reader->readbyte(reader->data);
+ mp_uint_t b = reader->readbyte(reader->data);
+ if (b == MP_READER_EOF) {
+ raise_corrupt_mpy();
+ }
+ return b;
}
STATIC void read_bytes(mp_reader_t *reader, byte *buf, size_t len) {
while (len-- > 0) {
- *buf++ = reader->readbyte(reader->data);
+ mp_uint_t b =reader->readbyte(reader->data);
+ if (b == MP_READER_EOF) {
+ raise_corrupt_mpy();
+ }
+ *buf++ = b;
}
}
STATIC size_t read_uint(mp_reader_t *reader) {
size_t unum = 0;
for (;;) {
- byte b = reader->readbyte(reader->data);
+ mp_uint_t b = reader->readbyte(reader->data);
+ if (b == MP_READER_EOF) {
+ raise_corrupt_mpy();
+ }
unum = (unum << 7) | (b & 0x7f);
if ((b & 0x80) == 0) {
break;
@@ -145,11 +160,12 @@ STATIC mp_obj_t load_obj(mp_reader_t *reader) {
return mp_obj_new_str_from_vstr(obj_type == 's' ? &mp_type_str : &mp_type_bytes, &vstr);
} else if (obj_type == 'i') {
return mp_parse_num_integer(vstr.buf, vstr.len, 10, NULL);
- } else {
- assert(obj_type == 'f' || obj_type == 'c');
+ } else if (obj_type == 'f' || obj_type == 'c') {
return mp_parse_num_decimal(vstr.buf, vstr.len, obj_type == 'c', false, NULL);
}
}
+ raise_corrupt_mpy();
+ return MP_OBJ_FROM_PTR(&mp_const_none_obj);
}
STATIC void load_bytecode_qstrs(mp_reader_t *reader, byte *ip, byte *ip_top) {
diff --git a/py/py.mk b/py/py.mk
index a69243b01..17cb79264 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -107,9 +107,9 @@ endif
# External modules written in C.
ifneq ($(USER_C_MODULES),)
-# pre-define USERMOD variables as expanded so that variables are immediate
+# pre-define USERMOD variables as expanded so that variables are immediate
# expanded as they're added to them
-SRC_USERMOD :=
+SRC_USERMOD :=
CFLAGS_USERMOD :=
LDFLAGS_USERMOD :=
$(foreach module, $(wildcard $(USER_C_MODULES)/*/micropython.mk), \
@@ -343,10 +343,23 @@ $(PY_BUILD)/qstr.o: $(HEADER_BUILD)/qstrdefs.generated.h
$(PY_BUILD)/nlr%.o: CFLAGS += -Os
# optimising gc for speed; 5ms down to 4ms on pybv2
+ifndef SUPEROPT_GC
+ SUPEROPT_GC = 1
+endif
+
+ifeq ($(SUPEROPT_GC),1)
$(PY_BUILD)/gc.o: CFLAGS += $(CSUPEROPT)
+endif
# optimising vm for speed, adds only a small amount to code size but makes a huge difference to speed (20% faster)
+ifndef SUPEROPT_VM
+ SUPEROPT_VM = 1
+endif
+
+ifeq ($(SUPEROPT_VM),1)
$(PY_BUILD)/vm.o: CFLAGS += $(CSUPEROPT)
+endif
+
# Optimizing vm.o for modern deeply pipelined CPUs with branch predictors
# may require disabling tail jump optimization. This will make sure that
# each opcode has its own dispatching jump which will improve branch
diff --git a/py/vmentrytable.h b/py/vmentrytable.h
index 615f4e2ce..a0e2d4065 100644
--- a/py/vmentrytable.h
+++ b/py/vmentrytable.h
@@ -24,7 +24,7 @@
* THE SOFTWARE.
*/
-#if __clang__
+#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winitializer-overrides"
#endif // __clang__
@@ -113,6 +113,6 @@ static const void *const entry_table[256] = {
[MP_BC_BINARY_OP_MULTI ... MP_BC_BINARY_OP_MULTI + MP_BINARY_OP_NUM_BYTECODE - 1] = &&entry_MP_BC_BINARY_OP_MULTI,
};
-#if __clang__
+#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__
diff --git a/requirements-dev.txt b/requirements-dev.txt
new file mode 100644
index 000000000..7cd491ade
--- /dev/null
+++ b/requirements-dev.txt
@@ -0,0 +1 @@
+rst2pyi>=0.3.0
diff --git a/setup.py b/setup.py
new file mode 100644
index 000000000..1e0d81da3
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,22 @@
+from datetime import datetime
+from setuptools import setup
+from pathlib import Path
+
+stub_root = Path("circuitpython-stubs")
+stubs = [p.relative_to(stub_root).as_posix() for p in stub_root.glob("*.pyi")]
+
+now = datetime.utcnow()
+version = now.strftime("%Y.%m.%d")
+
+setup(
+ name="circuitpython-stubs",
+ description="PEP 561 type stubs for CircuitPython",
+ url="https://github.com/adafruit/circuitpython",
+ maintainer="CircuitPythonistas",
+ author_email="circuitpython@adafruit.com",
+ version=version,
+ license="MIT",
+ package_data={"circuitpython-stubs": stubs},
+ packages=["circuitpython-stubs"],
+ setup_requires=["setuptools>=38.6.0"],
+)
diff --git a/shared-bindings/_pew/PewPew.c b/shared-bindings/_pew/PewPew.c
index d7ae0116d..3ff208761 100644
--- a/shared-bindings/_pew/PewPew.c
+++ b/shared-bindings/_pew/PewPew.c
@@ -96,8 +96,9 @@ STATIC mp_obj_t pewpew_make_new(const mp_obj_type_t *type, size_t n_args,
mp_raise_TypeError(translate("Row entry must be digitalio.DigitalInOut"));
}
digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(rows[i]);
- raise_error_if_deinited(
- common_hal_digitalio_digitalinout_deinited(pin));
+ if (common_hal_digitalio_digitalinout_deinited(pin)) {
+ raise_deinited_error();
+ }
}
for (size_t i = 0; i < cols_size; ++i) {
@@ -105,8 +106,9 @@ STATIC mp_obj_t pewpew_make_new(const mp_obj_type_t *type, size_t n_args,
mp_raise_TypeError(translate("Column entry must be digitalio.DigitalInOut"));
}
digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(cols[i]);
- raise_error_if_deinited(
- common_hal_digitalio_digitalinout_deinited(pin));
+ if (common_hal_digitalio_digitalinout_deinited(pin)) {
+ raise_deinited_error();
+ }
}
if (!MP_OBJ_IS_TYPE(args[ARG_buttons].u_obj,
@@ -115,8 +117,9 @@ STATIC mp_obj_t pewpew_make_new(const mp_obj_type_t *type, size_t n_args,
}
digitalio_digitalinout_obj_t *buttons = MP_OBJ_TO_PTR(
args[ARG_buttons].u_obj);
- raise_error_if_deinited(
- common_hal_digitalio_digitalinout_deinited(buttons));
+ if (common_hal_digitalio_digitalinout_deinited(buttons)) {
+ raise_deinited_error();
+ }
pew_obj_t *pew = MP_STATE_VM(pew_singleton);
if (!pew) {
diff --git a/shared-bindings/_pixelbuf/PixelBuf.c b/shared-bindings/_pixelbuf/PixelBuf.c
index 7c2766aa3..420720e62 100644
--- a/shared-bindings/_pixelbuf/PixelBuf.c
+++ b/shared-bindings/_pixelbuf/PixelBuf.c
@@ -51,7 +51,7 @@ extern const int32_t colorwheel(float pos);
//|
//| :class:`~_pixelbuf.PixelBuf` implements an RGB[W] bytearray abstraction.
//|
-//| .. class:: PixelBuf(size, buf, byteorder=BGR, bpp=3)
+//| .. class:: PixelBuf(size, buf, byteorder=BGR, brightness=0, rawbuf=None, offset=0, dotstar=False, auto_write=False, write_function=None, write_args=None)
//|
//| Create a PixelBuf object of the specified size, byteorder, and bits per pixel.
//|
@@ -66,14 +66,14 @@ extern const int32_t colorwheel(float pos);
//|
//| :param ~int size: Number of pixelsx
//| :param ~bytearray buf: Bytearray to store pixel data in
-//| :param ~_pixelbuf.ByteOrder byteorder: Byte order constant from `_pixelbuf` (also sets the bpp)
+//| :param ~_pixelbuf.ByteOrder byteorder: Byte order constant from `_pixelbuf`
//| :param ~float brightness: Brightness (0 to 1.0, default 1.0)
//| :param ~bytearray rawbuf: Bytearray to store raw pixel colors in
//| :param ~int offset: Offset from start of buffer (default 0)
//| :param ~bool dotstar: Dotstar mode (default False)
//| :param ~bool auto_write: Whether to automatically write pixels (Default False)
//| :param ~callable write_function: (optional) Callable to use to send pixels
-//| :param ~list write_args: (optional) Tuple or list of args to pass to ``write_function``. The
+//| :param ~list write_args: (optional) Tuple or list of args to pass to ``write_function``. The
//| PixelBuf instance is appended after these args.
//|
STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -95,7 +95,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
- if (mp_obj_is_subclass_fast(args[ARG_byteorder].u_obj, &pixelbuf_byteorder_type))
+ if (mp_obj_is_subclass_fast(args[ARG_byteorder].u_obj, &pixelbuf_byteorder_type))
mp_raise_TypeError_varg(translate("byteorder is not an instance of ByteOrder (got a %s)"), mp_obj_get_type_str(args[ARG_byteorder].u_obj));
pixelbuf_byteorder_obj_t *byteorder = (args[ARG_byteorder].u_obj == mp_const_none) ? MP_OBJ_FROM_PTR(&byteorder_BGR) : args[ARG_byteorder].u_obj;
@@ -122,7 +122,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a
if (!MP_OBJ_IS_TYPE(args[ARG_write_args].u_obj, &mp_type_list) &&
!MP_OBJ_IS_TYPE(args[ARG_write_args].u_obj, &mp_type_tuple) &&
- args[ARG_write_args].u_obj != mp_const_none)
+ args[ARG_write_args].u_obj != mp_const_none)
{
mp_raise_ValueError(translate("write_args must be a list, tuple, or None"));
}
@@ -186,8 +186,8 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a
else if (self->brightness > 1)
self->brightness = 1;
}
-
- if (self->dotstar_mode) {
+
+ if (self->dotstar_mode) {
// Initialize the buffer with the dotstar start bytes.
// Header and end must be setup by caller
for (uint i = 0; i < self->pixels * 4; i += 4) {
@@ -197,7 +197,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a
}
}
}
-
+
return MP_OBJ_FROM_PTR(self);
}
@@ -227,7 +227,7 @@ const mp_obj_property_t pixelbuf_pixelbuf_bpp_obj = {
//| setting this value causes a recomputation of the values in buf.
//| If only a buf was provided, then the brightness only applies to
//| future pixel changes.
-//| In DotStar mode
+//| In DotStar mode
//|
STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_brightness(mp_obj_t self_in) {
mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type));
@@ -266,7 +266,7 @@ void pixelbuf_recalculate_brightness(pixelbuf_pixelbuf_obj_t *self) {
// Compensate for shifted buffer (bpp=3 dotstar)
for (uint i = 0; i < self->bytes; i++) {
// Don't adjust per-pixel luminance bytes in dotstar mode
- if (!self->dotstar_mode || (i % 4 != 0))
+ if (!self->dotstar_mode || (i % 4 != 0))
buf[i] = rawbuf[i] * self->brightness;
}
}
@@ -367,11 +367,13 @@ void call_write_function(pixelbuf_pixelbuf_obj_t *self) {
}
}
-
-
-//| .. method:: []
+//| .. method:: __getitem__(index)
+//|
+//| Returns the pixel value at the given index.
//|
-//| Get or set pixels. Supports individual pixels and slices.
+//| .. method:: __setitem__(index, value)
+//|
+//| Sets the pixel value at the given index.
//|
STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) {
mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type));
@@ -380,7 +382,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
// delete item
// slice deletion
return MP_OBJ_NULL; // op not supported
- }
+ }
pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (0) {
@@ -390,7 +392,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
if (!mp_seq_get_fast_slice_indexes(self->bytes, index_in, &slice))
mp_raise_NotImplementedError(translate("Only slices with step=1 (aka None) are supported"));
- if ((slice.stop * self->pixel_step) > self->bytes)
+ if ((slice.stop * self->pixel_step) > self->bytes)
mp_raise_IndexError(translate("Range out of bounds"));
if (value == MP_OBJ_SENTINEL) { // Get
@@ -422,8 +424,8 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
for (size_t i = slice.start; i < slice.stop; i++) {
mp_obj_t *item = src_objs[i-slice.start];
if (MP_OBJ_IS_TYPE(value, &mp_type_list) || MP_OBJ_IS_TYPE(value, &mp_type_tuple) || MP_OBJ_IS_INT(value)) {
- pixelbuf_set_pixel(self->buf + (i * self->pixel_step),
- self->two_buffers ? self->rawbuf + (i * self->pixel_step) : NULL,
+ pixelbuf_set_pixel(self->buf + (i * self->pixel_step),
+ self->two_buffers ? self->rawbuf + (i * self->pixel_step) : NULL,
self->brightness, item, &self->byteorder, self->dotstar_mode);
}
}
@@ -438,14 +440,14 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
} else { // Single index rather than slice.
size_t index = mp_get_index(self->base.type, self->pixels, index_in, false);
size_t offset = (index * self->pixel_step);
- if (offset > self->bytes)
+ if (offset > self->bytes)
mp_raise_IndexError(translate("Pixel beyond bounds of buffer"));
if (value == MP_OBJ_SENTINEL) { // Get
uint8_t *pixelstart = (uint8_t *)(self->two_buffers ? self->rawbuf : self->buf) + offset;
return pixelbuf_get_pixel(pixelstart, &self->byteorder, self->dotstar_mode);
} else { // Store
- pixelbuf_set_pixel(self->buf + offset, self->two_buffers ? self->rawbuf + offset : NULL,
+ pixelbuf_set_pixel(self->buf + offset, self->two_buffers ? self->rawbuf + offset : NULL,
self->brightness, value, &self->byteorder, self->dotstar_mode);
if (self->auto_write)
call_write_function(self);
diff --git a/shared-bindings/_pixelbuf/__init__.c b/shared-bindings/_pixelbuf/__init__.c
index 31defc7fb..48b9f1cef 100644
--- a/shared-bindings/_pixelbuf/__init__.c
+++ b/shared-bindings/_pixelbuf/__init__.c
@@ -53,7 +53,7 @@
//|
//| PixelBuf
-//| .. class:: ByteOrder
+//| .. class:: ByteOrder()
//|
//| Classes representing byteorders for circuitpython
@@ -169,34 +169,34 @@ const int32_t colorwheel(float pos) {
/// RGB
-//| .. class:: RGB
+//| .. data:: RGB
//|
//| * **order** Red, Green, Blue
//| * **bpp** 3
PIXELBUF_BYTEORDER(RGB, 3, 0, 1, 2, 3, false, false)
-//| .. class:: RBG
+//| .. data:: RBG
//|
//| * **order** Red, Blue, Green
//| * **bpp** 3
PIXELBUF_BYTEORDER(RBG, 3, 0, 2, 1, 3, false, false)
-//| .. class:: GRB
+//| .. data:: GRB
//|
//| * **order** Green, Red, Blue
//| * **bpp** 3
//|
//| Commonly used by NeoPixel.
PIXELBUF_BYTEORDER(GRB, 3, 1, 0, 2, 3, false, false)
-//| .. class:: GBR
+//| .. data:: GBR
//|
//| * **order** Green, Blue, Red
//| * **bpp** 3
PIXELBUF_BYTEORDER(GBR, 3, 1, 2, 0, 3, false, false)
-//| .. class:: BRG
+//| .. data:: BRG
//|
//| * **order** Blue, Red, Green
//| * **bpp** 3
PIXELBUF_BYTEORDER(BRG, 3, 2, 0, 1, 3, false, false)
-//| .. class:: BGR
+//| .. data:: BGR
//|
//| * **order** Blue, Green, Red
//| * **bpp** 3
@@ -205,19 +205,19 @@ PIXELBUF_BYTEORDER(BRG, 3, 2, 0, 1, 3, false, false)
PIXELBUF_BYTEORDER(BGR, 3, 2, 1, 0, 3, false, false)
// RGBW
-//| .. class:: RGBW
+//| .. data:: RGBW
//|
//| * **order** Red, Green, Blue, White
//| * **bpp** 4
//| * **has_white** True
PIXELBUF_BYTEORDER(RGBW, 4, 0, 1, 2, 3, true, false)
-//| .. class:: RBGW
+//| .. data:: RBGW
//|
//| * **order** Red, Blue, Green, White
//| * **bpp** 4
//| * **has_white** True
PIXELBUF_BYTEORDER(RBGW, 4, 0, 2, 1, 3, true, false)
-//| .. class:: GRBW
+//| .. data:: GRBW
//|
//| * **order** Green, Red, Blue, White
//| * **bpp** 4
@@ -225,19 +225,19 @@ PIXELBUF_BYTEORDER(RBGW, 4, 0, 2, 1, 3, true, false)
//|
//| Commonly used by RGBW NeoPixels.
PIXELBUF_BYTEORDER(GRBW, 4, 1, 0, 2, 3, true, false)
-//| .. class:: GBRW
+//| .. data:: GBRW
//|
//| * **order** Green, Blue, Red, White
//| * **bpp** 4
//| * **has_white** True
PIXELBUF_BYTEORDER(GBRW, 4, 1, 2, 0, 3, true, false)
-//| .. class:: BRGW
+//| .. data:: BRGW
//|
//| * **order** Blue, Red, Green, White
//| * **bpp** 4
//| * **has_white** True
PIXELBUF_BYTEORDER(BRGW, 4, 2, 0, 1, 3, true, false)
-//| .. class:: BGRW
+//| .. data:: BGRW
//|
//| * **order** Blue, Green, Red, White
//| * **bpp** 4
@@ -248,37 +248,37 @@ PIXELBUF_BYTEORDER(BGRW, 4, 2, 1, 0, 3, true, false)
// Luminosity chosen because the luminosity of a Dotstar at full bright
// burns the eyes like looking at the Sun.
// https://www.thesaurus.com/browse/luminosity?s=t
-//| .. class:: LRGB
+//| .. data:: LRGB
//|
//| * **order** *Luminosity*, Red, Green, Blue
//| * **bpp** 4
//| * **has_luminosity** True
PIXELBUF_BYTEORDER(LRGB, 4, 1, 2, 3, 0, false, true)
-//| .. class:: LRBG
+//| .. data:: LRBG
//|
//| * **order** *Luminosity*, Red, Blue, Green
//| * **bpp** 4
//| * **has_luminosity** True
PIXELBUF_BYTEORDER(LRBG, 4, 1, 3, 2, 0, false, true)
-//| .. class:: LGRB
+//| .. data:: LGRB
//|
//| * **order** *Luminosity*, Green, Red, Blue
//| * **bpp** 4
//| * **has_luminosity** True
PIXELBUF_BYTEORDER(LGRB, 4, 2, 1, 3, 0, false, true)
-//| .. class:: LGBR
+//| .. data:: LGBR
//|
//| * **order** *Luminosity*, Green, Blue, Red
//| * **bpp** 4
//| * **has_luminosity** True
PIXELBUF_BYTEORDER(LGBR, 4, 2, 3, 1, 0, false, true)
-//| .. class:: LBRG
+//| .. data:: LBRG
//|
//| * **order** *Luminosity*, Blue, Red, Green
//| * **bpp** 4
//| * **has_luminosity** True
PIXELBUF_BYTEORDER(LBRG, 4, 3, 1, 2, 0, false, true)
-//| .. class:: LBGR
+//| .. data:: LBGR
//|
//| * **order** *Luminosity*, Blue, Green, Red
//| * **bpp** 4
diff --git a/shared-bindings/_stage/__init__.c b/shared-bindings/_stage/__init__.c
index 03775b1de..485fa80c5 100644
--- a/shared-bindings/_stage/__init__.c
+++ b/shared-bindings/_stage/__init__.c
@@ -50,7 +50,7 @@
//| Layer
//| Text
//|
-//| .. function:: render(x0, y0, x1, y1, layers, buffer, display)
+//| .. function:: render(x0, y0, x1, y1, layers, buffer, display[, scale])
//|
//| Render and send to the display a fragment of the screen.
//|
@@ -61,6 +61,7 @@
//| :param list layers: A list of the :py:class:`~_stage.Layer` objects.
//| :param bytearray buffer: A buffer to use for rendering.
//| :param ~displayio.Display display: The display to use.
+//| :param int scale: How many times should the image be scaled up.
//|
//| There are also no sanity checks, outside of the basic overflow
//| checking. The caller is responsible for making the passed parameters
@@ -89,19 +90,31 @@ STATIC mp_obj_t stage_render(size_t n_args, const mp_obj_t *args) {
mp_raise_TypeError(translate("argument num/types mismatch"));
}
displayio_display_obj_t *display = MP_OBJ_TO_PTR(native_display);
+ uint8_t scale = 1;
+ if (n_args >= 8) {
+ scale = mp_obj_get_int(args[7]);
+ }
while (!displayio_display_begin_transaction(display)) {
#ifdef MICROPY_VM_HOOK_LOOP
MICROPY_VM_HOOK_LOOP ;
#endif
}
- displayio_display_set_region_to_update(display, x0, y0, x1, y1);
- render_stage(x0, y0, x1, y1, layers, layers_size, buffer, buffer_size, display);
+ displayio_area_t area;
+ area.x1 = x0;
+ area.y1 = y0;
+ area.x2 = x1;
+ area.y2 = y1;
+ displayio_display_set_region_to_update(display, &area);
+
+ display->send(display->bus, true, &display->write_ram_command, 1);
+ render_stage(x0, y0, x1, y1, layers, layers_size, buffer, buffer_size,
+ display, scale);
displayio_display_end_transaction(display);
return mp_const_none;
}
-MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stage_render_obj, 7, 7, stage_render);
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stage_render_obj, 7, 8, stage_render);
STATIC const mp_rom_map_elem_t stage_module_globals_table[] = {
diff --git a/shared-bindings/analogio/AnalogIn.c b/shared-bindings/analogio/AnalogIn.c
index 116f82a03..a8bbbf59a 100644
--- a/shared-bindings/analogio/AnalogIn.c
+++ b/shared-bindings/analogio/AnalogIn.c
@@ -86,6 +86,11 @@ STATIC mp_obj_t analogio_analogin_deinit(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_deinit_obj, analogio_analogin_deinit);
+STATIC void check_for_deinit(analogio_analogin_obj_t *self) {
+ if (common_hal_analogio_analogin_deinited(self)) {
+ raise_deinited_error();
+ }
+}
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -113,7 +118,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogin___exit___obj, 4, 4,
//|
STATIC mp_obj_t analogio_analogin_obj_get_value(mp_obj_t self_in) {
analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_analogio_analogin_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_analogio_analogin_get_value(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_get_value_obj, analogio_analogin_obj_get_value);
@@ -132,7 +137,7 @@ const mp_obj_property_t analogio_analogin_value_obj = {
//|
STATIC mp_obj_t analogio_analogin_obj_get_reference_voltage(mp_obj_t self_in) {
analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_analogio_analogin_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_float(common_hal_analogio_analogin_get_reference_voltage(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_get_reference_voltage_obj,
diff --git a/shared-bindings/analogio/AnalogOut.c b/shared-bindings/analogio/AnalogOut.c
index dcbd7ecfb..0816da465 100644
--- a/shared-bindings/analogio/AnalogOut.c
+++ b/shared-bindings/analogio/AnalogOut.c
@@ -112,7 +112,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogout___exit___obj, 4, 4
//| resolution, the value is 16-bit.
STATIC mp_obj_t analogio_analogout_obj_set_value(mp_obj_t self_in, mp_obj_t value) {
analogio_analogout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_analogio_analogout_deinited(self));
+ if (common_hal_analogio_analogout_deinited(self)) {
+ raise_deinited_error();
+ }
uint32_t v = mp_obj_get_int(value);
if (v >= (1 << 16)) {
mp_raise_ValueError(translate("AnalogOut is only 16 bits. Value must be less than 65536."));
diff --git a/shared-bindings/audiobusio/I2SOut.c b/shared-bindings/audiobusio/I2SOut.c
index 48424d073..9bce9c760 100644
--- a/shared-bindings/audiobusio/I2SOut.c
+++ b/shared-bindings/audiobusio/I2SOut.c
@@ -56,7 +56,7 @@
//| using `UDA1334 Breakout <https://www.adafruit.com/product/3678>`_::
//|
//| import audiobusio
-//| import audioio
+//| import audiocore
//| import board
//| import array
//| import time
@@ -68,7 +68,7 @@
//| for i in range(length):
//| sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15)
//|
-//| sine_wave = audiobusio.RawSample(sine_wave, sample_rate=8000)
+//| sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000)
//| i2s = audiobusio.I2SOut(board.D1, board.D0, board.D9)
//| i2s.play(sine_wave, loop=True)
//| time.sleep(1)
@@ -78,12 +78,13 @@
//|
//| import board
//| import audioio
+//| import audiocore
//| import audiobusio
//| import digitalio
//|
//|
//| f = open("cplay-5.1-16bit-16khz.wav", "rb")
-//| wav = audioio.WaveFile(f)
+//| wav = audiocore.WaveFile(f)
//|
//| a = audiobusio.I2SOut(board.D1, board.D0, board.D9)
//|
@@ -134,6 +135,11 @@ STATIC mp_obj_t audiobusio_i2sout_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_deinit_obj, audiobusio_i2sout_deinit);
+STATIC void check_for_deinit(audiobusio_i2sout_obj_t *self) {
+ if (common_hal_audiobusio_i2sout_deinited(self)) {
+ raise_deinited_error();
+ }
+}
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -158,7 +164,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_i2sout___exit___obj, 4, 4,
//| Plays the sample once when loop=False and continuously when loop=True.
//| Does not block. Use `playing` to block.
//|
-//| Sample must be an `audioio.WaveFile` or `audioio.RawSample`.
+//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiocore.Mixer`.
//|
//| The sample itself should consist of 8 bit or 16 bit samples.
//|
@@ -169,7 +175,7 @@ STATIC mp_obj_t audiobusio_i2sout_obj_play(size_t n_args, const mp_obj_t *pos_ar
{ MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
};
audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self));
+ check_for_deinit(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -186,7 +192,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audiobusio_i2sout_play_obj, 1, audiobusio_i2sout_obj_
//|
STATIC mp_obj_t audiobusio_i2sout_obj_stop(mp_obj_t self_in) {
audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self));
+ check_for_deinit(self);
common_hal_audiobusio_i2sout_stop(self);
return mp_const_none;
}
@@ -198,7 +204,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_stop_obj, audiobusio_i2sout_obj_stop
//|
STATIC mp_obj_t audiobusio_i2sout_obj_get_playing(mp_obj_t self_in) {
audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_audiobusio_i2sout_get_playing(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_get_playing_obj, audiobusio_i2sout_obj_get_playing);
@@ -216,7 +222,7 @@ const mp_obj_property_t audiobusio_i2sout_playing_obj = {
//|
STATIC mp_obj_t audiobusio_i2sout_obj_pause(mp_obj_t self_in) {
audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self));
+ check_for_deinit(self);
if (!common_hal_audiobusio_i2sout_get_playing(self)) {
mp_raise_RuntimeError(translate("Not playing"));
@@ -232,7 +238,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_pause_obj, audiobusio_i2sout_obj_pau
//|
STATIC mp_obj_t audiobusio_i2sout_obj_resume(mp_obj_t self_in) {
audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self));
+ check_for_deinit(self);
if (common_hal_audiobusio_i2sout_get_paused(self)) {
common_hal_audiobusio_i2sout_resume(self);
@@ -248,7 +254,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_resume_obj, audiobusio_i2sout_obj_re
//|
STATIC mp_obj_t audiobusio_i2sout_obj_get_paused(mp_obj_t self_in) {
audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_audiobusio_i2sout_get_paused(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_get_paused_obj, audiobusio_i2sout_obj_get_paused);
diff --git a/shared-bindings/audiobusio/PDMIn.c b/shared-bindings/audiobusio/PDMIn.c
index 5dca3fa59..0c92c2478 100644
--- a/shared-bindings/audiobusio/PDMIn.c
+++ b/shared-bindings/audiobusio/PDMIn.c
@@ -43,7 +43,7 @@
//|
//| PDMIn can be used to record an input audio signal on a given set of pins.
//|
-//| .. class:: PDMIn(clock_pin, data_pin, \*, sample_rate=16000, bit_depth=8, mono=True, oversample=64, startup_delay=0.11)
+//| .. class:: PDMIn(clock_pin, data_pin, *, sample_rate=16000, bit_depth=8, mono=True, oversample=64, startup_delay=0.11)
//|
//| Create a PDMIn object associated with the given pins. This allows you to
//| record audio signals from the given pins. Individual ports may put further
@@ -156,6 +156,11 @@ STATIC mp_obj_t audiobusio_pdmin_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_pdmin_deinit_obj, audiobusio_pdmin_deinit);
+STATIC void check_for_deinit(audiobusio_pdmin_obj_t *self) {
+ if (common_hal_audiobusio_pdmin_deinited(self)) {
+ raise_deinited_error();
+ }
+}
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -188,7 +193,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_pdmin___exit___obj, 4, 4,
//|
STATIC mp_obj_t audiobusio_pdmin_obj_record(mp_obj_t self_obj, mp_obj_t destination, mp_obj_t destination_length) {
audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_obj);
- raise_error_if_deinited(common_hal_audiobusio_pdmin_deinited(self));
+ check_for_deinit(self);
if (!MP_OBJ_IS_SMALL_INT(destination_length) || MP_OBJ_SMALL_INT_VALUE(destination_length) < 0) {
mp_raise_TypeError(translate("destination_length must be an int >= 0"));
}
@@ -223,7 +228,7 @@ MP_DEFINE_CONST_FUN_OBJ_3(audiobusio_pdmin_record_obj, audiobusio_pdmin_obj_reco
//|
STATIC mp_obj_t audiobusio_pdmin_obj_get_sample_rate(mp_obj_t self_in) {
audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audiobusio_pdmin_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_audiobusio_pdmin_get_sample_rate(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_pdmin_get_sample_rate_obj, audiobusio_pdmin_obj_get_sample_rate);
diff --git a/shared-bindings/audioio/Mixer.c b/shared-bindings/audiocore/Mixer.c
index 43ef2c524..9ab720434 100644
--- a/shared-bindings/audioio/Mixer.c
+++ b/shared-bindings/audiocore/Mixer.c
@@ -23,7 +23,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "shared-bindings/audioio/Mixer.h"
+#include "shared-bindings/audiocore/Mixer.h"
#include <stdint.h>
@@ -32,11 +32,11 @@
#include "py/objproperty.h"
#include "py/runtime.h"
#include "shared-bindings/microcontroller/Pin.h"
-#include "shared-bindings/audioio/RawSample.h"
+#include "shared-bindings/audiocore/RawSample.h"
#include "shared-bindings/util.h"
#include "supervisor/shared/translate.h"
-//| .. currentmodule:: audioio
+//| .. currentmodule:: audiocore
//|
//| :class:`Mixer` -- Mixes one or more audio samples together
//| ===========================================================
@@ -54,15 +54,16 @@
//|
//| import board
//| import audioio
+//| import audiocore
//| import digitalio
//|
//| # Required for CircuitPlayground Express
//| speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
//| speaker_enable.switch_to_output(value=True)
//|
-//| music = audioio.WaveFile(open("cplay-5.1-16bit-16khz.wav", "rb"))
-//| drum = audioio.WaveFile(open("drum.wav", "rb"))
-//| mixer = audioio.Mixer(voice_count=2, sample_rate=16000, channel_count=1, bits_per_sample=16, samples_signed=True)
+//| music = audiocore.WaveFile(open("cplay-5.1-16bit-16khz.wav", "rb"))
+//| drum = audiocore.WaveFile(open("drum.wav", "rb"))
+//| mixer = audiocore.Mixer(voice_count=2, sample_rate=16000, channel_count=1, bits_per_sample=16, samples_signed=True)
//| a = audioio.AudioOut(board.A0)
//|
//| print("playing")
@@ -121,6 +122,12 @@ STATIC mp_obj_t audioio_mixer_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_deinit_obj, audioio_mixer_deinit);
+STATIC void check_for_deinit(audioio_mixer_obj_t *self) {
+ if (common_hal_audioio_mixer_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -145,7 +152,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_mixer___exit___obj, 4, 4, aud
//| Plays the sample once when loop=False and continuously when loop=True.
//| Does not block. Use `playing` to block.
//|
-//| Sample must be an `audioio.WaveFile`, `audioio.Mixer` or `audioio.RawSample`.
+//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiocore.Mixer`.
//|
//| The sample must match the Mixer's encoding settings given in the constructor.
//|
@@ -157,7 +164,7 @@ STATIC mp_obj_t audioio_mixer_obj_play(size_t n_args, const mp_obj_t *pos_args,
{ MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
};
audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_audioio_mixer_deinited(self));
+ check_for_deinit(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -178,7 +185,7 @@ STATIC mp_obj_t audioio_mixer_obj_stop_voice(size_t n_args, const mp_obj_t *pos_
{ MP_QSTR_voice, MP_ARG_INT, {.u_int = 0} },
};
audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_audioio_mixer_deinited(self));
+ check_for_deinit(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -193,7 +200,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audioio_mixer_stop_voice_obj, 1, audioio_mixer_obj_st
//|
STATIC mp_obj_t audioio_mixer_obj_get_playing(mp_obj_t self_in) {
audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_mixer_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_audioio_mixer_get_playing(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_get_playing_obj, audioio_mixer_obj_get_playing);
@@ -211,7 +218,7 @@ const mp_obj_property_t audioio_mixer_playing_obj = {
//|
STATIC mp_obj_t audioio_mixer_obj_get_sample_rate(mp_obj_t self_in) {
audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_mixer_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_mixer_get_sample_rate(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_get_sample_rate_obj, audioio_mixer_obj_get_sample_rate);
diff --git a/shared-bindings/audioio/Mixer.h b/shared-bindings/audiocore/Mixer.h
index 832072b8f..ef12f9a70 100644
--- a/shared-bindings/audioio/Mixer.h
+++ b/shared-bindings/audiocore/Mixer.h
@@ -28,8 +28,8 @@
#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MIXER_H
#include "common-hal/microcontroller/Pin.h"
-#include "shared-module/audioio/Mixer.h"
-#include "shared-bindings/audioio/RawSample.h"
+#include "shared-module/audiocore/Mixer.h"
+#include "shared-bindings/audiocore/RawSample.h"
extern const mp_obj_type_t audioio_mixer_type;
diff --git a/shared-bindings/audioio/RawSample.c b/shared-bindings/audiocore/RawSample.c
index 7fc896449..07f8c683f 100644
--- a/shared-bindings/audioio/RawSample.c
+++ b/shared-bindings/audiocore/RawSample.c
@@ -31,11 +31,11 @@
#include "py/objproperty.h"
#include "py/runtime.h"
#include "shared-bindings/microcontroller/Pin.h"
-#include "shared-bindings/audioio/AudioOut.h"
#include "shared-bindings/util.h"
+#include "shared-bindings/audiocore/RawSample.h"
#include "supervisor/shared/translate.h"
-//| .. currentmodule:: audioio
+//| .. currentmodule:: audiocore
//|
//| :class:`RawSample` -- A raw audio sample buffer
//| ========================================================
@@ -55,6 +55,7 @@
//|
//| Simple 8ksps 440 Hz sin wave::
//|
+//| import audiocore
//| import audioio
//| import board
//| import array
@@ -68,7 +69,7 @@
//| sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15))
//|
//| dac = audioio.AudioOut(board.SPEAKER)
-//| sine_wave = audioio.RawSample(sine_wave)
+//| sine_wave = audiocore.RawSample(sine_wave)
//| dac.play(sine_wave, loop=True)
//| time.sleep(1)
//| dac.stop()
@@ -115,6 +116,12 @@ STATIC mp_obj_t audioio_rawsample_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_rawsample_deinit_obj, audioio_rawsample_deinit);
+STATIC void check_for_deinit(audioio_rawsample_obj_t *self) {
+ if (common_hal_audioio_rawsample_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -142,14 +149,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_rawsample___exit___obj, 4, 4,
//|
STATIC mp_obj_t audioio_rawsample_obj_get_sample_rate(mp_obj_t self_in) {
audioio_rawsample_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_rawsample_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_rawsample_get_sample_rate(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audioio_rawsample_get_sample_rate_obj, audioio_rawsample_obj_get_sample_rate);
STATIC mp_obj_t audioio_rawsample_obj_set_sample_rate(mp_obj_t self_in, mp_obj_t sample_rate) {
audioio_rawsample_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_rawsample_deinited(self));
+ check_for_deinit(self);
common_hal_audioio_rawsample_set_sample_rate(self, mp_obj_get_int(sample_rate));
return mp_const_none;
}
diff --git a/shared-bindings/audioio/RawSample.h b/shared-bindings/audiocore/RawSample.h
index 0d764b77c..b02778cad 100644
--- a/shared-bindings/audioio/RawSample.h
+++ b/shared-bindings/audiocore/RawSample.h
@@ -27,9 +27,8 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_RAWSAMPLE_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_RAWSAMPLE_H
-#include "common-hal/audioio/AudioOut.h"
#include "common-hal/microcontroller/Pin.h"
-#include "shared-module/audioio/RawSample.h"
+#include "shared-module/audiocore/RawSample.h"
extern const mp_obj_type_t audioio_rawsample_type;
diff --git a/shared-bindings/audioio/WaveFile.c b/shared-bindings/audiocore/WaveFile.c
index cddeef769..edb190d3a 100644
--- a/shared-bindings/audioio/WaveFile.c
+++ b/shared-bindings/audiocore/WaveFile.c
@@ -29,11 +29,11 @@
#include "lib/utils/context_manager_helpers.h"
#include "py/objproperty.h"
#include "py/runtime.h"
-#include "shared-bindings/audioio/WaveFile.h"
+#include "shared-bindings/audiocore/WaveFile.h"
#include "shared-bindings/util.h"
#include "supervisor/shared/translate.h"
-//| .. currentmodule:: audioio
+//| .. currentmodule:: audiocore
//|
//| :class:`WaveFile` -- Load a wave file for audio playback
//| ========================================================
@@ -41,15 +41,16 @@
//| A .wav file prepped for audio playback. Only mono and stereo files are supported. Samples must
//| be 8 bit unsigned or 16 bit signed.
//|
-//| .. class:: WaveFile(filename)
+//| .. class:: WaveFile(file)
//|
//| Load a .wav file for playback with `audioio.AudioOut` or `audiobusio.I2SOut`.
//|
-//| :param bytes-like file: Already opened wave file
+//| :param typing.BinaryIO file: Already opened wave file
//|
//| Playing a wave file from flash::
//|
//| import board
+//| import audiocore
//| import audioio
//| import digitalio
//|
@@ -58,7 +59,7 @@
//| speaker_enable.switch_to_output(value=True)
//|
//| data = open("cplay-5.1-16bit-16khz.wav", "rb")
-//| wav = audioio.WaveFile(data)
+//| wav = audiocore.WaveFile(data)
//| a = audioio.AudioOut(board.A0)
//|
//| print("playing")
@@ -92,6 +93,12 @@ STATIC mp_obj_t audioio_wavefile_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_deinit_obj, audioio_wavefile_deinit);
+STATIC void check_for_deinit(audioio_wavefile_obj_t *self) {
+ if (common_hal_audioio_wavefile_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -118,14 +125,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_wavefile___exit___obj, 4, 4,
//|
STATIC mp_obj_t audioio_wavefile_obj_get_sample_rate(mp_obj_t self_in) {
audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_wavefile_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_sample_rate(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_sample_rate_obj, audioio_wavefile_obj_get_sample_rate);
STATIC mp_obj_t audioio_wavefile_obj_set_sample_rate(mp_obj_t self_in, mp_obj_t sample_rate) {
audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_wavefile_deinited(self));
+ check_for_deinit(self);
common_hal_audioio_wavefile_set_sample_rate(self, mp_obj_get_int(sample_rate));
return mp_const_none;
}
@@ -144,7 +151,7 @@ const mp_obj_property_t audioio_wavefile_sample_rate_obj = {
//|
STATIC mp_obj_t audioio_wavefile_obj_get_bits_per_sample(mp_obj_t self_in) {
audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_wavefile_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_bits_per_sample(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_bits_per_sample_obj, audioio_wavefile_obj_get_bits_per_sample);
@@ -162,7 +169,7 @@ const mp_obj_property_t audioio_wavefile_bits_per_sample_obj = {
//|
STATIC mp_obj_t audioio_wavefile_obj_get_channel_count(mp_obj_t self_in) {
audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_wavefile_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_channel_count(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_channel_count_obj, audioio_wavefile_obj_get_channel_count);
diff --git a/shared-bindings/audioio/WaveFile.h b/shared-bindings/audiocore/WaveFile.h
index 62a4200dc..d2572318b 100644
--- a/shared-bindings/audioio/WaveFile.h
+++ b/shared-bindings/audiocore/WaveFile.h
@@ -27,10 +27,11 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_WAVEFILE_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_WAVEFILE_H
-#include "common-hal/audioio/AudioOut.h"
-#include "common-hal/microcontroller/Pin.h"
+#include "py/obj.h"
#include "extmod/vfs_fat.h"
+#include "shared-module/audiocore/WaveFile.h"
+
extern const mp_obj_type_t audioio_wavefile_type;
void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self,
diff --git a/shared-bindings/audiocore/__init__.c b/shared-bindings/audiocore/__init__.c
new file mode 100644
index 000000000..c64759d4f
--- /dev/null
+++ b/shared-bindings/audiocore/__init__.c
@@ -0,0 +1,69 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdint.h>
+
+#include "py/obj.h"
+#include "py/runtime.h"
+
+#include "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/audiocore/__init__.h"
+#include "shared-bindings/audiocore/Mixer.h"
+#include "shared-bindings/audiocore/RawSample.h"
+#include "shared-bindings/audiocore/WaveFile.h"
+
+//| :mod:`audiocore` --- Support for audio samples and mixer
+//| ========================================================
+//|
+//| .. module:: audiocore
+//| :synopsis: Support for audio samples and mixer
+//| :platform: SAMD21
+//|
+//| The `audiocore` module contains core classes for audio IO
+//|
+//| Libraries
+//|
+//| .. toctree::
+//| :maxdepth: 3
+//|
+//| Mixer
+//| RawSample
+//| WaveFile
+//|
+
+STATIC const mp_rom_map_elem_t audiocore_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiocore) },
+ { MP_ROM_QSTR(MP_QSTR_Mixer), MP_ROM_PTR(&audioio_mixer_type) },
+ { MP_ROM_QSTR(MP_QSTR_RawSample), MP_ROM_PTR(&audioio_rawsample_type) },
+ { MP_ROM_QSTR(MP_QSTR_WaveFile), MP_ROM_PTR(&audioio_wavefile_type) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(audiocore_module_globals, audiocore_module_globals_table);
+
+const mp_obj_module_t audiocore_module = {
+ .base = { &mp_type_module },
+ .globals = (mp_obj_dict_t*)&audiocore_module_globals,
+};
diff --git a/shared-bindings/bleio/AdvertisementData.h b/shared-bindings/audiocore/__init__.h
index 05b5a2c8d..02437cd13 100644
--- a/shared-bindings/bleio/AdvertisementData.h
+++ b/shared-bindings/audiocore/__init__.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,11 +24,11 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADVERTISEMENTDATA_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADVERTISEMENTDATA_H
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOCORE___INIT___H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOCORE___INIT___H
#include "py/obj.h"
-extern const mp_obj_type_t bleio_advertisementdata_type;
+// Nothing now.
-#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADVERTISEMENTDATA_H
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOCORE___INIT___H
diff --git a/shared-bindings/audioio/AudioOut.c b/shared-bindings/audioio/AudioOut.c
index 9cb98d1f8..af2fce48e 100644
--- a/shared-bindings/audioio/AudioOut.c
+++ b/shared-bindings/audioio/AudioOut.c
@@ -32,7 +32,7 @@
#include "py/runtime.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/audioio/AudioOut.h"
-#include "shared-bindings/audioio/RawSample.h"
+#include "shared-bindings/audiocore/RawSample.h"
#include "shared-bindings/util.h"
#include "supervisor/shared/translate.h"
@@ -55,6 +55,7 @@
//|
//| Simple 8ksps 440 Hz sin wave::
//|
+//| import audiocore
//| import audioio
//| import board
//| import array
@@ -68,7 +69,7 @@
//| sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15)
//|
//| dac = audioio.AudioOut(board.SPEAKER)
-//| sine_wave = audioio.RawSample(sine_wave, sample_rate=8000)
+//| sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000)
//| dac.play(sine_wave, loop=True)
//| time.sleep(1)
//| dac.stop()
@@ -84,7 +85,7 @@
//| speaker_enable.switch_to_output(value=True)
//|
//| data = open("cplay-5.1-16bit-16khz.wav", "rb")
-//| wav = audioio.WaveFile(data)
+//| wav = audiocore.WaveFile(data)
//| a = audioio.AudioOut(board.A0)
//|
//| print("playing")
@@ -133,6 +134,11 @@ STATIC mp_obj_t audioio_audioout_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_deinit_obj, audioio_audioout_deinit);
+STATIC void check_for_deinit(audioio_audioout_obj_t *self) {
+ if (common_hal_audioio_audioout_deinited(self)) {
+ raise_deinited_error();
+ }
+}
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -157,7 +163,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_audioout___exit___obj, 4, 4,
//| Plays the sample once when loop=False and continuously when loop=True.
//| Does not block. Use `playing` to block.
//|
-//| Sample must be an `audioio.WaveFile` or `audioio.RawSample`.
+//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiocore.Mixer`.
//|
//| The sample itself should consist of 16 bit samples. Microcontrollers with a lower output
//| resolution will use the highest order bits to output. For example, the SAMD21 has a 10 bit
@@ -170,7 +176,7 @@ STATIC mp_obj_t audioio_audioout_obj_play(size_t n_args, const mp_obj_t *pos_arg
{ MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
};
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_audioio_audioout_deinited(self));
+ check_for_deinit(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -187,7 +193,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audioio_audioout_play_obj, 1, audioio_audioout_obj_pl
//|
STATIC mp_obj_t audioio_audioout_obj_stop(mp_obj_t self_in) {
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_audioout_deinited(self));
+ check_for_deinit(self);
common_hal_audioio_audioout_stop(self);
return mp_const_none;
}
@@ -199,7 +205,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_stop_obj, audioio_audioout_obj_stop);
//|
STATIC mp_obj_t audioio_audioout_obj_get_playing(mp_obj_t self_in) {
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_audioout_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_audioio_audioout_get_playing(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_get_playing_obj, audioio_audioout_obj_get_playing);
@@ -217,7 +223,7 @@ const mp_obj_property_t audioio_audioout_playing_obj = {
//|
STATIC mp_obj_t audioio_audioout_obj_pause(mp_obj_t self_in) {
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_audioout_deinited(self));
+ check_for_deinit(self);
if (!common_hal_audioio_audioout_get_playing(self)) {
mp_raise_RuntimeError(translate("Not playing"));
@@ -233,7 +239,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_pause_obj, audioio_audioout_obj_pause
//|
STATIC mp_obj_t audioio_audioout_obj_resume(mp_obj_t self_in) {
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_audioout_deinited(self));
+ check_for_deinit(self);
if (common_hal_audioio_audioout_get_paused(self)) {
common_hal_audioio_audioout_resume(self);
@@ -249,7 +255,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_resume_obj, audioio_audioout_obj_resu
//|
STATIC mp_obj_t audioio_audioout_obj_get_paused(mp_obj_t self_in) {
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_audioout_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_audioio_audioout_get_paused(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_get_paused_obj, audioio_audioout_obj_get_paused);
diff --git a/shared-bindings/audioio/AudioOut.h b/shared-bindings/audioio/AudioOut.h
index d09a5c9ca..1076ac5cc 100644
--- a/shared-bindings/audioio/AudioOut.h
+++ b/shared-bindings/audioio/AudioOut.h
@@ -29,7 +29,7 @@
#include "common-hal/audioio/AudioOut.h"
#include "common-hal/microcontroller/Pin.h"
-#include "shared-bindings/audioio/RawSample.h"
+#include "shared-bindings/audiocore/RawSample.h"
extern const mp_obj_type_t audioio_audioout_type;
diff --git a/shared-bindings/audioio/__init__.c b/shared-bindings/audioio/__init__.c
index 4786b6425..3fecf2708 100644
--- a/shared-bindings/audioio/__init__.c
+++ b/shared-bindings/audioio/__init__.c
@@ -32,9 +32,6 @@
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/audioio/__init__.h"
#include "shared-bindings/audioio/AudioOut.h"
-#include "shared-bindings/audioio/Mixer.h"
-#include "shared-bindings/audioio/RawSample.h"
-#include "shared-bindings/audioio/WaveFile.h"
//| :mod:`audioio` --- Support for audio input and output
//| ======================================================
@@ -51,22 +48,19 @@
//| :maxdepth: 3
//|
//| AudioOut
-//| Mixer
-//| RawSample
-//| WaveFile
//|
//| All classes change hardware state and should be deinitialized when they
//| are no longer needed if the program continues after use. To do so, either
//| call :py:meth:`!deinit` or use a context manager. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
+//| Since CircuitPython 5, `Mixer`, `RawSample` and `WaveFile` are moved
+//| to :mod:`audiocore`.
+//|
STATIC const mp_rom_map_elem_t audioio_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audioio) },
{ MP_ROM_QSTR(MP_QSTR_AudioOut), MP_ROM_PTR(&audioio_audioout_type) },
- { MP_ROM_QSTR(MP_QSTR_Mixer), MP_ROM_PTR(&audioio_mixer_type) },
- { MP_ROM_QSTR(MP_QSTR_RawSample), MP_ROM_PTR(&audioio_rawsample_type) },
- { MP_ROM_QSTR(MP_QSTR_WaveFile), MP_ROM_PTR(&audioio_wavefile_type) },
};
STATIC MP_DEFINE_CONST_DICT(audioio_module_globals, audioio_module_globals_table);
diff --git a/shared-bindings/audiopwmio/PWMAudioOut.c b/shared-bindings/audiopwmio/PWMAudioOut.c
new file mode 100644
index 000000000..92543d112
--- /dev/null
+++ b/shared-bindings/audiopwmio/PWMAudioOut.c
@@ -0,0 +1,294 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdint.h>
+
+#include "lib/utils/context_manager_helpers.h"
+#include "py/binary.h"
+#include "py/objproperty.h"
+#include "py/runtime.h"
+#include "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/audiopwmio/PWMAudioOut.h"
+#include "shared-bindings/audiocore/RawSample.h"
+#include "shared-bindings/util.h"
+#include "supervisor/shared/translate.h"
+
+//| .. currentmodule:: audiopwmio
+//|
+//| :class:`PWMAudioOut` -- Output an analog audio signal
+//| ========================================================
+//|
+//| AudioOut can be used to output an analog audio signal on a given pin.
+//|
+//| .. class:: PWMAudioOut(left_channel, *, right_channel=None, quiescent_value=0x8000)
+//|
+//| Create a PWMAudioOut object associated with the given pin(s). This allows you to
+//| play audio signals out on the given pin(s). In contrast to mod:`audioio`,
+//| the pin(s) specified are digital pins, and are driven with a device-dependent PWM
+//| signal.
+//|
+//| :param ~microcontroller.Pin left_channel: The pin to output the left channel to
+//| :param ~microcontroller.Pin right_channel: The pin to output the right channel to
+//| :param int quiescent_value: The output value when no signal is present. Samples should start
+//| and end with this value to prevent audible popping.
+//|
+//| Simple 8ksps 440 Hz sin wave::
+//|
+//| import audiocore
+//| import audiopwmio
+//| import board
+//| import array
+//| import time
+//| import math
+//|
+//| # Generate one period of sine wav.
+//| length = 8000 // 440
+//| sine_wave = array.array("H", [0] * length)
+//| for i in range(length):
+//| sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15)
+//|
+//| dac = audiopwmio.PWMAudioOut(board.SPEAKER)
+//| sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000)
+//| dac.play(sine_wave, loop=True)
+//| time.sleep(1)
+//| dac.stop()
+//|
+//| Playing a wave file from flash::
+//|
+//| import board
+//| import audiocore
+//| import audiopwmio
+//| import digitalio
+//|
+//| # Required for CircuitPlayground Express
+//| speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
+//| speaker_enable.switch_to_output(value=True)
+//|
+//| data = open("cplay-5.1-16bit-16khz.wav", "rb")
+//| wav = audiocore.WaveFile(data)
+//| a = audiopwmio.PWMAudioOut(board.SPEAKER)
+//|
+//| print("playing")
+//| a.play(wav)
+//| while a.playing:
+//| pass
+//| print("stopped")
+//|
+STATIC mp_obj_t audiopwmio_pwmaudioout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_left_channel, ARG_right_channel, ARG_quiescent_value };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_left_channel, MP_ARG_OBJ | MP_ARG_REQUIRED },
+ { MP_QSTR_right_channel, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = mp_const_none} },
+ { MP_QSTR_quiescent_value, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x8000} },
+ };
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ mp_obj_t left_channel_obj = args[ARG_left_channel].u_obj;
+ assert_pin(left_channel_obj, false);
+ const mcu_pin_obj_t *left_channel_pin = MP_OBJ_TO_PTR(left_channel_obj);
+
+ mp_obj_t right_channel_obj = args[ARG_right_channel].u_obj;
+ const mcu_pin_obj_t *right_channel_pin = NULL;
+ if (right_channel_obj != mp_const_none) {
+ assert_pin(right_channel_obj, false);
+ right_channel_pin = MP_OBJ_TO_PTR(right_channel_obj);
+ }
+
+ // create AudioOut object from the given pin
+ audiopwmio_pwmaudioout_obj_t *self = m_new_obj(audiopwmio_pwmaudioout_obj_t);
+ self->base.type = &audiopwmio_pwmaudioout_type;
+ common_hal_audiopwmio_pwmaudioout_construct(self, left_channel_pin, right_channel_pin, args[ARG_quiescent_value].u_int);
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+//| .. method:: deinit()
+//|
+//| Deinitialises the PWMAudioOut and releases any hardware resources for reuse.
+//|
+STATIC mp_obj_t audiopwmio_pwmaudioout_deinit(mp_obj_t self_in) {
+ audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ common_hal_audiopwmio_pwmaudioout_deinit(self);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_deinit_obj, audiopwmio_pwmaudioout_deinit);
+
+STATIC void check_for_deinit(audiopwmio_pwmaudioout_obj_t *self) {
+ if (common_hal_audiopwmio_pwmaudioout_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+//| .. method:: __enter__()
+//|
+//| No-op used by Context Managers.
+//|
+// Provided by context manager helper.
+
+//| .. method:: __exit__()
+//|
+//| Automatically deinitializes the hardware when exiting a context. See
+//| :ref:`lifetime-and-contextmanagers` for more info.
+//|
+STATIC mp_obj_t audiopwmio_pwmaudioout_obj___exit__(size_t n_args, const mp_obj_t *args) {
+ (void)n_args;
+ common_hal_audiopwmio_pwmaudioout_deinit(args[0]);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiopwmio_pwmaudioout___exit___obj, 4, 4, audiopwmio_pwmaudioout_obj___exit__);
+
+
+//| .. method:: play(sample, *, loop=False)
+//|
+//| Plays the sample once when loop=False and continuously when loop=True.
+//| Does not block. Use `playing` to block.
+//|
+//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiocore.Mixer`.
+//|
+//| The sample itself should consist of 16 bit samples. Microcontrollers with a lower output
+//| resolution will use the highest order bits to output. For example, the SAMD21 has a 10 bit
+//| DAC that ignores the lowest 6 bits when playing 16 bit samples.
+//|
+STATIC mp_obj_t audiopwmio_pwmaudioout_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_sample, ARG_loop };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED },
+ { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
+ };
+ audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+ check_for_deinit(self);
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ mp_obj_t sample = args[ARG_sample].u_obj;
+ common_hal_audiopwmio_pwmaudioout_play(self, sample, args[ARG_loop].u_bool);
+
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_KW(audiopwmio_pwmaudioout_play_obj, 1, audiopwmio_pwmaudioout_obj_play);
+
+//| .. method:: stop()
+//|
+//| Stops playback and resets to the start of the sample.
+//|
+STATIC mp_obj_t audiopwmio_pwmaudioout_obj_stop(mp_obj_t self_in) {
+ audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+ common_hal_audiopwmio_pwmaudioout_stop(self);
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_stop_obj, audiopwmio_pwmaudioout_obj_stop);
+
+//| .. attribute:: playing
+//|
+//| True when an audio sample is being output even if `paused`. (read-only)
+//|
+STATIC mp_obj_t audiopwmio_pwmaudioout_obj_get_playing(mp_obj_t self_in) {
+ audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+ return mp_obj_new_bool(common_hal_audiopwmio_pwmaudioout_get_playing(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_get_playing_obj, audiopwmio_pwmaudioout_obj_get_playing);
+
+const mp_obj_property_t audiopwmio_pwmaudioout_playing_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&audiopwmio_pwmaudioout_get_playing_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+//| .. method:: pause()
+//|
+//| Stops playback temporarily while remembering the position. Use `resume` to resume playback.
+//|
+STATIC mp_obj_t audiopwmio_pwmaudioout_obj_pause(mp_obj_t self_in) {
+ audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+
+ if (!common_hal_audiopwmio_pwmaudioout_get_playing(self)) {
+ mp_raise_RuntimeError(translate("Not playing"));
+ }
+ common_hal_audiopwmio_pwmaudioout_pause(self);
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_pause_obj, audiopwmio_pwmaudioout_obj_pause);
+
+//| .. method:: resume()
+//|
+//| Resumes sample playback after :py:func:`pause`.
+//|
+STATIC mp_obj_t audiopwmio_pwmaudioout_obj_resume(mp_obj_t self_in) {
+ audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+
+ if (common_hal_audiopwmio_pwmaudioout_get_paused(self)) {
+ common_hal_audiopwmio_pwmaudioout_resume(self);
+ }
+
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_resume_obj, audiopwmio_pwmaudioout_obj_resume);
+
+//| .. attribute:: paused
+//|
+//| True when playback is paused. (read-only)
+//|
+STATIC mp_obj_t audiopwmio_pwmaudioout_obj_get_paused(mp_obj_t self_in) {
+ audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+ return mp_obj_new_bool(common_hal_audiopwmio_pwmaudioout_get_paused(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_get_paused_obj, audiopwmio_pwmaudioout_obj_get_paused);
+
+const mp_obj_property_t audiopwmio_pwmaudioout_paused_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&audiopwmio_pwmaudioout_get_paused_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+STATIC const mp_rom_map_elem_t audiopwmio_pwmaudioout_locals_dict_table[] = {
+ // Methods
+ { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiopwmio_pwmaudioout_deinit_obj) },
+ { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
+ { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiopwmio_pwmaudioout___exit___obj) },
+ { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiopwmio_pwmaudioout_play_obj) },
+ { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiopwmio_pwmaudioout_stop_obj) },
+ { MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&audiopwmio_pwmaudioout_pause_obj) },
+ { MP_ROM_QSTR(MP_QSTR_resume), MP_ROM_PTR(&audiopwmio_pwmaudioout_resume_obj) },
+
+ // Properties
+ { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiopwmio_pwmaudioout_playing_obj) },
+ { MP_ROM_QSTR(MP_QSTR_paused), MP_ROM_PTR(&audiopwmio_pwmaudioout_paused_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(audiopwmio_pwmaudioout_locals_dict, audiopwmio_pwmaudioout_locals_dict_table);
+
+const mp_obj_type_t audiopwmio_pwmaudioout_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_PWMAudioOut,
+ .make_new = audiopwmio_pwmaudioout_make_new,
+ .locals_dict = (mp_obj_dict_t*)&audiopwmio_pwmaudioout_locals_dict,
+};
diff --git a/shared-bindings/audiopwmio/PWMAudioOut.h b/shared-bindings/audiopwmio/PWMAudioOut.h
new file mode 100644
index 000000000..22afc70d3
--- /dev/null
+++ b/shared-bindings/audiopwmio/PWMAudioOut.h
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOPWMIO_AUDIOOUT_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOPWMIO_AUDIOOUT_H
+
+#include "common-hal/audiopwmio/PWMAudioOut.h"
+#include "common-hal/microcontroller/Pin.h"
+#include "shared-bindings/audiocore/RawSample.h"
+
+extern const mp_obj_type_t audiopwmio_pwmaudioout_type;
+
+// left_channel will always be non-NULL but right_channel may be for mono output.
+void common_hal_audiopwmio_pwmaudioout_construct(audiopwmio_pwmaudioout_obj_t* self,
+ const mcu_pin_obj_t* left_channel, const mcu_pin_obj_t* right_channel, uint16_t default_value);
+
+void common_hal_audiopwmio_pwmaudioout_deinit(audiopwmio_pwmaudioout_obj_t* self);
+bool common_hal_audiopwmio_pwmaudioout_deinited(audiopwmio_pwmaudioout_obj_t* self);
+void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t* self, mp_obj_t sample, bool loop);
+void common_hal_audiopwmio_pwmaudioout_stop(audiopwmio_pwmaudioout_obj_t* self);
+bool common_hal_audiopwmio_pwmaudioout_get_playing(audiopwmio_pwmaudioout_obj_t* self);
+void common_hal_audiopwmio_pwmaudioout_pause(audiopwmio_pwmaudioout_obj_t* self);
+void common_hal_audiopwmio_pwmaudioout_resume(audiopwmio_pwmaudioout_obj_t* self);
+bool common_hal_audiopwmio_pwmaudioout_get_paused(audiopwmio_pwmaudioout_obj_t* self);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOPWMIO_AUDIOOUT_H
diff --git a/shared-bindings/audiopwmio/__init__.c b/shared-bindings/audiopwmio/__init__.c
new file mode 100644
index 000000000..8a2b202b3
--- /dev/null
+++ b/shared-bindings/audiopwmio/__init__.c
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdint.h>
+
+#include "py/obj.h"
+#include "py/runtime.h"
+
+#include "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/audiopwmio/__init__.h"
+#include "shared-bindings/audiopwmio/PWMAudioOut.h"
+
+//| :mod:`audiopwmio` --- Support for audio input and output
+//| ========================================================
+//|
+//| .. module:: audiopwmio
+//| :synopsis: Support for audio output via digital PWM
+//| :platform: NRF52
+//|
+//| The `audiopwmio` module contains classes to provide access to audio IO.
+//|
+//| Libraries
+//|
+//| .. toctree::
+//| :maxdepth: 3
+//|
+//| PWMAudioOut
+//|
+//| All classes change hardware state and should be deinitialized when they
+//| are no longer needed if the program continues after use. To do so, either
+//| call :py:meth:`!deinit` or use a context manager. See
+//| :ref:`lifetime-and-contextmanagers` for more info.
+//|
+//| Since CircuitPython 5, `Mixer`, `RawSample` and `WaveFile` are moved
+//| to :mod:`audiocore`.
+//|
+
+STATIC const mp_rom_map_elem_t audiopwmio_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiopwmio) },
+ { MP_ROM_QSTR(MP_QSTR_PWMAudioOut), MP_ROM_PTR(&audiopwmio_pwmaudioout_type) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(audiopwmio_module_globals, audiopwmio_module_globals_table);
+
+const mp_obj_module_t audiopwmio_module = {
+ .base = { &mp_type_module },
+ .globals = (mp_obj_dict_t*)&audiopwmio_module_globals,
+};
diff --git a/shared-bindings/audiopwmio/__init__.h b/shared-bindings/audiopwmio/__init__.h
new file mode 100644
index 000000000..e4b7067d1
--- /dev/null
+++ b/shared-bindings/audiopwmio/__init__.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO___INIT___H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO___INIT___H
+
+#include "py/obj.h"
+
+// Nothing now.
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO___INIT___H
diff --git a/shared-bindings/bitbangio/I2C.c b/shared-bindings/bitbangio/I2C.c
index 374268e3d..0a3b03f51 100644
--- a/shared-bindings/bitbangio/I2C.c
+++ b/shared-bindings/bitbangio/I2C.c
@@ -42,7 +42,7 @@
//| :class:`I2C` --- Two wire serial protocol
//| ------------------------------------------
//|
-//| .. class:: I2C(scl, sda, \*, frequency=400000)
+//| .. class:: I2C(scl, sda, *, frequency=400000, timeout)
//|
//| I2C is a two-wire protocol for communicating between devices. At the
//| physical level it consists of 2 wires: SCL and SDA, the clock and data
@@ -69,13 +69,12 @@ STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args,
const mcu_pin_obj_t* sda = MP_OBJ_TO_PTR(args[ARG_sda].u_obj);
bitbangio_i2c_obj_t *self = m_new_obj(bitbangio_i2c_obj_t);
- raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self));
self->base.type = &bitbangio_i2c_type;
shared_module_bitbangio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int);
return (mp_obj_t)self;
}
-//| .. method:: I2C.deinit()
+//| .. method:: deinit()
//|
//| Releases control of the underlying hardware so other classes can use it.
//|
@@ -86,13 +85,19 @@ STATIC mp_obj_t bitbangio_i2c_obj_deinit(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_deinit_obj, bitbangio_i2c_obj_deinit);
-//| .. method:: I2C.__enter__()
+STATIC void check_for_deinit(bitbangio_i2c_obj_t *self) {
+ if (shared_module_bitbangio_i2c_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
+//| .. method:: __enter__()
//|
//| No-op used in Context Managers.
//|
// Provided by context manager helper.
-//| .. method:: I2C.__exit__()
+//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware on context exit. See
//| :ref:`lifetime-and-contextmanagers` for more info.
@@ -110,7 +115,7 @@ static void check_lock(bitbangio_i2c_obj_t *self) {
}
}
-//| .. method:: I2C.scan()
+//| .. method:: scan()
//|
//| Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of
//| those that respond. A device responds if it pulls the SDA line low after
@@ -118,7 +123,7 @@ static void check_lock(bitbangio_i2c_obj_t *self) {
//|
STATIC mp_obj_t bitbangio_i2c_scan(mp_obj_t self_in) {
bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_obj_t list = mp_obj_new_list(0, NULL);
// 7-bit addresses 0b0000xxx and 0b1111xxx are reserved
@@ -132,30 +137,30 @@ STATIC mp_obj_t bitbangio_i2c_scan(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_scan_obj, bitbangio_i2c_scan);
-//| .. method:: I2C.try_lock()
+//| .. method:: try_lock()
//|
//| Attempts to grab the I2C lock. Returns True on success.
//|
STATIC mp_obj_t bitbangio_i2c_obj_try_lock(mp_obj_t self_in) {
bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(shared_module_bitbangio_i2c_try_lock(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_try_lock_obj, bitbangio_i2c_obj_try_lock);
-//| .. method:: I2C.unlock()
+//| .. method:: unlock()
//|
//| Releases the I2C lock.
//|
STATIC mp_obj_t bitbangio_i2c_obj_unlock(mp_obj_t self_in) {
bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self));
+ check_for_deinit(self);
shared_module_bitbangio_i2c_unlock(self);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_unlock_obj, bitbangio_i2c_obj_unlock);
-//| .. method:: I2C.readfrom_into(address, buffer, \*, start=0, end=len(buffer))
+//| .. method:: readfrom_into(address, buffer, *, start=0, end=None)
//|
//| Read into ``buffer`` from the slave specified by ``address``.
//| The number of bytes read will be the length of ``buffer``.
@@ -179,7 +184,7 @@ STATIC mp_obj_t bitbangio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_a
{ MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
};
bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self));
+ check_for_deinit(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
check_lock(self);
@@ -203,7 +208,7 @@ STATIC mp_obj_t bitbangio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_a
}
MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_readfrom_into_obj, 3, bitbangio_i2c_readfrom_into);
-//| .. method:: I2C.writeto(address, buffer, \*, start=0, end=len(buffer), stop=True)
+//| .. method:: writeto(address, buffer, *, start=0, end=None, stop=True)
//|
//| Write the bytes from ``buffer`` to the slave specified by ``address``.
//| Transmits a stop bit if ``stop`` is set.
@@ -232,7 +237,7 @@ STATIC mp_obj_t bitbangio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, m
{ MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
};
bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
diff --git a/shared-bindings/bitbangio/OneWire.c b/shared-bindings/bitbangio/OneWire.c
index a3c53d2a5..73bedcd8d 100644
--- a/shared-bindings/bitbangio/OneWire.c
+++ b/shared-bindings/bitbangio/OneWire.c
@@ -91,6 +91,12 @@ STATIC mp_obj_t bitbangio_onewire_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_deinit_obj, bitbangio_onewire_deinit);
+STATIC void check_for_deinit(bitbangio_onewire_obj_t *self) {
+ if (shared_module_bitbangio_onewire_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -115,7 +121,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_onewire___exit___obj, 4, 4,
//|
STATIC mp_obj_t bitbangio_onewire_obj_reset(mp_obj_t self_in) {
bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_onewire_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(shared_module_bitbangio_onewire_reset(self));
}
@@ -130,7 +136,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_reset_obj, bitbangio_onewire_obj_res
//|
STATIC mp_obj_t bitbangio_onewire_obj_read_bit(mp_obj_t self_in) {
bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_onewire_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(shared_module_bitbangio_onewire_read_bit(self));
}
@@ -142,7 +148,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_read_bit_obj, bitbangio_onewire_obj_
//|
STATIC mp_obj_t bitbangio_onewire_obj_write_bit(mp_obj_t self_in, mp_obj_t bool_obj) {
bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_onewire_deinited(self));
+ check_for_deinit(self);
shared_module_bitbangio_onewire_write_bit(self, mp_obj_is_true(bool_obj));
return mp_const_none;
diff --git a/shared-bindings/bitbangio/SPI.c b/shared-bindings/bitbangio/SPI.c
index 974ec99e2..88bd3d6cb 100644
--- a/shared-bindings/bitbangio/SPI.c
+++ b/shared-bindings/bitbangio/SPI.c
@@ -84,7 +84,7 @@ STATIC mp_obj_t bitbangio_spi_make_new(const mp_obj_type_t *type, size_t n_args,
return (mp_obj_t)self;
}
-//| .. method:: SPI.deinit()
+//| .. method:: deinit()
//|
//| Turn off the SPI bus.
//|
@@ -95,13 +95,19 @@ STATIC mp_obj_t bitbangio_spi_obj_deinit(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_deinit_obj, bitbangio_spi_obj_deinit);
-//| .. method:: SPI.__enter__()
+STATIC void check_for_deinit(bitbangio_spi_obj_t *self) {
+ if (shared_module_bitbangio_spi_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
+//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
//|
// Provided by context manager helper.
-//| .. method:: SPI.__exit__()
+//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
@@ -120,7 +126,7 @@ static void check_lock(bitbangio_spi_obj_t *self) {
}
}
-//| .. method:: SPI.configure(\*, baudrate=100000, polarity=0, phase=0, bits=8)
+//| .. method:: configure(*, baudrate=100000, polarity=0, phase=0, bits=8)
//|
//| Configures the SPI bus. Only valid when locked.
//|
@@ -139,7 +145,7 @@ STATIC mp_obj_t bitbangio_spi_configure(size_t n_args, const mp_obj_t *pos_args,
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
};
bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -162,7 +168,7 @@ STATIC mp_obj_t bitbangio_spi_configure(size_t n_args, const mp_obj_t *pos_args,
}
MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_configure_obj, 1, bitbangio_spi_configure);
-//| .. method:: SPI.try_lock()
+//| .. method:: try_lock()
//|
//| Attempts to grab the SPI lock. Returns True on success.
//|
@@ -171,24 +177,24 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_configure_obj, 1, bitbangio_spi_configu
//|
STATIC mp_obj_t bitbangio_spi_obj_try_lock(mp_obj_t self_in) {
bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(shared_module_bitbangio_spi_try_lock(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_try_lock_obj, bitbangio_spi_obj_try_lock);
-//| .. method:: SPI.unlock()
+//| .. method:: unlock()
//|
//| Releases the SPI lock.
//|
STATIC mp_obj_t bitbangio_spi_obj_unlock(mp_obj_t self_in) {
bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self));
+ check_for_deinit(self);
shared_module_bitbangio_spi_unlock(self);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_unlock_obj, bitbangio_spi_obj_unlock);
-//| .. method:: SPI.write(buf)
+//| .. method:: write(buf)
//|
//| Write the data contained in ``buf``. Requires the SPI being locked.
//| If the buffer is empty, nothing happens.
@@ -196,7 +202,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_unlock_obj, bitbangio_spi_obj_unlock);
// TODO(tannewt): Add support for start and end kwargs.
STATIC mp_obj_t bitbangio_spi_write(mp_obj_t self_in, mp_obj_t wr_buf) {
bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self));
+ check_for_deinit(self);
mp_buffer_info_t src;
mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ);
if (src.len == 0) {
@@ -212,7 +218,7 @@ STATIC mp_obj_t bitbangio_spi_write(mp_obj_t self_in, mp_obj_t wr_buf) {
MP_DEFINE_CONST_FUN_OBJ_2(bitbangio_spi_write_obj, bitbangio_spi_write);
-//| .. method:: SPI.readinto(buf)
+//| .. method:: readinto(buf)
//|
//| Read into the buffer specified by ``buf`` while writing zeroes.
//| Requires the SPI being locked.
@@ -221,7 +227,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(bitbangio_spi_write_obj, bitbangio_spi_write);
// TODO(tannewt): Add support for start and end kwargs.
STATIC mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *args) {
bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(args[0]);
- raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self));
+ check_for_deinit(self);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
if (bufinfo.len == 0) {
@@ -236,7 +242,7 @@ STATIC mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *args) {
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_spi_readinto_obj, 2, 2, bitbangio_spi_readinto);
-//| .. method:: SPI.write_readinto(buffer_out, buffer_in, \*, out_start=0, out_end=len(buffer_out), in_start=0, in_end=len(buffer_in))
+//| .. method:: write_readinto(buffer_out, buffer_in, *, out_start=0, out_end=None, in_start=0, in_end=None)
//|
//| Write out the data in ``buffer_out`` while simultaneously reading data into ``buffer_in``.
//| The lengths of the slices defined by ``buffer_out[out_start:out_end]`` and ``buffer_in[in_start:in_end]``
@@ -246,9 +252,9 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_spi_readinto_obj, 2, 2, bitbangio_
//| :param bytearray buffer_out: Write out the data in this buffer
//| :param bytearray buffer_in: Read data into this buffer
//| :param int out_start: Start of the slice of buffer_out to write out: ``buffer_out[out_start:out_end]``
-//| :param int out_end: End of the slice; this index is not included
+//| :param int out_end: End of the slice; this index is not included. Defaults to ``len(buffer_out)``
//| :param int in_start: Start of the slice of ``buffer_in`` to read into: ``buffer_in[in_start:in_end]``
-//| :param int in_end: End of the slice; this index is not included
+//| :param int in_end: End of the slice; this index is not included. Defaults to ``len(buffer_in)``
//|
STATIC mp_obj_t bitbangio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_buffer_out, ARG_buffer_in, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end };
@@ -261,7 +267,7 @@ STATIC mp_obj_t bitbangio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_
{ MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
};
bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self));
+ check_for_deinit(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
diff --git a/shared-bindings/bleio/Adapter.c b/shared-bindings/bleio/Adapter.c
index d9449d3ab..7b8df5103 100644
--- a/shared-bindings/bleio/Adapter.c
+++ b/shared-bindings/bleio/Adapter.c
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/shared-bindings/bleio/Adapter.h b/shared-bindings/bleio/Adapter.h
index fe3886e59..de9d1d6db 100644
--- a/shared-bindings/bleio/Adapter.h
+++ b/shared-bindings/bleio/Adapter.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/shared-bindings/bleio/Address.c b/shared-bindings/bleio/Address.c
index b7c76b7b2..37f01042c 100644
--- a/shared-bindings/bleio/Address.c
+++ b/shared-bindings/bleio/Address.c
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -33,13 +34,6 @@
#include "shared-bindings/bleio/Address.h"
#include "shared-module/bleio/Address.h"
-#define ADDRESS_BYTE_LEN 12
-
-STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) {
- return unichar_xdigit_value(nibble1) | (unichar_xdigit_value(nibble2) << 4);
-}
-
-
//| .. currentmodule:: bleio
//|
//| :class:`Address` -- BLE address
@@ -48,31 +42,20 @@ STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) {
//| Encapsulates the address of a BLE device.
//|
-//| .. class:: Address(address)
+//| .. class:: Address(address, address_type)
//|
//| Create a new Address object encapsulating the address value.
//| The value itself can be one of:
//|
-//| - a `str` value in the format of 'XXXXXXXXXXXX' or 'XX:XX:XX:XX:XX:XX' (12 hex digits)
-//| - a `bytes` or `bytearray` containing 6 bytes
-//| - another Address object
-//|
-//| :param address: The address to encapsulate
-//|
-
-//| .. attribute:: type
-//|
-//| The address type. One of:
-//|
-//| - `bleio.AddressType.PUBLIC`
-//| - `bleio.AddressType.RANDOM_STATIC`
-//| - `bleio.AddressType.RANDOM_PRIVATE_RESOLVABLE`
-//| - `bleio.AddressType.RANDOM_PRIVATE_NON_RESOLVABLE`
+//| :param buf address: The address value to encapsulate. A buffer object (bytearray, bytes) of 6 bytes.
+//| :param int address_type: one of the integer values: `PUBLIC`, `RANDOM_STATIC`,
+//| `RANDOM_PRIVATE_RESOLVABLE`, or `RANDOM_PRIVATE_NON_RESOLVABLE`.
//|
STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- enum { ARG_address };
+ enum { ARG_address, ARG_address_type };
static const mp_arg_t allowed_args[] = {
- { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_address, MP_ARG_OBJ | MP_ARG_REQUIRED },
+ { MP_QSTR_address_type, MP_ARG_INT, {.u_int = BLEIO_ADDRESS_TYPE_PUBLIC } },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@@ -80,83 +63,52 @@ STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args,
bleio_address_obj_t *self = m_new_obj(bleio_address_obj_t);
self->base.type = &bleio_address_type;
- self->type = ADDRESS_PUBLIC;
const mp_obj_t address = args[ARG_address].u_obj;
+ mp_buffer_info_t buf_info;
+ mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ);
+ if (buf_info.len != NUM_BLEIO_ADDRESS_BYTES) {
+ mp_raise_ValueError_varg(translate("Address must be %d bytes long"), NUM_BLEIO_ADDRESS_BYTES);
+ }
- if (MP_OBJ_IS_STR(address)) {
- GET_STR_DATA_LEN(address, str, str_len);
-
- size_t value_index = 0;
- int str_index = str_len;
- bool error = false;
-
- // Loop until fewer than two characters left.
- while (str_index >= 1 && value_index < sizeof(self->value)) {
- if (str[str_index] == ':') {
- // Skip colon separators.
- str_index--;
- continue;
- }
-
- if (!unichar_isxdigit(str[str_index]) ||
- !unichar_isxdigit(str[str_index-1])) {
- error = true;
- break;
- }
-
- self->value[value_index] = xdigit_8b_value(str[str_index],
- str[str_index-1]);
- value_index += 1;
- str_index -= 2;
- }
- // Check for correct number of hex digits and no parsing errors.
- if (error || value_index != ADDRESS_BYTE_LEN || str_index != -1) {
- mp_raise_ValueError_varg(translate("Address is not %d bytes long or is in wrong format"),
- ADDRESS_BYTE_LEN);
- }
- } else if (MP_OBJ_IS_TYPE(address, &mp_type_bytearray) || MP_OBJ_IS_TYPE(address, &mp_type_bytes)) {
- mp_buffer_info_t buf_info;
- mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ);
- if (buf_info.len != BLEIO_ADDRESS_BYTES) {
- mp_raise_ValueError_varg(translate("Address must be %d bytes long"), BLEIO_ADDRESS_BYTES);
- }
-
- for (size_t b = 0; b < BLEIO_ADDRESS_BYTES; ++b) {
- self->value[BLEIO_ADDRESS_BYTES - b - 1] = ((uint8_t*)buf_info.buf)[b];
- }
- } else if (MP_OBJ_IS_TYPE(address, &bleio_address_type)) {
- // deep copy
- bleio_address_obj_t *other = MP_OBJ_TO_PTR(address);
- self->type = other->type;
- memcpy(self->value, other->value, BLEIO_ADDRESS_BYTES);
+ const mp_int_t address_type = args[ARG_address_type].u_int;
+ if (address_type < BLEIO_ADDRESS_TYPE_MIN || address_type > BLEIO_ADDRESS_TYPE_MAX) {
+ mp_raise_ValueError(translate("Address type out of range"));
}
+ common_hal_bleio_address_construct(self, buf_info.buf, address_type);
+
return MP_OBJ_FROM_PTR(self);
}
-STATIC void bleio_address_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+//| .. attribute:: address_bytes
+//|
+//| The bytes that make up the device address (read-only)
+//|
+STATIC mp_obj_t bleio_address_get_address_bytes(mp_obj_t self_in) {
bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in);
- mp_printf(print, "Address('%02x:%02x:%02x:%02x:%02x:%02x')",
- self->value[5], self->value[4], self->value[3],
- self->value[2], self->value[1], self->value[0]);
+ return common_hal_bleio_address_get_address_bytes(self);
}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_address_get_address_bytes_obj, bleio_address_get_address_bytes);
+
+const mp_obj_property_t bleio_address_address_bytes_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&bleio_address_get_address_bytes_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+//| .. attribute:: type
+//|
+//| The address type (read-only).
+//| One of the integer values: `PUBLIC`, `RANDOM_STATIC`,
+//| `RANDOM_PRIVATE_RESOLVABLE`, or `RANDOM_PRIVATE_NON_RESOLVABLE`.
+//|
STATIC mp_obj_t bleio_address_get_type(mp_obj_t self_in) {
bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in);
- if (self->type == ADDRESS_PUBLIC) {
- return (mp_obj_t)&bleio_addresstype_public_obj;
- } else if (self->type == ADDRESS_RANDOM_STATIC) {
- return (mp_obj_t)&bleio_addresstype_random_static_obj;
- } else if (self->type == ADDRESS_RANDOM_PRIVATE_RESOLVABLE) {
- return (mp_obj_t)&bleio_addresstype_random_private_resolvable_obj;
- } else if (self->type == ADDRESS_RANDOM_PRIVATE_NON_RESOLVABLE) {
- return (mp_obj_t)&bleio_addresstype_random_private_non_resolvable_obj;
- }
-
- return mp_const_none;
+ return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_address_get_type(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(bleio_address_get_type_obj, bleio_address_get_type);
@@ -167,8 +119,74 @@ const mp_obj_property_t bleio_address_type_obj = {
(mp_obj_t)&mp_const_none_obj},
};
+//| .. method:: __eq__(other)
+//|
+//| Two Address objects are equal if their addresses and address types are equal.
+//|
+STATIC mp_obj_t bleio_address_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
+ switch (op) {
+ // Two Addresses are equal if their address bytes and address_type are equal
+ case MP_BINARY_OP_EQUAL:
+ if (MP_OBJ_IS_TYPE(rhs_in, &bleio_address_type)) {
+ bleio_address_obj_t *lhs = MP_OBJ_TO_PTR(lhs_in);
+ bleio_address_obj_t *rhs = MP_OBJ_TO_PTR(rhs_in);
+ return mp_obj_new_bool(
+ mp_obj_equal(common_hal_bleio_address_get_address_bytes(lhs),
+ common_hal_bleio_address_get_address_bytes(rhs)) &&
+ common_hal_bleio_address_get_type(lhs) ==
+ common_hal_bleio_address_get_type(rhs));
+
+ } else {
+ return mp_const_false;
+ }
+
+ default:
+ return MP_OBJ_NULL; // op not supported
+ }
+}
+
+STATIC void bleio_address_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ if (kind == PRINT_STR) {
+ mp_buffer_info_t buf_info;
+ mp_obj_t address_bytes = common_hal_bleio_address_get_address_bytes(self);
+ mp_get_buffer_raise(address_bytes, &buf_info, MP_BUFFER_READ);
+
+ const uint8_t *buf = (uint8_t *) buf_info.buf;
+ mp_printf(print,
+ "%02x:%02x:%02x:%02x:%02x:%02x",
+ buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]);
+ } else {
+ mp_printf(print, "<Address>");
+ }
+}
+
+//| .. data:: PUBLIC
+//|
+//| A publicly known address, with a company ID (high 24 bits)and company-assigned part (low 24 bits).
+//|
+//| .. data:: RANDOM_STATIC
+//|
+//| A randomly generated address that does not change often. It may never change or may change after
+//| a power cycle.
+//|
+//| .. data:: RANDOM_PRIVATE_RESOLVABLE
+//|
+//| An address that is usable when the peer knows the other device's secret Identity Resolving Key (IRK).
+//|
+//| .. data:: RANDOM_PRIVATE_NON_RESOLVABLE
+//|
+//| A randomly generated address that changes on every connection.
+//|
STATIC const mp_rom_map_elem_t bleio_address_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_address_bytes), MP_ROM_PTR(&bleio_address_address_bytes_obj) },
{ MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_address_type_obj) },
+ // These match the BLE_GAP_ADDR_TYPES values used by the nRF library.
+ { MP_ROM_QSTR(MP_QSTR_PUBLIC), MP_OBJ_NEW_SMALL_INT(0) },
+ { MP_ROM_QSTR(MP_QSTR_RANDOM_STATIC), MP_OBJ_NEW_SMALL_INT(1) },
+ { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_RESOLVABLE), MP_OBJ_NEW_SMALL_INT(2) },
+ { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE), MP_OBJ_NEW_SMALL_INT(3) },
+
};
STATIC MP_DEFINE_CONST_DICT(bleio_address_locals_dict, bleio_address_locals_dict_table);
@@ -176,7 +194,8 @@ STATIC MP_DEFINE_CONST_DICT(bleio_address_locals_dict, bleio_address_locals_dict
const mp_obj_type_t bleio_address_type = {
{ &mp_type_type },
.name = MP_QSTR_Address,
- .print = bleio_address_print,
.make_new = bleio_address_make_new,
+ .print = bleio_address_print,
+ .binary_op = bleio_address_binary_op,
.locals_dict = (mp_obj_dict_t*)&bleio_address_locals_dict
};
diff --git a/shared-bindings/bleio/Address.h b/shared-bindings/bleio/Address.h
index 9c9e20968..5e02ee210 100644
--- a/shared-bindings/bleio/Address.h
+++ b/shared-bindings/bleio/Address.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -28,7 +29,20 @@
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H
#include "py/objtype.h"
+#include "shared-module/bleio/Address.h"
+
+#define BLEIO_ADDRESS_TYPE_PUBLIC (0)
+#define BLEIO_ADDRESS_TYPE_RANDOM_STATIC (1)
+#define BLEIO_ADDRESS_TYPE_RANDOM_PRIVATE_RESOLVABLE (2)
+#define BLEIO_ADDRESS_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE (3)
+
+#define BLEIO_ADDRESS_TYPE_MIN BLEIO_ADDRESS_TYPE_PUBLIC
+#define BLEIO_ADDRESS_TYPE_MAX BLEIO_ADDRESS_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE
extern const mp_obj_type_t bleio_address_type;
+extern void common_hal_bleio_address_construct(bleio_address_obj_t *self, uint8_t *bytes, uint8_t address_type);
+extern mp_obj_t common_hal_bleio_address_get_address_bytes(bleio_address_obj_t *self);
+extern uint8_t common_hal_bleio_address_get_type(bleio_address_obj_t *self);
+
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H
diff --git a/shared-bindings/bleio/AddressType.c b/shared-bindings/bleio/AddressType.c
deleted file mode 100644
index cf2151c94..000000000
--- a/shared-bindings/bleio/AddressType.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * This file is part of the Micro Python project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 Artur Pacholec
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "shared-bindings/bleio/AddressType.h"
-
-//| .. currentmodule:: bleio
-//|
-//| :class:`AddressType` -- defines the type of a BLE address
-//| =============================================================
-//|
-//| .. class:: bleio.AddressType
-//|
-//| Enum-like class to define the type of a BLE address, see also `bleio.Address`.
-//|
-//| .. data:: PUBLIC
-//|
-//| The address is public
-//|
-//| .. data:: RANDOM_STATIC
-//|
-//| The address is random static
-//|
-//| .. data:: RANDOM_PRIVATE_RESOLVABLE
-//|
-//| The address is random private resolvable
-//|
-//| .. data:: RANDOM_PRIVATE_NON_RESOLVABLE
-//|
-//| The address is private non-resolvable
-//|
-const mp_obj_type_t bleio_addresstype_type;
-
-const bleio_addresstype_obj_t bleio_addresstype_public_obj = {
- { &bleio_addresstype_type },
-};
-
-const bleio_addresstype_obj_t bleio_addresstype_random_static_obj = {
- { &bleio_addresstype_type },
-};
-
-const bleio_addresstype_obj_t bleio_addresstype_random_private_resolvable_obj = {
- { &bleio_addresstype_type },
-};
-
-const bleio_addresstype_obj_t bleio_addresstype_random_private_non_resolvable_obj = {
- { &bleio_addresstype_type },
-};
-
-STATIC const mp_rom_map_elem_t bleio_addresstype_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_PUBLIC), MP_ROM_PTR(&bleio_addresstype_public_obj) },
- { MP_ROM_QSTR(MP_QSTR_RANDOM_STATIC), MP_ROM_PTR(&bleio_addresstype_random_static_obj) },
- { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_RESOLVABLE), MP_ROM_PTR(&bleio_addresstype_random_private_resolvable_obj) },
- { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE), MP_ROM_PTR(&bleio_addresstype_random_private_non_resolvable_obj) },
-};
-STATIC MP_DEFINE_CONST_DICT(bleio_addresstype_locals_dict, bleio_addresstype_locals_dict_table);
-
-STATIC void bleio_addresstype_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
- qstr type = MP_QSTR_PUBLIC;
-
- if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_static_obj)) {
- type = MP_QSTR_RANDOM_STATIC;
- } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_private_resolvable_obj)) {
- type = MP_QSTR_RANDOM_PRIVATE_RESOLVABLE;
- } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_private_non_resolvable_obj)) {
- type = MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE;
- }
-
- mp_printf(print, "%q.%q.%q", MP_QSTR_bleio, MP_QSTR_AddressType, type);
-}
-
-const mp_obj_type_t bleio_addresstype_type = {
- { &mp_type_type },
- .name = MP_QSTR_AddressType,
- .print = bleio_addresstype_print,
- .locals_dict = (mp_obj_t)&bleio_addresstype_locals_dict,
-};
diff --git a/shared-bindings/bleio/AdvertisementData.c b/shared-bindings/bleio/AdvertisementData.c
deleted file mode 100644
index 9cfdd74e9..000000000
--- a/shared-bindings/bleio/AdvertisementData.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 Artur Pacholec
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "py/obj.h"
-#include "shared-module/bleio/AdvertisementData.h"
-
-//| .. currentmodule:: bleio
-//|
-//| :class:`AdvertisementData` -- data used during BLE advertising
-//| ==============================================================
-//|
-//| Represents the data to be broadcast during BLE advertising.
-//|
-
-STATIC const mp_rom_map_elem_t bleio_advertisementdata_locals_dict_table[] = {
- // Static variables
- { MP_ROM_QSTR(MP_QSTR_FLAGS), MP_ROM_INT(AdFlags) },
- { MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_16BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf16BitServiceClassUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_16BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf16BitServiceClassUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_32BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf32BitServiceClassUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_32BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf32BitServiceClassUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_128BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf128BitServiceClassUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_128BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf128BitServiceClassUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_SHORTENED_LOCAL_NAME), MP_ROM_INT(AdShortenedLocalName) },
- { MP_ROM_QSTR(MP_QSTR_COMPLETE_LOCAL_NAME), MP_ROM_INT(AdCompleteLocalName) },
- { MP_ROM_QSTR(MP_QSTR_TX_POWER_LEVEL), MP_ROM_INT(AdTxPowerLevel) },
- { MP_ROM_QSTR(MP_QSTR_CLASS_OF_DEVICE), MP_ROM_INT(AdClassOfDevice) },
- { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_HASH_C), MP_ROM_INT(AdSimplePairingHashC) },
- { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_RANDOMIZER_R), MP_ROM_INT(AdSimplePairingRandomizerR) },
- { MP_ROM_QSTR(MP_QSTR_SECURITY_MANAGER_TK_VALUE), MP_ROM_INT(AdSecurityManagerTKValue) },
- { MP_ROM_QSTR(MP_QSTR_SECURITY_MANAGER_OOB_FLAGS), MP_ROM_INT(AdSecurityManagerOOBFlags) },
- { MP_ROM_QSTR(MP_QSTR_SLAVE_CONNECTION_INTERVAL_RANGE), MP_ROM_INT(AdSlaveConnectionIntervalRange) },
- { MP_ROM_QSTR(MP_QSTR_LIST_OF_16BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf16BitServiceSolicitationUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_LIST_OF_128BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf128BitServiceSolicitationUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_SERVICE_DATA), MP_ROM_INT(AdServiceData) },
- { MP_ROM_QSTR(MP_QSTR_PUBLIC_TARGET_ADDRESS), MP_ROM_INT(AdPublicTargetAddress) },
- { MP_ROM_QSTR(MP_QSTR_RANDOM_TARGET_ADDRESS), MP_ROM_INT(AdRandomTargetAddress) },
- { MP_ROM_QSTR(MP_QSTR_APPEARANCE), MP_ROM_INT(AdAppearance) },
- { MP_ROM_QSTR(MP_QSTR_ADVERTISING_INTERNAL), MP_ROM_INT(AdAdvertisingInterval) },
- { MP_ROM_QSTR(MP_QSTR_LE_BLUETOOTH_DEVICE_ADDRESS), MP_ROM_INT(AdLEBluetoothDeviceAddress) },
- { MP_ROM_QSTR(MP_QSTR_LE_ROLE), MP_ROM_INT(AdLERole) },
- { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_HASH_C256), MP_ROM_INT(AdSimplePairingHashC256) },
- { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_RANDOMIZER_R256), MP_ROM_INT(AdSimplePairingRandomizerR256) },
- { MP_ROM_QSTR(MP_QSTR_LIST_OF_32BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf32BitServiceSolicitationUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_SERVICE_DATA_32BIT_UUID), MP_ROM_INT(AdServiceData32BitUUID) },
- { MP_ROM_QSTR(MP_QSTR_SERVICE_DATA_128BIT_UUID), MP_ROM_INT(AdServiceData128BitUUID) },
- { MP_ROM_QSTR(MP_QSTR_LE_SECURE_CONNECTIONS_CONFIRMATION_VALUE), MP_ROM_INT(AdLESecureConnectionsConfirmationValue) },
- { MP_ROM_QSTR(MP_QSTR_LE_SECURE_CONNECTIONS_RANDOM_VALUE), MP_ROM_INT(AdLESecureConnectionsRandomValue) },
- { MP_ROM_QSTR(MP_QSTR_URI), MP_ROM_INT(AdURI) },
- { MP_ROM_QSTR(MP_QSTR_INDOOR_POSITIONING), MP_ROM_INT(AdIndoorPositioning) },
- { MP_ROM_QSTR(MP_QSTR_TRANSPORT_DISCOVERY_DATA), MP_ROM_INT(AdTransportDiscoveryData) },
- { MP_ROM_QSTR(MP_QSTR_LE_SUPPORTED_FEATURES), MP_ROM_INT(AdLESupportedFeatures) },
- { MP_ROM_QSTR(MP_QSTR_CHANNEL_MAP_UPDATE_INDICATION), MP_ROM_INT(AdChannelMapUpdateIndication) },
- { MP_ROM_QSTR(MP_QSTR_PB_ADV), MP_ROM_INT(AdPBADV) },
- { MP_ROM_QSTR(MP_QSTR_MESH_MESSAGE), MP_ROM_INT(AdMeshMessage) },
- { MP_ROM_QSTR(MP_QSTR_MESH_BEACON), MP_ROM_INT(AdMeshBeacon) },
- { MP_ROM_QSTR(MP_QSTR_3D_INFORMATION_DATA), MP_ROM_INT(Ad3DInformationData) },
- { MP_ROM_QSTR(MP_QSTR_MANUFACTURER_SPECIFIC_DATA), MP_ROM_INT(AdManufacturerSpecificData) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(bleio_advertisementdata_locals_dict, bleio_advertisementdata_locals_dict_table);
-
-const mp_obj_type_t bleio_advertisementdata_type = {
- { &mp_type_type },
- .name = MP_QSTR_AdvertisementData,
- .locals_dict = (mp_obj_dict_t*)&bleio_advertisementdata_locals_dict
-};
diff --git a/shared-bindings/bleio/Broadcaster.c b/shared-bindings/bleio/Broadcaster.c
deleted file mode 100644
index 209e66490..000000000
--- a/shared-bindings/bleio/Broadcaster.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 Dan Halbert for Adafruit Industries
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "ble_drv.h"
-#include "py/runtime.h"
-
-#include "shared-bindings/bleio/Broadcaster.h"
-
-//| .. currentmodule:: bleio
-//|
-//| :class:`Broadcaster` -- Broadcast advertising packets.
-//| =========================================================
-//|
-//| Implement a BLE broadcaster which sends data in advertising packets and does not connect.
-//| Used for beacons and other one-way data transmission.
-//|
-//| Usage::
-//|
-//| import bleio
-//| import time
-//|
-//| # Broadcast once a second.
-//| broadcaster = bleio.Broadcaster(interval=1)
-//| data = 0
-//| # Broadcast a byte of data that's incremented once a minute
-//| while True:
-//| # data is an entire advertising data packet, starting with flags.
-//| broadcaster.start_advertising(data)
-//| time.sleep(60)
-//| data += 1
-//|
-//| .. class:: Broadcaster(interval=1)
-//|
-//| Create a new Broadcaster object.
-
-//| :param float interval: how often to broadcast
-//|
-
-STATIC mp_obj_t bleio_broadcaster_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- enum { ARG_interval };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_interval, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} },
- };
-
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- mp_float_t interval = mp_obj_get_float(args[ARG_interval].u_obj);
-
- bleio_broadcaster_obj_t *self = m_new_obj(bleio_broadcaster_obj_t);
- self->base.type = &bleio_broadcaster_type;
- // Do port-specific initialization. interval will be validated.
- common_hal_bleio_broadcaster_construct(self, interval);
-
- return MP_OBJ_FROM_PTR(self);
-}
-
-//| .. method:: start_advertising(data)
-//|
-//| Start advertising using the given data packet.
-//|
-//| :param buf data: advertising data packet, starting with advertising data flags (0x01)
-//|
-STATIC mp_obj_t bleio_broadcaster_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- bleio_broadcaster_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
-
- enum { ARG_data };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ },
- };
-
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- mp_buffer_info_t bufinfo;
- mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ);
-
- common_hal_bleio_broadcaster_start_advertising(self, &bufinfo);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_broadcaster_start_advertising_obj, 0, bleio_broadcaster_start_advertising);
-
-//| .. method:: stop_advertising()
-//|
-//| Stop sending advertising packets.
-STATIC mp_obj_t bleio_broadcaster_stop_advertising(mp_obj_t self_in) {
- bleio_broadcaster_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- common_hal_bleio_broadcaster_stop_advertising(self);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_broadcaster_stop_advertising_obj, bleio_broadcaster_stop_advertising);
-
-STATIC const mp_rom_map_elem_t bleio_broadcaster_locals_dict_table[] = {
- // Methods
- { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_broadcaster_start_advertising_obj) },
- { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_broadcaster_stop_advertising_obj) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(bleio_broadcaster_locals_dict, bleio_broadcaster_locals_dict_table);
-
-const mp_obj_type_t bleio_broadcaster_type = {
- { &mp_type_type },
- .name = MP_QSTR_Broadcaster,
- .make_new = bleio_broadcaster_make_new,
- .locals_dict = (mp_obj_dict_t*)&bleio_broadcaster_locals_dict
-};
diff --git a/shared-bindings/bleio/Central.c b/shared-bindings/bleio/Central.c
new file mode 100644
index 000000000..fc00bce5c
--- /dev/null
+++ b/shared-bindings/bleio/Central.c
@@ -0,0 +1,199 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include "ble_drv.h"
+#include "py/objarray.h"
+#include "py/objproperty.h"
+#include "py/objstr.h"
+#include "py/runtime.h"
+#include "shared-bindings/bleio/Adapter.h"
+#include "shared-bindings/bleio/Address.h"
+#include "shared-bindings/bleio/Characteristic.h"
+#include "shared-bindings/bleio/Central.h"
+#include "shared-bindings/bleio/Service.h"
+
+//| .. currentmodule:: bleio
+//|
+//| :class:`Central` -- A BLE central device
+//| =========================================================
+//|
+//| Implement a BLE central, which runs locally. Can connect to a given address.
+//|
+//| Usage::
+//|
+//| import bleio
+//|
+//| scanner = bleio.Scanner()
+//| entries = scanner.scan(2.5)
+//|
+//| my_entry = None
+//| for entry in entries:
+//| if entry.name is not None and entry.name == 'MyPeripheral':
+//| my_entry = entry
+//| break
+//|
+//| central = bleio.Central(my_entry.address)
+//| central.connect(10.0) # timeout after 10 seconds
+//|
+
+//| .. class:: Central()
+//|
+//| Create a new Central object.
+//|
+STATIC mp_obj_t bleio_central_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 0, 0, false);
+
+ bleio_central_obj_t *self = m_new_obj(bleio_central_obj_t);
+ self->base.type = &bleio_central_type;
+
+ common_hal_bleio_central_construct(self);
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+//| .. method:: connect(address, timeout, *, service_uuids=None)
+//| Attempts a connection to the remote peripheral. If the connection is successful,
+//| Do BLE discovery for the listed services, to find their handles and characteristics.
+//| The attribute `remote_services` will contain a list of all discovered services.
+//|
+//| :param bleio.Address address: The address of the peripheral to connect to
+//| :param float/int timeout: Try to connect for timeout seconds.
+//| :param iterable service_uuids_whitelist: an iterable of :py:class:~`UUID` objects for the services
+//| provided by the peripheral that you want to use.
+//| The peripheral may provide more services, but services not listed are ignored.
+//| If a service in service_uuids is not found during discovery, it will not
+//| appear in `remote_services`.
+//|
+//| If service_uuids_whitelist is None, then all services will undergo discovery, which can be slow.
+//|
+//| If the service UUID is 128-bit, or its characteristic UUID's are 128-bit, you
+//| you must have already created a :py:class:~`UUID` object for that UUID in order for the
+//| service or characteristic to be discovered. (This restriction may be lifted in the future.)
+//|
+STATIC mp_obj_t bleio_central_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_central_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_address, ARG_timeout, ARG_service_uuids_whitelist };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_timeout, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_service_uuids_whitelist, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ if (!MP_OBJ_IS_TYPE(args[ARG_address].u_obj, &bleio_address_type)) {
+ mp_raise_ValueError(translate("Expected an Address"));
+ }
+
+ bleio_address_obj_t *address = MP_OBJ_TO_PTR(args[ARG_address].u_obj);
+ mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj);
+
+ // common_hal_bleio_central_connect() will validate that services is an iterable or None.
+ common_hal_bleio_central_connect(self, address, timeout, args[ARG_service_uuids_whitelist].u_obj);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_central_connect_obj, 3, bleio_central_connect);
+
+
+//| .. method:: disconnect()
+//|
+//| Disconnects from the remote peripheral.
+//|
+STATIC mp_obj_t bleio_central_disconnect(mp_obj_t self_in) {
+ bleio_central_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ common_hal_bleio_central_disconnect(self);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_disconnect_obj, bleio_central_disconnect);
+
+//| .. attribute:: connected
+//|
+//| True if connected to a remove peripheral.
+//|
+STATIC mp_obj_t bleio_central_get_connected(mp_obj_t self_in) {
+ bleio_central_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(common_hal_bleio_central_get_connected(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_get_connected_obj, bleio_central_get_connected);
+
+const mp_obj_property_t bleio_central_connected_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_central_get_connected_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+
+//| .. attribute:: remote_services (read-only)
+//|
+//| A tuple of services provided by the remote peripheral.
+//| If the Central is not connected, an empty tuple will be returned.
+//|
+STATIC mp_obj_t bleio_central_get_remote_services(mp_obj_t self_in) {
+ bleio_central_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ // Return list as a tuple so user won't be able to change it.
+ mp_obj_list_t *service_list = common_hal_bleio_central_get_remote_services(self);
+ return mp_obj_new_tuple(service_list->len, service_list->items);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_get_remote_services_obj, bleio_central_get_remote_services);
+
+const mp_obj_property_t bleio_central_remote_services_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_central_get_remote_services_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC const mp_rom_map_elem_t bleio_central_locals_dict_table[] = {
+ // Methods
+ { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_central_connect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_central_disconnect_obj) },
+
+ // Properties
+ { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_central_connected_obj) },
+ { MP_ROM_QSTR(MP_QSTR_remote_services), MP_ROM_PTR(&bleio_central_remote_services_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(bleio_central_locals_dict, bleio_central_locals_dict_table);
+
+const mp_obj_type_t bleio_central_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Central,
+ .make_new = bleio_central_make_new,
+ .locals_dict = (mp_obj_dict_t*)&bleio_central_locals_dict
+};
diff --git a/shared-bindings/bleio/Device.h b/shared-bindings/bleio/Central.h
index aebf1d639..0e84037f9 100644
--- a/shared-bindings/bleio/Device.h
+++ b/shared-bindings/bleio/Central.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -24,19 +25,18 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H
-#include "shared-module/bleio/AdvertisementData.h"
-#include "shared-module/bleio/Device.h"
-#include "shared-module/bleio/Service.h"
+#include "common-hal/bleio/Central.h"
+#include "common-hal/bleio/Service.h"
-extern const mp_obj_type_t bleio_device_type;
+extern const mp_obj_type_t bleio_central_type;
-extern void common_hal_bleio_device_add_service(bleio_device_obj_t *device, bleio_service_obj_t *service);
-extern void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bool connectable, mp_buffer_info_t *raw_data);
-extern void common_hal_bleio_device_stop_advertising(bleio_device_obj_t *device);
-extern void common_hal_bleio_device_connect(bleio_device_obj_t *device);
-extern void common_hal_bleio_device_disconnect(bleio_device_obj_t *device);
+extern void common_hal_bleio_central_construct(bleio_central_obj_t *self);
+extern void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout, mp_obj_t service_uuids);
+extern void common_hal_bleio_central_disconnect(bleio_central_obj_t *self);
+extern bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self);
+extern mp_obj_list_t *common_hal_bleio_central_get_remote_services(bleio_central_obj_t *self);
-#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H
diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c
index ae83de864..3bf0476ab 100644
--- a/shared-bindings/bleio/Characteristic.c
+++ b/shared-bindings/bleio/Characteristic.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -68,15 +69,15 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
- const mp_obj_t uuid = args[ARG_uuid].u_obj;
+ const mp_obj_t uuid_obj = args[ARG_uuid].u_obj;
- if (!MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) {
+ if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
mp_raise_ValueError(translate("Expected a UUID"));
}
+ bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj);
bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t);
self->base.type = &bleio_characteristic_type;
- self->uuid = MP_OBJ_TO_PTR(uuid);
bleio_characteristic_properties_t properties;
@@ -87,7 +88,8 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t
properties.write = args[ARG_write].u_bool;
properties.write_no_response = args[ARG_write_no_response].u_bool;
- common_hal_bleio_characteristic_construct(self, uuid, properties);
+ // Initialize, with an empty descriptor list.
+ common_hal_bleio_characteristic_construct(self, uuid, properties, mp_obj_new_list(0, NULL));
return MP_OBJ_FROM_PTR(self);
}
@@ -99,7 +101,7 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t
STATIC mp_obj_t bleio_characteristic_get_broadcast(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return mp_obj_new_bool(self->props.broadcast);
+ return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).broadcast);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_broadcast_obj, bleio_characteristic_get_broadcast);
@@ -117,7 +119,7 @@ const mp_obj_property_t bleio_characteristic_broadcast_obj = {
STATIC mp_obj_t bleio_characteristic_get_indicate(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return mp_obj_new_bool(self->props.indicate);
+ return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).indicate);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_indicate_obj, bleio_characteristic_get_indicate);
@@ -136,7 +138,7 @@ const mp_obj_property_t bleio_characteristic_indicate_obj = {
STATIC mp_obj_t bleio_characteristic_get_notify(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return mp_obj_new_bool(self->props.notify);
+ return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).notify);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_notify_obj, bleio_characteristic_get_notify);
@@ -154,7 +156,7 @@ const mp_obj_property_t bleio_characteristic_notify_obj = {
STATIC mp_obj_t bleio_characteristic_get_read(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return mp_obj_new_bool(self->props.read);
+ return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).read);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_read_obj, bleio_characteristic_get_read);
@@ -172,7 +174,7 @@ const mp_obj_property_t bleio_characteristic_read_obj = {
STATIC mp_obj_t bleio_characteristic_get_write(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return mp_obj_new_bool(self->props.write);
+ return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).write);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_obj, bleio_characteristic_get_write);
@@ -190,7 +192,7 @@ const mp_obj_property_t bleio_characteristic_write_obj = {
STATIC mp_obj_t bleio_characteristic_get_write_no_response(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return mp_obj_new_bool(self->props.write_no_response);
+ return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).write_no_response);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_no_response_obj, bleio_characteristic_get_write_no_response);
@@ -204,11 +206,13 @@ const mp_obj_property_t bleio_characteristic_write_no_response_obj = {
//| .. attribute:: uuid
//|
//| The UUID of this characteristic. (read-only)
+//| Will be ``None`` if the 128-bit UUID for this characteristic is not known.
//|
STATIC mp_obj_t bleio_characteristic_get_uuid(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return MP_OBJ_FROM_PTR(self->uuid);
+ bleio_uuid_obj_t *uuid = common_hal_bleio_characteristic_get_uuid(self);
+ return uuid ? MP_OBJ_FROM_PTR(uuid) : mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_uuid_obj, bleio_characteristic_get_uuid);
@@ -228,9 +232,7 @@ const mp_obj_property_t bleio_characteristic_uuid_obj = {
STATIC mp_obj_t bleio_characteristic_get_value(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- common_hal_bleio_characteristic_get_value(self);
-
- return self->value_data;
+ return common_hal_bleio_characteristic_get_value(self);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_value_obj, bleio_characteristic_get_value);
@@ -253,22 +255,80 @@ const mp_obj_property_t bleio_characteristic_value_obj = {
(mp_obj_t)&mp_const_none_obj },
};
+//| .. attribute:: descriptors
+//|
+//| A tuple of `bleio.Descriptor` that describe this characteristic. (read-only)
+//|
+STATIC mp_obj_t bleio_characteristic_get_descriptors(mp_obj_t self_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ // Return list as a tuple so user won't be able to change it.
+ mp_obj_list_t *char_list = common_hal_bleio_characteristic_get_descriptor_list(self);
+ return mp_obj_new_tuple(char_list->len, char_list->items);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_descriptors_obj, bleio_characteristic_get_descriptors);
+
+const mp_obj_property_t bleio_characteristic_descriptors_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_characteristic_get_descriptors_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+//| .. method:: set_cccd(*, notify=False, indicate=False)
+//|
+//| Set the remote characteristic's CCCD to enable or disable notification and indication.
+//|
+//| :param bool notify: True if Characteristic should receive notifications of remote writes
+//| :param float indicate: True if Characteristic should receive indications of remote writes
+//|
+STATIC mp_obj_t bleio_characteristic_set_cccd(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_notify, ARG_indicate };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_notify, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
+ { MP_QSTR_indicate, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ common_hal_bleio_characteristic_set_cccd(self, args[ARG_notify].u_bool, args[ARG_indicate].u_bool);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_characteristic_set_cccd_obj, 1, bleio_characteristic_set_cccd);
+
+
STATIC const mp_rom_map_elem_t bleio_characteristic_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_broadcast), MP_ROM_PTR(&bleio_characteristic_broadcast_obj) },
+ { MP_ROM_QSTR(MP_QSTR_descriptors), MP_ROM_PTR(&bleio_characteristic_descriptors_obj) },
{ MP_ROM_QSTR(MP_QSTR_indicate), MP_ROM_PTR(&bleio_characteristic_indicate_obj) },
{ MP_ROM_QSTR(MP_QSTR_notify), MP_ROM_PTR(&bleio_characteristic_notify_obj) },
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&bleio_characteristic_read_obj) },
+ { MP_ROM_QSTR(MP_QSTR_set_cccd), MP_ROM_PTR(&bleio_characteristic_set_cccd_obj) },
{ MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_characteristic_uuid_obj) },
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&bleio_characteristic_value_obj) },
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&bleio_characteristic_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_write_no_response), MP_ROM_PTR(&bleio_characteristic_write_no_response_obj) },
};
-
STATIC MP_DEFINE_CONST_DICT(bleio_characteristic_locals_dict, bleio_characteristic_locals_dict_table);
+STATIC void bleio_characteristic_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ if (self->uuid) {
+ mp_printf(print, "Characteristic(");
+ bleio_uuid_print(print, MP_OBJ_FROM_PTR(self->uuid), kind);
+ mp_printf(print, ")");
+ } else {
+ mp_printf(print, "<Characteristic with Unregistered UUID>");
+ }
+}
+
const mp_obj_type_t bleio_characteristic_type = {
{ &mp_type_type },
.name = MP_QSTR_Characteristic,
.make_new = bleio_characteristic_make_new,
+ .print = bleio_characteristic_print,
.locals_dict = (mp_obj_dict_t*)&bleio_characteristic_locals_dict
};
diff --git a/shared-bindings/bleio/Characteristic.h b/shared-bindings/bleio/Characteristic.h
index 206cbcd40..d450c42b4 100644
--- a/shared-bindings/bleio/Characteristic.h
+++ b/shared-bindings/bleio/Characteristic.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -27,12 +28,17 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H
+#include "shared-module/bleio/Characteristic.h"
#include "common-hal/bleio/Characteristic.h"
extern const mp_obj_type_t bleio_characteristic_type;
-extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props);
-extern void common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self);
+extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, mp_obj_list_t *descriptor_list);
+extern mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self);
extern void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo);
+extern bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties(bleio_characteristic_obj_t *self);
+extern bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self);
+extern mp_obj_list_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self);
+extern void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H
diff --git a/shared-bindings/bleio/CharacteristicBuffer.c b/shared-bindings/bleio/CharacteristicBuffer.c
index c368de361..26f9e012b 100644
--- a/shared-bindings/bleio/CharacteristicBuffer.c
+++ b/shared-bindings/bleio/CharacteristicBuffer.c
@@ -47,12 +47,15 @@ STATIC void raise_error_if_not_connected(bleio_characteristic_buffer_obj_t *self
//|
//| Accumulates a Characteristic's incoming values in a FIFO buffer.
//|
-//| .. class:: CharacteristicBuffer(Characteristic, *, timeout=1, buffer_size=64)
+//| .. class:: CharacteristicBuffer(characteristic, *, timeout=1, buffer_size=64)
//|
-//| Create a new Characteristic object identified by the specified UUID.
+//| Monitor the given Characteristic. Each time a new value is written to the Characteristic
+//| add the newly-written bytes to a FIFO buffer.
//|
-//| :param bleio.Characteristic characteristic: The characteristic to monitor
-//| :param int timeout: the timeout in seconds to wait for the first character and between subsequent characters.//|
+//| :param bleio.Characteristic characteristic: The Characteristic to monitor.
+//| It may be a local Characteristic provided by a Peripheral Service, or a remote Characteristic
+//| in a remote Service that a Central has connected to.
+//| :param int timeout: the timeout in seconds to wait for the first character and between subsequent characters.
//| :param int buffer_size: Size of ring buffer that stores incoming data coming from client.
//| Must be >= 1.
//|
@@ -85,13 +88,18 @@ STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type,
bleio_characteristic_buffer_obj_t *self = m_new_obj(bleio_characteristic_buffer_obj_t);
self->base.type = &bleio_characteristic_buffer_type;
- self->characteristic = MP_OBJ_TO_PTR(characteristic);
- common_hal_bleio_characteristic_buffer_construct(self, self->characteristic, timeout, buffer_size);
+ common_hal_bleio_characteristic_buffer_construct(self, MP_OBJ_TO_PTR(characteristic), timeout, buffer_size);
return MP_OBJ_FROM_PTR(self);
}
+STATIC void check_for_deinit(bleio_characteristic_buffer_obj_t *self) {
+ if (common_hal_bleio_characteristic_buffer_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
// These are standard stream methods. Code is in py/stream.c.
//
//| .. method:: read(nbytes=None)
@@ -122,7 +130,7 @@ STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type,
// These three methods are used by the shared stream methods.
STATIC mp_uint_t bleio_characteristic_buffer_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_bleio_characteristic_buffer_deinited(self));
+ check_for_deinit(self);
raise_error_if_not_connected(self);
byte *buf = buf_in;
@@ -141,7 +149,7 @@ STATIC mp_uint_t bleio_characteristic_buffer_write(mp_obj_t self_in, const void
STATIC mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_bleio_characteristic_buffer_deinited(self));
+ check_for_deinit(self);
raise_error_if_not_connected(self);
if (!common_hal_bleio_characteristic_buffer_connected(self)) {
mp_raise_ValueError(translate("Not connected"));
@@ -170,7 +178,7 @@ STATIC mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t r
//|
STATIC mp_obj_t bleio_characteristic_buffer_obj_get_in_waiting(mp_obj_t self_in) {
bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_bleio_characteristic_buffer_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_characteristic_buffer_rx_characters_available(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_buffer_get_in_waiting_obj, bleio_characteristic_buffer_obj_get_in_waiting);
@@ -188,7 +196,7 @@ const mp_obj_property_t bleio_characteristic_buffer_in_waiting_obj = {
//|
STATIC mp_obj_t bleio_characteristic_buffer_obj_reset_input_buffer(mp_obj_t self_in) {
bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_bleio_characteristic_buffer_deinited(self));
+ check_for_deinit(self);
common_hal_bleio_characteristic_buffer_clear_rx_buffer(self);
return mp_const_none;
}
diff --git a/shared-bindings/bleio/CharacteristicBuffer.h b/shared-bindings/bleio/CharacteristicBuffer.h
index f25017c19..b45835ff3 100644
--- a/shared-bindings/bleio/CharacteristicBuffer.h
+++ b/shared-bindings/bleio/CharacteristicBuffer.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c
index b32f4f08e..f2e5aa01d 100644
--- a/shared-bindings/bleio/Descriptor.c
+++ b/shared-bindings/bleio/Descriptor.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,27 +31,6 @@
#include "shared-bindings/bleio/Descriptor.h"
#include "shared-bindings/bleio/UUID.h"
-enum {
- DescriptorUuidCharacteristicExtendedProperties = 0x2900,
- DescriptorUuidCharacteristicUserDescription = 0x2901,
- DescriptorUuidClientCharacteristicConfiguration = 0x2902,
- DescriptorUuidServerCharacteristicConfiguration = 0x2903,
- DescriptorUuidCharacteristicPresentationFormat = 0x2904,
- DescriptorUuidCharacteristicAggregateFormat = 0x2905,
- DescriptorUuidValidRange = 0x2906,
- DescriptorUuidExternalReportReference = 0x2907,
- DescriptorUuidReportReference = 0x2908,
- DescriptorUuidNumberOfDigitals = 0x2909,
- DescriptorUuidValueTriggerSetting = 0x290A,
- DescriptorUuidEnvironmentalSensingConfiguration = 0x290B,
- DescriptorUuidEnvironmentalSensingMeasurement = 0x290C,
- DescriptorUuidEnvironmentalSensingTriggerSetting = 0x290D,
- DescriptorUuidTimeTriggerSetting = 0x290E,
-};
-
-// Work-in-progress: orphaned for now.
-//| :orphan:
-//|
//| .. currentmodule:: bleio
//|
//| :class:`Descriptor` -- BLE descriptor
@@ -113,7 +93,9 @@ const mp_obj_property_t bleio_descriptor_handle_obj = {
STATIC mp_obj_t bleio_descriptor_get_uuid(mp_obj_t self_in) {
bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return common_hal_bleio_descriptor_get_uuid(self);
+
+ bleio_uuid_obj_t *uuid = common_hal_bleio_descriptor_get_uuid(self);
+ return uuid ? MP_OBJ_FROM_PTR(uuid) : mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_uuid_obj, bleio_descriptor_get_uuid);
@@ -130,28 +112,69 @@ STATIC const mp_rom_map_elem_t bleio_descriptor_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_descriptor_uuid_obj) },
// Static variables
- { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_EXTENDED_PROPERTIES), MP_ROM_INT(DescriptorUuidCharacteristicExtendedProperties) },
- { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_USER_DESCRIPTION), MP_ROM_INT(DescriptorUuidCharacteristicUserDescription) },
- { MP_ROM_QSTR(MP_QSTR_CLIENT_CHARACTERISTIC_CONFIGURATION), MP_ROM_INT(DescriptorUuidClientCharacteristicConfiguration) },
- { MP_ROM_QSTR(MP_QSTR_SERVER_CHARACTERISTIC_CONFIGURATION), MP_ROM_INT(DescriptorUuidServerCharacteristicConfiguration) },
- { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_PRESENTATION_FORMAT), MP_ROM_INT(DescriptorUuidCharacteristicPresentationFormat) },
- { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_AGGREGATE_FORMAT), MP_ROM_INT(DescriptorUuidCharacteristicAggregateFormat) },
- { MP_ROM_QSTR(MP_QSTR_VALID_RANGE), MP_ROM_INT(DescriptorUuidValidRange) },
- { MP_ROM_QSTR(MP_QSTR_EXTERNAL_REPORT_REFERENCE), MP_ROM_INT(DescriptorUuidExternalReportReference) },
- { MP_ROM_QSTR(MP_QSTR_REPORT_REFERENCE), MP_ROM_INT(DescriptorUuidReportReference) },
- { MP_ROM_QSTR(MP_QSTR_NUMBER_OF_DIGITALS), MP_ROM_INT(DescriptorUuidNumberOfDigitals) },
- { MP_ROM_QSTR(MP_QSTR_VALUE_TRIGGER_SETTING), MP_ROM_INT(DescriptorUuidValueTriggerSetting) },
- { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_CONFIGURATION), MP_ROM_INT(DescriptorUuidEnvironmentalSensingConfiguration) },
- { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_MEASUREMENT ), MP_ROM_INT(DescriptorUuidEnvironmentalSensingMeasurement) },
- { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_TRIGGER_SETTING), MP_ROM_INT(DescriptorUuidEnvironmentalSensingTriggerSetting) },
- { MP_ROM_QSTR(MP_QSTR_TIME_TRIGGER_SETTING), MP_ROM_INT(DescriptorUuidTimeTriggerSetting) }
+ { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_EXTENDED_PROPERTIES),
+ MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_EXTENDED_PROPERTIES) },
+
+ { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_USER_DESCRIPTION),
+ MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_USER_DESCRIPTION) },
+
+ { MP_ROM_QSTR(MP_QSTR_CLIENT_CHARACTERISTIC_CONFIGURATION),
+ MP_ROM_INT(DESCRIPTOR_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION) },
+
+ { MP_ROM_QSTR(MP_QSTR_SERVER_CHARACTERISTIC_CONFIGURATION),
+ MP_ROM_INT(DESCRIPTOR_UUID_SERVER_CHARACTERISTIC_CONFIGURATION) },
+
+ { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_PRESENTATION_FORMAT),
+ MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_PRESENTATION_FORMAT) },
+
+ { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_AGGREGATE_FORMAT),
+ MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_AGGREGATE_FORMAT) },
+
+ { MP_ROM_QSTR(MP_QSTR_VALID_RANGE),
+ MP_ROM_INT(DESCRIPTOR_UUID_VALID_RANGE) },
+
+ { MP_ROM_QSTR(MP_QSTR_EXTERNAL_REPORT_REFERENCE),
+ MP_ROM_INT(DESCRIPTOR_UUID_EXTERNAL_REPORT_REFERENCE) },
+
+ { MP_ROM_QSTR(MP_QSTR_REPORT_REFERENCE),
+ MP_ROM_INT(DESCRIPTOR_UUID_REPORT_REFERENCE) },
+
+ { MP_ROM_QSTR(MP_QSTR_NUMBER_OF_DIGITALS),
+ MP_ROM_INT(DESCRIPTOR_UUID_NUMBER_OF_DIGITALS) },
+
+ { MP_ROM_QSTR(MP_QSTR_VALUE_TRIGGER_SETTING),
+ MP_ROM_INT(DESCRIPTOR_UUID_VALUE_TRIGGER_SETTING) },
+
+ { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_CONFIGURATION),
+ MP_ROM_INT(DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_CONFIGURATION) },
+
+ { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_MEASUREMENT ),
+ MP_ROM_INT(DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_MEASUREMENT) },
+
+ { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_TRIGGER_SETTING),
+ MP_ROM_INT(DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_TRIGGER_SETTING) },
+
+ { MP_ROM_QSTR(MP_QSTR_TIME_TRIGGER_SETTING),
+ MP_ROM_INT(DESCRIPTOR_UUID_TIME_TRIGGER_SETTING) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_descriptor_locals_dict, bleio_descriptor_locals_dict_table);
+STATIC void bleio_descriptor_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ if (self->uuid) {
+ mp_printf(print, "Descriptor(");
+ bleio_uuid_print(print, MP_OBJ_FROM_PTR(self->uuid), kind);
+ mp_printf(print, ")");
+ } else {
+ mp_printf(print, "<Descriptor with Unregistered UUID>");
+ }
+}
+
const mp_obj_type_t bleio_descriptor_type = {
{ &mp_type_type },
.name = MP_QSTR_Descriptor,
.make_new = bleio_descriptor_make_new,
+ .print = bleio_descriptor_print,
.locals_dict = (mp_obj_dict_t*)&bleio_descriptor_locals_dict
};
diff --git a/shared-bindings/bleio/Descriptor.h b/shared-bindings/bleio/Descriptor.h
index f47378ee1..fd11ea08c 100644
--- a/shared-bindings/bleio/Descriptor.h
+++ b/shared-bindings/bleio/Descriptor.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -30,6 +31,24 @@
#include "common-hal/bleio/Descriptor.h"
#include "common-hal/bleio/UUID.h"
+enum {
+ DESCRIPTOR_UUID_CHARACTERISTIC_EXTENDED_PROPERTIES = 0x2900,
+ DESCRIPTOR_UUID_CHARACTERISTIC_USER_DESCRIPTION = 0x2901,
+ DESCRIPTOR_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION = 0x2902,
+ DESCRIPTOR_UUID_SERVER_CHARACTERISTIC_CONFIGURATION = 0x2903,
+ DESCRIPTOR_UUID_CHARACTERISTIC_PRESENTATION_FORMAT = 0x2904,
+ DESCRIPTOR_UUID_CHARACTERISTIC_AGGREGATE_FORMAT = 0x2905,
+ DESCRIPTOR_UUID_VALID_RANGE = 0x2906,
+ DESCRIPTOR_UUID_EXTERNAL_REPORT_REFERENCE = 0x2907,
+ DESCRIPTOR_UUID_REPORT_REFERENCE = 0x2908,
+ DESCRIPTOR_UUID_NUMBER_OF_DIGITALS = 0x2909,
+ DESCRIPTOR_UUID_VALUE_TRIGGER_SETTING = 0x290A,
+ DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_CONFIGURATION = 0x290B,
+ DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_MEASUREMENT = 0x290C,
+ DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_TRIGGER_SETTING = 0x290D,
+ DESCRIPTOR_UUID_TIME_TRIGGER_SETTING = 0x290E,
+};
+
extern const mp_obj_type_t bleio_descriptor_type;
extern void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid);
diff --git a/shared-bindings/bleio/Device.c b/shared-bindings/bleio/Device.c
deleted file mode 100644
index 80595ef33..000000000
--- a/shared-bindings/bleio/Device.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2016 Glenn Ruben Bakke
- * Copyright (c) 2018 Artur Pacholec
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include "ble_drv.h"
-#include "py/objarray.h"
-#include "py/objproperty.h"
-#include "py/objstr.h"
-#include "py/runtime.h"
-#include "shared-bindings/bleio/Adapter.h"
-#include "shared-bindings/bleio/AddressType.h"
-#include "shared-bindings/bleio/Characteristic.h"
-#include "shared-bindings/bleio/Device.h"
-#include "shared-bindings/bleio/Service.h"
-#include "shared-bindings/bleio/UUID.h"
-#include "shared-module/bleio/AdvertisementData.h"
-#include "shared-module/bleio/Device.h"
-#include "shared-module/bleio/ScanEntry.h"
-
-// Work-in-progress: orphaned for now.
-//| :orphan:
-//|
-//| .. currentmodule:: bleio
-//|
-//| :class:`Device` -- BLE device
-//| =========================================================
-//|
-//| **IGNORE ``Device`` and all its documentation.
-//| It is being replaced by `Peripheral` and other classes.**
-//|
-//| Provides access a to BLE device, either in a Peripheral or Central role.
-//| When a device is created without any parameter passed to the constructor,
-//| it will be set to the Peripheral role. If a address is passed, the device
-//| will be a Central. For a Peripheral you can set the `name`, add services
-//| via `add_service` and then start and stop advertising via `bleio.Device.start_advertising`
-//| and `bleio.Device.stop_advertising`. For the Central, you can `bleio.Device.connect` and `bleio.Device.disconnect`
-//| to the device, once a connection is established, the device's services can
-//| be accessed using `bleio.Device.services`.
-//|
-//| Usage::
-//|
-//| import bleio
-//|
-//| # Peripheral
-//| periph = bleio.Device()
-//|
-//| serv = bleio.Service(bleio.UUID(0x180f))
-//| p.add_service(serv)
-//|
-//| chara = bleio.Characteristic(bleio.UUID(0x2919))
-//| chara.read = True
-//| chara.notify = True
-//| serv.add_characteristic(chara)
-//|
-//| periph.start_advertising()
-//|
-//| # Central
-//| scanner = bleio.Scanner()
-//| entries = scanner.scan(2500)
-//|
-//| my_entry = None
-//| for entry in entries:
-//| if entry.name is not None and entry.name == 'MyDevice':
-//| my_entry = entry
-//| break
-//|
-//| central = bleio.Device(my_entry.address)
-//| central.connect()
-//|
-
-//| .. class:: Device(address=None, scan_entry=None)
-//|
-//| Create a new Device object. If the `address` or :py:data:`scan_entry` parameters are not `None`,
-//| the role is set to Central, otherwise it's set to Peripheral.
-//|
-//| :param bleio.Address address: The address of the device to connect to
-//| :param bleio.ScanEntry scan_entry: The scan entry returned from `bleio.Scanner`
-//|
-
-//| .. attribute:: name
-//|
-//| For the Peripheral role, this property can be used to read and write the device's name.
-//| For the Central role, this property will equal the name of the remote device, if one was
-//| advertised by the device. In the Central role this property is read-only.
-//|
-
-//| .. attribute:: services
-//|
-//| A `list` of `bleio.Service` that are offered by this device. (read-only)
-//| For a Peripheral device, this list will contain services added using `add_service`,
-//| for a Central, this list will be empty until a connection is established, at which point
-//| it will be filled with the remote device's services.
-//|
-
-//| .. method:: add_service(service)
-//|
-//| Appends the :py:data:`service` to the list of this devices's services.
-//| This method can only be called for Peripheral devices.
-//|
-//| :param bleio.Service service: the service to append
-//|
-
-//| .. method:: connect()
-//|
-//| Attempts a connection to the remote device. If the connection is successful,
-//| the device's services are available via `services`.
-//| This method can only be called for Central devices.
-//|
-
-//| .. method:: disconnect()
-//|
-//| Disconnects from the remote device.
-//| This method can only be called for Central devices.
-//|
-
-//| .. method:: start_advertising(connectable=True)
-//|
-//| Starts advertising the device. The device's name and
-//| services are put into the advertisement packets.
-//| If :py:data:`connectable` is `True` then other devices are allowed to conncet to this device.
-//| This method can only be called for Peripheral devices.
-//|
-
-//| .. method:: stop_advertising()
-//|
-//| Disconnects from the remote device.
-//| This method can only be called for Peripheral devices.
-//|
-
-// TODO: Add unique MAC address part to name
-static const char default_name[] = "CIRCUITPY";
-
-STATIC void bleio_device_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- mp_printf(print, "Device(role: %s)", self->is_peripheral ? "Peripheral" : "Central");
-}
-
-STATIC mp_obj_t bleio_device_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
- mp_arg_check_num(n_args, n_kw, 0, 1, true);
- bleio_device_obj_t *self = m_new_obj(bleio_device_obj_t);
- self->base.type = &bleio_device_type;
- self->service_list = mp_obj_new_list(0, NULL);
- self->notif_handler = mp_const_none;
- self->conn_handler = mp_const_none;
- self->conn_handle = 0xFFFF;
- self->is_peripheral = true;
-
- mp_map_t kw_args;
- mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
-
- enum { ARG_address, ARG_scan_entry };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_address, MP_ARG_OBJ, {.u_obj = mp_const_none} },
- { MP_QSTR_scan_entry, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
- };
-
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- const mp_obj_t address_obj = args[ARG_address].u_obj;
- const mp_obj_t scan_entry_obj = args[ARG_scan_entry].u_obj;
-
- if (address_obj != mp_const_none) {
- bleio_address_obj_t *address = MP_OBJ_TO_PTR(address_obj);
-
- self->is_peripheral = false;
- self->address.type = address->type;
- memcpy(self->address.value, address->value, BLEIO_ADDRESS_BYTES);
- } else if (scan_entry_obj != mp_const_none) {
- bleio_scanentry_obj_t *scan_entry = MP_OBJ_TO_PTR(scan_entry_obj);
-
- self->is_peripheral = false;
- self->address.type = scan_entry->address.type;
- memcpy(self->address.value, scan_entry->address.value, BLEIO_ADDRESS_BYTES);
- } else {
- self->name = mp_obj_new_str(default_name, strlen(default_name));
- common_hal_bleio_adapter_get_address(&self->address);
- }
-
- return MP_OBJ_FROM_PTR(self);
-}
-
-STATIC mp_obj_t bleio_device_add_service(mp_obj_t self_in, mp_obj_t service_in) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
- bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_in);
-
- if (!self->is_peripheral) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- translate("Can't add services in Central mode")));
- }
-
- service->device = self;
-
- mp_obj_list_append(self->service_list, service);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_device_add_service_obj, bleio_device_add_service);
-
-STATIC mp_obj_t bleio_device_connect(mp_obj_t self_in) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- if (self->is_peripheral) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- translate("Can't connect in Peripheral mode")));
- }
-
- common_hal_bleio_device_connect(self);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_connect_obj, bleio_device_connect);
-
-STATIC mp_obj_t bleio_device_disconnect(mp_obj_t self_in) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- common_hal_bleio_device_disconnect(self);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_disconnect_obj, bleio_device_disconnect);
-
-STATIC mp_obj_t bleio_device_get_name(mp_obj_t self_in) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return self->name;
-}
-MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_get_name_obj, bleio_device_get_name);
-
-static mp_obj_t bleio_device_set_name(mp_obj_t self_in, mp_obj_t value) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- if (!self->is_peripheral) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- translate("Can't change the name in Central mode")));
- }
-
- self->name = value;
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_device_set_name_obj, bleio_device_set_name);
-
-const mp_obj_property_t bleio_device_name_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_device_get_name_obj,
- (mp_obj_t)&bleio_device_set_name_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-STATIC mp_obj_t bleio_device_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
-
- if (!self->is_peripheral) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- translate("Can't advertise in Central mode")));
- }
-
- enum { ARG_connectable, ARG_data };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
- { MP_QSTR_data, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
- };
-
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- mp_buffer_info_t bufinfo = { 0 };
- if (args[ARG_data].u_obj != mp_const_none) {
- mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ);
- }
-
- const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list);
- for (size_t i = 0; i < service_list->len; ++i) {
- bleio_service_obj_t *service = service_list->items[i];
- if (service->handle == 0xFFFF) {
- common_hal_bleio_device_add_service(self, service);
- }
- }
-
- common_hal_bleio_device_start_advertising(self, args[ARG_connectable].u_bool, &bufinfo);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_device_start_advertising_obj, 0, bleio_device_start_advertising);
-
-STATIC mp_obj_t bleio_device_stop_advertising(mp_obj_t self_in) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- if (!self->is_peripheral) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- translate("Can't advertise in Central mode")));
- }
-
- common_hal_bleio_device_stop_advertising(self);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_stop_advertising_obj, bleio_device_stop_advertising);
-
-STATIC mp_obj_t bleio_device_get_services(mp_obj_t self_in) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return self->service_list;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_get_services_obj, bleio_device_get_services);
-
-const mp_obj_property_t bleio_device_services_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_device_get_services_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-STATIC const mp_rom_map_elem_t bleio_device_locals_dict_table[] = {
- // Methods
- { MP_ROM_QSTR(MP_QSTR_add_service), MP_ROM_PTR(&bleio_device_add_service_obj) },
- { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_device_connect_obj) },
- { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_device_disconnect_obj) },
- { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_device_start_advertising_obj) },
- { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_device_stop_advertising_obj) },
-
- // Properties
- { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_device_name_obj) },
- { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_device_services_obj) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(bleio_device_locals_dict, bleio_device_locals_dict_table);
-
-const mp_obj_type_t bleio_device_type = {
- { &mp_type_type },
- .name = MP_QSTR_Device,
- .print = bleio_device_print,
- .make_new = bleio_device_make_new,
- .locals_dict = (mp_obj_dict_t*)&bleio_device_locals_dict
-};
diff --git a/shared-bindings/bleio/Peripheral.c b/shared-bindings/bleio/Peripheral.c
index 340485f35..570896d27 100644
--- a/shared-bindings/bleio/Peripheral.c
+++ b/shared-bindings/bleio/Peripheral.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -35,19 +36,22 @@
#include "py/runtime.h"
#include "shared-bindings/bleio/Adapter.h"
-#include "shared-bindings/bleio/AddressType.h"
#include "shared-bindings/bleio/Characteristic.h"
#include "shared-bindings/bleio/Peripheral.h"
#include "shared-bindings/bleio/Service.h"
#include "shared-bindings/bleio/UUID.h"
-#include "shared-module/bleio/AdvertisementData.h"
#include "shared-module/bleio/ScanEntry.h"
#include "common-hal/bleio/Peripheral.h"
-// TODO: Add unique MAC address part to name
static const char default_name[] = "CIRCUITPY";
+#define ADV_INTERVAL_DEFAULT (1.0f)
+#define ADV_INTERVAL_MIN (0.0020f)
+#define ADV_INTERVAL_MIN_STRING "0.0020"
+#define ADV_INTERVAL_MAX (10.24f)
+#define ADV_INTERVAL_MAX_STRING "10.24"
+
//| .. currentmodule:: bleio
//|
//| :class:`Peripheral` -- A BLE peripheral device
@@ -59,6 +63,7 @@ static const char default_name[] = "CIRCUITPY";
//| Usage::
//|
//| import bleio
+//| from adafruit_ble.advertising import ServerAdvertisement
//|
//| # Create a Characteristic.
//| chara = bleio.Characteristic(bleio.UUID(0x2919), read=True, notify=True)
@@ -67,26 +72,28 @@ static const char default_name[] = "CIRCUITPY";
//| serv = bleio.Service(bleio.UUID(0x180f), [chara])
//|
//| # Create a peripheral and start it up.
-//| periph = bleio.Peripheral([service])
-//| periph.start_advertising()
+//| periph = bleio.Peripheral([serv])
+//| adv = ServerAdvertisement(periph)
+//| periph.start_advertising(adv.advertising_data_bytes, adv.scan_response_bytes)
//|
//| while not periph.connected:
//| # Wait for connection.
//| pass
//|
-//| .. class:: Peripheral(services, *, name='CIRCUITPY')
+//| .. class:: Peripheral(services=(), \*, name='CIRCUITPY')
//|
//| Create a new Peripheral object.
-
-//| :param iterable services: the Service objects representing services available from this peripheral.
-//| :param str name: The name used when advertising this peripheral
//|
-
+//| :param iterable services: the Service objects representing services available from this peripheral, if any.
+//| A non-connectable peripheral will have no services.
+//| :param str name: The name used when advertising this peripheral. Use ``None`` when a name is not needed,
+//| such as when the peripheral is a beacon
+//|
STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_services, ARG_name };
static const mp_arg_t allowed_args[] = {
- { MP_QSTR_services, MP_ARG_OBJ, {.u_obj = mp_const_none} },
- { MP_QSTR_name, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
+ { MP_QSTR_services, MP_ARG_OBJ, {.u_obj = mp_const_empty_tuple} },
+ { MP_QSTR_name, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@@ -95,32 +102,33 @@ STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_ar
// If services is not an iterable, an exception will be thrown.
mp_obj_iter_buf_t iter_buf;
mp_obj_t iterable = mp_getiter(args[ARG_services].u_obj, &iter_buf);
- mp_obj_t service;
bleio_peripheral_obj_t *self = m_new_obj(bleio_peripheral_obj_t);
self->base.type = &bleio_peripheral_type;
- self->service_list = mp_obj_new_list(0, NULL);
- self->notif_handler = mp_const_none;
+
+ // Copy the services list and validate its items.
+ mp_obj_t service_list_obj = mp_obj_new_list(0, NULL);
+ mp_obj_list_t *service_list = MP_OBJ_FROM_PTR(service_list_obj);
+
+ mp_obj_t service;
while ((service = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
if (!MP_OBJ_IS_TYPE(service, &bleio_service_type)) {
- mp_raise_ValueError(translate("services includes an object that is not a Service"));
+ mp_raise_ValueError(translate("non-Service found in services"));
}
- bleio_service_obj_t *service_ptr = MP_OBJ_TO_PTR(service);
- service_ptr->device = MP_OBJ_FROM_PTR(self);
- mp_obj_list_append(self->service_list, service);
+ mp_obj_list_append(service_list, service);
}
const mp_obj_t name = args[ARG_name].u_obj;
- if (name == mp_const_none) {
- self->name = mp_obj_new_str(default_name, strlen(default_name));
+ mp_obj_t name_str;
+ if (name == MP_OBJ_NULL || name == mp_const_none) {
+ name_str = mp_obj_new_str(default_name, strlen(default_name));
} else if (MP_OBJ_IS_STR(name)) {
- self->name = name;
+ name_str = name;
} else {
mp_raise_ValueError(translate("name must be a string"));
}
- // Do port-specific initialization.
- common_hal_bleio_peripheral_construct(self);
+ common_hal_bleio_peripheral_construct(self, service_list, name_str);
return MP_OBJ_FROM_PTR(self);
}
@@ -132,7 +140,6 @@ STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_ar
STATIC mp_obj_t bleio_peripheral_get_connected(mp_obj_t self_in) {
bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
- // Return list as a tuple so user won't be able to change it.
return mp_obj_new_bool(common_hal_bleio_peripheral_get_connected(self));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_connected_obj, bleio_peripheral_get_connected);
@@ -151,7 +158,7 @@ const mp_obj_property_t bleio_peripheral_connected_obj = {
STATIC mp_obj_t bleio_peripheral_get_services(mp_obj_t self_in) {
bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
// Return list as a tuple so user won't be able to change it.
- mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list);
+ mp_obj_list_t *service_list = common_hal_bleio_peripheral_get_service_list(self);
return mp_obj_new_tuple(service_list->len, service_list->items);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_services_obj, bleio_peripheral_get_services);
@@ -170,7 +177,7 @@ const mp_obj_property_t bleio_peripheral_services_obj = {
STATIC mp_obj_t bleio_peripheral_get_name(mp_obj_t self_in) {
bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return self->name;
+ return common_hal_bleio_peripheral_get_name(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_name_obj, bleio_peripheral_get_name);
@@ -181,37 +188,55 @@ const mp_obj_property_t bleio_peripheral_name_obj = {
(mp_obj_t)&mp_const_none_obj },
};
-//| .. method:: start_advertising(*, connectable=True, data=None)
+//| .. method:: start_advertising(data, *, scan_response=None, connectable=True, interval=1)
//|
//| Starts advertising the peripheral. The peripheral's name and
//| services are included in the advertisement packets.
//|
+//| :param buf data: advertising data packet bytes
+//| :param buf scan_response: scan response data packet bytes. ``None`` if no scan response is needed.
//| :param bool connectable: If `True` then other devices are allowed to connect to this peripheral.
-//| :param buf data: If `None`, advertise the services passed to this Peripheral when it was created.
-//| If not `None`, then send the bytes in ``data`` as the advertising packet.
+//| :param float interval: advertising interval, in seconds
//|
STATIC mp_obj_t bleio_peripheral_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- enum { ARG_connectable, ARG_data };
+ enum { ARG_data, ARG_scan_response, ARG_connectable, ARG_interval };
static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_scan_response, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
- { MP_QSTR_data, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
- mp_buffer_info_t bufinfo = { 0 };
- if (args[ARG_data].u_obj != mp_const_none) {
- mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ);
+ mp_buffer_info_t data_bufinfo;
+ mp_get_buffer_raise(args[ARG_data].u_obj, &data_bufinfo, MP_BUFFER_READ);
+
+ // Pass an empty buffer if scan_response not provided.
+ mp_buffer_info_t scan_response_bufinfo = { 0 };
+ if (args[ARG_scan_response].u_obj != mp_const_none) {
+ mp_get_buffer_raise(args[ARG_scan_response].u_obj, &scan_response_bufinfo, MP_BUFFER_READ);
}
- common_hal_bleio_peripheral_start_advertising(self, args[ARG_connectable].u_bool, &bufinfo);
+ if (args[ARG_interval].u_obj == MP_OBJ_NULL) {
+ args[ARG_interval].u_obj = mp_obj_new_float(1.0F);
+ }
+
+ const mp_float_t interval = mp_obj_float_get(args[ARG_interval].u_obj);
+ if (interval < ADV_INTERVAL_MIN || interval > ADV_INTERVAL_MAX) {
+ mp_raise_ValueError_varg(translate("interval must be in range %s-%s"),
+ ADV_INTERVAL_MIN_STRING, ADV_INTERVAL_MAX_STRING);
+ }
+
+ common_hal_bleio_peripheral_start_advertising(self, args[ARG_connectable].u_bool, interval,
+ &data_bufinfo, &scan_response_bufinfo);
return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_peripheral_start_advertising_obj, 0, bleio_peripheral_start_advertising);
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_peripheral_start_advertising_obj, 2, bleio_peripheral_start_advertising);
//| .. method:: stop_advertising()
//|
@@ -225,10 +250,26 @@ STATIC mp_obj_t bleio_peripheral_stop_advertising(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_stop_advertising_obj, bleio_peripheral_stop_advertising);
+//| .. method:: disconnect()
+//|
+//| Disconnects from the remote central.
+//| Normally the central initiates a disconnection. Use this only
+//| if necessary for your application.
+//|
+STATIC mp_obj_t bleio_peripheral_disconnect(mp_obj_t self_in) {
+ bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ common_hal_bleio_peripheral_disconnect(self);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_disconnect_obj, bleio_peripheral_disconnect);
+
STATIC const mp_rom_map_elem_t bleio_peripheral_locals_dict_table[] = {
// Methods
{ MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_peripheral_start_advertising_obj) },
{ MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_peripheral_stop_advertising_obj) },
+ { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_peripheral_disconnect_obj) },
// Properties
{ MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_peripheral_connected_obj) },
diff --git a/shared-bindings/bleio/Peripheral.h b/shared-bindings/bleio/Peripheral.h
index 02a5c1ef8..846250a5f 100644
--- a/shared-bindings/bleio/Peripheral.h
+++ b/shared-bindings/bleio/Peripheral.h
@@ -3,8 +3,8 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
- * Copyright (c) 2018 Dan Halbert for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -32,9 +32,12 @@
extern const mp_obj_type_t bleio_peripheral_type;
-extern void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self);
+extern void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_list_t *service_list, mp_obj_t name);
+extern mp_obj_list_t *common_hal_bleio_peripheral_get_service_list(bleio_peripheral_obj_t *self);
extern bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self);
-extern void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *device, bool connectable, mp_buffer_info_t *raw_data);
+extern mp_obj_t common_hal_bleio_peripheral_get_name(bleio_peripheral_obj_t *self);
+extern void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *device, bool connectable, float interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo);
extern void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *device);
+extern void common_hal_bleio_peripheral_disconnect(bleio_peripheral_obj_t *device);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H
diff --git a/shared-bindings/bleio/ScanEntry.c b/shared-bindings/bleio/ScanEntry.c
index e6b955078..6eb02c716 100644
--- a/shared-bindings/bleio/ScanEntry.c
+++ b/shared-bindings/bleio/ScanEntry.c
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
* Copyright (c) 2017 Glenn Ruben Bakke
*
@@ -27,278 +28,78 @@
#include <string.h>
-#include "py/objarray.h"
#include "py/objproperty.h"
-#include "py/objstr.h"
-#include "py/objtuple.h"
#include "shared-bindings/bleio/Address.h"
#include "shared-bindings/bleio/ScanEntry.h"
#include "shared-bindings/bleio/UUID.h"
-#include "shared-module/bleio/AdvertisementData.h"
#include "shared-module/bleio/ScanEntry.h"
-// Work-in-progress: orphaned for now.
-//| :orphan:
-//|
//| .. currentmodule:: bleio
//|
//| :class:`ScanEntry` -- BLE scan response entry
//| =========================================================
//|
//| Encapsulates information about a device that was received as a
-//| response to a BLE scan request.
+//| response to a BLE scan request. This object may only be created
+//| by a `bleio.Scanner`: it has no user-visible constructor.
//|
//| .. attribute:: address
//|
-//| The address of the device. (read-only)
-//| This attribute is of type `bleio.Address`.
-//|
-
-//| .. attribute:: manufacturer_specific_data
-//|
-//| The manufacturer-specific data present in the advertisement packet. (read-only)
-//|
-
-//| .. attribute:: name
-//|
-//| The name of the device. (read-only)
-//| This attribute might be `None` if the data was missing from the advertisement packet.
-//|
-
-//| .. attribute:: raw_data
-//|
-//| All the advertisement data present in the packet. (read-only)
+//| The address of the device (read-only), of type `bleio.Address`.
//|
-
-//| .. attribute:: rssi
-//|
-//| The signal strength of the device at the time of the scan. (read-only)
-//|
-
-//| .. attribute:: service_uuids
-//|
-//| The address of the device. (read-only)
-//| This attribute is a list of `bleio.UUID`.
-//| This attribute might be empty or incomplete, depending on the advertisement packet.
-//| Currently only 16-bit UUIDS are listed.
-//|
-
-//| .. attribute:: tx_power_level
-//|
-//| The transmit power level of the device. (read-only)
-//| This attribute might be `None` if the data was missing from the advertisement packet.
-//|
-static uint8_t find_data_item(mp_obj_array_t *data_in, uint8_t type, uint8_t **data_out) {
- uint16_t i = 0;
- while (i < data_in->len) {
- const uint8_t item_len = ((uint8_t*)data_in->items)[i];
- const uint8_t item_type = ((uint8_t*)data_in->items)[i + 1];
- if (item_type != type) {
- i += (item_len + 1);
- continue;
- }
-
- *data_out = &((uint8_t*)data_in->items)[i + 2];
-
- return item_len;
- }
-
- return 0;
-}
-
-STATIC mp_obj_t scanentry_get_name(mp_obj_t self_in);
-
-STATIC void bleio_scanentry_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
- bleio_scanentry_obj_t *self = (bleio_scanentry_obj_t *)self_in;
- mp_printf(print, "ScanEntry(address: %02x:%02x:%02x:%02x:%02x:%02x",
- self->address.value[5], self->address.value[4], self->address.value[3],
- self->address.value[1], self->address.value[1], self->address.value[0]);
-
- const mp_obj_t name_obj = scanentry_get_name(self_in);
- if (name_obj != mp_const_none) {
- mp_obj_str_t *str = MP_OBJ_TO_PTR(name_obj);
- mp_printf(print, " name: %s", str->data);
- }
-
- mp_print_str(print, ")");
-}
-
STATIC mp_obj_t bleio_scanentry_get_address(mp_obj_t self_in) {
bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- mp_obj_t obj = bleio_address_type.make_new(&bleio_address_type, 1, 0, (mp_obj_t)&mp_const_none_obj);
- bleio_address_obj_t *address = MP_OBJ_TO_PTR(obj);
-
- address->type = self->address.type;
- memcpy(address->value, self->address.value, BLEIO_ADDRESS_BYTES);
-
- return obj;
+ return common_hal_bleio_scanentry_get_address(self);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_address_obj, bleio_scanentry_get_address);
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_address_obj, bleio_scanentry_get_address);
const mp_obj_property_t bleio_scanentry_address_obj = {
.base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bluepy_scanentry_get_address_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-STATIC mp_obj_t scanentry_get_manufacturer_specific_data(mp_obj_t self_in) {
- bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
- mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data);
- uint8_t *manuf_data;
-
- const uint8_t manuf_data_len = find_data_item(data, AdManufacturerSpecificData, &manuf_data);
- if (manuf_data_len == 0) {
- return mp_const_none;
- }
-
- return mp_obj_new_bytearray_by_ref(manuf_data_len, manuf_data);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_manufacturer_specific_data_obj, scanentry_get_manufacturer_specific_data);
-
-const mp_obj_property_t bleio_scanentry_manufacturer_specific_data_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&scanentry_get_manufacturer_specific_data_obj,
+ .proxy = { (mp_obj_t)&bleio_scanentry_get_address_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj },
};
-STATIC mp_obj_t scanentry_get_name(mp_obj_t self_in) {
- bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
- mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data);
- uint8_t *name;
-
- // Try for Complete but settle for Shortened
- uint8_t name_len = find_data_item(data, AdCompleteLocalName, &name);
- if (name_len == 0) {
- name_len = find_data_item(data, AdShortenedLocalName, &name);
- }
-
- if (name_len == 0) {
- return mp_const_none;
- }
-
- return mp_obj_new_str((const char*)name, name_len - 1);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_name_obj, scanentry_get_name);
-
-const mp_obj_property_t bleio_scanentry_name_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bluepy_scanentry_get_name_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-STATIC mp_obj_t scanentry_get_raw_data(mp_obj_t self_in) {
+//| .. attribute:: advertisement_bytes
+//|
+//| All the advertisement data present in the packet, returned as a ``bytes`` object. (read-only)
+//|
+STATIC mp_obj_t scanentry_get_advertisement_bytes(mp_obj_t self_in) {
bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- mp_obj_t entries = mp_obj_new_list(0, NULL);
-
- mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data);
-
- uint16_t i = 0;
- while (i < data->len) {
- mp_obj_tuple_t *entry = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
-
- const uint8_t item_len = ((uint8_t*)data->items)[i];
- const uint8_t item_type = ((uint8_t*)data->items)[i + 1];
-
- entry->items[0] = MP_OBJ_NEW_SMALL_INT(item_type);
- entry->items[1] = mp_obj_new_bytearray(item_len - 1, &((uint8_t*)data->items)[i + 2]);
- mp_obj_list_append(entries, MP_OBJ_FROM_PTR(entry));
-
- i += (item_len + 1);
- }
-
- return entries;
+ return common_hal_bleio_scanentry_get_advertisement_bytes(self);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_raw_data_obj, scanentry_get_raw_data);
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_advertisement_bytes_obj, scanentry_get_advertisement_bytes);
-const mp_obj_property_t bleio_scanentry_raw_data_obj = {
+const mp_obj_property_t bleio_scanentry_advertisement_bytes_obj = {
.base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_scanentry_get_raw_data_obj,
+ .proxy = { (mp_obj_t)&bleio_scanentry_get_advertisement_bytes_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj },
};
+//| .. attribute:: rssi
+//|
+//| The signal strength of the device at the time of the scan, in integer dBm. (read-only)
+//|
STATIC mp_obj_t scanentry_get_rssi(mp_obj_t self_in) {
bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return mp_obj_new_int(self->rssi);
+ return mp_obj_new_int(common_hal_bleio_scanentry_get_rssi(self));
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_rssi_obj, scanentry_get_rssi);
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_rssi_obj, scanentry_get_rssi);
const mp_obj_property_t bleio_scanentry_rssi_obj = {
.base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bluepy_scanentry_get_rssi_obj,
+ .proxy = { (mp_obj_t)&bleio_scanentry_get_rssi_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj },
};
-STATIC mp_obj_t scanentry_get_service_uuids(mp_obj_t self_in) {
- bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
- mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data);
- uint8_t *uuids;
-
- // Try for Complete but settle for Incomplete
- uint8_t uuids_len = find_data_item(data, AdCompleteListOf16BitServiceClassUUIDs, &uuids);
- if (uuids_len == 0) {
- uuids_len = find_data_item(data, AdIncompleteListOf16BitServiceClassUUIDs, &uuids);
- }
-
- mp_obj_t entries = mp_obj_new_list(0, NULL);
- for (size_t i = 0; i < uuids_len / sizeof(uint16_t); ++i) {
- const mp_obj_t uuid_int = mp_obj_new_int(uuids[sizeof(uint16_t) * i] | (uuids[sizeof(uint16_t) * i + 1] << 8));
- const mp_obj_t uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, &uuid_int, NULL);
-
- mp_obj_list_append(entries, uuid_obj);
- }
-
- // TODO: 32-bit UUIDs
- // TODO: 128-bit UUIDs
-
- return entries;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_service_uuids_obj, scanentry_get_service_uuids);
-
-const mp_obj_property_t bleio_scanentry_service_uuids_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&scanentry_get_service_uuids_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-STATIC mp_obj_t scanentry_get_tx_power_level(mp_obj_t self_in) {
- bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
- mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data);
- uint8_t *tx_power;
-
- const uint8_t tx_power_len = find_data_item(data, AdTxPowerLevel, &tx_power);
- if (tx_power_len == 0) {
- return mp_const_none;
- }
-
- return mp_obj_new_int((int8_t)(*tx_power));
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_tx_power_level_obj, scanentry_get_tx_power_level);
-
-const mp_obj_property_t bleio_scanentry_tx_power_level_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&scanentry_get_tx_power_level_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
STATIC const mp_rom_map_elem_t bleio_scanentry_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_scanentry_address_obj) },
- { MP_ROM_QSTR(MP_QSTR_manufacturer_specific_data), MP_ROM_PTR(&bleio_scanentry_manufacturer_specific_data_obj) },
- { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_scanentry_name_obj) },
- { MP_ROM_QSTR(MP_QSTR_raw_data), MP_ROM_PTR(&bleio_scanentry_raw_data_obj) },
- { MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&bleio_scanentry_rssi_obj) },
- { MP_ROM_QSTR(MP_QSTR_service_uuids), MP_ROM_PTR(&bleio_scanentry_service_uuids_obj) },
- { MP_ROM_QSTR(MP_QSTR_tx_power_level), MP_ROM_PTR(&bleio_scanentry_tx_power_level_obj) },
+ { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_scanentry_address_obj) },
+ { MP_ROM_QSTR(MP_QSTR_advertisement_bytes), MP_ROM_PTR(&bleio_scanentry_advertisement_bytes_obj) },
+ { MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&bleio_scanentry_rssi_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_scanentry_locals_dict, bleio_scanentry_locals_dict_table);
@@ -306,6 +107,5 @@ STATIC MP_DEFINE_CONST_DICT(bleio_scanentry_locals_dict, bleio_scanentry_locals_
const mp_obj_type_t bleio_scanentry_type = {
{ &mp_type_type },
.name = MP_QSTR_ScanEntry,
- .print = bleio_scanentry_print,
.locals_dict = (mp_obj_dict_t*)&bleio_scanentry_locals_dict
};
diff --git a/shared-bindings/bleio/ScanEntry.h b/shared-bindings/bleio/ScanEntry.h
index 2b44ba3f4..77e93175f 100644
--- a/shared-bindings/bleio/ScanEntry.h
+++ b/shared-bindings/bleio/ScanEntry.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
* Copyright (c) 2017 Glenn Ruben Bakke
*
@@ -29,7 +30,12 @@
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H
#include "py/obj.h"
+#include "shared-module/bleio/ScanEntry.h"
extern const mp_obj_type_t bleio_scanentry_type;
+mp_obj_t common_hal_bleio_scanentry_get_address(bleio_scanentry_obj_t *self);
+mp_obj_t common_hal_bleio_scanentry_get_advertisement_bytes(bleio_scanentry_obj_t *self);
+mp_int_t common_hal_bleio_scanentry_get_rssi(bleio_scanentry_obj_t *self);
+
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H
diff --git a/shared-bindings/bleio/Scanner.c b/shared-bindings/bleio/Scanner.c
index f5424f706..269c42591 100644
--- a/shared-bindings/bleio/Scanner.c
+++ b/shared-bindings/bleio/Scanner.c
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -29,132 +30,93 @@
#include "shared-bindings/bleio/ScanEntry.h"
#include "shared-bindings/bleio/Scanner.h"
-#define DEFAULT_INTERVAL 100
-#define DEFAULT_WINDOW 100
+#define INTERVAL_DEFAULT (0.1f)
+#define INTERVAL_MIN (0.0025f)
+#define INTERVAL_MIN_STRING "0.0025"
+#define INTERVAL_MAX (40.959375f)
+#define INTERVAL_MAX_STRING "40.959375"
+#define WINDOW_DEFAULT (0.1f)
-// Work-in-progress: orphaned for now.
-//| :orphan:
-//|
//| .. currentmodule:: bleio
//|
//| :class:`Scanner` -- scan for nearby BLE devices
//| =========================================================
//|
-//| Allows scanning for nearby BLE devices.
+//| Scan for nearby BLE devices.
//|
//| Usage::
//|
//| import bleio
//| scanner = bleio.Scanner()
-//| entries = scanner.scan(2500)
-//| print(entries)
+//| entries = scanner.scan(2.5) # Scan for 2.5 seconds
//|
//| .. class:: Scanner()
//|
//| Create a new Scanner object.
//|
-
-//| .. attribute:: interval
-//|
-//| The interval (in ms) between the start of two consecutive scan windows.
-//| Allowed values are between 10ms and 10.24 sec.
-//|
-
-//| .. attribute:: window
-//|
-//| The duration (in ms) in which a single BLE channel is scanned.
-//| Allowed values are between 10ms and 10.24 sec.
-//|
-
-//| .. method:: scan(timeout)
-//|
-//| Performs a BLE scan.
-//|
-//| :param int timeout: the scan timeout in ms
-//| :returns: advertising packets found
-//| :rtype: list of :py:class:`bleio.ScanEntry`
-//|
-STATIC void bleio_scanner_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
- bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- mp_printf(print, "Scanner(interval: %d window: %d)", self->interval, self->window);
-}
-
STATIC mp_obj_t bleio_scanner_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args) {
mp_arg_check_num(n_args, kw_args, 0, 0, false);
bleio_scanner_obj_t *self = m_new_obj(bleio_scanner_obj_t);
self->base.type = type;
- self->interval = DEFAULT_INTERVAL;
- self->window = DEFAULT_WINDOW;
+ common_hal_bleio_scanner_construct(self);
return MP_OBJ_FROM_PTR(self);
}
-STATIC mp_obj_t bleio_scanner_get_interval(mp_obj_t self_in) {
- bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return mp_obj_new_int(self->interval);
-}
-MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanner_get_interval_obj, bleio_scanner_get_interval);
-
-static mp_obj_t bleio_scanner_set_interval(mp_obj_t self_in, mp_obj_t value) {
- bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- self->interval = mp_obj_get_int(value);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_scanner_set_interval_obj, bleio_scanner_set_interval);
-
-const mp_obj_property_t bleio_scanner_interval_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_scanner_get_interval_obj,
- (mp_obj_t)&bleio_scanner_set_interval_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-STATIC mp_obj_t scanner_scan(mp_obj_t self_in, mp_obj_t timeout_in) {
- bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
- const mp_int_t timeout = mp_obj_get_int(timeout_in);
-
- self->adv_reports = mp_obj_new_list(0, NULL);
-
- common_hal_bleio_scanner_scan(self, timeout);
-
- return self->adv_reports;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_scanner_scan_obj, scanner_scan);
-
-STATIC mp_obj_t bleio_scanner_get_window(mp_obj_t self_in) {
- bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return mp_obj_new_int(self->window);
-}
-MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanner_get_window_obj, bleio_scanner_get_window);
-
-static mp_obj_t bleio_scanner_set_window(mp_obj_t self_in, mp_obj_t value) {
- bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- self->window = mp_obj_get_int(value);
-
- return mp_const_none;
+//| .. method:: scan(timeout, \*, interval=0.1, window=0.1)
+//|
+//| Performs a BLE scan.
+//|
+//| :param float timeout: the scan timeout in seconds
+//| :param float interval: the interval (in seconds) between the start of two consecutive scan windows
+//| Must be in the range 0.0025 - 40.959375 seconds.
+//| :param float window: the duration (in seconds) to scan a single BLE channel.
+//| window must be <= interval.
+//| :returns: an iterable of `ScanEntry` objects
+//| :rtype: iterable
+//|
+STATIC mp_obj_t bleio_scanner_scan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_timeout, ARG_interval, ARG_window };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_timeout, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_window, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ };
+
+ bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ const mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj);
+
+ if (args[ARG_interval].u_obj == MP_OBJ_NULL) {
+ args[ARG_interval].u_obj = mp_obj_new_float(INTERVAL_DEFAULT);
+ }
+
+ if (args[ARG_window].u_obj == MP_OBJ_NULL) {
+ args[ARG_window].u_obj = mp_obj_new_float(WINDOW_DEFAULT);
+ }
+
+ const mp_float_t interval = mp_obj_float_get(args[ARG_interval].u_obj);
+ if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
+ mp_raise_ValueError_varg(translate("interval must be in range %s-%s"), INTERVAL_MIN_STRING, INTERVAL_MAX_STRING);
+ }
+
+ const mp_float_t window = mp_obj_float_get(args[ARG_window].u_obj);
+ if (window > interval) {
+ mp_raise_ValueError(translate("window must be <= interval"));
+ }
+
+ return common_hal_bleio_scanner_scan(self, timeout, interval, window);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_scanner_set_window_obj, bleio_scanner_set_window);
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_scanner_scan_obj, 2, bleio_scanner_scan);
-const mp_obj_property_t bleio_scanner_window_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_scanner_get_window_obj,
- (mp_obj_t)&bleio_scanner_set_window_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
STATIC const mp_rom_map_elem_t bleio_scanner_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_interval), MP_ROM_PTR(&bleio_scanner_interval_obj) },
{ MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&bleio_scanner_scan_obj) },
- { MP_ROM_QSTR(MP_QSTR_window), MP_ROM_PTR(&bleio_scanner_window_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_scanner_locals_dict, bleio_scanner_locals_dict_table);
@@ -162,7 +124,6 @@ STATIC MP_DEFINE_CONST_DICT(bleio_scanner_locals_dict, bleio_scanner_locals_dict
const mp_obj_type_t bleio_scanner_type = {
{ &mp_type_type },
.name = MP_QSTR_Scanner,
- .print = bleio_scanner_print,
.make_new = bleio_scanner_make_new,
.locals_dict = (mp_obj_dict_t*)&bleio_scanner_locals_dict
};
diff --git a/shared-bindings/bleio/Scanner.h b/shared-bindings/bleio/Scanner.h
index 9bd071747..3a0ce7eae 100644
--- a/shared-bindings/bleio/Scanner.h
+++ b/shared-bindings/bleio/Scanner.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -29,11 +29,12 @@
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H
#include "py/objtype.h"
-#include "shared-module/bleio/Scanner.h"
+#include "common-hal/bleio/Scanner.h"
extern const mp_obj_type_t bleio_scanner_type;
-extern void common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_int_t timeout);
+extern void common_hal_bleio_scanner_construct(bleio_scanner_obj_t *self);
+extern mp_obj_t common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_float_t timeout, mp_float_t interval, mp_float_t window);
extern void common_hal_bleio_scanner_stop(bleio_scanner_obj_t *self);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H
diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c
index c3be26260..db0606991 100644
--- a/shared-bindings/bleio/Service.c
+++ b/shared-bindings/bleio/Service.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -60,53 +61,53 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args,
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
- const mp_obj_t uuid = args[ARG_uuid].u_obj;
+ const mp_obj_t uuid_obj = args[ARG_uuid].u_obj;
- if (!MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) {
+ if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
mp_raise_ValueError(translate("Expected a UUID"));
}
bleio_service_obj_t *self = m_new_obj(bleio_service_obj_t);
- self->char_list = mp_obj_new_list(0, NULL);
self->base.type = &bleio_service_type;
- self->device = mp_const_none;
- self->handle = 0xFFFF;
- self->is_secondary = args[ARG_secondary].u_bool;
- self->uuid = MP_OBJ_TO_PTR(uuid);
+
+ const bool is_secondary = args[ARG_secondary].u_bool;
+ bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj);
// If characteristics is not an iterable, an exception will be thrown.
mp_obj_iter_buf_t iter_buf;
mp_obj_t iterable = mp_getiter(args[ARG_characteristics].u_obj, &iter_buf);
- mp_obj_t characteristic;
+ mp_obj_t characteristic_obj;
- while ((characteristic = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
- if (!MP_OBJ_IS_TYPE(characteristic, &bleio_characteristic_type)) {
+ // Copy the characteristics list and validate its items.
+ mp_obj_t char_list_obj = mp_obj_new_list(0, NULL);
+ mp_obj_list_t *char_list = MP_OBJ_TO_PTR(char_list_obj);
+
+ while ((characteristic_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
+ if (!MP_OBJ_IS_TYPE(characteristic_obj, &bleio_characteristic_type)) {
mp_raise_ValueError(translate("characteristics includes an object that is not a Characteristic"));
}
- bleio_characteristic_obj_t *characteristic_ptr = MP_OBJ_TO_PTR(characteristic);
+ bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(characteristic_obj);
if (common_hal_bleio_uuid_get_uuid128_reference(uuid) !=
- common_hal_bleio_uuid_get_uuid128_reference(characteristic_ptr->uuid)) {
+ common_hal_bleio_uuid_get_uuid128_reference(characteristic->uuid)) {
// The descriptor base UUID doesn't match the characteristic base UUID.
mp_raise_ValueError(translate("Characteristic UUID doesn't match Service UUID"));
}
- characteristic_ptr->service = self;
- mp_obj_list_append(self->char_list, characteristic);
+ mp_obj_list_append(char_list_obj, characteristic_obj);
}
- // Do port-specific initialization.
- common_hal_bleio_service_construct(self);
+ common_hal_bleio_service_construct(self, uuid, char_list, is_secondary);
return MP_OBJ_FROM_PTR(self);
}
//| .. attribute:: characteristics
//|
-//| A `list` of `bleio.Characteristic` that are offered by this service. (read-only)
+//| A tuple of `bleio.Characteristic` that are offered by this service. (read-only)
//|
STATIC mp_obj_t bleio_service_get_characteristics(mp_obj_t self_in) {
bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
// Return list as a tuple so user won't be able to change it.
- mp_obj_list_t *char_list = MP_OBJ_TO_PTR(self->char_list);
+ mp_obj_list_t *char_list = common_hal_bleio_service_get_characteristic_list(self);
return mp_obj_new_tuple(char_list->len, char_list->items);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_characteristics_obj, bleio_service_get_characteristics);
@@ -118,14 +119,34 @@ const mp_obj_property_t bleio_service_characteristics_obj = {
(mp_obj_t)&mp_const_none_obj },
};
+//| .. attribute:: secondary
+//|
+//| True if this is a secondary service. (read-only)
+//|
+STATIC mp_obj_t bleio_service_get_secondary(mp_obj_t self_in) {
+ bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(common_hal_bleio_service_get_is_secondary(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_secondary_obj, bleio_service_get_secondary);
+
+const mp_obj_property_t bleio_service_secondary_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_service_get_secondary_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
//| .. attribute:: uuid
//|
//| The UUID of this service. (read-only)
+//| Will be ``None`` if the 128-bit UUID for this service is not known.
//|
STATIC mp_obj_t bleio_service_get_uuid(mp_obj_t self_in) {
bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return MP_OBJ_FROM_PTR(self->uuid);
+ bleio_uuid_obj_t *uuid = common_hal_bleio_service_get_uuid(self);
+ return uuid ? MP_OBJ_FROM_PTR(uuid) : mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_uuid_obj, bleio_service_get_uuid);
@@ -138,14 +159,26 @@ const mp_obj_property_t bleio_service_uuid_obj = {
STATIC const mp_rom_map_elem_t bleio_service_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_characteristics), MP_ROM_PTR(&bleio_service_characteristics_obj) },
+ { MP_ROM_QSTR(MP_QSTR_secondary), MP_ROM_PTR(&bleio_service_secondary_obj) },
{ MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_service_uuid_obj) },
};
-
STATIC MP_DEFINE_CONST_DICT(bleio_service_locals_dict, bleio_service_locals_dict_table);
+STATIC void bleio_service_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ if (self->uuid) {
+ mp_printf(print, "Service(");
+ bleio_uuid_print(print, MP_OBJ_FROM_PTR(self->uuid), kind);
+ mp_printf(print, ")");
+ } else {
+ mp_printf(print, "<Service with unregistered UUID>");
+ }
+}
+
const mp_obj_type_t bleio_service_type = {
{ &mp_type_type },
.name = MP_QSTR_Service,
.make_new = bleio_service_make_new,
+ .print = bleio_service_print,
.locals_dict = (mp_obj_dict_t*)&bleio_service_locals_dict
};
diff --git a/shared-bindings/bleio/Service.h b/shared-bindings/bleio/Service.h
index 389db3b2e..f646c81a9 100644
--- a/shared-bindings/bleio/Service.h
+++ b/shared-bindings/bleio/Service.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -27,12 +28,14 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
-#include "shared-module/bleio/Characteristic.h"
-#include "shared-module/bleio/Service.h"
+#include "common-hal/bleio/Service.h"
const mp_obj_type_t bleio_service_type;
-extern void common_hal_bleio_service_construct(bleio_service_obj_t *self);
+extern void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, mp_obj_list_t *characteristic_list, bool is_secondary);
+extern bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self);
+extern mp_obj_list_t *common_hal_bleio_service_get_characteristic_list(bleio_service_obj_t *self);
+extern bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self);
extern void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c
index c6ad9e626..dca7ea010 100644
--- a/shared-bindings/bleio/UUID.c
+++ b/shared-bindings/bleio/UUID.c
@@ -3,9 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
- * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2017 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -47,9 +47,14 @@
//| The value can be one of:
//|
//| - an `int` value in range 0 to 0xFFFF (Bluetooth SIG 16-bit UUID)
-//| - a buffer object (bytearray, bytes) of 16 bytes in little-endian order (128-bit UUID)
+//| - a buffer object (bytearray, bytes) of 16 bytes in little-endian order (128-bit UUID)
+//| - a string of hex digits of the form 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
+//|
+//| Creating a 128-bit UUID registers the UUID with the onboard BLE software, and provides a
+//| temporary 16-bit UUID that can be used in place of the full 128-bit UUID.
//|
-//| :param int/buffer value: The uuid value to encapsulate
+//| :param value: The uuid value to encapsulate
+//| :type value: int or typing.ByteString
//|
STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
mp_arg_check_num(n_args, kw_args, 1, 1, false);
@@ -63,7 +68,7 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, co
if (MP_OBJ_IS_INT(value)) {
mp_int_t uuid16 = mp_obj_get_int(value);
if (uuid16 < 0 || uuid16 > 0xffff) {
- mp_raise_ValueError(translate("UUID integer value not in range 0 to 0xffff"));
+ mp_raise_ValueError(translate("UUID integer value must be 0-0xffff"));
}
// NULL means no 128-bit value.
@@ -124,6 +129,8 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, co
//|
//| The 16-bit part of the UUID. (read-only)
//|
+//| :type: int
+//|
STATIC mp_obj_t bleio_uuid_get_uuid16(mp_obj_t self_in) {
bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in);
return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_uuid_get_uuid16(self));
@@ -140,9 +147,11 @@ const mp_obj_property_t bleio_uuid_uuid16_obj = {
//| .. attribute:: uuid128
//|
-//| The 128-bit value of the UUID, returned as bytes.
+//| The 128-bit value of the UUID
//| Raises AttributeError if this is a 16-bit UUID. (read-only)
//|
+//| :type: bytes
+//|
STATIC mp_obj_t bleio_uuid_get_uuid128(mp_obj_t self_in) {
bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -164,9 +173,10 @@ const mp_obj_property_t bleio_uuid_uuid128_obj = {
//| .. attribute:: size
//|
-//| Returns 128 if this UUID represents a 128-bit vendor-specific UUID.
-//| Returns 16 if this UUID represents a 16-bit Bluetooth SIG assigned UUID. (read-only)
-//| 32-bit UUIDs are not currently supported.
+//| 128 if this UUID represents a 128-bit vendor-specific UUID. 16 if this UUID represents a
+//| 16-bit Bluetooth SIG assigned UUID. (read-only) 32-bit UUIDs are not currently supported.
+//|
+//| :type: int
//|
STATIC mp_obj_t bleio_uuid_get_size(mp_obj_t self_in) {
bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -213,6 +223,12 @@ STATIC mp_obj_t bleio_uuid_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
}
}
+//|
+
+//| .. method:: __eq__(other)
+//|
+//| Two UUID objects are equal if their values match and they are both 128-bit or both 16-bit.
+//|
STATIC mp_obj_t bleio_uuid_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
switch (op) {
// Two UUID's are equal if their uuid16 values and uuid128 references match.
diff --git a/shared-bindings/bleio/UUID.h b/shared-bindings/bleio/UUID.h
index aef2c1e29..caf039aec 100644
--- a/shared-bindings/bleio/UUID.h
+++ b/shared-bindings/bleio/UUID.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c
index 7348655ac..ba3bae6c7 100644
--- a/shared-bindings/bleio/__init__.c
+++ b/shared-bindings/bleio/__init__.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -27,12 +28,10 @@
#include "shared-bindings/bleio/__init__.h"
#include "shared-bindings/bleio/Address.h"
-#include "shared-bindings/bleio/AddressType.h"
-#include "shared-bindings/bleio/AdvertisementData.h"
-#include "shared-bindings/bleio/Broadcaster.h"
+#include "shared-bindings/bleio/Central.h"
#include "shared-bindings/bleio/Characteristic.h"
#include "shared-bindings/bleio/CharacteristicBuffer.h"
-#include "shared-bindings/bleio/Descriptor.h"
+// #include "shared-bindings/bleio/Descriptor.h"
#include "shared-bindings/bleio/Peripheral.h"
#include "shared-bindings/bleio/ScanEntry.h"
#include "shared-bindings/bleio/Scanner.h"
@@ -54,18 +53,14 @@
//| :maxdepth: 3
//|
//| Address
-//| AddressType
-//| AdvertisementData
//| Adapter
-//| Broadcaster
+//| Central
//| Characteristic
//| CharacteristicBuffer
-// Work-in-progress classes are omitted, and marked as :orphan: in their files.
-// Descriptor
-// Device
+//| Descriptor
//| Peripheral
-// ScanEntry
-// Scanner
+//| ScanEntry
+//| Scanner
//| Service
//| UUID
//|
@@ -79,23 +74,18 @@
STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) },
{ MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) },
- { MP_ROM_QSTR(MP_QSTR_AdvertisementData), MP_ROM_PTR(&bleio_advertisementdata_type) },
- { MP_ROM_QSTR(MP_QSTR_Broadcaster), MP_ROM_PTR(&bleio_broadcaster_type) },
+ { MP_ROM_QSTR(MP_QSTR_Central), MP_ROM_PTR(&bleio_central_type) },
{ MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) },
{ MP_ROM_QSTR(MP_QSTR_CharacteristicBuffer), MP_ROM_PTR(&bleio_characteristic_buffer_type) },
// { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) },
{ MP_ROM_QSTR(MP_QSTR_Peripheral), MP_ROM_PTR(&bleio_peripheral_type) },
-// Hide work-in-progress.
-// { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) },
-// { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) },
+ { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) },
+ { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) },
{ MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&bleio_service_type) },
{ MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) },
// Properties
{ MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) },
-
- // Enum-like Classes.
- { MP_ROM_QSTR(MP_QSTR_AddressType), MP_ROM_PTR(&bleio_addresstype_type) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table);
diff --git a/shared-bindings/bleio/__init__.h b/shared-bindings/bleio/__init__.h
index 1f4e0a66f..4aa6dd45b 100644
--- a/shared-bindings/bleio/__init__.h
+++ b/shared-bindings/bleio/__init__.h
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/shared-bindings/board/__init__.c b/shared-bindings/board/__init__.c
index 82a0cab67..47e2d64bc 100644
--- a/shared-bindings/board/__init__.c
+++ b/shared-bindings/board/__init__.c
@@ -34,7 +34,6 @@
//|
//| .. module:: board
//| :synopsis: Board specific pin names
-//| :platform: SAMD21
//|
//| Common container for board base pin names. These will vary from board to
//| board so don't expect portability when using this module.
@@ -42,7 +41,7 @@
//| .. warning:: The board module varies by board. The APIs documented here may or may not be
//| available on a specific board.
-//| .. method:: I2C()
+//| .. function:: I2C()
//|
//| Returns the `busio.I2C` object for the board designated SDA and SCL pins. It is a singleton.
//|
@@ -66,7 +65,7 @@ mp_obj_t board_i2c(void) {
MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c);
-//| .. method:: SPI()
+//| .. function:: SPI()
//|
//| Returns the `busio.SPI` object for the board designated SCK, MOSI and MISO pins. It is a
//| singleton.
@@ -90,7 +89,7 @@ mp_obj_t board_spi(void) {
#endif
MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi);
-//| .. method:: UART()
+//| .. function:: UART()
//|
//| Returns the `busio.UART` object for the board designated TX and RX pins. It is a singleton.
//|
diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c
index e17a72b48..0e639f0b5 100644
--- a/shared-bindings/busio/I2C.c
+++ b/shared-bindings/busio/I2C.c
@@ -41,7 +41,7 @@
//| :class:`I2C` --- Two wire serial protocol
//| ------------------------------------------
//|
-//| .. class:: I2C(scl, sda, \*, frequency=400000)
+//| .. class:: I2C(scl, sda, *, frequency=400000, timeout=255)
//|
//| I2C is a two-wire protocol for communicating between devices. At the
//| physical level it consists of 2 wires: SCL and SDA, the clock and data
@@ -82,7 +82,7 @@ STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, con
return (mp_obj_t)self;
}
-//| .. method:: I2C.deinit()
+//| .. method:: deinit()
//|
//| Releases control of the underlying hardware so other classes can use it.
//|
@@ -93,13 +93,19 @@ STATIC mp_obj_t busio_i2c_obj_deinit(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_deinit_obj, busio_i2c_obj_deinit);
-//| .. method:: I2C.__enter__()
+STATIC void check_for_deinit(busio_i2c_obj_t *self) {
+ if (common_hal_busio_i2c_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
+//| .. method:: __enter__()
//|
//| No-op used in Context Managers.
//|
// Provided by context manager helper.
-//| .. method:: I2C.__exit__()
+//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware on context exit. See
//| :ref:`lifetime-and-contextmanagers` for more info.
@@ -118,7 +124,7 @@ static void check_lock(busio_i2c_obj_t *self) {
}
}
-//| .. method:: I2C.scan()
+//| .. method:: scan()
//|
//| Scan all I2C addresses between 0x08 and 0x77 inclusive and return a
//| list of those that respond.
@@ -128,7 +134,7 @@ static void check_lock(busio_i2c_obj_t *self) {
//|
STATIC mp_obj_t busio_i2c_scan(mp_obj_t self_in) {
busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_i2c_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_obj_t list = mp_obj_new_list(0, NULL);
// 7-bit addresses 0b0000xxx and 0b1111xxx are reserved
@@ -142,7 +148,7 @@ STATIC mp_obj_t busio_i2c_scan(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_scan_obj, busio_i2c_scan);
-//| .. method:: I2C.try_lock()
+//| .. method:: try_lock()
//|
//| Attempts to grab the I2C lock. Returns True on success.
//|
@@ -151,24 +157,24 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_scan_obj, busio_i2c_scan);
//|
STATIC mp_obj_t busio_i2c_obj_try_lock(mp_obj_t self_in) {
busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_i2c_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_busio_i2c_try_lock(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_try_lock_obj, busio_i2c_obj_try_lock);
-//| .. method:: I2C.unlock()
+//| .. method:: unlock()
//|
//| Releases the I2C lock.
//|
STATIC mp_obj_t busio_i2c_obj_unlock(mp_obj_t self_in) {
busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_i2c_deinited(self));
+ check_for_deinit(self);
common_hal_busio_i2c_unlock(self);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_unlock_obj, busio_i2c_obj_unlock);
-//| .. method:: I2C.readfrom_into(address, buffer, \*, start=0, end=len(buffer))
+//| .. method:: readfrom_into(address, buffer, *, start=0, end=None)
//|
//| Read into ``buffer`` from the slave specified by ``address``.
//| The number of bytes read will be the length of ``buffer``.
@@ -181,7 +187,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_unlock_obj, busio_i2c_obj_unlock);
//| :param int address: 7-bit device address
//| :param bytearray buffer: buffer to write into
//| :param int start: Index to start writing at
-//| :param int end: Index to write up to but not include
+//| :param int end: Index to write up to but not include. Defaults to ``len(buffer)``
//|
STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_address, ARG_buffer, ARG_start, ARG_end };
@@ -192,7 +198,7 @@ STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args,
{ MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
};
busio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_busio_i2c_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -216,7 +222,7 @@ STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args,
}
MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_readfrom_into_obj, 3, busio_i2c_readfrom_into);
-//| .. method:: I2C.writeto(address, buffer, \*, start=0, end=len(buffer), stop=True)
+//| .. method:: writeto(address, buffer, *, start=0, end=None, stop=True)
//|
//| Write the bytes from ``buffer`` to the slave specified by ``address``.
//| Transmits a stop bit if ``stop`` is set.
@@ -231,7 +237,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_readfrom_into_obj, 3, busio_i2c_readfrom_in
//| :param int address: 7-bit device address
//| :param bytearray buffer: buffer containing the bytes to write
//| :param int start: Index to start writing from
-//| :param int end: Index to read up to but not include
+//| :param int end: Index to read up to but not include. Defaults to ``len(buffer)``
//| :param bool stop: If true, output an I2C stop condition after the
//| buffer is written
//|
@@ -245,7 +251,7 @@ STATIC mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_ma
{ MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
};
busio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_busio_i2c_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
diff --git a/shared-bindings/busio/I2C.h b/shared-bindings/busio/I2C.h
index 739732e97..a2d5dbf50 100644
--- a/shared-bindings/busio/I2C.h
+++ b/shared-bindings/busio/I2C.h
@@ -69,4 +69,7 @@ extern uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addres
extern uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address,
uint8_t * data, size_t len);
+// This is used by the supervisor to claim I2C devices indefinitely.
+extern void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self);
+
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_H
diff --git a/shared-bindings/busio/OneWire.c b/shared-bindings/busio/OneWire.c
index ceba4f8ee..aca2a3ef2 100644
--- a/shared-bindings/busio/OneWire.c
+++ b/shared-bindings/busio/OneWire.c
@@ -91,6 +91,12 @@ STATIC mp_obj_t busio_onewire_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_deinit_obj, busio_onewire_deinit);
+STATIC void check_for_deinit(busio_onewire_obj_t *self) {
+ if (common_hal_busio_onewire_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -118,7 +124,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_onewire___exit___obj, 4, 4, bus
//|
STATIC mp_obj_t busio_onewire_obj_reset(mp_obj_t self_in) {
busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_onewire_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_busio_onewire_reset(self));
}
@@ -133,7 +139,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_reset_obj, busio_onewire_obj_reset);
//|
STATIC mp_obj_t busio_onewire_obj_read_bit(mp_obj_t self_in) {
busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_onewire_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_busio_onewire_read_bit(self));
}
@@ -145,7 +151,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_read_bit_obj, busio_onewire_obj_read_bit
//|
STATIC mp_obj_t busio_onewire_obj_write_bit(mp_obj_t self_in, mp_obj_t bool_obj) {
busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_onewire_deinited(self));
+ check_for_deinit(self);
common_hal_busio_onewire_write_bit(self, mp_obj_is_true(bool_obj));
return mp_const_none;
diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c
index f690eea18..a7d7d515c 100644
--- a/shared-bindings/busio/SPI.c
+++ b/shared-bindings/busio/SPI.c
@@ -95,7 +95,7 @@ STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, con
return (mp_obj_t)self;
}
-//| .. method:: SPI.deinit()
+//| .. method:: deinit()
//|
//| Turn off the SPI bus.
//|
@@ -106,13 +106,13 @@ STATIC mp_obj_t busio_spi_obj_deinit(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_deinit_obj, busio_spi_obj_deinit);
-//| .. method:: SPI.__enter__()
+//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
//|
// Provided by context manager helper.
-//| .. method:: SPI.__exit__()
+//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
@@ -124,14 +124,20 @@ STATIC mp_obj_t busio_spi_obj___exit__(size_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_spi_obj___exit___obj, 4, 4, busio_spi_obj___exit__);
-static void check_lock(busio_spi_obj_t *self) {
+STATIC void check_lock(busio_spi_obj_t *self) {
asm("");
if (!common_hal_busio_spi_has_lock(self)) {
mp_raise_RuntimeError(translate("Function requires lock"));
}
}
-//| .. method:: SPI.configure(\*, baudrate=100000, polarity=0, phase=0, bits=8)
+STATIC void check_for_deinit(busio_spi_obj_t *self) {
+ if (common_hal_busio_spi_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
+//| .. method:: configure(*, baudrate=100000, polarity=0, phase=0, bits=8)
//|
//| Configures the SPI bus. The SPI object must be locked.
//|
@@ -162,7 +168,7 @@ STATIC mp_obj_t busio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
};
busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_busio_spi_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -188,7 +194,7 @@ STATIC mp_obj_t busio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_
}
MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_configure_obj, 1, busio_spi_configure);
-//| .. method:: SPI.try_lock()
+//| .. method:: try_lock()
//|
//| Attempts to grab the SPI lock. Returns True on success.
//|
@@ -197,31 +203,30 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_configure_obj, 1, busio_spi_configure);
//|
STATIC mp_obj_t busio_spi_obj_try_lock(mp_obj_t self_in) {
busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_spi_deinited(self));
return mp_obj_new_bool(common_hal_busio_spi_try_lock(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_try_lock_obj, busio_spi_obj_try_lock);
-//| .. method:: SPI.unlock()
+//| .. method:: unlock()
//|
//| Releases the SPI lock.
//|
STATIC mp_obj_t busio_spi_obj_unlock(mp_obj_t self_in) {
busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_spi_deinited(self));
+ check_for_deinit(self);
common_hal_busio_spi_unlock(self);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_unlock_obj, busio_spi_obj_unlock);
-//| .. method:: SPI.write(buffer, \*, start=0, end=len(buffer))
+//| .. method:: write(buffer, *, start=0, end=None)
//|
//| Write the data contained in ``buffer``. The SPI object must be locked.
//| If the buffer is empty, nothing happens.
//|
//| :param bytearray buffer: Write out the data in this buffer
//| :param int start: Start of the slice of ``buffer`` to write out: ``buffer[start:end]``
-//| :param int end: End of the slice; this index is not included
+//| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)``
//|
STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_buffer, ARG_start, ARG_end };
@@ -231,7 +236,7 @@ STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_
{ MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
};
busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_busio_spi_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -255,7 +260,7 @@ STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_
MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_obj, 2, busio_spi_write);
-//| .. method:: SPI.readinto(buffer, \*, start=0, end=len(buffer), write_value=0)
+//| .. method:: readinto(buffer, *, start=0, end=None, write_value=0)
//|
//| Read into ``buffer`` while writing ``write_value`` for each byte read.
//| The SPI object must be locked.
@@ -263,7 +268,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_obj, 2, busio_spi_write);
//|
//| :param bytearray buffer: Read data into this buffer
//| :param int start: Start of the slice of ``buffer`` to read into: ``buffer[start:end]``
-//| :param int end: End of the slice; this index is not included
+//| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)``
//| :param int write_value: Value to write while reading. (Usually ignored.)
//|
STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -275,7 +280,7 @@ STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_m
{ MP_QSTR_write_value,MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
};
busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_busio_spi_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -298,7 +303,7 @@ STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_m
}
MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_readinto_obj, 2, busio_spi_readinto);
-//| .. method:: SPI.write_readinto(buffer_out, buffer_in, \*, out_start=0, out_end=len(buffer_out), in_start=0, in_end=len(buffer_in))
+//| .. method:: write_readinto(buffer_out, buffer_in, *, out_start=0, out_end=None, in_start=0, in_end=None)
//|
//| Write out the data in ``buffer_out`` while simultaneously reading data into ``buffer_in``.
//| The SPI object must be locked.
@@ -309,9 +314,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_readinto_obj, 2, busio_spi_readinto);
//| :param bytearray buffer_out: Write out the data in this buffer
//| :param bytearray buffer_in: Read data into this buffer
//| :param int out_start: Start of the slice of buffer_out to write out: ``buffer_out[out_start:out_end]``
-//| :param int out_end: End of the slice; this index is not included
+//| :param int out_end: End of the slice; this index is not included. Defaults to ``len(buffer_out)``
//| :param int in_start: Start of the slice of ``buffer_in`` to read into: ``buffer_in[in_start:in_end]``
-//| :param int in_end: End of the slice; this index is not included
+//| :param int in_end: End of the slice; this index is not included. Defaults to ``len(buffer_in)``
//|
STATIC mp_obj_t busio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_buffer_out, ARG_buffer_in, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end };
@@ -324,7 +329,7 @@ STATIC mp_obj_t busio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args
{ MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
};
busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_busio_spi_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -367,7 +372,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_readinto_obj, 2, busio_spi_write_read
//|
STATIC mp_obj_t busio_spi_obj_get_frequency(mp_obj_t self_in) {
busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_spi_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_busio_spi_get_frequency(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_get_frequency_obj, busio_spi_obj_get_frequency);
diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c
index 94ad1bd3e..c7eef8c43 100644
--- a/shared-bindings/busio/UART.c
+++ b/shared-bindings/busio/UART.c
@@ -46,7 +46,7 @@
//| =================================================
//|
//|
-//| .. class:: UART(tx, rx, \*, baudrate=9600, bits=8, parity=None, stop=1, timeout=1, receiver_buffer_size=64)
+//| .. class:: UART(tx, rx, *, baudrate=9600, bits=8, parity=None, stop=1, timeout=1, receiver_buffer_size=64)
//|
//| A common bidirectional serial protocol that uses an an agreed upon speed
//| rather than a shared clock line.
@@ -137,6 +137,12 @@ STATIC mp_obj_t busio_uart_obj_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_deinit_obj, busio_uart_obj_deinit);
+STATIC void check_for_deinit(busio_uart_obj_t *self) {
+ if (common_hal_busio_uart_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -196,7 +202,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_
// These three methods are used by the shared stream methods.
STATIC mp_uint_t busio_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_uart_deinited(self));
+ check_for_deinit(self);
byte *buf = buf_in;
// make sure we want at least 1 char
@@ -209,7 +215,7 @@ STATIC mp_uint_t busio_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size,
STATIC mp_uint_t busio_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_uart_deinited(self));
+ check_for_deinit(self);
const byte *buf = buf_in;
return common_hal_busio_uart_write(self, buf, size, errcode);
@@ -217,7 +223,7 @@ STATIC mp_uint_t busio_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_
STATIC mp_uint_t busio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_uart_deinited(self));
+ check_for_deinit(self);
mp_uint_t ret;
if (request == MP_IOCTL_POLL) {
mp_uint_t flags = arg;
@@ -241,14 +247,14 @@ STATIC mp_uint_t busio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t
//|
STATIC mp_obj_t busio_uart_obj_get_baudrate(mp_obj_t self_in) {
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_uart_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_busio_uart_get_baudrate(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_get_baudrate_obj, busio_uart_obj_get_baudrate);
STATIC mp_obj_t busio_uart_obj_set_baudrate(mp_obj_t self_in, mp_obj_t baudrate) {
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_uart_deinited(self));
+ check_for_deinit(self);
common_hal_busio_uart_set_baudrate(self, mp_obj_get_int(baudrate));
return mp_const_none;
}
@@ -268,7 +274,7 @@ const mp_obj_property_t busio_uart_baudrate_obj = {
//|
STATIC mp_obj_t busio_uart_obj_get_in_waiting(mp_obj_t self_in) {
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_uart_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_busio_uart_rx_characters_available(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_get_in_waiting_obj, busio_uart_obj_get_in_waiting);
@@ -286,13 +292,13 @@ const mp_obj_property_t busio_uart_in_waiting_obj = {
//|
STATIC mp_obj_t busio_uart_obj_reset_input_buffer(mp_obj_t self_in) {
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_uart_deinited(self));
+ check_for_deinit(self);
common_hal_busio_uart_clear_rx_buffer(self);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_reset_input_buffer_obj, busio_uart_obj_reset_input_buffer);
-//| .. class:: busio.UART.Parity
+//| .. class:: busio.UART.Parity()
//|
//| Enum-like class to define the parity used to verify correct data transfer.
//|
diff --git a/shared-bindings/busio/UART.h b/shared-bindings/busio/UART.h
index e171f8bb4..776a996be 100644
--- a/shared-bindings/busio/UART.h
+++ b/shared-bindings/busio/UART.h
@@ -42,7 +42,7 @@ typedef enum {
extern void common_hal_busio_uart_construct(busio_uart_obj_t *self,
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
- uint8_t receiver_buffer_size);
+ uint16_t receiver_buffer_size);
extern void common_hal_busio_uart_deinit(busio_uart_obj_t *self);
extern bool common_hal_busio_uart_deinited(busio_uart_obj_t *self);
diff --git a/shared-bindings/busio/__init__.c b/shared-bindings/busio/__init__.c
index 958ee062a..ff2933dc6 100644
--- a/shared-bindings/busio/__init__.c
+++ b/shared-bindings/busio/__init__.c
@@ -35,7 +35,6 @@
#include "shared-bindings/busio/OneWire.h"
#include "shared-bindings/busio/SPI.h"
#include "shared-bindings/busio/UART.h"
-#include "shared-bindings/busio/__init__.h"
#include "py/runtime.h"
diff --git a/shared-bindings/digitalio/DigitalInOut.c b/shared-bindings/digitalio/DigitalInOut.c
index 1ced15137..16472c12c 100644
--- a/shared-bindings/digitalio/DigitalInOut.c
+++ b/shared-bindings/digitalio/DigitalInOut.c
@@ -49,8 +49,8 @@
//| =========================================================
//|
//| A DigitalInOut is used to digitally control I/O pins. For analog control of
-//| a pin, see the :py:class:`~digitalio.AnalogIn` and
-//| :py:class:`~digitalio.AnalogOut` classes.
+//| a pin, see the :py:class:`analogio.AnalogIn` and
+//| :py:class:`analogio.AnalogOut` classes.
//|
//| .. class:: DigitalInOut(pin)
@@ -105,6 +105,12 @@ STATIC mp_obj_t digitalio_digitalinout_obj___exit__(size_t n_args, const mp_obj_
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(digitalio_digitalinout_obj___exit___obj, 4, 4, digitalio_digitalinout_obj___exit__);
+STATIC void check_for_deinit(digitalio_digitalinout_obj_t *self) {
+ if (common_hal_digitalio_digitalinout_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//|
//| .. method:: switch_to_output(value=False, drive_mode=digitalio.DriveMode.PUSH_PULL)
//|
@@ -121,7 +127,7 @@ STATIC mp_obj_t digitalio_digitalinout_switch_to_output(size_t n_args, const mp_
{ MP_QSTR_drive_mode, MP_ARG_OBJ, {.u_rom_obj = &digitalio_drive_mode_push_pull_obj} },
};
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -158,7 +164,7 @@ STATIC mp_obj_t digitalio_digitalinout_switch_to_input(size_t n_args, const mp_o
{ MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} },
};
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -191,7 +197,7 @@ extern const digitalio_digitalio_direction_obj_t digitalio_digitalio_direction_o
STATIC mp_obj_t digitalio_digitalinout_obj_get_direction(mp_obj_t self_in) {
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
digitalio_direction_t direction = common_hal_digitalio_digitalinout_get_direction(self);
if (direction == DIRECTION_INPUT) {
return (mp_obj_t)&digitalio_direction_input_obj;
@@ -202,7 +208,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_direction_obj, digitalio_di
STATIC mp_obj_t digitalio_digitalinout_obj_set_direction(mp_obj_t self_in, mp_obj_t value) {
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
if (value == &digitalio_direction_input_obj) {
common_hal_digitalio_digitalinout_switch_to_input(self, PULL_NONE);
} else if (value == &digitalio_direction_output_obj) {
@@ -227,7 +233,7 @@ const mp_obj_property_t digitalio_digitalio_direction_obj = {
//|
STATIC mp_obj_t digitalio_digitalinout_obj_get_value(mp_obj_t self_in) {
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
bool value = common_hal_digitalio_digitalinout_get_value(self);
return mp_obj_new_bool(value);
}
@@ -235,7 +241,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_value_obj, digitalio_digita
STATIC mp_obj_t digitalio_digitalinout_obj_set_value(mp_obj_t self_in, mp_obj_t value) {
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_INPUT) {
mp_raise_AttributeError(translate("Cannot set value when direction is input."));
return mp_const_none;
@@ -261,7 +267,7 @@ const mp_obj_property_t digitalio_digitalinout_value_obj = {
//|
STATIC mp_obj_t digitalio_digitalinout_obj_get_drive_mode(mp_obj_t self_in) {
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_INPUT) {
mp_raise_AttributeError(translate("Drive mode not used when direction is input."));
return mp_const_none;
@@ -276,7 +282,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_drive_mode_obj, digitalio_d
STATIC mp_obj_t digitalio_digitalinout_obj_set_drive_mode(mp_obj_t self_in, mp_obj_t drive_mode) {
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_INPUT) {
mp_raise_AttributeError(translate("Drive mode not used when direction is input."));
return mp_const_none;
@@ -309,7 +315,7 @@ const mp_obj_property_t digitalio_digitalio_drive_mode_obj = {
//|
STATIC mp_obj_t digitalio_digitalinout_obj_get_pull(mp_obj_t self_in) {
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_OUTPUT) {
mp_raise_AttributeError(translate("Pull not used when direction is output."));
return mp_const_none;
@@ -326,7 +332,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_pull_obj, digitalio_digital
STATIC mp_obj_t digitalio_digitalinout_obj_set_pull(mp_obj_t self_in, mp_obj_t pull_obj) {
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_OUTPUT) {
mp_raise_AttributeError(translate("Pull not used when direction is output."));
return mp_const_none;
@@ -381,7 +387,6 @@ digitalio_digitalinout_obj_t *assert_digitalinout(mp_obj_t obj) {
mp_raise_TypeError(translate("argument num/types mismatch"));
}
digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(obj);
- raise_error_if_deinited(
- common_hal_digitalio_digitalinout_deinited(pin));
+ check_for_deinit(pin);
return pin;
}
diff --git a/shared-bindings/digitalio/Direction.c b/shared-bindings/digitalio/Direction.c
index a3433d4b0..c8188fc89 100644
--- a/shared-bindings/digitalio/Direction.c
+++ b/shared-bindings/digitalio/Direction.c
@@ -43,7 +43,7 @@
//| :class:`Direction` -- defines the direction of a digital pin
//| =============================================================
//|
-//| .. class:: digitalio.DigitalInOut.Direction
+//| .. class:: Direction
//|
//| Enum-like class to define which direction the digital values are
//| going.
diff --git a/shared-bindings/digitalio/DriveMode.c b/shared-bindings/digitalio/DriveMode.c
index 477cd904c..51e1e2ee5 100644
--- a/shared-bindings/digitalio/DriveMode.c
+++ b/shared-bindings/digitalio/DriveMode.c
@@ -31,7 +31,7 @@
//| :class:`DriveMode` -- defines the drive mode of a digital pin
//| =============================================================
//|
-//| .. class:: digitalio.DriveMode
+//| .. class:: DriveMode
//|
//| Enum-like class to define the drive mode used when outputting
//| digital values.
diff --git a/shared-bindings/digitalio/Pull.c b/shared-bindings/digitalio/Pull.c
index 8d03f6c05..813268db7 100644
--- a/shared-bindings/digitalio/Pull.c
+++ b/shared-bindings/digitalio/Pull.c
@@ -31,7 +31,7 @@
//| :class:`Pull` -- defines the pull of a digital input pin
//| =============================================================
//|
-//| .. class:: digitalio.Pull
+//| .. class:: Pull
//|
//| Enum-like class to define the pull value, if any, used while reading
//| digital values in.
diff --git a/shared-bindings/displayio/ColorConverter.c b/shared-bindings/displayio/ColorConverter.c
index 561883810..d9524870d 100644
--- a/shared-bindings/displayio/ColorConverter.c
+++ b/shared-bindings/displayio/ColorConverter.c
@@ -62,6 +62,8 @@ STATIC mp_obj_t displayio_colorconverter_make_new(const mp_obj_type_t *type, siz
//| .. method:: convert(color)
//|
+//| Converts the given RGB888 color to RGB565
+//|
STATIC mp_obj_t displayio_colorconverter_obj_convert(mp_obj_t self_in, mp_obj_t color_obj) {
displayio_colorconverter_t *self = MP_OBJ_TO_PTR(self_in);
@@ -69,8 +71,10 @@ STATIC mp_obj_t displayio_colorconverter_obj_convert(mp_obj_t self_in, mp_obj_t
if (!mp_obj_get_int_maybe(color_obj, &color)) {
mp_raise_ValueError(translate("color should be an int"));
}
- uint16_t output_color;
- common_hal_displayio_colorconverter_convert(self, color, &output_color);
+ _displayio_colorspace_t colorspace;
+ colorspace.depth = 16;
+ uint32_t output_color;
+ common_hal_displayio_colorconverter_convert(self, &colorspace, color, &output_color);
return MP_OBJ_NEW_SMALL_INT(output_color);
}
MP_DEFINE_CONST_FUN_OBJ_2(displayio_colorconverter_convert_obj, displayio_colorconverter_obj_convert);
diff --git a/shared-bindings/displayio/ColorConverter.h b/shared-bindings/displayio/ColorConverter.h
index 71be7f543..24895500e 100644
--- a/shared-bindings/displayio/ColorConverter.h
+++ b/shared-bindings/displayio/ColorConverter.h
@@ -29,9 +29,11 @@
#include "shared-module/displayio/ColorConverter.h"
+#include "shared-module/displayio/Palette.h"
+
extern const mp_obj_type_t displayio_colorconverter_type;
void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t* self);
-bool common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *colorconverter, uint32_t input_color, uint16_t* output_color);
+void common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *colorconverter, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_COLORCONVERTER_H
diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c
index 52ab2ef31..9cb4d6e74 100644
--- a/shared-bindings/displayio/Display.c
+++ b/shared-bindings/displayio/Display.c
@@ -31,6 +31,7 @@
#include "lib/utils/context_manager_helpers.h"
#include "py/binary.h"
#include "py/objproperty.h"
+#include "py/objtype.h"
#include "py/runtime.h"
#include "shared-bindings/displayio/Group.h"
#include "shared-bindings/microcontroller/Pin.h"
@@ -50,7 +51,7 @@
//| Most people should not use this class directly. Use a specific display driver instead that will
//| contain the initialization sequence at minimum.
//|
-//| .. class:: Display(display_bus, init_sequence, *, width, height, colstart=0, rowstart=0, rotation=0, color_depth=16, set_column_command=0x2a, set_row_command=0x2b, write_ram_command=0x2c, set_vertical_scroll=0, backlight_pin=None, brightness=1.0, auto_brightness=False, single_byte_bounds=False, data_as_commands=False)
+//| .. class:: Display(display_bus, init_sequence, *, width, height, colstart=0, rowstart=0, rotation=0, color_depth=16, grayscale=False, pixels_in_byte_share_row=True, bytes_per_cell=1, reverse_pixels_in_byte=False, set_column_command=0x2a, set_row_command=0x2b, write_ram_command=0x2c, set_vertical_scroll=0, backlight_pin=None, brightness_command=None, brightness=1.0, auto_brightness=False, single_byte_bounds=False, data_as_commands=False)
//|
//| Create a Display object on the given display bus (`displayio.FourWire` or `displayio.ParallelBus`).
//|
@@ -77,7 +78,8 @@
//| The initialization sequence should always leave the display memory access inline with the scan
//| of the display to minimize tearing artifacts.
//|
-//| :param displayio.FourWire or displayio.ParallelBus display_bus: The bus that the display is connected to
+//| :param display_bus: The bus that the display is connected to
+//| :type display_bus: displayio.FourWire or displayio.ParallelBus
//| :param buffer init_sequence: Byte-packed initialization sequence.
//| :param int width: Width in pixels
//| :param int height: Height in pixels
@@ -86,18 +88,23 @@
//| :param int rotation: The rotation of the display in degrees clockwise. Must be in 90 degree increments (0, 90, 180, 270)
//| :param int color_depth: The number of bits of color per pixel transmitted. (Some displays
//| support 18 bit but 16 is easier to transmit. The last bit is extrapolated.)
+//| :param bool grayscale: True if the display only shows a single color.
+//| :param bool pixels_in_byte_share_row: True when pixels are less than a byte and a byte includes pixels from the same row of the display. When False, pixels share a column.
+//| :param int bytes_per_cell: Number of bytes per addressable memory location when color_depth < 8. When greater than one, bytes share a row or column according to pixels_in_byte_share_row.
+//| :param bool reverse_pixels_in_byte: Reverses the pixel order within each byte when color_depth < 8. Does not apply across multiple bytes even if there is more than one byte per cell (bytes_per_cell.)
//| :param int set_column_command: Command used to set the start and end columns to update
//| :param int set_row_command: Command used so set the start and end rows to update
-//| :param int write_ram_command: Command used to write pixels values into the update region
+//| :param int write_ram_command: Command used to write pixels values into the update region. Ignored if data_as_commands is set.
//| :param int set_vertical_scroll: Command used to set the first row to show
//| :param microcontroller.Pin backlight_pin: Pin connected to the display's backlight
+//| :param int brightness_command: Command to set display brightness. Usually available in OLED controllers.
//| :param bool brightness: Initial display brightness. This value is ignored if auto_brightness is True.
//| :param bool auto_brightness: If True, brightness is controlled via an ambient light sensor or other mechanism.
//| :param bool single_byte_bounds: Display column and row commands use single bytes
//| :param bool data_as_commands: Treat all init and boundary data as SPI commands. Certain displays require this.
//|
STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_set_vertical_scroll, ARG_backlight_pin, ARG_brightness, ARG_auto_brightness, ARG_single_byte_bounds, ARG_data_as_commands };
+ enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_grayscale, ARG_pixels_in_byte_share_row, ARG_bytes_per_cell, ARG_reverse_pixels_in_byte, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_set_vertical_scroll, ARG_backlight_pin, ARG_brightness_command, ARG_brightness, ARG_auto_brightness, ARG_single_byte_bounds, ARG_data_as_commands };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ },
@@ -107,11 +114,16 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a
{ MP_QSTR_rowstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
{ MP_QSTR_rotation, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
{ MP_QSTR_color_depth, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} },
+ { MP_QSTR_grayscale, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
+ { MP_QSTR_pixels_in_byte_share_row, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} },
+ { MP_QSTR_bytes_per_cell, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} },
+ { MP_QSTR_reverse_pixels_in_byte, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
{ MP_QSTR_set_column_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2a} },
{ MP_QSTR_set_row_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2b} },
{ MP_QSTR_write_ram_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2c} },
{ MP_QSTR_set_vertical_scroll, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x0} },
{ MP_QSTR_backlight_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
+ { MP_QSTR_brightness_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = NO_BRIGHTNESS_COMMAND} },
{ MP_QSTR_brightness, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} },
{ MP_QSTR_auto_brightness, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
{ MP_QSTR_single_byte_bounds, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
@@ -155,11 +167,14 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a
common_hal_displayio_display_construct(
self,
display_bus, args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, rotation,
- args[ARG_color_depth].u_int, args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int,
+ args[ARG_color_depth].u_int, args[ARG_grayscale].u_bool,
+ args[ARG_pixels_in_byte_share_row].u_bool, args[ARG_bytes_per_cell].u_bool, args[ARG_reverse_pixels_in_byte].u_bool,
+ args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int,
args[ARG_write_ram_command].u_int,
args[ARG_set_vertical_scroll].u_int,
bufinfo.buf, bufinfo.len,
MP_OBJ_TO_PTR(backlight_pin),
+ args[ARG_brightness_command].u_int,
brightness,
args[ARG_auto_brightness].u_bool,
args[ARG_single_byte_bounds].u_bool,
@@ -172,6 +187,7 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a
// Helper to ensure we have the native super class instead of a subclass.
static displayio_display_obj_t* native_display(mp_obj_t display_obj) {
mp_obj_t native_display = mp_instance_cast_to_native_base(display_obj, &displayio_display_type);
+ mp_obj_assert_native_inited(native_display);
return MP_OBJ_TO_PTR(native_display);
}
@@ -180,18 +196,18 @@ static displayio_display_obj_t* native_display(mp_obj_t display_obj) {
//| Switches to displaying the given group of layers. When group is None, the default
//| CircuitPython terminal will be shown.
//|
+//| :param Group group: The group to show.
STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in) {
displayio_display_obj_t *self = native_display(self_in);
displayio_group_t* group = NULL;
if (group_in != mp_const_none) {
- mp_obj_t native_layer = mp_instance_cast_to_native_base(group_in, &displayio_group_type);
- if (native_layer == MP_OBJ_NULL) {
- mp_raise_ValueError(translate("Must be a Group subclass."));
- }
- group = MP_OBJ_TO_PTR(native_layer);
+ group = MP_OBJ_TO_PTR(native_group(group_in));
}
- common_hal_displayio_display_show(self, group);
+ bool ok = common_hal_displayio_display_show(self, group);
+ if (!ok) {
+ mp_raise_ValueError(translate("Group already used"));
+ }
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show);
@@ -234,10 +250,14 @@ STATIC mp_obj_t displayio_display_obj_get_brightness(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_brightness_obj, displayio_display_obj_get_brightness);
-STATIC mp_obj_t displayio_display_obj_set_brightness(mp_obj_t self_in, mp_obj_t brightness) {
+STATIC mp_obj_t displayio_display_obj_set_brightness(mp_obj_t self_in, mp_obj_t brightness_obj) {
displayio_display_obj_t *self = native_display(self_in);
common_hal_displayio_display_set_auto_brightness(self, false);
- bool ok = common_hal_displayio_display_set_brightness(self, mp_obj_get_float(brightness));
+ mp_float_t brightness = mp_obj_get_float(brightness_obj);
+ if (brightness < 0 || brightness > 1.0) {
+ mp_raise_ValueError(translate("Brightness must be 0-1.0"));
+ }
+ bool ok = common_hal_displayio_display_set_brightness(self, brightness);
if (!ok) {
mp_raise_RuntimeError(translate("Brightness not adjustable"));
}
diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h
index 3136ae88a..a8938bbcd 100644
--- a/shared-bindings/displayio/Display.h
+++ b/shared-bindings/displayio/Display.h
@@ -36,29 +36,33 @@ extern const mp_obj_type_t displayio_display_type;
#define DELAY 0x80
+#define NO_BRIGHTNESS_COMMAND 0x100
+
void common_hal_displayio_display_construct(displayio_display_obj_t* self,
mp_obj_t bus, uint16_t width, uint16_t height,
- int16_t colstart, int16_t rowstart, uint16_t rotation, uint16_t color_depth,
+ int16_t colstart, int16_t rowstart, uint16_t rotation, uint16_t color_depth, bool grayscale,
+ bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte,
uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command, uint8_t set_vertical_scroll,
- uint8_t* init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t* backlight_pin,
+ uint8_t* init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t* backlight_pin, uint16_t brightness_command,
mp_float_t brightness, bool auto_brightness,
bool single_byte_bounds, bool data_as_commands);
int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* self);
-void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group);
+bool common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group);
void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self);
bool displayio_display_begin_transaction(displayio_display_obj_t* self);
void displayio_display_end_transaction(displayio_display_obj_t* self);
-void displayio_display_set_region_to_update(displayio_display_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
+// The second point of the region is exclusive.
+void displayio_display_set_region_to_update(displayio_display_obj_t* self, displayio_area_t* area);
bool displayio_display_frame_queued(displayio_display_obj_t* self);
bool displayio_display_refresh_queued(displayio_display_obj_t* self);
void displayio_display_finish_refresh(displayio_display_obj_t* self);
-void displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixels, uint32_t length);
+void displayio_display_send_pixels(displayio_display_obj_t* self, uint8_t* pixels, uint32_t length);
bool common_hal_displayio_display_get_auto_brightness(displayio_display_obj_t* self);
void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t* self, bool auto_brightness);
diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c
index 8ffe54be0..af64a2028 100644
--- a/shared-bindings/displayio/FourWire.c
+++ b/shared-bindings/displayio/FourWire.c
@@ -46,7 +46,7 @@
//| Manage updating a display over SPI four wire protocol in the background while Python code runs.
//| It doesn't handle display initialization.
//|
-//| .. class:: FourWire(spi_bus, *, command, chip_select, reset=None)
+//| .. class:: FourWire(spi_bus, *, command, chip_select, reset=None, baudrate=24000000)
//|
//| Create a FourWire object associated with the given pins.
//|
@@ -59,14 +59,16 @@
//| :param microcontroller.Pin command: Data or command pin
//| :param microcontroller.Pin chip_select: Chip select pin
//| :param microcontroller.Pin reset: Reset pin. When None only software reset can be used
+//| :param int baudrate: Maximum baudrate in Hz for the display on the bus
//|
STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- enum { ARG_spi_bus, ARG_command, ARG_chip_select, ARG_reset };
+ enum { ARG_spi_bus, ARG_command, ARG_chip_select, ARG_reset, ARG_baudrate };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_spi_bus, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
{ MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
{ MP_QSTR_reset, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
+ { MP_QSTR_baudrate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 24000000} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -97,7 +99,7 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_
}
common_hal_displayio_fourwire_construct(self,
- MP_OBJ_TO_PTR(spi), command, chip_select, reset);
+ MP_OBJ_TO_PTR(spi), command, chip_select, reset, args[ARG_baudrate].u_int);
return self;
}
diff --git a/shared-bindings/displayio/FourWire.h b/shared-bindings/displayio/FourWire.h
index b65b1b5b7..5dbd60764 100644
--- a/shared-bindings/displayio/FourWire.h
+++ b/shared-bindings/displayio/FourWire.h
@@ -36,7 +36,7 @@ extern const mp_obj_type_t displayio_fourwire_type;
void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self,
busio_spi_obj_t* spi, const mcu_pin_obj_t* command,
- const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset);
+ const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, uint32_t baudrate);
void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self);
diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c
index c7a72891a..5a35424ce 100644
--- a/shared-bindings/displayio/Group.c
+++ b/shared-bindings/displayio/Group.c
@@ -31,6 +31,7 @@
#include "lib/utils/context_manager_helpers.h"
#include "py/binary.h"
#include "py/objproperty.h"
+#include "py/objtype.h"
#include "py/runtime.h"
#include "supervisor/shared/translate.h"
@@ -80,8 +81,12 @@ STATIC mp_obj_t displayio_group_make_new(const mp_obj_type_t *type, size_t n_arg
}
// Helper to ensure we have the native super class instead of a subclass.
-static displayio_group_t* native_group(mp_obj_t group_obj) {
+displayio_group_t* native_group(mp_obj_t group_obj) {
mp_obj_t native_group = mp_instance_cast_to_native_base(group_obj, &displayio_group_type);
+ if (native_group == MP_OBJ_NULL) {
+ mp_raise_ValueError_varg(translate("Must be a %q subclass."), MP_QSTR_Group);
+ }
+ mp_obj_assert_native_inited(native_group);
return MP_OBJ_TO_PTR(native_group);
}
@@ -190,6 +195,21 @@ STATIC mp_obj_t displayio_group_obj_insert(mp_obj_t self_in, mp_obj_t index_obj,
}
MP_DEFINE_CONST_FUN_OBJ_3(displayio_group_insert_obj, displayio_group_obj_insert);
+
+//| .. method:: index(layer)
+//|
+//| Returns the index of the first copy of layer. Raises ValueError if not found.
+//|
+STATIC mp_obj_t displayio_group_obj_index(mp_obj_t self_in, mp_obj_t layer) {
+ displayio_group_t *self = native_group(self_in);
+ mp_int_t index = common_hal_displayio_group_index(self, layer);
+ if (index < 0) {
+ mp_raise_ValueError(translate("object not in sequence"));
+ }
+ return MP_OBJ_NEW_SMALL_INT(index);
+}
+MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_index_obj, displayio_group_obj_index);
+
//| .. method:: pop(i=-1)
//|
//| Remove the ith item and return it.
@@ -212,6 +232,20 @@ STATIC mp_obj_t displayio_group_obj_pop(size_t n_args, const mp_obj_t *pos_args,
}
MP_DEFINE_CONST_FUN_OBJ_KW(displayio_group_pop_obj, 1, displayio_group_obj_pop);
+
+//| .. method:: remove(layer)
+//|
+//| Remove the first copy of layer. Raises ValueError if it is not present.
+//|
+STATIC mp_obj_t displayio_group_obj_remove(mp_obj_t self_in, mp_obj_t layer) {
+ mp_obj_t index = displayio_group_obj_index(self_in, layer);
+ displayio_group_t *self = native_group(self_in);
+
+ common_hal_displayio_group_pop(self, MP_OBJ_SMALL_INT_VALUE(index));
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_remove_obj, displayio_group_obj_remove);
+
//| .. method:: __len__()
//|
//| Returns the number of layers in a Group
@@ -261,7 +295,7 @@ STATIC mp_obj_t group_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t valu
if (value == MP_OBJ_SENTINEL) {
// load
return common_hal_displayio_group_get(self, index);
- } else if (value == mp_const_none) {
+ } else if (value == MP_OBJ_NULL) {
common_hal_displayio_group_pop(self, index);
} else {
common_hal_displayio_group_set(self, index, value);
@@ -276,7 +310,9 @@ STATIC const mp_rom_map_elem_t displayio_group_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&displayio_group_y_obj) },
{ MP_ROM_QSTR(MP_QSTR_append), MP_ROM_PTR(&displayio_group_append_obj) },
{ MP_ROM_QSTR(MP_QSTR_insert), MP_ROM_PTR(&displayio_group_insert_obj) },
+ { MP_ROM_QSTR(MP_QSTR_index), MP_ROM_PTR(&displayio_group_index_obj) },
{ MP_ROM_QSTR(MP_QSTR_pop), MP_ROM_PTR(&displayio_group_pop_obj) },
+ { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&displayio_group_remove_obj) },
};
STATIC MP_DEFINE_CONST_DICT(displayio_group_locals_dict, displayio_group_locals_dict_table);
@@ -286,5 +322,6 @@ const mp_obj_type_t displayio_group_type = {
.make_new = displayio_group_make_new,
.subscr = group_subscr,
.unary_op = group_unary_op,
+ .getiter = mp_obj_new_generic_iterator,
.locals_dict = (mp_obj_dict_t*)&displayio_group_locals_dict,
};
diff --git a/shared-bindings/displayio/Group.h b/shared-bindings/displayio/Group.h
index fa3c32964..dc9616f2e 100644
--- a/shared-bindings/displayio/Group.h
+++ b/shared-bindings/displayio/Group.h
@@ -31,6 +31,7 @@
extern const mp_obj_type_t displayio_group_type;
+displayio_group_t* native_group(mp_obj_t group_obj);
void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y);
uint32_t common_hal_displayio_group_get_scale(displayio_group_t* self);
@@ -43,6 +44,7 @@ void common_hal_displayio_group_append(displayio_group_t* self, mp_obj_t layer);
void common_hal_displayio_group_insert(displayio_group_t* self, size_t index, mp_obj_t layer);
size_t common_hal_displayio_group_get_len(displayio_group_t* self);
mp_obj_t common_hal_displayio_group_pop(displayio_group_t* self, size_t index);
+mp_int_t common_hal_displayio_group_index(displayio_group_t* self, mp_obj_t layer);
mp_obj_t common_hal_displayio_group_get(displayio_group_t* self, size_t index);
void common_hal_displayio_group_set(displayio_group_t* self, size_t index, mp_obj_t layer);
diff --git a/shared-bindings/displayio/I2CDisplay.c b/shared-bindings/displayio/I2CDisplay.c
new file mode 100644
index 000000000..1f74e8c9e
--- /dev/null
+++ b/shared-bindings/displayio/I2CDisplay.c
@@ -0,0 +1,138 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "shared-bindings/displayio/I2CDisplay.h"
+
+#include <stdint.h>
+#include <string.h>
+
+#include "lib/utils/context_manager_helpers.h"
+#include "py/binary.h"
+#include "py/objproperty.h"
+#include "py/runtime.h"
+#include "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/util.h"
+#include "shared-module/displayio/__init__.h"
+#include "supervisor/shared/translate.h"
+
+//| .. currentmodule:: displayio
+//|
+//| :class:`I2CDisplay` -- Manage updating a display over I2C
+//| ==========================================================================
+//|
+//| Manage updating a display over I2C in the background while Python code runs.
+//| It doesn't handle display initialization.
+//|
+//| .. class:: I2CDisplay(i2c_bus, *, device_address, reset=None)
+//|
+//| Create a I2CDisplay object associated with the given I2C bus and reset pin.
+//|
+//| The I2C bus and pins are then in use by the display until `displayio.release_displays()` is
+//| called even after a reload. (It does this so CircuitPython can use the display after your code
+//| is done.) So, the first time you initialize a display bus in code.py you should call
+//| :py:func`displayio.release_displays` first, otherwise it will error after the first code.py run.
+//|
+//| :param busio.I2C i2c_bus: The I2C bus that make up the clock and data lines
+//| :param int device_address: The I2C address of the device
+//| :param microcontroller.Pin reset: Reset pin. When None only software reset can be used
+//|
+STATIC mp_obj_t displayio_i2cdisplay_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_i2c_bus, ARG_device_address, ARG_reset };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_i2c_bus, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_device_address, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
+ { MP_QSTR_reset, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
+ };
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ mp_obj_t reset = args[ARG_reset].u_obj;
+ if (reset != mp_const_none) {
+ assert_pin_free(reset);
+ } else {
+ reset = NULL;
+ }
+
+ displayio_i2cdisplay_obj_t* self = NULL;
+ mp_obj_t i2c = args[ARG_i2c_bus].u_obj;
+ for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+ if (displays[i].i2cdisplay_bus.base.type == NULL ||
+ displays[i].i2cdisplay_bus.base.type == &mp_type_NoneType) {
+ self = &displays[i].i2cdisplay_bus;
+ self->base.type = &displayio_i2cdisplay_type;
+ break;
+ }
+ }
+ if (self == NULL) {
+ mp_raise_RuntimeError(translate("Too many display busses"));
+ }
+
+ common_hal_displayio_i2cdisplay_construct(self,
+ MP_OBJ_TO_PTR(i2c), args[ARG_device_address].u_int, reset);
+ return self;
+}
+
+//| .. method:: send(command, data)
+//|
+//| Sends the given command value followed by the full set of data. Display state, such as
+//| vertical scroll, set via ``send`` may or may not be reset once the code is done.
+//|
+STATIC mp_obj_t displayio_i2cdisplay_obj_send(mp_obj_t self, mp_obj_t command_obj, mp_obj_t data_obj) {
+ mp_int_t command_int = MP_OBJ_SMALL_INT_VALUE(command_obj);
+ if (!MP_OBJ_IS_SMALL_INT(command_obj) || command_int > 255 || command_int < 0) {
+ mp_raise_ValueError(translate("Command must be 0-255"));
+ }
+ uint8_t command = command_int;
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(data_obj, &bufinfo, MP_BUFFER_READ);
+
+ // Wait for display bus to be available.
+ while (!common_hal_displayio_i2cdisplay_begin_transaction(self)) {
+#ifdef MICROPY_VM_HOOK_LOOP
+ MICROPY_VM_HOOK_LOOP ;
+#endif
+ }
+ uint8_t full_command[bufinfo.len + 1];
+ full_command[0] = command;
+ memcpy(full_command + 1, ((uint8_t*) bufinfo.buf), bufinfo.len);
+ common_hal_displayio_i2cdisplay_send(self, true, full_command, bufinfo.len + 1);
+ common_hal_displayio_i2cdisplay_end_transaction(self);
+
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_3(displayio_i2cdisplay_send_obj, displayio_i2cdisplay_obj_send);
+
+STATIC const mp_rom_map_elem_t displayio_i2cdisplay_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_i2cdisplay_send_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(displayio_i2cdisplay_locals_dict, displayio_i2cdisplay_locals_dict_table);
+
+const mp_obj_type_t displayio_i2cdisplay_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_I2CDisplay,
+ .make_new = displayio_i2cdisplay_make_new,
+ .locals_dict = (mp_obj_dict_t*)&displayio_i2cdisplay_locals_dict,
+};
diff --git a/shared-bindings/bleio/AddressType.h b/shared-bindings/displayio/I2CDisplay.h
index e69caffab..cc4162800 100644
--- a/shared-bindings/bleio/AddressType.h
+++ b/shared-bindings/displayio/I2CDisplay.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,27 +24,23 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_I2CDISPLAY_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_I2CDISPLAY_H
-#include "py/obj.h"
+#include "shared-module/displayio/I2CDisplay.h"
+#include "common-hal/microcontroller/Pin.h"
-typedef enum {
- ADDRESS_PUBLIC,
- ADDRESS_RANDOM_STATIC,
- ADDRESS_RANDOM_PRIVATE_RESOLVABLE,
- ADDRESS_RANDOM_PRIVATE_NON_RESOLVABLE
-} bleio_address_type_t;
+extern const mp_obj_type_t displayio_i2cdisplay_type;
-extern const mp_obj_type_t bleio_addresstype_type;
+void common_hal_displayio_i2cdisplay_construct(displayio_i2cdisplay_obj_t* self,
+ busio_i2c_obj_t* i2c, uint16_t device_address, const mcu_pin_obj_t* reset);
-typedef struct {
- mp_obj_base_t base;
-} bleio_addresstype_obj_t;
+void common_hal_displayio_i2cdisplay_deinit(displayio_i2cdisplay_obj_t* self);
-extern const bleio_addresstype_obj_t bleio_addresstype_public_obj;
-extern const bleio_addresstype_obj_t bleio_addresstype_random_static_obj;
-extern const bleio_addresstype_obj_t bleio_addresstype_random_private_resolvable_obj;
-extern const bleio_addresstype_obj_t bleio_addresstype_random_private_non_resolvable_obj;
+bool common_hal_displayio_i2cdisplay_begin_transaction(mp_obj_t self);
-#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H
+void common_hal_displayio_i2cdisplay_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length);
+
+void common_hal_displayio_i2cdisplay_end_transaction(mp_obj_t self);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_I2CDISPLAY_H
diff --git a/shared-bindings/displayio/Palette.c b/shared-bindings/displayio/Palette.c
index 799d42bef..dda58e3c5 100644
--- a/shared-bindings/displayio/Palette.c
+++ b/shared-bindings/displayio/Palette.c
@@ -67,6 +67,34 @@ STATIC mp_obj_t displayio_palette_make_new(const mp_obj_type_t *type, size_t n_a
return MP_OBJ_FROM_PTR(self);
}
+//| .. method:: __len__()
+//|
+//| Returns the number of colors in a Palette
+//|
+STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
+ displayio_palette_t *self = MP_OBJ_TO_PTR(self_in);
+ switch (op) {
+ case MP_UNARY_OP_BOOL: return mp_const_true;
+ case MP_UNARY_OP_LEN:
+ return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_palette_get_len(self));
+ default: return MP_OBJ_NULL; // op not supported
+ }
+}
+
+//| .. method:: __setitem__(index, value)
+//|
+//| Sets the pixel color at the given index. The index should be an integer in the range 0 to color_count-1.
+//|
+//| The value argument represents a color, and can be from 0x000000 to 0xFFFFFF (to represent an RGB value).
+//| Value can be an int, bytes (3 bytes (RGB) or 4 bytes (RGB + pad byte)), or bytearray.
+//|
+//| This allows you to::
+//|
+//| palette[0] = 0xFFFFFF # set using an integer
+//| palette[1] = b'\xff\xff\x00' # set using 3 bytes
+//| palette[2] = b'\xff\xff\x00\x00' # set using 4 bytes
+//| palette[3] = bytearray(b'\x00\x00\xFF') # set using a bytearay of 3 or 4 bytes
+//|
STATIC mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) {
if (value == MP_OBJ_NULL) {
// delete item
@@ -76,12 +104,12 @@ STATIC mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t val
if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) {
return MP_OBJ_NULL;
}
- // index read is not supported
- if (value == MP_OBJ_SENTINEL) {
- return MP_OBJ_NULL;
- }
displayio_palette_t *self = MP_OBJ_TO_PTR(self_in);
size_t index = mp_get_index(&displayio_palette_type, self->color_count, index_in, false);
+ // index read
+ if (value == MP_OBJ_SENTINEL) {
+ return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_palette_get_color(self, index));
+ }
uint32_t color;
mp_int_t int_value;
@@ -147,5 +175,7 @@ const mp_obj_type_t displayio_palette_type = {
.name = MP_QSTR_Palette,
.make_new = displayio_palette_make_new,
.subscr = palette_subscr,
+ .unary_op = group_unary_op,
+ .getiter = mp_obj_new_generic_iterator,
.locals_dict = (mp_obj_dict_t*)&displayio_palette_locals_dict,
};
diff --git a/shared-bindings/displayio/Palette.h b/shared-bindings/displayio/Palette.h
index 767fc7b63..8c9fe11e3 100644
--- a/shared-bindings/displayio/Palette.h
+++ b/shared-bindings/displayio/Palette.h
@@ -33,6 +33,8 @@ extern const mp_obj_type_t displayio_palette_type;
void common_hal_displayio_palette_construct(displayio_palette_t* self, uint16_t color_count);
void common_hal_displayio_palette_set_color(displayio_palette_t* self, uint32_t palette_index, uint32_t color);
+uint32_t common_hal_displayio_palette_get_color(displayio_palette_t* self, uint32_t palette_index);
+uint32_t common_hal_displayio_palette_get_len(displayio_palette_t* self);
void common_hal_displayio_palette_make_opaque(displayio_palette_t* self, uint32_t palette_index);
void common_hal_displayio_palette_make_transparent(displayio_palette_t* self, uint32_t palette_index);
diff --git a/shared-bindings/displayio/TileGrid.c b/shared-bindings/displayio/TileGrid.c
index 2b41eb8fd..53fbb51c8 100644
--- a/shared-bindings/displayio/TileGrid.c
+++ b/shared-bindings/displayio/TileGrid.c
@@ -31,6 +31,7 @@
#include "lib/utils/context_manager_helpers.h"
#include "py/binary.h"
#include "py/objproperty.h"
+#include "py/objtype.h"
#include "py/runtime.h"
#include "shared-bindings/displayio/Bitmap.h"
#include "shared-bindings/displayio/ColorConverter.h"
@@ -63,7 +64,7 @@
//| :param int height: Height of the grid in tiles.
//| :param int tile_width: Width of a single tile in pixels. Defaults to the full Bitmap and must evenly divide into the Bitmap's dimensions.
//| :param int tile_height: Height of a single tile in pixels. Defaults to the full Bitmap and must evenly divide into the Bitmap's dimensions.
-//| :param in default_tile: Default tile index to show.
+//| :param int default_tile: Default tile index to show.
//| :param int x: Initial x position of the left edge within the parent.
//| :param int y: Initial y position of the top edge within the parent.
//|
@@ -130,7 +131,8 @@ STATIC mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_
displayio_tilegrid_t *self = m_new_obj(displayio_tilegrid_t);
self->base.type = &displayio_tilegrid_type;
- common_hal_displayio_tilegrid_construct(self, native, bitmap_width / tile_width,
+ common_hal_displayio_tilegrid_construct(self, native,
+ bitmap_width / tile_width, bitmap_height / tile_height,
pixel_shader, args[ARG_width].u_int, args[ARG_height].u_int,
tile_width, tile_height, x, y, args[ARG_default_tile].u_int);
return MP_OBJ_FROM_PTR(self);
@@ -139,6 +141,7 @@ STATIC mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_
// Helper to ensure we have the native super class instead of a subclass.
static displayio_tilegrid_t* native_tilegrid(mp_obj_t tilegrid_obj) {
mp_obj_t native_tilegrid = mp_instance_cast_to_native_base(tilegrid_obj, &displayio_tilegrid_type);
+ mp_obj_assert_native_inited(native_tilegrid);
return MP_OBJ_TO_PTR(native_tilegrid);
}
@@ -194,6 +197,83 @@ const mp_obj_property_t displayio_tilegrid_y_obj = {
(mp_obj_t)&mp_const_none_obj},
};
+//| .. attribute:: flip_x
+//|
+//| If true, the left edge rendered will be the right edge of the right-most tile.
+//|
+STATIC mp_obj_t displayio_tilegrid_obj_get_flip_x(mp_obj_t self_in) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
+ return mp_obj_new_bool(common_hal_displayio_tilegrid_get_flip_x(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_flip_x_obj, displayio_tilegrid_obj_get_flip_x);
+
+STATIC mp_obj_t displayio_tilegrid_obj_set_flip_x(mp_obj_t self_in, mp_obj_t flip_x_obj) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
+
+ common_hal_displayio_tilegrid_set_flip_x(self, mp_obj_is_true(flip_x_obj));
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_flip_x_obj, displayio_tilegrid_obj_set_flip_x);
+
+const mp_obj_property_t displayio_tilegrid_flip_x_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&displayio_tilegrid_get_flip_x_obj,
+ (mp_obj_t)&displayio_tilegrid_set_flip_x_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+//| .. attribute:: flip_y
+//|
+//| If true, the top edge rendered will be the bottom edge of the bottom-most tile.
+//|
+STATIC mp_obj_t displayio_tilegrid_obj_get_flip_y(mp_obj_t self_in) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
+ return mp_obj_new_bool(common_hal_displayio_tilegrid_get_flip_y(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_flip_y_obj, displayio_tilegrid_obj_get_flip_y);
+
+STATIC mp_obj_t displayio_tilegrid_obj_set_flip_y(mp_obj_t self_in, mp_obj_t flip_y_obj) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
+
+ common_hal_displayio_tilegrid_set_flip_y(self, mp_obj_is_true(flip_y_obj));
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_flip_y_obj, displayio_tilegrid_obj_set_flip_y);
+
+const mp_obj_property_t displayio_tilegrid_flip_y_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&displayio_tilegrid_get_flip_y_obj,
+ (mp_obj_t)&displayio_tilegrid_set_flip_y_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+
+//| .. attribute:: transpose_xy
+//|
+//| If true, the TileGrid's axis will be swapped. When combined with mirroring, any 90 degree
+//| rotation can be achieved along with the corresponding mirrored version.
+//|
+STATIC mp_obj_t displayio_tilegrid_obj_get_transpose_xy(mp_obj_t self_in) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
+ return mp_obj_new_bool(common_hal_displayio_tilegrid_get_transpose_xy(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_transpose_xy_obj, displayio_tilegrid_obj_get_transpose_xy);
+
+STATIC mp_obj_t displayio_tilegrid_obj_set_transpose_xy(mp_obj_t self_in, mp_obj_t transpose_xy_obj) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
+
+ common_hal_displayio_tilegrid_set_transpose_xy(self, mp_obj_is_true(transpose_xy_obj));
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_transpose_xy_obj, displayio_tilegrid_obj_set_transpose_xy);
+
+const mp_obj_property_t displayio_tilegrid_transpose_xy_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&displayio_tilegrid_get_transpose_xy_obj,
+ (mp_obj_t)&displayio_tilegrid_set_transpose_xy_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
//| .. attribute:: pixel_shader
//|
//| The pixel shader of the tilegrid.
@@ -267,7 +347,7 @@ STATIC mp_obj_t tilegrid_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t v
}
if (x >= common_hal_displayio_tilegrid_get_width(self) ||
y >= common_hal_displayio_tilegrid_get_height(self)) {
- mp_raise_IndexError(translate("tile index out of bounds"));
+ mp_raise_IndexError(translate("Tile index out of bounds"));
}
if (value_obj == MP_OBJ_SENTINEL) {
@@ -278,7 +358,7 @@ STATIC mp_obj_t tilegrid_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t v
} else {
mp_int_t value = mp_obj_get_int(value_obj);
if (value < 0 || value > 255) {
- mp_raise_ValueError(translate("Tile indices must be 0 - 255"));
+ mp_raise_ValueError(translate("Tile value out of bounds"));
}
common_hal_displayio_tilegrid_set_tile(self, x, y, value);
}
@@ -290,6 +370,9 @@ STATIC const mp_rom_map_elem_t displayio_tilegrid_locals_dict_table[] = {
// Properties
{ MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&displayio_tilegrid_x_obj) },
{ MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&displayio_tilegrid_y_obj) },
+ { MP_ROM_QSTR(MP_QSTR_flip_x), MP_ROM_PTR(&displayio_tilegrid_flip_x_obj) },
+ { MP_ROM_QSTR(MP_QSTR_flip_y), MP_ROM_PTR(&displayio_tilegrid_flip_y_obj) },
+ { MP_ROM_QSTR(MP_QSTR_transpose_xy), MP_ROM_PTR(&displayio_tilegrid_transpose_xy_obj) },
{ MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&displayio_tilegrid_pixel_shader_obj) },
};
STATIC MP_DEFINE_CONST_DICT(displayio_tilegrid_locals_dict, displayio_tilegrid_locals_dict_table);
diff --git a/shared-bindings/displayio/TileGrid.h b/shared-bindings/displayio/TileGrid.h
index 15a71b53b..8227abfd3 100644
--- a/shared-bindings/displayio/TileGrid.h
+++ b/shared-bindings/displayio/TileGrid.h
@@ -32,7 +32,8 @@
extern const mp_obj_type_t displayio_tilegrid_type;
void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_t bitmap,
- uint16_t bitmap_width_in_tiles, mp_obj_t pixel_shader, uint16_t width, uint16_t height,
+ uint16_t bitmap_width_in_tiles, uint16_t bitmap_height_in_tiles,
+ mp_obj_t pixel_shader, uint16_t width, uint16_t height,
uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint8_t default_tile);
mp_int_t common_hal_displayio_tilegrid_get_x(displayio_tilegrid_t *self);
@@ -42,6 +43,14 @@ void common_hal_displayio_tilegrid_set_y(displayio_tilegrid_t *self, mp_int_t y)
mp_obj_t common_hal_displayio_tilegrid_get_pixel_shader(displayio_tilegrid_t *self);
void common_hal_displayio_tilegrid_set_pixel_shader(displayio_tilegrid_t *self, mp_obj_t pixel_shader);
+
+bool common_hal_displayio_tilegrid_get_flip_x(displayio_tilegrid_t *self);
+void common_hal_displayio_tilegrid_set_flip_x(displayio_tilegrid_t *self, bool flip_x);
+bool common_hal_displayio_tilegrid_get_flip_y(displayio_tilegrid_t *self);
+void common_hal_displayio_tilegrid_set_flip_y(displayio_tilegrid_t *self, bool flip_y);
+bool common_hal_displayio_tilegrid_get_transpose_xy(displayio_tilegrid_t *self);
+void common_hal_displayio_tilegrid_set_transpose_xy(displayio_tilegrid_t *self, bool transpose_xy);
+
uint16_t common_hal_displayio_tilegrid_get_width(displayio_tilegrid_t *self);
uint16_t common_hal_displayio_tilegrid_get_height(displayio_tilegrid_t *self);
diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c
index 44b1e0b07..fd3dc4233 100644
--- a/shared-bindings/displayio/__init__.c
+++ b/shared-bindings/displayio/__init__.c
@@ -35,6 +35,7 @@
#include "shared-bindings/displayio/Display.h"
#include "shared-bindings/displayio/FourWire.h"
#include "shared-bindings/displayio/Group.h"
+#include "shared-bindings/displayio/I2CDisplay.h"
#include "shared-bindings/displayio/OnDiskBitmap.h"
#include "shared-bindings/displayio/Palette.h"
#include "shared-bindings/displayio/ParallelBus.h"
@@ -61,6 +62,7 @@
//| Display
//| FourWire
//| Group
+//| I2CDisplay
//| OnDiskBitmap
//| Palette
//| ParallelBus
@@ -69,7 +71,7 @@
//|
-//| .. method:: release_displays()
+//| .. function:: release_displays()
//|
//| Releases any actively used displays so their busses and pins can be used again. This will also
//| release the builtin display on boards that have one. You will need to reinitialize it yourself
@@ -96,6 +98,7 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_TileGrid), MP_ROM_PTR(&displayio_tilegrid_type) },
{ MP_ROM_QSTR(MP_QSTR_FourWire), MP_ROM_PTR(&displayio_fourwire_type) },
+ { MP_ROM_QSTR(MP_QSTR_I2CDisplay), MP_ROM_PTR(&displayio_i2cdisplay_type) },
{ MP_ROM_QSTR(MP_QSTR_ParallelBus), MP_ROM_PTR(&displayio_parallelbus_type) },
{ MP_ROM_QSTR(MP_QSTR_release_displays), MP_ROM_PTR(&displayio_release_displays_obj) },
diff --git a/shared-bindings/fontio/Glyph.c b/shared-bindings/fontio/Glyph.c
index 80298fd16..a23284152 100644
--- a/shared-bindings/fontio/Glyph.c
+++ b/shared-bindings/fontio/Glyph.c
@@ -37,7 +37,7 @@
//|
//| Named tuple used to capture a single glyph and its attributes.
//|
-//| :param fontio.Bitmap bitmap: the bitmap including the glyph
+//| :param displayio.Bitmap bitmap: the bitmap including the glyph
//| :param int tile_index: the tile index within the bitmap
//| :param int width: the width of the glyph's bitmap
//| :param int height: the height of the glyph's bitmap
diff --git a/shared-bindings/frequencyio/FrequencyIn.c b/shared-bindings/frequencyio/FrequencyIn.c
index 908cb307d..e2b924c07 100644
--- a/shared-bindings/frequencyio/FrequencyIn.c
+++ b/shared-bindings/frequencyio/FrequencyIn.c
@@ -109,6 +109,12 @@ STATIC mp_obj_t frequencyio_frequencyin_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_deinit_obj, frequencyio_frequencyin_deinit);
+STATIC void check_for_deinit(frequencyio_frequencyin_obj_t *self) {
+ if (common_hal_frequencyio_frequencyin_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -133,7 +139,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(frequencyio_frequencyin___exit___obj,
//|
STATIC mp_obj_t frequencyio_frequencyin_obj_pause(mp_obj_t self_in) {
frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self));
+ check_for_deinit(self);
common_hal_frequencyio_frequencyin_pause(self);
return mp_const_none;
@@ -146,7 +152,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_pause_obj, frequencyio_frequen
//|
STATIC mp_obj_t frequencyio_frequencyin_obj_resume(mp_obj_t self_in) {
frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self));
+ check_for_deinit(self);
common_hal_frequencyio_frequencyin_resume(self);
return mp_const_none;
@@ -160,7 +166,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_resume_obj, frequencyio_freque
STATIC mp_obj_t frequencyio_frequencyin_obj_clear(mp_obj_t self_in) {
frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self));
+ check_for_deinit(self);
common_hal_frequencyio_frequencyin_clear(self);
return mp_const_none;
@@ -178,7 +184,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_clear_obj, frequencyio_frequen
//|
STATIC mp_obj_t frequencyio_frequencyin_obj_get_capture_period(mp_obj_t self_in) {
frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_frequencyio_frequencyin_get_capture_period(self));
}
@@ -186,7 +192,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequency_get_capture_period_obj, frequenc
STATIC mp_obj_t frequencyio_frequencyin_obj_set_capture_period(mp_obj_t self_in, mp_obj_t capture_period) {
frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self));
+ check_for_deinit(self);
common_hal_frequencyio_frequencyin_set_capture_period(self, mp_obj_get_int(capture_period));
return mp_const_none;
@@ -206,7 +212,7 @@ const mp_obj_property_t frequencyio_frequencyin_capture_period_obj = {
//|
STATIC mp_obj_t frequencyio_frequencyin_obj_get_value(mp_obj_t self_in) {
frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self));
+ check_for_deinit(self);
//return MP_OBJ_NEW_SMALL_INT(common_hal_frequencyio_frequencyin_get_item(self));
return mp_obj_new_int_from_float(common_hal_frequencyio_frequencyin_get_item(self));
diff --git a/shared-bindings/gamepad/GamePad.c b/shared-bindings/gamepad/GamePad.c
index 15304d6a2..d3c29019a 100644
--- a/shared-bindings/gamepad/GamePad.c
+++ b/shared-bindings/gamepad/GamePad.c
@@ -127,7 +127,7 @@ STATIC mp_obj_t gamepad_make_new(const mp_obj_type_t *type, size_t n_args,
STATIC mp_obj_t gamepad_get_pressed(mp_obj_t self_in) {
gamepad_obj_t* gamepad_singleton = MP_STATE_VM(gamepad_singleton);
mp_obj_t pressed = MP_OBJ_NEW_SMALL_INT(gamepad_singleton->pressed);
- gamepad_singleton->pressed = 0;
+ gamepad_singleton->pressed = gamepad_singleton->last;
return pressed;
}
MP_DEFINE_CONST_FUN_OBJ_1(gamepad_get_pressed_obj, gamepad_get_pressed);
diff --git a/shared-bindings/gamepadshift/GamePadShift.c b/shared-bindings/gamepadshift/GamePadShift.c
index d6f365388..91203ad20 100644
--- a/shared-bindings/gamepadshift/GamePadShift.c
+++ b/shared-bindings/gamepadshift/GamePadShift.c
@@ -94,7 +94,7 @@ STATIC mp_obj_t gamepadshift_make_new(const mp_obj_type_t *type, size_t n_args,
STATIC mp_obj_t gamepadshift_get_pressed(mp_obj_t self_in) {
gamepadshift_obj_t* gamepad_singleton = MP_STATE_VM(gamepad_singleton);
mp_obj_t pressed = MP_OBJ_NEW_SMALL_INT(gamepad_singleton->pressed);
- gamepad_singleton->pressed = 0;
+ gamepad_singleton->pressed = gamepad_singleton->last;
return pressed;
}
MP_DEFINE_CONST_FUN_OBJ_1(gamepadshift_get_pressed_obj, gamepadshift_get_pressed);
diff --git a/shared-bindings/help.c b/shared-bindings/help.c
index e0770ff3c..4e7c3a78b 100644
--- a/shared-bindings/help.c
+++ b/shared-bindings/help.c
@@ -27,7 +27,7 @@
//| :func:`help` - Built-in method to provide helpful information
//| ==============================================================
//|
-//| .. method:: help(object=None)
+//| .. function:: help(object=None)
//|
//| Prints a help method about the given object. When ``object`` is none,
//| prints general port information.
diff --git a/shared-bindings/i2cslave/I2CSlave.c b/shared-bindings/i2cslave/I2CSlave.c
index 090a53581..2598accbb 100644
--- a/shared-bindings/i2cslave/I2CSlave.c
+++ b/shared-bindings/i2cslave/I2CSlave.c
@@ -150,7 +150,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cslave_i2c_slave___exit___obj, 4, 4
STATIC mp_obj_t i2cslave_i2c_slave_request(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
mp_check_self(MP_OBJ_IS_TYPE(pos_args[0], &i2cslave_i2c_slave_type));
i2cslave_i2c_slave_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_i2cslave_i2c_slave_deinited(self));
+ if(common_hal_i2cslave_i2c_slave_deinited(self)) {
+ raise_deinited_error();
+ }
enum { ARG_timeout };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)} },
diff --git a/shared-bindings/index.rst b/shared-bindings/index.rst
index 4f2e28702..cbffdb614 100644
--- a/shared-bindings/index.rst
+++ b/shared-bindings/index.rst
@@ -1,11 +1,11 @@
Core Modules
========================================
-These core modules are intended on being consistent across ports. Currently
-they are only implemented in the SAMD21 and ESP8266 ports. A module may not exist
-in a port if no underlying hardware support is present or if flash space is
-limited. For example, a microcontroller without analog features will not have
-`analogio`.
+These core modules are intended on being consistent across ports and boards.
+A module may not exist on a port/board if no underlying hardware support is
+present or if flash space is limited. For example, a microcontroller without
+analog features will not have `analogio`. See the `support_matrix` page for
+a list of modules supported on each board.
Modules
---------
@@ -14,54 +14,6 @@ Modules
:glob:
:maxdepth: 3
+ support_matrix
*/__init__
help
-
-.. _module-support-matrix:
-
-Support Matrix
----------------
-NOTE 1: **All Supported** means the following ports are supported: SAMD21, SAMD21 Express,
-SAMD51, SAMD51 Express, and ESP8266.
-
-NOTE 2: **SAMD** and/or **SAMD Express** without additional numbers, means both SAMD21 & SAMD51 versions
-are supported.
-
-NOTE 3: The `pIRkey SAMD21 board <https://www.adafruit.com/product/3364>`_ is specialized and may not
-have modules as listed below.
-
-================= ==============================
-Module Supported Ports
-================= ==============================
-`analogio` **All Supported**
-`audiobusio` **SAMD/SAMD Express**
-`audioio` **SAMD Express**
-`binascii` **ESP8266**
-`bitbangio` **SAMD Express, ESP8266**
-`board` **All Supported**
-`bleio` **nRF**
-`busio` **All Supported**
-`digitalio` **All Supported**
-`frequencyio` **SAMD51**
-`gamepad` **SAMD Express, nRF**
-`hashlib` **ESP8266**
-`i2cslave` **SAMD Express**
-`math` **All Supported**
-`microcontroller` **All Supported**
-`multiterminal` **ESP8266**
-`neopixel_write` **All Supported**
-`nvm` **SAMD Express**
-`os` **All Supported**
-`pulseio` **SAMD/SAMD Express**
-`random` **All Supported**
-`rotaryio` **SAMD51, SAMD Express**
-`storage` **All Supported**
-`struct` **All Supported**
-`supervisor` **SAMD/SAMD Express**
-`time` **All Supported**
-`touchio` **SAMD/SAMD Express**
-`uheap` **Debug (All)**
-`usb_hid` **SAMD/SAMD Express**
-`_pixelbuf` **SAMD Express**
-`_stage` **SAMD/SAMD Express**
-================= ==============================
diff --git a/shared-bindings/microcontroller/Pin.c b/shared-bindings/microcontroller/Pin.c
index e79663107..3635f0afb 100644
--- a/shared-bindings/microcontroller/Pin.c
+++ b/shared-bindings/microcontroller/Pin.c
@@ -40,7 +40,7 @@
//|
//| Identifies an IO pin on the microcontroller.
//|
-//| .. class:: Pin
+//| .. class:: Pin()
//|
//| Identifies an IO pin on the microcontroller. They are fixed by the
//| hardware so they cannot be constructed on demand. Instead, use
diff --git a/shared-bindings/microcontroller/RunMode.c b/shared-bindings/microcontroller/RunMode.c
index 7c3f84fca..913242ad2 100644
--- a/shared-bindings/microcontroller/RunMode.c
+++ b/shared-bindings/microcontroller/RunMode.c
@@ -31,24 +31,30 @@
//| :class:`RunMode` -- run state of the microcontroller
//| =============================================================
//|
-//| .. class:: microcontroller.RunMode
+//| .. class:: RunMode()
//|
//| Enum-like class to define the run mode of the microcontroller and
//| CircuitPython.
//|
-//| .. data:: NORMAL
+//| .. attribute:: NORMAL
//|
//| Run CircuitPython as normal.
//|
-//| .. data:: SAFE_MODE
+//| :type microcontroller.RunMode:
+//|
+//| .. attribute:: SAFE_MODE
//|
//| Run CircuitPython in safe mode. User code will not be run and the
//| file system will be writeable over USB.
//|
-//| .. data:: BOOTLOADER
+//| :type microcontroller.RunMode:
+//|
+//| .. attribute:: BOOTLOADER
//|
//| Run the bootloader.
//|
+//| :type microcontroller.RunMode:
+//|
const mp_obj_type_t mcu_runmode_type;
const mcu_runmode_obj_t mcu_runmode_normal_obj = {
diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c
index da8d0bd94..090c4564d 100644
--- a/shared-bindings/microcontroller/__init__.c
+++ b/shared-bindings/microcontroller/__init__.c
@@ -62,14 +62,14 @@
//| RunMode
//|
-//| .. attribute:: cpu
+//| .. data:: cpu
//|
//| CPU information and control, such as ``cpu.temperature`` and ``cpu.frequency``
//| (clock frequency).
//| This object is the sole instance of `microcontroller.Processor`.
//|
-//| .. method:: delay_us(delay)
+//| .. function:: delay_us(delay)
//|
//| Dedicated delay method used for very short delays. **Do not** do long delays
//| because this stops all other functions from completing. Think of this as an empty
@@ -87,7 +87,7 @@ STATIC mp_obj_t mcu_delay_us(mp_obj_t delay_obj) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mcu_delay_us_obj, mcu_delay_us);
-//| .. method:: disable_interrupts()
+//| .. function:: disable_interrupts()
//|
//| Disable all interrupts. Be very careful, this can stall everything.
//|
@@ -97,7 +97,7 @@ STATIC mp_obj_t mcu_disable_interrupts(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_disable_interrupts_obj, mcu_disable_interrupts);
-//| .. method:: enable_interrupts()
+//| .. function:: enable_interrupts()
//|
//| Enable the interrupts that were enabled at the last disable.
//|
@@ -107,7 +107,7 @@ STATIC mp_obj_t mcu_enable_interrupts(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_enable_interrupts_obj, mcu_enable_interrupts);
-//| .. method:: on_next_reset(run_mode)
+//| .. function:: on_next_reset(run_mode)
//|
//| Configure the run mode used the next time the microcontroller is reset but
//| not powered down.
@@ -132,7 +132,7 @@ STATIC mp_obj_t mcu_on_next_reset(mp_obj_t run_mode_obj) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mcu_on_next_reset_obj, mcu_on_next_reset);
-//| .. method:: reset()
+//| .. function:: reset()
//|
//| Reset the microcontroller. After reset, the microcontroller will enter the
//| run mode last set by `on_next_reset`.
@@ -148,11 +148,13 @@ STATIC mp_obj_t mcu_reset(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_reset_obj, mcu_reset);
-//| .. attribute:: nvm
+//| .. data:: nvm
//|
//| Available non-volatile memory.
//| This object is the sole instance of `nvm.ByteArray` when available or ``None`` otherwise.
//|
+//| :type: nvm.ByteArray or None
+//|
//| :mod:`microcontroller.pin` --- Microcontroller pin names
//| --------------------------------------------------------
diff --git a/shared-bindings/neopixel_write/__init__.c b/shared-bindings/neopixel_write/__init__.c
index 05d6fd97a..1ee66337b 100644
--- a/shared-bindings/neopixel_write/__init__.c
+++ b/shared-bindings/neopixel_write/__init__.c
@@ -55,11 +55,11 @@
//| pixel_off = bytearray([0, 0, 0])
//| neopixel_write.neopixel_write(pin, pixel_off)
//|
-//| .. method:: neopixel_write.neopixel_write(digitalinout, buf)
+//| .. function:: neopixel_write(digitalinout, buf)
//|
//| Write buf out on the given DigitalInOut.
//|
-//| :param ~digitalio.DigitalInOut gpio: the DigitalInOut to output with
+//| :param ~digitalio.DigitalInOut digitalinout: the DigitalInOut to output with
//| :param bytearray buf: The bytes to clock out. No assumption is made about color order
//|
STATIC mp_obj_t neopixel_write_neopixel_write_(mp_obj_t digitalinout_obj, mp_obj_t buf) {
diff --git a/shared-bindings/network/__init__.c b/shared-bindings/network/__init__.c
index 1067ea549..01763a73c 100644
--- a/shared-bindings/network/__init__.c
+++ b/shared-bindings/network/__init__.c
@@ -49,7 +49,7 @@
//| It is used by the 'socket' module to look up a suitable
//| NIC when a socket is created.
//|
-//| .. function:: route
+//| .. function:: route()
//|
//| Returns a list of all configured NICs.
//|
diff --git a/shared-bindings/ps2io/Ps2.c b/shared-bindings/ps2io/Ps2.c
new file mode 100644
index 000000000..fb5c24b85
--- /dev/null
+++ b/shared-bindings/ps2io/Ps2.c
@@ -0,0 +1,243 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Elvis Pfutzenreuter <epxx@epxx.co>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdint.h>
+
+#include "lib/utils/context_manager_helpers.h"
+#include "py/objproperty.h"
+#include "py/runtime.h"
+#include "py/runtime0.h"
+#include "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/ps2io/Ps2.h"
+#include "shared-bindings/util.h"
+#include "supervisor/shared/translate.h"
+
+//| .. currentmodule:: ps2io
+//|
+//| :class:`Ps2` -- Communicate with a PS/2 keyboard or mouse
+//| =========================================================
+//|
+//| Ps2 implements the PS/2 keyboard/mouse serial protocol, used in
+//| legacy devices. It is similar to UART but there are only two
+//| lines (Data and Clock). PS/2 devices are 5V, so bidirectional
+//| level converters must be used to connect the I/O lines to pins
+//| of 3.3V boards.
+//|
+//| .. class:: Ps2(data_pin, clock_pin)
+//|
+//| Create a Ps2 object associated with the given pins.
+//|
+//| :param ~microcontroller.Pin data_pin: Pin tied to data wire.
+//| :param ~microcontroller.Pin clock_pin: Pin tied to clock wire.
+//| This pin must support interrupts.
+//|
+//| Read one byte from PS/2 keyboard and turn on Scroll Lock LED::
+//|
+//| import ps2io
+//| import board
+//|
+//| kbd = ps2io.Ps2(board.D10, board.D11)
+//|
+//| while len(kbd) == 0:
+//| pass
+//|
+//| print(kbd.popleft())
+//| print(kbd.sendcmd(0xed))
+//| print(kbd.sendcmd(0x01))
+//|
+STATIC mp_obj_t ps2io_ps2_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_datapin, ARG_clkpin };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_datapin, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_clkpin, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ };
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+ assert_pin(args[ARG_clkpin].u_obj, false);
+ assert_pin(args[ARG_datapin].u_obj, false);
+ const mcu_pin_obj_t* clkpin = MP_OBJ_TO_PTR(args[ARG_clkpin].u_obj);
+ assert_pin_free(clkpin);
+ const mcu_pin_obj_t* datapin = MP_OBJ_TO_PTR(args[ARG_datapin].u_obj);
+ assert_pin_free(datapin);
+
+ ps2io_ps2_obj_t *self = m_new_obj(ps2io_ps2_obj_t);
+ self->base.type = &ps2io_ps2_type;
+
+ common_hal_ps2io_ps2_construct(self, datapin, clkpin);
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+//| .. method:: deinit()
+//|
+//| Deinitialises the Ps2 and releases any hardware resources for reuse.
+//|
+STATIC mp_obj_t ps2io_ps2_deinit(mp_obj_t self_in) {
+ ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ common_hal_ps2io_ps2_deinit(self);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(ps2io_ps2_deinit_obj, ps2io_ps2_deinit);
+
+STATIC void check_for_deinit(ps2io_ps2_obj_t *self) {
+ if (common_hal_ps2io_ps2_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
+//| .. method:: __enter__()
+//|
+//| No-op used by Context Managers.
+//|
+// Provided by context manager helper.
+
+//| .. method:: __exit__()
+//|
+//| Automatically deinitializes the hardware when exiting a context. See
+//| :ref:`lifetime-and-contextmanagers` for more info.
+//|
+STATIC mp_obj_t ps2io_ps2_obj___exit__(size_t n_args, const mp_obj_t *args) {
+ (void)n_args;
+ common_hal_ps2io_ps2_deinit(args[0]);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ps2io_ps2___exit___obj, 4, 4, ps2io_ps2_obj___exit__);
+
+//| .. method:: popleft()
+//|
+//| Removes and returns the oldest received byte. When buffer
+//| is empty, raises an IndexError exception.
+//|
+STATIC mp_obj_t ps2io_ps2_obj_popleft(mp_obj_t self_in) {
+ ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+
+ int b = common_hal_ps2io_ps2_popleft(self);
+ if (b < 0) {
+ mp_raise_IndexError(translate("Pop from an empty Ps2 buffer"));
+ }
+ return MP_OBJ_NEW_SMALL_INT(b);
+}
+MP_DEFINE_CONST_FUN_OBJ_1(ps2io_ps2_popleft_obj, ps2io_ps2_obj_popleft);
+
+//| .. method:: sendcmd(byte)
+//|
+//| Sends a command byte to PS/2. Returns the response byte, typically
+//| the general ack value (0xFA). Some commands return additional data
+//| which is available through :py:func:`popleft()`.
+//|
+//| Raises a RuntimeError in case of failure. The root cause can be found
+//| by calling :py:func:`clear_errors()`. It is advisable to call
+//| :py:func:`clear_errors()` before :py:func:`sendcmd()` to flush any
+//| previous errors.
+//|
+//| :param int byte: byte value of the command
+//|
+STATIC mp_obj_t ps2io_ps2_obj_sendcmd(mp_obj_t self_in, mp_obj_t ob) {
+ ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+ mp_int_t cmd = mp_obj_get_int(ob) & 0xff;
+ int resp = common_hal_ps2io_ps2_sendcmd(self, cmd);
+ if (resp < 0) {
+ mp_raise_RuntimeError(translate("Failed sending command."));
+ }
+ return MP_OBJ_NEW_SMALL_INT(resp);
+}
+MP_DEFINE_CONST_FUN_OBJ_2(ps2io_ps2_sendcmd_obj, ps2io_ps2_obj_sendcmd);
+
+//| .. method:: clear_errors()
+//|
+//| Returns and clears a bitmap with latest recorded communication errors.
+//|
+//| Reception errors (arise asynchronously, as data is received):
+//|
+//| 0x01: start bit not 0
+//|
+//| 0x02: timeout
+//|
+//| 0x04: parity bit error
+//|
+//| 0x08: stop bit not 1
+//|
+//| 0x10: buffer overflow, newest data discarded
+//|
+//| Transmission errors (can only arise in the course of sendcmd()):
+//|
+//| 0x100: clock pin didn't go to LO in time
+//|
+//| 0x200: clock pin didn't go to HI in time
+//|
+//| 0x400: data pin didn't ACK
+//|
+//| 0x800: clock pin didn't ACK
+//|
+//| 0x1000: device didn't respond to RTS
+//|
+//| 0x2000: device didn't send a response byte in time
+//|
+STATIC mp_obj_t ps2io_ps2_obj_clear_errors(mp_obj_t self_in) {
+ ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+
+ return MP_OBJ_NEW_SMALL_INT(common_hal_ps2io_ps2_clear_errors(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(ps2io_ps2_clear_errors_obj, ps2io_ps2_obj_clear_errors);
+
+//| .. method:: __len__()
+//|
+//| Returns the number of received bytes in buffer, available
+//| to :py:func:`popleft()`.
+//|
+STATIC mp_obj_t ps2_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
+ ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+ uint16_t len = common_hal_ps2io_ps2_get_len(self);
+ switch (op) {
+ case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0);
+ case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len);
+ default: return MP_OBJ_NULL; // op not supported
+ }
+}
+
+STATIC const mp_rom_map_elem_t ps2io_ps2_locals_dict_table[] = {
+ // Methods
+ { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&ps2io_ps2_deinit_obj) },
+ { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
+ { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&ps2io_ps2___exit___obj) },
+ { MP_ROM_QSTR(MP_QSTR_popleft), MP_ROM_PTR(&ps2io_ps2_popleft_obj) },
+ { MP_ROM_QSTR(MP_QSTR_sendcmd), MP_ROM_PTR(&ps2io_ps2_sendcmd_obj) },
+ { MP_ROM_QSTR(MP_QSTR_clear_errors), MP_ROM_PTR(&ps2io_ps2_clear_errors_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(ps2io_ps2_locals_dict, ps2io_ps2_locals_dict_table);
+
+const mp_obj_type_t ps2io_ps2_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Ps2,
+ .make_new = ps2io_ps2_make_new,
+ .unary_op = ps2_unary_op,
+ .locals_dict = (mp_obj_dict_t*)&ps2io_ps2_locals_dict,
+};
diff --git a/shared-bindings/ps2io/Ps2.h b/shared-bindings/ps2io/Ps2.h
new file mode 100644
index 000000000..523869d55
--- /dev/null
+++ b/shared-bindings/ps2io/Ps2.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Elvis Pfutzenreuter <epxx@epxx.co>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO_PS2_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO_PS2_H
+
+#include "common-hal/microcontroller/Pin.h"
+#include "common-hal/ps2io/Ps2.h"
+
+extern const mp_obj_type_t ps2io_ps2_type;
+
+extern void common_hal_ps2io_ps2_construct(ps2io_ps2_obj_t* self,
+ const mcu_pin_obj_t* data_pin, const mcu_pin_obj_t* clk_pin);
+extern void common_hal_ps2io_ps2_deinit(ps2io_ps2_obj_t* self);
+extern bool common_hal_ps2io_ps2_deinited(ps2io_ps2_obj_t* self);
+extern uint16_t common_hal_ps2io_ps2_get_len(ps2io_ps2_obj_t* self);
+extern int16_t common_hal_ps2io_ps2_popleft(ps2io_ps2_obj_t* self);
+extern int16_t common_hal_ps2io_ps2_sendcmd(ps2io_ps2_obj_t* self, uint8_t b);
+extern uint16_t common_hal_ps2io_ps2_clear_errors(ps2io_ps2_obj_t* self);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO_PS2_H
diff --git a/shared-bindings/ps2io/__init__.c b/shared-bindings/ps2io/__init__.c
new file mode 100644
index 000000000..ec7c43e51
--- /dev/null
+++ b/shared-bindings/ps2io/__init__.c
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Elvis Pfutzenreuter <epxx@epxx.co>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdint.h>
+
+#include "py/obj.h"
+#include "py/runtime.h"
+
+#include "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/ps2io/Ps2.h"
+
+//| :mod:`ps2io` --- Support for PS/2 protocol
+//| =====================================================
+//|
+//| .. module:: ps2io
+//| :synopsis: Support for PS/2 based devices
+//| :platform: SAMD21
+//|
+//| The `ps2io` module contains classes to provide PS/2 communication.
+//|
+//| Libraries
+//|
+//| .. toctree::
+//| :maxdepth: 3
+//|
+//| Ps2
+//|
+
+//| .. warning:: This module is not available in some SAMD21 builds. See the
+//| :ref:`module-support-matrix` for more info.
+//|
+
+//| All classes change hardware state and should be deinitialized when they
+//| are no longer needed if the program continues after use. To do so, either
+//| call :py:meth:`!deinit` or use a context manager. See
+//| :ref:`lifetime-and-contextmanagers` for more info.
+//|
+
+STATIC const mp_rom_map_elem_t ps2io_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ps2io) },
+ { MP_ROM_QSTR(MP_QSTR_Ps2), MP_ROM_PTR(&ps2io_ps2_type) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(ps2io_module_globals, ps2io_module_globals_table);
+
+const mp_obj_module_t ps2io_module = {
+ .base = { &mp_type_module },
+ .globals = (mp_obj_dict_t*)&ps2io_module_globals,
+};
diff --git a/shared-bindings/ps2io/__init__.h b/shared-bindings/ps2io/__init__.h
new file mode 100644
index 000000000..1ff3d97b5
--- /dev/null
+++ b/shared-bindings/ps2io/__init__.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Scott Shawcroft
+ * Copyright (c) 2019 Elvis Pfutzenreuter <epxx@epxx.co>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO___INIT___H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO___INIT___H
+
+#include "py/obj.h"
+
+// Nothing now.
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO___INIT___H
diff --git a/shared-bindings/pulseio/PWMOut.c b/shared-bindings/pulseio/PWMOut.c
index 37939a07a..40981e0a8 100644
--- a/shared-bindings/pulseio/PWMOut.c
+++ b/shared-bindings/pulseio/PWMOut.c
@@ -42,7 +42,7 @@
//|
//| PWMOut can be used to output a PWM signal on a given pin.
//|
-//| .. class:: PWMOut(pin, \*, duty_cycle=0, frequency=500, variable_frequency=False)
+//| .. class:: PWMOut(pin, *, duty_cycle=0, frequency=500, variable_frequency=False)
//|
//| Create a PWM object associated with the given pin. This allows you to
//| write PWM signals out on the given pin. Frequency is fixed after init
@@ -133,6 +133,12 @@ STATIC mp_obj_t pulseio_pwmout_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_deinit_obj, pulseio_pwmout_deinit);
+STATIC void check_for_deinit(pulseio_pwmout_obj_t *self) {
+ if (common_hal_pulseio_pwmout_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -158,14 +164,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pwmout___exit___obj, 4, 4, pu
//| be half high and then half low.
STATIC mp_obj_t pulseio_pwmout_obj_get_duty_cycle(mp_obj_t self_in) {
pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pwmout_get_duty_cycle(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_get_duty_cycle_obj, pulseio_pwmout_obj_get_duty_cycle);
STATIC mp_obj_t pulseio_pwmout_obj_set_duty_cycle(mp_obj_t self_in, mp_obj_t duty_cycle) {
pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self));
+ check_for_deinit(self);
mp_int_t duty = mp_obj_get_int(duty_cycle);
if (duty < 0 || duty > 0xffff) {
mp_raise_ValueError(translate("PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"));
@@ -189,14 +195,14 @@ const mp_obj_property_t pulseio_pwmout_duty_cycle_obj = {
//|
STATIC mp_obj_t pulseio_pwmout_obj_get_frequency(mp_obj_t self_in) {
pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pwmout_get_frequency(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_get_frequency_obj, pulseio_pwmout_obj_get_frequency);
STATIC mp_obj_t pulseio_pwmout_obj_set_frequency(mp_obj_t self_in, mp_obj_t frequency) {
pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self));
+ check_for_deinit(self);
if (!common_hal_pulseio_pwmout_get_variable_frequency(self)) {
mp_raise_AttributeError(translate(
"PWM frequency not writable when variable_frequency is False on "
diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c
index 426ac4384..8b69109f0 100644
--- a/shared-bindings/pulseio/PulseIn.c
+++ b/shared-bindings/pulseio/PulseIn.c
@@ -45,7 +45,7 @@
//| The pulsed signal consists of timed active and idle periods. Unlike PWM,
//| there is no set duration for active and idle pairs.
//|
-//| .. class:: PulseIn(pin, maxlen=2, \*, idle_state=False)
+//| .. class:: PulseIn(pin, maxlen=2, *, idle_state=False)
//|
//| Create a PulseIn object associated with the given pin. The object acts as
//| a read-only sequence of pulse lengths with a given max length. When it is
@@ -114,6 +114,12 @@ STATIC mp_obj_t pulseio_pulsein_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_deinit_obj, pulseio_pulsein_deinit);
+STATIC void check_for_deinit(pulseio_pulsein_obj_t *self) {
+ if (common_hal_pulseio_pulsein_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -138,7 +144,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pulsein___exit___obj, 4, 4, p
//|
STATIC mp_obj_t pulseio_pulsein_obj_pause(mp_obj_t self_in) {
pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+ check_for_deinit(self);
common_hal_pulseio_pulsein_pause(self);
return mp_const_none;
@@ -162,7 +168,7 @@ STATIC mp_obj_t pulseio_pulsein_obj_resume(size_t n_args, const mp_obj_t *pos_ar
{ MP_QSTR_trigger_duration, MP_ARG_INT, {.u_int = 0} },
};
pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+ check_for_deinit(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -178,7 +184,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(pulseio_pulsein_resume_obj, 1, pulseio_pulsein_obj_re
//|
STATIC mp_obj_t pulseio_pulsein_obj_clear(mp_obj_t self_in) {
pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+ check_for_deinit(self);
common_hal_pulseio_pulsein_clear(self);
return mp_const_none;
@@ -191,7 +197,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_clear_obj, pulseio_pulsein_obj_clear);
//|
STATIC mp_obj_t pulseio_pulsein_obj_popleft(mp_obj_t self_in) {
pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pulsein_popleft(self));
}
@@ -204,7 +210,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_popleft_obj, pulseio_pulsein_obj_pople
//|
STATIC mp_obj_t pulseio_pulsein_obj_get_maxlen(mp_obj_t self_in) {
pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pulsein_get_maxlen(self));
}
@@ -224,7 +230,7 @@ const mp_obj_property_t pulseio_pulsein_maxlen_obj = {
//|
STATIC mp_obj_t pulseio_pulsein_obj_get_paused(mp_obj_t self_in) {
pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_pulseio_pulsein_get_paused(self));
}
@@ -248,7 +254,7 @@ const mp_obj_property_t pulseio_pulsein_paused_obj = {
//|
STATIC mp_obj_t pulsein_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+ check_for_deinit(self);
uint16_t len = common_hal_pulseio_pulsein_get_len(self);
switch (op) {
case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0);
@@ -272,7 +278,7 @@ STATIC mp_obj_t pulsein_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t va
mp_raise_AttributeError(translate("Cannot delete values"));
} else {
pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+ check_for_deinit(self);
if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) {
mp_raise_NotImplementedError(translate("Slices not supported"));
diff --git a/shared-bindings/pulseio/PulseOut.c b/shared-bindings/pulseio/PulseOut.c
index 493b7e2ff..172459e5d 100644
--- a/shared-bindings/pulseio/PulseOut.c
+++ b/shared-bindings/pulseio/PulseOut.c
@@ -127,7 +127,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pulseout___exit___obj, 4, 4,
//|
STATIC mp_obj_t pulseio_pulseout_obj_send(mp_obj_t self_in, mp_obj_t pulses) {
pulseio_pulseout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pulseout_deinited(self));
+ if (common_hal_pulseio_pulseout_deinited(self)) {
+ raise_deinited_error();
+ }
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(pulses, &bufinfo, MP_BUFFER_READ);
diff --git a/shared-bindings/pulseio/__init__.c b/shared-bindings/pulseio/__init__.c
index 1114b604b..a3cec3dca 100644
--- a/shared-bindings/pulseio/__init__.c
+++ b/shared-bindings/pulseio/__init__.c
@@ -54,10 +54,6 @@
//| PWMOut
//|
-//| .. warning:: This module is not available in some SAMD21 builds. See the
-//| :ref:`module-support-matrix` for more info.
-//|
-
//| All classes change hardware state and should be deinitialized when they
//| are no longer needed if the program continues after use. To do so, either
//| call :py:meth:`!deinit` or use a context manager. See
diff --git a/shared-bindings/rotaryio/IncrementalEncoder.c b/shared-bindings/rotaryio/IncrementalEncoder.c
index 5d2264ffc..f2f157847 100644
--- a/shared-bindings/rotaryio/IncrementalEncoder.c
+++ b/shared-bindings/rotaryio/IncrementalEncoder.c
@@ -100,6 +100,12 @@ STATIC mp_obj_t rotaryio_incrementalencoder_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(rotaryio_incrementalencoder_deinit_obj, rotaryio_incrementalencoder_deinit);
+STATIC void check_for_deinit(rotaryio_incrementalencoder_obj_t *self) {
+ if (common_hal_rotaryio_incrementalencoder_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -126,7 +132,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(rotaryio_incrementalencoder___exit___
//|
STATIC mp_obj_t rotaryio_incrementalencoder_obj_get_position(mp_obj_t self_in) {
rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_rotaryio_incrementalencoder_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_int(common_hal_rotaryio_incrementalencoder_get_position(self));
}
@@ -134,7 +140,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(rotaryio_incrementalencoder_get_position_obj, rotaryio
STATIC mp_obj_t rotaryio_incrementalencoder_obj_set_position(mp_obj_t self_in, mp_obj_t new_position) {
rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_rotaryio_incrementalencoder_deinited(self));
+ check_for_deinit(self);
common_hal_rotaryio_incrementalencoder_set_position(self, mp_obj_get_int(new_position));
return mp_const_none;
diff --git a/shared-bindings/socket/__init__.c b/shared-bindings/socket/__init__.c
index 8e34c3700..6d04a9893 100644
--- a/shared-bindings/socket/__init__.c
+++ b/shared-bindings/socket/__init__.c
@@ -51,7 +51,7 @@ STATIC const mp_obj_type_t socket_type;
//| .. currentmodule:: socket
//|
-//| .. class:: socket(family, type, proto, ...)
+//| .. class:: socket(family, type, proto)
//|
//| Create a new socket
//|
@@ -257,7 +257,7 @@ STATIC mp_int_t _socket_recv_into(mod_network_socket_obj_t *sock, byte *buf, mp_
//| Reads some bytes from the connected remote address, writing
//| into the provided buffer. If bufsize <= len(buffer) is given,
//| a maximum of bufsize bytes will be read into the buffer. If no
-//| valid value is given for bufsize, the default is the length of
+//| valid value is given for bufsize, the default is the length of
//| the given buffer.
//|
//| Suits sockets of type SOCK_STREAM
@@ -274,13 +274,14 @@ STATIC mp_obj_t socket_recv_into(size_t n_args, const mp_obj_t *args) {
}
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
- mp_int_t len;
+ mp_int_t len = bufinfo.len;
if (n_args == 3) {
- len = mp_obj_get_int(args[2]);
- }
- if (n_args == 2 || (size_t) len > bufinfo.len) {
- len = bufinfo.len;
+ mp_int_t given_len = mp_obj_get_int(args[2]);
+ if (given_len < len) {
+ len = given_len;
+ }
}
+
mp_int_t ret = _socket_recv_into(self, (byte*)bufinfo.buf, len);
return mp_obj_new_int_from_uint(ret);
}
diff --git a/shared-bindings/storage/__init__.c b/shared-bindings/storage/__init__.c
index 4db3a9fec..ba439b951 100644
--- a/shared-bindings/storage/__init__.c
+++ b/shared-bindings/storage/__init__.c
@@ -48,7 +48,7 @@
//| directly.
//|
-//| .. function:: mount(filesystem, mount_path, \*, readonly=False)
+//| .. function:: mount(filesystem, mount_path, *, readonly=False)
//|
//| Mounts the given filesystem object at the given path.
//|
@@ -183,7 +183,7 @@ STATIC const mp_rom_map_elem_t storage_module_globals_table[] = {
//| this property can only be set when the device is writable by the
//| microcontroller.
//|
- //| .. method:: mkfs
+ //| .. method:: mkfs()
//|
//| Format the block device, deleting any data that may have been there
//|
@@ -216,7 +216,7 @@ STATIC const mp_rom_map_elem_t storage_module_globals_table[] = {
//|
//| Don't call this directly, call `storage.mount`.
//|
- //| .. method:: umount
+ //| .. method:: umount()
//|
//| Don't call this directly, call `storage.umount`.
//|
diff --git a/shared-bindings/struct/__init__.c b/shared-bindings/struct/__init__.c
index 9240a15bb..ea14b3763 100644
--- a/shared-bindings/struct/__init__.c
+++ b/shared-bindings/struct/__init__.c
@@ -67,9 +67,9 @@ STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(struct_calcsize_obj, struct_calcsize);
-//| .. function:: pack(fmt, v1, v2, ...)
+//| .. function:: pack(fmt, *values)
//|
-//| Pack the values v1, v2, ... according to the format string fmt.
+//| Pack the values according to the format string fmt.
//| The return value is a bytes object encoding the values.
//|
@@ -85,9 +85,9 @@ STATIC mp_obj_t struct_pack(size_t n_args, const mp_obj_t *args) {
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_obj, 1, MP_OBJ_FUN_ARGS_MAX, struct_pack);
-//| .. function:: pack_into(fmt, buffer, offset, v1, v2, ...)
+//| .. function:: pack_into(fmt, buffer, offset, *values)
//|
-//| Pack the values v1, v2, ... according to the format string fmt into a buffer
+//| Pack the values according to the format string fmt into a buffer
//| starting at offset. offset may be negative to count from the end of buffer.
//|
diff --git a/shared-bindings/support_matrix.rst b/shared-bindings/support_matrix.rst
new file mode 100644
index 000000000..124f3a810
--- /dev/null
+++ b/shared-bindings/support_matrix.rst
@@ -0,0 +1,16 @@
+.. _module-support-matrix:
+
+Support Matrix
+===============
+
+The following table lists the available built-in modules for each CircuitPython
+capable board.
+
+.. csv-table::
+ :header-rows: 1
+ :widths: 7, 50
+
+ "Board", "Modules Available"
+ {% for key, value in support_matrix|dictsort -%}
+ "{{ key }}", "{{ '`' ~ value|join("`, `") ~ '`' }}"
+ {% endfor -%}
diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c
index 3babe2db4..70c01c2d8 100644
--- a/shared-bindings/time/__init__.c
+++ b/shared-bindings/time/__init__.c
@@ -47,7 +47,7 @@
//| written in MicroPython will work in CPython but not necessarily the other
//| way around.
//|
-//| .. method:: monotonic()
+//| .. function:: monotonic()
//|
//| Returns an always increasing value of time with an unknown reference
//| point. Only use it to compare against other values from `monotonic`.
@@ -62,7 +62,7 @@ STATIC mp_obj_t time_monotonic(void) {
}
MP_DEFINE_CONST_FUN_OBJ_0(time_monotonic_obj, time_monotonic);
-//| .. method:: sleep(seconds)
+//| .. function:: sleep(seconds)
//|
//| Sleep for a given number of seconds.
//|
@@ -95,19 +95,20 @@ mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, const mp
return namedtuple_make_new(type, 9, tuple->items, NULL);
}
-//| .. class:: struct_time((tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst))
+//| .. class:: struct_time(time_tuple)
//|
//| Structure used to capture a date and time. Note that it takes a tuple!
//|
-//| :param int tm_year: the year, 2017 for example
-//| :param int tm_mon: the month, range [1, 12]
-//| :param int tm_mday: the day of the month, range [1, 31]
-//| :param int tm_hour: the hour, range [0, 23]
-//| :param int tm_min: the minute, range [0, 59]
-//| :param int tm_sec: the second, range [0, 61]
-//| :param int tm_wday: the day of the week, range [0, 6], Monday is 0
-//| :param int tm_yday: the day of the year, range [1, 366], -1 indicates not known
-//| :param int tm_isdst: 1 when in daylight savings, 0 when not, -1 if unknown.
+//| :param Tuple[tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst] time_tuple: Tuple of time info.
+//| * the year, 2017 for example
+//| * the month, range [1, 12]
+//| * the day of the month, range [1, 31]
+//| * the hour, range [0, 23]
+//| * the minute, range [0, 59]
+//| * the second, range [0, 61]
+//| * the day of the week, range [0, 6], Monday is 0
+//| * the day of the year, range [1, 366], -1 indicates not known
+//| * 1 when in daylight savings, 0 when not, -1 if unknown.
//|
const mp_obj_namedtuple_type_t struct_time_type_obj = {
.base = {
@@ -190,7 +191,7 @@ mp_obj_t MP_WEAK rtc_get_time_source_time(void) {
mp_raise_RuntimeError(translate("RTC is not supported on this board"));
}
-//| .. method:: time()
+//| .. function:: time()
//|
//| Return the current time in seconds since since Jan 1, 1970.
//|
@@ -206,7 +207,7 @@ STATIC mp_obj_t time_time(void) {
}
MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
-//| .. method:: monotonic_ns()
+//| .. function:: monotonic_ns()
//|
//| Return the time of the specified clock clk_id in nanoseconds.
//|
@@ -219,7 +220,7 @@ STATIC mp_obj_t time_monotonic_ns(void) {
}
MP_DEFINE_CONST_FUN_OBJ_0(time_monotonic_ns_obj, time_monotonic_ns);
-//| .. method:: localtime([secs])
+//| .. function:: localtime([secs])
//|
//| Convert a time expressed in seconds since Jan 1, 1970 to a struct_time in
//| local time. If secs is not provided or None, the current time as returned
@@ -245,7 +246,7 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) {
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_localtime_obj, 0, 1, time_localtime);
-//| .. method:: mktime(t)
+//| .. function:: mktime(t)
//|
//| This is the inverse function of localtime(). Its argument is the
//| struct_time or full 9-tuple (since the dst flag is needed; use -1 as the
diff --git a/shared-bindings/touchio/TouchIn.c b/shared-bindings/touchio/TouchIn.c
index 3b26aca8c..78fceef41 100644
--- a/shared-bindings/touchio/TouchIn.c
+++ b/shared-bindings/touchio/TouchIn.c
@@ -88,6 +88,12 @@ STATIC mp_obj_t touchio_touchin_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_deinit_obj, touchio_touchin_deinit);
+STATIC void check_for_deinit(touchio_touchin_obj_t *self) {
+ if (common_hal_touchio_touchin_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -114,7 +120,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(touchio_touchin___exit___obj, 4, 4, t
//|
STATIC mp_obj_t touchio_touchin_obj_get_value(mp_obj_t self_in) {
touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_touchio_touchin_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_touchio_touchin_get_value(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_get_value_obj, touchio_touchin_obj_get_value);
@@ -133,7 +139,7 @@ const mp_obj_property_t touchio_touchin_value_obj = {
//|
STATIC mp_obj_t touchio_touchin_obj_get_raw_value(mp_obj_t self_in) {
touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_touchio_touchin_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_touchio_touchin_get_raw_value(self));
}
@@ -158,7 +164,7 @@ const mp_obj_property_t touchio_touchin_raw_value_obj = {
//|
STATIC mp_obj_t touchio_touchin_obj_get_threshold(mp_obj_t self_in) {
touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_touchio_touchin_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_touchio_touchin_get_threshold(self));
}
@@ -166,7 +172,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_get_threshold_obj, touchio_touchin_obj
STATIC mp_obj_t touchio_touchin_obj_set_threshold(mp_obj_t self_in, mp_obj_t threshold_obj) {
touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_touchio_touchin_deinited(self));
+ check_for_deinit(self);
uint32_t new_threshold = mp_obj_get_int(threshold_obj);
if (new_threshold < 0 || new_threshold > UINT16_MAX) {
// I would use MP_STRINGIFY(UINT16_MAX), but that prints "0xffff" instead of 65536.
diff --git a/shared-bindings/uheap/__init__.c b/shared-bindings/uheap/__init__.c
index df18237ac..0d699cd28 100644
--- a/shared-bindings/uheap/__init__.c
+++ b/shared-bindings/uheap/__init__.c
@@ -38,7 +38,7 @@
//| :synopsis: Heap size analysis
//|
-//| .. method:: info(object)
+//| .. function:: info(object)
//|
//| Prints memory debugging info for the given object and returns the
//| estimated size.
diff --git a/shared-bindings/ustack/__init__.c b/shared-bindings/ustack/__init__.c
index c4391c132..08b772e41 100644
--- a/shared-bindings/ustack/__init__.c
+++ b/shared-bindings/ustack/__init__.c
@@ -39,7 +39,7 @@
//|
#if MICROPY_MAX_STACK_USAGE
-//| .. method:: max_stack_usage()
+//| .. function:: max_stack_usage()
//|
//| Return the maximum excursion of the stack so far.
//|
@@ -50,7 +50,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(max_stack_usage_obj, max_stack_usage);
#endif // MICROPY_MAX_STACK_USAGE
-//| .. method:: stack_size()
+//| .. function:: stack_size()
//|
//| Return the size of the entire stack.
//| Same as in micropython.mem_info(), but returns a value instead
@@ -61,7 +61,7 @@ STATIC mp_obj_t stack_size(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(stack_size_obj, stack_size);
-//| .. method:: stack_usage()
+//| .. function:: stack_usage()
//|
//| Return how much stack is currently in use.
//| Same as micropython.stack_use(); duplicated here for convenience.
diff --git a/shared-bindings/util.c b/shared-bindings/util.c
index 80a0bdaeb..c1ca01e0a 100644
--- a/shared-bindings/util.c
+++ b/shared-bindings/util.c
@@ -32,11 +32,9 @@
#include "shared-bindings/util.h"
#include "supervisor/shared/translate.h"
-// Check if pin is None. If so, deinit() has already been called on the object, so complain.
-void raise_error_if_deinited(bool deinited) {
- if (deinited) {
- mp_raise_ValueError(translate("Object has been deinitialized and can no longer be used. Create a new object."));
- }
+// If so, deinit() has already been called on the object, so complain.
+void raise_deinited_error(void) {
+ mp_raise_ValueError(translate("Object has been deinitialized and can no longer be used. Create a new object."));
}
diff --git a/shared-bindings/util.h b/shared-bindings/util.h
index b26ed7e93..33454f10e 100644
--- a/shared-bindings/util.h
+++ b/shared-bindings/util.h
@@ -27,7 +27,7 @@
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_UTIL_H
#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_UTIL_H
-void raise_error_if_deinited(bool deinited);
+void raise_deinited_error(void);
#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_UTIL_H
diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c
index 878095b2a..ac89cc691 100644
--- a/shared-bindings/wiznet/wiznet5k.c
+++ b/shared-bindings/wiznet/wiznet5k.c
@@ -138,7 +138,7 @@ const mp_obj_property_t wiznet5k_dhcp_obj = {
(mp_obj_t)&mp_const_none_obj},
};
-//| .. method:: ifconfig(...)
+//| .. method:: ifconfig(params=None)
//|
//| Called without parameters, returns a tuple of
//| (ip_address, subnet_mask, gateway_address, dns_server)
diff --git a/shared-module/_stage/__init__.c b/shared-module/_stage/__init__.c
index 1af279e92..ca71b758e 100644
--- a/shared-module/_stage/__init__.c
+++ b/shared-module/_stage/__init__.c
@@ -34,30 +34,35 @@
void render_stage(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,
mp_obj_t *layers, size_t layers_size,
uint16_t *buffer, size_t buffer_size,
- displayio_display_obj_t *display) {
+ displayio_display_obj_t *display, uint8_t scale) {
size_t index = 0;
for (uint16_t y = y0; y < y1; ++y) {
- for (uint16_t x = x0; x < x1; ++x) {
- for (size_t layer = 0; layer < layers_size; ++layer) {
+ for (uint8_t yscale = 0; yscale < scale; ++yscale) {
+ for (uint16_t x = x0; x < x1; ++x) {
uint16_t c = TRANSPARENT;
- layer_obj_t *obj = MP_OBJ_TO_PTR(layers[layer]);
- if (obj->base.type == &mp_type_layer) {
- c = get_layer_pixel(obj, x, y);
- } else if (obj->base.type == &mp_type_text) {
- c = get_text_pixel((text_obj_t *)obj, x, y);
+ for (size_t layer = 0; layer < layers_size; ++layer) {
+ layer_obj_t *obj = MP_OBJ_TO_PTR(layers[layer]);
+ if (obj->base.type == &mp_type_layer) {
+ c = get_layer_pixel(obj, x, y);
+ } else if (obj->base.type == &mp_type_text) {
+ c = get_text_pixel((text_obj_t *)obj, x, y);
+ }
+ if (c != TRANSPARENT) {
+ break;
+ }
}
- if (c != TRANSPARENT) {
+ for (uint8_t xscale = 0; xscale < scale; ++xscale) {
buffer[index] = c;
- break;
+ index += 1;
+ // The buffer is full, send it.
+ if (index >= buffer_size) {
+ display->send(display->bus, false, ((uint8_t*)buffer),
+ buffer_size * 2);
+ index = 0;
+ }
}
}
- index += 1;
- // The buffer is full, send it.
- if (index >= buffer_size) {
- display->send(display->bus, false, ((uint8_t*)buffer), buffer_size * 2);
- index = 0;
- }
}
}
// Send the remaining data.
diff --git a/shared-module/_stage/__init__.h b/shared-module/_stage/__init__.h
index d263302b4..5af2124ae 100644
--- a/shared-module/_stage/__init__.h
+++ b/shared-module/_stage/__init__.h
@@ -37,6 +37,6 @@
void render_stage(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,
mp_obj_t *layers, size_t layers_size,
uint16_t *buffer, size_t buffer_size,
- displayio_display_obj_t *display);
+ displayio_display_obj_t *display, uint8_t scale);
#endif // MICROPY_INCLUDED_SHARED_MODULE__STAGE
diff --git a/shared-module/audioio/Mixer.c b/shared-module/audiocore/Mixer.c
index 8020a621e..da66bb36e 100644
--- a/shared-module/audioio/Mixer.c
+++ b/shared-module/audiocore/Mixer.c
@@ -24,13 +24,13 @@
* THE SOFTWARE.
*/
-#include "shared-bindings/audioio/Mixer.h"
+#include "shared-bindings/audiocore/Mixer.h"
#include <stdint.h>
#include "py/runtime.h"
-#include "shared-module/audioio/__init__.h"
-#include "shared-module/audioio/RawSample.h"
+#include "shared-module/audiocore/__init__.h"
+#include "shared-module/audiocore/RawSample.h"
void common_hal_audioio_mixer_construct(audioio_mixer_obj_t* self,
uint8_t voice_count,
diff --git a/shared-module/audioio/Mixer.h b/shared-module/audiocore/Mixer.h
index 6a88fe0bd..22eb6a37f 100644
--- a/shared-module/audioio/Mixer.h
+++ b/shared-module/audiocore/Mixer.h
@@ -29,7 +29,7 @@
#include "py/obj.h"
-#include "shared-module/audioio/__init__.h"
+#include "shared-module/audiocore/__init__.h"
typedef struct {
mp_obj_t sample;
diff --git a/shared-module/audioio/RawSample.c b/shared-module/audiocore/RawSample.c
index 6422e346b..d6bf3a567 100644
--- a/shared-module/audioio/RawSample.c
+++ b/shared-module/audiocore/RawSample.c
@@ -24,11 +24,11 @@
* THE SOFTWARE.
*/
-#include "shared-bindings/audioio/RawSample.h"
+#include "shared-bindings/audiocore/RawSample.h"
#include <stdint.h>
-#include "shared-module/audioio/RawSample.h"
+#include "shared-module/audiocore/RawSample.h"
void common_hal_audioio_rawsample_construct(audioio_rawsample_obj_t* self,
uint8_t* buffer,
diff --git a/shared-module/audioio/RawSample.h b/shared-module/audiocore/RawSample.h
index fe5283db4..6c2c19c9b 100644
--- a/shared-module/audioio/RawSample.h
+++ b/shared-module/audiocore/RawSample.h
@@ -29,7 +29,7 @@
#include "py/obj.h"
-#include "shared-module/audioio/__init__.h"
+#include "shared-module/audiocore/__init__.h"
typedef struct {
mp_obj_base_t base;
diff --git a/shared-module/audioio/WaveFile.c b/shared-module/audiocore/WaveFile.c
index d5dd9419c..810d9c33b 100644
--- a/shared-module/audioio/WaveFile.c
+++ b/shared-module/audiocore/WaveFile.c
@@ -24,7 +24,7 @@
* THE SOFTWARE.
*/
-#include "shared-bindings/audioio/WaveFile.h"
+#include "shared-bindings/audiocore/WaveFile.h"
#include <stdint.h>
#include <string.h>
@@ -32,7 +32,7 @@
#include "py/mperrno.h"
#include "py/runtime.h"
-#include "shared-module/audioio/WaveFile.h"
+#include "shared-module/audiocore/WaveFile.h"
#include "supervisor/shared/translate.h"
struct wave_format_chunk {
diff --git a/shared-module/audioio/WaveFile.h b/shared-module/audiocore/WaveFile.h
index 75a46c03b..3eecbf15c 100644
--- a/shared-module/audioio/WaveFile.h
+++ b/shared-module/audiocore/WaveFile.h
@@ -27,9 +27,10 @@
#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_WAVEFILE_H
#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_WAVEFILE_H
+#include "extmod/vfs_fat.h"
#include "py/obj.h"
-#include "shared-module/audioio/__init__.h"
+#include "shared-module/audiocore/__init__.h"
typedef struct {
mp_obj_base_t base;
@@ -44,7 +45,7 @@ typedef struct {
uint32_t bytes_remaining;
uint8_t channel_count;
- uint16_t sample_rate;
+ uint32_t sample_rate;
uint32_t len;
pyb_file_obj_t* file;
diff --git a/shared-module/audiocore/__init__.c b/shared-module/audiocore/__init__.c
new file mode 100644
index 000000000..067cae5dd
--- /dev/null
+++ b/shared-module/audiocore/__init__.c
@@ -0,0 +1,125 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "shared-module/audioio/__init__.h"
+
+#include "py/obj.h"
+#include "shared-bindings/audiocore/Mixer.h"
+#include "shared-bindings/audiocore/RawSample.h"
+#include "shared-bindings/audiocore/WaveFile.h"
+#include "shared-module/audiocore/Mixer.h"
+#include "shared-module/audiocore/RawSample.h"
+#include "shared-module/audiocore/WaveFile.h"
+
+uint32_t audiosample_sample_rate(mp_obj_t sample_obj) {
+ if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
+ audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
+ return sample->sample_rate;
+ } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
+ audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
+ return file->sample_rate;
+ } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) {
+ audioio_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj);
+ return mixer->sample_rate;
+ }
+ return 16000;
+}
+
+uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj) {
+ if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
+ audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
+ return sample->bits_per_sample;
+ } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
+ audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
+ return file->bits_per_sample;
+ } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) {
+ audioio_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj);
+ return mixer->bits_per_sample;
+ }
+ return 8;
+}
+
+uint8_t audiosample_channel_count(mp_obj_t sample_obj) {
+ if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
+ audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
+ return sample->channel_count;
+ } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
+ audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
+ return file->channel_count;
+ } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) {
+ audioio_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj);
+ return mixer->channel_count;
+ }
+ return 1;
+}
+
+void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t audio_channel) {
+ if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
+ audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
+ audioio_rawsample_reset_buffer(sample, single_channel, audio_channel);
+ } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
+ audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
+ audioio_wavefile_reset_buffer(file, single_channel, audio_channel);
+ } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) {
+ audioio_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
+ audioio_mixer_reset_buffer(file, single_channel, audio_channel);
+ }
+}
+
+audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj,
+ bool single_channel,
+ uint8_t channel,
+ uint8_t** buffer, uint32_t* buffer_length) {
+ if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
+ audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
+ return audioio_rawsample_get_buffer(sample, single_channel, channel, buffer, buffer_length);
+ } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
+ audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
+ return audioio_wavefile_get_buffer(file, single_channel, channel, buffer, buffer_length);
+ } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) {
+ audioio_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
+ return audioio_mixer_get_buffer(file, single_channel, channel, buffer, buffer_length);
+ }
+ return GET_BUFFER_DONE;
+}
+
+void audiosample_get_buffer_structure(mp_obj_t sample_obj, bool single_channel,
+ bool* single_buffer, bool* samples_signed,
+ uint32_t* max_buffer_length, uint8_t* spacing) {
+ if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
+ audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
+ audioio_rawsample_get_buffer_structure(sample, single_channel, single_buffer,
+ samples_signed, max_buffer_length, spacing);
+ } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
+ audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
+ audioio_wavefile_get_buffer_structure(file, single_channel, single_buffer, samples_signed,
+ max_buffer_length, spacing);
+ } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) {
+ audioio_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
+ audioio_mixer_get_buffer_structure(file, single_channel, single_buffer, samples_signed,
+ max_buffer_length, spacing);
+ }
+}
diff --git a/shared-module/audiocore/__init__.h b/shared-module/audiocore/__init__.h
new file mode 100644
index 000000000..7aa0c1824
--- /dev/null
+++ b/shared-module/audiocore/__init__.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOCORE__INIT__H
+#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOCORE__INIT__H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "py/obj.h"
+
+typedef enum {
+ GET_BUFFER_DONE, // No more data to read
+ GET_BUFFER_MORE_DATA, // More data to read.
+ GET_BUFFER_ERROR, // Error while reading data.
+} audioio_get_buffer_result_t;
+
+uint32_t audiosample_sample_rate(mp_obj_t sample_obj);
+uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj);
+uint8_t audiosample_channel_count(mp_obj_t sample_obj);
+void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t audio_channel);
+audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj,
+ bool single_channel,
+ uint8_t channel,
+ uint8_t** buffer, uint32_t* buffer_length);
+void audiosample_get_buffer_structure(mp_obj_t sample_obj, bool single_channel,
+ bool* single_buffer, bool* samples_signed,
+ uint32_t* max_buffer_length, uint8_t* spacing);
+
+#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOCORE__INIT__H
diff --git a/shared-module/audioio/__init__.c b/shared-module/audioio/__init__.c
index b87b06a83..e69de29bb 100644
--- a/shared-module/audioio/__init__.c
+++ b/shared-module/audioio/__init__.c
@@ -1,125 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "shared-module/audioio/__init__.h"
-
-#include "py/obj.h"
-#include "shared-bindings/audioio/Mixer.h"
-#include "shared-bindings/audioio/RawSample.h"
-#include "shared-bindings/audioio/WaveFile.h"
-#include "shared-module/audioio/Mixer.h"
-#include "shared-module/audioio/RawSample.h"
-#include "shared-module/audioio/WaveFile.h"
-
-uint32_t audiosample_sample_rate(mp_obj_t sample_obj) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- return sample->sample_rate;
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- return file->sample_rate;
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) {
- audioio_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj);
- return mixer->sample_rate;
- }
- return 16000;
-}
-
-uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- return sample->bits_per_sample;
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- return file->bits_per_sample;
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) {
- audioio_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj);
- return mixer->bits_per_sample;
- }
- return 8;
-}
-
-uint8_t audiosample_channel_count(mp_obj_t sample_obj) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- return sample->channel_count;
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- return file->channel_count;
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) {
- audioio_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj);
- return mixer->channel_count;
- }
- return 1;
-}
-
-void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t audio_channel) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- audioio_rawsample_reset_buffer(sample, single_channel, audio_channel);
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- audioio_wavefile_reset_buffer(file, single_channel, audio_channel);
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) {
- audioio_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- audioio_mixer_reset_buffer(file, single_channel, audio_channel);
- }
-}
-
-audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj,
- bool single_channel,
- uint8_t channel,
- uint8_t** buffer, uint32_t* buffer_length) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- return audioio_rawsample_get_buffer(sample, single_channel, channel, buffer, buffer_length);
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- return audioio_wavefile_get_buffer(file, single_channel, channel, buffer, buffer_length);
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) {
- audioio_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- return audioio_mixer_get_buffer(file, single_channel, channel, buffer, buffer_length);
- }
- return GET_BUFFER_DONE;
-}
-
-void audiosample_get_buffer_structure(mp_obj_t sample_obj, bool single_channel,
- bool* single_buffer, bool* samples_signed,
- uint32_t* max_buffer_length, uint8_t* spacing) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- audioio_rawsample_get_buffer_structure(sample, single_channel, single_buffer,
- samples_signed, max_buffer_length, spacing);
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- audioio_wavefile_get_buffer_structure(file, single_channel, single_buffer, samples_signed,
- max_buffer_length, spacing);
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) {
- audioio_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- audioio_mixer_get_buffer_structure(file, single_channel, single_buffer, samples_signed,
- max_buffer_length, spacing);
- }
-}
diff --git a/shared-module/audioio/__init__.h b/shared-module/audioio/__init__.h
index c805f3116..53b2d4a16 100644
--- a/shared-module/audioio/__init__.h
+++ b/shared-module/audioio/__init__.h
@@ -27,27 +27,6 @@
#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO__INIT__H
#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO__INIT__H
-#include <stdbool.h>
-#include <stdint.h>
-
-#include "py/obj.h"
-
-typedef enum {
- GET_BUFFER_DONE, // No more data to read
- GET_BUFFER_MORE_DATA, // More data to read.
- GET_BUFFER_ERROR, // Error while reading data.
-} audioio_get_buffer_result_t;
-
-uint32_t audiosample_sample_rate(mp_obj_t sample_obj);
-uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj);
-uint8_t audiosample_channel_count(mp_obj_t sample_obj);
-void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t audio_channel);
-audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj,
- bool single_channel,
- uint8_t channel,
- uint8_t** buffer, uint32_t* buffer_length);
-void audiosample_get_buffer_structure(mp_obj_t sample_obj, bool single_channel,
- bool* single_buffer, bool* samples_signed,
- uint32_t* max_buffer_length, uint8_t* spacing);
+#include "shared-module/audiocore/__init__.h"
#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO__INIT__H
diff --git a/shared-module/audiopwmio/__init__.c b/shared-module/audiopwmio/__init__.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/shared-module/audiopwmio/__init__.c
diff --git a/shared-module/audiopwmio/__init__.h b/shared-module/audiopwmio/__init__.h
new file mode 100644
index 000000000..964e4aafe
--- /dev/null
+++ b/shared-module/audiopwmio/__init__.h
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOPWMIO__INIT__H
+#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOPWMIO__INIT__H
+
+#include "shared-module/audiocore/__init__.h"
+
+#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOPWMIO__INIT__H
diff --git a/shared-module/bleio/Address.c b/shared-module/bleio/Address.c
new file mode 100644
index 000000000..6bc458b7c
--- /dev/null
+++ b/shared-module/bleio/Address.c
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+
+#include "py/objstr.h"
+#include "shared-bindings/bleio/Address.h"
+#include "shared-module/bleio/Address.h"
+
+void common_hal_bleio_address_construct(bleio_address_obj_t *self, uint8_t *bytes, uint8_t address_type) {
+ self->bytes = mp_obj_new_bytes(bytes, NUM_BLEIO_ADDRESS_BYTES);
+ self->type = address_type;
+}
+
+mp_obj_t common_hal_bleio_address_get_address_bytes(bleio_address_obj_t *self) {
+ return self->bytes;
+}
+
+uint8_t common_hal_bleio_address_get_type(bleio_address_obj_t *self) {
+ return self->type;
+}
diff --git a/shared-module/bleio/Address.h b/shared-module/bleio/Address.h
index f0998c163..39789842f 100644
--- a/shared-module/bleio/Address.h
+++ b/shared-module/bleio/Address.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -27,14 +28,14 @@
#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADDRESS_H
#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADDRESS_H
-#include "shared-bindings/bleio/AddressType.h"
+#include "py/obj.h"
-#define BLEIO_ADDRESS_BYTES 6
+#define NUM_BLEIO_ADDRESS_BYTES 6
typedef struct {
mp_obj_base_t base;
- bleio_address_type_t type;
- uint8_t value[BLEIO_ADDRESS_BYTES];
+ uint8_t type;
+ mp_obj_t bytes; // a bytes() object
} bleio_address_obj_t;
#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADDRESS_H
diff --git a/shared-module/bleio/AdvertisementData.h b/shared-module/bleio/AdvertisementData.h
deleted file mode 100644
index 738d53b23..000000000
--- a/shared-module/bleio/AdvertisementData.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 Artur Pacholec
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H
-#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H
-
-#include "py/obj.h"
-
-// Taken from https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
-enum {
- AdFlags = 0x01,
- AdIncompleteListOf16BitServiceClassUUIDs = 0x02,
- AdCompleteListOf16BitServiceClassUUIDs = 0x03,
- AdIncompleteListOf32BitServiceClassUUIDs = 0x04,
- AdCompleteListOf32BitServiceClassUUIDs = 0x05,
- AdIncompleteListOf128BitServiceClassUUIDs = 0x06,
- AdCompleteListOf128BitServiceClassUUIDs = 0x07,
- AdShortenedLocalName = 0x08,
- AdCompleteLocalName = 0x09,
- AdTxPowerLevel = 0x0A,
- AdClassOfDevice = 0x0D,
- AdSimplePairingHashC = 0x0E,
- AdSimplePairingRandomizerR = 0x0F,
- AdSecurityManagerTKValue = 0x10,
- AdSecurityManagerOOBFlags = 0x11,
- AdSlaveConnectionIntervalRange = 0x12,
- AdListOf16BitServiceSolicitationUUIDs = 0x14,
- AdListOf128BitServiceSolicitationUUIDs = 0x15,
- AdServiceData = 0x16,
- AdPublicTargetAddress = 0x17,
- AdRandomTargetAddress = 0x18,
- AdAppearance = 0x19,
- AdAdvertisingInterval = 0x1A,
- AdLEBluetoothDeviceAddress = 0x1B,
- AdLERole = 0x1C,
- AdSimplePairingHashC256 = 0x1D,
- AdSimplePairingRandomizerR256 = 0x1E,
- AdListOf32BitServiceSolicitationUUIDs = 0x1F,
- AdServiceData32BitUUID = 0x20,
- AdServiceData128BitUUID = 0x21,
- AdLESecureConnectionsConfirmationValue = 0x22,
- AdLESecureConnectionsRandomValue = 0x23,
- AdURI = 0x24,
- AdIndoorPositioning = 0x25,
- AdTransportDiscoveryData = 0x26,
- AdLESupportedFeatures = 0x27,
- AdChannelMapUpdateIndication = 0x28,
- AdPBADV = 0x29,
- AdMeshMessage = 0x2A,
- AdMeshBeacon = 0x2B,
- Ad3DInformationData = 0x3D,
- AdManufacturerSpecificData = 0xFF,
-};
-
-typedef struct {
- mp_obj_t device_name;
- mp_obj_t services;
- mp_obj_t data;
- bool connectable;
-} bleio_advertisement_data_t;
-
-#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H
diff --git a/shared-module/bleio/Characteristic.h b/shared-module/bleio/Characteristic.h
index 958837e64..27b43588f 100644
--- a/shared-module/bleio/Characteristic.h
+++ b/shared-module/bleio/Characteristic.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -37,5 +37,4 @@ typedef struct {
bool indicate : 1;
} bleio_characteristic_properties_t;
-
#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H
diff --git a/shared-bindings/bleio/Broadcaster.h b/shared-module/bleio/ScanEntry.c
index 8aa125af9..306ac33c5 100644
--- a/shared-bindings/bleio/Broadcaster.h
+++ b/shared-module/bleio/ScanEntry.c
@@ -3,7 +3,9 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,15 +26,20 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_BROADCASTER_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_BROADCASTER_H
+#include <string.h>
-#include "common-hal/bleio/Broadcaster.h"
+#include "shared-bindings/bleio/Address.h"
+#include "shared-module/bleio/Address.h"
+#include "shared-module/bleio/ScanEntry.h"
-extern const mp_obj_type_t bleio_broadcaster_type;
+mp_obj_t common_hal_bleio_scanentry_get_address(bleio_scanentry_obj_t *self) {
+ return MP_OBJ_FROM_PTR(self->address);
+}
-extern void common_hal_bleio_broadcaster_construct(bleio_broadcaster_obj_t *self, mp_float_t interval);
-extern void common_hal_bleio_broadcaster_start_advertising(bleio_broadcaster_obj_t *self, mp_buffer_info_t *data);
-extern void common_hal_bleio_broadcaster_stop_advertising(bleio_broadcaster_obj_t *self);
+mp_obj_t common_hal_bleio_scanentry_get_advertisement_bytes(bleio_scanentry_obj_t *self) {
+ return self->data;
+}
-#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_BROADCASTER_H
+mp_int_t common_hal_bleio_scanentry_get_rssi(bleio_scanentry_obj_t *self) {
+ return self->rssi;
+}
diff --git a/shared-module/bleio/ScanEntry.h b/shared-module/bleio/ScanEntry.h
index 2f01669e2..b302460e6 100644
--- a/shared-module/bleio/ScanEntry.h
+++ b/shared-module/bleio/ScanEntry.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -27,13 +28,14 @@
#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H
#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H
-#include "shared-module/bleio/Address.h"
+#include "py/obj.h"
+#include "shared-bindings/bleio/Address.h"
typedef struct {
mp_obj_base_t base;
- bleio_address_obj_t address;
bool connectable;
int8_t rssi;
+ bleio_address_obj_t *address;
mp_obj_t data;
} bleio_scanentry_obj_t;
diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c
index ac4de2fe5..5a1dead78 100644
--- a/shared-module/board/__init__.c
+++ b/shared-module/board/__init__.c
@@ -24,16 +24,18 @@
* THE SOFTWARE.
*/
-#include "shared-bindings/busio/I2C.h"
-#include "shared-bindings/busio/SPI.h"
-#include "shared-bindings/busio/UART.h"
-
#include "shared-bindings/microcontroller/Pin.h"
#include "supervisor/shared/translate.h"
#include "mpconfigboard.h"
#include "py/runtime.h"
-#ifdef CIRCUITPY_DISPLAYIO
+#if CIRCUITPY_BUSIO
+#include "shared-bindings/busio/I2C.h"
+#include "shared-bindings/busio/SPI.h"
+#include "shared-bindings/busio/UART.h"
+#endif
+
+#if CIRCUITPY_DISPLAYIO
#include "shared-module/displayio/__init__.h"
#endif
@@ -103,7 +105,7 @@ void reset_board_busses(void) {
#endif
#if BOARD_SPI
bool display_using_spi = false;
- #ifdef CIRCUITPY_DISPLAYIO
+ #if CIRCUITPY_DISPLAYIO
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
if (displays[i].fourwire_bus.bus == spi_singleton) {
display_using_spi = true;
diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c
index f8dc24c15..59971d25c 100644
--- a/shared-module/displayio/Bitmap.c
+++ b/shared-module/displayio/Bitmap.c
@@ -63,6 +63,11 @@ void common_hal_displayio_bitmap_construct(displayio_bitmap_t *self, uint32_t wi
}
self->x_mask = (1 << self->x_shift) - 1; // Used as a modulus on the x value
self->bitmask = (1 << bits_per_value) - 1;
+
+ self->dirty_area.x1 = 0;
+ self->dirty_area.x2 = width;
+ self->dirty_area.y1 = 0;
+ self->dirty_area.y2 = height;
}
uint16_t common_hal_displayio_bitmap_get_height(displayio_bitmap_t *self) {
@@ -104,6 +109,26 @@ void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *self, int16_t x,
if (self->read_only) {
mp_raise_RuntimeError(translate("Read-only object"));
}
+ // Update the dirty area.
+ if (self->dirty_area.x1 == self->dirty_area.x2) {
+ self->dirty_area.x1 = x;
+ self->dirty_area.x2 = x + 1;
+ self->dirty_area.y1 = y;
+ self->dirty_area.y2 = y + 1;
+ } else {
+ if (x < self->dirty_area.x1) {
+ self->dirty_area.x1 = x;
+ } else if (x >= self->dirty_area.x2) {
+ self->dirty_area.x2 = x + 1;
+ }
+ if (y < self->dirty_area.y1) {
+ self->dirty_area.y1 = y;
+ } else if (y >= self->dirty_area.y2) {
+ self->dirty_area.y2 = y + 1;
+ }
+ }
+
+ // Update our data
int32_t row_start = y * self->stride;
uint32_t bytes_per_value = self->bits_per_value / 8;
if (bytes_per_value < 1) {
@@ -124,3 +149,16 @@ void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *self, int16_t x,
}
}
}
+
+displayio_area_t* displayio_bitmap_get_refresh_areas(displayio_bitmap_t *self, displayio_area_t* tail) {
+ if (self->dirty_area.x1 == self->dirty_area.x2) {
+ return tail;
+ }
+ self->dirty_area.next = tail;
+ return &self->dirty_area;
+}
+
+void displayio_bitmap_finish_refresh(displayio_bitmap_t *self) {
+ self->dirty_area.x1 = 0;
+ self->dirty_area.x2 = 0;
+}
diff --git a/shared-module/displayio/Bitmap.h b/shared-module/displayio/Bitmap.h
index 48ca9e2cf..f4bd7ce4d 100644
--- a/shared-module/displayio/Bitmap.h
+++ b/shared-module/displayio/Bitmap.h
@@ -31,6 +31,7 @@
#include <stdint.h>
#include "py/obj.h"
+#include "shared-module/displayio/area.h"
typedef struct {
mp_obj_base_t base;
@@ -41,8 +42,12 @@ typedef struct {
uint8_t bits_per_value;
uint8_t x_shift;
size_t x_mask;
+ displayio_area_t dirty_area;
uint16_t bitmask;
bool read_only;
} displayio_bitmap_t;
+void displayio_bitmap_finish_refresh(displayio_bitmap_t *self);
+displayio_area_t* displayio_bitmap_get_refresh_areas(displayio_bitmap_t *self, displayio_area_t* tail);
+
#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_BITMAP_H
diff --git a/shared-module/displayio/ColorConverter.c b/shared-module/displayio/ColorConverter.c
index 3928e115a..6b9bd5840 100644
--- a/shared-module/displayio/ColorConverter.c
+++ b/shared-module/displayio/ColorConverter.c
@@ -29,15 +29,36 @@
void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t* self) {
}
-bool common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *self, uint32_t input_color, uint16_t* output_color) {
- // TODO(tannewt): Validate the color input against the input format.
- uint32_t r5 = (input_color >> 19);
- uint32_t g6 = (input_color >> 10) & 0x3f;
- uint32_t b5 = (input_color >> 3) & 0x1f;
+uint16_t displayio_colorconverter_compute_rgb565(uint32_t color_rgb888) {
+ uint32_t r5 = (color_rgb888 >> 19);
+ uint32_t g6 = (color_rgb888 >> 10) & 0x3f;
+ uint32_t b5 = (color_rgb888 >> 3) & 0x1f;
uint32_t packed = r5 << 11 | g6 << 5 | b5;
// swap bytes
- *output_color = __builtin_bswap16(packed);
- return true;
+ return __builtin_bswap16(packed);
+}
+
+uint8_t displayio_colorconverter_compute_luma(uint32_t color_rgb888) {
+ uint32_t r8 = (color_rgb888 >> 16);
+ uint32_t g8 = (color_rgb888 >> 8) & 0xff;
+ uint32_t b8 = color_rgb888 & 0xff;
+ return (r8 * 19) / 255 + (g8 * 182) / 255 + (b8 + 54) / 255;
+}
+
+bool displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color) {
+ if (colorspace->depth == 16) {
+ *output_color = displayio_colorconverter_compute_rgb565(input_color);
+ return true;
+ } else if (colorspace->grayscale && colorspace->depth <= 8) {
+ uint8_t luma = displayio_colorconverter_compute_luma(input_color);
+ *output_color = luma >> (8 - colorspace->depth);
+ return true;
+ }
+ return false;
+}
+
+void common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color) {
+ displayio_colorconverter_convert(self, colorspace, input_color, output_color);
}
// Currently no refresh logic is needed for a ColorConverter.
diff --git a/shared-module/displayio/ColorConverter.h b/shared-module/displayio/ColorConverter.h
index 7f3c1a0a0..c48b98e6d 100644
--- a/shared-module/displayio/ColorConverter.h
+++ b/shared-module/displayio/ColorConverter.h
@@ -31,6 +31,7 @@
#include <stdint.h>
#include "py/obj.h"
+#include "shared-module/displayio/Palette.h"
typedef struct {
mp_obj_base_t base;
@@ -38,5 +39,8 @@ typedef struct {
bool displayio_colorconverter_needs_refresh(displayio_colorconverter_t *self);
void displayio_colorconverter_finish_refresh(displayio_colorconverter_t *self);
+bool displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color);
+uint16_t displayio_colorconverter_compute_rgb565(uint32_t color_rgb888);
+uint8_t displayio_colorconverter_compute_luma(uint32_t color_rgb888);
#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_COLORCONVERTER_H
diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c
index 3b1613974..51c6f292a 100644
--- a/shared-module/displayio/Display.c
+++ b/shared-module/displayio/Display.c
@@ -28,6 +28,7 @@
#include "py/runtime.h"
#include "shared-bindings/displayio/FourWire.h"
+#include "shared-bindings/displayio/I2CDisplay.h"
#include "shared-bindings/displayio/ParallelBus.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/time/__init__.h"
@@ -35,6 +36,7 @@
#include "supervisor/shared/display.h"
#include <stdint.h>
+#include <string.h>
#include "tick.h"
@@ -42,11 +44,16 @@
void common_hal_displayio_display_construct(displayio_display_obj_t* self,
mp_obj_t bus, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart, uint16_t rotation,
- uint16_t color_depth, uint8_t set_column_command, uint8_t set_row_command,
+ uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte,
+ uint8_t set_column_command, uint8_t set_row_command,
uint8_t write_ram_command, uint8_t set_vertical_scroll, uint8_t* init_sequence, uint16_t init_sequence_len,
- const mcu_pin_obj_t* backlight_pin, mp_float_t brightness, bool auto_brightness,
+ const mcu_pin_obj_t* backlight_pin, uint16_t brightness_command, mp_float_t brightness, bool auto_brightness,
bool single_byte_bounds, bool data_as_commands) {
- self->color_depth = color_depth;
+ self->colorspace.depth = color_depth;
+ self->colorspace.grayscale = grayscale;
+ self->colorspace.pixels_in_byte_share_row = pixels_in_byte_share_row;
+ self->colorspace.bytes_per_cell = bytes_per_cell;
+ self->colorspace.reverse_pixels_in_byte = reverse_pixels_in_byte;
self->set_column_command = set_column_command;
self->set_row_command = set_row_command;
self->write_ram_command = write_ram_command;
@@ -54,6 +61,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
self->current_group = NULL;
self->colstart = colstart;
self->rowstart = rowstart;
+ self->brightness_command = brightness_command;
self->auto_brightness = auto_brightness;
self->data_as_commands = data_as_commands;
self->single_byte_bounds = single_byte_bounds;
@@ -66,6 +74,10 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
self->begin_transaction = common_hal_displayio_fourwire_begin_transaction;
self->send = common_hal_displayio_fourwire_send;
self->end_transaction = common_hal_displayio_fourwire_end_transaction;
+ } else if (MP_OBJ_IS_TYPE(bus, &displayio_i2cdisplay_type)) {
+ self->begin_transaction = common_hal_displayio_i2cdisplay_begin_transaction;
+ self->send = common_hal_displayio_i2cdisplay_send;
+ self->end_transaction = common_hal_displayio_i2cdisplay_end_transaction;
} else {
mp_raise_ValueError(translate("Unsupported display bus type"));
}
@@ -83,13 +95,13 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
bool delay = (data_size & DELAY) != 0;
data_size &= ~DELAY;
uint8_t *data = cmd + 2;
- self->send(self->bus, true, cmd, 1);
if (self->data_as_commands) {
- // Loop through each parameter to force a CS toggle
- for (uint32_t j=0; j < data_size; j++) {
- self->send(self->bus, true, data + j, 1);
- }
+ uint8_t full_command[data_size + 1];
+ full_command[0] = cmd[0];
+ memcpy(full_command + 1, data, data_size);
+ self->send(self->bus, true, full_command, data_size + 1);
} else {
+ self->send(self->bus, true, cmd, 1);
self->send(self->bus, false, data, data_size);
}
uint16_t delay_length_ms = 10;
@@ -107,28 +119,26 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
supervisor_start_terminal(width, height);
- // Set the group after initialization otherwise we may send pixels while we delay in
- // initialization.
- self->refresh = true;
- self->current_group = &circuitpython_splash;
-
self->width = width;
self->height = height;
rotation = rotation % 360;
- self->mirror_x = false;
- self->mirror_y = false;
- self->transpose_xy = false;
+ self->transform.x = 0;
+ self->transform.y = 0;
+ self->transform.scale = 1;
+ self->transform.mirror_x = false;
+ self->transform.mirror_y = false;
+ self->transform.transpose_xy = false;
if (rotation == 0 || rotation == 180) {
if (rotation == 180) {
- self->mirror_x = true;
- self->mirror_y = true;
+ self->transform.mirror_x = true;
+ self->transform.mirror_y = true;
}
} else {
- self->transpose_xy = true;
- if (rotation == 90) {
- self->mirror_y = true;
+ self->transform.transpose_xy = true;
+ if (rotation == 270) {
+ self->transform.mirror_y = true;
} else {
- self->mirror_x = true;
+ self->transform.mirror_x = true;
}
}
@@ -143,25 +153,84 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
} else {
self->backlight_pwm.base.type = &pulseio_pwmout_type;
common_hal_pulseio_pwmout_never_reset(&self->backlight_pwm);
- if (!self->auto_brightness) {
- common_hal_displayio_display_set_brightness(self, brightness);
- }
}
}
+ if (!self->auto_brightness && (self->backlight_inout.base.type != &mp_type_NoneType ||
+ brightness_command != NO_BRIGHTNESS_COMMAND)) {
+ common_hal_displayio_display_set_brightness(self, brightness);
+ } else {
+ self->current_brightness = -1.0;
+ }
+
+ self->area.x1 = 0;
+ self->area.y1 = 0;
+ self->area.next = NULL;
+
+ self->transform.dx = 1;
+ self->transform.dy = 1;
+ if (self->transform.transpose_xy) {
+ self->area.x2 = height;
+ self->area.y2 = width;
+ if (self->transform.mirror_x) {
+ self->transform.x = height;
+ self->transform.dx = -1;
+ }
+ if (self->transform.mirror_y) {
+ self->transform.y = width;
+ self->transform.dy = -1;
+ }
+ } else {
+ self->area.x2 = width;
+ self->area.y2 = height;
+ if (self->transform.mirror_x) {
+ self->transform.x = width;
+ self->transform.dx = -1;
+ }
+ if (self->transform.mirror_y) {
+ self->transform.y = height;
+ self->transform.dy = -1;
+ }
+ }
+
+ // Set the group after initialization otherwise we may send pixels while we delay in
+ // initialization.
+ common_hal_displayio_display_show(self, &circuitpython_splash);
}
-void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) {
+bool common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) {
if (root_group == NULL) {
root_group = &circuitpython_splash;
}
+ if (root_group == self->current_group) {
+ return true;
+ }
+ if (root_group->in_group) {
+ return false;
+ }
+ if (self->current_group != NULL) {
+ self->current_group->in_group = false;
+ }
+ displayio_group_update_transform(root_group, &self->transform);
+ root_group->in_group = true;
self->current_group = root_group;
+ self->full_refresh = true;
common_hal_displayio_display_refresh_soon(self);
+ return true;
}
void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self) {
self->refresh = true;
}
+const displayio_area_t* displayio_display_get_refresh_areas(displayio_display_obj_t *self) {
+ if (self->full_refresh) {
+ self->area.next = NULL;
+ return &self->area;
+ } else {
+ return displayio_group_get_refresh_areas(self->current_group, NULL);
+ }
+}
+
int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* self) {
uint64_t last_refresh = self->last_refresh;
// Don't try to refresh if we got an exception.
@@ -188,17 +257,7 @@ void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t* s
}
mp_float_t common_hal_displayio_display_get_brightness(displayio_display_obj_t* self) {
- if (self->backlight_pwm.base.type == &pulseio_pwmout_type) {
- uint16_t duty_cycle = common_hal_pulseio_pwmout_get_duty_cycle(&self->backlight_pwm);
- return duty_cycle / ((mp_float_t) 0xffff);
- } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) {
- if (common_hal_digitalio_digitalinout_get_value(&self->backlight_inout)) {
- return 1.0;
- } else {
- return 0.0;
- }
- }
- return -1.0;
+ return self->current_brightness;
}
bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self, mp_float_t brightness) {
@@ -210,8 +269,26 @@ bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self,
} else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) {
common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, brightness > 0.99);
ok = true;
+ } else if (self->brightness_command != NO_BRIGHTNESS_COMMAND) {
+ ok = self->begin_transaction(self->bus);
+ if (ok) {
+ if (self->data_as_commands) {
+ uint8_t set_brightness[2] = {self->brightness_command, (uint8_t) (0xff * brightness)};
+ self->send(self->bus, true, set_brightness, 2);
+ } else {
+ uint8_t command = self->brightness_command;
+ uint8_t hex_brightness = 0xff * brightness;
+ self->send(self->bus, true, &command, 1);
+ self->send(self->bus, false, &hex_brightness, 1);
+ }
+ self->end_transaction(self->bus);
+ }
+
}
self->updating_backlight = false;
+ if (ok) {
+ self->current_brightness = brightness;
+ }
return ok;
}
@@ -223,45 +300,75 @@ void displayio_display_end_transaction(displayio_display_obj_t* self) {
self->end_transaction(self->bus);
}
-void displayio_display_set_region_to_update(displayio_display_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
+void displayio_display_set_region_to_update(displayio_display_obj_t* self, displayio_area_t* area) {
+ uint16_t x1 = area->x1;
+ uint16_t x2 = area->x2;
+ uint16_t y1 = area->y1;
+ uint16_t y2 = area->y2;
+ // Collapse down the dimension where multiple pixels are in a byte.
+ if (self->colorspace.depth < 8) {
+ uint8_t pixels_per_byte = 8 / self->colorspace.depth;
+ if (self->colorspace.pixels_in_byte_share_row) {
+ x1 /= pixels_per_byte * self->colorspace.bytes_per_cell;
+ x2 /= pixels_per_byte * self->colorspace.bytes_per_cell;
+ } else {
+ y1 /= pixels_per_byte * self->colorspace.bytes_per_cell;
+ y2 /= pixels_per_byte * self->colorspace.bytes_per_cell;
+ }
+ }
- self->send(self->bus, true, &self->set_column_command, 1);
- bool isCommand = self->data_as_commands;
- if (self->single_byte_bounds) {
- uint8_t data[2];
- data[0] = x0 + self->colstart;
- data[1] = x1 - 1 + self->colstart;
- self->send(self->bus, isCommand, (uint8_t*) data, 2);
- } else {
- uint16_t data[2];
- data[0] = __builtin_bswap16(x0 + self->colstart);
- data[1] = __builtin_bswap16(x1 - 1 + self->colstart);
- self->send(self->bus, isCommand, (uint8_t*) data, 4);
+ // Set column.
+ uint8_t data[5];
+ data[0] = self->set_column_command;
+ uint8_t data_length = 1;
+ if (!self->data_as_commands) {
+ self->send(self->bus, true, data, 1);
+ data_length = 0;
}
- self->send(self->bus, true, &self->set_row_command, 1);
if (self->single_byte_bounds) {
- uint8_t data[2];
- data[0] = y0 + self->rowstart;
- data[1] = y1 - 1 + self->rowstart;
- self->send(self->bus, isCommand, (uint8_t*) data, 2);
+ data[data_length++] = x1 + self->colstart;
+ data[data_length++] = x2 - 1 + self->colstart;
} else {
- uint16_t data[2];
- data[0] = __builtin_bswap16(y0 + self->rowstart);
- data[1] = __builtin_bswap16(y1 - 1 + self->rowstart);
- self->send(self->bus, isCommand, (uint8_t*) data, 4);
+ x1 += self->colstart;
+ x2 += self->colstart - 1;
+ data[data_length++] = x1 >> 8;
+ data[data_length++] = x1 & 0xff;
+ data[data_length++] = x2 >> 8;
+ data[data_length++] = x2 & 0xff;
}
+ self->send(self->bus, self->data_as_commands, data, data_length);
+
+ // Set row.
+ data[0] = self->set_row_command;
+ data_length = 1;
if (!self->data_as_commands) {
- self->send(self->bus, true, &self->write_ram_command, 1);
+ self->send(self->bus, true, data, 1);
+ data_length = 0;
+ }
+ if (self->single_byte_bounds) {
+ data[data_length++] = y1 + self->rowstart;
+ data[data_length++] = y2 - 1 + self->rowstart;
+ } else {
+ y1 += self->rowstart;
+ y2 += self->rowstart - 1;
+ data[data_length++] = y1 >> 8;
+ data[data_length++] = y1 & 0xff;
+ data[data_length++] = y2 >> 8;
+ data[data_length++] = y2 & 0xff;
}
+ self->send(self->bus, self->data_as_commands, data, data_length);
}
-bool displayio_display_frame_queued(displayio_display_obj_t* self) {
- // Refresh at ~30 fps.
- return (ticks_ms - self->last_refresh) > 32;
+void displayio_display_start_refresh(displayio_display_obj_t* self) {
+ self->last_refresh = ticks_ms;
}
-bool displayio_display_refresh_queued(displayio_display_obj_t* self) {
- return self->refresh || (self->current_group != NULL && displayio_group_needs_refresh(self->current_group));
+bool displayio_display_frame_queued(displayio_display_obj_t* self) {
+ if (self->current_group == NULL) {
+ return false;
+ }
+ // Refresh at ~60 fps.
+ return (ticks_ms - self->last_refresh) > 16;
}
void displayio_display_finish_refresh(displayio_display_obj_t* self) {
@@ -269,11 +376,15 @@ void displayio_display_finish_refresh(displayio_display_obj_t* self) {
displayio_group_finish_refresh(self->current_group);
}
self->refresh = false;
+ self->full_refresh = false;
self->last_refresh = ticks_ms;
}
-void displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixels, uint32_t length) {
- self->send(self->bus, false, (uint8_t*) pixels, length * 4);
+void displayio_display_send_pixels(displayio_display_obj_t* self, uint8_t* pixels, uint32_t length) {
+ if (!self->data_as_commands) {
+ self->send(self->bus, true, &self->write_ram_command, 1);
+ }
+ self->send(self->bus, false, pixels, length);
}
void displayio_display_update_backlight(displayio_display_obj_t* self) {
@@ -298,3 +409,35 @@ void release_display(displayio_display_obj_t* self) {
common_hal_digitalio_digitalinout_deinit(&self->backlight_inout);
}
}
+
+bool displayio_display_fill_area(displayio_display_obj_t *self, displayio_area_t* area, uint32_t* mask, uint32_t *buffer) {
+ return displayio_group_fill_area(self->current_group, &self->colorspace, area, mask, buffer);
+}
+
+bool displayio_display_clip_area(displayio_display_obj_t *self, const displayio_area_t* area, displayio_area_t* clipped) {
+ bool overlaps = displayio_area_compute_overlap(&self->area, area, clipped);
+ if (!overlaps) {
+ return false;
+ }
+ // Expand the area if we have multiple pixels per byte and we need to byte
+ // align the bounds.
+ if (self->colorspace.depth < 8) {
+ uint8_t pixels_per_byte = 8 / self->colorspace.depth * self->colorspace.bytes_per_cell;
+ if (self->colorspace.pixels_in_byte_share_row) {
+ if (clipped->x1 % pixels_per_byte != 0) {
+ clipped->x1 -= clipped->x1 % pixels_per_byte;
+ }
+ if (clipped->x2 % pixels_per_byte != 0) {
+ clipped->x2 += pixels_per_byte - clipped->x2 % pixels_per_byte;
+ }
+ } else {
+ if (clipped->y1 % pixels_per_byte != 0) {
+ clipped->y1 -= clipped->y1 % pixels_per_byte;
+ }
+ if (clipped->y2 % pixels_per_byte != 0) {
+ clipped->y2 += pixels_per_byte - clipped->y2 % pixels_per_byte;
+ }
+ }
+ }
+ return true;
+}
diff --git a/shared-module/displayio/Display.h b/shared-module/displayio/Display.h
index 52f98a252..96d1c06d5 100644
--- a/shared-module/displayio/Display.h
+++ b/shared-module/displayio/Display.h
@@ -31,6 +31,8 @@
#include "shared-bindings/displayio/Group.h"
#include "shared-bindings/pulseio/PWMOut.h"
+#include "shared-module/displayio/area.h"
+
typedef bool (*display_bus_begin_transaction)(mp_obj_t bus);
typedef void (*display_bus_send)(mp_obj_t bus, bool command, uint8_t *data, uint32_t data_length);
typedef void (*display_bus_end_transaction)(mp_obj_t bus);
@@ -38,19 +40,8 @@ typedef void (*display_bus_end_transaction)(mp_obj_t bus);
typedef struct {
mp_obj_base_t base;
mp_obj_t bus;
- uint16_t width;
- uint16_t height;
- uint16_t color_depth;
- uint8_t set_column_command;
- uint8_t set_row_command;
- uint8_t write_ram_command;
displayio_group_t *current_group;
- bool refresh;
uint64_t last_refresh;
- int16_t colstart;
- int16_t rowstart;
- bool single_byte_bounds;
- bool data_as_commands;
display_bus_begin_transaction begin_transaction;
display_bus_send send;
display_bus_end_transaction end_transaction;
@@ -59,14 +50,31 @@ typedef struct {
pulseio_pwmout_obj_t backlight_pwm;
};
uint64_t last_backlight_refresh;
- bool auto_brightness:1;
- bool updating_backlight:1;
- bool mirror_x;
- bool mirror_y;
- bool transpose_xy;
+ displayio_buffer_transform_t transform;
+ displayio_area_t area;
+ mp_float_t current_brightness;
+ uint16_t width;
+ uint16_t height;
+ _displayio_colorspace_t colorspace;
+ int16_t colstart;
+ int16_t rowstart;
+ uint16_t brightness_command;
+ uint8_t set_column_command;
+ uint8_t set_row_command;
+ uint8_t write_ram_command;
+ bool refresh;
+ bool single_byte_bounds;
+ bool data_as_commands;
+ bool auto_brightness;
+ bool updating_backlight;
+ bool full_refresh; // New group means we need to refresh the whole display.
} displayio_display_obj_t;
+void displayio_display_start_refresh(displayio_display_obj_t* self);
+const displayio_area_t* displayio_display_get_refresh_areas(displayio_display_obj_t *self);
+bool displayio_display_fill_area(displayio_display_obj_t *self, displayio_area_t* area, uint32_t* mask, uint32_t *buffer);
void displayio_display_update_backlight(displayio_display_obj_t* self);
+bool displayio_display_clip_area(displayio_display_obj_t *self, const displayio_area_t* area, displayio_area_t* clipped);
void release_display(displayio_display_obj_t* self);
#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H
diff --git a/shared-module/displayio/FourWire.c b/shared-module/displayio/FourWire.c
index b01456bba..913635db8 100644
--- a/shared-module/displayio/FourWire.c
+++ b/shared-module/displayio/FourWire.c
@@ -31,13 +31,14 @@
#include "py/gc.h"
#include "shared-bindings/busio/SPI.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/time/__init__.h"
#include "tick.h"
void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self,
busio_spi_obj_t* spi, const mcu_pin_obj_t* command,
- const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset) {
+ const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, uint32_t baudrate) {
self->bus = spi;
common_hal_busio_spi_never_reset(self->bus);
@@ -45,7 +46,7 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self,
// of the heap as well.
gc_never_free(self->bus);
- self->frequency = common_hal_busio_spi_get_frequency(spi);
+ self->frequency = baudrate;
self->polarity = common_hal_busio_spi_get_polarity(spi);
self->phase = common_hal_busio_spi_get_phase(spi);
@@ -58,6 +59,11 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self,
common_hal_digitalio_digitalinout_construct(&self->reset, reset);
common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL);
never_reset_pin_number(reset->number);
+
+ common_hal_digitalio_digitalinout_set_value(&self->reset, false);
+ common_hal_mcu_delay_us(10);
+ common_hal_digitalio_digitalinout_set_value(&self->reset, true);
+ common_hal_mcu_delay_us(10);
}
never_reset_pin_number(command->number);
@@ -87,13 +93,19 @@ bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t obj) {
void common_hal_displayio_fourwire_send(mp_obj_t obj, bool command, uint8_t *data, uint32_t data_length) {
displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj);
+ common_hal_digitalio_digitalinout_set_value(&self->command, !command);
if (command) {
- common_hal_digitalio_digitalinout_set_value(&self->chip_select, true);
- common_hal_time_delay_ms(1);
- common_hal_digitalio_digitalinout_set_value(&self->chip_select, false);
+ // Toggle chip select after each command byte in case the display driver
+ // IC latches commands based on it.
+ for (size_t i = 0; i < data_length; i++) {
+ common_hal_busio_spi_write(self->bus, &data[i], 1);
+ common_hal_digitalio_digitalinout_set_value(&self->chip_select, true);
+ common_hal_mcu_delay_us(1);
+ common_hal_digitalio_digitalinout_set_value(&self->chip_select, false);
+ }
+ } else {
+ common_hal_busio_spi_write(self->bus, data, data_length);
}
- common_hal_digitalio_digitalinout_set_value(&self->command, !command);
- common_hal_busio_spi_write(self->bus, data, data_length);
}
void common_hal_displayio_fourwire_end_transaction(mp_obj_t obj) {
diff --git a/shared-module/displayio/FourWire.h b/shared-module/displayio/FourWire.h
index 743139e62..a4260a3ac 100644
--- a/shared-module/displayio/FourWire.h
+++ b/shared-module/displayio/FourWire.h
@@ -24,8 +24,8 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_FOURWIRE_H
-#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_FOURWIRE_H
+#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_FOURWIRE_H
+#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_FOURWIRE_H
#include "common-hal/busio/SPI.h"
#include "common-hal/digitalio/DigitalInOut.h"
@@ -43,4 +43,4 @@ typedef struct {
uint8_t phase;
} displayio_fourwire_obj_t;
-#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_FOURWIRE_H
+#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_FOURWIRE_H
diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c
index 097edf33b..38418a029 100644
--- a/shared-module/displayio/Group.c
+++ b/shared-module/displayio/Group.c
@@ -38,9 +38,85 @@ uint32_t common_hal_displayio_group_get_scale(displayio_group_t* self) {
return self->scale;
}
+bool displayio_group_get_previous_area(displayio_group_t *self, displayio_area_t* area) {
+ bool first = true;
+ for (size_t i = 0; i < self->size; i++) {
+ mp_obj_t layer = self->children[i].native;
+ displayio_area_t layer_area;
+ if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
+ if (!displayio_tilegrid_get_previous_area(layer, &layer_area)) {
+ continue;
+ }
+ } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
+ if (!displayio_group_get_previous_area(layer, &layer_area)) {
+ continue;
+ }
+ }
+ if (first) {
+ displayio_area_copy(&layer_area, area);
+ first = false;
+ } else {
+ displayio_area_expand(area, &layer_area);
+ }
+ }
+ if (self->item_removed) {
+ if (first) {
+ displayio_area_copy(&self->dirty_area, area);
+ first = false;
+ } else {
+ displayio_area_expand(area, &self->dirty_area);
+ }
+ }
+ return !first;
+}
+
+static void _update_child_transforms(displayio_group_t* self) {
+ if (!self->in_group) {
+ return;
+ }
+ for (size_t i = 0; i < self->size; i++) {
+ mp_obj_t layer = self->children[i].native;
+ if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
+ displayio_tilegrid_update_transform(layer, &self->absolute_transform);
+ } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
+ displayio_group_update_transform(layer, &self->absolute_transform);
+ }
+ }
+}
+
+void displayio_group_update_transform(displayio_group_t *self,
+ const displayio_buffer_transform_t* parent_transform) {
+ self->in_group = parent_transform != NULL;
+ if (self->in_group) {
+ int16_t x = self->x;
+ int16_t y = self->y;
+ if (parent_transform->transpose_xy) {
+ x = y;
+ y = self->x;
+ }
+ self->absolute_transform.x = parent_transform->x + parent_transform->dx * x;
+ self->absolute_transform.y = parent_transform->y + parent_transform->dy * y;
+ self->absolute_transform.dx = parent_transform->dx * self->scale;
+ self->absolute_transform.dy = parent_transform->dy * self->scale;
+ self->absolute_transform.transpose_xy = parent_transform->transpose_xy;
+ self->absolute_transform.mirror_x = parent_transform->mirror_x;
+ self->absolute_transform.mirror_y = parent_transform->mirror_y;
+
+ self->absolute_transform.scale = parent_transform->scale * self->scale;
+ }
+ _update_child_transforms(self);
+}
+
void common_hal_displayio_group_set_scale(displayio_group_t* self, uint32_t scale) {
- self->needs_refresh = self->scale != scale;
+ if (self->scale == scale) {
+ return;
+ }
+ uint8_t parent_scale = self->absolute_transform.scale / self->scale;
+ self->absolute_transform.dx = self->absolute_transform.dx / self->scale * scale;
+ self->absolute_transform.dy = self->absolute_transform.dy / self->scale * scale;
+ self->absolute_transform.scale = parent_scale * scale;
self->scale = scale;
+ _update_child_transforms(self);
}
mp_int_t common_hal_displayio_group_get_x(displayio_group_t* self) {
@@ -48,8 +124,19 @@ mp_int_t common_hal_displayio_group_get_x(displayio_group_t* self) {
}
void common_hal_displayio_group_set_x(displayio_group_t* self, mp_int_t x) {
- self->needs_refresh = self->x != x;
+ if (self->x == x) {
+ return;
+ }
+ if (self->absolute_transform.transpose_xy) {
+ int16_t dy = self->absolute_transform.dy / self->scale;
+ self->absolute_transform.y += dy * (x - self->x);
+ } else {
+ int16_t dx = self->absolute_transform.dx / self->scale;
+ self->absolute_transform.x += dx * (x - self->x);
+ }
+
self->x = x;
+ _update_child_transforms(self);
}
mp_int_t common_hal_displayio_group_get_y(displayio_group_t* self) {
@@ -57,21 +144,75 @@ mp_int_t common_hal_displayio_group_get_y(displayio_group_t* self) {
}
void common_hal_displayio_group_set_y(displayio_group_t* self, mp_int_t y) {
- self->needs_refresh = self->y != y;
+ if (self->y == y) {
+ return;
+ }
+ if (self->absolute_transform.transpose_xy) {
+ int8_t dx = self->absolute_transform.dx / self->scale;
+ self->absolute_transform.x += dx * (y - self->y);
+ } else {
+ int8_t dy = self->absolute_transform.dy / self->scale;
+ self->absolute_transform.y += dy * (y - self->y);
+ }
self->y = y;
+ _update_child_transforms(self);
}
-void common_hal_displayio_group_insert(displayio_group_t* self, size_t index, mp_obj_t layer) {
- if (self->size == self->max_size) {
- mp_raise_RuntimeError(translate("Group full"));
- }
+static mp_obj_t _add_layer(displayio_group_t* self, mp_obj_t layer) {
mp_obj_t native_layer = mp_instance_cast_to_native_base(layer, &displayio_group_type);
if (native_layer == MP_OBJ_NULL) {
native_layer = mp_instance_cast_to_native_base(layer, &displayio_tilegrid_type);
+ if (native_layer == MP_OBJ_NULL) {
+ mp_raise_ValueError(translate("Layer must be a Group or TileGrid subclass."));
+ }
+ displayio_tilegrid_t* tilegrid = native_layer;
+ if (tilegrid->in_group) {
+ mp_raise_ValueError(translate("Layer already in a group."));
+ } else {
+ tilegrid->in_group = true;
+ }
+ displayio_tilegrid_update_transform(tilegrid, &self->absolute_transform);
+ } else {
+ displayio_group_t* group = native_layer;
+ if (group->in_group) {
+ mp_raise_ValueError(translate("Layer already in a group."));
+ } else {
+ group->in_group = true;
+ }
+ displayio_group_update_transform(group, &self->absolute_transform);
}
- if (native_layer == MP_OBJ_NULL) {
- mp_raise_ValueError(translate("Layer must be a Group or TileGrid subclass."));
+ return native_layer;
+}
+
+static void _remove_layer(displayio_group_t* self, size_t index) {
+ mp_obj_t layer = self->children[index].native;
+ displayio_area_t layer_area;
+ bool rendered_last_frame = false;
+ if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
+ displayio_tilegrid_t* tilegrid = layer;
+ rendered_last_frame = displayio_tilegrid_get_previous_area(tilegrid, &layer_area);
+ displayio_tilegrid_update_transform(tilegrid, NULL);
+ } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
+ displayio_group_t* group = layer;
+ rendered_last_frame = displayio_group_get_previous_area(group, &layer_area);
+ displayio_group_update_transform(group, NULL);
+ }
+ if (!rendered_last_frame) {
+ return;
}
+ if (!self->item_removed) {
+ displayio_area_copy(&layer_area, &self->dirty_area);
+ } else {
+ displayio_area_expand(&self->dirty_area, &layer_area);
+ }
+ self->item_removed = true;
+}
+
+void common_hal_displayio_group_insert(displayio_group_t* self, size_t index, mp_obj_t layer) {
+ if (self->size == self->max_size) {
+ mp_raise_RuntimeError(translate("Group full"));
+ }
+ mp_obj_t native_layer = _add_layer(self, layer);
// Shift everything right.
for (size_t i = self->size; i > index; i--) {
self->children[i] = self->children[i - 1];
@@ -79,22 +220,31 @@ void common_hal_displayio_group_insert(displayio_group_t* self, size_t index, mp
self->children[index].native = native_layer;
self->children[index].original = layer;
self->size++;
- self->needs_refresh = true;
}
mp_obj_t common_hal_displayio_group_pop(displayio_group_t* self, size_t index) {
self->size--;
mp_obj_t item = self->children[index].original;
+ _remove_layer(self, index);
+
// Shift everything left.
for (size_t i = index; i < self->size; i++) {
self->children[i] = self->children[i + 1];
}
self->children[self->size].native = NULL;
self->children[self->size].original = NULL;
- self->needs_refresh = true;
return item;
}
+mp_int_t common_hal_displayio_group_index(displayio_group_t* self, mp_obj_t layer) {
+ for (size_t i = 0; i < self->size; i++) {
+ if (self->children[i].original == layer) {
+ return i;
+ }
+ }
+ return -1;
+}
+
size_t common_hal_displayio_group_get_len(displayio_group_t* self) {
return self->size;
}
@@ -104,16 +254,10 @@ mp_obj_t common_hal_displayio_group_get(displayio_group_t* self, size_t index) {
}
void common_hal_displayio_group_set(displayio_group_t* self, size_t index, mp_obj_t layer) {
- mp_obj_t native_layer = mp_instance_cast_to_native_base(layer, &displayio_group_type);
- if (native_layer == MP_OBJ_NULL) {
- native_layer = mp_instance_cast_to_native_base(layer, &displayio_tilegrid_type);
- }
- if (native_layer == MP_OBJ_NULL) {
- mp_raise_ValueError(translate("Layer must be a Group or TileGrid subclass."));
- }
+ mp_obj_t native_layer = _add_layer(self, layer);
+ _remove_layer(self, index);
self->children[index].native = native_layer;
self->children[index].original = layer;
- self->needs_refresh = true;
}
void displayio_group_construct(displayio_group_t* self, displayio_group_child_t* child_array, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y) {
@@ -121,65 +265,58 @@ void displayio_group_construct(displayio_group_t* self, displayio_group_child_t*
self->y = y;
self->children = child_array;
self->max_size = max_size;
- self->needs_refresh = false;
+ self->item_removed = false;
self->scale = scale;
+ self->in_group = false;
}
-bool displayio_group_get_pixel(displayio_group_t *self, int16_t x, int16_t y, uint16_t* pixel) {
- x -= self->x;
- y -= self->y;
- // When we are scaled we need to substract all but one to ensure -scale to 0 divide down to -1.
- // Normally -scale to scale both divide down to 0 because 0 is unsigned.
- if (x < 0) {
- x -= self->scale - 1;
- }
- if (y < 0) {
- y -= self->scale - 1;
- }
- x /= self->scale;
- y /= self->scale;
+bool displayio_group_fill_area(displayio_group_t *self, const _displayio_colorspace_t* colorspace, const displayio_area_t* area, uint32_t* mask, uint32_t* buffer) {
+ // Track if any of the layers finishes filling in the given area. We can ignore any remaining
+ // layers at that point.
+ bool full_coverage = false;
for (int32_t i = self->size - 1; i >= 0 ; i--) {
mp_obj_t layer = self->children[i].native;
if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
- if (displayio_tilegrid_get_pixel(layer, x, y, pixel)) {
- return true;
+ if (displayio_tilegrid_fill_area(layer, colorspace, area, mask, buffer)) {
+ full_coverage = true;
+ break;
}
} else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
- if (displayio_group_get_pixel(layer, x, y, pixel)) {
- return true;
+ if (displayio_group_fill_area(layer, colorspace, area, mask, buffer)) {
+ full_coverage = true;
+ break;
}
}
}
- return false;
+ return full_coverage;
}
-bool displayio_group_needs_refresh(displayio_group_t *self) {
- if (self->needs_refresh) {
- return true;
- }
+void displayio_group_finish_refresh(displayio_group_t *self) {
+ self->item_removed = false;
for (int32_t i = self->size - 1; i >= 0 ; i--) {
mp_obj_t layer = self->children[i].native;
if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
- if (displayio_tilegrid_needs_refresh(layer)) {
- return true;
- }
+ displayio_tilegrid_finish_refresh(layer);
} else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
- if (displayio_group_needs_refresh(layer)) {
- return true;
- }
+ displayio_group_finish_refresh(layer);
}
}
- return false;
}
-void displayio_group_finish_refresh(displayio_group_t *self) {
- self->needs_refresh = false;
+displayio_area_t* displayio_group_get_refresh_areas(displayio_group_t *self, displayio_area_t* tail) {
+ if (self->item_removed) {
+ self->dirty_area.next = tail;
+ tail = &self->dirty_area;
+ }
+
for (int32_t i = self->size - 1; i >= 0 ; i--) {
mp_obj_t layer = self->children[i].native;
if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
- displayio_tilegrid_finish_refresh(layer);
+ tail = displayio_tilegrid_get_refresh_areas(layer, tail);
} else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
- displayio_group_finish_refresh(layer);
+ tail = displayio_group_get_refresh_areas(layer, tail);
}
}
+
+ return tail;
}
diff --git a/shared-module/displayio/Group.h b/shared-module/displayio/Group.h
index 7826b9e66..4e2308e56 100644
--- a/shared-module/displayio/Group.h
+++ b/shared-module/displayio/Group.h
@@ -31,6 +31,8 @@
#include <stdint.h>
#include "py/obj.h"
+#include "shared-module/displayio/area.h"
+#include "shared-module/displayio/Palette.h"
typedef struct {
mp_obj_t native;
@@ -39,18 +41,23 @@ typedef struct {
typedef struct {
mp_obj_base_t base;
+ displayio_group_child_t* children;
int16_t x;
int16_t y;
uint16_t scale;
uint16_t size;
uint16_t max_size;
- displayio_group_child_t* children;
- bool needs_refresh;
+ bool item_removed;
+ bool in_group;
+ displayio_buffer_transform_t absolute_transform;
+ displayio_area_t dirty_area; // Catch all for changed area
} displayio_group_t;
void displayio_group_construct(displayio_group_t* self, displayio_group_child_t* child_array, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y);
-bool displayio_group_get_pixel(displayio_group_t *group, int16_t x, int16_t y, uint16_t *pixel);
-bool displayio_group_needs_refresh(displayio_group_t *self);
+bool displayio_group_get_previous_area(displayio_group_t *group, displayio_area_t* area);
+bool displayio_group_fill_area(displayio_group_t *group, const _displayio_colorspace_t* colorspace, const displayio_area_t* area, uint32_t* mask, uint32_t *buffer);
+void displayio_group_update_transform(displayio_group_t *group, const displayio_buffer_transform_t* parent_transform);
void displayio_group_finish_refresh(displayio_group_t *self);
+displayio_area_t* displayio_group_get_refresh_areas(displayio_group_t *self, displayio_area_t* tail);
#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_GROUP_H
diff --git a/shared-module/displayio/I2CDisplay.c b/shared-module/displayio/I2CDisplay.c
new file mode 100644
index 000000000..9d8949528
--- /dev/null
+++ b/shared-module/displayio/I2CDisplay.c
@@ -0,0 +1,105 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "shared-bindings/displayio/I2CDisplay.h"
+
+#include <stdint.h>
+#include <string.h>
+
+#include "py/gc.h"
+#include "py/runtime.h"
+#include "shared-bindings/busio/I2C.h"
+#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "shared-bindings/microcontroller/__init__.h"
+#include "shared-bindings/time/__init__.h"
+
+#include "tick.h"
+
+void common_hal_displayio_i2cdisplay_construct(displayio_i2cdisplay_obj_t* self,
+ busio_i2c_obj_t* i2c, uint16_t device_address, const mcu_pin_obj_t* reset) {
+
+ // Probe the bus to see if a device acknowledges the given address.
+ if (!common_hal_busio_i2c_probe(i2c, device_address)) {
+ mp_raise_ValueError_varg(translate("Unable to find I2C Display at %x"), device_address);
+ }
+
+ // Write to the device and return 0 on success or an appropriate error code from mperrno.h
+ self->bus = i2c;
+ common_hal_busio_i2c_never_reset(self->bus);
+ // Our object is statically allocated off the heap so make sure the bus object lives to the end
+ // of the heap as well.
+ gc_never_free(self->bus);
+
+ self->address = device_address;
+
+ if (reset != NULL) {
+ common_hal_digitalio_digitalinout_construct(&self->reset, reset);
+ common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL);
+ never_reset_pin_number(reset->number);
+
+ common_hal_digitalio_digitalinout_set_value(&self->reset, false);
+ common_hal_mcu_delay_us(1);
+ common_hal_digitalio_digitalinout_set_value(&self->reset, true);
+ }
+}
+
+void common_hal_displayio_i2cdisplay_deinit(displayio_i2cdisplay_obj_t* self) {
+ if (self->bus == &self->inline_bus) {
+ common_hal_busio_i2c_deinit(self->bus);
+ }
+
+ reset_pin_number(self->reset.pin->number);
+}
+
+bool common_hal_displayio_i2cdisplay_begin_transaction(mp_obj_t obj) {
+ displayio_i2cdisplay_obj_t* self = MP_OBJ_TO_PTR(obj);
+ if (!common_hal_busio_i2c_try_lock(self->bus)) {
+ return false;
+ }
+ return true;
+}
+
+void common_hal_displayio_i2cdisplay_send(mp_obj_t obj, bool command, uint8_t *data, uint32_t data_length) {
+ displayio_i2cdisplay_obj_t* self = MP_OBJ_TO_PTR(obj);
+ if (command) {
+ uint8_t command_bytes[2 * data_length];
+ for (uint32_t i = 0; i < data_length; i++) {
+ command_bytes[2 * i] = 0x80;
+ command_bytes[2 * i + 1] = data[i];
+ }
+ common_hal_busio_i2c_write(self->bus, self->address, command_bytes, 2 * data_length, true);
+ } else {
+ uint8_t data_bytes[data_length + 1];
+ data_bytes[0] = 0x40;
+ memcpy(data_bytes + 1, data, data_length);
+ common_hal_busio_i2c_write(self->bus, self->address, data_bytes, data_length + 1, true);
+ }
+}
+
+void common_hal_displayio_i2cdisplay_end_transaction(mp_obj_t obj) {
+ displayio_i2cdisplay_obj_t* self = MP_OBJ_TO_PTR(obj);
+ common_hal_busio_i2c_unlock(self->bus);
+}
diff --git a/shared-module/displayio/I2CDisplay.h b/shared-module/displayio/I2CDisplay.h
new file mode 100644
index 000000000..4636c3f73
--- /dev/null
+++ b/shared-module/displayio/I2CDisplay.h
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_I2CDISPLAY_H
+#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_I2CDISPLAY_H
+
+#include "common-hal/busio/I2C.h"
+#include "common-hal/digitalio/DigitalInOut.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ busio_i2c_obj_t* bus;
+ busio_i2c_obj_t inline_bus;
+ digitalio_digitalinout_obj_t reset;
+ uint16_t address;
+} displayio_i2cdisplay_obj_t;
+
+#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_I2CDISPLAY_H
diff --git a/shared-module/displayio/Palette.c b/shared-module/displayio/Palette.c
index e810be875..444151b3c 100644
--- a/shared-module/displayio/Palette.c
+++ b/shared-module/displayio/Palette.c
@@ -26,45 +26,49 @@
#include "shared-bindings/displayio/Palette.h"
+#include "shared-module/displayio/ColorConverter.h"
+
void common_hal_displayio_palette_construct(displayio_palette_t* self, uint16_t color_count) {
self->color_count = color_count;
- self->colors = (uint32_t *) m_malloc(color_count * sizeof(uint16_t), false);
- uint32_t opaque_byte_count = color_count / 8;
- if (color_count % 8 > 0) {
- opaque_byte_count += 1;
- }
- self->opaque = (uint32_t *) m_malloc(opaque_byte_count, false);
+ self->colors = (_displayio_color_t *) m_malloc(color_count * sizeof(_displayio_color_t), false);
}
void common_hal_displayio_palette_make_opaque(displayio_palette_t* self, uint32_t palette_index) {
- self->opaque[palette_index / 32] &= ~(0x1 << (palette_index % 32));
+ self->colors[palette_index].transparent = false;
}
void common_hal_displayio_palette_make_transparent(displayio_palette_t* self, uint32_t palette_index) {
- self->opaque[palette_index / 32] |= (0x1 << (palette_index % 32));
+ self->colors[palette_index].transparent = true;
+}
+
+uint32_t common_hal_displayio_palette_get_len(displayio_palette_t* self) {
+ return self->color_count;
}
void common_hal_displayio_palette_set_color(displayio_palette_t* self, uint32_t palette_index, uint32_t color) {
- uint32_t shift = (palette_index % 2) * 16;
- uint32_t masked = self->colors[palette_index / 2] & ~(0xffff << shift);
- uint32_t r5 = (color >> 19);
- uint32_t g6 = (color >> 10) & 0x3f;
- uint32_t b5 = (color >> 3) & 0x1f;
- uint32_t packed = r5 << 11 | g6 << 5 | b5;
- // swap bytes
- packed = __builtin_bswap16(packed);
- self->colors[palette_index / 2] = masked | packed << shift;
+ if (self->colors[palette_index].rgb888 == color) {
+ return;
+ }
+ self->colors[palette_index].rgb888 = color;
+ self->colors[palette_index].luma = displayio_colorconverter_compute_luma(color);
+ self->colors[palette_index].rgb565 = displayio_colorconverter_compute_rgb565(color);
self->needs_refresh = true;
}
-bool displayio_palette_get_color(displayio_palette_t *self, uint32_t palette_index, uint16_t* color) {
- if (palette_index > self->color_count) {
- return false;
+uint32_t common_hal_displayio_palette_get_color(displayio_palette_t* self, uint32_t palette_index) {
+ return self->colors[palette_index].rgb888;
+}
+
+bool displayio_palette_get_color(displayio_palette_t *self, const _displayio_colorspace_t* colorspace, uint32_t palette_index, uint32_t* color) {
+ if (palette_index > self->color_count || self->colors[palette_index].transparent) {
+ return false; // returns opaque
}
- if ((self->opaque[palette_index / 32] & (0x1 << (palette_index % 32))) != 0) {
- return false;
+
+ if (colorspace->grayscale) {
+ *color = self->colors[palette_index].luma >> (8 - colorspace->depth);
+ } else {
+ *color = self->colors[palette_index].rgb565;
}
- *color = (self->colors[palette_index / 2] >> (16 * (palette_index % 2))) & 0xffff;
return true;
}
diff --git a/shared-module/displayio/Palette.h b/shared-module/displayio/Palette.h
index 3813e8bdd..a917e2432 100644
--- a/shared-module/displayio/Palette.h
+++ b/shared-module/displayio/Palette.h
@@ -33,14 +33,31 @@
#include "py/obj.h"
typedef struct {
+ uint8_t depth;
+ bool grayscale;
+ bool pixels_in_byte_share_row;
+ uint8_t bytes_per_cell;
+ bool reverse_pixels_in_byte;
+ uint8_t hue;
+} _displayio_colorspace_t;
+
+typedef struct {
+ uint32_t rgb888;
+ uint16_t rgb565;
+ uint8_t luma;
+ bool transparent; // This may have additional bits added later for blending.
+} _displayio_color_t;
+
+typedef struct {
mp_obj_base_t base;
- uint32_t* opaque;
- uint32_t* colors;
+ _displayio_color_t* colors;
uint32_t color_count;
bool needs_refresh;
} displayio_palette_t;
-bool displayio_palette_get_color(displayio_palette_t *palette, uint32_t palette_index, uint16_t* color);
+// Returns false if color fetch did not succeed (out of range or transparent).
+// Returns true if color is opaque, and sets color.
+bool displayio_palette_get_color(displayio_palette_t *palette, const _displayio_colorspace_t* colorspace, uint32_t palette_index, uint32_t* color);
bool displayio_palette_needs_refresh(displayio_palette_t *self);
void displayio_palette_finish_refresh(displayio_palette_t *self);
diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c
index 3212dfe8b..6144f8f99 100644
--- a/shared-module/displayio/TileGrid.c
+++ b/shared-module/displayio/TileGrid.c
@@ -26,6 +26,7 @@
#include "shared-bindings/displayio/TileGrid.h"
+#include "py/runtime.h"
#include "shared-bindings/displayio/Bitmap.h"
#include "shared-bindings/displayio/ColorConverter.h"
#include "shared-bindings/displayio/OnDiskBitmap.h"
@@ -33,7 +34,7 @@
#include "shared-bindings/displayio/Shape.h"
void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_t bitmap,
- uint16_t bitmap_width_in_tiles,
+ uint16_t bitmap_width_in_tiles, uint16_t bitmap_height_in_tiles,
mp_obj_t pixel_shader, uint16_t width, uint16_t height,
uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint8_t default_tile) {
uint32_t total_tiles = width * height;
@@ -54,33 +55,126 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_
self->inline_tiles = false;
}
self->bitmap_width_in_tiles = bitmap_width_in_tiles;
+ self->tiles_in_bitmap = bitmap_width_in_tiles * bitmap_height_in_tiles;
self->width_in_tiles = width;
self->height_in_tiles = height;
- self->total_width = width * tile_width;
- self->total_height = height * tile_height;
+ self->x = x;
+ self->y = y;
+ self->pixel_width = width * tile_width;
+ self->pixel_height = height * tile_height;
self->tile_width = tile_width;
self->tile_height = tile_height;
self->bitmap = bitmap;
self->pixel_shader = pixel_shader;
- self->x = x;
- self->y = y;
+ self->in_group = false;
+ self->first_draw = true;
+ self->flip_x = false;
+ self->flip_y = false;
+ self->transpose_xy = false;
+}
+
+bool displayio_tilegrid_get_previous_area(displayio_tilegrid_t *self, displayio_area_t* area) {
+ if (self->first_draw) {
+ return false;
+ }
+ displayio_area_copy(&self->previous_area, area);
+ return true;
}
+void _update_current_x(displayio_tilegrid_t *self) {
+ int16_t width;
+ if (self->transpose_xy) {
+ width = self->pixel_height;
+ } else {
+ width = self->pixel_width;
+ }
+ if (self->absolute_transform->transpose_xy) {
+ self->current_area.y1 = self->absolute_transform->y + self->absolute_transform->dy * self->x;
+ self->current_area.y2 = self->absolute_transform->y + self->absolute_transform->dy * (self->x + width);
+ if (self->current_area.y2 < self->current_area.y1) {
+ int16_t temp = self->current_area.y2;
+ self->current_area.y2 = self->current_area.y1;
+ self->current_area.y1 = temp;
+ }
+ } else {
+ self->current_area.x1 = self->absolute_transform->x + self->absolute_transform->dx * self->x;
+ self->current_area.x2 = self->absolute_transform->x + self->absolute_transform->dx * (self->x + width);
+ if (self->current_area.x2 < self->current_area.x1) {
+ int16_t temp = self->current_area.x2;
+ self->current_area.x2 = self->current_area.x1;
+ self->current_area.x1 = temp;
+ }
+ }
+}
+
+void _update_current_y(displayio_tilegrid_t *self) {
+ int16_t height;
+ if (self->transpose_xy) {
+ height = self->pixel_width;
+ } else {
+ height = self->pixel_height;
+ }
+ if (self->absolute_transform->transpose_xy) {
+ self->current_area.x1 = self->absolute_transform->x + self->absolute_transform->dx * self->y;
+ self->current_area.x2 = self->absolute_transform->x + self->absolute_transform->dx * (self->y + height);
+ if (self->current_area.x2 < self->current_area.x1) {
+ int16_t temp = self->current_area.x2;
+ self->current_area.x2 = self->current_area.x1;
+ self->current_area.x1 = temp;
+ }
+ } else {
+ self->current_area.y1 = self->absolute_transform->y + self->absolute_transform->dy * self->y;
+ self->current_area.y2 = self->absolute_transform->y + self->absolute_transform->dy * (self->y + height);
+ if (self->current_area.y2 < self->current_area.y1) {
+ int16_t temp = self->current_area.y2;
+ self->current_area.y2 = self->current_area.y1;
+ self->current_area.y1 = temp;
+ }
+ }
+}
+
+void displayio_tilegrid_update_transform(displayio_tilegrid_t *self,
+ const displayio_buffer_transform_t* absolute_transform) {
+ self->in_group = absolute_transform != NULL;
+ self->absolute_transform = absolute_transform;
+ if (absolute_transform != NULL) {
+ self->moved = !self->first_draw;
+
+ _update_current_x(self);
+ _update_current_y(self);
+ } else {
+ self->first_draw = true;
+ }
+}
mp_int_t common_hal_displayio_tilegrid_get_x(displayio_tilegrid_t *self) {
return self->x;
}
void common_hal_displayio_tilegrid_set_x(displayio_tilegrid_t *self, mp_int_t x) {
- self->needs_refresh = self->x != x;
+ if (self->x == x) {
+ return;
+ }
+
+ self->moved = !self->first_draw;
+
self->x = x;
+ if (self->absolute_transform != NULL) {
+ _update_current_x(self);
+ }
}
mp_int_t common_hal_displayio_tilegrid_get_y(displayio_tilegrid_t *self) {
return self->y;
}
void common_hal_displayio_tilegrid_set_y(displayio_tilegrid_t *self, mp_int_t y) {
- self->needs_refresh = self->y != y;
+ if (self->y == y) {
+ return;
+ }
+ self->moved = !self->first_draw;
self->y = y;
+ if (self->absolute_transform != NULL) {
+ _update_current_y(self);
+ }
}
mp_obj_t common_hal_displayio_tilegrid_get_pixel_shader(displayio_tilegrid_t *self) {
@@ -89,10 +183,9 @@ mp_obj_t common_hal_displayio_tilegrid_get_pixel_shader(displayio_tilegrid_t *se
void common_hal_displayio_tilegrid_set_pixel_shader(displayio_tilegrid_t *self, mp_obj_t pixel_shader) {
self->pixel_shader = pixel_shader;
- self->needs_refresh = true;
+ self->full_change = true;
}
-
uint16_t common_hal_displayio_tilegrid_get_width(displayio_tilegrid_t *self) {
return self->width_in_tiles;
}
@@ -113,6 +206,9 @@ uint8_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint1
}
void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index) {
+ if (tile_index >= self->tiles_in_bitmap) {
+ mp_raise_ValueError(translate("Tile value out of bounds"));
+ }
uint8_t* tiles = self->tiles;
if (self->inline_tiles) {
tiles = (uint8_t*) &self->tiles;
@@ -121,21 +217,87 @@ void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t
return;
}
tiles[y * self->width_in_tiles + x] = tile_index;
- self->needs_refresh = true;
+ displayio_area_t temp_area;
+ displayio_area_t* tile_area;
+ if (!self->partial_change) {
+ tile_area = &self->dirty_area;
+ } else {
+ tile_area = &temp_area;
+ }
+ int16_t tx = (x - self->top_left_x) % self->width_in_tiles;
+ if (tx < 0) {
+ tx += self->width_in_tiles;
+ }
+ tile_area->x1 = tx * self->tile_width;
+ tile_area->x2 = tile_area->x1 + self->tile_width;
+ int16_t ty = (y - self->top_left_y) % self->height_in_tiles;
+ if (ty < 0) {
+ ty += self->height_in_tiles;
+ }
+ tile_area->y1 = ty * self->tile_height;
+ tile_area->y2 = tile_area->y1 + self->tile_height;
+
+ if (self->partial_change) {
+ displayio_area_expand(&self->dirty_area, &temp_area);
+ }
+
+ self->partial_change = true;
+}
+
+bool common_hal_displayio_tilegrid_get_flip_x(displayio_tilegrid_t *self) {
+ return self->flip_x;
+}
+
+void common_hal_displayio_tilegrid_set_flip_x(displayio_tilegrid_t *self, bool flip_x) {
+ if (self->flip_x == flip_x) {
+ return;
+ }
+ self->flip_x = flip_x;
+ self->full_change = true;
}
+bool common_hal_displayio_tilegrid_get_flip_y(displayio_tilegrid_t *self) {
+ return self->flip_y;
+}
+
+void common_hal_displayio_tilegrid_set_flip_y(displayio_tilegrid_t *self, bool flip_y) {
+ if (self->flip_y == flip_y) {
+ return;
+ }
+ self->flip_y = flip_y;
+ self->full_change = true;
+}
+
+bool common_hal_displayio_tilegrid_get_transpose_xy(displayio_tilegrid_t *self) {
+ return self->transpose_xy;
+}
+
+void common_hal_displayio_tilegrid_set_transpose_xy(displayio_tilegrid_t *self, bool transpose_xy) {
+ if (self->transpose_xy == transpose_xy) {
+ return;
+ }
+ self->transpose_xy = transpose_xy;
+
+ // Square TileGrids do not change dimensions when transposed.
+ if (self->pixel_width == self->pixel_height) {
+ self->full_change = true;
+ return;
+ }
+
+ _update_current_x(self);
+ _update_current_y(self);
+
+ self->moved = true;
+}
void common_hal_displayio_tilegrid_set_top_left(displayio_tilegrid_t *self, uint16_t x, uint16_t y) {
self->top_left_x = x;
self->top_left_y = y;
+ self->full_change = true;
}
-bool displayio_tilegrid_get_pixel(displayio_tilegrid_t *self, int16_t x, int16_t y, uint16_t* pixel) {
- x -= self->x;
- y -= self->y;
- if (y < 0 || y >= self->total_height || x >= self->total_width || x < 0) {
- return false;
- }
+bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const _displayio_colorspace_t* colorspace, const displayio_area_t* area, uint32_t* mask, uint32_t *buffer) {
+ // If no tiles are present we have no impact.
uint8_t* tiles = self->tiles;
if (self->inline_tiles) {
tiles = (uint8_t*) &self->tiles;
@@ -143,51 +305,244 @@ bool displayio_tilegrid_get_pixel(displayio_tilegrid_t *self, int16_t x, int16_t
if (tiles == NULL) {
return false;
}
- uint16_t tile_location = ((y / self->tile_height + self->top_left_y) % self->height_in_tiles) * self->width_in_tiles + (x / self->tile_width + self->top_left_x) % self->width_in_tiles;
- uint8_t tile = tiles[tile_location];
- uint16_t tile_x = tile_x = (tile % self->bitmap_width_in_tiles) * self->tile_width + x % self->tile_width;
- uint16_t tile_y = tile_y = (tile / self->bitmap_width_in_tiles) * self->tile_height + y % self->tile_height;
- uint32_t value = 0;
- if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) {
- value = common_hal_displayio_bitmap_get_pixel(self->bitmap, tile_x, tile_y);
- } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) {
- value = common_hal_displayio_shape_get_pixel(self->bitmap, tile_x, tile_y);
- } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) {
- value = common_hal_displayio_ondiskbitmap_get_pixel(self->bitmap, tile_x, tile_y);
+ displayio_area_t overlap;
+ if (!displayio_area_compute_overlap(area, &self->current_area, &overlap)) {
+ return false;
}
- if (self->pixel_shader == mp_const_none) {
- *pixel = value;
- return true;
- } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type) && displayio_palette_get_color(self->pixel_shader, value, pixel)) {
- return true;
- } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type) && common_hal_displayio_colorconverter_convert(self->pixel_shader, value, pixel)) {
- return true;
+ int16_t x_stride = 1;
+ int16_t y_stride = displayio_area_width(area);
+
+ bool flip_x = self->flip_x;
+ bool flip_y = self->flip_y;
+ if (self->transpose_xy != self->absolute_transform->transpose_xy) {
+ bool temp_flip = flip_x;
+ flip_x = flip_y;
+ flip_y = temp_flip;
}
- return false;
-}
+ // How many pixels are outside of our area between us and the start of the row.
+ uint16_t start = 0;
+ if ((self->absolute_transform->dx < 0) != flip_x) {
+ start += (area->x2 - area->x1 - 1) * x_stride;
+ x_stride *= -1;
+ }
+ if ((self->absolute_transform->dy < 0) != flip_y) {
+ start += (area->y2 - area->y1 - 1) * y_stride;
+ y_stride *= -1;
+ }
-bool displayio_tilegrid_needs_refresh(displayio_tilegrid_t *self) {
- if (self->needs_refresh) {
- return true;
- } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) {
- return displayio_palette_needs_refresh(self->pixel_shader);
- } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) {
- return displayio_colorconverter_needs_refresh(self->pixel_shader);
+ // Track if this layer finishes filling in the given area. We can ignore any remaining
+ // layers at that point.
+ bool full_coverage = displayio_area_equal(area, &overlap);
+
+ // TODO(tannewt): Skip coverage tracking if all pixels outside the overlap have already been
+ // set and our palette is all opaque.
+
+ // TODO(tannewt): Check to see if the pixel_shader has any transparency. If it doesn't then we
+ // can either return full coverage or bulk update the mask.
+ displayio_area_t transformed;
+ displayio_area_transform_within(flip_x != (self->absolute_transform->dx < 0), flip_y != (self->absolute_transform->dy < 0), self->transpose_xy != self->absolute_transform->transpose_xy,
+ &overlap,
+ &self->current_area,
+ &transformed);
+
+ int16_t start_x = (transformed.x1 - self->current_area.x1);
+ int16_t end_x = (transformed.x2 - self->current_area.x1);
+ int16_t start_y = (transformed.y1 - self->current_area.y1);
+ int16_t end_y = (transformed.y2 - self->current_area.y1);
+
+ int16_t y_shift = 0;
+ int16_t x_shift = 0;
+ if ((self->absolute_transform->dx < 0) != flip_x) {
+ x_shift = area->x2 - overlap.x2;
+ } else {
+ x_shift = overlap.x1 - area->x1;
+ }
+ if ((self->absolute_transform->dy < 0) != flip_y) {
+ y_shift = area->y2 - overlap.y2;
+ } else {
+ y_shift = overlap.y1 - area->y1;
+ }
+
+ // This untransposes x and y so it aligns with bitmap rows.
+ if (self->transpose_xy != self->absolute_transform->transpose_xy) {
+ int16_t temp_stride = x_stride;
+ x_stride = y_stride;
+ y_stride = temp_stride;
+ int16_t temp_shift = x_shift;
+ x_shift = y_shift;
+ y_shift = temp_shift;
}
- return false;
+ uint8_t pixels_per_byte = 8 / colorspace->depth;
+ for (int16_t y = start_y; y < end_y; y++) {
+ int16_t row_start = start + (y - start_y + y_shift) * y_stride; // in pixels
+ int16_t local_y = y / self->absolute_transform->scale;
+ for (int16_t x = start_x; x < end_x; x++) {
+ // Compute the destination pixel in the buffer and mask based on the transformations.
+ int16_t offset = row_start + (x - start_x + x_shift) * x_stride; // in pixels
+
+ // This is super useful for debugging out of range accesses. Uncomment to use.
+ // if (offset < 0 || offset >= (int32_t) displayio_area_size(area)) {
+ // asm("bkpt");
+ // }
+
+ // Check the mask first to see if the pixel has already been set.
+ if ((mask[offset / 32] & (1 << (offset % 32))) != 0) {
+ continue;
+ }
+ int16_t local_x = x / self->absolute_transform->scale;
+ uint16_t tile_location = ((local_y / self->tile_height + self->top_left_y) % self->height_in_tiles) * self->width_in_tiles + (local_x / self->tile_width + self->top_left_x) % self->width_in_tiles;
+ uint8_t tile = tiles[tile_location];
+ uint16_t tile_x = (tile % self->bitmap_width_in_tiles) * self->tile_width + local_x % self->tile_width;
+ uint16_t tile_y = (tile / self->bitmap_width_in_tiles) * self->tile_height + local_y % self->tile_height;
+
+ uint32_t value = 0;
+ // We always want to read bitmap pixels by row first and then transpose into the destination
+ // buffer because most bitmaps are row associated.
+ if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) {
+ value = common_hal_displayio_bitmap_get_pixel(self->bitmap, tile_x, tile_y);
+ } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) {
+ value = common_hal_displayio_shape_get_pixel(self->bitmap, tile_x, tile_y);
+ } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) {
+ value = common_hal_displayio_ondiskbitmap_get_pixel(self->bitmap, tile_x, tile_y);
+ }
+
+ uint32_t pixel;
+ bool opaque = true;
+ if (self->pixel_shader == mp_const_none) {
+ pixel = value;
+ } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) {
+ opaque = displayio_palette_get_color(self->pixel_shader, colorspace, value, &pixel);
+ } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) {
+ opaque = displayio_colorconverter_convert(self->pixel_shader, colorspace, value, &pixel);
+ }
+ if (!opaque) {
+ // A pixel is transparent so we haven't fully covered the area ourselves.
+ full_coverage = false;
+ } else {
+ mask[offset / 32] |= 1 << (offset % 32);
+ if (colorspace->depth == 16) {
+ *(((uint16_t*) buffer) + offset) = pixel;
+ } else if (colorspace->depth == 8) {
+ *(((uint8_t*) buffer) + offset) = pixel;
+ } else if (colorspace->depth < 8) {
+ // Reorder the offsets to pack multiple rows into a byte (meaning they share a column).
+ if (!colorspace->pixels_in_byte_share_row) {
+ uint16_t width = displayio_area_width(area);
+ uint16_t row = offset / width;
+ uint16_t col = offset % width;
+ // Dividing by pixels_per_byte does truncated division even if we multiply it back out.
+ offset = col * pixels_per_byte + (row / pixels_per_byte) * pixels_per_byte * width + row % pixels_per_byte;
+ // Also useful for validating that the bitpacking worked correctly.
+ // if (offset > displayio_area_size(area)) {
+ // asm("bkpt");
+ // }
+ }
+ uint8_t shift = (offset % pixels_per_byte) * colorspace->depth;
+ if (colorspace->reverse_pixels_in_byte) {
+ shift = (pixels_per_byte - 1) * colorspace->depth - shift;
+ }
+ ((uint8_t*)buffer)[offset / pixels_per_byte] |= pixel << shift;
+ }
+ }
+ }
+ }
+ return full_coverage;
}
void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self) {
- self->needs_refresh = false;
+ if (self->moved || self->first_draw) {
+ displayio_area_copy(&self->current_area, &self->previous_area);
+ }
+
+ self->moved = false;
+ self->full_change = false;
+ self->partial_change = false;
+ self->first_draw = false;
if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) {
displayio_palette_finish_refresh(self->pixel_shader);
} else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) {
displayio_colorconverter_finish_refresh(self->pixel_shader);
}
+ if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) {
+ displayio_bitmap_finish_refresh(self->bitmap);
+ } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) {
+ // TODO: Support shape changes.
+ } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) {
+ // OnDiskBitmap changes will trigger a complete reload so no need to
+ // track changes.
+ }
// TODO(tannewt): We could double buffer changes to position and move them over here.
// That way they won't change during a refresh and tear.
}
+
+displayio_area_t* displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *self, displayio_area_t* tail) {
+ if (self->moved && !self->first_draw) {
+ displayio_area_union(&self->previous_area, &self->current_area, &self->dirty_area);
+ if (displayio_area_size(&self->dirty_area) <= 2U * self->pixel_width * self->pixel_height) {
+ self->dirty_area.next = tail;
+ return &self->dirty_area;
+ }
+ self->previous_area.next = tail;
+ self->current_area.next = &self->previous_area;
+ return &self->current_area;
+ }
+
+ // If we have an in-memory bitmap, then check it for modifications.
+ if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) {
+ displayio_area_t* refresh_area = displayio_bitmap_get_refresh_areas(self->bitmap, tail);
+ if (refresh_area != tail) {
+ // Special case a TileGrid that shows a full bitmap and use its
+ // dirty area. Copy it to ours so we can transform it.
+ if (self->tiles_in_bitmap == 1) {
+ displayio_area_copy(refresh_area, &self->dirty_area);
+ self->partial_change = true;
+ } else {
+ self->full_change = true;
+ }
+ }
+ }
+
+ self->full_change = self->full_change ||
+ (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type) &&
+ displayio_palette_needs_refresh(self->pixel_shader)) ||
+ (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type) &&
+ displayio_colorconverter_needs_refresh(self->pixel_shader));
+ if (self->full_change || self->first_draw) {
+ self->current_area.next = tail;
+ return &self->current_area;
+ }
+
+ if (self->partial_change) {
+ if (self->absolute_transform->transpose_xy) {
+ int16_t x1 = self->dirty_area.x1;
+ self->dirty_area.x1 = self->absolute_transform->x + self->absolute_transform->dx * (self->y + self->dirty_area.y1);
+ self->dirty_area.y1 = self->absolute_transform->y + self->absolute_transform->dy * (self->x + x1);
+ int16_t x2 = self->dirty_area.x2;
+ self->dirty_area.x2 = self->absolute_transform->x + self->absolute_transform->dx * (self->y + self->dirty_area.y2);
+ self->dirty_area.y2 = self->absolute_transform->y + self->absolute_transform->dy * (self->x + x2);
+ } else {
+ self->dirty_area.x1 = self->absolute_transform->x + self->absolute_transform->dx * (self->x + self->dirty_area.x1);
+ self->dirty_area.y1 = self->absolute_transform->y + self->absolute_transform->dy * (self->y + self->dirty_area.y1);
+ self->dirty_area.x2 = self->absolute_transform->x + self->absolute_transform->dx * (self->x + self->dirty_area.x2);
+ self->dirty_area.y2 = self->absolute_transform->y + self->absolute_transform->dy * (self->y + self->dirty_area.y2);
+ }
+ if (self->dirty_area.y2 < self->dirty_area.y1) {
+ int16_t temp = self->dirty_area.y2;
+ self->dirty_area.y2 = self->dirty_area.y1;
+ self->dirty_area.y1 = temp;
+ }
+ if (self->dirty_area.x2 < self->dirty_area.x1) {
+ int16_t temp = self->dirty_area.x2;
+ self->dirty_area.x2 = self->dirty_area.x1;
+ self->dirty_area.x1 = temp;
+ }
+
+ self->dirty_area.next = tail;
+ return &self->dirty_area;
+ }
+ return tail;
+}
diff --git a/shared-module/displayio/TileGrid.h b/shared-module/displayio/TileGrid.h
index 59645553d..222aaed19 100644
--- a/shared-module/displayio/TileGrid.h
+++ b/shared-module/displayio/TileGrid.h
@@ -31,29 +31,54 @@
#include <stdint.h>
#include "py/obj.h"
+#include "shared-module/displayio/area.h"
+#include "shared-module/displayio/Palette.h"
typedef struct {
mp_obj_base_t base;
mp_obj_t bitmap;
mp_obj_t pixel_shader;
- uint16_t x;
- uint16_t y;
- uint16_t bitmap_width_in_tiles;
+ int16_t x;
+ int16_t y;
+ uint16_t pixel_width;
+ uint16_t pixel_height;
+ uint16_t bitmap_width_in_tiles;;
+ uint8_t tiles_in_bitmap;
uint16_t width_in_tiles;
uint16_t height_in_tiles;
- uint16_t total_width;
- uint16_t total_height;
uint16_t tile_width;
uint16_t tile_height;
uint16_t top_left_x;
uint16_t top_left_y;
uint8_t* tiles;
- bool needs_refresh;
+ const displayio_buffer_transform_t* absolute_transform;
+ displayio_area_t dirty_area; // Stored as a relative area until the refresh area is fetched.
+ displayio_area_t previous_area; // Stored as an absolute area.
+ displayio_area_t current_area; // Stored as an absolute area so it applies across frames.
+ bool partial_change;
+ bool full_change;
+ bool first_draw;
+ bool moved;
bool inline_tiles;
+ bool in_group;
+ bool flip_x;
+ bool flip_y;
+ bool transpose_xy;
} displayio_tilegrid_t;
-bool displayio_tilegrid_get_pixel(displayio_tilegrid_t *self, int16_t x, int16_t y, uint16_t *pixel);
-bool displayio_tilegrid_needs_refresh(displayio_tilegrid_t *self);
+// Updating the screen is a three stage process.
+
+// The first stage is used to determine i
+displayio_area_t* displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *self, displayio_area_t* tail);
+
+// Area is always in absolute screen coordinates. Update transform is used to inform TileGrids how
+// they relate to it.
+bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const _displayio_colorspace_t* colorspace, const displayio_area_t* area, uint32_t* mask, uint32_t *buffer);
+void displayio_tilegrid_update_transform(displayio_tilegrid_t *group, const displayio_buffer_transform_t* parent_transform);
+
+// Fills in area with the maximum bounds of all related pixels in the last rendered frame. Returns
+// false if the tilegrid wasn't rendered in the last frame.
+bool displayio_tilegrid_get_previous_area(displayio_tilegrid_t *self, displayio_area_t* area);
void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self);
#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_TILEGRID_H
diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index 156640440..8f6e650a1 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -1,8 +1,10 @@
#include <string.h>
+
#include "shared-module/displayio/__init__.h"
#include "lib/utils/interrupt_char.h"
+#include "py/gc.h"
#include "py/reload.h"
#include "py/runtime.h"
#include "shared-bindings/board/__init__.h"
@@ -10,17 +12,101 @@
#include "shared-bindings/displayio/Display.h"
#include "shared-bindings/displayio/Group.h"
#include "shared-bindings/displayio/Palette.h"
+#include "shared-module/displayio/area.h"
#include "supervisor/shared/autoreload.h"
#include "supervisor/shared/display.h"
#include "supervisor/memory.h"
#include "supervisor/usb.h"
primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT];
+uint32_t frame_count = 0;
+
+bool refresh_area(displayio_display_obj_t* display, const displayio_area_t* area) {
+ uint16_t buffer_size = 128; // In uint32_ts
+
+ displayio_area_t clipped;
+ // Clip the area to the display by overlapping the areas. If there is no overlap then we're done.
+ if (!displayio_display_clip_area(display, area, &clipped)) {
+ return true;
+ }
+ uint16_t subrectangles = 1;
+ uint16_t rows_per_buffer = displayio_area_height(&clipped);
+ uint8_t pixels_per_word = (sizeof(uint32_t) * 8) / display->colorspace.depth;
+ uint16_t pixels_per_buffer = displayio_area_size(&clipped);
+ if (displayio_area_size(&clipped) > buffer_size * pixels_per_word) {
+ rows_per_buffer = buffer_size * pixels_per_word / displayio_area_width(&clipped);
+ if (rows_per_buffer == 0) {
+ rows_per_buffer = 1;
+ }
+ // If pixels are packed by column then ensure rows_per_buffer is on a byte boundary.
+ if (display->colorspace.depth < 8 && !display->colorspace.pixels_in_byte_share_row) {
+ uint8_t pixels_per_byte = 8 / display->colorspace.depth;
+ if (rows_per_buffer % pixels_per_byte != 0) {
+ rows_per_buffer -= rows_per_buffer % pixels_per_byte;
+ }
+ }
+ subrectangles = displayio_area_height(&clipped) / rows_per_buffer;
+ if (displayio_area_height(&clipped) % rows_per_buffer != 0) {
+ subrectangles++;
+ }
+ pixels_per_buffer = rows_per_buffer * displayio_area_width(&clipped);
+ buffer_size = pixels_per_buffer / pixels_per_word;
+ if (pixels_per_buffer % pixels_per_word) {
+ buffer_size += 1;
+ }
+ }
+
+ // Allocated and shared as a uint32_t array so the compiler knows the
+ // alignment everywhere.
+ uint32_t buffer[buffer_size];
+ volatile uint32_t mask_length = (pixels_per_buffer / 32) + 1;
+ uint32_t mask[mask_length];
+ uint16_t remaining_rows = displayio_area_height(&clipped);
+
+ for (uint16_t j = 0; j < subrectangles; j++) {
+ displayio_area_t subrectangle = {
+ .x1 = clipped.x1,
+ .y1 = clipped.y1 + rows_per_buffer * j,
+ .x2 = clipped.x2,
+ .y2 = clipped.y1 + rows_per_buffer * (j + 1)
+ };
+ if (remaining_rows < rows_per_buffer) {
+ subrectangle.y2 = subrectangle.y1 + remaining_rows;
+ }
+ remaining_rows -= rows_per_buffer;
-static inline void swap(uint16_t* a, uint16_t* b) {
- uint16_t temp = *a;
- *a = *b;
- *b = temp;
+ displayio_display_begin_transaction(display);
+ displayio_display_set_region_to_update(display, &subrectangle);
+ displayio_display_end_transaction(display);
+
+ uint16_t subrectangle_size_bytes;
+ if (display->colorspace.depth >= 8) {
+ subrectangle_size_bytes = displayio_area_size(&subrectangle) * (display->colorspace.depth / 8);
+ } else {
+ subrectangle_size_bytes = displayio_area_size(&subrectangle) / (8 / display->colorspace.depth);
+ }
+
+ for (uint16_t k = 0; k < mask_length; k++) {
+ mask[k] = 0x00000000;
+ }
+ for (uint16_t k = 0; k < buffer_size; k++) {
+ buffer[k] = 0x00000000;
+ }
+
+ displayio_display_fill_area(display, &subrectangle, mask, buffer);
+
+ if (!displayio_display_begin_transaction(display)) {
+ // Can't acquire display bus; skip the rest of the data. Try next display.
+ return false;
+ }
+ displayio_display_send_pixels(display, (uint8_t*) buffer, subrectangle_size_bytes);
+ displayio_display_end_transaction(display);
+
+ // TODO(tannewt): Make refresh displays faster so we don't starve other
+ // background tasks.
+ usb_background();
+ }
+ return true;
}
// Check for recursive calls to displayio_refresh_displays.
@@ -55,105 +141,19 @@ void displayio_refresh_displays(void) {
// Too soon. Try next display.
continue;
}
- if (displayio_display_refresh_queued(display)) {
- // We compute the pixels. r and c are row and column to match the display memory
- // structure. x and y match location within the groups.
- uint16_t c0 = 0;
- uint16_t r0 = 0;
- uint16_t c1 = display->width;
- uint16_t r1 = display->height;
- if (display->transpose_xy) {
- swap(&c1, &r1);
- }
-
- if (!displayio_display_begin_transaction(display)) {
- // Can't acquire display bus; skip updating this display. Try next display.
- continue;
- }
- displayio_display_set_region_to_update(display, c0, r0, c1, r1);
- displayio_display_end_transaction(display);
-
- uint16_t x0 = 0;
- uint16_t x1 = display->width - 1;
- uint16_t startx = 0;
- int8_t dx = 1;
- if (display->mirror_x) {
- dx = -1;
- startx = x1;
- }
- uint16_t y0 = 0;
- uint16_t y1 = display->height - 1;
- uint16_t starty = 0;
- int8_t dy = 1;
- if (display->mirror_y) {
- dy = -1;
- starty = y1;
- }
-
- bool transpose = false;
- if (display->transpose_xy) {
- transpose = true;
- int8_t temp_dx = dx;
- dx = dy;
- dy = temp_dx;
-
- swap(&starty, &startx);
- swap(&x0, &y0);
- swap(&x1, &y1);
- }
-
- size_t index = 0;
- uint16_t buffer_size = 256;
- uint32_t buffer[buffer_size / 2];
- bool skip_this_display = false;
-
- for (uint16_t y = starty; y0 <= y && y <= y1; y += dy) {
- for (uint16_t x = startx; x0 <= x && x <= x1; x += dx) {
- uint16_t* pixel = &(((uint16_t*)buffer)[index]);
- *pixel = 0;
-
- if (display->current_group != NULL) {
- if (transpose) {
- displayio_group_get_pixel(display->current_group, y, x, pixel);
- } else {
- displayio_group_get_pixel(display->current_group, x, y, pixel);
- }
- }
-
- index += 1;
- // The buffer is full, send it.
- if (index >= buffer_size) {
- if (!displayio_display_begin_transaction(display)) {
- // Can't acquire display bus; skip the rest of the data. Try next display.
- index = 0;
- skip_this_display = true;
- break;
- }
- displayio_display_send_pixels(display, buffer, buffer_size / 2);
- displayio_display_end_transaction(display);
- // TODO(tannewt): Make refresh displays faster so we don't starve other
- // background tasks.
- usb_background();
- index = 0;
- }
- }
- }
-
- if (skip_this_display) {
- // Go on to next display.
- continue;
- }
- // Send the remaining data.
- if (index) {
- if (!displayio_display_begin_transaction(display)) {
- // Can't get display bus. Skip the rest of the data. Try next display.
- continue;
- }
- displayio_display_send_pixels(display, buffer, index * 2);
- }
- displayio_display_end_transaction(display);
+ if (!displayio_display_begin_transaction(display)) {
+ // Can't acquire display bus; skip updating this display. Try next display.
+ continue;
+ }
+ displayio_display_end_transaction(display);
+ displayio_display_start_refresh(display);
+ const displayio_area_t* current_area = displayio_display_get_refresh_areas(display);
+ while (current_area != NULL) {
+ refresh_area(display, current_area);
+ current_area = current_area->next;
}
displayio_display_finish_refresh(display);
+ frame_count++;
}
// All done.
@@ -167,6 +167,8 @@ void common_hal_displayio_release_displays(void) {
continue;
} else if (bus_type == &displayio_fourwire_type) {
common_hal_displayio_fourwire_deinit(&displays[i].fourwire_bus);
+ } else if (bus_type == &displayio_i2cdisplay_type) {
+ common_hal_displayio_i2cdisplay_deinit(&displays[i].i2cdisplay_bus);
} else if (bus_type == &displayio_parallelbus_type) {
common_hal_displayio_parallelbus_deinit(&displays[i].parallel_bus);
}
@@ -181,42 +183,210 @@ void common_hal_displayio_release_displays(void) {
}
void reset_displays(void) {
- #if CIRCUITPY_DISPLAYIO
// The SPI buses used by FourWires may be allocated on the heap so we need to move them inline.
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
- if (displays[i].fourwire_bus.base.type != &displayio_fourwire_type) {
- continue;
- }
- displayio_fourwire_obj_t* fourwire = &displays[i].fourwire_bus;
- if (((uint32_t) fourwire->bus) < ((uint32_t) &displays) ||
- ((uint32_t) fourwire->bus) > ((uint32_t) &displays + CIRCUITPY_DISPLAY_LIMIT)) {
- busio_spi_obj_t* original_spi = fourwire->bus;
- #if BOARD_SPI
- // We don't need to move original_spi if it is the board.SPI object because it is
- // statically allocated already. (Doing so would also make it impossible to reference in
- // a subsequent VM run.)
- if (original_spi == common_hal_board_get_spi()) {
- continue;
+ if (displays[i].fourwire_bus.base.type == &displayio_fourwire_type) {
+ displayio_fourwire_obj_t* fourwire = &displays[i].fourwire_bus;
+ if (((uint32_t) fourwire->bus) < ((uint32_t) &displays) ||
+ ((uint32_t) fourwire->bus) > ((uint32_t) &displays + CIRCUITPY_DISPLAY_LIMIT)) {
+ busio_spi_obj_t* original_spi = fourwire->bus;
+ #if BOARD_SPI
+ // We don't need to move original_spi if it is the board.SPI object because it is
+ // statically allocated already. (Doing so would also make it impossible to reference in
+ // a subsequent VM run.)
+ if (original_spi == common_hal_board_get_spi()) {
+ continue;
+ }
+ #endif
+ memcpy(&fourwire->inline_bus, original_spi, sizeof(busio_spi_obj_t));
+ fourwire->bus = &fourwire->inline_bus;
+ // Check for other displays that use the same spi bus and swap them too.
+ for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) {
+ if (displays[i].fourwire_bus.base.type == &displayio_fourwire_type &&
+ displays[i].fourwire_bus.bus == original_spi) {
+ displays[i].fourwire_bus.bus = &fourwire->inline_bus;
+ }
}
- #endif
- memcpy(&fourwire->inline_bus, original_spi, sizeof(busio_spi_obj_t));
- fourwire->bus = &fourwire->inline_bus;
- // Check for other displays that use the same spi bus and swap them too.
- for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) {
- if (displays[i].fourwire_bus.bus == original_spi) {
- displays[i].fourwire_bus.bus = &fourwire->inline_bus;
+ }
+ } else if (displays[i].i2cdisplay_bus.base.type == &displayio_i2cdisplay_type) {
+ displayio_i2cdisplay_obj_t* i2c = &displays[i].i2cdisplay_bus;
+ if (((uint32_t) i2c->bus) < ((uint32_t) &displays) ||
+ ((uint32_t) i2c->bus) > ((uint32_t) &displays + CIRCUITPY_DISPLAY_LIMIT)) {
+ busio_i2c_obj_t* original_i2c = i2c->bus;
+ #if BOARD_I2C
+ // We don't need to move original_i2c if it is the board.SPI object because it is
+ // statically allocated already. (Doing so would also make it impossible to reference in
+ // a subsequent VM run.)
+ if (original_i2c == common_hal_board_get_i2c()) {
+ continue;
+ }
+ #endif
+ memcpy(&i2c->inline_bus, original_i2c, sizeof(busio_i2c_obj_t));
+ i2c->bus = &i2c->inline_bus;
+ // Check for other displays that use the same i2c bus and swap them too.
+ for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) {
+ if (displays[i].i2cdisplay_bus.base.type == &displayio_i2cdisplay_type &&
+ displays[i].i2cdisplay_bus.bus == original_i2c) {
+ displays[i].i2cdisplay_bus.bus = &i2c->inline_bus;
+ }
}
}
+ } else {
+ // Not an active display.
+ continue;
}
+
+ // Reset the displayed group. Only the first will get the terminal but
+ // that's ok.
+ displayio_display_obj_t* display = &displays[i].display;
+ display->auto_brightness = true;
+ common_hal_displayio_display_show(display, &circuitpython_splash);
}
+}
+void displayio_gc_collect(void) {
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
if (displays[i].display.base.type == NULL) {
continue;
}
- displayio_display_obj_t* display = &displays[i].display;
- display->auto_brightness = true;
- common_hal_displayio_display_show(display, &circuitpython_splash);
+
+ // Alternatively, we could use gc_collect_root over the whole object,
+ // but this is more precise, and is the only field that needs marking.
+ gc_collect_ptr(displays[i].display.current_group);
+
+ }
+}
+
+void displayio_area_expand(displayio_area_t* original, const displayio_area_t* addition) {
+ if (addition->x1 < original->x1) {
+ original->x1 = addition->x1;
+ }
+ if (addition->y1 < original->y1) {
+ original->y1 = addition->y1;
+ }
+ if (addition->x2 > original->x2) {
+ original->x2 = addition->x2;
+ }
+ if (addition->y2 > original->y2) {
+ original->y2 = addition->y2;
+ }
+}
+
+void displayio_area_copy(const displayio_area_t* src, displayio_area_t* dst) {
+ dst->x1 = src->x1;
+ dst->y1 = src->y1;
+ dst->x2 = src->x2;
+ dst->y2 = src->y2;
+}
+
+void displayio_area_scale(displayio_area_t* area, uint16_t scale) {
+ area->x1 *= scale;
+ area->y1 *= scale;
+ area->x2 *= scale;
+ area->y2 *= scale;
+}
+
+void displayio_area_shift(displayio_area_t* area, int16_t dx, int16_t dy) {
+ area->x1 += dx;
+ area->y1 += dy;
+ area->x2 += dx;
+ area->y2 += dy;
+}
+
+bool displayio_area_compute_overlap(const displayio_area_t* a,
+ const displayio_area_t* b,
+ displayio_area_t* overlap) {
+ overlap->x1 = a->x1;
+ if (b->x1 > overlap->x1) {
+ overlap->x1 = b->x1;
+ }
+ overlap->x2 = a->x2;
+ if (b->x2 < overlap->x2) {
+ overlap->x2 = b->x2;
+ }
+ if (overlap->x1 >= overlap->x2) {
+ return false;
+ }
+ overlap->y1 = a->y1;
+ if (b->y1 > overlap->y1) {
+ overlap->y1 = b->y1;
+ }
+ overlap->y2 = a->y2;
+ if (b->y2 < overlap->y2) {
+ overlap->y2 = b->y2;
+ }
+ if (overlap->y1 >= overlap->y2) {
+ return false;
+ }
+ return true;
+}
+
+void displayio_area_union(const displayio_area_t* a,
+ const displayio_area_t* b,
+ displayio_area_t* u) {
+ u->x1 = a->x1;
+ if (b->x1 < u->x1) {
+ u->x1 = b->x1;
+ }
+ u->x2 = a->x2;
+ if (b->x2 > u->x2) {
+ u->x2 = b->x2;
+ }
+
+ u->y1 = a->y1;
+ if (b->y1 < u->y1) {
+ u->y1 = b->y1;
+ }
+ u->y2 = a->y2;
+ if (b->y2 > u->y2) {
+ u->y2 = b->y2;
+ }
+}
+
+uint16_t displayio_area_width(const displayio_area_t* area) {
+ return area->x2 - area->x1;
+}
+
+uint16_t displayio_area_height(const displayio_area_t* area) {
+ return area->y2 - area->y1;
+}
+
+uint32_t displayio_area_size(const displayio_area_t* area) {
+ return displayio_area_width(area) * displayio_area_height(area);
+}
+
+bool displayio_area_equal(const displayio_area_t* a, const displayio_area_t* b) {
+ return a->x1 == b->x1 &&
+ a->y1 == b->y1 &&
+ a->x2 == b->x2 &&
+ a->y2 == b->y2;
+}
+
+// Original and whole must be in the same coordinate space.
+void displayio_area_transform_within(bool mirror_x, bool mirror_y, bool transpose_xy,
+ const displayio_area_t* original,
+ const displayio_area_t* whole,
+ displayio_area_t* transformed) {
+ if (mirror_x) {
+ transformed->x1 = whole->x1 + (whole->x2 - original->x2);
+ transformed->x2 = whole->x2 - (original->x1 - whole->x1);
+ } else {
+ transformed->x1 = original->x1;
+ transformed->x2 = original->x2;
+ }
+ if (mirror_y) {
+ transformed->y1 = whole->y1 + (whole->y2 - original->y2);
+ transformed->y2 = whole->y2 - (original->y1 - whole->y1);
+ } else {
+ transformed->y1 = original->y1;
+ transformed->y2 = original->y2;
+ }
+ if (transpose_xy) {
+ int16_t y1 = transformed->y1;
+ int16_t y2 = transformed->y2;
+ transformed->y1 = whole->y1 + (transformed->x1 - whole->x1);
+ transformed->y2 = whole->y1 + (transformed->x2 - whole->x1);
+ transformed->x2 = whole->x1 + (y2 - whole->y1);
+ transformed->x1 = whole->x1 + (y1 - whole->y1);
}
- #endif
}
diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h
index 5b56ed55c..caa5ce36d 100644
--- a/shared-module/displayio/__init__.h
+++ b/shared-module/displayio/__init__.h
@@ -24,17 +24,19 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H
+#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO___INIT___H
+#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO___INIT___H
#include "shared-bindings/displayio/Display.h"
#include "shared-bindings/displayio/FourWire.h"
#include "shared-bindings/displayio/Group.h"
+#include "shared-bindings/displayio/I2CDisplay.h"
#include "shared-bindings/displayio/ParallelBus.h"
typedef struct {
union {
displayio_fourwire_obj_t fourwire_bus;
+ displayio_i2cdisplay_obj_t i2cdisplay_bus;
displayio_parallelbus_obj_t parallel_bus;
};
displayio_display_obj_t display;
@@ -46,5 +48,6 @@ extern displayio_group_t circuitpython_splash;
void displayio_refresh_displays(void);
void reset_displays(void);
+void displayio_gc_collect(void);
-#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H
+#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO___INIT___H
diff --git a/shared-module/displayio/area.h b/shared-module/displayio/area.h
new file mode 100644
index 000000000..ec7c389b4
--- /dev/null
+++ b/shared-module/displayio/area.h
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_AREA_H
+#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_AREA_H
+
+// Implementations are in __init__.c
+typedef struct _displayio_area_t displayio_area_t;
+
+struct _displayio_area_t {
+ int16_t x1;
+ int16_t y1;
+ int16_t x2; // Second point is exclusive.
+ int16_t y2;
+ const displayio_area_t* next; // Next area in the linked list.
+};
+
+typedef struct {
+ uint16_t x;
+ uint16_t y;
+ int8_t dx;
+ int8_t dy;
+ uint8_t scale;
+ uint16_t width;
+ uint16_t height;
+ bool mirror_x;
+ bool mirror_y;
+ bool transpose_xy;
+} displayio_buffer_transform_t;
+
+void displayio_area_union(const displayio_area_t* a,
+ const displayio_area_t* b,
+ displayio_area_t* u);
+void displayio_area_expand(displayio_area_t* original, const displayio_area_t* addition);
+void displayio_area_copy(const displayio_area_t* src, displayio_area_t* dst);
+void displayio_area_scale(displayio_area_t* area, uint16_t scale);
+void displayio_area_shift(displayio_area_t* area, int16_t dx, int16_t dy);
+bool displayio_area_compute_overlap(const displayio_area_t* a,
+ const displayio_area_t* b,
+ displayio_area_t* overlap);
+uint16_t displayio_area_width(const displayio_area_t* area);
+uint16_t displayio_area_height(const displayio_area_t* area);
+uint32_t displayio_area_size(const displayio_area_t* area);
+bool displayio_area_equal(const displayio_area_t* a, const displayio_area_t* b);
+void displayio_area_transform_within(bool mirror_x, bool mirror_y, bool transpose_xy,
+ const displayio_area_t* original,
+ const displayio_area_t* whole,
+ displayio_area_t* transformed);
+
+#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_AREA_H
diff --git a/shared-module/terminalio/Terminal.c b/shared-module/terminalio/Terminal.c
index 7adf9d032..86c3e903e 100644
--- a/shared-module/terminalio/Terminal.c
+++ b/shared-module/terminalio/Terminal.c
@@ -35,6 +35,8 @@ void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, d
self->font = font;
self->tilegrid = tilegrid;
self->first_row = 0;
+
+ common_hal_displayio_tilegrid_set_top_left(self->tilegrid, 0, 1);
}
size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, const byte *data, size_t len, int *errcode) {
diff --git a/shared-module/usb_hid/Device.c b/shared-module/usb_hid/Device.c
index 0e256cb5e..a5a57419c 100644
--- a/shared-module/usb_hid/Device.c
+++ b/shared-module/usb_hid/Device.c
@@ -47,15 +47,15 @@ void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t*
// Wait until interface is ready, timeout = 2 seconds
uint64_t end_ticks = ticks_ms + 2000;
- while ( (ticks_ms < end_ticks) && !tud_hid_generic_ready() ) { }
+ while ( (ticks_ms < end_ticks) && !tud_hid_ready() ) { }
- if ( !tud_hid_generic_ready() ) {
+ if ( !tud_hid_ready() ) {
mp_raise_msg(&mp_type_OSError, translate("USB Busy"));
}
memcpy(self->report_buffer, report, len);
- if ( !tud_hid_generic_report(self->report_id, self->report_buffer, len) ) {
+ if ( !tud_hid_report(self->report_id, self->report_buffer, len) ) {
mp_raise_msg(&mp_type_OSError, translate("USB Error"));
}
}
@@ -70,7 +70,7 @@ static usb_hid_device_obj_t* get_hid_device(uint8_t report_id) {
}
// Callbacks invoked when receive Get_Report request through control endpoint
-uint16_t tud_hid_generic_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) {
+uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) {
// only support Input Report
if ( report_type != HID_REPORT_TYPE_INPUT ) return 0;
@@ -80,7 +80,7 @@ uint16_t tud_hid_generic_get_report_cb(uint8_t report_id, hid_report_type_t repo
}
// Callbacks invoked when receive Set_Report request through control endpoint
-void tud_hid_generic_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) {
+void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) {
usb_hid_device_obj_t* hid_device = get_hid_device(report_id);
if ( report_type == HID_REPORT_TYPE_OUTPUT ) {
diff --git a/shared-module/usb_midi/PortOut.c b/shared-module/usb_midi/PortOut.c
index 99a4fad43..0b37dcfd4 100644
--- a/shared-module/usb_midi/PortOut.c
+++ b/shared-module/usb_midi/PortOut.c
@@ -33,5 +33,5 @@ size_t common_hal_usb_midi_portout_write(usb_midi_portout_obj_t *self, const uin
}
bool common_hal_usb_midi_portout_ready_to_tx(usb_midi_portout_obj_t *self) {
- return tud_midi_connected();
+ return tud_midi_mounted();
}
diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c
index 0b3fbe178..fd51e2c07 100644
--- a/supervisor/shared/display.c
+++ b/supervisor/shared/display.c
@@ -50,6 +50,10 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
}
width_in_tiles = (width_px - blinka_bitmap.width * scale) / (grid->tile_width * scale);
uint16_t height_in_tiles = height_px / (grid->tile_height * scale);
+ uint16_t remaining_pixels = height_px % (grid->tile_height * scale);
+ if (remaining_pixels > 0) {
+ height_in_tiles += 1;
+ }
circuitpython_splash.scale = scale;
uint16_t total_tiles = width_in_tiles * height_in_tiles;
@@ -67,15 +71,18 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
if (tiles == NULL) {
return;
}
-
+ grid->y = 0;
+ grid->top_left_y = 0;
+ if (remaining_pixels > 0) {
+ grid->y -= (grid->tile_height - remaining_pixels);
+ }
grid->width_in_tiles = width_in_tiles;
grid->height_in_tiles = height_in_tiles;
- grid->total_width = width_in_tiles * grid->tile_width;
- grid->total_height = height_in_tiles * grid->tile_height;
+ grid->pixel_width = width_in_tiles * grid->tile_width;
+ grid->pixel_height = height_in_tiles * grid->tile_height;
grid->tiles = tiles;
- supervisor_terminal.cursor_x = 0;
- supervisor_terminal.cursor_y = 0;
+ common_hal_terminalio_terminal_construct(&supervisor_terminal, grid, &supervisor_terminal_font);
}
void supervisor_stop_terminal(void) {
@@ -139,17 +146,49 @@ displayio_bitmap_t blinka_bitmap = {
.read_only = true
};
-uint32_t blinka_transparency[1] = {0x80000000};
-
-// These colors are RGB 565 with the bytes swapped.
-uint32_t blinka_colors[8] = {0x78890000, 0x9F86B8FC, 0xffff0D5A, 0x0000f501,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000};
+_displayio_color_t blinka_colors[7] = {
+ {
+ .rgb888 = 0x000000,
+ .rgb565 = 0x0000,
+ .luma = 0x00,
+ .transparent = true
+ },
+ {
+ .rgb888 = 0x8428bc,
+ .rgb565 = 0x7889,
+ .luma = 0xff // We cheat the luma here. It is actually 0x60
+ },
+ {
+ .rgb888 = 0xff89bc,
+ .rgb565 = 0xB8FC,
+ .luma = 0xb5
+ },
+ {
+ .rgb888 = 0x7beffe,
+ .rgb565 = 0x9F86,
+ .luma = 0xe0
+ },
+ {
+ .rgb888 = 0x51395f,
+ .rgb565 = 0x0D5A,
+ .luma = 0x47
+ },
+ {
+ .rgb888 = 0xffffff,
+ .rgb565 = 0xffff,
+ .luma = 0xff
+ },
+ {
+ .rgb888 = 0x0736a0,
+ .rgb565 = 0xf501,
+ .luma = 0x44
+ },
+};
displayio_palette_t blinka_palette = {
.base = {.type = &displayio_palette_type },
- .opaque = blinka_transparency,
.colors = blinka_colors,
- .color_count = 16,
+ .color_count = 7,
.needs_refresh = false
};
@@ -159,18 +198,22 @@ displayio_tilegrid_t blinka_sprite = {
.pixel_shader = &blinka_palette,
.x = 0,
.y = 0,
+ .pixel_width = 16,
+ .pixel_height = 16,
.bitmap_width_in_tiles = 1,
.width_in_tiles = 1,
.height_in_tiles = 1,
- .total_width = 16,
- .total_height = 16,
.tile_width = 16,
.tile_height = 16,
.top_left_x = 16,
.top_left_y = 16,
.tiles = 0,
- .needs_refresh = false,
- .inline_tiles = true
+ .partial_change = false,
+ .full_change = false,
+ .first_draw = true,
+ .moved = false,
+ .inline_tiles = true,
+ .in_group = true
};
displayio_group_child_t splash_children[2] = {
@@ -186,5 +229,6 @@ displayio_group_t circuitpython_splash = {
.size = 2,
.max_size = 2,
.children = splash_children,
- .needs_refresh = true
+ .item_removed = false,
+ .in_group = false
};
diff --git a/supervisor/shared/display.h b/supervisor/shared/display.h
index d5faa7777..2a2ccf46d 100644
--- a/supervisor/shared/display.h
+++ b/supervisor/shared/display.h
@@ -35,11 +35,10 @@
// These are autogenerated resources.
// This is fixed so it doesn't need to be in RAM.
-extern const displayio_bitmap_t supervisor_terminal_font_bitmap;
-
extern const fontio_builtinfont_t supervisor_terminal_font;
// These will change so they must live in RAM.
+extern displayio_bitmap_t supervisor_terminal_font_bitmap;
extern displayio_tilegrid_t supervisor_terminal_text_grid;
extern terminalio_terminal_obj_t supervisor_terminal;
diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c
index fa34ed0da..c50d7f4ee 100644
--- a/supervisor/shared/filesystem.c
+++ b/supervisor/shared/filesystem.c
@@ -99,6 +99,9 @@ void filesystem_init(bool create_allowed, bool force_create) {
make_empty_file(&vfs_fat->fatfs, "/.Trashes");
make_empty_file(&vfs_fat->fatfs, "/.fseventsd/no_log");
+ // create empty lib directory
+ f_mkdir(&vfs_fat->fatfs, "/lib");
+
// and ensure everything is flushed
supervisor_flash_flush();
} else if (res != FR_OK) {
diff --git a/supervisor/shared/rgb_led_status.c b/supervisor/shared/rgb_led_status.c
index 209eef55e..0e69cd2e0 100644
--- a/supervisor/shared/rgb_led_status.c
+++ b/supervisor/shared/rgb_led_status.c
@@ -50,10 +50,28 @@ busio_spi_obj_t status_apa102;
#endif
#endif
-#if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK))
+#if defined(CP_RGB_STATUS_R) || defined(CP_RGB_STATUS_G) || defined(CP_RGB_STATUS_B)
+#define CP_RGB_STATUS_LED
+
+#include "shared-bindings/pulseio/PWMOut.h"
+#include "shared-bindings/microcontroller/Pin.h"
+
+pulseio_pwmout_obj_t rgb_status_r;
+pulseio_pwmout_obj_t rgb_status_g;
+pulseio_pwmout_obj_t rgb_status_b;
+
+uint8_t rgb_status_brightness = 0xFF;
+
+uint16_t status_rgb_color[3] = {
+ 0 /* red */, 0 /* green */, 0 /* blue */
+};
+#endif
+
+#if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
static uint32_t current_status_color = 0;
#endif
+
void rgb_led_status_init() {
#ifdef MICROPY_HW_NEOPIXEL
common_hal_digitalio_digitalinout_construct(&status_neopixel, MICROPY_HW_NEOPIXEL);
@@ -93,7 +111,34 @@ void rgb_led_status_init() {
#endif
#endif
- #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK))
+
+ #if defined(CP_RGB_STATUS_LED)
+ if (common_hal_mcu_pin_is_free(CP_RGB_STATUS_R)) {
+ pwmout_result_t red_result = common_hal_pulseio_pwmout_construct(&rgb_status_r, CP_RGB_STATUS_R, 0, 50000, false);
+
+ if (PWMOUT_OK == red_result) {
+ common_hal_pulseio_pwmout_never_reset(&rgb_status_r);
+ }
+ }
+
+ if (common_hal_mcu_pin_is_free(CP_RGB_STATUS_G)) {
+ pwmout_result_t green_result = common_hal_pulseio_pwmout_construct(&rgb_status_g, CP_RGB_STATUS_G, 0, 50000, false);
+
+ if (PWMOUT_OK == green_result) {
+ common_hal_pulseio_pwmout_never_reset(&rgb_status_g);
+ }
+ }
+
+ if (common_hal_mcu_pin_is_free(CP_RGB_STATUS_B)) {
+ pwmout_result_t blue_result = common_hal_pulseio_pwmout_construct(&rgb_status_b, CP_RGB_STATUS_B, 0, 50000, false);
+
+ if (PWMOUT_OK == blue_result) {
+ common_hal_pulseio_pwmout_never_reset(&rgb_status_b);
+ }
+ }
+ #endif
+
+ #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
// Force a write of the current status color.
uint32_t rgb = current_status_color;
current_status_color = 0x1000000; // Not a valid color
@@ -109,10 +154,13 @@ void reset_status_led() {
reset_pin_number(MICROPY_HW_APA102_MOSI->number);
reset_pin_number(MICROPY_HW_APA102_SCK->number);
#endif
+ #if defined(CP_RGB_STATUS_LED)
+ // TODO: Support sharing status LED with user.
+ #endif
}
void new_status_color(uint32_t rgb) {
- #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK))
+ #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
if (current_status_color == rgb) {
return;
}
@@ -143,10 +191,30 @@ void new_status_color(uint32_t rgb) {
common_hal_busio_spi_write(&status_apa102, status_apa102_color, 8);
#endif
#endif
+
+ #if defined(CP_RGB_STATUS_LED)
+ uint8_t red_u8 = (rgb_adjusted >> 16) & 0xFF;
+ uint8_t green_u8 = (rgb_adjusted >> 8) & 0xFF;
+ uint8_t blue_u8 = rgb_adjusted & 0xFF;
+
+ #if defined(CP_RGB_STATUS_INVERTED_PWM)
+ status_rgb_color[0] = (1 << 16) - 1 - ((uint16_t) (red_u8 << 8) + red_u8);
+ status_rgb_color[1] = (1 << 16) - 1 - ((uint16_t) (green_u8 << 8) + green_u8);
+ status_rgb_color[2] = (1 << 16) - 1 - ((uint16_t) (blue_u8 << 8) + blue_u8);
+ #else
+ status_rgb_color[0] = (uint16_t) (red_u8 << 8) + red_u8;
+ status_rgb_color[1] = (uint16_t) (green_u8 << 8) + green_u8;
+ status_rgb_color[2] = (uint16_t) (blue_u8 << 8) + blue_u8;
+ #endif
+
+ common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_r, status_rgb_color[0]);
+ common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_g, status_rgb_color[1]);
+ common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_b, status_rgb_color[2]);
+ #endif
}
void temp_status_color(uint32_t rgb) {
- #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK))
+ #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
uint32_t rgb_adjusted = rgb;
rgb_adjusted = color_brightness(rgb, rgb_status_brightness);
#endif
@@ -168,6 +236,27 @@ void temp_status_color(uint32_t rgb) {
common_hal_busio_spi_write(&status_apa102, colors, 12);
#endif
#endif
+ #if defined(CP_RGB_STATUS_LED)
+ uint8_t red_u8 = (rgb_adjusted >> 16) & 0xFF;
+ uint8_t green_u8 = (rgb_adjusted >> 8) & 0xFF;
+ uint8_t blue_u8 = rgb_adjusted & 0xFF;
+
+ uint16_t temp_status_color_rgb[3] = {0};
+
+ #if defined(CP_RGB_STATUS_INVERTED_PWM)
+ temp_status_color_rgb[0] = (1 << 16) - 1 - ((uint16_t) (red_u8 << 8) + red_u8);
+ temp_status_color_rgb[1] = (1 << 16) - 1 - ((uint16_t) (green_u8 << 8) + green_u8);
+ temp_status_color_rgb[2] = (1 << 16) - 1 - ((uint16_t) (blue_u8 << 8) + blue_u8);
+ #else
+ temp_status_color_rgb[0] = (uint16_t) (red_u8 << 8) + red_u8;
+ temp_status_color_rgb[1] = (uint16_t) (green_u8 << 8) + green_u8;
+ temp_status_color_rgb[2] = (uint16_t) (blue_u8 << 8) + blue_u8;
+ #endif
+
+ common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_r, temp_status_color_rgb[0]);
+ common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_g, temp_status_color_rgb[1]);
+ common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_b, temp_status_color_rgb[2]);
+ #endif
}
void clear_temp_status() {
@@ -181,10 +270,30 @@ void clear_temp_status() {
common_hal_busio_spi_write(&status_apa102, status_apa102_color, 8);
#endif
#endif
+ #if defined(CP_RGB_STATUS_LED)
+
+ uint16_t red = 0;
+ uint16_t green = 0;
+ uint16_t blue = 0;
+
+ #if defined(CP_RGB_STATUS_INVERTED_PWM)
+ red = (1 << 16) - 1 - status_rgb_color[0];
+ green = (1 << 16) - 1 - status_rgb_color[1];
+ blue = (1 << 16) - 1 - status_rgb_color[2];
+ #else
+ red = status_rgb_color[0];
+ green = status_rgb_color[1];
+ blue = status_rgb_color[2];
+ #endif
+
+ common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_r, red);
+ common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_g, green);
+ common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_b, blue);
+ #endif
}
uint32_t color_brightness(uint32_t color, uint8_t brightness) {
- #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK))
+ #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
uint32_t result = ((color & 0xff0000) * brightness / 255) & 0xff0000;
result += ((color & 0xff00) * brightness / 255) & 0xff00;
result += ((color & 0xff) * brightness / 255) & 0xff;
@@ -195,7 +304,7 @@ uint32_t color_brightness(uint32_t color, uint8_t brightness) {
}
void set_rgb_status_brightness(uint8_t level){
- #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK))
+ #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
rgb_status_brightness = level;
uint32_t current_color = current_status_color;
// Temporarily change the current color global to force the new_status_color call to update the
@@ -210,7 +319,7 @@ void prep_rgb_status_animation(const pyexec_result_t* result,
bool found_main,
safe_mode_t safe_mode,
rgb_status_animation_t* status) {
- #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK))
+ #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
new_status_color(ALL_DONE);
status->pattern_start = ticks_ms;
status->safe_mode = safe_mode;
@@ -256,7 +365,7 @@ void prep_rgb_status_animation(const pyexec_result_t* result,
}
void tick_rgb_status_animation(rgb_status_animation_t* status) {
- #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK))
+ #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
uint32_t tick_diff = ticks_ms - status->pattern_start;
if (status->ok) {
// All is good. Ramp ALL_DONE up and down.
diff --git a/supervisor/shared/status_leds.c b/supervisor/shared/status_leds.c
index d99853ceb..672242a96 100644
--- a/supervisor/shared/status_leds.c
+++ b/supervisor/shared/status_leds.c
@@ -26,8 +26,10 @@
#include "supervisor/shared/status_leds.h"
+#if CIRCUITPY_DIGITALIO
#include "common-hal/digitalio/DigitalInOut.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
+#endif
#ifdef MICROPY_HW_LED_RX
digitalio_digitalinout_obj_t rx_led;
diff --git a/supervisor/shared/usb/tusb_config.h b/supervisor/shared/usb/tusb_config.h
index 301805275..ad5825b6c 100644
--- a/supervisor/shared/usb/tusb_config.h
+++ b/supervisor/shared/usb/tusb_config.h
@@ -107,7 +107,7 @@
// USB RAM PLACEMENT
//--------------------------------------------------------------------+
#define CFG_TUSB_ATTR_USBRAM
-#define CFG_TUSB_MEM_ALIGN ATTR_ALIGNED(4)
+#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
#ifdef __cplusplus
diff --git a/supervisor/shared/usb/usb_desc.c b/supervisor/shared/usb/usb_desc.c
index 5a0de1ffc..9b333d6fe 100644
--- a/supervisor/shared/usb/usb_desc.c
+++ b/supervisor/shared/usb/usb_desc.c
@@ -24,23 +24,35 @@
* THE SOFTWARE.
*/
-#include "supervisor/shared/usb/usb_desc.h"
+#include "lib/tinyusb/src/tusb.h"
#include "shared-module/usb_hid/Device.h"
#include "genhdr/autogen_usb_descriptor.h"
-// tud_desc_set is required by tinyusb stack
-tud_desc_set_t tud_desc_set =
-{
- .device = &usb_desc_dev,
- .config = &usb_desc_cfg,
- .string_arr = (uint8_t const **) string_desc_arr,
- .string_count = sizeof(string_desc_arr)/sizeof(string_desc_arr[0]),
+// Invoked when received GET DEVICE DESCRIPTOR
+// Application return pointer to descriptor
+uint8_t const * tud_descriptor_device_cb(void) {
+ return usb_desc_dev;
+}
- .hid_report =
- {
- .generic = hid_report_descriptor,
- .boot_keyboard = NULL,
- .boot_mouse = NULL
- }
-};
+// Invoked when received GET CONFIGURATION DESCRIPTOR
+// Application return pointer to descriptor
+// Descriptor contents must exist long enough for transfer to complete
+uint8_t const * tud_descriptor_configuration_cb(uint8_t index) {
+ (void) index; // for multiple configurations
+ return usb_desc_cfg;
+}
+
+// Invoked when received GET HID REPORT DESCRIPTOR
+// Application return pointer to descriptor
+// Descriptor contents must exist long enough for transfer to complete
+uint8_t const * tud_hid_descriptor_report_cb(void) {
+ return hid_report_descriptor;
+}
+
+// Invoked when received GET STRING DESCRIPTOR request
+// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
+uint16_t const* tud_descriptor_string_cb(uint8_t index) {
+ uint8_t const max_index = sizeof(string_desc_arr)/sizeof(string_desc_arr[0]);
+ return (index < max_index) ? string_desc_arr[index] : NULL;
+}
diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c
index f6f0fa9c3..205cb7b50 100644
--- a/supervisor/shared/usb/usb_msc_flash.c
+++ b/supervisor/shared/usb/usb_msc_flash.c
@@ -59,59 +59,18 @@ static fs_user_mount_t* get_vfs(int lun) {
}
// Callback invoked when received an SCSI command not in built-in list below
-// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
+// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, TEST_UNIT_READY, START_STOP_UNIT, MODE_SENSE6, REQUEST_SENSE
// - READ10 and WRITE10 have their own callbacks
int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer, uint16_t bufsize) {
const void* response = NULL;
int32_t resplen = 0;
switch ( scsi_cmd[0] ) {
- case SCSI_CMD_TEST_UNIT_READY:
- // Command that host uses to check our readiness before sending other commands
- resplen = 0;
- if (lun > 1) {
- resplen = -1;
- } else {
- fs_user_mount_t* current_mount = get_vfs(lun);
- if (current_mount == NULL) {
- resplen = -1;
- }
- if (ejected[lun]) {
- resplen = -1;
- }
- }
- break;
-
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
// Host is about to read/write etc ... better not to disconnect disk
resplen = 0;
break;
- case SCSI_CMD_START_STOP_UNIT:
- {
- // Host try to eject/safe remove/poweroff us. We could safely disconnect with disk storage, or go into lower power
- const scsi_start_stop_unit_t* start_stop = (const scsi_start_stop_unit_t*) scsi_cmd;
- // Start bit = 0 : low power mode, if load_eject = 1 : unmount disk storage as well
- // Start bit = 1 : Ready mode, if load_eject = 1 : mount disk storage
- resplen = 0;
- if (start_stop->load_eject == 1) {
- if (lun > 1) {
- resplen = -1;
- } else {
- fs_user_mount_t* current_mount = get_vfs(lun);
- if (current_mount == NULL) {
- resplen = -1;
- }
- if (disk_ioctl(current_mount, CTRL_SYNC, NULL) != RES_OK) {
- resplen = -1;
- } else {
- ejected[lun] = true;
- }
- }
- }
- }
- break;
-
default:
// Set Sense = Invalid Command Operation
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
@@ -127,7 +86,7 @@ int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer,
}
// copy response to stack's buffer if any
- if ( response && resplen ) {
+ if ( response && (resplen > 0) ) {
memcpy(buffer, response, resplen);
}
@@ -206,3 +165,54 @@ void tud_msc_write10_complete_cb (uint8_t lun) {
// This write is complete, start the autoreload clock.
autoreload_start();
}
+
+// Invoked when received SCSI_CMD_INQUIRY
+// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
+void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) {
+ (void) lun;
+
+ memcpy(vendor_id , CFG_TUD_MSC_VENDOR , strlen(CFG_TUD_MSC_VENDOR));
+ memcpy(product_id , CFG_TUD_MSC_PRODUCT , strlen(CFG_TUD_MSC_PRODUCT));
+ memcpy(product_rev, CFG_TUD_MSC_PRODUCT_REV, strlen(CFG_TUD_MSC_PRODUCT_REV));
+}
+
+// Invoked when received Test Unit Ready command.
+// return true allowing host to read/write this LUN e.g SD card inserted
+bool tud_msc_test_unit_ready_cb(uint8_t lun) {
+ if (lun > 1) {
+ return false;
+ }
+
+ fs_user_mount_t* current_mount = get_vfs(lun);
+ if (current_mount == NULL) {
+ return false;
+ }
+ if (ejected[lun]) {
+ return false;
+ }
+
+ return true;
+}
+
+// Invoked when received Start Stop Unit command
+// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
+// - Start = 1 : active mode, if load_eject = 1 : load disk storage
+bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) {
+ if (load_eject) {
+ if (lun > 1) {
+ return false;
+ } else {
+ fs_user_mount_t* current_mount = get_vfs(lun);
+ if (current_mount == NULL) {
+ return false;
+ }
+ if (disk_ioctl(current_mount, CTRL_SYNC, NULL) != RES_OK) {
+ return false;
+ } else {
+ ejected[lun] = true;
+ }
+ }
+ }
+
+ return true;
+}
diff --git a/tests/basics/array_overflow.py b/tests/basics/bigint_array_overflow.py
index ba3eb7f06..0dd79c23d 100644
--- a/tests/basics/array_overflow.py
+++ b/tests/basics/bigint_array_overflow.py
@@ -13,13 +13,6 @@ def test_array_overflow(typecode, val):
except OverflowError:
print('OverflowError')
-# small int -1
-test_array_overflow('Q', -1)
-test_array_overflow('L', -1)
-test_array_overflow('I', -1)
-test_array_overflow('H', -1)
-test_array_overflow('B', -1)
-
# big int -1
test_array_overflow('Q', -2**64 // 2**64)
test_array_overflow('L', -2**64 // 2**64)
diff --git a/tests/basics/int_bytes.py b/tests/basics/int_bytes.py
index 8c0c9a82f..aaf440081 100644
--- a/tests/basics/int_bytes.py
+++ b/tests/basics/int_bytes.py
@@ -1,4 +1,6 @@
print((10).to_bytes(1, "little"))
+# Test fitting in length that's not a power of two.
+print((0x10000).to_bytes(3, 'little'))
print((111111).to_bytes(4, "little"))
print((100).to_bytes(10, "little"))
diff --git a/tests/basics/smallint_array_overflow.py b/tests/basics/smallint_array_overflow.py
new file mode 100644
index 000000000..25b457cca
--- /dev/null
+++ b/tests/basics/smallint_array_overflow.py
@@ -0,0 +1,52 @@
+try:
+ from array import array
+except ImportError:
+ print("SKIP")
+ raise SystemExit
+
+def test_array_overflow(typecode, val):
+ try:
+ print(array(typecode, [val]))
+ except OverflowError:
+ print('OverflowError')
+
+def test_bytearray_overflow(val):
+ try:
+ print(bytearray([val]))
+ except (OverflowError, ValueError):
+ # CircuitPython always does OverflowError
+ print('(OverflowError, ValueError)')
+
+
+# small int -1
+test_array_overflow('Q', -1)
+test_array_overflow('L', -1)
+test_array_overflow('I', -1)
+test_array_overflow('H', -1)
+test_array_overflow('B', -1)
+
+# 0 ok
+test_array_overflow('Q', 0)
+test_array_overflow('L', 0)
+test_array_overflow('I', 0)
+test_array_overflow('H', 0)
+test_array_overflow('B', 0)
+
+# 1 ok
+test_array_overflow('Q', 1)
+test_array_overflow('L', 1)
+test_array_overflow('I', 1)
+test_array_overflow('H', 1)
+test_array_overflow('B', 1)
+
+# truth value conversions
+test_array_overflow('b', True)
+test_array_overflow('b', False)
+
+# similar tests for bytearrays
+test_bytearray_overflow(0)
+test_bytearray_overflow(1)
+test_bytearray_overflow(-1)
+test_bytearray_overflow(256)
+test_bytearray_overflow(True)
+test_bytearray_overflow(False)
diff --git a/tests/import/mpy_invalid.py b/tests/import/mpy_invalid.py
index 6a4e116e7..b9dd99a44 100644
--- a/tests/import/mpy_invalid.py
+++ b/tests/import/mpy_invalid.py
@@ -59,8 +59,8 @@ for i in range(len(user_files)):
mod = 'mod%u' % i
try:
__import__(mod)
- except ValueError as er:
- print(mod, 'ValueError', er)
+ except Exception as e:
+ print(mod, type(e).__name__, e)
# unmount and undo path addition
uos.umount('/userfs')
diff --git a/tests/import/mpy_invalid.py.exp b/tests/import/mpy_invalid.py.exp
index e4f2b13e9..197eb4f7b 100644
--- a/tests/import/mpy_invalid.py.exp
+++ b/tests/import/mpy_invalid.py.exp
@@ -1,3 +1,3 @@
-mod0 ValueError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info.
-mod1 ValueError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info.
-mod2 ValueError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info.
+mod0 RuntimeError Corrupt .mpy file
+mod1 RuntimeError Corrupt .mpy file
+mod2 MpyError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info.
diff --git a/tools/build_board_info.py b/tools/build_board_info.py
index 307d90d7a..8731a6feb 100644
--- a/tools/build_board_info.py
+++ b/tools/build_board_info.py
@@ -39,7 +39,8 @@ extension_by_board = {
"makerdiary_nrf52840_mdk": HEX,
"makerdiary_nrf52840_mdk_usb_dongle": HEX,
"pca10056": BIN_UF2,
- "pca10059": BIN_UF2
+ "pca10059": BIN_UF2,
+ "electronut_labs_blip": HEX
}
aliases_by_board = {
diff --git a/tools/build_release_files.py b/tools/build_release_files.py
index 872302a4f..e29b098c7 100755
--- a/tools/build_release_files.py
+++ b/tools/build_release_files.py
@@ -1,3 +1,5 @@
+#! /usr/bin/env python3
+
import os
import sys
import subprocess
@@ -6,7 +8,7 @@ import build_board_info as build_info
import time
for port in build_info.SUPPORTED_PORTS:
- result = subprocess.run("rm -rf ../ports/{}/build*".format(port), shell=True)
+ result = subprocess.run("rm -rf ../ports/{port}/build*".format(port=port), shell=True)
ROSIE_SETUPS = ["rosie-ci"]
rosie_ok = {}
@@ -37,7 +39,25 @@ for board in build_boards:
bin_directory = "../bin/{board}/{language}".format(board=board, language=language)
os.makedirs(bin_directory, exist_ok=True)
start_time = time.monotonic()
- make_result = subprocess.run("make -C ../ports/" + board_info["port"] + " TRANSLATION=" + language + " BOARD=" + board, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+
+ # Normally different language builds are all done based on the same set of compiled sources.
+ # But sometimes a particular language needs to be built from scratch, if, for instance,
+ # CFLAGS_INLINE_LIMIT is set for a particular language to make it fit.
+ clean_build_check_result = subprocess.run(
+ "make -C ../ports/{port} TRANSLATION={language} BOARD={board} check-release-needs-clean-build | fgrep 'RELEASE_NEEDS_CLEAN_BUILD = 1'".format(
+ port = board_info["port"], language=language, board=board),
+ shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ clean_build = clean_build_check_result.returncode == 0
+
+ build_dir = "build-{board}".format(board=board)
+ if clean_build:
+ build_dir += "-{language}".format(language=language)
+
+ make_result = subprocess.run(
+ "make -C ../ports/{port} TRANSLATION={language} BOARD={board} BUILD={build}".format(
+ port = board_info["port"], language=language, board=board, build=build_dir),
+ shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+
build_duration = time.monotonic() - start_time
success = "\033[32msucceeded\033[0m"
if make_result.returncode != 0:
@@ -47,11 +67,14 @@ for board in build_boards:
other_output = ""
for extension in board_info["extensions"]:
- temp_filename = "../ports/{port}/build-{board}/firmware.{extension}".format(port=board_info["port"], board=board, extension=extension)
+ temp_filename = "../ports/{port}/{build}/firmware.{extension}".format(
+ port=board_info["port"], build=build_dir, extension=extension)
for alias in board_info["aliases"] + [board]:
- bin_directory = "../bin/{alias}/{language}".format(alias=alias, language=language)
+ bin_directory = "../bin/{alias}/{language}".format(
+ alias=alias, language=language)
os.makedirs(bin_directory, exist_ok=True)
- final_filename = "adafruit-circuitpython-{alias}-{language}-{version}.{extension}".format(alias=alias, language=language, version=version, extension=extension)
+ final_filename = "adafruit-circuitpython-{alias}-{language}-{version}.{extension}".format(
+ alias=alias, language=language, version=version, extension=extension)
final_filename = os.path.join(bin_directory, final_filename)
try:
shutil.copyfile(temp_filename, final_filename)
@@ -62,7 +85,9 @@ for board in build_boards:
if travis:
print('travis_fold:start:adafruit-bins-{}-{}\\r'.format(language, board))
- print("Build {} for {} took {:.2f}s and {}".format(board, language, build_duration, success))
+ print("Build {board} for {language}{clean_build} took {build_duration:.2f}s and {success}".format(
+ board=board, language=language, clean_build=(" (clean_build)" if clean_build else ""),
+ build_duration=build_duration, success=success))
if make_result.returncode != 0:
print(make_result.stdout.decode("utf-8"))
print(other_output)
diff --git a/tools/gen_display_resources.py b/tools/gen_display_resources.py
index ebea9dccc..0f6b9014b 100644
--- a/tools/gen_display_resources.py
+++ b/tools/gen_display_resources.py
@@ -29,7 +29,6 @@ class BitmapStub:
self.rows[y] = bytes(row)
f = bitmap_font.load_font(args.font, BitmapStub)
-real_bb = [0, 0]
# Load extra characters from the sample file.
sample_characters = set()
@@ -61,13 +60,11 @@ for c in all_characters:
print("Font missing character:", c, ord(c))
filtered_characters = filtered_characters.replace(c, "")
continue
- x, y, dx, dy = g["bounds"]
if g["shift"][1] != 0:
raise RuntimeError("y shift")
- real_bb[0] = max(real_bb[0], x - dx)
- real_bb[1] = max(real_bb[1], y - dy)
-tile_x, tile_y = real_bb
+x, y, dx, dy = f.get_bounding_box()
+tile_x, tile_y = x - dx, y - dy
total_bits = tile_x * len(all_characters)
total_bits += 32 - total_bits % 32
bytes_per_row = total_bits // 8
@@ -101,14 +98,21 @@ c_file.write("""\
""")
c_file.write("""\
-uint32_t terminal_transparency[1] = {0x00000000};
-
-// These colors are RGB 565 with the bytes swapped.
-uint32_t terminal_colors[1] = {0xffff0000};
+_displayio_color_t terminal_colors[2] = {
+ {
+ .rgb888 = 0x000000,
+ .rgb565 = 0x0000,
+ .luma = 0x00
+ },
+ {
+ .rgb888 = 0xffffff,
+ .rgb565 = 0xffff,
+ .luma = 0xff
+ },
+};
displayio_palette_t supervisor_terminal_color = {
.base = {.type = &displayio_palette_type },
- .opaque = terminal_transparency,
.colors = terminal_colors,
.color_count = 2,
.needs_refresh = false
@@ -122,16 +126,21 @@ displayio_tilegrid_t supervisor_terminal_text_grid = {{
.pixel_shader = &supervisor_terminal_color,
.x = 16,
.y = 0,
+ .pixel_width = {1},
+ .pixel_height = {2},
.bitmap_width_in_tiles = {0},
+ .tiles_in_bitmap = {0},
.width_in_tiles = 1,
.height_in_tiles = 1,
- .total_width = {1},
- .total_height = {2},
.tile_width = {1},
.tile_height = {2},
.tiles = NULL,
- .needs_refresh = false,
- .inline_tiles = false
+ .partial_change = false,
+ .full_change = false,
+ .first_draw = true,
+ .moved = false,
+ .inline_tiles = false,
+ .in_group = true
}};
""".format(len(all_characters), tile_x, tile_y))
@@ -149,7 +158,7 @@ c_file.write("""\
""")
c_file.write("""\
-const displayio_bitmap_t supervisor_terminal_font_bitmap = {{
+displayio_bitmap_t supervisor_terminal_font_bitmap = {{
.base = {{.type = &displayio_bitmap_type }},
.width = {},
.height = {},
diff --git a/tools/git-checkout-latest-tag.sh b/tools/git-checkout-latest-tag.sh
new file mode 100755
index 000000000..f6242a946
--- /dev/null
+++ b/tools/git-checkout-latest-tag.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+git fetch --tags
+git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
diff --git a/tools/travis_new_boards_check.py b/tools/travis_new_boards_check.py
new file mode 100644
index 000000000..5ae05aec4
--- /dev/null
+++ b/tools/travis_new_boards_check.py
@@ -0,0 +1,51 @@
+#! /usr/bin/env python3
+
+import sys
+import os
+import json
+
+import build_board_info
+
+# Get boards in json format
+boards_info_json = build_board_info.get_board_mapping()
+
+# Get all the boards out of the json format
+info_boards = [board for board in boards_info_json.keys() if not boards_info_json[board].get("alias", False)]
+
+# We need to know the path of the .travis.yml file
+base_path = os.path.dirname(__file__)
+travis_path = os.path.abspath(os.path.join(base_path, '..', '.travis.yml'))
+
+# Loading board list based on TRAVIS_BOARDS env variable on .travis.yml
+travis_boards = []
+with open(travis_path, 'r') as travis:
+
+ # Get all lines that contain the substring 'TRAVIS_BOARDS'
+ for line in travis:
+
+ # Get the lines with TRAVIS_BOARDS= in it
+ if line.find('TRAVIS_BOARDS=') is not -1:
+ # Store all the boards names into travis_boards
+ begin_of_names = line.find('TRAVIS_BOARDS=') + len('TRAVIS_BOARDS=') + 1
+ end_of_names = line.rfind('"')
+ boards = line[begin_of_names:end_of_names]
+ boards = boards.split(' ')
+ travis_boards.extend(boards)
+
+ # We've reached the end of the env: section
+ elif 'addons' in line:
+ break
+ else:
+ pass
+
+# All the travis_boards elements must be on info_boards
+info_boards.sort()
+travis_boards.sort()
+
+missing_boards = set(info_boards) - set(travis_boards)
+
+if missing_boards:
+ print('Boards missing in TRAVIS_BOARDS:')
+ for board in missing_boards:
+ print(board)
+ sys.exit(1)