summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2019-12-05 22:45:53 -0500
committerDan Halbert <halbert@halwitz.org>2019-12-05 22:45:53 -0500
commit40434d691934cf7f5792f91ce0288beb568bab85 (patch)
treee2f7d0191685f0b519e98c3e1551626fbbf49585
parent1505da784f228d43df41a773cfe504e7e4da330a (diff)
parent15886b1505d854d76e353b9c5261568c7065d2bf (diff)
wip
-rw-r--r--.github/workflows/build.yml30
-rw-r--r--.github/workflows/create_website_pr.yml7
-rw-r--r--Makefile2
-rw-r--r--drivers/wiznet5k/internet/dns/dns.c4
m---------lib/stm32lib0
-rw-r--r--lib/utils/interrupt_char.c2
-rw-r--r--locale/ID.po282
-rw-r--r--locale/circuitpython.pot209
-rw-r--r--locale/de_DE.po435
-rw-r--r--locale/en_US.po209
-rw-r--r--locale/en_x_pirate.po209
-rw-r--r--locale/es.po281
-rw-r--r--locale/fil.po287
-rw-r--r--locale/fr.po300
-rw-r--r--locale/it_IT.po282
-rw-r--r--locale/ko.po2645
-rw-r--r--locale/pl.po278
-rw-r--r--locale/pt_BR.po274
-rw-r--r--locale/zh_Latn_pinyin.po303
-rwxr-xr-xmain.c15
-rw-r--r--ports/atmel-samd/Makefile9
-rw-r--r--ports/atmel-samd/background.c26
-rw-r--r--ports/atmel-samd/boards/common.template.ld16
-rw-r--r--ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk4
-rw-r--r--ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk4
-rw-r--r--ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk4
-rw-r--r--ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk4
-rw-r--r--ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk4
-rw-r--r--ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/monster_m4sk/mpconfigboard.mk3
-rw-r--r--ports/atmel-samd/boards/pewpew10/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk4
-rw-r--r--ports/atmel-samd/boards/pybadge/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/pygamer/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/pygamer_advance/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/pyportal_titano/board.c25
-rw-r--r--ports/atmel-samd/boards/pyportal_titano/mpconfigboard.h1
-rw-r--r--ports/atmel-samd/boards/pyportal_titano/pins.c9
-rw-r--r--ports/atmel-samd/boards/pyruler/mpconfigboard.mk5
-rw-r--r--ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.h34
-rw-r--r--ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.mk28
-rw-r--r--ports/atmel-samd/boards/robohatmm1_m0/pins.c92
-rw-r--r--ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/robohatmm1_m4/pins.c7
-rw-r--r--ports/atmel-samd/boards/shirtty/board.c (renamed from ports/stm32f4/boards/feather_f405/mpconfigboard.h)21
-rw-r--r--ports/atmel-samd/boards/shirtty/mpconfigboard.h63
-rw-r--r--ports/atmel-samd/boards/shirtty/mpconfigboard.mk15
-rw-r--r--ports/atmel-samd/boards/shirtty/pins.c36
-rw-r--r--ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/board.c (renamed from ports/atmel-samd/boards/robohatmm1_m0/board.c)0
-rw-r--r--ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/mpconfigboard.h34
-rw-r--r--ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/mpconfigboard.mk13
-rw-r--r--ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/pins.c42
-rw-r--r--ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/board.c38
-rw-r--r--ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/mpconfigboard.h42
-rw-r--r--ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/mpconfigboard.mk15
-rw-r--r--ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/pins.c42
-rw-r--r--ports/atmel-samd/boards/stringcar_m0_express/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/winterbloom_sol/board.c38
-rw-r--r--ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.h27
-rw-r--r--ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk30
-rw-r--r--ports/atmel-samd/boards/winterbloom_sol/pins.c15
-rw-r--r--ports/atmel-samd/common-hal/busio/I2C.c1
-rw-r--r--ports/atmel-samd/common-hal/busio/UART.c45
-rw-r--r--ports/atmel-samd/common-hal/microcontroller/Pin.c8
-rw-r--r--ports/atmel-samd/common-hal/microcontroller/__init__.c2
-rw-r--r--ports/atmel-samd/common-hal/pulseio/PWMOut.c11
-rw-r--r--ports/atmel-samd/common-hal/pulseio/PWMOut.h1
-rw-r--r--ports/atmel-samd/common-hal/time/__init__.c4
-rw-r--r--ports/atmel-samd/ld_defines.c31
-rw-r--r--ports/atmel-samd/mpconfigport.h52
-rw-r--r--ports/atmel-samd/mpconfigport.mk31
-rw-r--r--ports/atmel-samd/mphalport.c6
-rw-r--r--ports/atmel-samd/mphalport.h6
-rw-r--r--ports/atmel-samd/supervisor/port.c8
-rw-r--r--ports/atmel-samd/tick.c36
-rw-r--r--ports/atmel-samd/tick.h2
-rw-r--r--ports/cxd56/Makefile2
-rw-r--r--ports/cxd56/boards/spresense/mpconfigboard.h1
-rw-r--r--ports/cxd56/common-hal/analogio/AnalogIn.c8
-rw-r--r--ports/cxd56/common-hal/analogio/AnalogIn.h2
-rw-r--r--ports/cxd56/common-hal/busio/UART.c92
-rw-r--r--ports/cxd56/common-hal/busio/UART.h6
-rw-r--r--ports/cxd56/common-hal/pulseio/PWMOut.c8
-rw-r--r--ports/cxd56/common-hal/pulseio/PWMOut.h2
-rw-r--r--ports/cxd56/common-hal/time/__init__.c4
-rw-r--r--ports/cxd56/mpconfigport.h6
-rw-r--r--ports/cxd56/mphalport.c6
-rw-r--r--ports/cxd56/mphalport.h2
m---------ports/cxd56/spresense-exported-sdk0
-rw-r--r--ports/cxd56/supervisor/port.c18
-rw-r--r--ports/cxd56/tick.c15
-rw-r--r--ports/cxd56/tick.h2
-rwxr-xr-xports/nrf/Makefile9
-rw-r--r--ports/nrf/background.c7
-rw-r--r--ports/nrf/bluetooth/ble_drv.c28
-rw-r--r--ports/nrf/bluetooth/ble_drv.h7
-rw-r--r--ports/nrf/boards/adafruit_nrf52840_s140_v6.ld9
-rw-r--r--ports/nrf/boards/arduino_nano_33_ble/README.md27
-rw-r--r--ports/nrf/boards/arduino_nano_33_ble/board.c63
-rw-r--r--ports/nrf/boards/arduino_nano_33_ble/mpconfigboard.h16
-rw-r--r--ports/nrf/boards/arduino_nano_33_ble/mpconfigboard.mk15
-rw-r--r--ports/nrf/boards/arduino_nano_33_ble/pins.c63
-rw-r--r--ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.h3
-rw-r--r--ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.mk23
-rw-r--r--ports/nrf/boards/common.template.ld141
-rw-r--r--ports/nrf/boards/electronut_labs_blip/mpconfigboard.h1
-rw-r--r--ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk18
-rw-r--r--ports/nrf/boards/electronut_labs_papyr/mpconfigboard.h1
-rw-r--r--ports/nrf/boards/electronut_labs_papyr/mpconfigboard.mk16
-rw-r--r--ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h1
-rw-r--r--ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk16
-rw-r--r--ports/nrf/boards/itsybitsy_nrf52840_express/board.c (renamed from ports/stm32f4/boards/feather_f405/board.c)0
-rw-r--r--ports/nrf/boards/itsybitsy_nrf52840_express/mpconfigboard.h46
-rw-r--r--ports/nrf/boards/itsybitsy_nrf52840_express/mpconfigboard.mk13
-rw-r--r--ports/nrf/boards/itsybitsy_nrf52840_express/pins.c46
-rw-r--r--ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h1
-rw-r--r--ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk16
-rw-r--r--ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.h1
-rw-r--r--ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.mk17
-rw-r--r--ports/nrf/boards/metro_nrf52840_express/mpconfigboard.h1
-rw-r--r--ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk16
-rw-r--r--ports/nrf/boards/particle_argon/mpconfigboard.h1
-rw-r--r--ports/nrf/boards/particle_argon/mpconfigboard.mk16
-rw-r--r--ports/nrf/boards/particle_boron/mpconfigboard.h1
-rw-r--r--ports/nrf/boards/particle_boron/mpconfigboard.mk16
-rw-r--r--ports/nrf/boards/particle_xenon/mpconfigboard.h1
-rw-r--r--ports/nrf/boards/particle_xenon/mpconfigboard.mk16
-rw-r--r--ports/nrf/boards/pca10056/mpconfigboard.h1
-rw-r--r--ports/nrf/boards/pca10056/mpconfigboard.mk16
-rw-r--r--ports/nrf/boards/pca10059/mpconfigboard.h1
-rw-r--r--ports/nrf/boards/pca10059/mpconfigboard.mk17
-rw-r--r--ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.h1
-rw-r--r--ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.mk16
-rw-r--r--ports/nrf/common-hal/_bleio/Adapter.c523
-rw-r--r--ports/nrf/common-hal/_bleio/Adapter.h20
-rw-r--r--ports/nrf/common-hal/_bleio/Central.c145
-rw-r--r--ports/nrf/common-hal/_bleio/Characteristic.c144
-rw-r--r--ports/nrf/common-hal/_bleio/Characteristic.h5
-rw-r--r--ports/nrf/common-hal/_bleio/CharacteristicBuffer.c17
-rw-r--r--ports/nrf/common-hal/_bleio/Connection.c630
-rw-r--r--ports/nrf/common-hal/_bleio/Connection.h (renamed from ports/nrf/common-hal/_bleio/Peripheral.h)39
-rw-r--r--ports/nrf/common-hal/_bleio/Descriptor.c58
-rw-r--r--ports/nrf/common-hal/_bleio/Descriptor.h9
-rw-r--r--ports/nrf/common-hal/_bleio/Peripheral.c361
-rw-r--r--ports/nrf/common-hal/_bleio/Scanner.c105
-rw-r--r--ports/nrf/common-hal/_bleio/Service.c50
-rw-r--r--ports/nrf/common-hal/_bleio/Service.h12
-rw-r--r--ports/nrf/common-hal/_bleio/UUID.c36
-rw-r--r--ports/nrf/common-hal/_bleio/__init__.c511
-rw-r--r--ports/nrf/common-hal/_bleio/__init__.h8
-rw-r--r--ports/nrf/common-hal/audiobusio/I2SOut.c40
-rw-r--r--ports/nrf/common-hal/busio/I2C.c29
-rw-r--r--ports/nrf/common-hal/busio/UART.c28
-rw-r--r--ports/nrf/common-hal/microcontroller/Pin.c36
-rw-r--r--ports/nrf/common-hal/microcontroller/__init__.c4
-rw-r--r--ports/nrf/common-hal/nvm/ByteArray.c2
-rw-r--r--ports/nrf/common-hal/time/__init__.c2
-rw-r--r--ports/nrf/mpconfigport.h61
-rw-r--r--ports/nrf/mpconfigport.mk43
-rw-r--r--ports/nrf/mphalport.c5
-rw-r--r--ports/nrf/mphalport.h5
-rw-r--r--ports/nrf/nrfx_config.h33
-rw-r--r--ports/nrf/supervisor/port.c8
-rw-r--r--ports/nrf/tick.c33
-rw-r--r--ports/nrf/tick.h2
-rwxr-xr-xports/stm32f4/Makefile2
-rw-r--r--ports/stm32f4/boards/feather_stm32f405_express/board.c (renamed from shared-bindings/_bleio/Scanner.h)21
-rw-r--r--ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.h51
-rw-r--r--ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.mk (renamed from ports/stm32f4/boards/feather_f405/mpconfigboard.mk)2
-rw-r--r--ports/stm32f4/boards/feather_stm32f405_express/pins.c (renamed from ports/stm32f4/boards/feather_f405/pins.c)5
-rw-r--r--ports/stm32f4/boards/feather_stm32f405_express/stm32f4xx_hal_conf.h (renamed from ports/stm32f4/boards/feather_f405/stm32f4xx_hal_conf.h)6
-rw-r--r--ports/stm32f4/boards/pyboard_v11/mpconfigboard.h7
-rw-r--r--ports/stm32f4/boards/pyboard_v11/pins.c2
-rw-r--r--ports/stm32f4/boards/pyboard_v11/stm32f4xx_hal_conf.h4
-rw-r--r--ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h3
-rw-r--r--ports/stm32f4/boards/stm32f411ve_discovery/stm32f4xx_hal_conf.h2
-rw-r--r--ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h6
-rw-r--r--ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk1
-rw-r--r--ports/stm32f4/boards/stm32f412zg_discovery/pins.c6
-rw-r--r--ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h4
-rw-r--r--ports/stm32f4/common-hal/analogio/AnalogOut.c19
-rw-r--r--ports/stm32f4/common-hal/analogio/AnalogOut.h2
-rw-r--r--ports/stm32f4/common-hal/busio/SPI.c220
-rw-r--r--ports/stm32f4/common-hal/busio/UART.c541
-rw-r--r--ports/stm32f4/common-hal/busio/UART.h28
-rw-r--r--ports/stm32f4/common-hal/microcontroller/Pin.c43
-rw-r--r--ports/stm32f4/common-hal/microcontroller/Pin.h8
-rw-r--r--ports/stm32f4/common-hal/microcontroller/__init__.c53
-rw-r--r--ports/stm32f4/common-hal/neopixel_write/__init__.c96
-rw-r--r--ports/stm32f4/common-hal/os/__init__.c35
-rw-r--r--ports/stm32f4/common-hal/pulseio/PWMOut.c399
-rw-r--r--ports/stm32f4/common-hal/pulseio/PWMOut.h51
-rw-r--r--ports/stm32f4/common-hal/pulseio/PulseIn.c79
-rw-r--r--ports/stm32f4/common-hal/pulseio/PulseIn.h53
-rw-r--r--ports/stm32f4/common-hal/pulseio/PulseOut.c55
-rw-r--r--ports/stm32f4/common-hal/pulseio/PulseOut.h (renamed from ports/nrf/common-hal/_bleio/Central.h)24
-rw-r--r--ports/stm32f4/common-hal/pulseio/__init__.c1
-rw-r--r--ports/stm32f4/common-hal/time/__init__.c2
-rw-r--r--ports/stm32f4/mpconfigport.h3
-rw-r--r--ports/stm32f4/mpconfigport.mk40
-rw-r--r--ports/stm32f4/mphalport.c6
-rw-r--r--ports/stm32f4/mphalport.h6
-rw-r--r--ports/stm32f4/peripherals/stm32f4/periph.h50
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f405xx/clocks.c6
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.c108
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.h12
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.c74
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.h13
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.c102
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.h13
-rw-r--r--ports/stm32f4/supervisor/port.c24
-rw-r--r--ports/stm32f4/tick.c37
-rw-r--r--ports/stm32f4/tick.h2
-rw-r--r--py/circuitpy_defns.mk5
-rw-r--r--py/circuitpy_mpconfig.h22
-rw-r--r--py/circuitpy_mpconfig.mk20
-rw-r--r--py/compile.c15
-rw-r--r--py/emitnative.c18
-rwxr-xr-xpy/gc.c10
-rw-r--r--py/gc.h11
-rwxr-xr-xpy/gc_long_lived.c5
-rw-r--r--py/makeqstrdata.py39
-rw-r--r--py/objfun.c2
-rw-r--r--py/py.mk2
-rw-r--r--py/ringbuf.h7
-rw-r--r--py/runtime.c2
-rw-r--r--py/vm.c2
-rw-r--r--shared-bindings/_bleio/Adapter.c299
-rw-r--r--shared-bindings/_bleio/Adapter.h28
-rw-r--r--shared-bindings/_bleio/Address.c30
-rw-r--r--shared-bindings/_bleio/Central.c207
-rw-r--r--shared-bindings/_bleio/Characteristic.c37
-rw-r--r--shared-bindings/_bleio/Characteristic.h6
-rw-r--r--shared-bindings/_bleio/CharacteristicBuffer.c8
-rw-r--r--shared-bindings/_bleio/Connection.c216
-rw-r--r--shared-bindings/_bleio/Connection.h (renamed from shared-bindings/_bleio/Central.h)20
-rw-r--r--shared-bindings/_bleio/Descriptor.c13
-rw-r--r--shared-bindings/_bleio/Descriptor.h2
-rw-r--r--shared-bindings/_bleio/Peripheral.c325
-rw-r--r--shared-bindings/_bleio/Peripheral.h48
-rw-r--r--shared-bindings/_bleio/ScanEntry.c74
-rw-r--r--shared-bindings/_bleio/ScanEntry.h3
-rw-r--r--shared-bindings/_bleio/ScanResults.c72
-rw-r--r--shared-bindings/_bleio/ScanResults.h (renamed from ports/nrf/common-hal/_bleio/Scanner.h)17
-rw-r--r--shared-bindings/_bleio/Scanner.c129
-rw-r--r--shared-bindings/_bleio/Service.c76
-rw-r--r--shared-bindings/_bleio/Service.h14
-rw-r--r--shared-bindings/_bleio/UUID.c51
-rw-r--r--shared-bindings/_bleio/UUID.h5
-rw-r--r--shared-bindings/_bleio/__init__.c88
-rw-r--r--shared-bindings/_bleio/__init__.h40
-rw-r--r--shared-bindings/_pixelbuf/__init__.c4
-rw-r--r--shared-bindings/audiobusio/I2SOut.c5
-rw-r--r--shared-bindings/audioio/__init__.c2
-rw-r--r--shared-bindings/board/__init__.c6
-rw-r--r--shared-bindings/busio/I2C.c4
-rw-r--r--shared-bindings/busio/SPI.c7
-rw-r--r--shared-bindings/busio/UART.c46
-rw-r--r--shared-bindings/busio/UART.h3
-rw-r--r--shared-bindings/microcontroller/Pin.h2
-rw-r--r--shared-bindings/pulseio/PWMOut.c11
-rw-r--r--shared-bindings/rtc/RTC.c23
-rw-r--r--shared-bindings/rtc/__init__.c16
-rw-r--r--shared-bindings/time/__init__.c4
-rw-r--r--shared-module/_bleio/ScanEntry.c43
-rw-r--r--shared-module/_bleio/ScanEntry.h7
-rw-r--r--shared-module/_bleio/ScanResults.c139
-rw-r--r--shared-module/_bleio/ScanResults.h64
-rw-r--r--shared-module/bitbangio/SPI.c5
-rw-r--r--shared-module/board/__init__.c2
-rw-r--r--shared-module/displayio/Display.c13
-rw-r--r--shared-module/displayio/EPaperDisplay.c12
-rw-r--r--shared-module/displayio/FourWire.c13
-rw-r--r--shared-module/displayio/I2CDisplay.c24
-rw-r--r--shared-module/displayio/display_core.c5
-rw-r--r--shared-module/network/__init__.c4
-rw-r--r--shared-module/usb_hid/Device.c5
-rw-r--r--supervisor/port.h6
-rw-r--r--supervisor/shared/autoreload.c8
-rw-r--r--supervisor/shared/autoreload.h2
-rw-r--r--supervisor/shared/bluetooth.c340
-rw-r--r--supervisor/shared/bluetooth.h34
-rw-r--r--supervisor/shared/external_flash/devices.h17
-rw-r--r--supervisor/shared/filesystem.c15
-rwxr-xr-xsupervisor/shared/memory.c7
-rw-r--r--supervisor/shared/rgb_led_colors.h24
-rw-r--r--supervisor/shared/rgb_led_status.c67
-rw-r--r--supervisor/shared/safe_mode.c5
-rw-r--r--supervisor/shared/safe_mode.h3
-rwxr-xr-xsupervisor/shared/stack.c3
-rw-r--r--supervisor/shared/tick.c94
-rw-r--r--supervisor/shared/tick.h67
-rw-r--r--supervisor/shared/translate.c20
-rw-r--r--supervisor/supervisor.mk29
-rw-r--r--tools/build_board_info.py1
-rw-r--r--tools/build_memory_info.py8
-rwxr-xr-xtools/gen_ld_files.py39
-rw-r--r--tools/gen_usb_descriptor.py28
306 files changed, 11392 insertions, 5167 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index e81562861..7fd816b30 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,6 +1,12 @@
name: Build CI
-on: [push, pull_request, release]
+on:
+ push:
+ pull_request:
+ release:
+ types: [published]
+ check_suite:
+ types: [rerequested]
jobs:
test:
@@ -10,9 +16,6 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - name: Fail if not a release publish # workaround has `on` doesn't have this filter
- run: exit 1
- if: github.event_name == 'release' && (github.event.action != 'published' && github.event.action != 'rerequested')
- name: Set up Python 3.5
uses: actions/setup-python@v1
with:
@@ -49,9 +52,6 @@ jobs:
done
working-directory: tests
if: failure()
- - name: Test threads
- run: MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread
- working-directory: tests
- name: Native Tests
run: MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native
working-directory: tests
@@ -75,6 +75,7 @@ jobs:
board:
- "arduino_mkr1300"
- "arduino_mkrzero"
+ - "arduino_nano_33_ble"
- "arduino_zero"
- "bast_pro_mini_m0"
- "capablerobot_usbhub"
@@ -92,7 +93,6 @@ jobs:
- "electronut_labs_blip"
- "electronut_labs_papyr"
- "escornabot_makech"
- - "feather_f405"
- "feather_m0_adalogger"
- "feather_m0_basic"
- "feather_m0_express"
@@ -103,12 +103,14 @@ jobs:
- "feather_m4_express"
- "feather_nrf52840_express"
- "feather_radiofruit_zigbee"
+ - "feather_stm32f405_express"
- "gemma_m0"
- "grandcentral_m4_express"
- "hallowing_m0_express"
- "hallowing_m4_express"
- "itsybitsy_m0_express"
- "itsybitsy_m4_express"
+ - "itsybitsy_nrf52840_express"
- "kicksat-sprite"
- "makerdiary_nrf52840_mdk"
- "makerdiary_nrf52840_mdk_usb_dongle"
@@ -135,13 +137,15 @@ jobs:
- "pyportal"
- "pyportal_titano"
- "pyruler"
- - "robohatmm1_m0"
- "robohatmm1_m4"
- "sam32"
- "serpente"
+ - "shirtty"
- "snekboard"
- "sparkfun_lumidrive"
- "sparkfun_nrf52840_mini"
+ - "sparkfun_qwiic_micro_no_flash"
+ - "sparkfun_qwiic_micro_with_flash"
- "sparkfun_redboard_turbo"
- "sparkfun_samd21_dev"
- "sparkfun_samd21_mini"
@@ -154,6 +158,7 @@ jobs:
- "trinket_m0_haxpress"
- "uchip"
- "ugame10"
+ - "winterbloom_sol"
steps:
- name: Set up Python 3.5
@@ -164,7 +169,8 @@ jobs:
run: |
sudo apt-get install -y gettext
pip install requests sh click setuptools awscli
- wget https://s3.amazonaws.com/adafruit-circuit-python/gcc-arm-embedded_7-2018q2-1~xenial1_amd64.deb && sudo dpkg -i gcc-arm-embedded*_amd64.deb
+ wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2
+ sudo tar -C /usr --strip-components=1 -xaf gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2
- name: Versions
run: |
gcc --version
@@ -185,7 +191,7 @@ jobs:
name: ${{ matrix.board }}
path: bin/${{ matrix.board }}
- name: Upload to S3
- run: aws s3 cp bin/ s3://adafruit-circuit-python/bin/ --recursive --no-progress --region us-east-1
+ run: "[ -z \"$AWS_ACCESS_KEY_ID\" ] || aws s3 cp bin/ s3://adafruit-circuit-python/bin/ --recursive --no-progress --region us-east-1"
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
@@ -194,7 +200,7 @@ jobs:
run: |
pip install uritemplate
- name: Upload to Release
- run: python3 -u upload_release_files.py
+ run: "[ -z \"$ADABOT_GITHUB_ACCESS_TOKEN\" ] || python3 -u upload_release_files.py"
working-directory: tools
env:
UPLOAD_URL: ${{ github.event.release.upload_url }}
diff --git a/.github/workflows/create_website_pr.yml b/.github/workflows/create_website_pr.yml
index ce9323702..69ca8f12b 100644
--- a/.github/workflows/create_website_pr.yml
+++ b/.github/workflows/create_website_pr.yml
@@ -1,6 +1,8 @@
name: Update CircuitPython.org
-on: release
+on:
+ release:
+ types: [published]
jobs:
website:
@@ -10,9 +12,6 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - name: Fail if not a release publish # workaround has `on` doesn't have this filter
- run: exit 1
- if: github.event.action != 'published'
- name: Set up Python 3.5
uses: actions/setup-python@v1
with:
diff --git a/Makefile b/Makefile
index b9c489fd4..d7127b517 100644
--- a/Makefile
+++ b/Makefile
@@ -204,7 +204,7 @@ pseudoxml:
all-source:
locale/circuitpython.pot: all-source
- find $(TRANSLATE_SOURCES) -iname "*.c" -print0 | (LC_ALL=C sort -z) | xargs -0 xgettext -L C -s --add-location=file --keyword=translate -o circuitpython.pot -p locale
+ find $(TRANSLATE_SOURCES) -iname "*.c" -print | (LC_ALL=C sort) | xgettext -f- -L C -s --add-location=file --keyword=translate -o circuitpython.pot -p locale
translate: locale/circuitpython.pot
for po in $(shell ls locale/*.po); do msgmerge -U $$po -s --no-fuzzy-matching --add-location=file locale/circuitpython.pot; done
diff --git a/drivers/wiznet5k/internet/dns/dns.c b/drivers/wiznet5k/internet/dns/dns.c
index daf4db123..8b9e96670 100644
--- a/drivers/wiznet5k/internet/dns/dns.c
+++ b/drivers/wiznet5k/internet/dns/dns.c
@@ -52,7 +52,7 @@
#include <string.h>
#include <stdlib.h>
-#include "tick.h"
+#include "supervisor/shared/tick.h"
//#include "Ethernet/socket.h"
//#include "Internet/DNS/dns.h"
@@ -125,7 +125,7 @@ uint16_t DNS_MSGID; // DNS message ID
uint32_t HAL_GetTick(void) {
- return ticks_ms;
+ return supervisor_ticks_ms32();
}
uint32_t hal_sys_tick;
diff --git a/lib/stm32lib b/lib/stm32lib
deleted file mode 160000
-Subproject d2bcfda543d3b99361e44112aca929225bdcc07
diff --git a/lib/utils/interrupt_char.c b/lib/utils/interrupt_char.c
index 91ee5c80e..da7f70254 100644
--- a/lib/utils/interrupt_char.c
+++ b/lib/utils/interrupt_char.c
@@ -49,7 +49,7 @@ void mp_keyboard_interrupt(void) {
// Check to see if we've been CTRL-C'ed by autoreload or the user.
bool mp_hal_is_interrupted(void) {
- return MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception));
+ return MP_STATE_VM(mp_pending_exception) != NULL;
}
#endif
diff --git a/locale/ID.po b/locale/ID.po
index 63e3466b6..6a0b73b6f 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-11-27 14:54-0500\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"
@@ -261,6 +261,10 @@ msgstr "Semua timer untuk pin ini sedang digunakan"
msgid "All timers in use"
msgstr "Semua timer sedang digunakan"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "fungsionalitas AnalogOut tidak didukung"
@@ -329,6 +333,11 @@ msgstr ""
msgid "Brightness not adjustable"
msgstr ""
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -465,6 +474,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr ""
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -473,11 +488,6 @@ msgstr ""
msgid "Corrupt raw code"
msgstr ""
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Could not decode ble_uuid, err 0x%04x"
-msgstr ""
-
#: ports/atmel-samd/common-hal/busio/UART.c
msgid "Could not initialize UART"
msgstr "Tidak dapat menginisialisasi UART"
@@ -507,7 +517,7 @@ msgstr ""
msgid "Data chunk must follow fmt chunk"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, fuzzy
msgid "Data too large for advertisement packet"
msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment"
@@ -554,10 +564,6 @@ msgstr ""
msgid "Expected a Characteristic"
msgstr ""
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -567,7 +573,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr ""
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -585,21 +591,6 @@ msgstr ""
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX"
-#: ports/nrf/common-hal/_bleio/Service.c
-#, fuzzy, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Gagal untuk menambahkan karakteristik, status: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to add descriptor, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Gagal untuk mengalokasikan buffer RX"
@@ -611,119 +602,18 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Gagal untuk megalokasikan buffer RX dari %d byte"
#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to change softdevice state"
-msgstr "Gagal untuk merubah status softdevice, error: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Central.c
-msgid "Failed to connect: timeout"
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, fuzzy, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy
-msgid "Failed to discover services"
-msgstr "Gagal untuk menemukan layanan, status: 0x%08lX"
-
#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to get local address"
-msgstr "Gagal untuk mendapatkan alamat lokal, error: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to get softdevice state"
-msgstr "Gagal untuk mendapatkan status softdevice, error: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to notify or indicate attribute value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-msgid "Failed to pair"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, fuzzy, c-format
-msgid "Failed to read CCCD value, err 0x%04x"
-msgstr "Gagal untuk membaca nilai atribut, status: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#: ports/nrf/common-hal/_bleio/Descriptor.c
-#, c-format
-msgid "Failed to read attribute value, err 0x%04x"
+msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy, c-format
-msgid "Failed to read gatts value, err 0x%04x"
-msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, fuzzy, c-format
-msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
-msgstr "Gagal untuk menambahkan Vendor Spesific UUID, status: 0x%08lX"
-
#: ports/nrf/sd_mutex.c
#, fuzzy, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "Gagal untuk memulai advertisement, status: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Central.c
-#, c-format
-msgid "Failed to start connecting, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start pairing, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, fuzzy, c-format
-msgid "Failed to start scanning, err 0x%04x"
-msgstr "Gagal untuk melakukan scanning, status: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to write CCCD, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy, c-format
-msgid "Failed to write attribute value, err 0x%04x"
-msgstr "Gagal untuk menulis nilai atribut, status: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy, c-format
-msgid "Failed to write gatts value, err 0x%04x"
-msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX"
-
#: py/moduerrno.c
msgid "File exists"
msgstr ""
@@ -786,6 +676,14 @@ msgstr ""
msgid "Input/output error"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient authentication"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient encryption"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
@@ -1004,9 +902,8 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
#, fuzzy
msgid "Not connected"
msgstr "Tidak dapat menyambungkan ke AP"
@@ -1081,6 +978,10 @@ msgstr "Tambahkan module apapun pada filesystem\n"
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1137,7 +1038,7 @@ msgid "Running in safe mode! Not running saved code.\n"
msgstr ""
"Berjalan di mode aman(safe mode)! tidak menjalankan kode yang tersimpan.\n"
-#: ports/atmel-samd/common-hal/busio/I2C.c
+#: ports/atmel-samd/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
msgid "SDA or SCL needs a pull up"
msgstr "SDA atau SCL membutuhkan pull up"
@@ -1151,6 +1052,10 @@ msgstr ""
msgid "Sample rate too high. It must be less than %d"
msgstr "Nilai sampel terlalu tinggi. Nilai harus kurang dari %d"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1165,11 +1070,6 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr "Dukungan soft device, id: 0x%08lX, pc: 0x%08l"
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Memisahkan dengan menggunakan sub-captures"
@@ -1323,11 +1223,32 @@ msgstr ""
msgid "Unexpected nrfx uuid type"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown gatt error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown security error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown soft device error: %04x"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Unmatched number of items on RHS (expected %d, got %d)."
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid ""
+"Unspecified issue. Can be that the pairing prompt on the other device was "
+"declined or ignored."
+msgstr ""
+
#: ports/atmel-samd/common-hal/busio/I2C.c
msgid "Unsupported baudrate"
msgstr "Baudrate tidak didukung"
@@ -1984,7 +1905,7 @@ msgstr ""
msgid "integer required"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2161,11 +2082,6 @@ msgstr ""
msgid "name '%q' is not defined"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c
-#, fuzzy
-msgid "name must be a string"
-msgstr "keyword harus berupa string"
-
#: py/runtime.c
msgid "name not defined"
msgstr ""
@@ -2216,7 +2132,7 @@ msgstr ""
msgid "no such attribute"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2538,12 +2454,8 @@ msgstr ""
msgid "time.struct_time() takes a 9-sequence"
msgstr ""
-#: shared-bindings/time/__init__.c
-msgid "time.struct_time() takes exactly 1 argument"
-msgstr ""
-
#: shared-bindings/busio/UART.c
-msgid "timeout >100 (units are now seconds, not msecs)"
+msgid "timeout must be 0.0-100.0 seconds"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
@@ -2700,7 +2612,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr ""
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
@@ -2771,10 +2683,22 @@ msgstr ""
#~ msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX"
#, fuzzy
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Gagal untuk menambahkan karakteristik, status: 0x%08lX"
+
+#, fuzzy
#~ msgid "Failed to add service"
#~ msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX"
#, fuzzy
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "Gagal untuk merubah status softdevice, error: 0x%08lX"
+
+#, fuzzy
#~ msgid "Failed to connect:"
#~ msgstr "Gagal untuk menyambungkan, status: 0x%08lX"
@@ -2783,18 +2707,46 @@ msgstr ""
#~ msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX"
#, fuzzy
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ 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 discover services"
+#~ msgstr "Gagal untuk menemukan layanan, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to get local address"
+#~ msgstr "Gagal untuk mendapatkan alamat lokal, error: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to get softdevice state"
+#~ msgstr "Gagal untuk mendapatkan status softdevice, error: 0x%08lX"
+
+#, fuzzy
#~ msgid "Failed to notify or indicate attribute value, err %0x04x"
#~ msgstr "Gagal untuk melaporkan nilai atribut, status: 0x%08lX"
#, fuzzy
+#~ msgid "Failed to read CCCD value, err 0x%04x"
+#~ msgstr "Gagal untuk membaca nilai atribut, status: 0x%08lX"
+
+#, fuzzy
#~ msgid "Failed to read attribute value, err %0x04x"
#~ msgstr "Gagal untuk membaca nilai atribut, status: 0x%08lX"
#, fuzzy
+#~ msgid "Failed to read gatts value, err 0x%04x"
+#~ msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
+#~ msgstr "Gagal untuk menambahkan Vendor Spesific UUID, status: 0x%08lX"
+
+#, fuzzy
#~ msgid "Failed to release mutex"
#~ msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX"
@@ -2803,13 +2755,33 @@ msgstr ""
#~ msgstr "Gagal untuk memulai advertisement, status: 0x%08lX"
#, fuzzy
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ 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 start scanning, err 0x%04x"
+#~ msgstr "Gagal untuk melakukan scanning, status: 0x%08lX"
+
+#, fuzzy
#~ msgid "Failed to stop advertising"
#~ msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX"
+#, fuzzy
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to write attribute value, err 0x%04x"
+#~ msgstr "Gagal untuk menulis nilai atribut, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to write gatts value, err 0x%04x"
+#~ msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX"
+
#~ msgid "GPIO16 does not support pull up."
#~ msgstr "GPIO16 tidak mendukung pull up"
@@ -2859,6 +2831,10 @@ msgstr ""
#~ msgid "STA required"
#~ msgstr "STA dibutuhkan"
+#, fuzzy
+#~ msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
+#~ msgstr "Dukungan soft device, id: 0x%08lX, pc: 0x%08l"
+
#~ msgid "UART(%d) does not exist"
#~ msgstr "UART(%d) tidak ada"
@@ -2936,6 +2912,10 @@ msgstr ""
#~ msgid "memory allocation failed, allocating %u bytes for native code"
#~ msgstr "alokasi memori gagal, mengalokasikan %u byte untuk kode native"
+#, fuzzy
+#~ msgid "name must be a string"
+#~ msgstr "keyword harus berupa string"
+
#~ msgid "not a valid ADC Channel: %d"
#~ msgstr "tidak valid channel ADC: %d"
diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot
index d709a69cc..d3bd2d978 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-12-04 10:16-0500\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"
@@ -259,6 +259,10 @@ msgstr ""
msgid "All timers in use"
msgstr ""
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr ""
@@ -325,6 +329,11 @@ msgstr ""
msgid "Brightness not adjustable"
msgstr ""
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -455,6 +464,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr ""
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -463,11 +478,6 @@ msgstr ""
msgid "Corrupt raw code"
msgstr ""
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Could not decode ble_uuid, err 0x%04x"
-msgstr ""
-
#: ports/atmel-samd/common-hal/busio/UART.c
msgid "Could not initialize UART"
msgstr ""
@@ -497,7 +507,7 @@ msgstr ""
msgid "Data chunk must follow fmt chunk"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Data too large for advertisement packet"
msgstr ""
@@ -543,10 +553,6 @@ msgstr ""
msgid "Expected a Characteristic"
msgstr ""
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -556,7 +562,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr ""
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -574,21 +580,6 @@ msgstr ""
msgid "Failed to acquire mutex, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Service.c
-#, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to add descriptor, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr ""
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr ""
@@ -600,63 +591,11 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr ""
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to change softdevice state"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Central.c
-msgid "Failed to connect: timeout"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-msgid "Failed to discover services"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to get local address"
+msgid "Failed to connect: internal error"
msgstr ""
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to get softdevice state"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to notify or indicate attribute value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-msgid "Failed to pair"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to read CCCD value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#: ports/nrf/common-hal/_bleio/Descriptor.c
-#, c-format
-msgid "Failed to read attribute value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to read gatts value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
+msgid "Failed to connect: timeout"
msgstr ""
#: ports/nrf/sd_mutex.c
@@ -664,51 +603,6 @@ msgstr ""
msgid "Failed to release mutex, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Central.c
-#, c-format
-msgid "Failed to start connecting, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start pairing, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to start scanning, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to write CCCD, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to write attribute value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to write gatts value, err 0x%04x"
-msgstr ""
-
#: py/moduerrno.c
msgid "File exists"
msgstr ""
@@ -771,6 +665,14 @@ msgstr ""
msgid "Input/output error"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient authentication"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient encryption"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
@@ -989,9 +891,8 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
msgid "Not connected"
msgstr ""
@@ -1065,6 +966,10 @@ msgstr ""
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1117,7 +1022,7 @@ msgstr ""
msgid "Running in safe mode! Not running saved code.\n"
msgstr ""
-#: ports/atmel-samd/common-hal/busio/I2C.c
+#: ports/atmel-samd/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
msgid "SDA or SCL needs a pull up"
msgstr ""
@@ -1131,6 +1036,10 @@ msgstr ""
msgid "Sample rate too high. It must be less than %d"
msgstr ""
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1145,11 +1054,6 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr ""
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr ""
@@ -1300,11 +1204,32 @@ msgstr ""
msgid "Unexpected nrfx uuid type"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown gatt error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown security error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown soft device error: %04x"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Unmatched number of items on RHS (expected %d, got %d)."
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid ""
+"Unspecified issue. Can be that the pairing prompt on the other device was "
+"declined or ignored."
+msgstr ""
+
#: ports/atmel-samd/common-hal/busio/I2C.c
msgid "Unsupported baudrate"
msgstr ""
@@ -1950,7 +1875,7 @@ msgstr ""
msgid "integer required"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2127,10 +2052,6 @@ msgstr ""
msgid "name '%q' is not defined"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c
-msgid "name must be a string"
-msgstr ""
-
#: py/runtime.c
msgid "name not defined"
msgstr ""
@@ -2181,7 +2102,7 @@ msgstr ""
msgid "no such attribute"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2502,12 +2423,8 @@ msgstr ""
msgid "time.struct_time() takes a 9-sequence"
msgstr ""
-#: shared-bindings/time/__init__.c
-msgid "time.struct_time() takes exactly 1 argument"
-msgstr ""
-
#: shared-bindings/busio/UART.c
-msgid "timeout >100 (units are now seconds, not msecs)"
+msgid "timeout must be 0.0-100.0 seconds"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
@@ -2663,7 +2580,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr ""
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
diff --git a/locale/de_DE.po b/locale/de_DE.po
index d8fbc1f0d..37937b94f 100644
--- a/locale/de_DE.po
+++ b/locale/de_DE.po
@@ -7,11 +7,11 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-11-27 14:54-0500\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: Pascal Deneaux\n"
"Language-Team: Sebastian Plamauer, Pascal Deneaux\n"
-"Language: en_US\n"
+"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -261,6 +261,10 @@ msgstr "Alle timer für diesen Pin werden bereits benutzt"
msgid "All timers in use"
msgstr "Alle timer werden benutzt"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "AnalogOut-Funktion wird nicht unterstützt"
@@ -329,6 +333,11 @@ msgstr "Die Helligkeit muss zwischen 0 und 255 liegen"
msgid "Brightness not adjustable"
msgstr "Die Helligkeit ist nicht einstellbar"
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -336,7 +345,7 @@ msgstr "Der Puffergröße ist inkorrekt. Sie sollte %d bytes haben."
#: shared-bindings/displayio/Display.c
msgid "Buffer is not a bytearray."
-msgstr ""
+msgstr "Der Puffer ist kein Byte-Array"
#: shared-bindings/displayio/Display.c
msgid "Buffer is too small"
@@ -345,7 +354,7 @@ msgstr "Der Puffer ist zu klein"
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
#, c-format
msgid "Buffer length %d too big. It must be less than %d"
-msgstr ""
+msgstr "Die Pufferlänge %d ist zu groß. Sie muss kleiner als %d sein."
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
@@ -367,7 +376,7 @@ msgstr "Ein Bytes kann nur Werte zwischen 0 und 255 annehmen."
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
-msgstr ""
+msgstr "Rufe super().__init__() vor dem Zugriff auf ein natives Objekt auf."
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
@@ -449,28 +458,29 @@ msgstr "Clock unit wird benutzt"
#: shared-bindings/_pew/PewPew.c
msgid "Column entry must be digitalio.DigitalInOut"
-msgstr ""
+msgstr "Spalteneintrag muss digitalio.DigitalInOut sein"
#: shared-bindings/displayio/I2CDisplay.c
msgid "Command must be 0-255"
-msgstr ""
+msgstr "Der Befehl muss zwischen 0 und 255 liegen"
#: 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"
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
-msgstr ""
+msgstr "Beschädigte .mpy Datei"
#: py/emitglue.c
msgid "Corrupt raw code"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Could not decode ble_uuid, err 0x%04x"
-msgstr "Konnte ble_uuid nicht decodieren. Status: 0x%04x"
+msgstr "Beschädigter raw code"
#: ports/atmel-samd/common-hal/busio/UART.c
msgid "Could not initialize UART"
@@ -499,9 +509,9 @@ msgstr "Data 0 pin muss am Byte ausgerichtet sein"
#: shared-module/audiocore/WaveFile.c
msgid "Data chunk must follow fmt chunk"
-msgstr ""
+msgstr "Dem fmt Block muss ein Datenblock folgen"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Data too large for advertisement packet"
msgstr "Zu vielen Daten für das advertisement packet"
@@ -511,11 +521,11 @@ msgstr "Die Zielkapazität ist kleiner als destination_length."
#: ports/nrf/common-hal/audiobusio/I2SOut.c
msgid "Device in use"
-msgstr ""
+msgstr "Gerät in Benutzung"
#: shared-bindings/displayio/Display.c
msgid "Display must have a 16 bit colorspace."
-msgstr ""
+msgstr "Display muss einen 16 Bit Farbraum haben."
#: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
@@ -547,20 +557,16 @@ msgstr "Erwartet ein(e) %q"
msgid "Expected a Characteristic"
msgstr "Characteristic wird erwartet"
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
-msgstr ""
+msgstr "Ein Service wird erwartet"
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
#: shared-bindings/_bleio/Service.c
msgid "Expected a UUID"
msgstr "Eine UUID wird erwartet"
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr "Erwartet eine Adresse"
@@ -578,21 +584,6 @@ msgstr "Kommando nicht gesendet."
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Mutex konnte nicht akquiriert werden. Status: 0x%04x"
-#: ports/nrf/common-hal/_bleio/Service.c
-#, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Hinzufügen des Characteristic ist gescheitert. Status: 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to add descriptor, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Dienst konnte nicht hinzugefügt werden. Status: 0x%04x"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Konnte keinen RX Buffer allozieren"
@@ -604,115 +595,18 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Konnte keine RX Buffer mit %d allozieren"
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to change softdevice state"
-msgstr "Fehler beim Ändern des Softdevice-Status"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Failed to connect: timeout"
msgstr "Verbindung nicht erfolgreich: timeout"
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr "Der Scanvorgang kann nicht fortgesetzt werden. Status: 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-msgid "Failed to discover services"
-msgstr "Es konnten keine Dienste gefunden werden"
-
-#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to get local address"
-msgstr "Lokale Adresse konnte nicht abgerufen werden"
-
-#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to get softdevice state"
-msgstr "Fehler beim Abrufen des Softdevice-Status"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to notify or indicate attribute value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-msgid "Failed to pair"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to read CCCD value, err 0x%04x"
-msgstr "Kann CCCD value nicht lesen. Status: 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#: ports/nrf/common-hal/_bleio/Descriptor.c
-#, c-format
-msgid "Failed to read attribute value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to read gatts value, err 0x%04x"
-msgstr "gatts value konnte nicht gelesen werden. Status: 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
-msgstr "Kann keine herstellerspezifische UUID hinzufügen. Status: 0x%04x"
-
#: ports/nrf/sd_mutex.c
#, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "Mutex konnte nicht freigegeben werden. Status: 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "Kann advertisement nicht starten. Status: 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Central.c
-#, c-format
-msgid "Failed to start connecting, error 0x%04x"
-msgstr "Verbindung konnte nicht hergestellt werden. Fehler: 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start pairing, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to start scanning, err 0x%04x"
-msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "Kann advertisement nicht stoppen. Status: 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to write CCCD, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to write attribute value, err 0x%04x"
-msgstr "Kann den Attributwert nicht schreiben. Status: 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to write gatts value, err 0x%04x"
-msgstr "gatts value konnte nicht geschrieben werden. Status: 0x%04x"
-
#: py/moduerrno.c
msgid "File exists"
msgstr "Datei existiert"
@@ -738,6 +632,8 @@ msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
msgid "Frequency captured is above capability. Capture Paused."
msgstr ""
+"Die aufgezeichnete Frequenz liegt über der Leistungsgrenze. Aufnahme "
+"angehalten."
#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c
#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c
@@ -747,7 +643,7 @@ msgstr "Die Funktion erwartet, dass der 'lock'-Befehl zuvor ausgeführt wurde"
#: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Group already used"
-msgstr ""
+msgstr "Gruppe schon benutzt"
#: shared-module/displayio/Group.c
msgid "Group full"
@@ -771,12 +667,20 @@ msgstr ""
#: shared-bindings/_pew/PewPew.c
msgid "Incorrect buffer size"
-msgstr ""
+msgstr "Inkorrekte Puffergröße"
#: py/moduerrno.c
msgid "Input/output error"
msgstr "Eingabe-/Ausgabefehler"
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient authentication"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient encryption"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
@@ -797,7 +701,7 @@ msgstr "Ungültiges Argument"
#: shared-module/displayio/Bitmap.c
msgid "Invalid bits per value"
-msgstr ""
+msgstr "Ungültige Bits pro Wert"
#: ports/nrf/common-hal/busio/UART.c
msgid "Invalid buffer size"
@@ -805,7 +709,7 @@ msgstr "Ungültige Puffergröße"
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
msgid "Invalid capture period. Valid range: 1 - 500"
-msgstr ""
+msgstr "Ungültiger Aufnahmezeitraum. Gültiger Bereich: 1 - 500"
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid channel count"
@@ -859,7 +763,7 @@ msgstr "Ungültige Polarität"
#: shared-bindings/_bleio/Characteristic.c
msgid "Invalid properties"
-msgstr ""
+msgstr "Ungültige Eigenschaften"
#: shared-bindings/microcontroller/__init__.c
msgid "Invalid run mode."
@@ -867,11 +771,11 @@ msgstr "Ungültiger Ausführungsmodus"
#: shared-module/_bleio/Attribute.c
msgid "Invalid security_mode"
-msgstr ""
+msgstr "Ungültiger security_mode"
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
-msgstr ""
+msgstr "Ungültige Stimme"
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice count"
@@ -887,7 +791,7 @@ msgstr "LHS des Schlüsselwortarguments muss eine id sein"
#: shared-module/displayio/Group.c
msgid "Layer already in a group."
-msgstr ""
+msgstr "Layer ist bereits in einer Gruppe."
#: shared-module/displayio/Group.c
msgid "Layer must be a Group or TileGrid subclass."
@@ -942,11 +846,11 @@ msgstr ""
#: shared-bindings/displayio/Group.c
msgid "Must be a %q subclass."
-msgstr ""
+msgstr "Muss eine %q Unterklasse sein."
#: ports/nrf/common-hal/_bleio/Characteristic.c
msgid "No CCCD for this Characteristic"
-msgstr ""
+msgstr "Kein CCCD für diese Charakteristik"
#: ports/atmel-samd/common-hal/analogio/AnalogOut.c
msgid "No DAC on chip"
@@ -967,7 +871,7 @@ msgstr "Kein TX Pin"
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
msgid "No available clocks"
-msgstr ""
+msgstr "Keine Taktgeber verfügbar"
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
@@ -983,7 +887,7 @@ msgstr "Kein hardware random verfügbar"
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
msgid "No hardware support on clk pin"
-msgstr ""
+msgstr "Keine Hardwareunterstützung am clk Pin"
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
@@ -992,26 +896,25 @@ msgstr "Keine Hardwareunterstützung an diesem Pin"
#: shared-module/touchio/TouchIn.c
msgid "No pulldown on pin; 1Mohm recommended"
-msgstr ""
+msgstr "Kein Pulldown Widerstand am Pin; 1Mohm wird vorgeschlagen"
#: py/moduerrno.c
msgid "No space left on device"
-msgstr "Kein Speicherplatz auf Gerät"
+msgstr "Kein Speicherplatz mehr verfügbar auf dem Gerät"
#: py/moduerrno.c
msgid "No such file/directory"
msgstr "Keine solche Datei/Verzeichnis"
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
msgid "Not connected"
msgstr "Nicht verbunden"
#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c
#: shared-bindings/audiopwmio/PWMAudioOut.c
msgid "Not playing"
-msgstr "Spielt nicht"
+msgstr "Spielt nicht ab"
#: shared-bindings/util.c
msgid ""
@@ -1033,6 +936,8 @@ msgstr "Nur 8 oder 16 bit mono mit "
msgid ""
"Only Windows format, uncompressed BMP supported: given header size is %d"
msgstr ""
+"Nur Windows-Format, unkomprimiertes BMP unterstützt: die gegebene Header-"
+"Größe ist %d"
#: shared-module/displayio/OnDiskBitmap.c
#, c-format
@@ -1040,6 +945,8 @@ msgid ""
"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: "
"%d bpp given"
msgstr ""
+"Nur monochrome, indizierte 4bpp oder 8bpp, und 16bpp oder größere BMPs "
+"unterstützt: %d bpp wurden gegeben"
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "Only slices with step=1 (aka None) are supported"
@@ -1080,6 +987,10 @@ msgstr "und alle Module im Dateisystem \n"
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1100,7 +1011,7 @@ msgstr "Eine RTC wird auf diesem Board nicht unterstützt"
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "Range out of bounds"
-msgstr ""
+msgstr "Bereich außerhalb der Grenzen"
#: shared-bindings/pulseio/PulseIn.c
msgid "Read-only"
@@ -1116,7 +1027,7 @@ msgstr "Schreibgeschützte Objekt"
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
-msgstr ""
+msgstr "Zu früh neu geladen"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
@@ -1124,7 +1035,7 @@ msgstr "Rechter Kanal wird nicht unterstützt"
#: shared-bindings/_pew/PewPew.c
msgid "Row entry must be digitalio.DigitalInOut"
-msgstr ""
+msgstr "Zeileneintrag muss ein digitalio.DigitalInOut sein"
#: main.c
msgid "Running in safe mode! Auto-reload is off.\n"
@@ -1134,7 +1045,7 @@ msgstr "Sicherheitsmodus aktiv! Automatisches Neuladen ist deaktiviert.\n"
msgid "Running in safe mode! Not running saved code.\n"
msgstr "Sicherheitsmodus aktiv! Gespeicherter Code wird nicht ausgeführt\n"
-#: ports/atmel-samd/common-hal/busio/I2C.c
+#: ports/atmel-samd/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
msgid "SDA or SCL needs a pull up"
msgstr "SDA oder SCL brauchen pull up"
@@ -1148,6 +1059,10 @@ msgstr "Abtastrate muss positiv sein"
msgid "Sample rate too high. It must be less than %d"
msgstr "Abtastrate zu hoch. Wert muss unter %d liegen"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1162,11 +1077,6 @@ msgstr "Slice und Wert (value) haben unterschiedliche Längen."
msgid "Slices not supported"
msgstr "Slices werden nicht unterstützt"
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr ""
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Splitting mit sub-captures"
@@ -1199,6 +1109,8 @@ msgid ""
"The `microcontroller` module was used to boot into safe mode. Press reset to "
"exit safe mode.\n"
msgstr ""
+"Das `Mikrocontroller` Modul wurde benutzt, um in den Sicherheitsmodus zu "
+"starten. Drücke Reset um den Sicherheitsmodus zu verlassen.\n"
#: supervisor/shared/safe_mode.c
msgid ""
@@ -1288,7 +1200,7 @@ msgstr "USB Fehler"
#: shared-bindings/_bleio/UUID.c
msgid "UUID integer value must be 0-0xffff"
-msgstr ""
+msgstr "UUID Integer-Wert muss ein Wert von 0 bis 0xffff sein"
#: shared-bindings/_bleio/UUID.c
msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'"
@@ -1306,7 +1218,7 @@ msgstr "Konnte keine Buffer für Vorzeichenumwandlung allozieren"
#: shared-module/displayio/I2CDisplay.c
#, c-format
msgid "Unable to find I2C Display at %x"
-msgstr ""
+msgstr "Konnte kein I2C Display finden an %x"
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
@@ -1319,7 +1231,7 @@ msgstr "Parser konnte nicht gestartet werden"
#: shared-module/displayio/OnDiskBitmap.c
msgid "Unable to read color palette data"
-msgstr ""
+msgstr "Konnte Farbpalettendaten nicht lesen"
#: shared-bindings/nvm/ByteArray.c
msgid "Unable to write to nvm."
@@ -1329,6 +1241,21 @@ msgstr "Schreiben in nvm nicht möglich."
msgid "Unexpected nrfx uuid type"
msgstr "Unerwarteter nrfx uuid-Typ"
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown gatt error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown security error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown soft device error: %04x"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Unmatched number of items on RHS (expected %d, got %d)."
@@ -1336,6 +1263,12 @@ msgstr ""
"Nicht übereinstimmende Anzahl von Elementen auf der rechten Seite (erwartet "
"%d, %d erhalten)."
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid ""
+"Unspecified issue. Can be that the pairing prompt on the other device was "
+"declined or ignored."
+msgstr ""
+
#: ports/atmel-samd/common-hal/busio/I2C.c
msgid "Unsupported baudrate"
msgstr "Baudrate wird nicht unterstützt"
@@ -1364,7 +1297,7 @@ msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#: ports/nrf/common-hal/_bleio/Descriptor.c
msgid "Value length > max_length"
-msgstr ""
+msgstr "Länge des Wertes > max_length"
#: py/emitnative.c
msgid "Viper functions don't currently support more than 4 arguments"
@@ -1471,11 +1404,11 @@ msgstr ""
#: py/objstr.c
msgid "bad format string"
-msgstr ""
+msgstr "Falscher Formatstring"
#: py/binary.c
msgid "bad typecode"
-msgstr ""
+msgstr "Falscher Typcode"
#: py/emitnative.c
msgid "binary op %q not implemented"
@@ -1534,7 +1467,7 @@ msgstr ""
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "byteorder is not an instance of ByteOrder (got a %s)"
-msgstr ""
+msgstr "byteorder ist keine Instanz von ByteOrder (%s erhalten)"
#: ports/atmel-samd/common-hal/busio/UART.c
msgid "bytes > 8 bits not supported"
@@ -1558,7 +1491,7 @@ msgstr "Kalibrierwert nicht im Bereich von +/-127"
#: py/emitinlinethumb.c
msgid "can only have up to 4 parameters to Thumb assembly"
-msgstr ""
+msgstr "kann nur bis zu 4 Parameter für die Thumb assembly haben"
#: py/emitinlinextensa.c
msgid "can only have up to 4 parameters to Xtensa assembly"
@@ -1657,7 +1590,7 @@ msgstr "Laden von '%q' nicht möglich"
#: py/emitnative.c
msgid "can't load with '%q' index"
-msgstr ""
+msgstr "Laden mit '%q' index nicht möglich"
#: py/objgenerator.c
msgid "can't pend throw to just-started generator"
@@ -1669,7 +1602,7 @@ msgstr ""
#: py/objnamedtuple.c
msgid "can't set attribute"
-msgstr ""
+msgstr "kann Attribut nicht setzen"
#: py/emitnative.c
msgid "can't store '%q'"
@@ -1695,11 +1628,11 @@ msgstr ""
#: py/objtype.c
msgid "cannot create '%q' instances"
-msgstr ""
+msgstr "Kann '%q' Instanzen nicht erstellen"
#: py/objtype.c
msgid "cannot create instance"
-msgstr ""
+msgstr "Kann Instanz nicht erstellen"
#: py/runtime.c
msgid "cannot import name %q"
@@ -1727,31 +1660,32 @@ msgstr "chr() arg ist nicht in range(256)"
#: shared-bindings/displayio/Palette.c
msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)"
-msgstr ""
+msgstr "Farbpuffer muss 3 Bytes (RGB) oder 4 Bytes (RGB + pad byte) sein"
#: shared-bindings/displayio/Palette.c
msgid "color buffer must be a buffer or int"
-msgstr ""
+msgstr "Farbpuffer muss ein Puffer oder ein int sein"
#: shared-bindings/displayio/Palette.c
msgid "color buffer must be a bytearray or array of type 'b' or 'B'"
msgstr ""
+"Farbpuffer muss ein Byte-Array oder ein Array vom Typ 'b' oder 'B' sein"
#: shared-bindings/displayio/Palette.c
msgid "color must be between 0x000000 and 0xffffff"
-msgstr ""
+msgstr "Farbe muss zwischen 0x000000 und 0xffffff liegen"
#: shared-bindings/displayio/ColorConverter.c
msgid "color should be an int"
-msgstr ""
+msgstr "Farbe sollte ein int sein"
#: py/objcomplex.c
msgid "complex division by zero"
-msgstr ""
+msgstr "Komplexe Division durch null"
#: py/objfloat.c py/parsenum.c
msgid "complex values not supported"
-msgstr ""
+msgstr "Komplexe Zahlen nicht unterstützt"
#: extmod/moduzlib.c
msgid "compression header"
@@ -1759,15 +1693,15 @@ msgstr "kompression header"
#: py/parse.c
msgid "constant must be an integer"
-msgstr ""
+msgstr "constant muss ein integer sein"
#: py/emitnative.c
msgid "conversion to object"
-msgstr ""
+msgstr "Umwandlung zu Objekt"
#: py/parsenum.c
msgid "decimal numbers not supported"
-msgstr ""
+msgstr "Dezimalzahlen nicht unterstützt"
#: py/compile.c
msgid "default 'except' must be last"
@@ -1784,7 +1718,7 @@ msgstr ""
#: shared-bindings/audiobusio/PDMIn.c
msgid "destination_length must be an int >= 0"
-msgstr ""
+msgstr "destination_length muss ein int >= 0 sein"
#: py/objdict.c
msgid "dict update sequence has wrong length"
@@ -1817,7 +1751,7 @@ msgstr ""
#: shared-bindings/displayio/Shape.c
msgid "end_x should be an int"
-msgstr ""
+msgstr "end_x sollte ein int sein"
#: ports/nrf/common-hal/busio/UART.c
#, c-format
@@ -1991,10 +1925,10 @@ msgstr "int() arg 2 muss >= 2 und <= 36 sein"
msgid "integer required"
msgstr "integer erforderlich"
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
-msgstr ""
+msgstr "Das Intervall muss im Bereich %s-%s sein"
#: extmod/machine_i2c.c
msgid "invalid I2C peripheral"
@@ -2127,7 +2061,7 @@ msgstr ""
#: ports/nrf/common-hal/_bleio/Descriptor.c
#, c-format
msgid "max_length must be 0-%d when fixed_length is %s"
-msgstr ""
+msgstr "max_length muss 0-%d sein, wenn fixed_length %s ist"
#: py/runtime.c
msgid "maximum recursion depth exceeded"
@@ -2156,7 +2090,7 @@ msgstr ""
#: py/objtype.c
msgid "multiple inheritance not supported"
-msgstr ""
+msgstr "Mehrfache Vererbung nicht unterstützt"
#: py/emitnative.c
msgid "must raise an object"
@@ -2174,10 +2108,6 @@ msgstr "muss Schlüsselwortargument für key function verwenden"
msgid "name '%q' is not defined"
msgstr "Name '%q' ist nirgends definiert worden (Schreibweise kontrollieren)"
-#: shared-bindings/_bleio/Peripheral.c
-msgid "name must be a string"
-msgstr "name muss ein String sein"
-
#: py/runtime.c
msgid "name not defined"
msgstr "Dieser Name ist nirgends definiert worden (Schreibweise kontrollieren)"
@@ -2209,7 +2139,7 @@ msgstr ""
#: shared-bindings/socket/__init__.c shared-module/network/__init__.c
msgid "no available NIC"
-msgstr ""
+msgstr "kein verfügbares Netzwerkadapter (NIC)"
#: py/compile.c
msgid "no binding for nonlocal found"
@@ -2222,13 +2152,13 @@ msgstr "Kein Modul mit dem Namen '%q'"
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
#: shared-bindings/displayio/ParallelBus.c
msgid "no reset pin available"
-msgstr ""
+msgstr "kein Reset Pin verfügbar"
#: py/runtime.c shared-bindings/_pixelbuf/__init__.c
msgid "no such attribute"
-msgstr ""
+msgstr "kein solches Attribut"
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2316,11 +2246,11 @@ msgstr "offset außerhalb der Grenzen"
#: ports/nrf/common-hal/audiobusio/PDMIn.c
msgid "only bit_depth=16 is supported"
-msgstr ""
+msgstr "nur eine bit_depth=16 wird unterstützt"
#: ports/nrf/common-hal/audiobusio/PDMIn.c
msgid "only sample_rate=16000 is supported"
-msgstr ""
+msgstr "nur eine sample_rate=16000 wird unterstützt"
#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c
#: shared-bindings/nvm/ByteArray.c
@@ -2340,7 +2270,7 @@ msgstr ""
#: py/objint_mpz.c
msgid "overflow converting long int to machine word"
-msgstr ""
+msgstr "Überlauf beim konvertieren von long int zu machine word"
#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c
msgid "palette must be 32 bytes long"
@@ -2348,7 +2278,7 @@ msgstr ""
#: shared-bindings/displayio/Palette.c
msgid "palette_index should be an int"
-msgstr ""
+msgstr "palette_index sollte ein int sein"
#: py/compile.c
msgid "parameter annotation must be an identifier"
@@ -2450,7 +2380,7 @@ msgstr "Der schedule stack ist voll"
#: lib/utils/pyexec.c py/builtinimport.c
msgid "script compilation not supported"
-msgstr "kompilieren von Skripten ist nicht unterstützt"
+msgstr "kompilieren von Skripten nicht unterstützt"
#: py/objstr.c
msgid "sign not allowed in string format specifier"
@@ -2482,11 +2412,11 @@ msgstr "weicher reboot\n"
#: py/objstr.c
msgid "start/end indices"
-msgstr ""
+msgstr "start/end Indizes"
#: shared-bindings/displayio/Shape.c
msgid "start_x should be an int"
-msgstr ""
+msgstr "start_x sollte ein int sein"
#: shared-bindings/random/__init__.c
msgid "step must be non-zero"
@@ -2506,7 +2436,7 @@ msgstr "stream operation ist nicht unterstützt"
#: py/objstrunicode.c
msgid "string index out of range"
-msgstr ""
+msgstr "String index außerhalb des Bereiches"
#: py/objstrunicode.c
#, c-format
@@ -2554,12 +2484,8 @@ msgstr "threshold muss im Intervall 0-65536 liegen"
msgid "time.struct_time() takes a 9-sequence"
msgstr ""
-#: shared-bindings/time/__init__.c
-msgid "time.struct_time() takes exactly 1 argument"
-msgstr ""
-
#: shared-bindings/busio/UART.c
-msgid "timeout >100 (units are now seconds, not msecs)"
+msgid "timeout must be 0.0-100.0 seconds"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
@@ -2597,11 +2523,11 @@ msgstr "tx und rx können nicht beide None sein"
#: py/objtype.c
msgid "type '%q' is not an acceptable base type"
-msgstr ""
+msgstr "Typ '%q' ist kein akzeptierter Basis-Typ"
#: py/objtype.c
msgid "type is not an acceptable base type"
-msgstr ""
+msgstr "Typ ist kein akzeptierter Basis-Typ"
#: py/runtime.c
msgid "type object '%q' has no attribute '%q'"
@@ -2713,13 +2639,13 @@ msgstr "nicht unterstützte Typen für %q: '%s', '%s'"
#: py/objint.c
#, c-format
msgid "value must fit in %d byte(s)"
-msgstr ""
+msgstr "Wert muss in %d Byte(s) passen"
#: shared-bindings/displayio/Bitmap.c
msgid "value_count must be > 0"
-msgstr ""
+msgstr "value_count muss größer als 0 sein"
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
@@ -2790,6 +2716,9 @@ msgstr ""
#~ msgid "Characteristic already in use by another Service."
#~ msgstr "Characteristic wird bereits von einem anderen Dienst verwendet."
+#~ msgid "Could not decode ble_uuid, err 0x%04x"
+#~ msgstr "Konnte ble_uuid nicht decodieren. Status: 0x%04x"
+
#~ msgid "Data too large for the advertisement packet"
#~ msgstr "Daten sind zu groß für das advertisement packet"
@@ -2806,39 +2735,108 @@ msgstr ""
#~ msgid "Error in ffi_prep_cif"
#~ msgstr "Fehler in ffi_prep_cif"
+#~ msgid "Expected a Peripheral"
+#~ msgstr "Ein Peripheriegerät wird erwartet"
+
#~ msgid "Failed to acquire mutex"
#~ msgstr "Akquirieren des Mutex gescheitert"
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Hinzufügen des Characteristic ist gescheitert. Status: 0x%04x"
+
+#~ msgid "Failed to add descriptor, err 0x%04x"
+#~ msgstr "Deskriptor konnte nicht hinzugefügt werden. Status: 0x%04x"
+
#~ msgid "Failed to add service"
#~ msgstr "Dienst konnte nicht hinzugefügt werden"
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Dienst konnte nicht hinzugefügt werden. Status: 0x%04x"
+
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "Fehler beim Ändern des Softdevice-Status"
+
#~ msgid "Failed to connect:"
#~ msgstr "Verbindung fehlgeschlagen:"
#~ msgid "Failed to continue scanning"
#~ msgstr "Der Scanvorgang kann nicht fortgesetzt werden"
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ msgstr "Der Scanvorgang kann nicht fortgesetzt werden. Status: 0x%04x"
+
#~ msgid "Failed to create mutex"
#~ msgstr "Erstellen des Mutex ist fehlgeschlagen"
+#~ msgid "Failed to discover services"
+#~ msgstr "Es konnten keine Dienste gefunden werden"
+
+#~ msgid "Failed to get local address"
+#~ msgstr "Lokale Adresse konnte nicht abgerufen werden"
+
+#~ msgid "Failed to get softdevice state"
+#~ msgstr "Fehler beim Abrufen des Softdevice-Status"
+
#~ msgid "Failed to notify or indicate attribute value, err %0x04x"
#~ msgstr "Kann den Attributwert nicht mitteilen. Status: 0x%04x"
+#~ msgid "Failed to pair"
+#~ msgstr "Koppeln fehlgeschlagen"
+
+#~ msgid "Failed to read CCCD value, err 0x%04x"
+#~ msgstr "Kann CCCD value nicht lesen. Status: 0x%04x"
+
#~ msgid "Failed to read attribute value, err %0x04x"
#~ msgstr "Kann den Attributwert nicht lesen. Status: 0x%04x"
+#~ msgid "Failed to read attribute value, err 0x%04x"
+#~ msgstr "Kann Attributwert nicht lesen, Status: 0x%04x"
+
+#~ msgid "Failed to read gatts value, err 0x%04x"
+#~ 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"
+
#~ msgid "Failed to release mutex"
#~ msgstr "Loslassen des Mutex gescheitert"
+#~ msgid "Failed to set device name, err 0x%04x"
+#~ msgstr "Gerätename konnte nicht gesetzt werden, Status: 0x%04x"
+
#~ msgid "Failed to start advertising"
#~ msgstr "Kann advertisement nicht starten"
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ msgstr "Kann advertisement nicht starten. Status: 0x%04x"
+
+#~ msgid "Failed to start connecting, error 0x%04x"
+#~ msgstr "Verbindung konnte nicht hergestellt werden. Status: 0x%04x"
+
+#~ msgid "Failed to start pairing, error 0x%04x"
+#~ msgstr "Starten des Koppelns fehlgeschlagen, Status: 0x%04x"
+
#~ msgid "Failed to start scanning"
#~ msgstr "Der Scanvorgang kann nicht gestartet werden"
+#~ msgid "Failed to start scanning, err 0x%04x"
+#~ msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%04x"
+
#~ msgid "Failed to stop advertising"
#~ msgstr "Kann advertisement nicht stoppen"
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "Kann advertisement nicht stoppen. Status: 0x%04x"
+
+#~ msgid "Failed to write CCCD, err 0x%04x"
+#~ msgstr "Konnte CCCD nicht schreiben, Status: 0x%04x"
+
+#~ msgid "Failed to write attribute value, err 0x%04x"
+#~ msgstr "Kann den Attributwert nicht schreiben. Status: 0x%04x"
+
+#~ msgid "Failed to write gatts value, err 0x%04x"
+#~ msgstr "gatts value konnte nicht geschrieben werden. Status: 0x%04x"
+
#~ msgid "Function requires lock."
#~ msgstr ""
#~ "Die Funktion erwartet, dass der 'lock'-Befehl zuvor ausgeführt wurde"
@@ -2972,6 +2970,9 @@ msgstr ""
#~ msgstr ""
#~ "Speicherallozierung fehlgeschlagen, alloziere %u Bytes für nativen Code"
+#~ msgid "name must be a string"
+#~ msgstr "name muss ein String sein"
+
#~ msgid "not a valid ADC Channel: %d"
#~ msgstr "Kein gültiger ADC Kanal: %d"
diff --git a/locale/en_US.po b/locale/en_US.po
index 652053ee9..e0e63e4fd 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-11-27 14:54-0500\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -259,6 +259,10 @@ msgstr ""
msgid "All timers in use"
msgstr ""
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr ""
@@ -325,6 +329,11 @@ msgstr ""
msgid "Brightness not adjustable"
msgstr ""
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -455,6 +464,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr ""
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -463,11 +478,6 @@ msgstr ""
msgid "Corrupt raw code"
msgstr ""
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Could not decode ble_uuid, err 0x%04x"
-msgstr ""
-
#: ports/atmel-samd/common-hal/busio/UART.c
msgid "Could not initialize UART"
msgstr ""
@@ -497,7 +507,7 @@ msgstr ""
msgid "Data chunk must follow fmt chunk"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Data too large for advertisement packet"
msgstr ""
@@ -543,10 +553,6 @@ msgstr ""
msgid "Expected a Characteristic"
msgstr ""
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -556,7 +562,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr ""
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -574,21 +580,6 @@ msgstr ""
msgid "Failed to acquire mutex, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Service.c
-#, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to add descriptor, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr ""
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr ""
@@ -600,63 +591,11 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr ""
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to change softdevice state"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Central.c
-msgid "Failed to connect: timeout"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-msgid "Failed to discover services"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to get local address"
+msgid "Failed to connect: internal error"
msgstr ""
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to get softdevice state"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to notify or indicate attribute value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-msgid "Failed to pair"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to read CCCD value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#: ports/nrf/common-hal/_bleio/Descriptor.c
-#, c-format
-msgid "Failed to read attribute value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to read gatts value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
+msgid "Failed to connect: timeout"
msgstr ""
#: ports/nrf/sd_mutex.c
@@ -664,51 +603,6 @@ msgstr ""
msgid "Failed to release mutex, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Central.c
-#, c-format
-msgid "Failed to start connecting, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start pairing, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to start scanning, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to write CCCD, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to write attribute value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to write gatts value, err 0x%04x"
-msgstr ""
-
#: py/moduerrno.c
msgid "File exists"
msgstr ""
@@ -771,6 +665,14 @@ msgstr ""
msgid "Input/output error"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient authentication"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient encryption"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
@@ -989,9 +891,8 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
msgid "Not connected"
msgstr ""
@@ -1065,6 +966,10 @@ msgstr ""
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1117,7 +1022,7 @@ msgstr ""
msgid "Running in safe mode! Not running saved code.\n"
msgstr ""
-#: ports/atmel-samd/common-hal/busio/I2C.c
+#: ports/atmel-samd/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
msgid "SDA or SCL needs a pull up"
msgstr ""
@@ -1131,6 +1036,10 @@ msgstr ""
msgid "Sample rate too high. It must be less than %d"
msgstr ""
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1145,11 +1054,6 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr ""
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr ""
@@ -1300,11 +1204,32 @@ msgstr ""
msgid "Unexpected nrfx uuid type"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown gatt error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown security error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown soft device error: %04x"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Unmatched number of items on RHS (expected %d, got %d)."
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid ""
+"Unspecified issue. Can be that the pairing prompt on the other device was "
+"declined or ignored."
+msgstr ""
+
#: ports/atmel-samd/common-hal/busio/I2C.c
msgid "Unsupported baudrate"
msgstr ""
@@ -1950,7 +1875,7 @@ msgstr ""
msgid "integer required"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2127,10 +2052,6 @@ msgstr ""
msgid "name '%q' is not defined"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c
-msgid "name must be a string"
-msgstr ""
-
#: py/runtime.c
msgid "name not defined"
msgstr ""
@@ -2181,7 +2102,7 @@ msgstr ""
msgid "no such attribute"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2502,12 +2423,8 @@ msgstr ""
msgid "time.struct_time() takes a 9-sequence"
msgstr ""
-#: shared-bindings/time/__init__.c
-msgid "time.struct_time() takes exactly 1 argument"
-msgstr ""
-
#: shared-bindings/busio/UART.c
-msgid "timeout >100 (units are now seconds, not msecs)"
+msgid "timeout must be 0.0-100.0 seconds"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
@@ -2663,7 +2580,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr ""
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
diff --git a/locale/en_x_pirate.po b/locale/en_x_pirate.po
index 1d2fcb659..b22687469 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-11-27 14:54-0500\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: @sommersoft, @MrCertainly\n"
@@ -261,6 +261,10 @@ msgstr ""
msgid "All timers in use"
msgstr ""
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr ""
@@ -329,6 +333,11 @@ msgstr ""
msgid "Brightness not adjustable"
msgstr ""
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -459,6 +468,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr ""
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -467,11 +482,6 @@ msgstr ""
msgid "Corrupt raw code"
msgstr ""
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Could not decode ble_uuid, err 0x%04x"
-msgstr ""
-
#: ports/atmel-samd/common-hal/busio/UART.c
msgid "Could not initialize UART"
msgstr ""
@@ -501,7 +511,7 @@ msgstr ""
msgid "Data chunk must follow fmt chunk"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Data too large for advertisement packet"
msgstr ""
@@ -547,10 +557,6 @@ msgstr ""
msgid "Expected a Characteristic"
msgstr ""
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -560,7 +566,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr ""
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -578,21 +584,6 @@ msgstr ""
msgid "Failed to acquire mutex, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Service.c
-#, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to add descriptor, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr ""
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr ""
@@ -604,63 +595,11 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr ""
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to change softdevice state"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Central.c
-msgid "Failed to connect: timeout"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-msgid "Failed to discover services"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to get local address"
+msgid "Failed to connect: internal error"
msgstr ""
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to get softdevice state"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to notify or indicate attribute value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-msgid "Failed to pair"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to read CCCD value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#: ports/nrf/common-hal/_bleio/Descriptor.c
-#, c-format
-msgid "Failed to read attribute value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to read gatts value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
+msgid "Failed to connect: timeout"
msgstr ""
#: ports/nrf/sd_mutex.c
@@ -668,51 +607,6 @@ msgstr ""
msgid "Failed to release mutex, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Central.c
-#, c-format
-msgid "Failed to start connecting, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start pairing, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to start scanning, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to write CCCD, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to write attribute value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to write gatts value, err 0x%04x"
-msgstr ""
-
#: py/moduerrno.c
msgid "File exists"
msgstr ""
@@ -775,6 +669,14 @@ msgstr ""
msgid "Input/output error"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient authentication"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient encryption"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
@@ -993,9 +895,8 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
msgid "Not connected"
msgstr ""
@@ -1069,6 +970,10 @@ msgstr ""
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1121,7 +1026,7 @@ msgstr "Runnin' in safe mode! Auto-reload be off.\n"
msgid "Running in safe mode! Not running saved code.\n"
msgstr "Runnin' in safe mode! Nay runnin' saved code.\n"
-#: ports/atmel-samd/common-hal/busio/I2C.c
+#: ports/atmel-samd/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
msgid "SDA or SCL needs a pull up"
msgstr ""
@@ -1135,6 +1040,10 @@ msgstr ""
msgid "Sample rate too high. It must be less than %d"
msgstr ""
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1149,11 +1058,6 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr ""
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr ""
@@ -1304,11 +1208,32 @@ msgstr ""
msgid "Unexpected nrfx uuid type"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown gatt error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown security error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown soft device error: %04x"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Unmatched number of items on RHS (expected %d, got %d)."
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid ""
+"Unspecified issue. Can be that the pairing prompt on the other device was "
+"declined or ignored."
+msgstr ""
+
#: ports/atmel-samd/common-hal/busio/I2C.c
msgid "Unsupported baudrate"
msgstr ""
@@ -1954,7 +1879,7 @@ msgstr ""
msgid "integer required"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2131,10 +2056,6 @@ msgstr ""
msgid "name '%q' is not defined"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c
-msgid "name must be a string"
-msgstr ""
-
#: py/runtime.c
msgid "name not defined"
msgstr ""
@@ -2185,7 +2106,7 @@ msgstr ""
msgid "no such attribute"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2506,12 +2427,8 @@ msgstr ""
msgid "time.struct_time() takes a 9-sequence"
msgstr ""
-#: shared-bindings/time/__init__.c
-msgid "time.struct_time() takes exactly 1 argument"
-msgstr ""
-
#: shared-bindings/busio/UART.c
-msgid "timeout >100 (units are now seconds, not msecs)"
+msgid "timeout must be 0.0-100.0 seconds"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
@@ -2667,7 +2584,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr ""
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
diff --git a/locale/es.po b/locale/es.po
index ca8593dcd..4e8df4195 100644
--- a/locale/es.po
+++ b/locale/es.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-11-27 14:54-0500\n"
"PO-Revision-Date: 2018-08-24 22:56-0500\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -263,6 +263,10 @@ msgstr "Todos los timers para este pin están siendo utilizados"
msgid "All timers in use"
msgstr "Todos los timers en uso"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "Funcionalidad AnalogOut no soportada"
@@ -333,6 +337,11 @@ msgstr "El brillo debe estar entro 0 y 255"
msgid "Brightness not adjustable"
msgstr "El brillo no se puede ajustar"
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -463,6 +472,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr "Command debe estar entre 0 y 255."
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -471,11 +486,6 @@ msgstr ""
msgid "Corrupt raw code"
msgstr ""
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Could not decode ble_uuid, err 0x%04x"
-msgstr "No se puede descodificar ble_uuid, err 0x%04x"
-
#: ports/atmel-samd/common-hal/busio/UART.c
msgid "Could not initialize UART"
msgstr "No se puede inicializar la UART"
@@ -505,7 +515,7 @@ msgstr "El pin Data 0 debe estar alineado a bytes"
msgid "Data chunk must follow fmt chunk"
msgstr "Trozo de datos debe seguir fmt chunk"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Data too large for advertisement packet"
msgstr "Data es muy grande para el paquete de advertisement."
@@ -551,10 +561,6 @@ msgstr "Se espera un %q"
msgid "Expected a Characteristic"
msgstr "Se esperaba una Característica."
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -564,7 +570,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr "Se esperaba un UUID"
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -582,21 +588,6 @@ msgstr "Fallo enviando comando"
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "No se puede adquirir el mutex, status: 0x%08lX"
-#: ports/nrf/common-hal/_bleio/Service.c
-#, fuzzy, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Fallo al añadir caracteristica, err: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to add descriptor, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Fallo al agregar servicio. err: 0x%02x"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Ha fallado la asignación del buffer RX"
@@ -608,116 +599,18 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Falló la asignación del buffer RX de %d bytes"
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to change softdevice state"
-msgstr "No se puede cambiar el estado del softdevice"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
-msgid "Failed to connect: timeout"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr "No se puede iniciar el escaneo. err: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy
-msgid "Failed to discover services"
-msgstr "No se puede descubrir servicios"
-
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to get local address"
-msgstr "No se puede obtener la dirección local"
-
-#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to get softdevice state"
-msgstr "No se puede obtener el estado del softdevice"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to notify or indicate attribute value, err 0x%04x"
-msgstr "Error al notificar o indicar el valor del atributo, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-msgid "Failed to pair"
+msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to read CCCD value, err 0x%04x"
-msgstr "No se puede leer el valor del atributo. err 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#: ports/nrf/common-hal/_bleio/Descriptor.c
-#, fuzzy, c-format
-msgid "Failed to read attribute value, err 0x%04x"
-msgstr "Error al leer valor del atributo, err 0x%04"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to read gatts value, err 0x%04x"
-msgstr "No se puede escribir el valor del atributo. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
-msgstr "Fallo al registrar el Vendor-Specific UUID, err 0x%04x"
-
#: ports/nrf/sd_mutex.c
#, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "No se puede liberar el mutex, err 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "No se puede inicar el anuncio. err: 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Central.c
-#, c-format
-msgid "Failed to start connecting, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start pairing, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to start scanning, err 0x%04x"
-msgstr "No se puede iniciar el escaneo. err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "No se puede detener el anuncio. err: 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to write CCCD, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to write attribute value, err 0x%04x"
-msgstr "No se puede escribir el valor del atributo. err: 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to write gatts value, err 0x%04x"
-msgstr "No se puede escribir el valor del atributo. err: 0x%04x"
-
#: py/moduerrno.c
msgid "File exists"
msgstr "El archivo ya existe"
@@ -782,6 +675,14 @@ msgstr "Tamaño incorrecto del buffer"
msgid "Input/output error"
msgstr "error Input/output"
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient authentication"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient encryption"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
@@ -1004,9 +905,8 @@ msgstr "No queda espacio en el dispositivo"
msgid "No such file/directory"
msgstr "No existe el archivo/directorio"
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
msgid "Not connected"
msgstr "No conectado"
@@ -1088,6 +988,10 @@ msgstr "Incapaz de montar de nuevo el sistema de archivos"
msgid "Pop from an empty Ps2 buffer"
msgstr "Pop de un buffer Ps2 vacio"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1143,7 +1047,7 @@ msgstr "Ejecutando en modo seguro! La auto-recarga esta deshabilitada.\n"
msgid "Running in safe mode! Not running saved code.\n"
msgstr "Ejecutando en modo seguro! No se esta ejecutando el código guardado.\n"
-#: ports/atmel-samd/common-hal/busio/I2C.c
+#: ports/atmel-samd/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
msgid "SDA or SCL needs a pull up"
msgstr "SDA o SCL necesitan una pull up"
@@ -1157,6 +1061,10 @@ msgstr "Sample rate debe ser positivo"
msgid "Sample rate too high. It must be less than %d"
msgstr "Frecuencia de muestreo demasiado alta. Debe ser menor a %d"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1171,11 +1079,6 @@ msgstr "Slice y value tienen diferentes longitudes"
msgid "Slices not supported"
msgstr "Rebanadas no soportadas"
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Dividiendo con sub-capturas"
@@ -1338,11 +1241,32 @@ msgstr "Imposible escribir en nvm"
msgid "Unexpected nrfx uuid type"
msgstr "Tipo de uuid nrfx inesperado"
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown gatt error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown security error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown soft device error: %04x"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Unmatched number of items on RHS (expected %d, got %d)."
msgstr "Número incomparable de elementos en RHS (%d esperado,%d obtenido)"
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid ""
+"Unspecified issue. Can be that the pairing prompt on the other device was "
+"declined or ignored."
+msgstr ""
+
#: ports/atmel-samd/common-hal/busio/I2C.c
msgid "Unsupported baudrate"
msgstr "Baudrate no soportado"
@@ -2004,7 +1928,7 @@ msgstr "int() arg 2 debe ser >= 2 y <= 36"
msgid "integer required"
msgstr "Entero requerido"
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2184,10 +2108,6 @@ msgstr "debe utilizar argumento de palabra clave para la función clave"
msgid "name '%q' is not defined"
msgstr "name '%q' no esta definido"
-#: shared-bindings/_bleio/Peripheral.c
-msgid "name must be a string"
-msgstr "name debe de ser un string"
-
#: py/runtime.c
msgid "name not defined"
msgstr "name no definido"
@@ -2238,7 +2158,7 @@ msgstr ""
msgid "no such attribute"
msgstr "no hay tal atributo"
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2567,13 +2487,9 @@ msgstr "limite debe ser en el rango 0-65536"
msgid "time.struct_time() takes a 9-sequence"
msgstr "time.struct_time() toma un sequencio 9"
-#: shared-bindings/time/__init__.c
-msgid "time.struct_time() takes exactly 1 argument"
-msgstr "time.struct_time() acepta exactamente 1 argumento"
-
#: shared-bindings/busio/UART.c
-msgid "timeout >100 (units are now seconds, not msecs)"
-msgstr "timepo muerto >100 (unidades en segundos)"
+msgid "timeout must be 0.0-100.0 seconds"
+msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
msgid "timeout must be >= 0.0"
@@ -2728,7 +2644,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr ""
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
@@ -2798,6 +2714,9 @@ msgstr "paso cero"
#~ msgid "Characteristic already in use by another Service."
#~ msgstr "Características ya esta en uso por otro Serivice"
+#~ msgid "Could not decode ble_uuid, err 0x%04x"
+#~ msgstr "No se puede descodificar ble_uuid, err 0x%04x"
+
#, fuzzy
#~ msgid "Data too large for the advertisement packet"
#~ msgstr "Los datos no caben en el paquete de anuncio."
@@ -2819,9 +2738,19 @@ msgstr "paso cero"
#~ msgstr "No se puede adquirir el mutex, status: 0x%08lX"
#, fuzzy
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Fallo al añadir caracteristica, err: 0x%08lX"
+
+#, fuzzy
#~ msgid "Failed to add service"
#~ msgstr "No se puede detener el anuncio. status: 0x%02x"
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Fallo al agregar servicio. err: 0x%02x"
+
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "No se puede cambiar el estado del softdevice"
+
#, fuzzy
#~ msgid "Failed to connect:"
#~ msgstr "No se puede conectar. status: 0x%02x"
@@ -2830,19 +2759,48 @@ msgstr "paso cero"
#~ msgid "Failed to continue scanning"
#~ msgstr "No se puede iniciar el escaneo. status: 0x%02x"
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ msgstr "No se puede iniciar el escaneo. err: 0x%02x"
+
#, fuzzy
#~ msgid "Failed to create mutex"
#~ msgstr "No se puede leer el valor del atributo. status 0x%02x"
#, fuzzy
+#~ msgid "Failed to discover services"
+#~ msgstr "No se puede descubrir servicios"
+
+#~ msgid "Failed to get local address"
+#~ msgstr "No se puede obtener la dirección local"
+
+#~ msgid "Failed to get softdevice state"
+#~ msgstr "No se puede obtener el estado del softdevice"
+
+#, fuzzy
#~ msgid "Failed to notify or indicate attribute value, err %0x04x"
#~ msgstr "No se puede notificar el valor del anuncio. status: 0x%02x"
+#~ msgid "Failed to notify or indicate attribute value, err 0x%04x"
+#~ msgstr "Error al notificar o indicar el valor del atributo, err 0x%04x"
+
+#~ msgid "Failed to read CCCD value, err 0x%04x"
+#~ msgstr "No se puede leer el valor del atributo. err 0x%02x"
+
#, fuzzy
#~ msgid "Failed to read attribute value, err %0x04x"
#~ msgstr "No se puede leer el valor del atributo. status 0x%02x"
#, fuzzy
+#~ msgid "Failed to read attribute value, err 0x%04x"
+#~ msgstr "Error al leer valor del atributo, err 0x%04"
+
+#~ msgid "Failed to read gatts value, err 0x%04x"
+#~ msgstr "No se puede escribir el valor del atributo. status: 0x%02x"
+
+#~ msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
+#~ msgstr "Fallo al registrar el Vendor-Specific UUID, err 0x%04x"
+
+#, fuzzy
#~ msgid "Failed to release mutex"
#~ msgstr "No se puede liberar el mutex, status: 0x%08lX"
@@ -2850,14 +2808,29 @@ msgstr "paso cero"
#~ msgid "Failed to start advertising"
#~ msgstr "No se puede inicar el anuncio. status: 0x%02x"
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ msgstr "No se puede inicar el anuncio. err: 0x%04x"
+
#, fuzzy
#~ msgid "Failed to start scanning"
#~ msgstr "No se puede iniciar el escaneo. status: 0x%02x"
+#~ msgid "Failed to start scanning, err 0x%04x"
+#~ msgstr "No se puede iniciar el escaneo. err 0x%04x"
+
#, fuzzy
#~ msgid "Failed to stop advertising"
#~ msgstr "No se puede detener el anuncio. status: 0x%02x"
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "No se puede detener el anuncio. err: 0x%04x"
+
+#~ msgid "Failed to write attribute value, err 0x%04x"
+#~ msgstr "No se puede escribir el valor del atributo. err: 0x%04x"
+
+#~ msgid "Failed to write gatts value, err 0x%04x"
+#~ msgstr "No se puede escribir el valor del atributo. err: 0x%04x"
+
#~ msgid "Function requires lock."
#~ msgstr "La función requiere lock"
@@ -2932,6 +2905,9 @@ msgstr "paso cero"
#~ msgid "STA required"
#~ msgstr "STA requerido"
+#~ msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
+#~ msgstr "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
+
#~ msgid "Tile indices must be 0 - 255"
#~ msgstr "Los índices de Tile deben ser 0 - 255"
@@ -3027,6 +3003,9 @@ msgstr "paso cero"
#~ msgstr ""
#~ "falló la asignación de memoria, asignando %u bytes para código nativo"
+#~ msgid "name must be a string"
+#~ msgstr "name debe de ser un string"
+
#~ msgid "not a valid ADC Channel: %d"
#~ msgstr "no es un canal ADC válido: %d"
@@ -3048,6 +3027,12 @@ msgstr "paso cero"
#~ msgid "tile index out of bounds"
#~ msgstr "el indice del tile fuera de limite"
+#~ msgid "time.struct_time() takes exactly 1 argument"
+#~ msgstr "time.struct_time() acepta exactamente 1 argumento"
+
+#~ msgid "timeout >100 (units are now seconds, not msecs)"
+#~ msgstr "timepo muerto >100 (unidades en segundos)"
+
#~ msgid "too many arguments"
#~ msgstr "muchos argumentos"
diff --git a/locale/fil.po b/locale/fil.po
index 6f460c94c..f3f2b7e3b 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-11-27 14:54-0500\n"
"PO-Revision-Date: 2018-12-20 22:15-0800\n"
"Last-Translator: Timothy <me@timothygarcia.ca>\n"
"Language-Team: fil\n"
@@ -263,6 +263,10 @@ msgstr "Lahat ng timers para sa pin na ito ay ginagamit"
msgid "All timers in use"
msgstr "Lahat ng timer ginagamit"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "Hindi supportado ang AnalogOut"
@@ -331,6 +335,11 @@ msgstr "Ang liwanag ay dapat sa gitna ng 0 o 255"
msgid "Brightness not adjustable"
msgstr ""
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -464,6 +473,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr "Sa gitna ng 0 o 255 dapat ang bytes."
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -472,11 +487,6 @@ msgstr ""
msgid "Corrupt raw code"
msgstr ""
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Could not decode ble_uuid, err 0x%04x"
-msgstr ""
-
#: ports/atmel-samd/common-hal/busio/UART.c
msgid "Could not initialize UART"
msgstr "Hindi ma-initialize ang UART"
@@ -507,7 +517,7 @@ msgstr "graphic ay dapat 2048 bytes ang haba"
msgid "Data chunk must follow fmt chunk"
msgstr "Dapat sunurin ng Data chunk ang fmt chunk"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, fuzzy
msgid "Data too large for advertisement packet"
msgstr "Hindi makasya ang data sa loob ng advertisement packet"
@@ -556,10 +566,6 @@ msgstr "Umasa ng %q"
msgid "Expected a Characteristic"
msgstr "Hindi mabasa and Characteristic."
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -570,7 +576,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr "Umasa ng %q"
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -588,21 +594,6 @@ msgstr ""
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX"
-#: ports/nrf/common-hal/_bleio/Service.c
-#, fuzzy, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Nabigo sa paglagay ng characteristic, status: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to add descriptor, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Hindi matagumpay ang paglagay ng service, status: 0x%08lX"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Nabigong ilaan ang RX buffer"
@@ -614,119 +605,18 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Nabigong ilaan ang RX buffer ng %d bytes"
#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to change softdevice state"
-msgstr "Nabigo sa pagbago ng softdevice state, error: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Central.c
-msgid "Failed to connect: timeout"
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, fuzzy, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr "Hindi maituloy ang pag scan, status: 0x%0xlX"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy
-msgid "Failed to discover services"
-msgstr "Nabigo sa pagdiscover ng services, status: 0x%08lX"
-
#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to get local address"
-msgstr "Nabigo sa pagkuha ng local na address, , error: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to get softdevice state"
-msgstr "Nabigo sa pagkuha ng softdevice state, error: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to notify or indicate attribute value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-msgid "Failed to pair"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, fuzzy, c-format
-msgid "Failed to read CCCD value, err 0x%04x"
-msgstr "Hindi mabasa ang value ng attribute, status: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#: ports/nrf/common-hal/_bleio/Descriptor.c
-#, c-format
-msgid "Failed to read attribute value, err 0x%04x"
+msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy, c-format
-msgid "Failed to read gatts value, err 0x%04x"
-msgstr "Hindi maisulat ang gatts value, status: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, fuzzy, c-format
-msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
-msgstr "Hindi matagumpay ang paglagay ng Vender Specific UUID, status: 0x%08lX"
-
#: ports/nrf/sd_mutex.c
#, fuzzy, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "Nabigo sa pagrelease ng mutex, status: 0x%08lX"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Central.c
-#, c-format
-msgid "Failed to start connecting, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start pairing, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, fuzzy, c-format
-msgid "Failed to start scanning, err 0x%04x"
-msgstr "Hindi masimulaan mag i-scan, status: 0x%0xlX"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "Hindi mahinto ang advertisement, status: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to write CCCD, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy, c-format
-msgid "Failed to write attribute value, err 0x%04x"
-msgstr "Hindi maisulat ang attribute value, status: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy, c-format
-msgid "Failed to write gatts value, err 0x%04x"
-msgstr "Hindi maisulat ang gatts value, status: 0x%08lX"
-
#: py/moduerrno.c
msgid "File exists"
msgstr "Mayroong file"
@@ -791,6 +681,14 @@ msgstr ""
msgid "Input/output error"
msgstr "May mali sa Input/Output"
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient authentication"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient encryption"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
@@ -1013,9 +911,8 @@ msgstr ""
msgid "No such file/directory"
msgstr "Walang file/directory"
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
#, fuzzy
msgid "Not connected"
msgstr "Hindi maka connect sa AP"
@@ -1094,6 +991,10 @@ msgstr "Kasama ang kung ano pang modules na sa filesystem\n"
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1150,7 +1051,7 @@ msgstr "Tumatakbo sa safe mode! Awtomatikong pag re-reload ay OFF.\n"
msgid "Running in safe mode! Not running saved code.\n"
msgstr "Tumatakbo sa safe mode! Hindi tumatakbo ang nai-save na code.\n"
-#: ports/atmel-samd/common-hal/busio/I2C.c
+#: ports/atmel-samd/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
msgid "SDA or SCL needs a pull up"
msgstr "Kailangan ng pull up resistors ang SDA o SCL"
@@ -1164,6 +1065,10 @@ msgstr "Sample rate ay dapat positibo"
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/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1178,11 +1083,6 @@ msgstr "Slice at value iba't ibang haba."
msgid "Slices not supported"
msgstr "Hindi suportado ang Slices"
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr ""
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Binibiyak gamit ang sub-captures"
@@ -1344,11 +1244,32 @@ msgstr "Hindi ma i-sulat sa NVM."
msgid "Unexpected nrfx uuid type"
msgstr "hindi inaasahang indent"
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown gatt error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown security error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown soft device error: %04x"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Unmatched number of items on RHS (expected %d, got %d)."
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid ""
+"Unspecified issue. Can be that the pairing prompt on the other device was "
+"declined or ignored."
+msgstr ""
+
#: ports/atmel-samd/common-hal/busio/I2C.c
msgid "Unsupported baudrate"
msgstr "Hindi supportadong baudrate"
@@ -2016,7 +1937,7 @@ msgstr "int() arg 2 ay dapat >=2 at <= 36"
msgid "integer required"
msgstr "kailangan ng int"
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2197,11 +2118,6 @@ msgstr "dapat gumamit ng keyword argument para sa key function"
msgid "name '%q' is not defined"
msgstr "name '%q' ay hindi defined"
-#: shared-bindings/_bleio/Peripheral.c
-#, fuzzy
-msgid "name must be a string"
-msgstr "ang keywords dapat strings"
-
#: py/runtime.c
msgid "name not defined"
msgstr "name hindi na define"
@@ -2252,7 +2168,7 @@ msgstr ""
msgid "no such attribute"
msgstr "walang ganoon na attribute"
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2579,13 +2495,9 @@ msgstr "ang threshold ay dapat sa range 0-65536"
msgid "time.struct_time() takes a 9-sequence"
msgstr "time.struct_time() kumukuha ng 9-sequence"
-#: shared-bindings/time/__init__.c
-msgid "time.struct_time() takes exactly 1 argument"
-msgstr "time.struct_time() kumukuha ng 1 argument"
-
#: shared-bindings/busio/UART.c
-msgid "timeout >100 (units are now seconds, not msecs)"
-msgstr "timeout >100 (units ay seconds, hindi na msecs)"
+msgid "timeout must be 0.0-100.0 seconds"
+msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
#, fuzzy
@@ -2741,7 +2653,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr ""
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
@@ -2826,10 +2738,22 @@ msgstr "zero step"
#~ msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX"
#, fuzzy
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Nabigo sa paglagay ng characteristic, status: 0x%08lX"
+
+#, fuzzy
#~ msgid "Failed to add service"
#~ msgstr "Hindi matagumpay ang paglagay ng service, status: 0x%08lX"
#, fuzzy
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Hindi matagumpay ang paglagay ng service, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "Nabigo sa pagbago ng softdevice state, error: 0x%08lX"
+
+#, fuzzy
#~ msgid "Failed to connect:"
#~ msgstr "Hindi makaconnect, status: 0x%08lX"
@@ -2838,18 +2762,47 @@ msgstr "zero step"
#~ msgstr "Hindi maituloy ang pag scan, status: 0x%0xlX"
#, fuzzy
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ 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 discover services"
+#~ msgstr "Nabigo sa pagdiscover ng services, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to get local address"
+#~ msgstr "Nabigo sa pagkuha ng local na address, , error: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to get softdevice state"
+#~ msgstr "Nabigo sa pagkuha ng softdevice state, error: 0x%08lX"
+
+#, fuzzy
#~ msgid "Failed to notify or indicate attribute value, err %0x04x"
#~ msgstr "Hindi mabalitaan ang attribute value, status: 0x%08lX"
#, fuzzy
+#~ msgid "Failed to read CCCD value, err 0x%04x"
+#~ msgstr "Hindi mabasa ang value ng attribute, status: 0x%08lX"
+
+#, fuzzy
#~ msgid "Failed to read attribute value, err %0x04x"
#~ msgstr "Hindi mabasa ang value ng attribute, status: 0x%08lX"
#, fuzzy
+#~ msgid "Failed to read gatts value, err 0x%04x"
+#~ msgstr "Hindi maisulat ang gatts value, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
+#~ msgstr ""
+#~ "Hindi matagumpay ang paglagay ng Vender Specific UUID, status: 0x%08lX"
+
+#, fuzzy
#~ msgid "Failed to release mutex"
#~ msgstr "Nabigo sa pagrelease ng mutex, status: 0x%08lX"
@@ -2858,13 +2811,33 @@ msgstr "zero step"
#~ msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX"
#, fuzzy
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ 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 start scanning, err 0x%04x"
+#~ msgstr "Hindi masimulaan mag i-scan, status: 0x%0xlX"
+
+#, fuzzy
#~ msgid "Failed to stop advertising"
#~ msgstr "Hindi mahinto ang advertisement, status: 0x%08lX"
+#, fuzzy
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "Hindi mahinto ang advertisement, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to write attribute value, err 0x%04x"
+#~ msgstr "Hindi maisulat ang attribute value, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to write gatts value, err 0x%04x"
+#~ msgstr "Hindi maisulat ang gatts value, status: 0x%08lX"
+
#~ msgid "Function requires lock."
#~ msgstr "Kailangan ng lock ang function."
@@ -3010,6 +2983,10 @@ msgstr "zero step"
#~ msgstr ""
#~ "nabigo ang paglalaan ng memorya, naglalaan ng %u bytes para sa native code"
+#, fuzzy
+#~ msgid "name must be a string"
+#~ msgstr "ang keywords dapat strings"
+
#~ msgid "not a valid ADC Channel: %d"
#~ msgstr "hindi tamang ADC Channel: %d"
@@ -3025,6 +3002,12 @@ msgstr "zero step"
#~ msgid "scan failed"
#~ msgstr "nabigo ang pag-scan"
+#~ msgid "time.struct_time() takes exactly 1 argument"
+#~ msgstr "time.struct_time() kumukuha ng 1 argument"
+
+#~ msgid "timeout >100 (units are now seconds, not msecs)"
+#~ msgstr "timeout >100 (units ay seconds, hindi na msecs)"
+
#~ msgid "too many arguments"
#~ msgstr "masyadong maraming argumento"
diff --git a/locale/fr.po b/locale/fr.po
index c176fd8bc..098bd8d1f 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-11-27 14:54-0500\n"
"PO-Revision-Date: 2019-04-14 20:05+0100\n"
"Last-Translator: Pierrick Couturier <arofarn@arofarn.info>\n"
"Language-Team: fr\n"
@@ -266,6 +266,10 @@ msgstr "Tous les timers pour cette broche sont utilisés"
msgid "All timers in use"
msgstr "Tous les timers sont utilisés"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "Fonctionnalité AnalogOut non supportée"
@@ -336,6 +340,11 @@ msgstr "La luminosité doit être entre 0 et 255"
msgid "Brightness not adjustable"
msgstr "Luminosité non-ajustable"
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -470,6 +479,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr "La commande doit être un entier entre 0 et 255"
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -478,11 +493,6 @@ msgstr ""
msgid "Corrupt raw code"
msgstr ""
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Could not decode ble_uuid, err 0x%04x"
-msgstr "Impossible de décoder le 'ble_uuid', err 0x%04x"
-
#: ports/atmel-samd/common-hal/busio/UART.c
msgid "Could not initialize UART"
msgstr "L'UART n'a pu être initialisé"
@@ -513,7 +523,7 @@ msgstr "La broche 'Data 0' doit être aligné sur l'octet"
msgid "Data chunk must follow fmt chunk"
msgstr "Un bloc de données doit suivre un bloc de format"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Data too large for advertisement packet"
msgstr "Données trop volumineuses pour un paquet de diffusion"
@@ -560,10 +570,6 @@ msgstr "Attendu un %q"
msgid "Expected a Characteristic"
msgstr "Une 'Characteristic' est attendue"
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -574,7 +580,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr "Un UUID est attendu"
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -592,21 +598,6 @@ msgstr ""
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Echec de l'obtention de mutex, err 0x%04x"
-#: ports/nrf/common-hal/_bleio/Service.c
-#, fuzzy, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Echec de l'ajout de caractéristique, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to add descriptor, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Echec de l'ajout de service, err 0x%04x"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Echec de l'allocation du tampon RX"
@@ -618,120 +609,18 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Echec de l'allocation de %d octets du tampon RX"
#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to change softdevice state"
-msgstr "Echec de la modification de l'état du périphérique"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Central.c
-msgid "Failed to connect: timeout"
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, fuzzy, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr "Impossible de poursuivre le scan, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy
-msgid "Failed to discover services"
-msgstr "Echec de la découverte de services"
-
#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to get local address"
-msgstr "Echec de l'obtention de l'adresse locale"
-
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to get softdevice state"
-msgstr "Echec de l'obtention de l'état du périphérique"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to notify or indicate attribute value, err 0x%04x"
-msgstr ""
-"Impossible de notifier ou d'indiquer la valeur de l'attribut, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-msgid "Failed to pair"
+msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, fuzzy, c-format
-msgid "Failed to read CCCD value, err 0x%04x"
-msgstr "Impossible de lire la valeur 'CCCD', err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#: ports/nrf/common-hal/_bleio/Descriptor.c
-#, c-format
-msgid "Failed to read attribute value, err 0x%04x"
-msgstr "Impossible de lire la valeur de l'attribut, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy, c-format
-msgid "Failed to read gatts value, err 0x%04x"
-msgstr "Impossible de lire la valeur de 'gatts', err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, fuzzy, c-format
-msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
-msgstr "Echec de l'ajout de l'UUID du fournisseur, err 0x%04x"
-
#: ports/nrf/sd_mutex.c
#, fuzzy, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "Impossible de libérer mutex, err 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "Impossible de commencer à diffuser, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Central.c
-#, c-format
-msgid "Failed to start connecting, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start pairing, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, fuzzy, c-format
-msgid "Failed to start scanning, err 0x%04x"
-msgstr "Impossible de commencer à scanner, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "Echec de l'arrêt de diffusion, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to write CCCD, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy, c-format
-msgid "Failed to write attribute value, err 0x%04x"
-msgstr "Impossible d'écrire la valeur de l'attribut, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy, c-format
-msgid "Failed to write gatts value, err 0x%04x"
-msgstr "Impossible d'écrire la valeur de 'gatts', err 0x%04x"
-
#: py/moduerrno.c
msgid "File exists"
msgstr "Le fichier existe"
@@ -796,6 +685,14 @@ msgstr "Taille de tampon incorrecte"
msgid "Input/output error"
msgstr "Erreur d'entrée/sortie"
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient authentication"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient encryption"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
@@ -1022,9 +919,8 @@ 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/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
#, fuzzy
msgid "Not connected"
msgstr "Non connecté"
@@ -1111,6 +1007,10 @@ msgstr "Ainsi que tout autre module présent sur le système de fichiers\n"
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+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."
@@ -1165,7 +1065,7 @@ msgstr "Mode sans-échec! Auto-chargement désactivé.\n"
msgid "Running in safe mode! Not running saved code.\n"
msgstr "Mode sans-échec! Le code sauvegardé n'est pas éxecuté.\n"
-#: ports/atmel-samd/common-hal/busio/I2C.c
+#: ports/atmel-samd/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
msgid "SDA or SCL needs a pull up"
msgstr "SDA ou SCL a besoin d'une résistance de tirage ('pull up')"
@@ -1180,6 +1080,10 @@ msgstr "Le taux d'échantillonage doit être positif"
msgid "Sample rate too high. It must be less than %d"
msgstr "Taux d'échantillonage trop élevé. Doit être inf. à %d"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1194,11 +1098,6 @@ msgstr "Tranche et valeur de tailles différentes"
msgid "Slices not supported"
msgstr "Tranches non supportées"
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr "Assertion en mode 'soft-device', id: 0x%08lX, pc: 0x%08lX"
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Fractionnement avec des sous-captures"
@@ -1367,12 +1266,33 @@ msgstr "Impossible d'écrire sur la mémoire non-volatile."
msgid "Unexpected nrfx uuid type"
msgstr "Type inattendu pour l'uuid nrfx"
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown gatt error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown security error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown soft device error: %04x"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Unmatched number of items on RHS (expected %d, got %d)."
msgstr ""
"Pas de correspondance du nombres d'éléments à droite (attendu %d, obtenu %d)"
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid ""
+"Unspecified issue. Can be that the pairing prompt on the other device was "
+"declined or ignored."
+msgstr ""
+
#: ports/atmel-samd/common-hal/busio/I2C.c
msgid "Unsupported baudrate"
msgstr "Débit non supporté"
@@ -2048,7 +1968,7 @@ msgstr "l'argument 2 de int() doit être >=2 et <=36"
msgid "integer required"
msgstr "entier requis"
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2229,11 +2149,6 @@ msgstr "doit utiliser un argument nommé pour une fonction key"
msgid "name '%q' is not defined"
msgstr "nom '%q' non défini"
-#: shared-bindings/_bleio/Peripheral.c
-#, fuzzy
-msgid "name must be a string"
-msgstr "les noms doivent être des chaînes de caractère"
-
#: py/runtime.c
msgid "name not defined"
msgstr "nom non défini"
@@ -2285,7 +2200,7 @@ msgstr ""
msgid "no such attribute"
msgstr "pas de tel attribut"
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2620,13 +2535,9 @@ msgstr "le seuil doit être dans la gamme 0-65536"
msgid "time.struct_time() takes a 9-sequence"
msgstr "time.struct_time() prend une séquence de longueur 9"
-#: shared-bindings/time/__init__.c
-msgid "time.struct_time() takes exactly 1 argument"
-msgstr "time.struct_time() prend exactement 1 argument"
-
#: shared-bindings/busio/UART.c
-msgid "timeout >100 (units are now seconds, not msecs)"
-msgstr "timeout >100 (exprimé en secondes, pas en ms)"
+msgid "timeout must be 0.0-100.0 seconds"
+msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
#, fuzzy
@@ -2783,7 +2694,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr "'value_count' doit être > 0"
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
@@ -2854,6 +2765,9 @@ msgstr "'step' nul"
#~ msgid "Characteristic already in use by another Service."
#~ msgstr "'Characteristic' déjà en utilisation par un autre service"
+#~ msgid "Could not decode ble_uuid, err 0x%04x"
+#~ msgstr "Impossible de décoder le 'ble_uuid', err 0x%04x"
+
#~ msgid "Data too large for the advertisement packet"
#~ msgstr "Données trop volumineuses pour le paquet de diffusion"
@@ -2874,10 +2788,22 @@ msgstr "'step' nul"
#~ msgstr "Echec de l'obtention de mutex"
#, fuzzy
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Echec de l'ajout de caractéristique, err 0x%04x"
+
+#, fuzzy
#~ msgid "Failed to add service"
#~ msgstr "Echec de l'ajout de service"
#, fuzzy
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Echec de l'ajout de service, err 0x%04x"
+
+#, fuzzy
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "Echec de la modification de l'état du périphérique"
+
+#, fuzzy
#~ msgid "Failed to connect:"
#~ msgstr "Echec de connection:"
@@ -2886,17 +2812,52 @@ msgstr "'step' nul"
#~ msgstr "Impossible de poursuivre le scan"
#, fuzzy
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ msgstr "Impossible de poursuivre le scan, err 0x%04x"
+
+#, fuzzy
#~ msgid "Failed to create mutex"
#~ msgstr "Echec de la création de mutex"
#, fuzzy
+#~ msgid "Failed to discover services"
+#~ msgstr "Echec de la découverte de services"
+
+#, fuzzy
+#~ msgid "Failed to get local address"
+#~ msgstr "Echec de l'obtention de l'adresse locale"
+
+#, fuzzy
+#~ msgid "Failed to get softdevice state"
+#~ msgstr "Echec de l'obtention de l'état du périphérique"
+
+#, fuzzy
#~ msgid "Failed to notify or indicate attribute value, err %0x04x"
#~ msgstr "Impossible de notifier la valeur de l'attribut. status: 0x%08lX"
+#~ msgid "Failed to notify or indicate attribute value, err 0x%04x"
+#~ msgstr ""
+#~ "Impossible de notifier ou d'indiquer la valeur de l'attribut, err 0x%04x"
+
+#, fuzzy
+#~ msgid "Failed to read CCCD value, err 0x%04x"
+#~ msgstr "Impossible de lire la valeur 'CCCD', err 0x%04x"
+
#, fuzzy
#~ msgid "Failed to read attribute value, err %0x04x"
#~ msgstr "Impossible de lire la valeur de l'attribut. status: 0x%08lX"
+#~ msgid "Failed to read attribute value, err 0x%04x"
+#~ msgstr "Impossible de lire la valeur de l'attribut, err 0x%04x"
+
+#, fuzzy
+#~ msgid "Failed to read gatts value, err 0x%04x"
+#~ msgstr "Impossible de lire la valeur de 'gatts', err 0x%04x"
+
+#, fuzzy
+#~ msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
+#~ msgstr "Echec de l'ajout de l'UUID du fournisseur, err 0x%04x"
+
#, fuzzy
#~ msgid "Failed to release mutex"
#~ msgstr "Impossible de libérer mutex"
@@ -2906,13 +2867,33 @@ msgstr "'step' nul"
#~ msgstr "Echec du démarrage de la diffusion"
#, fuzzy
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ msgstr "Impossible de commencer à diffuser, err 0x%04x"
+
+#, fuzzy
#~ msgid "Failed to start scanning"
#~ msgstr "Impossible de commencer à scanner"
#, fuzzy
+#~ msgid "Failed to start scanning, err 0x%04x"
+#~ msgstr "Impossible de commencer à scanner, err 0x%04x"
+
+#, fuzzy
#~ msgid "Failed to stop advertising"
#~ msgstr "Echec de l'arrêt de diffusion"
+#, fuzzy
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "Echec de l'arrêt de diffusion, err 0x%04x"
+
+#, fuzzy
+#~ msgid "Failed to write attribute value, err 0x%04x"
+#~ msgstr "Impossible d'écrire la valeur de l'attribut, err 0x%04x"
+
+#, fuzzy
+#~ msgid "Failed to write gatts value, err 0x%04x"
+#~ msgstr "Impossible d'écrire la valeur de 'gatts', err 0x%04x"
+
#~ msgid "Function requires lock."
#~ msgstr "La fonction nécessite un verrou."
@@ -2984,6 +2965,9 @@ msgstr "'step' nul"
#~ msgid "STA required"
#~ msgstr "'STA' requis"
+#~ msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
+#~ msgstr "Assertion en mode 'soft-device', id: 0x%08lX, pc: 0x%08lX"
+
#~ msgid "Tile indices must be 0 - 255"
#~ msgstr "Les indices des tuiles doivent être compris entre 0 et 255 "
@@ -3077,6 +3061,10 @@ msgstr "'step' nul"
#~ msgstr ""
#~ "l'allocation de mémoire a échoué en allouant %u octets pour un code natif"
+#, fuzzy
+#~ msgid "name must be a string"
+#~ msgstr "les noms doivent être des chaînes de caractère"
+
#~ msgid "not a valid ADC Channel: %d"
#~ msgstr "canal ADC non valide : %d"
@@ -3096,6 +3084,12 @@ msgstr "'step' nul"
#~ msgid "tile index out of bounds"
#~ msgstr "indice de tuile hors limites"
+#~ msgid "time.struct_time() takes exactly 1 argument"
+#~ msgstr "time.struct_time() prend exactement 1 argument"
+
+#~ msgid "timeout >100 (units are now seconds, not msecs)"
+#~ msgstr "timeout >100 (exprimé en secondes, pas en ms)"
+
#~ msgid "too many arguments"
#~ msgstr "trop d'arguments"
diff --git a/locale/it_IT.po b/locale/it_IT.po
index 883c65d41..154dda932 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-11-27 14:54-0500\n"
"PO-Revision-Date: 2018-10-02 16:27+0200\n"
"Last-Translator: Enrico Paganin <enrico.paganin@mail.com>\n"
"Language-Team: \n"
@@ -262,6 +262,10 @@ msgstr "Tutti i timer per questo pin sono in uso"
msgid "All timers in use"
msgstr "Tutti i timer utilizzati"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "funzionalità AnalogOut non supportata"
@@ -331,6 +335,11 @@ msgstr "La luminosità deve essere compreso tra 0 e 255"
msgid "Brightness not adjustable"
msgstr "Illiminazione non è regolabile"
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -465,6 +474,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr "I byte devono essere compresi tra 0 e 255"
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -473,11 +488,6 @@ msgstr ""
msgid "Corrupt raw code"
msgstr ""
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Could not decode ble_uuid, err 0x%04x"
-msgstr ""
-
#: ports/atmel-samd/common-hal/busio/UART.c
msgid "Could not initialize UART"
msgstr "Impossibile inizializzare l'UART"
@@ -508,7 +518,7 @@ msgstr "graphic deve essere lunga 2048 byte"
msgid "Data chunk must follow fmt chunk"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, fuzzy
msgid "Data too large for advertisement packet"
msgstr "Impossibile inserire dati nel pacchetto di advertisement."
@@ -556,10 +566,6 @@ msgstr "Atteso un %q"
msgid "Expected a Characteristic"
msgstr "Non è possibile aggiungere Characteristic."
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -570,7 +576,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr "Atteso un %q"
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -588,21 +594,6 @@ msgstr ""
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
-#: ports/nrf/common-hal/_bleio/Service.c
-#, fuzzy, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Impossibile fermare advertisement. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to add descriptor, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Impossibile fermare advertisement. status: 0x%02x"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Impossibile allocare buffer RX"
@@ -614,118 +605,18 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Fallita allocazione del buffer RX di %d byte"
#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to change softdevice state"
-msgstr "Impossibile fermare advertisement. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Central.c
-msgid "Failed to connect: timeout"
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, fuzzy, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr "Impossible iniziare la scansione. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy
-msgid "Failed to discover services"
-msgstr "Impossibile fermare advertisement. status: 0x%02x"
-
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to get local address"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to get softdevice state"
-msgstr "Impossibile fermare advertisement. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to notify or indicate attribute value, err 0x%04x"
-msgstr "Notificamento o indicazione di attribute value fallito, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-msgid "Failed to pair"
+msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, fuzzy, c-format
-msgid "Failed to read CCCD value, err 0x%04x"
-msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#: ports/nrf/common-hal/_bleio/Descriptor.c
-#, c-format
-msgid "Failed to read attribute value, err 0x%04x"
-msgstr "Tentative leggere attribute value fallito, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy, c-format
-msgid "Failed to read gatts value, err 0x%04x"
-msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, fuzzy, c-format
-msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
-msgstr "Non è possibile aggiungere l'UUID del vendor specifico da 128-bit"
-
#: ports/nrf/sd_mutex.c
#, fuzzy, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "Impossibile avviare advertisement. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Central.c
-#, c-format
-msgid "Failed to start connecting, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start pairing, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, fuzzy, c-format
-msgid "Failed to start scanning, err 0x%04x"
-msgstr "Impossible iniziare la scansione. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "Impossibile fermare advertisement. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to write CCCD, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy, c-format
-msgid "Failed to write attribute value, err 0x%04x"
-msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy, c-format
-msgid "Failed to write gatts value, err 0x%04x"
-msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x"
-
#: py/moduerrno.c
msgid "File exists"
msgstr "File esistente"
@@ -790,6 +681,14 @@ msgstr ""
msgid "Input/output error"
msgstr "Errore input/output"
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient authentication"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient encryption"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
@@ -1012,9 +911,8 @@ msgstr "Non che spazio sul dispositivo"
msgid "No such file/directory"
msgstr "Nessun file/directory esistente"
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
#, fuzzy
msgid "Not connected"
msgstr "Impossible connettersi all'AP"
@@ -1099,6 +997,10 @@ msgstr "Imposssibile rimontare il filesystem"
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1154,7 +1056,7 @@ msgstr "Modalità sicura in esecuzione! Auto-reload disattivato.\n"
msgid "Running in safe mode! Not running saved code.\n"
msgstr "Modalità sicura in esecuzione! Codice salvato non in esecuzione.\n"
-#: ports/atmel-samd/common-hal/busio/I2C.c
+#: ports/atmel-samd/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
msgid "SDA or SCL needs a pull up"
msgstr "SDA o SCL necessitano un pull-up"
@@ -1170,6 +1072,10 @@ 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/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1184,11 +1090,6 @@ msgstr ""
msgid "Slices not supported"
msgstr "Slice non supportate"
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr ""
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Suddivisione con sotto-catture"
@@ -1343,11 +1244,32 @@ msgstr "Imposibile scrivere su nvm."
msgid "Unexpected nrfx uuid type"
msgstr "indentazione inaspettata"
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown gatt error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown security error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown soft device error: %04x"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Unmatched number of items on RHS (expected %d, got %d)."
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid ""
+"Unspecified issue. Can be that the pairing prompt on the other device was "
+"declined or ignored."
+msgstr ""
+
#: ports/atmel-samd/common-hal/busio/I2C.c
msgid "Unsupported baudrate"
msgstr "baudrate non supportato"
@@ -2008,7 +1930,7 @@ msgstr "il secondo argomanto di int() deve essere >= 2 e <= 36"
msgid "integer required"
msgstr "intero richiesto"
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2190,11 +2112,6 @@ msgstr ""
msgid "name '%q' is not defined"
msgstr "nome '%q'non definito"
-#: shared-bindings/_bleio/Peripheral.c
-#, fuzzy
-msgid "name must be a string"
-msgstr "argomenti nominati devono essere stringhe"
-
#: py/runtime.c
msgid "name not defined"
msgstr "nome non definito"
@@ -2246,7 +2163,7 @@ msgstr ""
msgid "no such attribute"
msgstr "attributo inesistente"
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2577,12 +2494,8 @@ msgstr "la soglia deve essere nell'intervallo 0-65536"
msgid "time.struct_time() takes a 9-sequence"
msgstr ""
-#: shared-bindings/time/__init__.c
-msgid "time.struct_time() takes exactly 1 argument"
-msgstr "time.struct_time() prende esattamente un argomento"
-
#: shared-bindings/busio/UART.c
-msgid "timeout >100 (units are now seconds, not msecs)"
+msgid "timeout must be 0.0-100.0 seconds"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
@@ -2739,7 +2652,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr ""
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
@@ -2830,10 +2743,22 @@ msgstr "zero step"
#~ msgstr "Impossibile allocare buffer RX"
#, fuzzy
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Impossibile fermare advertisement. status: 0x%02x"
+
+#, fuzzy
#~ msgid "Failed to add service"
#~ msgstr "Impossibile fermare advertisement. status: 0x%02x"
#, fuzzy
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Impossibile fermare advertisement. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "Impossibile fermare advertisement. status: 0x%02x"
+
+#, fuzzy
#~ msgid "Failed to connect:"
#~ msgstr "Impossibile connettersi. status: 0x%02x"
@@ -2842,17 +2767,47 @@ msgstr "zero step"
#~ msgstr "Impossible iniziare la scansione. status: 0x%02x"
#, fuzzy
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ 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 discover services"
+#~ msgstr "Impossibile fermare advertisement. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to get softdevice state"
+#~ msgstr "Impossibile fermare advertisement. status: 0x%02x"
+
+#, fuzzy
#~ msgid "Failed to notify or indicate attribute value, err %0x04x"
#~ msgstr "Impossibile notificare valore dell'attributo. status: 0x%02x"
+#~ msgid "Failed to notify or indicate attribute value, err 0x%04x"
+#~ msgstr "Notificamento o indicazione di attribute value fallito, err 0x%04x"
+
+#, fuzzy
+#~ msgid "Failed to read CCCD value, err 0x%04x"
+#~ msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
+
#, fuzzy
#~ msgid "Failed to read attribute value, err %0x04x"
#~ msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
+#~ msgid "Failed to read attribute value, err 0x%04x"
+#~ msgstr "Tentative leggere attribute value fallito, err 0x%04x"
+
+#, fuzzy
+#~ msgid "Failed to read gatts value, err 0x%04x"
+#~ msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
+#~ msgstr "Non è possibile aggiungere l'UUID del vendor specifico da 128-bit"
+
#, fuzzy
#~ msgid "Failed to release mutex"
#~ msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
@@ -2862,13 +2817,33 @@ msgstr "zero step"
#~ msgstr "Impossibile avviare advertisement. status: 0x%02x"
#, fuzzy
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ 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 start scanning, err 0x%04x"
+#~ msgstr "Impossible iniziare la scansione. status: 0x%02x"
+
+#, fuzzy
#~ msgid "Failed to stop advertising"
#~ msgstr "Impossibile fermare advertisement. status: 0x%02x"
+#, fuzzy
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "Impossibile fermare advertisement. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to write attribute value, err 0x%04x"
+#~ msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to write gatts value, err 0x%04x"
+#~ msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x"
+
#~ msgid "GPIO16 does not support pull up."
#~ msgstr "GPIO16 non supporta pull-up"
@@ -3008,6 +2983,10 @@ msgstr "zero step"
#~ msgstr ""
#~ "allocazione di memoria fallita, allocazione di %d byte per codice nativo"
+#, fuzzy
+#~ msgid "name must be a string"
+#~ msgstr "argomenti nominati devono essere stringhe"
+
#~ msgid "not a valid ADC Channel: %d"
#~ msgstr "canale ADC non valido: %d"
@@ -3023,6 +3002,9 @@ msgstr "zero step"
#~ msgid "scan failed"
#~ msgstr "scansione fallita"
+#~ msgid "time.struct_time() takes exactly 1 argument"
+#~ msgstr "time.struct_time() prende esattamente un argomento"
+
#~ msgid "too many arguments"
#~ msgstr "troppi argomenti"
diff --git a/locale/ko.po b/locale/ko.po
new file mode 100644
index 000000000..5fc91553b
--- /dev/null
+++ b/locale/ko.po
@@ -0,0 +1,2645 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 글라파, 2019.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-11-27 14:54-0500\n"
+"PO-Revision-Date: 2019-05-06 14:22-0700\n"
+"Last-Translator: \n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: ko\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: main.c
+msgid ""
+"\n"
+"Code done running. Waiting for reload.\n"
+msgstr ""
+"\n"
+"실행 완료 코드. 재장전 을 기다리는 중입니다\n"
+
+#: py/obj.c
+msgid " File \"%q\""
+msgstr " 파일 \"%q\""
+
+#: py/obj.c
+msgid " File \"%q\", line %d"
+msgstr " 파일 \"%q\", 라인 %d"
+
+#: main.c
+msgid " output:\n"
+msgstr " 산출:\n"
+
+#: py/objstr.c
+#, c-format
+msgid "%%c requires int or char"
+msgstr "%%c 전수(int)또는 캐릭터(char)필요합니다"
+
+#: shared-bindings/microcontroller/Pin.c
+msgid "%q in use"
+msgstr "%q 사용 중입니다"
+
+#: py/obj.c
+msgid "%q index out of range"
+msgstr "%q 인덱스 범위를 벗어났습니다"
+
+#: py/obj.c
+msgid "%q indices must be integers, not %s"
+msgstr "%q 인덱스는 %s 가 아닌 정수 여야합니다"
+
+#: shared-bindings/_bleio/CharacteristicBuffer.c
+#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
+msgid "%q must be >= 1"
+msgstr "%q 는 >=1이어야합니다"
+
+#: shared-bindings/fontio/BuiltinFont.c
+msgid "%q should be an int"
+msgstr "%q 는 정수(int) 여야합니다"
+
+#: py/bc.c py/objnamedtuple.c
+msgid "%q() takes %d positional arguments but %d were given"
+msgstr ""
+
+#: py/argcheck.c
+msgid "'%q' argument required"
+msgstr ""
+
+#: py/emitinlinethumb.c py/emitinlinextensa.c
+#, c-format
+msgid "'%s' expects a label"
+msgstr "'%s' 에는 라벨이 필요합니다"
+
+#: py/emitinlinethumb.c py/emitinlinextensa.c
+#, c-format
+msgid "'%s' expects a register"
+msgstr "'%s%' 에는 레지스터가 필요합니다"
+
+#: py/emitinlinethumb.c
+#, c-format
+msgid "'%s' expects a special register"
+msgstr "'%s' 에는 특별한 레지스터가 필요합니다"
+
+#: py/emitinlinethumb.c
+#, c-format
+msgid "'%s' expects an FPU register"
+msgstr "'%s' 에는 FPU레지스터가 필요합니다"
+
+#: py/emitinlinethumb.c
+#, c-format
+msgid "'%s' expects an address of the form [a, b]"
+msgstr ""
+
+#: py/emitinlinethumb.c py/emitinlinextensa.c
+#, c-format
+msgid "'%s' expects an integer"
+msgstr "'%s' 는 정수 여야합니다"
+
+#: py/emitinlinethumb.c
+#, c-format
+msgid "'%s' expects at most r%d"
+msgstr ""
+
+#: py/emitinlinethumb.c
+#, c-format
+msgid "'%s' expects {r0, r1, ...}"
+msgstr "'%s' {r0, r1, ...}은 을 기대합니다"
+
+#: py/emitinlinextensa.c
+#, c-format
+msgid "'%s' integer %d is not within range %d..%d"
+msgstr ""
+
+#: py/emitinlinethumb.c
+#, c-format
+msgid "'%s' integer 0x%x does not fit in mask 0x%x"
+msgstr ""
+
+#: py/obj.c
+#, c-format
+msgid "'%s' object does not support item assignment"
+msgstr "'%s' 을 지정할 수 없습니다"
+
+#: py/obj.c
+#, c-format
+msgid "'%s' object does not support item deletion"
+msgstr "'%s' 은 삭제할 수 없습니다"
+
+#: py/runtime.c
+msgid "'%s' object has no attribute '%q'"
+msgstr ""
+
+#: py/runtime.c
+#, c-format
+msgid "'%s' object is not an iterator"
+msgstr "'%s' 은 수정할 수 없습니다"
+
+#: py/objtype.c py/runtime.c
+#, c-format
+msgid "'%s' object is not callable"
+msgstr "'%s' 을 검색 할 수 없습니다"
+
+#: py/runtime.c
+#, c-format
+msgid "'%s' object is not iterable"
+msgstr "'%s' 은 변경할 수 없습니다"
+
+#: py/obj.c
+#, c-format
+msgid "'%s' object is not subscriptable"
+msgstr ""
+
+#: py/objstr.c
+msgid "'=' alignment not allowed in string format specifier"
+msgstr ""
+
+#: shared-module/struct/__init__.c
+msgid "'S' and 'O' are not supported format types"
+msgstr ""
+
+#: py/compile.c
+msgid "'align' requires 1 argument"
+msgstr "'align' 에는 1 개의 독립변수가 필요합니다"
+
+#: py/compile.c
+msgid "'await' outside function"
+msgstr "'await' 는 펑크션 외부에 있습니다"
+
+#: py/compile.c
+msgid "'break' outside loop"
+msgstr "'break' 는 루프 외부에 있습니다"
+
+#: py/compile.c
+msgid "'continue' outside loop"
+msgstr "'continue' 는 루프 외부에 있습니다"
+
+#: py/compile.c
+msgid "'data' requires at least 2 arguments"
+msgstr "'data' 에는 >=2 개의 독립변수가 필요합니다"
+
+#: py/compile.c
+msgid "'data' requires integer arguments"
+msgstr ""
+
+#: py/compile.c
+msgid "'label' requires 1 argument"
+msgstr "'label' 에는 1 개의 독립변수가 필요합니다"
+
+#: py/compile.c
+msgid "'return' outside function"
+msgstr "'return' 는 함수 외부에 존재합니다"
+
+#: py/compile.c
+msgid "'yield' outside function"
+msgstr "'yield' 는 함수 외부에 존재합니다"
+
+#: py/compile.c
+msgid "*x must be assignment target"
+msgstr ""
+
+#: py/obj.c
+msgid ", in %q\n"
+msgstr ", 에서 %q\n"
+
+#: py/objcomplex.c
+msgid "0.0 to a complex power"
+msgstr ""
+
+#: py/modbuiltins.c
+msgid "3-arg pow() not supported"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
+msgid "A hardware interrupt channel is already in use"
+msgstr ""
+
+#: shared-bindings/_bleio/Address.c
+#, c-format
+msgid "Address must be %d bytes long"
+msgstr ""
+
+#: shared-bindings/_bleio/Address.c
+msgid "Address type out of range"
+msgstr ""
+
+#: ports/nrf/common-hal/busio/I2C.c
+msgid "All I2C peripherals are in use"
+msgstr "사용중인 모든 I2C주변 기기"
+
+#: ports/nrf/common-hal/busio/SPI.c
+msgid "All SPI peripherals are in use"
+msgstr "사용중인 모든 SPI주변 기기"
+
+#: ports/nrf/common-hal/busio/UART.c
+msgid "All UART peripherals are in use"
+msgstr "사용중인 모든 UART주변 기기"
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+msgid "All event channels in use"
+msgstr ""
+
+#: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+msgid "All sync event channels in use"
+msgstr ""
+
+#: shared-bindings/pulseio/PWMOut.c
+msgid "All timers for this pin are in use"
+msgstr "핀의 모든 타이머가 사용 중입니다"
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+#: ports/atmel-samd/common-hal/pulseio/PulseOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
+#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c
+#: shared-module/_pew/PewPew.c
+msgid "All timers in use"
+msgstr "모든 타이머가 사용 중입니다"
+
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
+#: ports/nrf/common-hal/analogio/AnalogOut.c
+msgid "AnalogOut functionality not supported"
+msgstr ""
+
+#: shared-bindings/analogio/AnalogOut.c
+msgid "AnalogOut is only 16 bits. Value must be less than 65536."
+msgstr ""
+
+#: ports/atmel-samd/common-hal/analogio/AnalogOut.c
+msgid "AnalogOut not supported on given pin"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/pulseio/PulseOut.c
+msgid "Another send is already active"
+msgstr ""
+
+#: shared-bindings/pulseio/PulseOut.c
+msgid "Array must contain halfwords (type 'H')"
+msgstr ""
+
+#: shared-bindings/nvm/ByteArray.c
+msgid "Array values should be single bytes."
+msgstr ""
+
+#: supervisor/shared/safe_mode.c
+msgid "Attempted heap allocation when MicroPython VM not running.\n"
+msgstr ""
+
+#: main.c
+msgid "Auto-reload is off.\n"
+msgstr "자동 재 장전이 꺼져 있습니다\n"
+
+#: main.c
+msgid ""
+"Auto-reload is on. Simply save files over USB to run them or enter REPL to "
+"disable.\n"
+msgstr ""
+"자동 새로 고침이 켜져 있습니다. USB를 통해 파일을 저장하여 실행하십시오. 비활"
+"성화하려면 REPL을 입력하십시오.\n"
+
+#: shared-module/displayio/Display.c
+msgid "Below minimum frame rate"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+msgid "Bit clock and word select must share a clock unit"
+msgstr ""
+
+#: shared-bindings/audiobusio/PDMIn.c
+msgid "Bit depth must be multiple of 8."
+msgstr ""
+
+#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
+msgid "Both pins must support hardware interrupts"
+msgstr ""
+
+#: shared-bindings/displayio/Display.c
+msgid "Brightness must be 0-1.0"
+msgstr ""
+
+#: shared-bindings/supervisor/__init__.c
+msgid "Brightness must be between 0 and 255"
+msgstr "밝기는 0에서 255 사이 여야합니다"
+
+#: shared-bindings/displayio/Display.c
+msgid "Brightness not adjustable"
+msgstr "밝기를 조절할 수 없습니다"
+
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
+#: shared-module/usb_hid/Device.c
+#, c-format
+msgid "Buffer incorrect size. Should be %d bytes."
+msgstr "잘못된 크기의 버퍼. %d 바이트 여야합니다."
+
+#: shared-bindings/displayio/Display.c
+msgid "Buffer is not a bytearray."
+msgstr ""
+
+#: shared-bindings/displayio/Display.c
+msgid "Buffer is too small"
+msgstr ""
+
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
+#, c-format
+msgid "Buffer length %d too big. It must be less than %d"
+msgstr ""
+
+#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
+msgid "Buffer must be at least length 1"
+msgstr "잘못된 크기의 버퍼. >1 여야합니다"
+
+#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
+#: ports/nrf/common-hal/displayio/ParallelBus.c
+#, c-format
+msgid "Bus pin %d is already in use"
+msgstr ""
+
+#: shared-bindings/_bleio/UUID.c
+msgid "Byte buffer must be 16 bytes."
+msgstr "잘못된 크기의 버퍼. 16 바이트 여야합니다."
+
+#: shared-bindings/nvm/ByteArray.c
+msgid "Bytes must be between 0 and 255."
+msgstr "바이트는 0에서 255 사이 여야합니다."
+
+#: py/objtype.c
+msgid "Call super().__init__() before accessing native object."
+msgstr ""
+
+#: shared-bindings/_pixelbuf/PixelBuf.c
+#, c-format
+msgid "Can not use dotstar with %s"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/Characteristic.c
+msgid "Can't set CCCD on local Characteristic"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
+msgid "Cannot delete values"
+msgstr "값을 삭제할 수 없습니다"
+
+#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c
+#: ports/nrf/common-hal/digitalio/DigitalInOut.c
+msgid "Cannot get pull while in output mode"
+msgstr ""
+
+#: ports/nrf/common-hal/microcontroller/Processor.c
+msgid "Cannot get temperature"
+msgstr "온도 데이터를 수신 할 수 없습니다"
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+msgid "Cannot output both channels on the same pin"
+msgstr ""
+
+#: shared-module/bitbangio/SPI.c
+msgid "Cannot read without MISO pin."
+msgstr "MISO핀이 없으면 읽을 수 없습니다"
+
+#: shared-bindings/audiobusio/PDMIn.c
+msgid "Cannot record to a file"
+msgstr "파일에 녹음 할 수 없습니다"
+
+#: shared-module/storage/__init__.c
+msgid "Cannot remount '/' when USB is active."
+msgstr ""
+
+#: ports/atmel-samd/common-hal/microcontroller/__init__.c
+msgid "Cannot reset into bootloader because no bootloader is present."
+msgstr ""
+
+#: shared-bindings/digitalio/DigitalInOut.c
+msgid "Cannot set value when direction is input."
+msgstr ""
+
+#: py/objslice.c
+msgid "Cannot subclass slice"
+msgstr ""
+
+#: shared-module/bitbangio/SPI.c
+msgid "Cannot transfer without MOSI and MISO pins."
+msgstr ""
+
+#: extmod/moductypes.c
+msgid "Cannot unambiguously get sizeof scalar"
+msgstr ""
+
+#: shared-module/bitbangio/SPI.c
+msgid "Cannot write without MOSI pin."
+msgstr ""
+
+#: shared-bindings/_bleio/CharacteristicBuffer.c
+msgid "CharacteristicBuffer writing not provided"
+msgstr ""
+
+#: shared-module/bitbangio/SPI.c
+msgid "Clock pin init failed."
+msgstr ""
+
+#: shared-module/bitbangio/I2C.c
+msgid "Clock stretch too long"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+msgid "Clock unit in use"
+msgstr ""
+
+#: shared-bindings/_pew/PewPew.c
+msgid "Column entry must be digitalio.DigitalInOut"
+msgstr ""
+
+#: shared-bindings/displayio/I2CDisplay.c
+msgid "Command must be 0-255"
+msgstr ""
+
+#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c
+msgid "Command must be an int between 0 and 255"
+msgstr "명령은 0에서 255 사이의 정수(int) 여야합니다"
+
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
+#: py/persistentcode.c
+msgid "Corrupt .mpy file"
+msgstr ""
+
+#: py/emitglue.c
+msgid "Corrupt raw code"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/busio/UART.c
+msgid "Could not initialize UART"
+msgstr ""
+
+#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c
+msgid "Couldn't allocate first buffer"
+msgstr ""
+
+#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c
+msgid "Couldn't allocate second buffer"
+msgstr ""
+
+#: supervisor/shared/safe_mode.c
+msgid "Crash into the HardFault_Handler.\n"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+msgid "DAC already in use"
+msgstr "DAC가 현재 사용 중입니다"
+
+#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
+#: ports/nrf/common-hal/displayio/ParallelBus.c
+msgid "Data 0 pin must be byte aligned"
+msgstr ""
+
+#: shared-module/audiocore/WaveFile.c
+msgid "Data chunk must follow fmt chunk"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Data too large for advertisement packet"
+msgstr "광고 (브로드 캐스트) 패킷에 대한 데이터가 너무 큽니다"
+
+#: shared-bindings/audiobusio/PDMIn.c
+msgid "Destination capacity is smaller than destination_length."
+msgstr ""
+
+#: ports/nrf/common-hal/audiobusio/I2SOut.c
+msgid "Device in use"
+msgstr ""
+
+#: shared-bindings/displayio/Display.c
+msgid "Display must have a 16 bit colorspace."
+msgstr ""
+
+#: shared-bindings/displayio/Display.c
+#: shared-bindings/displayio/EPaperDisplay.c
+msgid "Display rotation must be in 90 degree increments"
+msgstr ""
+
+#: shared-bindings/digitalio/DigitalInOut.c
+msgid "Drive mode not used when direction is input."
+msgstr ""
+
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
+#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
+msgid "EXTINT channel already in use"
+msgstr ""
+
+#: extmod/modure.c
+msgid "Error in regex"
+msgstr "Regex에 오류가 있습니다."
+
+#: shared-bindings/microcontroller/Pin.c
+#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c
+#: shared-bindings/terminalio/Terminal.c
+msgid "Expected a %q"
+msgstr "%q 이 예상되었습니다."
+
+#: shared-bindings/_bleio/CharacteristicBuffer.c
+#: shared-bindings/_bleio/Descriptor.c
+msgid "Expected a Characteristic"
+msgstr "특성(Characteristic)이 예상되었습니다."
+
+#: shared-bindings/_bleio/Characteristic.c
+msgid "Expected a Service"
+msgstr ""
+
+#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
+#: shared-bindings/_bleio/Service.c
+msgid "Expected a UUID"
+msgstr "UUID이 예상되었습니다."
+
+#: shared-bindings/_bleio/Adapter.c
+msgid "Expected an Address"
+msgstr ""
+
+#: shared-module/_pixelbuf/PixelBuf.c
+#, c-format
+msgid "Expected tuple of length %d, got %d"
+msgstr ""
+
+#: shared-bindings/ps2io/Ps2.c
+msgid "Failed sending command."
+msgstr ""
+
+#: ports/nrf/sd_mutex.c
+#, c-format
+msgid "Failed to acquire mutex, err 0x%04x"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
+msgid "Failed to allocate RX buffer"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
+#: ports/nrf/common-hal/pulseio/PulseIn.c
+#, c-format
+msgid "Failed to allocate RX buffer of %d bytes"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to connect: internal error"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to connect: timeout"
+msgstr ""
+
+#: ports/nrf/sd_mutex.c
+#, c-format
+msgid "Failed to release mutex, err 0x%04x"
+msgstr ""
+
+#: py/moduerrno.c
+msgid "File exists"
+msgstr ""
+
+#: ports/nrf/peripherals/nrf/nvm.c
+msgid "Flash erase failed"
+msgstr ""
+
+#: ports/nrf/peripherals/nrf/nvm.c
+#, c-format
+msgid "Flash erase failed to start, err 0x%04x"
+msgstr ""
+
+#: ports/nrf/peripherals/nrf/nvm.c
+msgid "Flash write failed"
+msgstr ""
+
+#: ports/nrf/peripherals/nrf/nvm.c
+#, c-format
+msgid "Flash write failed to start, err 0x%04x"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+msgid "Frequency captured is above capability. Capture Paused."
+msgstr ""
+
+#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c
+#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c
+msgid "Function requires lock"
+msgstr ""
+
+#: shared-bindings/displayio/Display.c
+#: shared-bindings/displayio/EPaperDisplay.c
+msgid "Group already used"
+msgstr ""
+
+#: shared-module/displayio/Group.c
+msgid "Group full"
+msgstr ""
+
+#: extmod/vfs_posix_file.c py/objstringio.c
+msgid "I/O operation on closed file"
+msgstr ""
+
+#: extmod/machine_i2c.c
+msgid "I2C operation not supported"
+msgstr ""
+
+#: py/persistentcode.c
+msgid ""
+"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
+"mpy-update for more info."
+msgstr ""
+
+#: shared-bindings/_pew/PewPew.c
+msgid "Incorrect buffer size"
+msgstr ""
+
+#: py/moduerrno.c
+msgid "Input/output error"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient authentication"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient encryption"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+msgid "Invalid %q pin"
+msgstr ""
+
+#: shared-module/displayio/OnDiskBitmap.c
+msgid "Invalid BMP file"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
+#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
+msgid "Invalid PWM frequency"
+msgstr ""
+
+#: py/moduerrno.c
+msgid "Invalid argument"
+msgstr ""
+
+#: shared-module/displayio/Bitmap.c
+msgid "Invalid bits per value"
+msgstr ""
+
+#: ports/nrf/common-hal/busio/UART.c
+msgid "Invalid buffer size"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+msgid "Invalid capture period. Valid range: 1 - 500"
+msgstr ""
+
+#: shared-bindings/audiomixer/Mixer.c
+msgid "Invalid channel count"
+msgstr ""
+
+#: shared-bindings/digitalio/DigitalInOut.c
+msgid "Invalid direction."
+msgstr ""
+
+#: shared-module/audiocore/WaveFile.c
+msgid "Invalid file"
+msgstr "파일이 유효하지 않습니다"
+
+#: shared-module/audiocore/WaveFile.c
+msgid "Invalid format chunk size"
+msgstr "형식 청크 크기가 잘못되었습니다"
+
+#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c
+msgid "Invalid number of bits"
+msgstr "비트 수가 유효하지 않습니다"
+
+#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c
+msgid "Invalid phase"
+msgstr "단계가 잘못되었습니다"
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c
+#: shared-bindings/pulseio/PWMOut.c
+msgid "Invalid pin"
+msgstr "핀이 잘못되었습니다"
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+msgid "Invalid pin for left channel"
+msgstr "왼쪽 채널 핀이 유효하지 않습니다"
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+msgid "Invalid pin for right channel"
+msgstr "오른쪽 채널 핀이 잘못되었습니다"
+
+#: ports/atmel-samd/common-hal/busio/I2C.c
+#: ports/atmel-samd/common-hal/busio/SPI.c
+#: ports/atmel-samd/common-hal/busio/UART.c
+#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c
+#: ports/nrf/common-hal/busio/I2C.c
+msgid "Invalid pins"
+msgstr "핀이 유효하지 않습니다"
+
+#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c
+msgid "Invalid polarity"
+msgstr ""
+
+#: shared-bindings/_bleio/Characteristic.c
+msgid "Invalid properties"
+msgstr ""
+
+#: shared-bindings/microcontroller/__init__.c
+msgid "Invalid run mode."
+msgstr ""
+
+#: shared-module/_bleio/Attribute.c
+msgid "Invalid security_mode"
+msgstr ""
+
+#: shared-bindings/audiomixer/Mixer.c
+msgid "Invalid voice"
+msgstr ""
+
+#: shared-bindings/audiomixer/Mixer.c
+msgid "Invalid voice count"
+msgstr ""
+
+#: shared-module/audiocore/WaveFile.c
+msgid "Invalid wave file"
+msgstr ""
+
+#: py/compile.c
+msgid "LHS of keyword arg must be an id"
+msgstr ""
+
+#: shared-module/displayio/Group.c
+msgid "Layer already in a group."
+msgstr ""
+
+#: shared-module/displayio/Group.c
+msgid "Layer must be a Group or TileGrid subclass."
+msgstr ""
+
+#: py/objslice.c
+msgid "Length must be an int"
+msgstr "길이는 정수(int) 여야합니다"
+
+#: py/objslice.c
+msgid "Length must be non-negative"
+msgstr ""
+
+#: supervisor/shared/safe_mode.c
+msgid ""
+"Looks like our core CircuitPython code crashed hard. Whoops!\n"
+"Please file an issue at https://github.com/adafruit/circuitpython/issues\n"
+" with the contents of your CIRCUITPY drive and this message:\n"
+msgstr ""
+
+#: shared-module/bitbangio/SPI.c
+msgid "MISO pin init failed."
+msgstr ""
+
+#: shared-module/bitbangio/SPI.c
+msgid "MOSI pin init failed."
+msgstr ""
+
+#: shared-module/displayio/Shape.c
+#, c-format
+msgid "Maximum x value when mirrored is %d"
+msgstr ""
+
+#: supervisor/shared/safe_mode.c
+msgid "MicroPython NLR jump failed. Likely memory corruption.\n"
+msgstr ""
+
+#: supervisor/shared/safe_mode.c
+msgid "MicroPython fatal error.\n"
+msgstr ""
+
+#: shared-bindings/audiobusio/PDMIn.c
+msgid "Microphone startup delay must be in range 0.0 to 1.0"
+msgstr ""
+
+#: shared-bindings/displayio/Group.c
+msgid "Must be a %q subclass."
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/Characteristic.c
+msgid "No CCCD for this Characteristic"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/analogio/AnalogOut.c
+msgid "No DAC on chip"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+msgid "No DMA channel found"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
+msgid "No RX pin"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
+msgid "No TX pin"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+msgid "No available clocks"
+msgstr ""
+
+#: shared-bindings/board/__init__.c
+msgid "No default %q bus"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/touchio/TouchIn.c
+msgid "No free GCLKs"
+msgstr ""
+
+#: shared-bindings/os/__init__.c
+msgid "No hardware random available"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/ps2io/Ps2.c
+msgid "No hardware support on clk pin"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
+#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
+msgid "No hardware support on pin"
+msgstr ""
+
+#: shared-module/touchio/TouchIn.c
+msgid "No pulldown on pin; 1Mohm recommended"
+msgstr ""
+
+#: py/moduerrno.c
+msgid "No space left on device"
+msgstr ""
+
+#: py/moduerrno.c
+msgid "No such file/directory"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#: shared-bindings/_bleio/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 ""
+
+#: shared-bindings/util.c
+msgid ""
+"Object has been deinitialized and can no longer be used. Create a new object."
+msgstr ""
+
+#: ports/nrf/common-hal/busio/UART.c
+msgid "Odd parity is not supported"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+msgid "Only 8 or 16 bit mono with "
+msgstr ""
+
+#: shared-module/displayio/OnDiskBitmap.c
+#, c-format
+msgid ""
+"Only Windows format, uncompressed BMP supported: given header size is %d"
+msgstr ""
+
+#: shared-module/displayio/OnDiskBitmap.c
+#, c-format
+msgid ""
+"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: "
+"%d bpp given"
+msgstr ""
+
+#: shared-bindings/_pixelbuf/PixelBuf.c
+msgid "Only slices with step=1 (aka None) are supported"
+msgstr ""
+
+#: shared-bindings/audiobusio/PDMIn.c
+msgid "Oversample must be multiple of 8."
+msgstr ""
+
+#: shared-bindings/pulseio/PWMOut.c
+msgid ""
+"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"
+msgstr ""
+
+#: shared-bindings/pulseio/PWMOut.c
+msgid ""
+"PWM frequency not writable when variable_frequency is False on construction."
+msgstr ""
+
+#: py/moduerrno.c
+msgid "Permission denied"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/analogio/AnalogIn.c
+#: ports/nrf/common-hal/analogio/AnalogIn.c
+msgid "Pin does not have ADC capabilities"
+msgstr ""
+
+#: shared-bindings/_pixelbuf/PixelBuf.c
+msgid "Pixel beyond bounds of buffer"
+msgstr ""
+
+#: py/builtinhelp.c
+msgid "Plus any modules on the filesystem\n"
+msgstr ""
+
+#: shared-bindings/ps2io/Ps2.c
+msgid "Pop from an empty Ps2 buffer"
+msgstr ""
+
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
+#: main.c
+msgid "Press any key to enter the REPL. Use CTRL-D to reload."
+msgstr ""
+
+#: shared-bindings/digitalio/DigitalInOut.c
+msgid "Pull not used when direction is output."
+msgstr ""
+
+#: ports/nrf/common-hal/rtc/RTC.c
+msgid "RTC calibration is not supported on this board"
+msgstr ""
+
+#: shared-bindings/time/__init__.c
+msgid "RTC is not supported on this board"
+msgstr ""
+
+#: shared-bindings/_pixelbuf/PixelBuf.c
+msgid "Range out of bounds"
+msgstr ""
+
+#: shared-bindings/pulseio/PulseIn.c
+msgid "Read-only"
+msgstr ""
+
+#: extmod/vfs_fat.c py/moduerrno.c
+msgid "Read-only filesystem"
+msgstr ""
+
+#: shared-module/displayio/Bitmap.c
+msgid "Read-only object"
+msgstr ""
+
+#: shared-bindings/displayio/EPaperDisplay.c
+msgid "Refresh too soon"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+msgid "Right channel unsupported"
+msgstr ""
+
+#: shared-bindings/_pew/PewPew.c
+msgid "Row entry must be digitalio.DigitalInOut"
+msgstr ""
+
+#: main.c
+msgid "Running in safe mode! Auto-reload is off.\n"
+msgstr ""
+
+#: main.c
+msgid "Running in safe mode! Not running saved code.\n"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
+msgid "SDA or SCL needs a pull up"
+msgstr ""
+
+#: shared-bindings/audiomixer/Mixer.c
+msgid "Sample rate must be positive"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/audioio/AudioOut.c
+#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
+#, c-format
+msgid "Sample rate too high. It must be less than %d"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+msgid "Serializer in use"
+msgstr ""
+
+#: shared-bindings/nvm/ByteArray.c
+msgid "Slice and value different lengths."
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c
+#: shared-bindings/displayio/TileGrid.c shared-bindings/pulseio/PulseIn.c
+msgid "Slices not supported"
+msgstr ""
+
+#: extmod/modure.c
+msgid "Splitting with sub-captures"
+msgstr ""
+
+#: shared-bindings/supervisor/__init__.c
+msgid "Stack size must be at least 256"
+msgstr ""
+
+#: shared-bindings/multiterminal/__init__.c
+msgid "Stream missing readinto() or write() method."
+msgstr ""
+
+#: supervisor/shared/safe_mode.c
+msgid ""
+"The CircuitPython heap was corrupted because the stack was too small.\n"
+"Please increase stack size limits and press reset (after ejecting "
+"CIRCUITPY).\n"
+"If you didn't change the stack, then file an issue here with the contents of "
+"your CIRCUITPY drive:\n"
+msgstr ""
+
+#: supervisor/shared/safe_mode.c
+msgid ""
+"The `microcontroller` module was used to boot into safe mode. Press reset to "
+"exit safe mode.\n"
+msgstr ""
+
+#: supervisor/shared/safe_mode.c
+msgid ""
+"The microcontroller's power dipped. Please make sure your power supply "
+"provides\n"
+"enough power for the whole circuit and press reset (after ejecting "
+"CIRCUITPY).\n"
+msgstr ""
+
+#: supervisor/shared/safe_mode.c
+msgid ""
+"The reset button was pressed while booting CircuitPython. Press again to "
+"exit safe mode.\n"
+msgstr ""
+
+#: shared-module/audiomixer/MixerVoice.c
+msgid "The sample's bits_per_sample does not match the mixer's"
+msgstr ""
+
+#: shared-module/audiomixer/MixerVoice.c
+msgid "The sample's channel count does not match the mixer's"
+msgstr ""
+
+#: shared-module/audiomixer/MixerVoice.c
+msgid "The sample's sample rate does not match the mixer's"
+msgstr ""
+
+#: shared-module/audiomixer/MixerVoice.c
+msgid "The sample's signedness does not match the mixer's"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c
+msgid "Tile height must exactly divide bitmap height"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
+msgid "Tile index out of bounds"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c
+msgid "Tile value out of bounds"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c
+msgid "Tile width must exactly divide bitmap width"
+msgstr ""
+
+#: supervisor/shared/safe_mode.c
+msgid "To exit, please reset the board without "
+msgstr ""
+
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+msgid "Too many channels in sample."
+msgstr ""
+
+#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
+#: shared-bindings/displayio/ParallelBus.c
+msgid "Too many display busses"
+msgstr ""
+
+#: shared-bindings/displayio/Display.c
+#: shared-bindings/displayio/EPaperDisplay.c
+msgid "Too many displays"
+msgstr ""
+
+#: py/obj.c
+msgid "Traceback (most recent call last):\n"
+msgstr ""
+
+#: shared-bindings/time/__init__.c
+msgid "Tuple or struct_time argument required"
+msgstr ""
+
+#: shared-module/usb_hid/Device.c
+msgid "USB Busy"
+msgstr ""
+
+#: shared-module/usb_hid/Device.c
+msgid "USB Error"
+msgstr ""
+
+#: shared-bindings/_bleio/UUID.c
+msgid "UUID integer value must be 0-0xffff"
+msgstr ""
+
+#: shared-bindings/_bleio/UUID.c
+msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'"
+msgstr "UUID문자열이 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'형식이 아닙니다"
+
+#: shared-bindings/_bleio/UUID.c
+msgid "UUID value is not str, int or byte buffer"
+msgstr ""
+"UUID값이 문자열(str), 정수(int) 또는 바이트버퍼가(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 ""
+
+#: shared-module/displayio/I2CDisplay.c
+#, c-format
+msgid "Unable to find I2C Display at %x"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+msgid "Unable to find free GCLK"
+msgstr ""
+
+#: py/parse.c
+msgid "Unable to init parser"
+msgstr "파서를 초기화(init) 할 수 없습니다"
+
+#: shared-module/displayio/OnDiskBitmap.c
+msgid "Unable to read color palette data"
+msgstr ""
+
+#: shared-bindings/nvm/ByteArray.c
+msgid "Unable to write to nvm."
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/UUID.c
+msgid "Unexpected nrfx uuid type"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown gatt error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown security error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown soft device error: %04x"
+msgstr ""
+
+#: shared-bindings/_pixelbuf/PixelBuf.c
+#, c-format
+msgid "Unmatched number of items on RHS (expected %d, got %d)."
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid ""
+"Unspecified issue. Can be that the pairing prompt on the other device was "
+"declined or ignored."
+msgstr ""
+
+#: ports/atmel-samd/common-hal/busio/I2C.c
+msgid "Unsupported baudrate"
+msgstr ""
+
+#: shared-module/displayio/display_core.c
+msgid "Unsupported display bus type"
+msgstr ""
+
+#: shared-module/audiocore/WaveFile.c
+msgid "Unsupported format"
+msgstr ""
+
+#: py/moduerrno.c
+msgid "Unsupported operation"
+msgstr ""
+
+#: shared-bindings/digitalio/DigitalInOut.c
+msgid "Unsupported pull value."
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/Characteristic.c
+#: ports/nrf/common-hal/_bleio/Descriptor.c
+msgid "Value length != required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/Characteristic.c
+#: ports/nrf/common-hal/_bleio/Descriptor.c
+msgid "Value length > max_length"
+msgstr ""
+
+#: py/emitnative.c
+msgid "Viper functions don't currently support more than 4 arguments"
+msgstr ""
+
+#: main.c
+msgid "WARNING: Your code filename has two extensions\n"
+msgstr ""
+
+#: py/builtinhelp.c
+#, c-format
+msgid ""
+"Welcome to Adafruit CircuitPython %s!\n"
+"\n"
+"Please visit learn.adafruit.com/category/circuitpython for project guides.\n"
+"\n"
+"To list built-in modules please do `help(\"modules\")`.\n"
+msgstr ""
+
+#: supervisor/shared/safe_mode.c
+msgid ""
+"You are running in safe mode which means something unanticipated happened.\n"
+msgstr ""
+
+#: supervisor/shared/safe_mode.c
+msgid "You requested starting safe mode by "
+msgstr ""
+
+#: py/objtype.c
+msgid "__init__() should return None"
+msgstr ""
+
+#: py/objtype.c
+#, c-format
+msgid "__init__() should return None, not '%s'"
+msgstr ""
+
+#: py/objobject.c
+msgid "__new__ arg must be a user-type"
+msgstr ""
+
+#: extmod/modubinascii.c extmod/moduhashlib.c
+msgid "a bytes-like object is required"
+msgstr ""
+
+#: lib/embed/abort_.c
+msgid "abort() called"
+msgstr ""
+
+#: extmod/machine_mem.c
+#, c-format
+msgid "address %08x is not aligned to %d bytes"
+msgstr ""
+
+#: shared-bindings/i2cslave/I2CSlave.c
+msgid "address out of bounds"
+msgstr ""
+
+#: shared-bindings/i2cslave/I2CSlave.c
+msgid "addresses is empty"
+msgstr ""
+
+#: py/modbuiltins.c
+msgid "arg is an empty sequence"
+msgstr ""
+
+#: py/runtime.c
+msgid "argument has wrong type"
+msgstr ""
+
+#: py/argcheck.c shared-bindings/_stage/__init__.c
+#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c
+msgid "argument num/types mismatch"
+msgstr ""
+
+#: py/runtime.c
+msgid "argument should be a '%q' not a '%q'"
+msgstr ""
+
+#: py/objarray.c shared-bindings/nvm/ByteArray.c
+msgid "array/bytes required on right side"
+msgstr ""
+
+#: py/objstr.c
+msgid "attributes not supported yet"
+msgstr ""
+
+#: py/builtinevex.c
+msgid "bad compile mode"
+msgstr ""
+
+#: py/objstr.c
+msgid "bad conversion specifier"
+msgstr ""
+
+#: py/objstr.c
+msgid "bad format string"
+msgstr ""
+
+#: py/binary.c
+msgid "bad typecode"
+msgstr ""
+
+#: py/emitnative.c
+msgid "binary op %q not implemented"
+msgstr ""
+
+#: shared-bindings/busio/UART.c
+msgid "bits must be 7, 8 or 9"
+msgstr "비트(bits)는 7, 8 또는 9 여야합니다"
+
+#: extmod/machine_spi.c
+msgid "bits must be 8"
+msgstr "비트(bits)는 8이어야합니다"
+
+#: shared-bindings/audiomixer/Mixer.c
+msgid "bits_per_sample must be 8 or 16"
+msgstr "bits_per_sample은 8 또는 16이어야합니다."
+
+#: py/emitinlinethumb.c
+msgid "branch not in range"
+msgstr ""
+
+#: shared-bindings/_pixelbuf/PixelBuf.c
+#, c-format
+msgid "buf is too small. need %d bytes"
+msgstr ""
+
+#: shared-bindings/audiocore/RawSample.c
+msgid "buffer must be a bytes-like object"
+msgstr ""
+
+#: shared-module/struct/__init__.c
+msgid "buffer size must match format"
+msgstr ""
+
+#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c
+msgid "buffer slices must be of equal length"
+msgstr ""
+
+#: py/modstruct.c shared-bindings/struct/__init__.c
+#: shared-module/struct/__init__.c
+msgid "buffer too small"
+msgstr ""
+
+#: extmod/machine_spi.c
+msgid "buffers must be the same length"
+msgstr ""
+
+#: shared-bindings/_pew/PewPew.c
+msgid "buttons must be digitalio.DigitalInOut"
+msgstr ""
+
+#: py/vm.c
+msgid "byte code not implemented"
+msgstr ""
+
+#: shared-bindings/_pixelbuf/PixelBuf.c
+#, c-format
+msgid "byteorder is not an instance of ByteOrder (got a %s)"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/busio/UART.c
+msgid "bytes > 8 bits not supported"
+msgstr ""
+
+#: py/objstr.c
+msgid "bytes value out of range"
+msgstr ""
+
+#: ports/atmel-samd/bindings/samd/Clock.c
+msgid "calibration is out of range"
+msgstr ""
+
+#: ports/atmel-samd/bindings/samd/Clock.c
+msgid "calibration is read only"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/rtc/RTC.c
+msgid "calibration value out of range +/-127"
+msgstr ""
+
+#: py/emitinlinethumb.c
+msgid "can only have up to 4 parameters to Thumb assembly"
+msgstr ""
+
+#: py/emitinlinextensa.c
+msgid "can only have up to 4 parameters to Xtensa assembly"
+msgstr ""
+
+#: py/persistentcode.c
+msgid "can only save bytecode"
+msgstr ""
+
+#: py/objtype.c
+msgid "can't add special method to already-subclassed class"
+msgstr ""
+
+#: py/compile.c
+msgid "can't assign to expression"
+msgstr ""
+
+#: py/obj.c
+#, c-format
+msgid "can't convert %s to complex"
+msgstr ""
+
+#: py/obj.c
+#, c-format
+msgid "can't convert %s to float"
+msgstr ""
+
+#: py/obj.c
+#, c-format
+msgid "can't convert %s to int"
+msgstr ""
+
+#: py/objstr.c
+msgid "can't convert '%q' object to %q implicitly"
+msgstr ""
+
+#: py/objint.c
+msgid "can't convert NaN to int"
+msgstr ""
+
+#: shared-bindings/i2cslave/I2CSlave.c
+msgid "can't convert address to int"
+msgstr ""
+
+#: py/objint.c
+msgid "can't convert inf to int"
+msgstr ""
+
+#: py/obj.c
+msgid "can't convert to complex"
+msgstr ""
+
+#: py/obj.c
+msgid "can't convert to float"
+msgstr ""
+
+#: py/obj.c
+msgid "can't convert to int"
+msgstr ""
+
+#: py/objstr.c
+msgid "can't convert to str implicitly"
+msgstr ""
+
+#: py/compile.c
+msgid "can't declare nonlocal in outer code"
+msgstr ""
+
+#: py/compile.c
+msgid "can't delete expression"
+msgstr ""
+
+#: py/emitnative.c
+msgid "can't do binary op between '%q' and '%q'"
+msgstr ""
+
+#: py/objcomplex.c
+msgid "can't do truncated division of a complex number"
+msgstr ""
+
+#: py/compile.c
+msgid "can't have multiple **x"
+msgstr ""
+
+#: py/compile.c
+msgid "can't have multiple *x"
+msgstr ""
+
+#: py/emitnative.c
+msgid "can't implicitly convert '%q' to 'bool'"
+msgstr ""
+
+#: py/emitnative.c
+msgid "can't load from '%q'"
+msgstr ""
+
+#: py/emitnative.c
+msgid "can't load with '%q' index"
+msgstr ""
+
+#: py/objgenerator.c
+msgid "can't pend throw to just-started generator"
+msgstr ""
+
+#: py/objgenerator.c
+msgid "can't send non-None value to a just-started generator"
+msgstr ""
+
+#: py/objnamedtuple.c
+msgid "can't set attribute"
+msgstr ""
+
+#: py/emitnative.c
+msgid "can't store '%q'"
+msgstr ""
+
+#: py/emitnative.c
+msgid "can't store to '%q'"
+msgstr ""
+
+#: py/emitnative.c
+msgid "can't store with '%q' index"
+msgstr ""
+
+#: py/objstr.c
+msgid ""
+"can't switch from automatic field numbering to manual field specification"
+msgstr ""
+
+#: py/objstr.c
+msgid ""
+"can't switch from manual field specification to automatic field numbering"
+msgstr ""
+
+#: py/objtype.c
+msgid "cannot create '%q' instances"
+msgstr ""
+
+#: py/objtype.c
+msgid "cannot create instance"
+msgstr ""
+
+#: py/runtime.c
+msgid "cannot import name %q"
+msgstr ""
+
+#: py/builtinimport.c
+msgid "cannot perform relative import"
+msgstr ""
+
+#: py/emitnative.c
+msgid "casting"
+msgstr ""
+
+#: shared-bindings/_stage/Text.c
+msgid "chars buffer too small"
+msgstr ""
+
+#: py/modbuiltins.c
+msgid "chr() arg not in range(0x110000)"
+msgstr ""
+
+#: py/modbuiltins.c
+msgid "chr() arg not in range(256)"
+msgstr ""
+
+#: shared-bindings/displayio/Palette.c
+msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)"
+msgstr ""
+
+#: shared-bindings/displayio/Palette.c
+msgid "color buffer must be a buffer or int"
+msgstr ""
+
+#: shared-bindings/displayio/Palette.c
+msgid "color buffer must be a bytearray or array of type 'b' or 'B'"
+msgstr ""
+
+#: shared-bindings/displayio/Palette.c
+msgid "color must be between 0x000000 and 0xffffff"
+msgstr ""
+
+#: shared-bindings/displayio/ColorConverter.c
+msgid "color should be an int"
+msgstr ""
+
+#: py/objcomplex.c
+msgid "complex division by zero"
+msgstr ""
+
+#: py/objfloat.c py/parsenum.c
+msgid "complex values not supported"
+msgstr ""
+
+#: extmod/moduzlib.c
+msgid "compression header"
+msgstr ""
+
+#: py/parse.c
+msgid "constant must be an integer"
+msgstr ""
+
+#: py/emitnative.c
+msgid "conversion to object"
+msgstr ""
+
+#: py/parsenum.c
+msgid "decimal numbers not supported"
+msgstr ""
+
+#: py/compile.c
+msgid "default 'except' must be last"
+msgstr ""
+
+#: shared-bindings/audiobusio/PDMIn.c
+msgid ""
+"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8"
+msgstr ""
+
+#: shared-bindings/audiobusio/PDMIn.c
+msgid "destination buffer must be an array of type 'H' for bit_depth = 16"
+msgstr ""
+
+#: shared-bindings/audiobusio/PDMIn.c
+msgid "destination_length must be an int >= 0"
+msgstr ""
+
+#: py/objdict.c
+msgid "dict update sequence has wrong length"
+msgstr ""
+
+#: py/modmath.c py/objfloat.c py/objint_longlong.c py/objint_mpz.c py/runtime.c
+#: shared-bindings/math/__init__.c
+msgid "division by zero"
+msgstr ""
+
+#: py/objdeque.c
+msgid "empty"
+msgstr ""
+
+#: extmod/moduheapq.c extmod/modutimeq.c
+msgid "empty heap"
+msgstr ""
+
+#: py/objstr.c
+msgid "empty separator"
+msgstr ""
+
+#: shared-bindings/random/__init__.c
+msgid "empty sequence"
+msgstr ""
+
+#: py/objstr.c
+msgid "end of format while looking for conversion specifier"
+msgstr ""
+
+#: shared-bindings/displayio/Shape.c
+msgid "end_x should be an int"
+msgstr ""
+
+#: ports/nrf/common-hal/busio/UART.c
+#, c-format
+msgid "error = 0x%08lX"
+msgstr ""
+
+#: py/runtime.c
+msgid "exceptions must derive from BaseException"
+msgstr ""
+
+#: py/objstr.c
+msgid "expected ':' after format specifier"
+msgstr "':'이 예상되었습니다"
+
+#: py/obj.c
+msgid "expected tuple/list"
+msgstr "튜플(tuple) 또는 리스트(list)이 예상되었습니다"
+
+#: py/modthread.c
+msgid "expecting a dict for keyword args"
+msgstr "사전(dict)이 예상되었습니다"
+
+#: py/compile.c
+msgid "expecting an assembler instruction"
+msgstr ""
+
+#: py/compile.c
+msgid "expecting just a value for set"
+msgstr ""
+
+#: py/compile.c
+msgid "expecting key:value for dict"
+msgstr ""
+
+#: py/argcheck.c
+msgid "extra keyword arguments given"
+msgstr ""
+
+#: py/argcheck.c
+msgid "extra positional arguments given"
+msgstr ""
+
+#: shared-bindings/audiocore/WaveFile.c
+#: shared-bindings/displayio/OnDiskBitmap.c
+msgid "file must be a file opened in byte mode"
+msgstr ""
+
+#: shared-bindings/storage/__init__.c
+msgid "filesystem must provide mount method"
+msgstr ""
+
+#: py/objtype.c
+msgid "first argument to super() must be type"
+msgstr ""
+
+#: extmod/machine_spi.c
+msgid "firstbit must be MSB"
+msgstr ""
+
+#: py/objint.c
+msgid "float too big"
+msgstr "float이 너무 큽니다"
+
+#: shared-bindings/_stage/Text.c
+msgid "font must be 2048 bytes long"
+msgstr ""
+
+#: py/objstr.c
+msgid "format requires a dict"
+msgstr ""
+
+#: py/objdeque.c
+msgid "full"
+msgstr "완전한(full)"
+
+#: py/argcheck.c
+msgid "function does not take keyword arguments"
+msgstr ""
+
+#: py/argcheck.c
+#, c-format
+msgid "function expected at most %d arguments, got %d"
+msgstr ""
+
+#: py/bc.c py/objnamedtuple.c
+msgid "function got multiple values for argument '%q'"
+msgstr ""
+
+#: py/argcheck.c
+#, c-format
+msgid "function missing %d required positional arguments"
+msgstr ""
+
+#: py/bc.c
+msgid "function missing keyword-only argument"
+msgstr ""
+
+#: py/bc.c
+msgid "function missing required keyword argument '%q'"
+msgstr ""
+
+#: py/bc.c
+#, c-format
+msgid "function missing required positional argument #%d"
+msgstr ""
+
+#: py/argcheck.c py/bc.c py/objnamedtuple.c
+#, c-format
+msgid "function takes %d positional arguments but %d were given"
+msgstr ""
+
+#: shared-bindings/time/__init__.c
+msgid "function takes exactly 9 arguments"
+msgstr ""
+
+#: py/objgenerator.c
+msgid "generator already executing"
+msgstr ""
+
+#: py/objgenerator.c
+msgid "generator ignored GeneratorExit"
+msgstr ""
+
+#: shared-bindings/_stage/Layer.c
+msgid "graphic must be 2048 bytes long"
+msgstr ""
+
+#: extmod/moduheapq.c
+msgid "heap must be a list"
+msgstr ""
+
+#: py/compile.c
+msgid "identifier redefined as global"
+msgstr ""
+
+#: py/compile.c
+msgid "identifier redefined as nonlocal"
+msgstr ""
+
+#: py/objstr.c
+msgid "incomplete format"
+msgstr ""
+
+#: py/objstr.c
+msgid "incomplete format key"
+msgstr ""
+
+#: extmod/modubinascii.c
+msgid "incorrect padding"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
+#: ports/nrf/common-hal/pulseio/PulseIn.c py/obj.c
+msgid "index out of range"
+msgstr ""
+
+#: py/obj.c
+msgid "indices must be integers"
+msgstr ""
+
+#: py/compile.c
+msgid "inline assembler must be a function"
+msgstr ""
+
+#: py/parsenum.c
+msgid "int() arg 2 must be >= 2 and <= 36"
+msgstr ""
+
+#: py/objstr.c
+msgid "integer required"
+msgstr "정수가 필요합니다"
+
+#: shared-bindings/_bleio/Adapter.c
+#, c-format
+msgid "interval must be in range %s-%s"
+msgstr ""
+
+#: extmod/machine_i2c.c
+msgid "invalid I2C peripheral"
+msgstr "ICT주변 기기가 유효하지 않습니다"
+
+#: extmod/machine_spi.c
+msgid "invalid SPI peripheral"
+msgstr "SPI주변 기기가 유효하지 않습니다"
+
+#: lib/netutils/netutils.c
+msgid "invalid arguments"
+msgstr ""
+
+#: extmod/modussl_axtls.c
+msgid "invalid cert"
+msgstr "cert가 유효하지 않습니다"
+
+#: extmod/uos_dupterm.c
+msgid "invalid dupterm index"
+msgstr "Dupterm index가 유효하지 않습니다"
+
+#: extmod/modframebuf.c
+msgid "invalid format"
+msgstr "형식가 유효하지 않습니다"
+
+#: py/objstr.c
+msgid "invalid format specifier"
+msgstr "형식 지정자(format specifier)가 유효하지 않습니다"
+
+#: extmod/modussl_axtls.c
+msgid "invalid key"
+msgstr "키가 유효하지 않습니다"
+
+#: py/compile.c
+msgid "invalid micropython decorator"
+msgstr ""
+
+#: shared-bindings/random/__init__.c
+msgid "invalid step"
+msgstr "단계(step)가 유효하지 않습니다"
+
+#: py/compile.c py/parse.c
+msgid "invalid syntax"
+msgstr "구문(syntax)가 유효하지 않습니다"
+
+#: py/parsenum.c
+msgid "invalid syntax for integer"
+msgstr "구문(syntax)가 정수가 유효하지 않습니다"
+
+#: py/parsenum.c
+#, c-format
+msgid "invalid syntax for integer with base %d"
+msgstr "구문(syntax)가 정수가 유효하지 않습니다"
+
+#: py/parsenum.c
+msgid "invalid syntax for number"
+msgstr "숫자에 대한 구문(syntax)가 유효하지 않습니다"
+
+#: py/objtype.c
+msgid "issubclass() arg 1 must be a class"
+msgstr ""
+
+#: py/objtype.c
+msgid "issubclass() arg 2 must be a class or a tuple of classes"
+msgstr ""
+
+#: py/objstr.c
+msgid "join expects a list of str/bytes objects consistent with self object"
+msgstr ""
+
+#: py/argcheck.c
+msgid "keyword argument(s) not yet implemented - use normal args instead"
+msgstr ""
+
+#: py/bc.c
+msgid "keywords must be strings"
+msgstr ""
+
+#: py/emitinlinethumb.c py/emitinlinextensa.c
+msgid "label '%q' not defined"
+msgstr ""
+
+#: py/compile.c
+msgid "label redefined"
+msgstr ""
+
+#: py/stream.c
+msgid "length argument not allowed for this type"
+msgstr ""
+
+#: shared-bindings/audiomixer/MixerVoice.c
+msgid "level must be between 0 and 1"
+msgstr ""
+
+#: py/objarray.c
+msgid "lhs and rhs should be compatible"
+msgstr ""
+
+#: py/emitnative.c
+msgid "local '%q' has type '%q' but source is '%q'"
+msgstr ""
+
+#: py/emitnative.c
+msgid "local '%q' used before type known"
+msgstr ""
+
+#: py/vm.c
+msgid "local variable referenced before assignment"
+msgstr ""
+
+#: py/objint.c
+msgid "long int not supported in this build"
+msgstr ""
+
+#: shared-bindings/_stage/Layer.c
+msgid "map buffer too small"
+msgstr ""
+
+#: py/modmath.c shared-bindings/math/__init__.c
+msgid "math domain error"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/Characteristic.c
+#: ports/nrf/common-hal/_bleio/Descriptor.c
+#, c-format
+msgid "max_length must be 0-%d when fixed_length is %s"
+msgstr ""
+
+#: py/runtime.c
+msgid "maximum recursion depth exceeded"
+msgstr ""
+
+#: py/runtime.c
+#, c-format
+msgid "memory allocation failed, allocating %u bytes"
+msgstr ""
+
+#: py/runtime.c
+msgid "memory allocation failed, heap is locked"
+msgstr ""
+
+#: py/builtinimport.c
+msgid "module not found"
+msgstr ""
+
+#: py/compile.c
+msgid "multiple *x in assignment"
+msgstr ""
+
+#: py/objtype.c
+msgid "multiple bases have instance lay-out conflict"
+msgstr ""
+
+#: py/objtype.c
+msgid "multiple inheritance not supported"
+msgstr ""
+
+#: py/emitnative.c
+msgid "must raise an object"
+msgstr ""
+
+#: extmod/machine_spi.c
+msgid "must specify all of sck/mosi/miso"
+msgstr ""
+
+#: py/modbuiltins.c
+msgid "must use keyword argument for key function"
+msgstr ""
+
+#: py/runtime.c
+msgid "name '%q' is not defined"
+msgstr ""
+
+#: py/runtime.c
+msgid "name not defined"
+msgstr ""
+
+#: py/compile.c
+msgid "name reused for argument"
+msgstr ""
+
+#: py/emitnative.c
+msgid "native yield"
+msgstr ""
+
+#: py/runtime.c
+#, c-format
+msgid "need more than %d values to unpack"
+msgstr ""
+
+#: py/objint_longlong.c py/objint_mpz.c py/runtime.c
+msgid "negative power with no float support"
+msgstr ""
+
+#: py/objint_mpz.c py/runtime.c
+msgid "negative shift count"
+msgstr ""
+
+#: py/vm.c
+msgid "no active exception to reraise"
+msgstr ""
+
+#: shared-bindings/socket/__init__.c shared-module/network/__init__.c
+msgid "no available NIC"
+msgstr ""
+
+#: py/compile.c
+msgid "no binding for nonlocal found"
+msgstr ""
+
+#: py/builtinimport.c
+msgid "no module named '%q'"
+msgstr ""
+
+#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
+#: shared-bindings/displayio/ParallelBus.c
+msgid "no reset pin available"
+msgstr ""
+
+#: py/runtime.c shared-bindings/_pixelbuf/__init__.c
+msgid "no such attribute"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/Connection.c
+msgid "non-UUID found in service_uuids_whitelist"
+msgstr ""
+
+#: py/compile.c
+msgid "non-default argument follows default argument"
+msgstr ""
+
+#: extmod/modubinascii.c
+msgid "non-hex digit found"
+msgstr ""
+
+#: py/compile.c
+msgid "non-keyword arg after */**"
+msgstr ""
+
+#: py/compile.c
+msgid "non-keyword arg after keyword arg"
+msgstr ""
+
+#: shared-bindings/_bleio/UUID.c
+msgid "not a 128-bit UUID"
+msgstr ""
+
+#: py/objstr.c
+msgid "not all arguments converted during string formatting"
+msgstr ""
+
+#: py/objstr.c
+msgid "not enough arguments for format string"
+msgstr ""
+
+#: py/obj.c
+#, c-format
+msgid "object '%s' is not a tuple or list"
+msgstr ""
+
+#: py/obj.c
+msgid "object does not support item assignment"
+msgstr ""
+
+#: py/obj.c
+msgid "object does not support item deletion"
+msgstr ""
+
+#: py/obj.c
+msgid "object has no len"
+msgstr ""
+
+#: py/obj.c
+msgid "object is not subscriptable"
+msgstr ""
+
+#: py/runtime.c
+msgid "object not an iterator"
+msgstr ""
+
+#: py/objtype.c py/runtime.c
+msgid "object not callable"
+msgstr ""
+
+#: py/sequence.c shared-bindings/displayio/Group.c
+msgid "object not in sequence"
+msgstr ""
+
+#: py/runtime.c
+msgid "object not iterable"
+msgstr ""
+
+#: py/obj.c
+#, c-format
+msgid "object of type '%s' has no len()"
+msgstr ""
+
+#: py/obj.c
+msgid "object with buffer protocol required"
+msgstr ""
+
+#: extmod/modubinascii.c
+msgid "odd-length string"
+msgstr ""
+
+#: py/objstr.c py/objstrunicode.c
+msgid "offset out of bounds"
+msgstr ""
+
+#: ports/nrf/common-hal/audiobusio/PDMIn.c
+msgid "only bit_depth=16 is supported"
+msgstr ""
+
+#: ports/nrf/common-hal/audiobusio/PDMIn.c
+msgid "only sample_rate=16000 is supported"
+msgstr ""
+
+#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c
+#: shared-bindings/nvm/ByteArray.c
+msgid "only slices with step=1 (aka None) are supported"
+msgstr ""
+
+#: py/modbuiltins.c
+msgid "ord expects a character"
+msgstr ""
+
+#: py/modbuiltins.c
+#, c-format
+msgid "ord() expected a character, but string of length %d found"
+msgstr ""
+
+#: py/objint_mpz.c
+msgid "overflow converting long int to machine word"
+msgstr ""
+
+#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c
+msgid "palette must be 32 bytes long"
+msgstr ""
+
+#: shared-bindings/displayio/Palette.c
+msgid "palette_index should be an int"
+msgstr ""
+
+#: py/compile.c
+msgid "parameter annotation must be an identifier"
+msgstr ""
+
+#: py/emitinlinextensa.c
+msgid "parameters must be registers in sequence a2 to a5"
+msgstr ""
+
+#: py/emitinlinethumb.c
+msgid "parameters must be registers in sequence r0 to r3"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "pixel coordinates out of bounds"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "pixel value requires too many bits"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c
+msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
+#: ports/nrf/common-hal/pulseio/PulseIn.c
+msgid "pop from an empty PulseIn"
+msgstr ""
+
+#: py/objset.c
+msgid "pop from an empty set"
+msgstr ""
+
+#: py/objlist.c
+msgid "pop from empty list"
+msgstr ""
+
+#: py/objdict.c
+msgid "popitem(): dictionary is empty"
+msgstr ""
+
+#: py/objint_mpz.c
+msgid "pow() 3rd argument cannot be 0"
+msgstr ""
+
+#: py/objint_mpz.c
+msgid "pow() with 3 arguments requires integers"
+msgstr ""
+
+#: extmod/modutimeq.c
+msgid "queue overflow"
+msgstr ""
+
+#: shared-bindings/_pixelbuf/PixelBuf.c
+msgid "rawbuf is not the same size as buf"
+msgstr ""
+
+#: shared-bindings/_pixelbuf/__init__.c
+msgid "readonly attribute"
+msgstr ""
+
+#: py/builtinimport.c
+msgid "relative import"
+msgstr ""
+
+#: py/obj.c
+#, c-format
+msgid "requested length %d but object has length %d"
+msgstr ""
+
+#: py/compile.c
+msgid "return annotation must be an identifier"
+msgstr ""
+
+#: py/emitnative.c
+msgid "return expected '%q' but got '%q'"
+msgstr ""
+
+#: py/objstr.c
+msgid "rsplit(None,n)"
+msgstr ""
+
+#: shared-bindings/audiocore/RawSample.c
+msgid ""
+"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or "
+"'B'"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+msgid "sampling rate out of range"
+msgstr ""
+
+#: py/modmicropython.c
+msgid "schedule stack full"
+msgstr ""
+
+#: lib/utils/pyexec.c py/builtinimport.c
+msgid "script compilation not supported"
+msgstr ""
+
+#: py/objstr.c
+msgid "sign not allowed in string format specifier"
+msgstr ""
+
+#: py/objstr.c
+msgid "sign not allowed with integer format specifier 'c'"
+msgstr ""
+
+#: py/objstr.c
+msgid "single '}' encountered in format string"
+msgstr ""
+
+#: shared-bindings/time/__init__.c
+msgid "sleep length must be non-negative"
+msgstr ""
+
+#: py/objslice.c py/sequence.c
+msgid "slice step cannot be zero"
+msgstr ""
+
+#: py/objint.c py/sequence.c
+msgid "small int overflow"
+msgstr ""
+
+#: main.c
+msgid "soft reboot\n"
+msgstr ""
+
+#: py/objstr.c
+msgid "start/end indices"
+msgstr ""
+
+#: shared-bindings/displayio/Shape.c
+msgid "start_x should be an int"
+msgstr ""
+
+#: shared-bindings/random/__init__.c
+msgid "step must be non-zero"
+msgstr ""
+
+#: shared-bindings/busio/UART.c
+msgid "stop must be 1 or 2"
+msgstr ""
+
+#: shared-bindings/random/__init__.c
+msgid "stop not reachable from start"
+msgstr ""
+
+#: py/stream.c
+msgid "stream operation not supported"
+msgstr ""
+
+#: py/objstrunicode.c
+msgid "string index out of range"
+msgstr ""
+
+#: py/objstrunicode.c
+#, c-format
+msgid "string indices must be integers, not %s"
+msgstr ""
+
+#: py/stream.c
+msgid "string not supported; use bytes or bytearray"
+msgstr ""
+
+#: extmod/moductypes.c
+msgid "struct: cannot index"
+msgstr ""
+
+#: extmod/moductypes.c
+msgid "struct: index out of range"
+msgstr ""
+
+#: extmod/moductypes.c
+msgid "struct: no fields"
+msgstr ""
+
+#: py/objstr.c
+msgid "substring not found"
+msgstr ""
+
+#: py/compile.c
+msgid "super() can't find self"
+msgstr ""
+
+#: extmod/modujson.c
+msgid "syntax error in JSON"
+msgstr ""
+
+#: extmod/moductypes.c
+msgid "syntax error in uctypes descriptor"
+msgstr ""
+
+#: shared-bindings/touchio/TouchIn.c
+msgid "threshold must be in the range 0-65536"
+msgstr ""
+
+#: shared-bindings/time/__init__.c
+msgid "time.struct_time() takes a 9-sequence"
+msgstr ""
+
+#: shared-bindings/busio/UART.c
+msgid "timeout must be 0.0-100.0 seconds"
+msgstr ""
+
+#: shared-bindings/_bleio/CharacteristicBuffer.c
+msgid "timeout must be >= 0.0"
+msgstr ""
+
+#: shared-bindings/time/__init__.c
+msgid "timestamp out of range for platform time_t"
+msgstr ""
+
+#: shared-module/struct/__init__.c
+msgid "too many arguments provided with the given format"
+msgstr ""
+
+#: py/runtime.c
+#, c-format
+msgid "too many values to unpack (expected %d)"
+msgstr ""
+
+#: py/objstr.c
+msgid "tuple index out of range"
+msgstr ""
+
+#: py/obj.c
+msgid "tuple/list has wrong length"
+msgstr ""
+
+#: shared-bindings/_pixelbuf/PixelBuf.c
+msgid "tuple/list required on RHS"
+msgstr ""
+
+#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
+msgid "tx and rx cannot both be None"
+msgstr ""
+
+#: py/objtype.c
+msgid "type '%q' is not an acceptable base type"
+msgstr ""
+
+#: py/objtype.c
+msgid "type is not an acceptable base type"
+msgstr ""
+
+#: py/runtime.c
+msgid "type object '%q' has no attribute '%q'"
+msgstr ""
+
+#: py/objtype.c
+msgid "type takes 1 or 3 arguments"
+msgstr ""
+
+#: py/objint_longlong.c
+msgid "ulonglong too large"
+msgstr ""
+
+#: py/emitnative.c
+msgid "unary op %q not implemented"
+msgstr ""
+
+#: py/parse.c
+msgid "unexpected indent"
+msgstr ""
+
+#: py/bc.c
+msgid "unexpected keyword argument"
+msgstr ""
+
+#: py/bc.c py/objnamedtuple.c
+msgid "unexpected keyword argument '%q'"
+msgstr ""
+
+#: py/lexer.c
+msgid "unicode name escapes"
+msgstr ""
+
+#: py/parse.c
+msgid "unindent does not match any outer indentation level"
+msgstr ""
+
+#: py/objstr.c
+#, c-format
+msgid "unknown conversion specifier %c"
+msgstr ""
+
+#: py/objstr.c
+#, c-format
+msgid "unknown format code '%c' for object of type '%s'"
+msgstr ""
+
+#: py/objstr.c
+#, c-format
+msgid "unknown format code '%c' for object of type 'float'"
+msgstr ""
+
+#: py/objstr.c
+#, c-format
+msgid "unknown format code '%c' for object of type 'str'"
+msgstr ""
+
+#: py/compile.c
+msgid "unknown type"
+msgstr ""
+
+#: py/emitnative.c
+msgid "unknown type '%q'"
+msgstr ""
+
+#: py/objstr.c
+msgid "unmatched '{' in format"
+msgstr ""
+
+#: py/objtype.c py/runtime.c
+msgid "unreadable attribute"
+msgstr ""
+
+#: shared-bindings/displayio/TileGrid.c
+msgid "unsupported %q type"
+msgstr ""
+
+#: py/emitinlinethumb.c
+#, c-format
+msgid "unsupported Thumb instruction '%s' with %d arguments"
+msgstr ""
+
+#: py/emitinlinextensa.c
+#, c-format
+msgid "unsupported Xtensa instruction '%s' with %d arguments"
+msgstr ""
+
+#: py/objstr.c
+#, c-format
+msgid "unsupported format character '%c' (0x%x) at index %d"
+msgstr ""
+
+#: py/runtime.c
+msgid "unsupported type for %q: '%s'"
+msgstr ""
+
+#: py/runtime.c
+msgid "unsupported type for operator"
+msgstr ""
+
+#: py/runtime.c
+msgid "unsupported types for %q: '%s', '%s'"
+msgstr ""
+
+#: py/objint.c
+#, c-format
+msgid "value must fit in %d byte(s)"
+msgstr ""
+
+#: shared-bindings/displayio/Bitmap.c
+msgid "value_count must be > 0"
+msgstr ""
+
+#: shared-bindings/_bleio/Adapter.c
+msgid "window must be <= interval"
+msgstr ""
+
+#: shared-bindings/_pixelbuf/PixelBuf.c
+msgid "write_args must be a list, tuple, or None"
+msgstr ""
+
+#: py/objstr.c
+msgid "wrong number of arguments"
+msgstr ""
+
+#: py/runtime.c
+msgid "wrong number of values to unpack"
+msgstr ""
+
+#: shared-module/displayio/Shape.c
+msgid "x value out of bounds"
+msgstr ""
+
+#: shared-bindings/displayio/Shape.c
+msgid "y should be an int"
+msgstr ""
+
+#: shared-module/displayio/Shape.c
+msgid "y value out of bounds"
+msgstr ""
+
+#: py/objrange.c
+msgid "zero step"
+msgstr ""
+
+#~ msgid "Can't add services in Central mode"
+#~ msgstr "센트랄(중앙) 모드에서는 서비스를 추가 할 수 없습니다"
+
+#~ msgid "Can't advertise in Central mode"
+#~ msgstr "센트랄(중앙) 모드로 광고 (브로드 캐스트) 할 수 없습니다"
+
+#~ msgid "Can't change the name in Central mode"
+#~ msgstr "센트랄(중앙) 모드에서는 이름을 변경할 수 없습니다"
+
+#~ msgid "Data too large for the advertisement packet"
+#~ msgstr "광고 (브로드 캐스트) 패킷에 대한 데이터가 너무 큽니다"
+
+#~ msgid "Failed to add service"
+#~ msgstr "서비스를 추가하지 못했습니다"
+
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "서비스를 추가하지 못했습니다., 오류 0x%04x"
+
+#~ msgid "Failed to connect:"
+#~ msgstr "연결할 수 없다"
+
+#~ msgid "Failed to continue scanning"
+#~ msgstr "스캔을 계속할 수 없습니다"
+
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ msgstr "스캔을 계속할 수 없습니다, 오류 0x%04x"
diff --git a/locale/pl.po b/locale/pl.po
index 9ed76924b..edfce95c6 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-11-27 14:54-0500\n"
"PO-Revision-Date: 2019-03-19 18:37-0700\n"
"Last-Translator: Radomir Dopieralski <circuitpython@sheep.art.pl>\n"
"Language-Team: pl\n"
@@ -260,6 +260,10 @@ msgstr "Wszystkie timery tej nóżki w użyciu"
msgid "All timers in use"
msgstr "Wszystkie timery w użyciu"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "AnalogOut jest niewspierane"
@@ -328,6 +332,11 @@ msgstr "Jasność musi być pomiędzy 0 a 255"
msgid "Brightness not adjustable"
msgstr "Jasność nie jest regulowana"
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -458,6 +467,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr "Komenda musi być int pomiędzy 0 a 255"
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -466,11 +481,6 @@ msgstr ""
msgid "Corrupt raw code"
msgstr ""
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Could not decode ble_uuid, err 0x%04x"
-msgstr "Nie można zdekodować ble_uuid, błąd 0x%04x"
-
#: ports/atmel-samd/common-hal/busio/UART.c
msgid "Could not initialize UART"
msgstr "Ustawienie UART nie powiodło się"
@@ -500,7 +510,7 @@ msgstr "Nóżka data 0 musi być wyrównana do bajtu"
msgid "Data chunk must follow fmt chunk"
msgstr "Fragment danych musi następować po fragmencie fmt"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Data too large for advertisement packet"
msgstr "Zbyt dużo danych pakietu rozgłoszeniowego"
@@ -546,10 +556,6 @@ msgstr "Oczekiwano %q"
msgid "Expected a Characteristic"
msgstr "Oczekiwano charakterystyki"
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -559,7 +565,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr "Oczekiwano UUID"
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -577,21 +583,6 @@ msgstr ""
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Nie udało się uzyskać blokady, błąd 0x$04x"
-#: ports/nrf/common-hal/_bleio/Service.c
-#, fuzzy, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Nie udało się dodać charakterystyki, błąd 0x$04x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to add descriptor, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Nie udało się dodać serwisu, błąd 0x%04x"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Nie udała się alokacja bufora RX"
@@ -603,115 +594,18 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Nie udała się alokacja %d bajtów na bufor RX"
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to change softdevice state"
-msgstr "Nie udało się zmienić stanu softdevice"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
-msgid "Failed to connect: timeout"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr "Nie udała się kontynuacja skanowania, błąd 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-msgid "Failed to discover services"
-msgstr "Nie udało się odkryć serwisów"
-
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to get local address"
-msgstr "Nie udało się uzyskać lokalnego adresu"
-
-#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to get softdevice state"
-msgstr "Nie udało się odczytać stanu softdevice"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to notify or indicate attribute value, err 0x%04x"
-msgstr "Nie udało się powiadomić o wartości atrybutu, błąd 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-msgid "Failed to pair"
+msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to read CCCD value, err 0x%04x"
-msgstr "Nie udało się odczytać CCCD, błąd 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#: ports/nrf/common-hal/_bleio/Descriptor.c
-#, c-format
-msgid "Failed to read attribute value, err 0x%04x"
-msgstr "Nie udało się odczytać wartości atrybutu, błąd 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to read gatts value, err 0x%04x"
-msgstr "Nie udało się odczytać gatts, błąd 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
-msgstr "Nie udało się zarejestrować UUID dostawcy, błąd 0x%04x"
-
#: ports/nrf/sd_mutex.c
#, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "Nie udało się zwolnić blokady, błąd 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "Nie udało się rozpocząć rozgłaszania, błąd 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Central.c
-#, c-format
-msgid "Failed to start connecting, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start pairing, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to start scanning, err 0x%04x"
-msgstr "Nie udało się rozpocząć skanowania, błąd 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "Nie udało się zatrzymać rozgłaszania, błąd 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to write CCCD, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to write attribute value, err 0x%04x"
-msgstr "Nie udało się zapisać atrybutu, błąd 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to write gatts value, err 0x%04x"
-msgstr "Nie udało się zapisać gatts, błąd 0x%04x"
-
#: py/moduerrno.c
msgid "File exists"
msgstr "Plik istnieje"
@@ -776,6 +670,14 @@ msgstr "Niewłaściwa wielkość bufora"
msgid "Input/output error"
msgstr "Błąd I/O"
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient authentication"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient encryption"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
@@ -999,9 +901,8 @@ msgstr "Brak miejsca"
msgid "No such file/directory"
msgstr "Brak pliku/katalogu"
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
msgid "Not connected"
msgstr "Nie podłączono"
@@ -1075,6 +976,10 @@ msgstr "Oraz moduły w systemie plików\n"
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+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ć."
@@ -1127,7 +1032,7 @@ msgstr "Uruchomiony tryb bezpieczeństwa! Samo-przeładowanie wyłączone.\n"
msgid "Running in safe mode! Not running saved code.\n"
msgstr "Uruchomiony tryb bezpieczeństwa! Zapisany kod nie jest uruchamiany.\n"
-#: ports/atmel-samd/common-hal/busio/I2C.c
+#: ports/atmel-samd/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
msgid "SDA or SCL needs a pull up"
msgstr "SDA lub SCL wymagają podciągnięcia"
@@ -1141,6 +1046,10 @@ msgstr "Częstotliwość próbkowania musi być dodatnia"
msgid "Sample rate too high. It must be less than %d"
msgstr "Zbyt wysoka częstotliwość próbkowania. Musi być mniejsza niż %d"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1155,11 +1064,6 @@ msgstr "Fragment i wartość są różnych długości."
msgid "Slices not supported"
msgstr "Fragmenty nieobsługiwane"
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Podział z podgrupami"
@@ -1320,11 +1224,32 @@ msgstr "Błąd zapisu do NVM."
msgid "Unexpected nrfx uuid type"
msgstr "Nieoczekiwany typ nrfx uuid."
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown gatt error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown security error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown soft device error: %04x"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Unmatched number of items on RHS (expected %d, got %d)."
msgstr "Zła liczba obiektów po prawej stronie (oczekiwano %d, jest %d)."
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid ""
+"Unspecified issue. Can be that the pairing prompt on the other device was "
+"declined or ignored."
+msgstr ""
+
#: ports/atmel-samd/common-hal/busio/I2C.c
msgid "Unsupported baudrate"
msgstr "Zła szybkość transmisji"
@@ -1975,7 +1900,7 @@ msgstr "argument 2 do int() busi być pomiędzy 2 a 36"
msgid "integer required"
msgstr "wymagana liczba całkowita"
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2152,10 +2077,6 @@ msgstr "funkcja key musi być podana jako argument nazwany"
msgid "name '%q' is not defined"
msgstr "nazwa '%q' niezdefiniowana"
-#: shared-bindings/_bleio/Peripheral.c
-msgid "name must be a string"
-msgstr "nazwa musi być łańcuchem"
-
#: py/runtime.c
msgid "name not defined"
msgstr "nazwa niezdefiniowana"
@@ -2206,7 +2127,7 @@ msgstr ""
msgid "no such attribute"
msgstr "nie ma takiego atrybutu"
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2529,13 +2450,9 @@ msgstr "threshold musi być w zakresie 0-65536"
msgid "time.struct_time() takes a 9-sequence"
msgstr "time.struct_time() wymaga 9-elementowej sekwencji"
-#: shared-bindings/time/__init__.c
-msgid "time.struct_time() takes exactly 1 argument"
-msgstr "time.struct_time() wymaga jednego argumentu"
-
#: shared-bindings/busio/UART.c
-msgid "timeout >100 (units are now seconds, not msecs)"
-msgstr "timeout > 100 (jednostkami są sekundy)"
+msgid "timeout must be 0.0-100.0 seconds"
+msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
msgid "timeout must be >= 0.0"
@@ -2690,7 +2607,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr "value_count musi być > 0"
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
@@ -2743,36 +2660,91 @@ msgstr "zerowy krok"
#~ msgid "Characteristic already in use by another Service."
#~ msgstr "Charakterystyka w użyciu w innym serwisie"
+#~ msgid "Could not decode ble_uuid, err 0x%04x"
+#~ msgstr "Nie można zdekodować ble_uuid, błąd 0x%04x"
+
#~ 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"
+#, fuzzy
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Nie udało się dodać charakterystyki, błąd 0x$04x"
+
#~ msgid "Failed to add service"
#~ msgstr "Nie udało się dodać serwisu"
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Nie udało się dodać serwisu, błąd 0x%04x"
+
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "Nie udało się zmienić stanu softdevice"
+
#~ 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 continue scanning, err 0x%04x"
+#~ msgstr "Nie udała się kontynuacja skanowania, błąd 0x%04x"
+
#~ msgid "Failed to create mutex"
#~ msgstr "Nie udało się stworzyć blokady"
+#~ msgid "Failed to discover services"
+#~ msgstr "Nie udało się odkryć serwisów"
+
+#~ msgid "Failed to get local address"
+#~ msgstr "Nie udało się uzyskać lokalnego adresu"
+
+#~ msgid "Failed to get softdevice state"
+#~ msgstr "Nie udało się odczytać stanu softdevice"
+
+#~ msgid "Failed to notify or indicate attribute value, err 0x%04x"
+#~ msgstr "Nie udało się powiadomić o wartości atrybutu, błąd 0x%04x"
+
+#~ msgid "Failed to read CCCD value, err 0x%04x"
+#~ msgstr "Nie udało się odczytać CCCD, błąd 0x%04x"
+
+#~ msgid "Failed to read attribute value, err 0x%04x"
+#~ msgstr "Nie udało się odczytać wartości atrybutu, błąd 0x%04x"
+
+#~ msgid "Failed to read gatts value, err 0x%04x"
+#~ 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"
+
#~ 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 advertising, err 0x%04x"
+#~ msgstr "Nie udało się rozpocząć rozgłaszania, błąd 0x%04x"
+
#~ msgid "Failed to start scanning"
#~ msgstr "Nie udało się rozpocząć skanowania"
+#~ msgid "Failed to start scanning, err 0x%04x"
+#~ msgstr "Nie udało się rozpocząć skanowania, błąd 0x%04x"
+
#~ msgid "Failed to stop advertising"
#~ msgstr "Nie udało się zatrzymać rozgłaszania"
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "Nie udało się zatrzymać rozgłaszania, błąd 0x%04x"
+
+#~ msgid "Failed to write attribute value, err 0x%04x"
+#~ msgstr "Nie udało się zapisać atrybutu, błąd 0x%04x"
+
+#~ msgid "Failed to write gatts value, err 0x%04x"
+#~ msgstr "Nie udało się zapisać gatts, błąd 0x%04x"
+
#~ msgid "Invalid bit clock pin"
#~ msgstr "Zła nóżka zegara"
@@ -2790,6 +2762,9 @@ msgstr "zerowy krok"
#~ "bpp given"
#~ msgstr "Wspierane są tylko pliki BMP czarno-białe, 8bpp i 16bpp: %d bpp "
+#~ msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
+#~ msgstr "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
+
#~ msgid "Tile indices must be 0 - 255"
#~ msgstr "Indeks kafelka musi być pomiędzy 0 a 255 włącznie"
@@ -2809,8 +2784,17 @@ msgstr "zerowy krok"
#~ msgid "interval not in range 0.0020 to 10.24"
#~ msgstr "przedział poza zakresem 0.0020 do 10.24"
+#~ msgid "name must be a string"
+#~ msgstr "nazwa musi być łańcuchem"
+
#~ 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"
+
+#~ msgid "time.struct_time() takes exactly 1 argument"
+#~ msgstr "time.struct_time() wymaga jednego argumentu"
+
+#~ msgid "timeout >100 (units are now seconds, not msecs)"
+#~ msgstr "timeout > 100 (jednostkami są sekundy)"
diff --git a/locale/pt_BR.po b/locale/pt_BR.po
index a17a27539..a2b259fc4 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-11-27 14:54-0500\n"
"PO-Revision-Date: 2018-10-02 21:14-0000\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -262,6 +262,10 @@ msgstr "Todos os temporizadores para este pino estão em uso"
msgid "All timers in use"
msgstr "Todos os temporizadores em uso"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "Funcionalidade AnalogOut não suportada"
@@ -328,6 +332,11 @@ msgstr "O brilho deve estar entre 0 e 255"
msgid "Brightness not adjustable"
msgstr ""
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -461,6 +470,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr "Os bytes devem estar entre 0 e 255."
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -469,11 +484,6 @@ msgstr ""
msgid "Corrupt raw code"
msgstr ""
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Could not decode ble_uuid, err 0x%04x"
-msgstr ""
-
#: ports/atmel-samd/common-hal/busio/UART.c
msgid "Could not initialize UART"
msgstr "Não foi possível inicializar o UART"
@@ -503,7 +513,7 @@ msgstr ""
msgid "Data chunk must follow fmt chunk"
msgstr "Pedaço de dados deve seguir o pedaço de cortes"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, fuzzy
msgid "Data too large for advertisement packet"
msgstr "Não é possível ajustar dados no pacote de anúncios."
@@ -551,10 +561,6 @@ msgstr "Esperado um"
msgid "Expected a Characteristic"
msgstr "Não é possível adicionar Característica."
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -565,7 +571,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr "Esperado um"
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -583,21 +589,6 @@ msgstr "Falha ao enviar comando."
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
-#: ports/nrf/common-hal/_bleio/Service.c
-#, fuzzy, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Não pode parar propaganda. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to add descriptor, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Não pode parar propaganda. status: 0x%02x"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Falha ao alocar buffer RX"
@@ -609,118 +600,18 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Falha ao alocar buffer RX de %d bytes"
#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to change softdevice state"
-msgstr "Não pode parar propaganda. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Central.c
-msgid "Failed to connect: timeout"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, fuzzy, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy
-msgid "Failed to discover services"
-msgstr "Não pode parar propaganda. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to get local address"
+msgid "Failed to connect: internal error"
msgstr ""
#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to get softdevice state"
-msgstr "Não pode parar propaganda. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to notify or indicate attribute value, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-msgid "Failed to pair"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, fuzzy, c-format
-msgid "Failed to read CCCD value, err 0x%04x"
-msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#: ports/nrf/common-hal/_bleio/Descriptor.c
-#, c-format
-msgid "Failed to read attribute value, err 0x%04x"
+msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy, c-format
-msgid "Failed to read gatts value, err 0x%04x"
-msgstr "Não é possível gravar o valor do atributo. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, fuzzy, c-format
-msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
-msgstr "Não é possível adicionar o UUID de 128 bits específico do fornecedor."
-
#: ports/nrf/sd_mutex.c
#, fuzzy, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Central.c
-#, c-format
-msgid "Failed to start connecting, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start pairing, error 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, fuzzy, c-format
-msgid "Failed to start scanning, err 0x%04x"
-msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "Não pode parar propaganda. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to write CCCD, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy, c-format
-msgid "Failed to write attribute value, err 0x%04x"
-msgstr "Não é possível gravar o valor do atributo. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, fuzzy, c-format
-msgid "Failed to write gatts value, err 0x%04x"
-msgstr "Não é possível gravar o valor do atributo. status: 0x%02x"
-
#: py/moduerrno.c
msgid "File exists"
msgstr "Arquivo já existe"
@@ -783,6 +674,14 @@ msgstr ""
msgid "Input/output error"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient authentication"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient encryption"
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
@@ -1004,9 +903,8 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
#, fuzzy
msgid "Not connected"
msgstr "Não é possível conectar-se ao AP"
@@ -1084,6 +982,10 @@ msgstr "Não é possível remontar o sistema de arquivos"
msgid "Pop from an empty Ps2 buffer"
msgstr "Buffer Ps2 vazio"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1137,7 +1039,7 @@ msgstr "Rodando em modo seguro! Atualização automática está desligada.\n"
msgid "Running in safe mode! Not running saved code.\n"
msgstr "Rodando em modo seguro! Não está executando o código salvo.\n"
-#: ports/atmel-samd/common-hal/busio/I2C.c
+#: ports/atmel-samd/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
msgid "SDA or SCL needs a pull up"
msgstr "SDA ou SCL precisa de um pull up"
@@ -1151,6 +1053,10 @@ msgstr ""
msgid "Sample rate too high. It must be less than %d"
msgstr "Taxa de amostragem muito alta. Deve ser menor que %d"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1165,11 +1071,6 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr ""
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr ""
@@ -1320,11 +1221,32 @@ msgstr "Não é possível gravar no nvm."
msgid "Unexpected nrfx uuid type"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown gatt error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown security error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown soft device error: %04x"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Unmatched number of items on RHS (expected %d, got %d)."
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid ""
+"Unspecified issue. Can be that the pairing prompt on the other device was "
+"declined or ignored."
+msgstr ""
+
#: ports/atmel-samd/common-hal/busio/I2C.c
msgid "Unsupported baudrate"
msgstr "Taxa de transmissão não suportada"
@@ -1975,7 +1897,7 @@ msgstr ""
msgid "integer required"
msgstr "inteiro requerido"
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2152,11 +2074,6 @@ msgstr ""
msgid "name '%q' is not defined"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c
-#, fuzzy
-msgid "name must be a string"
-msgstr "heap deve ser uma lista"
-
#: py/runtime.c
msgid "name not defined"
msgstr "nome não definido"
@@ -2207,7 +2124,7 @@ msgstr ""
msgid "no such attribute"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2530,12 +2447,8 @@ msgstr "Limite deve estar no alcance de 0-65536"
msgid "time.struct_time() takes a 9-sequence"
msgstr ""
-#: shared-bindings/time/__init__.c
-msgid "time.struct_time() takes exactly 1 argument"
-msgstr ""
-
#: shared-bindings/busio/UART.c
-msgid "timeout >100 (units are now seconds, not msecs)"
+msgid "timeout must be 0.0-100.0 seconds"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
@@ -2692,7 +2605,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr ""
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
@@ -2760,22 +2673,59 @@ msgstr "passo zero"
#~ msgstr "Falha ao alocar buffer RX"
#, fuzzy
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Não pode parar propaganda. status: 0x%02x"
+
+#, fuzzy
#~ msgid "Failed to add service"
#~ msgstr "Não pode parar propaganda. status: 0x%02x"
#, fuzzy
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Não pode parar propaganda. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "Não pode parar propaganda. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ msgstr "Não é possível iniciar o anúncio. 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 discover services"
+#~ msgstr "Não pode parar propaganda. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to get softdevice state"
+#~ msgstr "Não pode parar propaganda. status: 0x%02x"
+
+#, fuzzy
#~ msgid "Failed to notify or indicate attribute value, err %0x04x"
#~ msgstr "Não é possível gravar o valor do atributo. status: 0x%02x"
#, fuzzy
+#~ msgid "Failed to read CCCD value, err 0x%04x"
+#~ msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
+
+#, fuzzy
#~ msgid "Failed to read attribute value, err %0x04x"
#~ msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
#, fuzzy
+#~ msgid "Failed to read gatts value, err 0x%04x"
+#~ msgstr "Não é possível gravar o valor do atributo. status: 0x%02x"
+
+#, fuzzy
+#~ 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."
+
+#, fuzzy
#~ msgid "Failed to release mutex"
#~ msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
@@ -2784,13 +2734,33 @@ msgstr "passo zero"
#~ msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
#, fuzzy
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ 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 start scanning, err 0x%04x"
+#~ 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"
+#, fuzzy
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "Não pode parar propaganda. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to write attribute value, err 0x%04x"
+#~ msgstr "Não é possível gravar o valor do atributo. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to write gatts value, err 0x%04x"
+#~ msgstr "Não é possível gravar o valor do atributo. status: 0x%02x"
+
#~ msgid "GPIO16 does not support pull up."
#~ msgstr "GPIO16 não suporta pull up."
@@ -2921,6 +2891,10 @@ msgstr "passo zero"
#~ msgid "memory allocation failed, allocating %u bytes for native code"
#~ msgstr "alocação de memória falhou, alocando %u bytes para código nativo"
+#, fuzzy
+#~ msgid "name must be a string"
+#~ msgstr "heap deve ser uma lista"
+
#~ msgid "not a valid ADC Channel: %d"
#~ msgstr "não é um canal ADC válido: %d"
diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po
index d5df0b7b0..de78d35b5 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-11-27 14:54-0500\n"
"PO-Revision-Date: 2019-04-13 10:10-0700\n"
"Last-Translator: hexthat\n"
"Language-Team: Chinese Hanyu Pinyin\n"
@@ -261,6 +261,10 @@ msgstr "Cǐ yǐn jiǎo de suǒyǒu jìshí qì zhèngzài shǐyòng"
msgid "All timers in use"
msgstr "Suǒyǒu jìshí qì shǐyòng"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "Bù zhīchí AnalogOut gōngnéng"
@@ -329,6 +333,11 @@ msgstr "Liàngdù bìxū jiè yú 0 dào 255 zhī jiān"
msgid "Brightness not adjustable"
msgstr "Liàngdù wúfǎ tiáozhěng"
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -459,6 +468,12 @@ msgstr "Mìnglìng bìxū wèi 0-255"
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"
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr "Fǔbài de .mpy wénjiàn"
@@ -467,11 +482,6 @@ msgstr "Fǔbài de .mpy wénjiàn"
msgid "Corrupt raw code"
msgstr "Sǔnhuài de yuánshǐ dàimǎ"
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Could not decode ble_uuid, err 0x%04x"
-msgstr "Wúfǎ jiěmǎ kě dú_uuid, err 0x%04x"
-
#: ports/atmel-samd/common-hal/busio/UART.c
msgid "Could not initialize UART"
msgstr "Wúfǎ chūshǐhuà UART"
@@ -501,7 +511,7 @@ msgstr "Shùjù 0 de yǐn jiǎo bìxū shì zì jié duìqí"
msgid "Data chunk must follow fmt chunk"
msgstr "Shùjù kuài bìxū zūnxún fmt qū kuài"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Data too large for advertisement packet"
msgstr "Guǎnggào bāo de shùjù tài dà"
@@ -547,10 +557,6 @@ msgstr "Yùqí %q"
msgid "Expected a Characteristic"
msgstr "Yùqí de tèdiǎn"
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr "Qídài yīgè wàiwéi shèbèi"
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr "Yùqí fúwù"
@@ -560,7 +566,7 @@ msgstr "Yùqí fúwù"
msgid "Expected a UUID"
msgstr "Yùqí UUID"
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr "Qídài yīgè dìzhǐ"
@@ -578,21 +584,6 @@ msgstr "Fāsòng mìnglìng shībài."
msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Wúfǎ huòdé mutex, err 0x%04x"
-#: ports/nrf/common-hal/_bleio/Service.c
-#, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Tiānjiā tèxìng shībài, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to add descriptor, err 0x%04x"
-msgstr "Wúfǎ tiānjiā miáoshù fú, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Tiānjiā fúwù shībài, err 0x%04x"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Fēnpèi RX huǎnchōng shībài"
@@ -604,115 +595,18 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Fēnpèi RX huǎnchōng qū%d zì jié shībài"
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to change softdevice state"
-msgstr "Gēnggǎi ruǎn shèbèi zhuàngtài shībài"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
-msgstr "Wúfǎ pèizhì guǎnggào, cuòwù 0x%04x"
+msgid "Failed to connect: internal error"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Failed to connect: timeout"
msgstr "Liánjiē shībài: Chāoshí"
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr "Jìxù sǎomiáo shībài, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-msgid "Failed to discover services"
-msgstr "Fāxiàn fúwù shībài"
-
-#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to get local address"
-msgstr "Huòqǔ běndì dìzhǐ shībài"
-
-#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to get softdevice state"
-msgstr "Wúfǎ huòdé ruǎnjiàn shèbèi zhuàngtài"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to notify or indicate attribute value, err 0x%04x"
-msgstr "Wúfǎ tōngzhī huò xiǎnshì shǔxìng zhí, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-msgid "Failed to pair"
-msgstr "Pèiduì shībài"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to read CCCD value, err 0x%04x"
-msgstr "Dòu qǔ CCCD zhí, err 0x%04x shībài"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#: ports/nrf/common-hal/_bleio/Descriptor.c
-#, c-format
-msgid "Failed to read attribute value, err 0x%04x"
-msgstr "Dòu qǔ shǔxìng zhí shībài, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to read gatts value, err 0x%04x"
-msgstr "Wúfǎ dòu qǔ gatts zhí, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/UUID.c
-#, c-format
-msgid "Failed to register Vendor-Specific UUID, err 0x%04x"
-msgstr "Wúfǎ zhùcè màizhǔ tèdìng de UUID, err 0x%04x"
-
#: ports/nrf/sd_mutex.c
#, c-format
msgid "Failed to release mutex, err 0x%04x"
msgstr "Wúfǎ shìfàng mutex, err 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr "Wúfǎ shèzhì shèbèi míngchēng, cuòwù 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "Qǐdòng guǎnggào shībài, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Central.c
-#, c-format
-msgid "Failed to start connecting, error 0x%04x"
-msgstr "Wúfǎ kāishǐ liánjiē, cuòwù 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start pairing, error 0x%04x"
-msgstr "Wúfǎ kāishǐ pèiduì, cuòwù 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to start scanning, err 0x%04x"
-msgstr "Qǐdòng sǎomiáo shībài, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "Wúfǎ tíngzhǐ guǎnggào, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#, c-format
-msgid "Failed to write CCCD, err 0x%04x"
-msgstr "Wúfǎ xiě rù CCCD, cuòwù 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to write attribute value, err 0x%04x"
-msgstr "Xiě rù shǔxìng zhí shībài, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/__init__.c
-#, c-format
-msgid "Failed to write gatts value, err 0x%04x"
-msgstr "Xiě rù gatts zhí,err 0x%04x shībài"
-
#: py/moduerrno.c
msgid "File exists"
msgstr "Wénjiàn cúnzài"
@@ -777,6 +671,14 @@ msgstr "Huǎnchōng qū dàxiǎo bù zhèngquè"
msgid "Input/output error"
msgstr "Shūrù/shūchū cuòwù"
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient authentication"
+msgstr "Rènzhèng bùzú"
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid "Insufficient encryption"
+msgstr "Jiāmì bùzú"
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Invalid %q pin"
@@ -999,9 +901,8 @@ 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/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
msgid "Not connected"
msgstr "Wèi liánjiē"
@@ -1079,6 +980,10 @@ msgstr "Zài wénjiàn xìtǒng shàng tiānjiā rènhé mókuài\n"
msgid "Pop from an empty Ps2 buffer"
msgstr "Cóng kōng de Ps2 huǎnchōng qū dànchū"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: 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."
@@ -1131,7 +1036,7 @@ msgstr "Zài ānquán móshì xià yùnxíng! Zìdòng chóngxīn jiāzài yǐ g
msgid "Running in safe mode! Not running saved code.\n"
msgstr "Zài ānquán móshì xià yùnxíng! Bù yùnxíng yǐ bǎocún de dàimǎ.\n"
-#: ports/atmel-samd/common-hal/busio/I2C.c
+#: ports/atmel-samd/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
msgid "SDA or SCL needs a pull up"
msgstr "SDA huò SCL xūyào lādòng"
@@ -1145,6 +1050,10 @@ msgstr "Cǎiyàng lǜ bìxū wèi zhèng shù"
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/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1159,11 +1068,6 @@ msgstr "Qiēpiàn hé zhí bùtóng chángdù."
msgid "Slices not supported"
msgstr "Qiēpiàn bù shòu zhīchí"
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr "Ruǎn shèbèi wéihù, id: 0X%08lX, pc: 0X%08lX"
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Yǔ zi bǔhuò fēnliè"
@@ -1326,11 +1230,32 @@ msgstr "Wúfǎ xiě rù nvm."
msgid "Unexpected nrfx uuid type"
msgstr "Yìwài de nrfx uuid lèixíng"
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown gatt error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown security error: 0x%04x"
+msgstr ""
+
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Unknown soft device error: %04x"
+msgstr ""
+
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Unmatched number of items on RHS (expected %d, got %d)."
msgstr "RHS (yùqí %d, huòdé %d) shàng wèi pǐpèi de xiàngmù."
+#: ports/nrf/common-hal/_bleio/__init__.c
+msgid ""
+"Unspecified issue. Can be that the pairing prompt on the other device was "
+"declined or ignored."
+msgstr ""
+
#: ports/atmel-samd/common-hal/busio/I2C.c
msgid "Unsupported baudrate"
msgstr "Bù zhīchí de baudrate"
@@ -1986,7 +1911,7 @@ msgstr "zhěngshù() cānshù 2 bìxū > = 2 qiě <= 36"
msgid "integer required"
msgstr "xūyào zhěngshù"
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.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"
@@ -2164,10 +2089,6 @@ msgstr "bìxū shǐyòng guānjiàn cí cānshù"
msgid "name '%q' is not defined"
msgstr "míngchēng '%q' wèi dìngyì"
-#: shared-bindings/_bleio/Peripheral.c
-msgid "name must be a string"
-msgstr "míngchēng bìxū shì yīgè zìfú chuàn"
-
#: py/runtime.c
msgid "name not defined"
msgstr "míngchēng wèi dìngyì"
@@ -2219,7 +2140,7 @@ msgstr "Méiyǒu kěyòng de fùwèi yǐn jiǎo"
msgid "no such attribute"
msgstr "méiyǒu cǐ shǔxìng"
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr "Zài service_uuids bái míngdān zhōng zhǎodào fēi UUID"
@@ -2542,13 +2463,9 @@ msgstr "yùzhí bìxū zài fànwéi 0-65536"
msgid "time.struct_time() takes a 9-sequence"
msgstr "time.struct_time() xūyào 9 xùliè"
-#: shared-bindings/time/__init__.c
-msgid "time.struct_time() takes exactly 1 argument"
-msgstr "time.struct_time() xūyào wánquán 1 cānshù"
-
#: shared-bindings/busio/UART.c
-msgid "timeout >100 (units are now seconds, not msecs)"
-msgstr "chāoshí >100 (dānwèi shì miǎo, ér bùshì háomiǎo)"
+msgid "timeout must be 0.0-100.0 seconds"
+msgstr "Chāo shí shíjiān bìxū wèi 0.0 Dào 100.0 Miǎo"
#: shared-bindings/_bleio/CharacteristicBuffer.c
msgid "timeout must be >= 0.0"
@@ -2703,7 +2620,7 @@ msgstr "Zhí bìxū fúhé %d zì jié"
msgid "value_count must be > 0"
msgstr "zhí jìshù bìxū wèi > 0"
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr "Chuāngkǒu bìxū shì <= jiàngé"
@@ -2759,36 +2676,114 @@ msgstr "líng bù"
#~ msgid "Characteristic already in use by another Service."
#~ msgstr "Qítā fúwù bùmén yǐ shǐyòng de gōngnéng."
+#~ msgid "Could not decode ble_uuid, err 0x%04x"
+#~ msgstr "Wúfǎ jiěmǎ kě dú_uuid, err 0x%04x"
+
#~ msgid "Data too large for the advertisement packet"
#~ msgstr "Guǎnggào bāo de shùjù tài dà"
+#~ msgid "Expected a Peripheral"
+#~ msgstr "Qídài yīgè wàiwéi shèbèi"
+
#~ msgid "Failed to acquire mutex"
#~ msgstr "Wúfǎ huòdé mutex"
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Tiānjiā tèxìng shībài, err 0x%04x"
+
+#~ msgid "Failed to add descriptor, err 0x%04x"
+#~ msgstr "Wúfǎ tiānjiā miáoshù fú, err 0x%04x"
+
#~ msgid "Failed to add service"
#~ msgstr "Tiānjiā fúwù shībài"
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Tiānjiā fúwù shībài, err 0x%04x"
+
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "Gēnggǎi ruǎn shèbèi zhuàngtài shībài"
+
+#~ msgid "Failed to configure advertising, err 0x%04x"
+#~ msgstr "Wúfǎ pèizhì guǎnggào, cuòwù 0x%04x"
+
#~ 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 continue scanning, err 0x%04x"
+#~ msgstr "Jìxù sǎomiáo shībài, err 0x%04x"
+
#~ msgid "Failed to create mutex"
#~ msgstr "Wúfǎ chuàngjiàn hù chì suǒ"
+#~ msgid "Failed to discover services"
+#~ msgstr "Fāxiàn fúwù shībài"
+
+#~ msgid "Failed to get local address"
+#~ msgstr "Huòqǔ běndì dìzhǐ shībài"
+
+#~ msgid "Failed to get softdevice state"
+#~ msgstr "Wúfǎ huòdé ruǎnjiàn shèbèi zhuàngtài"
+
+#~ msgid "Failed to notify or indicate attribute value, err 0x%04x"
+#~ msgstr "Wúfǎ tōngzhī huò xiǎnshì shǔxìng zhí, err 0x%04x"
+
+#~ msgid "Failed to pair"
+#~ msgstr "Pèiduì shībài"
+
+#~ msgid "Failed to read CCCD value, err 0x%04x"
+#~ msgstr "Dòu qǔ CCCD zhí, err 0x%04x shībài"
+
+#~ msgid "Failed to read attribute value, err 0x%04x"
+#~ msgstr "Dòu qǔ shǔxìng zhí shībài, err 0x%04x"
+
+#~ msgid "Failed to read gatts value, err 0x%04x"
+#~ 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"
+
#~ msgid "Failed to release mutex"
#~ msgstr "Wúfǎ shìfàng mutex"
+#~ msgid "Failed to set device name, err 0x%04x"
+#~ msgstr "Wúfǎ shèzhì shèbèi míngchēng, cuòwù 0x%04x"
+
#~ msgid "Failed to start advertising"
#~ msgstr "Qǐdòng guǎnggào shībài"
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ msgstr "Qǐdòng guǎnggào shībài, err 0x%04x"
+
+#~ msgid "Failed to start connecting, error 0x%04x"
+#~ msgstr "Wúfǎ kāishǐ liánjiē, cuòwù 0x%04x"
+
+#~ msgid "Failed to start pairing, error 0x%04x"
+#~ msgstr "Wúfǎ kāishǐ pèiduì, cuòwù 0x%04x"
+
#~ msgid "Failed to start scanning"
#~ msgstr "Qǐdòng sǎomiáo shībài"
+#~ msgid "Failed to start scanning, err 0x%04x"
+#~ msgstr "Qǐdòng sǎomiáo shībài, err 0x%04x"
+
#~ msgid "Failed to stop advertising"
#~ msgstr "Wúfǎ tíngzhǐ guǎnggào"
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "Wúfǎ tíngzhǐ guǎnggào, err 0x%04x"
+
+#~ msgid "Failed to write CCCD, err 0x%04x"
+#~ msgstr "Wúfǎ xiě rù CCCD, cuòwù 0x%04x"
+
+#~ msgid "Failed to write attribute value, err 0x%04x"
+#~ msgstr "Xiě rù shǔxìng zhí shībài, err 0x%04x"
+
+#~ msgid "Failed to write gatts value, err 0x%04x"
+#~ msgstr "Xiě rù gatts zhí,err 0x%04x shībài"
+
#~ msgid "Invalid bit clock pin"
#~ msgstr "Wúxiào de wèi shízhōng yǐn jiǎo"
@@ -2819,6 +2814,9 @@ msgstr "líng bù"
#~ msgstr ""
#~ "Jǐn zhīchí dān sè, suǒyǐn 8bpp hé 16bpp huò gèng dà de BMP: %d bpp tígōng"
+#~ msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
+#~ msgstr "Ruǎn shèbèi wéihù, id: 0X%08lX, pc: 0X%08lX"
+
#~ msgid "Tile indices must be 0 - 255"
#~ msgstr "Píng pū zhǐshù bìxū wèi 0 - 255"
@@ -2840,6 +2838,9 @@ msgstr "líng bù"
#~ 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 "name must be a string"
+#~ msgstr "míngchēng bìxū shì yīgè zìfú chuàn"
+
#~ msgid "row must be packed and word aligned"
#~ msgstr "xíng bìxū dǎbāo bìngqiě zì duìqí"
@@ -2849,6 +2850,12 @@ msgstr "líng bù"
#~ msgid "tile index out of bounds"
#~ msgstr "kuài suǒyǐn chāochū fànwéi"
+#~ msgid "time.struct_time() takes exactly 1 argument"
+#~ msgstr "time.struct_time() xūyào wánquán 1 cānshù"
+
+#~ msgid "timeout >100 (units are now seconds, not msecs)"
+#~ msgstr "chāoshí >100 (dānwèi shì miǎo, ér bùshì háomiǎo)"
+
#~ msgid "too many arguments"
#~ msgstr "tài duō cānshù"
diff --git a/main.c b/main.c
index 4683bcf00..8796032cd 100755
--- a/main.c
+++ b/main.c
@@ -69,6 +69,11 @@
#include "shared-module/board/__init__.h"
#endif
+#if CIRCUITPY_BLEIO
+#include "shared-bindings/_bleio/__init__.h"
+#include "supervisor/shared/bluetooth.h"
+#endif
+
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
if (lex == NULL) {
@@ -439,6 +444,10 @@ int __attribute__((used)) main(void) {
// Start serial and HID after giving boot.py a chance to tweak behavior.
serial_init();
+ #if CIRCUITPY_BLEIO
+ supervisor_start_bluetooth();
+ #endif
+
// Boot script is finished, so now go into REPL/main mode.
int exit_code = PYEXEC_FORCED_EXIT;
bool skip_repl = true;
@@ -475,9 +484,13 @@ void gc_collect(void) {
displayio_gc_collect();
#endif
+ #if CIRCUITPY_BLEIO
+ common_hal_bleio_gc_collect();
+ #endif
+
// This naively collects all object references from an approximate stack
// range.
- gc_collect_root((void**)sp, ((uint32_t)&_estack - sp) / sizeof(uint32_t));
+ gc_collect_root((void**)sp, ((uint32_t)port_stack_get_top() - sp) / sizeof(uint32_t));
gc_collect_end();
}
diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile
index 16aed1615..32517c801 100644
--- a/ports/atmel-samd/Makefile
+++ b/ports/atmel-samd/Makefile
@@ -122,7 +122,16 @@ else
ifdef CFLAGS_INLINE_LIMIT
CFLAGS += -finline-limit=$(CFLAGS_INLINE_LIMIT)
endif
+
CFLAGS += -flto -flto-partition=none
+
+ ifeq ($(CIRCUITPY_SMALL_BUILD),1)
+ CFLAGS += --param inline-unit-growth=15 --param max-inline-insns-auto=20
+ endif
+
+ ifdef CFLAGS_BOARD
+ CFLAGS += $(CFLAGS_BOARD)
+ endif
endif
CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT)
diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c
index 386ba0715..ca91a31de 100644
--- a/ports/atmel-samd/background.c
+++ b/ports/atmel-samd/background.c
@@ -28,6 +28,7 @@
#include "audio_dma.h"
#include "tick.h"
#include "supervisor/filesystem.h"
+#include "supervisor/shared/tick.h"
#include "supervisor/usb.h"
#include "py/runtime.h"
@@ -44,6 +45,23 @@ bool stack_ok_so_far = true;
static bool running_background_tasks = false;
+#ifdef MONITOR_BACKGROUND_TASKS
+// PB03 is physical pin "SCL" on the Metro M4 express
+// so you can't use this code AND an i2c peripheral
+// at the same time unless you change this
+STATIC void start_background_task(void) {
+ REG_PORT_DIRSET1 = (1<<3);
+ REG_PORT_OUTSET1 = (1<<3);
+}
+
+STATIC void finish_background_task(void) {
+ REG_PORT_OUTCLR1 = (1<<3);
+}
+#else
+STATIC void start_background_task(void) {}
+STATIC void finish_background_task(void) {}
+#endif
+
void background_tasks_reset(void) {
running_background_tasks = false;
}
@@ -53,6 +71,9 @@ void run_background_tasks(void) {
if (running_background_tasks) {
return;
}
+
+ start_background_task();
+
assert_heap_ok();
running_background_tasks = true;
@@ -71,9 +92,10 @@ void run_background_tasks(void) {
running_background_tasks = false;
assert_heap_ok();
- last_finished_tick = ticks_ms;
+ last_finished_tick = supervisor_ticks_ms64();
+ finish_background_task();
}
bool background_tasks_ok(void) {
- return ticks_ms - last_finished_tick < 1000;
+ return supervisor_ticks_ms64() - last_finished_tick < 1000;
}
diff --git a/ports/atmel-samd/boards/common.template.ld b/ports/atmel-samd/boards/common.template.ld
index aebda87c2..4c537e001 100644
--- a/ports/atmel-samd/boards/common.template.ld
+++ b/ports/atmel-samd/boards/common.template.ld
@@ -3,7 +3,13 @@
/* Specify the memory areas */
MEMORY
{
- FLASH (rx) : ORIGIN = 0x00000000 + ${BOOTLOADER_SIZE}, LENGTH = ${CIRCUITPY_FIRMWARE_SIZE}
+ FLASH_BOOTLOADER (rx): ORIGIN = ${BOOTLOADER_START_ADDR}, LENGTH = ${BOOTLOADER_SIZE}
+
+ FLASH_FIRMWARE (rx) : ORIGIN = ${CIRCUITPY_FIRMWARE_START_ADDR}, LENGTH = ${CIRCUITPY_FIRMWARE_SIZE}
+ FLASH_NVM (r) : ORIGIN = ${CIRCUITPY_INTERNAL_NVM_START_ADDR}, LENGTH = ${CIRCUITPY_INTERNAL_NVM_SIZE}
+ FLASH_CONFIG (r) : ORIGIN = ${CIRCUITPY_INTERNAL_CONFIG_START_ADDR}, LENGTH = ${CIRCUITPY_INTERNAL_CONFIG_SIZE}
+ FLASH_FILESYSTEM (r) : ORIGIN = ${CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR}, LENGTH = ${CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE}
+
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = ${RAM_SIZE}
}
@@ -27,7 +33,7 @@ SECTIONS
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
- } >FLASH
+ } >FLASH_FIRMWARE
.ARM.exidx :
{
@@ -35,12 +41,12 @@ SECTIONS
*(.gnu.linkonce.armexidx.*)
_etext = .; /* define a global symbol at end of code */
_sidata = .; /* start of .data section */
- } > FLASH
+ } >FLASH_FIRMWARE
/* This is the initialized data section
The program executes knowing that the data is in the RAM
- but the loader puts the initial values in the FLASH (inidata).
- It is one task of the startup to copy the initial values from FLASH to RAM. */
+ but the loader puts the initial values in the FLASH_FIRMWARE (inidata).
+ It is one task of the startup to copy the initial values from FLASH_FIRMWARE to RAM. */
.data : AT ( _sidata )
{
. = ALIGN(4);
diff --git a/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk b/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk
index 25ec50162..6eb76c182 100644
--- a/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk
@@ -10,6 +10,5 @@ QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "W25Q128JV_PM"
-CIRCUITPY_PS2IO = 1
# No I2S on SAMD51G.
CIRCUITPY_AUDIOBUSIO = 0
diff --git a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk
index b2823e30c..b1dad30eb 100644
--- a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk
@@ -10,7 +10,3 @@ QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 3
EXTERNAL_FLASH_DEVICES = "GD25Q16C, W25Q16JV_IQ, W25Q16JV_IM"
LONGINT_IMPL = MPZ
-
-CIRCUITPY_NETWORK = 1
-MICROPY_PY_WIZNET5K = 5500
-CIRCUITPY_PS2IO = 1
diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk
index d736941df..38dd47758 100644
--- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk
@@ -10,7 +10,3 @@ QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = GD25Q16C
LONGINT_IMPL = MPZ
-
-CIRCUITPY_NETWORK = 1
-MICROPY_PY_WIZNET5K = 5500
-CIRCUITPY_PS2IO = 1
diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk
index 49331a705..ab81ec5a2 100644
--- a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk
@@ -10,5 +10,3 @@ QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C"
LONGINT_IMPL = MPZ
-
-CIRCUITPY_PS2IO = 1
diff --git a/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk
index 9379ed3fe..4bf155288 100644
--- a/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk
@@ -10,7 +10,3 @@ QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = GD25Q64C
LONGINT_IMPL = MPZ
-
-CIRCUITPY_NETWORK = 1
-MICROPY_PY_WIZNET5K = 5500
-CIRCUITPY_PS2IO = 1
diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk
index 7ce45d0a1..eb02d3c27 100644
--- a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk
@@ -11,7 +11,6 @@ EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = GD25Q16C
LONGINT_IMPL = MPZ
-CIRCUITPY_PS2IO = 1
# No I2S on SAMD51G
CIRCUITPY_AUDIOBUSIO = 0
diff --git a/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk
index 6d6571a2a..d9e81988c 100644
--- a/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk
@@ -13,3 +13,5 @@ LONGINT_IMPL = MPZ
# Not needed.
CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_DISPLAYIO = 0
+CIRCUITPY_NETWORK = 0
+CIRCUITPY_PS2IO = 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 78e27b422..4895cda77 100644
--- a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk
@@ -10,7 +10,3 @@ QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 3
EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C"
LONGINT_IMPL = MPZ
-
-CIRCUITPY_NETWORK = 1
-MICROPY_PY_WIZNET5K = 5500
-CIRCUITPY_PS2IO = 1
diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk
index 4f01f3edd..62e6b7c72 100644
--- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk
@@ -10,7 +10,3 @@ QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 3
EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C"
LONGINT_IMPL = MPZ
-
-CIRCUITPY_NETWORK = 1
-MICROPY_PY_WIZNET5K = 5500
-CIRCUITPY_PS2IO = 1
diff --git a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk
index eedfd2ecc..ae2a1e973 100644
--- a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk
@@ -11,7 +11,6 @@ EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "W25Q16JV_IM"
LONGINT_IMPL = MPZ
-CIRCUITPY_PS2IO = 1
# No I2S on SAMD51G
CIRCUITPY_AUDIOBUSIO = 0
diff --git a/ports/atmel-samd/boards/monster_m4sk/mpconfigboard.mk b/ports/atmel-samd/boards/monster_m4sk/mpconfigboard.mk
index e61f3d240..9b242a3ff 100644
--- a/ports/atmel-samd/boards/monster_m4sk/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/monster_m4sk/mpconfigboard.mk
@@ -10,6 +10,3 @@ QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = GD25Q64C
LONGINT_IMPL = MPZ
-
-CIRCUITPY_AUDIOIO = 1
-CIRCUITPY_DISPLAYIO = 1
diff --git a/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk b/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk
index c9aa26e3c..b3271d062 100644
--- a/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk
@@ -22,3 +22,5 @@ CIRCUITPY_USB_MIDI = 0
SUPEROPT_GC = 0
FROZEN_MPY_DIRS += $(TOP)/frozen/pew-pewpew-standalone-10.x
+
+CFLAGS_BOARD = --param max-inline-insns-auto=15
diff --git a/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk b/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk
index af7e3fb16..990b26ff3 100644
--- a/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk
@@ -16,7 +16,9 @@ CIRCUITPY_BITBANGIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CSLAVE = 0
CIRCUITPY_NEOPIXEL_WRITE = 0
+CIRCUITPY_NETWORK = 0
CIRCUITPY_PIXELBUF = 0
+CIRCUITPY_PS2IO = 0
CIRCUITPY_RTC = 0
CIRCUITPY_TOUCHIO = 0
CIRCUITPY_USB_HID = 0
diff --git a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk
index c5b2c9eb5..e6c227b13 100644
--- a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk
@@ -25,6 +25,8 @@ CIRCUITPY_SMALL_BUILD = 1
SUPEROPT_GC = 0
# Include these Python libraries in firmware.
-FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar
+# FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_IRRemote
+
+CFLAGS_BOARD = --param max-inline-insns-auto=12
diff --git a/ports/atmel-samd/boards/pybadge/mpconfigboard.mk b/ports/atmel-samd/boards/pybadge/mpconfigboard.mk
index 05df09627..7a213faf4 100644
--- a/ports/atmel-samd/boards/pybadge/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pybadge/mpconfigboard.mk
@@ -11,8 +11,6 @@ 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
diff --git a/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.mk b/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.mk
index 242722870..5ae09294d 100644
--- a/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.mk
@@ -11,8 +11,6 @@ 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
diff --git a/ports/atmel-samd/boards/pygamer/mpconfigboard.mk b/ports/atmel-samd/boards/pygamer/mpconfigboard.mk
index 70109e332..2db6786bf 100644
--- a/ports/atmel-samd/boards/pygamer/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pygamer/mpconfigboard.mk
@@ -11,8 +11,6 @@ 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
diff --git a/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.mk b/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.mk
index 7f3207ecd..d001374a5 100644
--- a/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.mk
@@ -11,8 +11,6 @@ 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
diff --git a/ports/atmel-samd/boards/pyportal_titano/board.c b/ports/atmel-samd/boards/pyportal_titano/board.c
index a18bb380b..828ceebc4 100644
--- a/ports/atmel-samd/boards/pyportal_titano/board.c
+++ b/ports/atmel-samd/boards/pyportal_titano/board.c
@@ -74,24 +74,21 @@ uint8_t display_init_sequence[] = {
0x11, 0x1d, 0x23, 0x35, 0x41, 0x4b, 0x4b, 0x42, 0x3A,
0x27, 0x1B, 0x08, 0x09, 0x03, 0x00, 0x01,
0x3a, 1, 0x55,
- 0x36, 1, 0x00,
+ 0x36, 1, 0x60,
0x11, DELAY, 150/5, // Exit Sleep, then delay 150 ms
0x29, DELAY, 50/5
};
void board_init(void) {
- busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus;
- common_hal_busio_spi_construct(spi, &pin_PA13, &pin_PA12, &pin_PA14);
- common_hal_busio_spi_never_reset(spi);
-
- displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
- bus->base.type = &displayio_fourwire_type;
- common_hal_displayio_fourwire_construct(bus,
- spi,
- &pin_PB05, // TFT_DC Command or data
- &pin_PB06, // TFT_CS Chip select
- &pin_PA00, // TFT_RST Reset
- 24000000);
+ displayio_parallelbus_obj_t* bus = &displays[0].parallel_bus;
+ bus->base.type = &displayio_parallelbus_type;
+ common_hal_displayio_parallelbus_construct(bus,
+ &pin_PA16, // Data0
+ &pin_PB05, // Command or data
+ &pin_PB06, // Chip select
+ &pin_PB09, // Write
+ &pin_PB04, // Read
+ &pin_PA00); // Reset
displayio_display_obj_t* display = &displays[0].display;
display->base.type = &displayio_display_type;
@@ -101,7 +98,7 @@ void board_init(void) {
320, // Height
0, // column start
0, // row start
- 270, // rotation
+ 0, // rotation
16, // Color depth
false, // grayscale
false, // pixels_in_byte_share_row (unused for depths > 8)
diff --git a/ports/atmel-samd/boards/pyportal_titano/mpconfigboard.h b/ports/atmel-samd/boards/pyportal_titano/mpconfigboard.h
index c463b5661..4d58b8183 100644
--- a/ports/atmel-samd/boards/pyportal_titano/mpconfigboard.h
+++ b/ports/atmel-samd/boards/pyportal_titano/mpconfigboard.h
@@ -3,7 +3,6 @@
#define CIRCUITPY_MCU_FAMILY samd51
-
#define MICROPY_HW_LED_STATUS (&pin_PA27)
#define MICROPY_HW_NEOPIXEL (&pin_PB22)
diff --git a/ports/atmel-samd/boards/pyportal_titano/pins.c b/ports/atmel-samd/boards/pyportal_titano/pins.c
index 6bc0a504a..14699a209 100644
--- a/ports/atmel-samd/boards/pyportal_titano/pins.c
+++ b/ports/atmel-samd/boards/pyportal_titano/pins.c
@@ -80,15 +80,6 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
- // TFT control pins
- {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_LITE), MP_ROM_PTR(&pin_PB31)},
- {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_PA12)},
- {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_SCK), MP_ROM_PTR(&pin_PA13)},
- {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_MISO), MP_ROM_PTR(&pin_PA14)},
- {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RST), MP_ROM_PTR(&pin_PA00)},
- {MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_PB06)},
- {MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_PB05)},
-
{ MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) },
};
MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/pyruler/mpconfigboard.mk b/ports/atmel-samd/boards/pyruler/mpconfigboard.mk
index 220e48872..ca7ed4bdc 100644
--- a/ports/atmel-samd/boards/pyruler/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pyruler/mpconfigboard.mk
@@ -11,3 +11,8 @@ LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
SUPEROPT_GC = 0
+
+CFLAGS_BOARD = --param max-inline-insns-auto=15
+ifeq ($(TRANSLATION), zh_Latn_pinyin)
+CFLAGS_INLINE_LIMIT = 35
+endif \ No newline at end of file
diff --git a/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.h b/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.h
deleted file mode 100644
index 68991f997..000000000
--- a/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#define MICROPY_HW_BOARD_NAME "Robo HAT MM1 M0"
-#define MICROPY_HW_MCU_NAME "samd21g18"
-
-#define MICROPY_HW_LED_STATUS (&pin_PB22)
-
-// Salae reads 12mhz which is the limit even though we set it to the safer 8mhz.
-#define SPI_FLASH_BAUDRATE (8000000)
-
-// On-board flash
-#define SPI_FLASH_MOSI_PIN &pin_PA12
-#define SPI_FLASH_MISO_PIN &pin_PA14
-#define SPI_FLASH_SCK_PIN &pin_PA13
-#define SPI_FLASH_CS_PIN &pin_PA15
-
-// These are pins not to reset.
-#define MICROPY_PORT_A ( 0 ) //PORT_PA06
-#define MICROPY_PORT_B ( 0 )
-#define MICROPY_PORT_C ( 0 )
-
-#define CALIBRATE_CRYSTALLESS 1
-
-#define DEFAULT_I2C_BUS_SCL (&pin_PA23)
-#define DEFAULT_I2C_BUS_SDA (&pin_PA22)
-
-#define DEFAULT_SPI_BUS_SCK (&pin_PB09)
-#define DEFAULT_SPI_BUS_MOSI (&pin_PB08)
-#define DEFAULT_SPI_BUS_MISO (&pin_PB11)
-
-//#define DEFAULT_UART_BUS_RX (&pin_PB03)
-//#define DEFAULT_UART_BUS_TX (&pin_PB02)
-
-// USB is always used internally so skip the pin objects for it.
-#define IGNORE_PIN_PA24 1
-#define IGNORE_PIN_PA25 1
diff --git a/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.mk b/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.mk
deleted file mode 100644
index 29cca569e..000000000
--- a/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-USB_VID = 0x1209
-USB_PID = 0x4D43
-USB_PRODUCT = "Robo HAT MM1 M0"
-USB_MANUFACTURER = "Robotics Masters"
-
-CHIP_VARIANT = SAMD21G18A
-CHIP_FAMILY = samd21
-
-SPI_FLASH_FILESYSTEM = 1
-EXTERNAL_FLASH_DEVICE_COUNT = 1
-EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ"
-LONGINT_IMPL = MPZ
-
-# Non-Flash Edition
-#INTERNAL_FLASH_FILESYSTEM = 1
-#LONGINT_IMPL = NONE
-
-CIRCUITPY_DISPLAYIO = 0
-CIRCUITPY_FREQUENCYIO = 0
-
-CFLAGS_INLINE_LIMIT = 60
-SUPEROPT_GC = 0
-
-# Include these Python libraries in firmware.
-#FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
-FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
-#FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_INA219
-#FROZEN_MPY_DIRS += $(TOP)/frozen/RoboticsMasters_CircuitPython_MPU9250
diff --git a/ports/atmel-samd/boards/robohatmm1_m0/pins.c b/ports/atmel-samd/boards/robohatmm1_m0/pins.c
deleted file mode 100644
index edaf0bc4c..000000000
--- a/ports/atmel-samd/boards/robohatmm1_m0/pins.c
+++ /dev/null
@@ -1,92 +0,0 @@
-#include "shared-bindings/board/__init__.h"
-// Version 2.4
-STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
- // SERVO Pins
- { MP_ROM_QSTR(MP_QSTR_SERVO1), MP_ROM_PTR(&pin_PA18) },
- { MP_ROM_QSTR(MP_QSTR_SERVO2), MP_ROM_PTR(&pin_PA19) },
- { MP_ROM_QSTR(MP_QSTR_SERVO3), MP_ROM_PTR(&pin_PA20) },
- { MP_ROM_QSTR(MP_QSTR_SERVO4), MP_ROM_PTR(&pin_PA21) },
- { MP_ROM_QSTR(MP_QSTR_SERVO5), MP_ROM_PTR(&pin_PA11) },
- { MP_ROM_QSTR(MP_QSTR_SERVO6), MP_ROM_PTR(&pin_PA10) },
- { MP_ROM_QSTR(MP_QSTR_SERVO7), MP_ROM_PTR(&pin_PA09) },
- { MP_ROM_QSTR(MP_QSTR_SERVO8), MP_ROM_PTR(&pin_PA08) },
-
- // RCC Pins
- { MP_ROM_QSTR(MP_QSTR_RCC1), MP_ROM_PTR(&pin_PA07) },
- { MP_ROM_QSTR(MP_QSTR_RCC2), MP_ROM_PTR(&pin_PA06) },
- { MP_ROM_QSTR(MP_QSTR_RCC3), MP_ROM_PTR(&pin_PA05) },
- { MP_ROM_QSTR(MP_QSTR_RCC4), MP_ROM_PTR(&pin_PA04) },
-
- // Special Function
- { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA02) },
- { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA02) },
- { MP_ROM_QSTR(MP_QSTR_POWER_OFF), MP_ROM_PTR(&pin_PA03) },
- { MP_ROM_QSTR(MP_QSTR_POWER_DISABLE), MP_ROM_PTR(&pin_PA03) },
- { MP_ROM_QSTR(MP_QSTR_POWER_ON), MP_ROM_PTR(&pin_PA27) },
- { MP_ROM_QSTR(MP_QSTR_POWER_ENABLE), MP_ROM_PTR(&pin_PA27) },
- { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_PA27) },
-
- { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB23) },
- { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB22) },
- { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB02) },
- { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB03) },
-
- // GROVE on SERCOM0
- { MP_ROM_QSTR(MP_QSTR_GROVE_SCL), MP_ROM_PTR(&pin_PA09) },
- { MP_ROM_QSTR(MP_QSTR_GROVE_SDA), MP_ROM_PTR(&pin_PA08) },
- { MP_ROM_QSTR(MP_QSTR_GROVE_RX), MP_ROM_PTR(&pin_PA09) },
- { MP_ROM_QSTR(MP_QSTR_GROVE_TX), MP_ROM_PTR(&pin_PA08) },
- { MP_ROM_QSTR(MP_QSTR_GROVE_D1), MP_ROM_PTR(&pin_PA09) },
- { MP_ROM_QSTR(MP_QSTR_GROVE_D0), MP_ROM_PTR(&pin_PA08) },
- { MP_ROM_QSTR(MP_QSTR_GROVE_A1), MP_ROM_PTR(&pin_PA09) },
- { MP_ROM_QSTR(MP_QSTR_GROVE_A0), MP_ROM_PTR(&pin_PA08) },
-
- // UART on SERCOM0
- { MP_ROM_QSTR(MP_QSTR_UART_TX), MP_ROM_PTR(&pin_PA04) },
- { MP_ROM_QSTR(MP_QSTR_UART_RX), MP_ROM_PTR(&pin_PA05) },
- { MP_ROM_QSTR(MP_QSTR_UART_CTS), MP_ROM_PTR(&pin_PA06) },
- { MP_ROM_QSTR(MP_QSTR_UART_RTS), MP_ROM_PTR(&pin_PA07) },
-
- // UART on SERCOM1 (Raspberry Pi)
- { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_PA16) },
- { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_PA17) },
- { MP_ROM_QSTR(MP_QSTR_PI_RX), MP_ROM_PTR(&pin_PA16) },
- { MP_ROM_QSTR(MP_QSTR_PI_TX), MP_ROM_PTR(&pin_PA17) },
-
- // I2C on SERCOM1 (External Connector)
- { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_PA00) },
- { MP_ROM_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_PA01) },
-
- // SPI Flash on SERCOM2
- { MP_ROM_QSTR(MP_QSTR_FLASH_SCK), MP_ROM_PTR(&pin_PA13) },
- { MP_ROM_QSTR(MP_QSTR_FLASH_MISO), MP_ROM_PTR(&pin_PA14) },
- { MP_ROM_QSTR(MP_QSTR_FLASH_MOSI), MP_ROM_PTR(&pin_PA12) },
- { MP_ROM_QSTR(MP_QSTR_FLASH_CS), MP_ROM_PTR(&pin_PA15) },
-
- // I2C on SERCOM3 (RPi & Internal)
- { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) },
- { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) },
- { MP_ROM_QSTR(MP_QSTR_PI_SDA), MP_ROM_PTR(&pin_PA22) },
- { MP_ROM_QSTR(MP_QSTR_PI_SCL), MP_ROM_PTR(&pin_PA23) },
-
- // SPI on SERCOM4
- { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB08) },
- { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB09) },
- { MP_ROM_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_PB10) },
- { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB11) },
-
- // GPS on SERCOM5
- { MP_ROM_QSTR(MP_QSTR_GPS_TX), MP_ROM_PTR(&pin_PB02) },
- { MP_ROM_QSTR(MP_QSTR_GPS_RX), MP_ROM_PTR(&pin_PB03) },
-
- // Raspberry Pi
- { MP_ROM_QSTR(MP_QSTR_PI_GP25), MP_ROM_PTR(&pin_PA30) },
- { MP_ROM_QSTR(MP_QSTR_SWCLK), MP_ROM_PTR(&pin_PA30) },
- { MP_ROM_QSTR(MP_QSTR_PI_GP24), MP_ROM_PTR(&pin_PA31) },
- { MP_ROM_QSTR(MP_QSTR_SWDIO), MP_ROM_PTR(&pin_PA31) },
-
- { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
- { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
- //{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
-};
-MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk b/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk
index b2ea18e5f..fd4f22230 100644
--- a/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk
@@ -13,7 +13,6 @@ EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ"
LONGINT_IMPL = MPZ
-CIRCUITPY_PS2IO = 1
# No I2S on SAMD51G
CIRCUITPY_AUDIOBUSIO = 0
# Make room for more stuff
diff --git a/ports/atmel-samd/boards/robohatmm1_m4/pins.c b/ports/atmel-samd/boards/robohatmm1_m4/pins.c
index edaf0bc4c..4fc290fb0 100644
--- a/ports/atmel-samd/boards/robohatmm1_m4/pins.c
+++ b/ports/atmel-samd/boards/robohatmm1_m4/pins.c
@@ -28,8 +28,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB23) },
{ MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB22) },
- { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB02) },
- { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB03) },
+
// GROVE on SERCOM0
{ MP_ROM_QSTR(MP_QSTR_GROVE_SCL), MP_ROM_PTR(&pin_PA09) },
@@ -50,8 +49,8 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
// UART on SERCOM1 (Raspberry Pi)
{ MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_PA16) },
{ MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_PA17) },
- { MP_ROM_QSTR(MP_QSTR_PI_RX), MP_ROM_PTR(&pin_PA16) },
- { MP_ROM_QSTR(MP_QSTR_PI_TX), MP_ROM_PTR(&pin_PA17) },
+ { MP_ROM_QSTR(MP_QSTR_PI_TX), MP_ROM_PTR(&pin_PA16) },
+ { MP_ROM_QSTR(MP_QSTR_PI_RX), MP_ROM_PTR(&pin_PA17) },
// I2C on SERCOM1 (External Connector)
{ MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_PA00) },
diff --git a/ports/stm32f4/boards/feather_f405/mpconfigboard.h b/ports/atmel-samd/boards/shirtty/board.c
index 908b35a71..d7e856d61 100644
--- a/ports/stm32f4/boards/feather_f405/mpconfigboard.h
+++ b/ports/atmel-samd/boards/shirtty/board.c
@@ -3,8 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
- * Copyright (c) 2018 Dan Halbert 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
@@ -25,16 +24,14 @@
* THE SOFTWARE.
*/
-//Micropython setup
+#include "boards/board.h"
-#define MICROPY_HW_BOARD_NAME "Feather F405"
-#define MICROPY_HW_MCU_NAME "STM32F405RG"
+void board_init(void) {
+}
-#define FLASH_SIZE (0x100000)
-#define FLASH_PAGE_SIZE (0x4000)
+bool board_requests_safe_mode(void) {
+ return false;
+}
-// On-board flash
-#define SPI_FLASH_MOSI_PIN &pin_PB05
-#define SPI_FLASH_MISO_PIN &pin_PB04
-#define SPI_FLASH_SCK_PIN &pin_PB03
-#define SPI_FLASH_CS_PIN &pin_PA15
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/shirtty/mpconfigboard.h b/ports/atmel-samd/boards/shirtty/mpconfigboard.h
new file mode 100644
index 000000000..796d23f86
--- /dev/null
+++ b/ports/atmel-samd/boards/shirtty/mpconfigboard.h
@@ -0,0 +1,63 @@
+#define MICROPY_HW_BOARD_NAME "@sarfata shIRtty"
+#define MICROPY_HW_MCU_NAME "samd21e18"
+
+#define MICROPY_HW_LED_STATUS (&pin_PA16)
+
+#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01)
+#define MICROPY_PORT_B (0)
+#define MICROPY_PORT_C (0)
+
+// #define IGNORE_PIN_PA00 1
+// #define IGNORE_PIN_PA01 1
+// #define IGNORE_PIN_PA02 1
+#define IGNORE_PIN_PA03 1
+#define IGNORE_PIN_PA04 1
+#define IGNORE_PIN_PA05 1
+#define IGNORE_PIN_PA11 1
+#define IGNORE_PIN_PA12 1
+#define IGNORE_PIN_PA13 1
+#define IGNORE_PIN_PA17 1
+#define IGNORE_PIN_PA18 1
+#define IGNORE_PIN_PA19 1
+#define IGNORE_PIN_PA20 1
+#define IGNORE_PIN_PA21 1
+#define IGNORE_PIN_PA22 1
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
+#define IGNORE_PIN_PA27 1
+#define IGNORE_PIN_PA28 1
+#define IGNORE_PIN_PA30 1
+#define IGNORE_PIN_PA31 1
+#define IGNORE_PIN_PB01 1
+#define IGNORE_PIN_PB02 1
+#define IGNORE_PIN_PB03 1
+#define IGNORE_PIN_PB04 1
+#define IGNORE_PIN_PB05 1
+#define IGNORE_PIN_PB06 1
+#define IGNORE_PIN_PB07 1
+#define IGNORE_PIN_PB08 1
+#define IGNORE_PIN_PB09 1
+#define IGNORE_PIN_PB10 1
+#define IGNORE_PIN_PB11 1
+#define IGNORE_PIN_PB12 1
+#define IGNORE_PIN_PB13 1
+#define IGNORE_PIN_PB14 1
+#define IGNORE_PIN_PB15 1
+#define IGNORE_PIN_PB16 1
+#define IGNORE_PIN_PB17 1
+#define IGNORE_PIN_PB22 1
+#define IGNORE_PIN_PB23 1
+#define IGNORE_PIN_PB30 1
+#define IGNORE_PIN_PB31 1
+#define IGNORE_PIN_PB00 1
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PA09)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA08)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PA07)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PA06)
+#define DEFAULT_SPI_BUS_MISO (&pin_PA09)
+
+#define DEFAULT_UART_BUS_RX (&pin_PA07)
+#define DEFAULT_UART_BUS_TX (&pin_PA06)
diff --git a/ports/atmel-samd/boards/shirtty/mpconfigboard.mk b/ports/atmel-samd/boards/shirtty/mpconfigboard.mk
new file mode 100644
index 000000000..bc37b5943
--- /dev/null
+++ b/ports/atmel-samd/boards/shirtty/mpconfigboard.mk
@@ -0,0 +1,15 @@
+USB_VID = 0x239A
+USB_PID = 0x806C
+USB_PRODUCT = "shIRtty"
+USB_MANUFACTURER = "@sarfata"
+
+CHIP_VARIANT = SAMD21E18A
+CHIP_FAMILY = samd21
+
+INTERNAL_FLASH_FILESYSTEM = 1
+LONGINT_IMPL = NONE
+CIRCUITPY_SMALL_BUILD = 1
+CIRCUITPY_I2CSLAVE = 1
+CIRCUITPY_TOUCHIO = 0
+
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/shirtty/pins.c b/ports/atmel-samd/boards/shirtty/pins.c
new file mode 100644
index 000000000..40e819234
--- /dev/null
+++ b/ports/atmel-samd/boards/shirtty/pins.c
@@ -0,0 +1,36 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_D0), 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_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_IR_RX), MP_ROM_PTR(&pin_PA10) },
+
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_A2), 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_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_D4), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA06) },
+
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA14) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA15) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA16) },
+
+ { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA23) },
+ { MP_ROM_QSTR(MP_QSTR_IR_TX), MP_ROM_PTR(&pin_PA23) },
+
+ { 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_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/robohatmm1_m0/board.c b/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/board.c
index c8e20206a..c8e20206a 100644
--- a/ports/atmel-samd/boards/robohatmm1_m0/board.c
+++ b/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/board.c
diff --git a/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/mpconfigboard.h b/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/mpconfigboard.h
new file mode 100644
index 000000000..dcce97b8d
--- /dev/null
+++ b/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/mpconfigboard.h
@@ -0,0 +1,34 @@
+#define MICROPY_HW_BOARD_NAME "SparkFun Qwiic Micro"
+#define MICROPY_HW_MCU_NAME "samd21e18"
+
+#define MICROPY_PORT_A ( 0 )
+#define MICROPY_PORT_B ( 0 )
+#define MICROPY_PORT_C ( 0 )
+
+#define CALIBRATE_CRYSTALLESS 1
+#define BOARD_HAS_CRYSTAL 0
+
+//I2C and Qwiic Connector
+#define DEFAULT_I2C_BUS_SCL (&pin_PA09)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA08)
+
+//SPI
+#define DEFAULT_SPI_BUS_SCK (&pin_PA07)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PA06)
+#define DEFAULT_SPI_BUS_MISO (&pin_PA05)
+
+//UART
+#define DEFAULT_UART_BUS_RX (&pin_PA23)
+#define DEFAULT_UART_BUS_TX (&pin_PA22)
+
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
+
+// Unused
+#define IGNORE_PIN_PA03 1
+#define IGNORE_PIN_PA11 1
+#define IGNORE_PIN_PA14 1
+#define IGNORE_PIN_PA15 1
+#define IGNORE_PIN_PA27 1
+#define IGNORE_PIN_PA28 1
diff --git a/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/mpconfigboard.mk
new file mode 100644
index 000000000..632cd095c
--- /dev/null
+++ b/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/mpconfigboard.mk
@@ -0,0 +1,13 @@
+USB_VID = 0x1B4F
+USB_PID = 0x8D24
+USB_PRODUCT = "SparkFun Qwiic Micro"
+USB_MANUFACTURER = "SparkFun Electronics"
+
+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/sparkfun_qwiic_micro_no_flash/pins.c b/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/pins.c
new file mode 100644
index 000000000..f9d755d93
--- /dev/null
+++ b/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/pins.c
@@ -0,0 +1,42 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA04) },
+
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA00) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA01) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_PA23) },
+
+ // External SPI
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+
+ // UART
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA23) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+
+ // I2C and Qwiic Connector
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }
+
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/board.c b/ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/board.c
new file mode 100644
index 000000000..c8e20206a
--- /dev/null
+++ b/ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/board.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+
+void board_init(void)
+{
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/mpconfigboard.h b/ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/mpconfigboard.h
new file mode 100644
index 000000000..c9b195eef
--- /dev/null
+++ b/ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/mpconfigboard.h
@@ -0,0 +1,42 @@
+#define MICROPY_HW_BOARD_NAME "SparkFun Qwiic Micro"
+#define MICROPY_HW_MCU_NAME "samd21e18"
+
+// Clock rates are off: Salae reads 12MHz which is the limit even though we set it to the safer 8MHz.
+#define SPI_FLASH_BAUDRATE (8000000)
+
+#define SPI_FLASH_MOSI_PIN &pin_PA16
+#define SPI_FLASH_MISO_PIN &pin_PA18
+#define SPI_FLASH_SCK_PIN &pin_PA17
+#define SPI_FLASH_CS_PIN &pin_PA19
+
+#define MICROPY_PORT_A ( 0 )
+#define MICROPY_PORT_B ( 0 )
+#define MICROPY_PORT_C ( 0 )
+
+#define CALIBRATE_CRYSTALLESS 1
+#define BOARD_HAS_CRYSTAL 0
+
+//I2C and Qwiic Connector
+#define DEFAULT_I2C_BUS_SCL (&pin_PA09)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA08)
+
+//SPI
+#define DEFAULT_SPI_BUS_SCK (&pin_PA07)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PA06)
+#define DEFAULT_SPI_BUS_MISO (&pin_PA05)
+
+//UART
+#define DEFAULT_UART_BUS_RX (&pin_PA23)
+#define DEFAULT_UART_BUS_TX (&pin_PA22)
+
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
+
+// Unused
+#define IGNORE_PIN_PA03 1
+#define IGNORE_PIN_PA11 1
+#define IGNORE_PIN_PA14 1
+#define IGNORE_PIN_PA15 1
+#define IGNORE_PIN_PA27 1
+#define IGNORE_PIN_PA28 1
diff --git a/ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/mpconfigboard.mk
new file mode 100644
index 000000000..ccf5a4149
--- /dev/null
+++ b/ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/mpconfigboard.mk
@@ -0,0 +1,15 @@
+USB_VID = 0x1B4F
+USB_PID = 0x8D24
+USB_PRODUCT = "SparkFun Qwiic Micro"
+USB_MANUFACTURER = "SparkFun Electronics"
+
+CHIP_VARIANT = SAMD21E18A
+CHIP_FAMILY = samd21
+
+SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "W25Q32FV"
+LONGINT_IMPL = MPZ
+
+CIRCUITPY_SMALL_BUILD = 1
+SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/pins.c b/ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/pins.c
new file mode 100644
index 000000000..f9d755d93
--- /dev/null
+++ b/ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/pins.c
@@ -0,0 +1,42 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA04) },
+
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA00) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA01) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA10) },
+ { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_PA23) },
+
+ // External SPI
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+
+ // UART
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA23) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+
+ // I2C and Qwiic Connector
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }
+
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/stringcar_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/stringcar_m0_express/mpconfigboard.mk
index 92129eb63..20feabd18 100644
--- a/ports/atmel-samd/boards/stringcar_m0_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/stringcar_m0_express/mpconfigboard.mk
@@ -2,6 +2,7 @@ USB_VID = 0x239A
USB_PID = 0x8060
USB_PRODUCT = "StringCar M0 Express"
USB_MANUFACTURER = "Cedar Grove Studios"
+USB_INTERFACE_NAME = "StringCarM0Ex"
CHIP_VARIANT = SAMD21E18A
CHIP_FAMILY = samd21
diff --git a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk
index 379520872..ee82b99c9 100644
--- a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk
@@ -11,7 +11,6 @@ EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C"
LONGINT_IMPL = MPZ
-CIRCUITPY_PS2IO = 1
# No I2S on SAMD51G
CIRCUITPY_AUDIOBUSIO = 0
diff --git a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk
index 0d41fa4bd..5c942901a 100644
--- a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk
@@ -1,4 +1,3 @@
-LD_TEMPLATE_FILE = boards/common.template.ld
USB_VID = 0x239A
USB_PID = 0x801F
USB_PRODUCT = "Trinket M0"
@@ -12,3 +11,8 @@ LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
SUPEROPT_GC = 0
+
+CFLAGS_BOARD = --param max-inline-insns-auto=15
+ifeq ($(TRANSLATION), zh_Latn_pinyin)
+CFLAGS_INLINE_LIMIT = 35
+endif
diff --git a/ports/atmel-samd/boards/winterbloom_sol/board.c b/ports/atmel-samd/boards/winterbloom_sol/board.c
new file mode 100644
index 000000000..8096b9b8e
--- /dev/null
+++ b/ports/atmel-samd/boards/winterbloom_sol/board.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "boards/board.h"
+#include "mpconfigboard.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.h b/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.h
new file mode 100644
index 000000000..86b1ad8a0
--- /dev/null
+++ b/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.h
@@ -0,0 +1,27 @@
+#define MICROPY_HW_BOARD_NAME "Winterbloom Sol"
+#define MICROPY_HW_MCU_NAME "samd51j20"
+
+#define CIRCUITPY_MCU_FAMILY samd51
+
+#define MICROPY_HW_LED_STATUS (&pin_PA23)
+#define MICROPY_HW_NEOPIXEL (&pin_PB03)
+
+// These are pins not to reset.
+// QSPI Data pins
+#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11)
+// QSPI CS, QSPI SCK and NeoPixel pin
+#define MICROPY_PORT_B (PORT_PB03 | PORT_PB10 | PORT_PB11)
+#define MICROPY_PORT_C (0)
+#define MICROPY_PORT_D (0)
+
+#define AUTORESET_DELAY_MS 500
+
+#define BOARD_HAS_CRYSTAL 1
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PA17)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PB23)
+#define DEFAULT_SPI_BUS_MISO (&pin_PB22)
+
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
diff --git a/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk b/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk
new file mode 100644
index 000000000..a0449d7bb
--- /dev/null
+++ b/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk
@@ -0,0 +1,30 @@
+# Adafruit
+USB_VID = 0x239A
+# Allocated for Winterbloom Sol
+# https://github.com/adafruit/circuitpython/issues/2217
+USB_PID = 0x8062
+USB_PRODUCT = "Sol"
+USB_MANUFACTURER = "Winterbloom"
+USB_INTERFACE_NAME = "Sol"
+
+CHIP_VARIANT = SAMD51J20A
+CHIP_FAMILY = samd51
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = W25Q32JV_IQ
+LONGINT_IMPL = MPZ
+
+# Disable modules that are unusable on this special-purpose board.
+CIRCUITPY_AUDIOBUSIO = 0
+CIRCUITPY_AUDIOIO = 0
+CIRCUITPY_BLEIO = 0
+CIRCUITPY_DISPLAYIO = 0
+CIRCUITPY_GAMEPAD = 0
+CIRCUITPY_I2CSLAVE = 0
+CIRCUITPY_NETWORK = 0
+CIRCUITPY_TOUCHIO = 0
+CIRCUITPY_PS2IO = 0
+
+# Enable micropython.native
+CIRCUITPY_ENABLE_MPY_NATIVE = 1
diff --git a/ports/atmel-samd/boards/winterbloom_sol/pins.c b/ports/atmel-samd/boards/winterbloom_sol/pins.c
new file mode 100644
index 000000000..013542d3c
--- /dev/null
+++ b/ports/atmel-samd/boards/winterbloom_sol/pins.c
@@ -0,0 +1,15 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB23) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB22) },
+ { MP_ROM_QSTR(MP_QSTR_DAC_CS), MP_ROM_PTR(&pin_PA18) },
+ { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_PA20) },
+ { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_PA21) },
+ { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_PA23) },
+ { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB03) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c
index cdc616bbc..b0e5714a7 100644
--- a/ports/atmel-samd/common-hal/busio/I2C.c
+++ b/ports/atmel-samd/common-hal/busio/I2C.c
@@ -116,6 +116,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
if (i2c_m_sync_set_baudrate(&self->i2c_desc, 0, frequency / 1000) != ERR_NONE) {
reset_pin_number(sda->number);
reset_pin_number(scl->number);
+ common_hal_busio_i2c_deinit(self);
mp_raise_ValueError(translate("Unsupported baudrate"));
}
diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c
index 2505e894a..4ad47a58d 100644
--- a/ports/atmel-samd/common-hal/busio/UART.c
+++ b/ports/atmel-samd/common-hal/busio/UART.c
@@ -34,8 +34,7 @@
#include "py/runtime.h"
#include "py/stream.h"
#include "supervisor/shared/translate.h"
-
-#include "tick.h"
+#include "supervisor/shared/tick.h"
#include "hpl_sercom_config.h"
#include "peripheral_clk_config.h"
@@ -272,10 +271,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
usart_async_get_io_descriptor(usart_desc_p, &io);
size_t total_read = 0;
- uint64_t start_ticks = ticks_ms;
+ uint64_t start_ticks = supervisor_ticks_ms64();
// Busy-wait until timeout or until we've read enough chars.
- while (ticks_ms - start_ticks <= self->timeout_ms) {
+ while (supervisor_ticks_ms64() - start_ticks <= self->timeout_ms) {
// Read as many chars as we can right now, up to len.
size_t num_read = io_read(io, data, len);
@@ -289,7 +288,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
}
if (num_read > 0) {
// Reset the timeout on every character read.
- start_ticks = ticks_ms;
+ start_ticks = supervisor_ticks_ms64();
}
RUN_BACKGROUND_TASKS;
// Allow user to break out of a timeout with a KeyboardInterrupt.
@@ -323,29 +322,23 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data,
struct io_descriptor *io;
usart_async_get_io_descriptor(usart_desc_p, &io);
+ // Start writing characters. This is non-blocking and will
+ // return immediately after setting up the write.
if (io_write(io, data, len) < 0) {
*errcode = MP_EAGAIN;
return MP_STREAM_ERROR;
}
- // Wait until write is complete or timeout.
- bool done = false;
- uint64_t start_ticks = ticks_ms;
- // Busy-wait for timeout.
- while (ticks_ms - start_ticks < self->timeout_ms) {
- if (usart_async_is_tx_empty(usart_desc_p)) {
- done = true;
+ // Busy-wait until all characters transmitted.
+ struct usart_async_status async_status;
+ while (true) {
+ usart_async_get_status(usart_desc_p, &async_status);
+ if (async_status.txcnt >= len) {
break;
}
RUN_BACKGROUND_TASKS;
}
- if (!done) {
- *errcode = MP_EAGAIN;
- return MP_STREAM_ERROR;
- }
-
- // All the characters got written.
return len;
}
@@ -368,6 +361,14 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat
self->baudrate = baudrate;
}
+mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) {
+ return (mp_float_t) (self->timeout_ms / 1000.0f);
+}
+
+void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) {
+ self->timeout_ms = timeout * 1000;
+}
+
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
// This assignment is only here because the usart_async routines take a *const argument.
struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
@@ -383,12 +384,14 @@ void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
}
+// True if there are no characters still to be written.
bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) {
if (self->tx_pin == NO_PIN) {
return false;
}
// This assignment is only here because the usart_async routines take a *const argument.
- const struct _usart_async_device * const usart_device_p =
- (struct _usart_async_device * const) &self->usart_desc.device;
- return _usart_async_is_byte_sent(usart_device_p);
+ struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
+ struct usart_async_status async_status;
+ usart_async_get_status(usart_desc_p, &async_status);
+ return !(async_status.flags & USART_ASYNC_STATUS_BUSY);
}
diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c
index 6f3cbc759..9719ea5b1 100644
--- a/ports/atmel-samd/common-hal/microcontroller/Pin.c
+++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c
@@ -158,6 +158,14 @@ void reset_pin_number(uint8_t pin_number) {
#endif
}
+void common_hal_never_reset_pin(const mcu_pin_obj_t* pin) {
+ never_reset_pin_number(pin->number);
+}
+
+void common_hal_reset_pin(const mcu_pin_obj_t* pin) {
+ reset_pin_number(pin->number);
+}
+
void claim_pin(const mcu_pin_obj_t* pin) {
#ifdef MICROPY_HW_NEOPIXEL
if (pin == MICROPY_HW_NEOPIXEL) {
diff --git a/ports/atmel-samd/common-hal/microcontroller/__init__.c b/ports/atmel-samd/common-hal/microcontroller/__init__.c
index 41dee2b49..09212a0d1 100644
--- a/ports/atmel-samd/common-hal/microcontroller/__init__.c
+++ b/ports/atmel-samd/common-hal/microcontroller/__init__.c
@@ -99,7 +99,7 @@ const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = {
.type = &nvm_bytearray_type,
},
.len = CIRCUITPY_INTERNAL_NVM_SIZE,
- .start_address = (uint8_t*) (FLASH_SIZE - CIRCUITPY_INTERNAL_NVM_SIZE)
+ .start_address = (uint8_t*) (CIRCUITPY_INTERNAL_NVM_START_ADDR)
};
#endif
diff --git a/ports/atmel-samd/common-hal/pulseio/PWMOut.c b/ports/atmel-samd/common-hal/pulseio/PWMOut.c
index 6dcace21f..0adb23fc5 100644
--- a/ports/atmel-samd/common-hal/pulseio/PWMOut.c
+++ b/ports/atmel-samd/common-hal/pulseio/PWMOut.c
@@ -135,6 +135,7 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
bool variable_frequency) {
self->pin = pin;
self->variable_frequency = variable_frequency;
+ self->duty_cycle = duty;
if (pin->timer[0].index >= TC_INST_NUM &&
pin->timer[1].index >= TCC_INST_NUM
@@ -322,6 +323,13 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) {
}
extern void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty) {
+ // Store the unadjusted duty cycle. It turns out the the process of adjusting and calculating
+ // the duty cycle here and reading it back is lossy - the value will decay over time.
+ // Track it here so that if frequency is changed we can use this value to recalculate the
+ // proper duty cycle.
+ // See https://github.com/adafruit/circuitpython/issues/2086 for more details
+ self->duty_cycle = duty;
+
const pin_timer_t* t = self->timer;
if (t->is_tc) {
uint16_t adjusted_duty = tc_periods[t->index] * duty / 0xffff;
@@ -415,7 +423,6 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self,
break;
}
}
- uint16_t old_duty = common_hal_pulseio_pwmout_get_duty_cycle(self);
if (t->is_tc) {
Tc* tc = tc_insts[t->index];
uint8_t old_divisor = tc->COUNT16.CTRLA.bit.PRESCALER;
@@ -450,7 +457,7 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self,
#endif
}
- common_hal_pulseio_pwmout_set_duty_cycle(self, old_duty);
+ common_hal_pulseio_pwmout_set_duty_cycle(self, self->duty_cycle);
}
uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self) {
diff --git a/ports/atmel-samd/common-hal/pulseio/PWMOut.h b/ports/atmel-samd/common-hal/pulseio/PWMOut.h
index eef653bcb..09abda819 100644
--- a/ports/atmel-samd/common-hal/pulseio/PWMOut.h
+++ b/ports/atmel-samd/common-hal/pulseio/PWMOut.h
@@ -36,6 +36,7 @@ typedef struct {
const mcu_pin_obj_t *pin;
const pin_timer_t* timer;
bool variable_frequency;
+ uint16_t duty_cycle;
} pulseio_pwmout_obj_t;
void pwmout_reset(void);
diff --git a/ports/atmel-samd/common-hal/time/__init__.c b/ports/atmel-samd/common-hal/time/__init__.c
index 0d60adef2..2d82b3d1a 100644
--- a/ports/atmel-samd/common-hal/time/__init__.c
+++ b/ports/atmel-samd/common-hal/time/__init__.c
@@ -28,10 +28,10 @@
#include "shared-bindings/time/__init__.h"
-#include "tick.h"
+#include "supervisor/shared/tick.h"
inline uint64_t common_hal_time_monotonic() {
- return ticks_ms;
+ return supervisor_ticks_ms64();
}
void common_hal_time_delay_ms(uint32_t delay) {
diff --git a/ports/atmel-samd/ld_defines.c b/ports/atmel-samd/ld_defines.c
index d8a7a209b..18f49d42c 100644
--- a/ports/atmel-samd/ld_defines.c
+++ b/ports/atmel-samd/ld_defines.c
@@ -2,12 +2,29 @@
#include "mpconfigport.h"
// For each value needed in the LD file, create a C-like line:
-// NAME_OF_VALUE; ///DEFINE_VALUE NAME_OF_VALUE <optional Python lambda expression to transform value>
+// /*NAME_OF_VALUE=*/ NAME_OF_VALUE;
// The C preprocessor will replace NAME_OF_VALUE with the actual value.
-// This will be post-processed by tools/gen_ld_files.py to extract the name and vlaue.
+// This will be post-processed by tools/gen_ld_files.py to extract the name and value.
-BOOTLOADER_SIZE; ///DEFINE_VALUE BOOTLOADER_SIZE
-RAM_SIZE; ///DEFINE_VALUE RAM_SIZE def noUL(expr): import re; return re.sub(
-FLASH_SIZE; ///DEFINE_VALUE FLASH_SIZE lambda expr: expr.rstrip("UL")
-CIRCUITPY_FIRMWARE_SIZE; ///DEFINE_VALUE CIRCUITPY_FIRMWARE_SIZE
-CIRCUITPY_DEFAULT_STACK_SIZE; ///DEFINE_VALUE CIRCUITPY_DEFAULT_STACK_SIZE
+// The next line is a marker to start looking for definitions. Lines above the next line are ignored.
+// START_LD_DEFINES
+
+/*RAM_SIZE=*/ RAM_SIZE;
+/*FLASH_SIZE=*/ FLASH_SIZE;
+
+/*BOOTLOADER_SIZE=*/ BOOTLOADER_SIZE;
+/*BOOTLOADER_START_ADDR=*/ BOOTLOADER_START_ADDR;
+
+/*CIRCUITPY_DEFAULT_STACK_SIZE=*/ CIRCUITPY_DEFAULT_STACK_SIZE;
+
+/*CIRCUITPY_FIRMWARE_START_ADDR=*/ CIRCUITPY_FIRMWARE_START_ADDR;
+/*CIRCUITPY_FIRMWARE_SIZE=*/ CIRCUITPY_FIRMWARE_SIZE;
+
+/*CIRCUITPY_INTERNAL_CONFIG_START_ADDR=*/ CIRCUITPY_INTERNAL_CONFIG_START_ADDR;
+/*CIRCUITPY_INTERNAL_CONFIG_SIZE=*/ CIRCUITPY_INTERNAL_CONFIG_SIZE;
+
+/*CIRCUITPY_INTERNAL_NVM_START_ADDR=*/ CIRCUITPY_INTERNAL_NVM_START_ADDR;
+/*CIRCUITPY_INTERNAL_NVM_SIZE=*/ CIRCUITPY_INTERNAL_NVM_SIZE;
+
+/*CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR=*/ CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR;
+/*CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE=*/ CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE;
diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h
index 3334ce153..9733d270a 100644
--- a/ports/atmel-samd/mpconfigport.h
+++ b/ports/atmel-samd/mpconfigport.h
@@ -30,28 +30,28 @@
// Definitions for which SAMD chip we're using.
#include "include/sam.h"
-#ifdef SAMD21
-
#if INTERNAL_FLASH_FILESYSTEM
#define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE (64*1024)
#else
-#define CIRCUITPYINTERNAL_FLASH_FILESYSTEM_SIZE (0)
+#define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE (0)
#endif
-#ifndef CIRCUITPY_INTERNAL_NVM_SIZE
-#define CIRCUITPY_INTERNAL_NVM_SIZE (256)
+#ifndef CALIBRATE_CRYSTALLESS
+#define CALIBRATE_CRYSTALLESS (0)
#endif
// if CALIBRATE_CRYSTALLESS is requested, make room for storing
// calibration data generated from external USB.
#ifndef CIRCUITPY_INTERNAL_CONFIG_SIZE
- #ifdef CALIBRATE_CRYSTALLESS
-#define CIRCUITPY_INTERNAL_CONFIG_SIZE (256)
+ #if CALIBRATE_CRYSTALLESS
+ #define CIRCUITPY_INTERNAL_CONFIG_SIZE (256)
#else
-#define CIRCUITPY_INTERNAL_CONFIG_SIZE (0)
- #endif
+ #define CIRCUITPY_INTERNAL_CONFIG_SIZE (0)
+ #endif
#endif
+#ifdef SAMD21
+
// HMCRAMC0_SIZE is defined in the ASF4 include files for each SAMD21 chip.
#define RAM_SIZE HMCRAMC0_SIZE
#define BOOTLOADER_SIZE (8*1024)
@@ -78,6 +78,10 @@
X(EISDIR) \
X(EINVAL) \
+#ifndef CIRCUITPY_INTERNAL_NVM_SIZE
+#define CIRCUITPY_INTERNAL_NVM_SIZE (256)
+#endif
+
#endif // SAMD21
#ifdef SAMD51
@@ -121,18 +125,30 @@
// microntroller.nvm (optional)
// internal CIRCUITPY flash filesystem (optional)
-// Bootloader starts at 0x00000000.
-#define CIRCUITPY_FIRMWARE_START_ADDR BOOTLOADER_SIZE
+// Define these regions starting up from the bottom of flash:
-// Total space available for code, after subtracting size of other regions used for non-code.
-#define CIRCUITPY_FIRMWARE_SIZE \
- (FLASH_SIZE - BOOTLOADER_SIZE - CIRCUITPY_INTERNAL_CONFIG_SIZE - CIRCUITPY_INTERNAL_NVM_SIZE - \
- CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE)
+#define BOOTLOADER_START_ADDR (0x00000000)
+
+#define CIRCUITPY_FIRMWARE_START_ADDR (BOOTLOADER_START_ADDR + BOOTLOADER_SIZE)
+
+// Define these regions start down from the top of flash:
-#define CIRCUITPY_INTERNAL_CONFIG_START_ADDR (CIRCUITPY_FIRMWARE_START_ADDR + CIRCUITPY_FIRMWARE_SIZE)
-#define CIRCUITPY_INTERNAL_NVM_START_ADDR (CIRCUITPY_INTERNAL_CONFIG_START_ADDR + CIRCUITPY_INTERNAL_CONFIG_SIZE)
#define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR \
- (CIRCUITPY_INTERNAL_NVM_START_ADDR + CIRCUITPY_INTERNAL_NVM_SIZE)
+ (FLASH_SIZE - CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE)
+
+#define CIRCUITPY_INTERNAL_NVM_START_ADDR \
+ (CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define CIRCUITPY_INTERNAL_CONFIG_START_ADDR \
+ (CIRCUITPY_INTERNAL_NVM_START_ADDR - CIRCUITPY_INTERNAL_CONFIG_SIZE)
+
+// The firmware space is the space left over between the fixed lower and upper regions.
+#define CIRCUITPY_FIRMWARE_SIZE \
+ (CIRCUITPY_INTERNAL_CONFIG_START_ADDR - CIRCUITPY_FIRMWARE_START_ADDR)
+
+#if CIRCUITPY_FIRMWARE_SIZE < 0
+#error No space left in flash for firmware after specifying other regions!
+#endif
// Turning off audioio, audiobusio, and touchio as necessary
// due to limitations of chips is handled in mpconfigboard.mk
diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk
index 63ddb5f23..ccfebd46c 100644
--- a/ports/atmel-samd/mpconfigport.mk
+++ b/ports/atmel-samd/mpconfigport.mk
@@ -20,21 +20,46 @@ endif
# Put samd21-only choices here.
ifeq ($(CHIP_FAMILY),samd21)
-# frequencyio not yet verified as working on SAMD21.
+# frequencyio not yet verified as working on SAMD21, though make it possible to override.
+ifndef CIRCUITPY_AUDIOMIXER
CIRCUITPY_AUDIOMIXER = 0
+endif
+
+ifndef CIRCUITPY_FREQUENCYIO
CIRCUITPY_FREQUENCYIO = 0
+endif
+
+ifndef CIRCUITPY_TOUCHIO_USE_NATIVE
CIRCUITPY_TOUCHIO_USE_NATIVE = 1
+endif
# SAMD21 needs separate endpoint pairs for MSC BULK IN and BULK OUT, otherwise it's erratic.
USB_MSC_EP_NUM_OUT = 1
-endif
+
+endif # samd21
# Put samd51-only choices here.
ifeq ($(CHIP_FAMILY),samd51)
-CIRCUITPY_SAMD = 1
+# No native touchio on SAMD51.
CIRCUITPY_TOUCHIO_USE_NATIVE = 0
+
+# The ifndef's allow overriding in mpconfigboard.mk.
+
+ifndef CIRCUITPY_NETWORK
+CIRCUITPY_NETWORK = 1
+MICROPY_PY_WIZNET5K = 5500
+endif
+
+ifndef CIRCUITPY_PS2IO
+CIRCUITPY_PS2IO = 1
endif
+ifndef CIRCUITPY_SAMD
+CIRCUITPY_SAMD = 1
+endif
+
+endif # samd51
+
INTERNAL_LIBM = 1
USB_SERIAL_NUMBER_LENGTH = 32
diff --git a/ports/atmel-samd/mphalport.c b/ports/atmel-samd/mphalport.c
index 957bf6073..96433d729 100644
--- a/ports/atmel-samd/mphalport.c
+++ b/ports/atmel-samd/mphalport.c
@@ -45,12 +45,12 @@
#include "mpconfigboard.h"
#include "mphalport.h"
#include "reset.h"
-#include "tick.h"
+#include "supervisor/shared/tick.h"
extern uint32_t common_hal_mcu_processor_get_frequency(void);
void mp_hal_delay_ms(mp_uint_t delay) {
- uint64_t start_tick = ticks_ms;
+ uint64_t start_tick = supervisor_ticks_ms64();
uint64_t duration = 0;
while (duration < delay) {
RUN_BACKGROUND_TASKS;
@@ -59,7 +59,7 @@ void mp_hal_delay_ms(mp_uint_t delay) {
MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
break;
}
- duration = (ticks_ms - start_tick);
+ duration = (supervisor_ticks_ms64() - start_tick);
// TODO(tannewt): Go to sleep for a little while while we wait.
}
}
diff --git a/ports/atmel-samd/mphalport.h b/ports/atmel-samd/mphalport.h
index 64269b201..8a762e258 100644
--- a/ports/atmel-samd/mphalport.h
+++ b/ports/atmel-samd/mphalport.h
@@ -31,11 +31,11 @@
#include "lib/oofatfs/ff.h"
-// Global millisecond tick count (driven by SysTick interrupt).
-extern volatile uint64_t ticks_ms;
+#include "supervisor/shared/tick.h"
+// Global millisecond tick count (driven by SysTick interrupt).
static inline mp_uint_t mp_hal_ticks_ms(void) {
- return ticks_ms;
+ return supervisor_ticks_ms32();
}
// Number of bytes in receive buffer
volatile uint8_t usb_rx_count;
diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c
index 512fd8eb8..e962281c1 100644
--- a/ports/atmel-samd/supervisor/port.c
+++ b/ports/atmel-samd/supervisor/port.c
@@ -271,6 +271,14 @@ void reset_cpu(void) {
reset();
}
+uint32_t *port_stack_get_limit(void) {
+ return &_ebss;
+}
+
+uint32_t *port_stack_get_top(void) {
+ return &_estack;
+}
+
// Place the word to save 8k from the end of RAM so we and the bootloader don't clobber it.
#ifdef SAMD21
uint32_t* safe_word = (uint32_t*) (HMCRAMC0_ADDR + HMCRAMC0_SIZE - 0x2000);
diff --git a/ports/atmel-samd/tick.c b/ports/atmel-samd/tick.c
index 6163a64d8..f996440ae 100644
--- a/ports/atmel-samd/tick.c
+++ b/ports/atmel-samd/tick.c
@@ -28,47 +28,21 @@
#include "peripheral_clk_config.h"
-#include "supervisor/shared/autoreload.h"
-#include "supervisor/filesystem.h"
+#include "supervisor/shared/tick.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/microcontroller/Processor.h"
-#if CIRCUITPY_GAMEPAD
-#include "shared-module/gamepad/__init__.h"
-#endif
-
-#if CIRCUITPY_GAMEPADSHIFT
-#include "shared-module/gamepadshift/__init__.h"
-#endif
-// Global millisecond tick count
-volatile uint64_t ticks_ms = 0;
-
void SysTick_Handler(void) {
// SysTick interrupt handler called when the SysTick timer reaches zero
// (every millisecond).
common_hal_mcu_disable_interrupts();
- ticks_ms += 1;
// Read the control register to reset the COUNTFLAG.
(void) SysTick->CTRL;
common_hal_mcu_enable_interrupts();
-#if CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS > 0
- filesystem_tick();
-#endif
-#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
- autoreload_tick();
-#endif
-#ifdef CIRCUITPY_GAMEPAD_TICKS
- if (!(ticks_ms & CIRCUITPY_GAMEPAD_TICKS)) {
- #if CIRCUITPY_GAMEPAD
- gamepad_tick();
- #endif
- #if CIRCUITPY_GAMEPADSHIFT
- gamepadshift_tick();
- #endif
- }
-#endif
+ // Do things common to all ports when the tick occurs
+ supervisor_tick();
}
void tick_init() {
@@ -115,7 +89,7 @@ void current_tick(uint64_t* ms, uint32_t* us_until_ms) {
uint32_t tick_status = SysTick->CTRL;
uint32_t current_us = SysTick->VAL;
uint32_t tick_status2 = SysTick->CTRL;
- uint64_t current_ms = ticks_ms;
+ uint64_t current_ms = supervisor_ticks_ms64();
// The second clause ensures our value actually rolled over. Its possible it hit zero between
// the VAL read and CTRL read.
if ((tick_status & SysTick_CTRL_COUNTFLAG_Msk) != 0 ||
@@ -129,5 +103,5 @@ void current_tick(uint64_t* ms, uint32_t* us_until_ms) {
void wait_until(uint64_t ms, uint32_t us_until_ms) {
uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000;
- while (ticks_ms <= ms && SysTick->VAL / ticks_per_us >= us_until_ms) {}
+ while (supervisor_ticks_ms64() <= ms && SysTick->VAL / ticks_per_us >= us_until_ms) {}
}
diff --git a/ports/atmel-samd/tick.h b/ports/atmel-samd/tick.h
index c8c8d739a..334352df2 100644
--- a/ports/atmel-samd/tick.h
+++ b/ports/atmel-samd/tick.h
@@ -28,8 +28,6 @@
#include "py/mpconfig.h"
-extern volatile uint64_t ticks_ms;
-
extern struct timer_descriptor ms_timer;
void tick_init(void);
diff --git a/ports/cxd56/Makefile b/ports/cxd56/Makefile
index 38ebd8305..d65c2e266 100644
--- a/ports/cxd56/Makefile
+++ b/ports/cxd56/Makefile
@@ -90,6 +90,7 @@ INC += \
-I$(SPRESENSE_SDK)/nuttx/include \
-I$(SPRESENSE_SDK)/nuttx/arch \
-I$(SPRESENSE_SDK)/nuttx/arch/chip \
+ -I$(SPRESENSE_SDK)/nuttx/arch/os \
-I$(SPRESENSE_SDK)/sdk/bsp/include \
-I$(SPRESENSE_SDK)/sdk/bsp/include/sdk \
@@ -124,7 +125,6 @@ LDFLAGS = \
--entry=__start \
-nostartfiles \
-nodefaultlibs \
- --defsym __stack=_vectors+786432 \
-T$(SPRESENSE_SDK)/nuttx/build/ramconfig.ld \
--gc-sections \
-Map=$(BUILD)/output.map \
diff --git a/ports/cxd56/boards/spresense/mpconfigboard.h b/ports/cxd56/boards/spresense/mpconfigboard.h
index b20d00658..0245e2045 100644
--- a/ports/cxd56/boards/spresense/mpconfigboard.h
+++ b/ports/cxd56/boards/spresense/mpconfigboard.h
@@ -26,7 +26,6 @@
#define MICROPY_HW_BOARD_NAME "SPRESENSE"
#define MICROPY_HW_MCU_NAME "CXD5602"
-#define MICROPY_PY_SYS_PLATFORM "SPRESENSE"
#define DEFAULT_I2C_BUS_SCL (&pin_I2C0_BCK)
#define DEFAULT_I2C_BUS_SDA (&pin_I2C0_BDT)
diff --git a/ports/cxd56/common-hal/analogio/AnalogIn.c b/ports/cxd56/common-hal/analogio/AnalogIn.c
index ebe291582..e2ca5e4a4 100644
--- a/ports/cxd56/common-hal/analogio/AnalogIn.c
+++ b/ports/cxd56/common-hal/analogio/AnalogIn.c
@@ -68,9 +68,11 @@ void common_hal_analogio_analogin_construct(analogio_analogin_obj_t *self, const
mp_raise_ValueError(translate("Pin does not have ADC capabilities"));
}
- analogin_dev[self->number].fd = open(analogin_dev[pin->number].devpath, O_RDONLY);
if (analogin_dev[self->number].fd < 0) {
- mp_raise_ValueError(translate("Pin does not have ADC capabilities"));
+ analogin_dev[self->number].fd = open(analogin_dev[self->number].devpath, O_RDONLY);
+ if (analogin_dev[self->number].fd < 0) {
+ mp_raise_ValueError(translate("Pin does not have ADC capabilities"));
+ }
}
// SCU FIFO overwrite
@@ -99,7 +101,7 @@ void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) {
}
bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t *self) {
- return self->pin == mp_const_none;
+ return analogin_dev[self->number].fd < 0;
}
uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) {
diff --git a/ports/cxd56/common-hal/analogio/AnalogIn.h b/ports/cxd56/common-hal/analogio/AnalogIn.h
index 4e8b41e52..9cf73003f 100644
--- a/ports/cxd56/common-hal/analogio/AnalogIn.h
+++ b/ports/cxd56/common-hal/analogio/AnalogIn.h
@@ -34,7 +34,7 @@
typedef struct {
mp_obj_base_t base;
const mcu_pin_obj_t *pin;
- uint8_t number;
+ int8_t number;
} analogio_analogin_obj_t;
void analogin_reset(void);
diff --git a/ports/cxd56/common-hal/busio/UART.c b/ports/cxd56/common-hal/busio/UART.c
index 2389cbf96..40ae3b761 100644
--- a/ports/cxd56/common-hal/busio/UART.c
+++ b/ports/cxd56/common-hal/busio/UART.c
@@ -32,7 +32,6 @@
#include <sys/time.h>
#include <sys/select.h>
#include <sys/ioctl.h>
-#include <arch/chip/pin.h>
#include <nuttx/serial/tioctl.h>
#include <nuttx/fs/ioctl.h>
@@ -42,22 +41,23 @@
#include "shared-bindings/busio/UART.h"
+typedef struct {
+ const char* devpath;
+ const mcu_pin_obj_t *tx;
+ const mcu_pin_obj_t *rx;
+ int fd;
+} busio_uart_dev_t;
+
+STATIC busio_uart_dev_t busio_uart_dev[] = {
+ {"/dev/ttyS2", &pin_UART2_TXD, &pin_UART2_RXD, -1},
+};
+
void common_hal_busio_uart_construct(busio_uart_obj_t *self,
const mcu_pin_obj_t *tx, const mcu_pin_obj_t *rx, uint32_t baudrate,
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
uint16_t receiver_buffer_size) {
struct termios tio;
- self->uart_fd = open("/dev/ttyS2", O_RDWR);
- if (self->uart_fd < 0) {
- mp_raise_ValueError(translate("Could not initialize UART"));
- }
-
- ioctl(self->uart_fd, TCGETS, (long unsigned int)&tio);
- tio.c_speed = baudrate;
- ioctl(self->uart_fd, TCSETS, (long unsigned int)&tio);
- ioctl(self->uart_fd, TCFLSH, (long unsigned int)NULL);
-
if (bits != 8) {
mp_raise_ValueError(translate("Could not initialize UART"));
}
@@ -70,17 +70,39 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
mp_raise_ValueError(translate("Could not initialize UART"));
}
- if (tx->number != PIN_UART2_TXD || rx->number != PIN_UART2_RXD) {
+ self->number = -1;
+
+ for (int i = 0; i < MP_ARRAY_SIZE(busio_uart_dev); i++) {
+ if (tx->number == busio_uart_dev[i].tx->number &&
+ rx->number == busio_uart_dev[i].rx->number) {
+ self->number = i;
+ break;
+ }
+ }
+
+ if (self->number < 0) {
mp_raise_ValueError(translate("Invalid pins"));
}
+ if (busio_uart_dev[self->number].fd < 0) {
+ busio_uart_dev[self->number].fd = open(busio_uart_dev[self->number].devpath, O_RDWR);
+ if (busio_uart_dev[self->number].fd < 0) {
+ mp_raise_ValueError(translate("Could not initialize UART"));
+ }
+ }
+
+ ioctl(busio_uart_dev[self->number].fd, TCGETS, (long unsigned int)&tio);
+ tio.c_speed = baudrate;
+ ioctl(busio_uart_dev[self->number].fd, TCSETS, (long unsigned int)&tio);
+ ioctl(busio_uart_dev[self->number].fd, TCFLSH, (long unsigned int)NULL);
+
claim_pin(tx);
claim_pin(rx);
self->tx_pin = tx;
self->rx_pin = rx;
self->baudrate = baudrate;
- self->timeout = timeout;
+ self->timeout_us = timeout * 1000000;
}
void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
@@ -88,15 +110,15 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
return;
}
- close(self->uart_fd);
- self->uart_fd = -1;
+ close(busio_uart_dev[self->number].fd);
+ busio_uart_dev[self->number].fd = -1;
reset_pin_number(self->tx_pin->number);
reset_pin_number(self->rx_pin->number);
}
bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) {
- return self->uart_fd < 0;
+ return busio_uart_dev[self->number].fd < 0;
}
size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) {
@@ -110,15 +132,15 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
}
FD_ZERO(&rfds);
- FD_SET(self->uart_fd, &rfds);
+ FD_SET(busio_uart_dev[self->number].fd, &rfds);
tv.tv_sec = 0;
- tv.tv_usec = self->timeout * 1000;
+ tv.tv_usec = self->timeout_us;
- retval = select(self->uart_fd + 1, &rfds, NULL, NULL, &tv);
+ retval = select(busio_uart_dev[self->number].fd + 1, &rfds, NULL, NULL, &tv);
if (retval) {
- bytes_read = read(self->uart_fd, data, len);
+ bytes_read = read(busio_uart_dev[self->number].fd, data, len);
} else {
*errcode = EAGAIN;
return MP_STREAM_ERROR;
@@ -128,8 +150,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
}
size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) {
- int bytes_written = write(self->uart_fd, data, len);
-
+ int bytes_written = write(busio_uart_dev[self->number].fd, data, len);
if (bytes_written < 0) {
*errcode = MP_EAGAIN;
return MP_STREAM_ERROR;
@@ -145,16 +166,24 @@ uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) {
void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) {
struct termios tio;
- ioctl(self->uart_fd, TCGETS, (long unsigned int)&tio);
+ ioctl(busio_uart_dev[self->number].fd, TCGETS, (long unsigned int)&tio);
tio.c_speed = baudrate;
- ioctl(self->uart_fd, TCSETS, (long unsigned int)&tio);
- ioctl(self->uart_fd, TCFLSH, (long unsigned int)NULL);
+ ioctl(busio_uart_dev[self->number].fd, TCSETS, (long unsigned int)&tio);
+ ioctl(busio_uart_dev[self->number].fd, TCFLSH, (long unsigned int)NULL);
+}
+
+mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) {
+ return (mp_float_t) (self->timeout_us / 1000000.0f);
+}
+
+void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) {
+ self->timeout_us = timeout * 1000000;
}
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
int count = 0;
- ioctl(self->uart_fd, FIONREAD, (long unsigned int)&count);
+ ioctl(busio_uart_dev[self->number].fd, FIONREAD, (long unsigned int)&count);
return count;
}
@@ -163,6 +192,15 @@ void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
}
bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) {
- ioctl(self->uart_fd, TCFLSH, (long unsigned int)NULL);
+ ioctl(busio_uart_dev[self->number].fd, TCFLSH, (long unsigned int)NULL);
return true;
}
+
+void busio_uart_reset(void) {
+ for (int i = 0; i < MP_ARRAY_SIZE(busio_uart_dev); i++) {
+ if (busio_uart_dev[i].fd >= 0) {
+ close(busio_uart_dev[i].fd);
+ busio_uart_dev[i].fd = -1;
+ }
+ }
+}
diff --git a/ports/cxd56/common-hal/busio/UART.h b/ports/cxd56/common-hal/busio/UART.h
index 1c01cfbb9..a69c47056 100644
--- a/ports/cxd56/common-hal/busio/UART.h
+++ b/ports/cxd56/common-hal/busio/UART.h
@@ -33,11 +33,13 @@
typedef struct {
mp_obj_base_t base;
- int uart_fd;
+ int8_t number;
const mcu_pin_obj_t *tx_pin;
const mcu_pin_obj_t *rx_pin;
uint32_t baudrate;
- uint32_t timeout;
+ uint32_t timeout_us;
} busio_uart_obj_t;
+void busio_uart_reset(void);
+
#endif // MICROPY_INCLUDED_CXD56_COMMON_HAL_BUSIO_UART_H
diff --git a/ports/cxd56/common-hal/pulseio/PWMOut.c b/ports/cxd56/common-hal/pulseio/PWMOut.c
index 38692146c..a0b4e79c6 100644
--- a/ports/cxd56/common-hal/pulseio/PWMOut.c
+++ b/ports/cxd56/common-hal/pulseio/PWMOut.c
@@ -62,9 +62,11 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t *self,
return PWMOUT_INVALID_PIN;
}
- pwmout_dev[self->number].fd = open(pwmout_dev[self->number].devpath, O_RDONLY);
if (pwmout_dev[self->number].fd < 0) {
- return PWMOUT_INVALID_PIN;
+ pwmout_dev[self->number].fd = open(pwmout_dev[self->number].devpath, O_RDONLY);
+ if (pwmout_dev[self->number].fd < 0) {
+ return PWMOUT_INVALID_PIN;
+ }
}
self->info.frequency = frequency;
@@ -97,7 +99,7 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t *self) {
}
bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t *self) {
- return self->pin == mp_const_none;
+ return pwmout_dev[self->number].fd < 0;
}
void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t *self, uint16_t duty) {
diff --git a/ports/cxd56/common-hal/pulseio/PWMOut.h b/ports/cxd56/common-hal/pulseio/PWMOut.h
index c16084fe6..57fc4181f 100644
--- a/ports/cxd56/common-hal/pulseio/PWMOut.h
+++ b/ports/cxd56/common-hal/pulseio/PWMOut.h
@@ -38,7 +38,7 @@ typedef struct {
const mcu_pin_obj_t *pin;
struct pwm_info_s info;
bool variable_frequency;
- uint8_t number;
+ int8_t number;
} pulseio_pwmout_obj_t;
void pwmout_reset(void);
diff --git a/ports/cxd56/common-hal/time/__init__.c b/ports/cxd56/common-hal/time/__init__.c
index 8f7326b62..6f5eedd41 100644
--- a/ports/cxd56/common-hal/time/__init__.c
+++ b/ports/cxd56/common-hal/time/__init__.c
@@ -26,10 +26,10 @@
#include "py/mphal.h"
-#include "tick.h"
+#include "supervisor/shared/tick.h"
uint64_t common_hal_time_monotonic(void) {
- return ticks_ms;
+ return supervisor_ticks_ms64();
}
void common_hal_time_delay_ms(uint32_t delay) {
diff --git a/ports/cxd56/mpconfigport.h b/ports/cxd56/mpconfigport.h
index 233b7b9a7..df87946b9 100644
--- a/ports/cxd56/mpconfigport.h
+++ b/ports/cxd56/mpconfigport.h
@@ -27,8 +27,10 @@
#ifndef __INCLUDED_MPCONFIGPORT_H
#define __INCLUDED_MPCONFIGPORT_H
-// 24kiB stack
-#define CIRCUITPY_DEFAULT_STACK_SIZE 0x6000
+#define MICROPY_PY_SYS_PLATFORM "CXD56"
+
+// 64kiB stack
+#define CIRCUITPY_DEFAULT_STACK_SIZE 0x10000
#include "py/circuitpy_mpconfig.h"
diff --git a/ports/cxd56/mphalport.c b/ports/cxd56/mphalport.c
index 79d93f975..1305706ca 100644
--- a/ports/cxd56/mphalport.c
+++ b/ports/cxd56/mphalport.c
@@ -31,7 +31,7 @@
#include "py/mpstate.h"
-#include "tick.h"
+#include "supervisor/shared/tick.h"
#define DELAY_CORRECTION (700)
#define DELAY_INTERVAL (50)
@@ -57,7 +57,7 @@ mp_uint_t mp_hal_ticks_cpu(void) {
}
void mp_hal_delay_ms(mp_uint_t delay) {
- uint64_t start_tick = ticks_ms;
+ uint64_t start_tick = supervisor_ticks_ms64();
uint64_t duration = 0;
while (duration < delay) {
#ifdef MICROPY_VM_HOOK_LOOP
@@ -68,7 +68,7 @@ void mp_hal_delay_ms(mp_uint_t delay) {
MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
break;
}
- duration = (ticks_ms - start_tick);
+ duration = (supervisor_ticks_ms64() - start_tick);
// TODO(tannewt): Go to sleep for a little while while we wait.
}
}
diff --git a/ports/cxd56/mphalport.h b/ports/cxd56/mphalport.h
index 25bca97ad..a2be10b8d 100644
--- a/ports/cxd56/mphalport.h
+++ b/ports/cxd56/mphalport.h
@@ -31,6 +31,4 @@
#include "lib/utils/interrupt_char.h"
-extern volatile uint64_t ticks_ms;
-
#endif // MICROPY_INCLUDED_CXD56_MPHALPORT_H
diff --git a/ports/cxd56/spresense-exported-sdk b/ports/cxd56/spresense-exported-sdk
-Subproject b473b28a14a03f3d416b6e2c071bcfd4fb92cb6
+Subproject 7f6568c7f4898cdb24a2f06040784a836050686
diff --git a/ports/cxd56/supervisor/port.c b/ports/cxd56/supervisor/port.c
index 3fddfe52c..f06133468 100644
--- a/ports/cxd56/supervisor/port.c
+++ b/ports/cxd56/supervisor/port.c
@@ -27,6 +27,8 @@
#include <stdint.h>
#include <sys/boardctl.h>
+#include "sched/sched.h"
+
#include "boards/board.h"
#include "supervisor/port.h"
@@ -35,6 +37,7 @@
#include "common-hal/analogio/AnalogIn.h"
#include "common-hal/pulseio/PulseOut.h"
#include "common-hal/pulseio/PWMOut.h"
+#include "common-hal/busio/UART.h"
safe_mode_t port_init(void) {
boardctl(BOARDIOC_INIT, 0);
@@ -60,6 +63,9 @@ void reset_port(void) {
pulseout_reset();
pwmout_reset();
#endif
+#if CIRCUITPY_BUSIO
+ busio_uart_reset();
+#endif
reset_all_pins();
}
@@ -67,6 +73,18 @@ void reset_port(void) {
void reset_to_bootloader(void) {
}
+uint32_t *port_stack_get_limit(void) {
+ struct tcb_s *rtcb = this_task();
+
+ return rtcb->adj_stack_ptr - (uint32_t)rtcb->adj_stack_size;
+}
+
+uint32_t *port_stack_get_top(void) {
+ struct tcb_s *rtcb = this_task();
+
+ return rtcb->adj_stack_ptr;
+}
+
extern uint32_t _ebss;
// Place the word to save just after our BSS section that gets blanked.
diff --git a/ports/cxd56/tick.c b/ports/cxd56/tick.c
index 6b93a3b65..671b82b74 100644
--- a/ports/cxd56/tick.c
+++ b/ports/cxd56/tick.c
@@ -27,19 +27,10 @@
#include "tick.h"
#include "supervisor/shared/autoreload.h"
-#include "supervisor/filesystem.h"
-
-// Global millisecond tick count
-volatile uint64_t ticks_ms = 0;
+#include "supervisor/shared/tick.h"
void board_timerhook(void)
{
- ticks_ms += 1;
-
-#if CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS > 0
- filesystem_tick();
-#endif
-#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
- autoreload_tick();
-#endif
+ // Do things common to all ports when the tick occurs
+ supervisor_tick();
}
diff --git a/ports/cxd56/tick.h b/ports/cxd56/tick.h
index a0d9ee526..d641d9cd4 100644
--- a/ports/cxd56/tick.h
+++ b/ports/cxd56/tick.h
@@ -29,6 +29,4 @@
#include "py/mpconfig.h"
-extern volatile uint64_t ticks_ms;
-
#endif // MICROPY_INCLUDED_CXD56_TICK_H
diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile
index be8a71b3f..b96b8affb 100755
--- a/ports/nrf/Makefile
+++ b/ports/nrf/Makefile
@@ -219,6 +219,15 @@ SRC_QSTR_PREPROCESSOR +=
all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2
+LD_FILE = $(BUILD)/$(notdir $(patsubst %.template.ld,%.ld,$(LD_TEMPLATE_FILE)))
+
+# ld_defines.pp is generated from ld_defines.c. See py/mkrules.mk.
+# Run gen_ld_files.py over ALL *.template.ld files, not just LD_TEMPLATE_FILE,
+# because it may include other template files.
+$(LD_FILE): $(BUILD)/ld_defines.pp boards/*.template.ld
+ $(STEPECHO) "GEN $@"
+ $(Q)$(PYTHON3) $(TOP)/tools/gen_ld_files.py --defines $< --out_dir $(BUILD) boards/*.template.ld
+
$(BUILD)/firmware.elf: $(OBJ)
$(STEPECHO) "LINK $@"
$(Q)$(CC) -o $@ $(LDFLAGS) $^ -Wl,--start-group $(LIBS) -Wl,--end-group
diff --git a/ports/nrf/background.c b/ports/nrf/background.c
index 305f607c5..629967b3d 100644
--- a/ports/nrf/background.c
+++ b/ports/nrf/background.c
@@ -41,6 +41,10 @@
#include "common-hal/audiopwmio/PWMAudioOut.h"
#endif
+#if CIRCUITPY_BLEIO
+#include "supervisor/shared/bluetooth.h"
+#endif
+
static bool running_background_tasks = false;
void background_tasks_reset(void) {
@@ -62,6 +66,9 @@ void run_background_tasks(void) {
i2s_background();
#endif
+#if CIRCUITPY_BLEIO
+ supervisor_bluetooth_background();
+#endif
#if CIRCUITPY_DISPLAYIO
displayio_background();
diff --git a/ports/nrf/bluetooth/ble_drv.c b/ports/nrf/bluetooth/ble_drv.c
index 6b17e7af2..16475e4b3 100644
--- a/ports/nrf/bluetooth/ble_drv.c
+++ b/ports/nrf/bluetooth/ble_drv.c
@@ -38,6 +38,8 @@
#include "py/misc.h"
#include "py/mpstate.h"
+#include "supervisor/shared/bluetooth.h"
+
nrf_nvic_state_t nrf_nvic_state = { 0 };
// Flag indicating progress of internal flash operation.
@@ -52,6 +54,14 @@ void ble_drv_reset() {
sd_flash_operation_status = SD_FLASH_OPERATION_DONE;
}
+void ble_drv_add_event_handler_entry(ble_drv_evt_handler_entry_t* entry, ble_drv_evt_handler_t func, void *param) {
+ entry->next = MP_STATE_VM(ble_drv_evt_handler_entries);
+ entry->param = param;
+ entry->func = func;
+
+ MP_STATE_VM(ble_drv_evt_handler_entries) = entry;
+}
+
void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) {
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
while (it != NULL) {
@@ -64,11 +74,7 @@ void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) {
// Add a new handler to the front of the list
ble_drv_evt_handler_entry_t *handler = m_new_ll(ble_drv_evt_handler_entry_t, 1);
- handler->next = MP_STATE_VM(ble_drv_evt_handler_entries);
- handler->param = param;
- handler->func = func;
-
- MP_STATE_VM(ble_drv_evt_handler_entries) = handler;
+ ble_drv_add_event_handler_entry(handler, func, param);
}
void ble_drv_remove_event_handler(ble_drv_evt_handler_t func, void *param) {
@@ -127,10 +133,20 @@ void SD_EVT_IRQHandler(void) {
break;
}
+ ble_evt_t* event = (ble_evt_t *)m_ble_evt_buf;
+
+ if (supervisor_bluetooth_hook(event)) {
+ continue;
+ }
+
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
+ bool done = false;
while (it != NULL) {
- it->func((ble_evt_t *)m_ble_evt_buf, it->param);
+ done = it->func(event, it->param) || done;
it = it->next;
}
+ if (!done) {
+ //mp_printf(&mp_plat_print, "Unhandled ble event: 0x%04x\n", event->header.evt_id);
+ }
}
}
diff --git a/ports/nrf/bluetooth/ble_drv.h b/ports/nrf/bluetooth/ble_drv.h
index a066f588f..7716cab8b 100644
--- a/ports/nrf/bluetooth/ble_drv.h
+++ b/ports/nrf/bluetooth/ble_drv.h
@@ -29,6 +29,8 @@
#ifndef MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H
#define MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H
+#include <stdbool.h>
+
#include "ble.h"
#define MAX_TX_IN_PROGRESS 10
@@ -48,7 +50,7 @@
#define UNIT_1_25_MS (1250)
#define UNIT_10_MS (10000)
-typedef void (*ble_drv_evt_handler_t)(ble_evt_t*, void*);
+typedef bool (*ble_drv_evt_handler_t)(ble_evt_t*, void*);
typedef enum {
SD_FLASH_OPERATION_DONE,
@@ -69,4 +71,7 @@ void ble_drv_reset(void);
void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param);
void ble_drv_remove_event_handler(ble_drv_evt_handler_t func, void *param);
+// Allow for user provided entries to prevent allocations outside the VM.
+void ble_drv_add_event_handler_entry(ble_drv_evt_handler_entry_t* entry, ble_drv_evt_handler_t func, void *param);
+
#endif // MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H
diff --git a/ports/nrf/boards/adafruit_nrf52840_s140_v6.ld b/ports/nrf/boards/adafruit_nrf52840_s140_v6.ld
index 74e66754d..2d158c496 100644
--- a/ports/nrf/boards/adafruit_nrf52840_s140_v6.ld
+++ b/ports/nrf/boards/adafruit_nrf52840_s140_v6.ld
@@ -16,6 +16,7 @@
0x00000000..0x00000FFF (4KB) Master Boot Record
*/
+
/* Specify the memory areas (S140 6.x.x) */
MEMORY
{
@@ -28,7 +29,10 @@ MEMORY
FLASH_CONFIG (r): ORIGIN = 0x000ED000, LENGTH = 0x007000
/* 0x2000000 - RAM:ORIGIN is reserved for Softdevice */
- RAM (xrw) : ORIGIN = 0x20004000, LENGTH = 0x20040000 - 0x20004000
+ /* SoftDevice 6.1.0 takes 0x1628 bytes (5.54 kb) minimum. */
+ /* To measure the minimum required amount of memory for given configuration, set this number
+ high enough to work and then check the mutation of the value done by sd_ble_enable. */
+ RAM (xrw) : ORIGIN = 0x20000000 + 16K, LENGTH = 256K - 16K
}
/* produce a link error if there is not this amount of RAM for these sections */
@@ -40,7 +44,8 @@ _minimum_heap_size = 0;
/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/
_estack = ORIGIN(RAM) + LENGTH(RAM);
-/* RAM extents for the garbage collector */
+/* RAM extents for the garbage collector and soft device init */
+_ram_start = ORIGIN(RAM);
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
_heap_end = 0x20020000; /* tunable */
diff --git a/ports/nrf/boards/arduino_nano_33_ble/README.md b/ports/nrf/boards/arduino_nano_33_ble/README.md
new file mode 100644
index 000000000..42d7a8618
--- /dev/null
+++ b/ports/nrf/boards/arduino_nano_33_ble/README.md
@@ -0,0 +1,27 @@
+# Arduino Nano 33 BLE and Nano 33 BLE Sense
+
+The [Arduino Nano 33 BLE](https://store.arduino.cc/usa/nano-33-ble-with-headers) and
+[Arduino Nano 33 BLE Sense](https://store.arduino.cc/usa/nano-33-ble-sense) and
+are built around the NINA B306 module, based on Nordic nRF 52840 and containing
+a powerful Cortex M4F. Both include an onboard 9 axis Inertial Measurement Unit (IMU), the LSM9DS1.
+The Nano 33 BLE Sense adds an LPS22HB barometric pressure and temperature sensor,
+an ADPS-9960 digital proximity, ambient light, RGB, and gensture sensor,
+and an MP34DT05 digital microphone.
+
+Note: the Arduino Nano 33 BLE and BLE Sense do not include a QSPI external
+flash. Any Python code will need to be stored on the internal flash
+filesystem.
+
+I2C pins `board.SCL1` and `board.SDA1` are not exposed and are used for onboard peripherals.
+Pin `board.R_PULLUP` must be set to high to enable the `SCL1` and `SDA1` pullups for proper operation.
+
+Pin `board.VDD_ENV` applies power to the LSM9DS1, and must be high for it to be operational.
+
+Pins `board.MIC_PWR`, `board.PDMDIN`, and `board.PDMCLK` are for the Nano 33 BLE Sense onboard microphone.
+
+Pin `board.INT_ADPS` is the interrupt pin from the ADPS-9960.
+
+Pins `board.RGB_LED_R`, `board.RGB_LED_G`, and `board.RGB_LED_B`
+are the red, green and blue LEDS in the onboard RGB LED.
+
+Pins `board.LED_G` and `board.LED_Y` are onboard green and red LEDs. `board.LED_Y` is also `board.SCK`.
diff --git a/ports/nrf/boards/arduino_nano_33_ble/board.c b/ports/nrf/boards/arduino_nano_33_ble/board.c
new file mode 100644
index 000000000..ddfcde284
--- /dev/null
+++ b/ports/nrf/boards/arduino_nano_33_ble/board.c
@@ -0,0 +1,63 @@
+/*
+ * 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 "nrf.h"
+#include "nrf_rtc.h"
+
+void board_init(void) {
+ // Initializations below from Arduino variant.cpp.
+
+ // // turn power LED on
+ // pinMode(LED_PWR, OUTPUT);
+ // digitalWrite(LED_PWR, HIGH);
+
+ // Errata Nano33BLE - I2C pullup is on SWO line, need to disable TRACE
+ // was being enabled by nrfx_clock_anomaly_132
+ CoreDebug->DEMCR = 0;
+ NRF_CLOCK->TRACECONFIG = 0;
+
+ // FIXME: bootloader enables interrupt on COMPARE[0], which we don't handle
+ // Disable it here to avoid getting stuck when OVERFLOW irq is triggered
+ nrf_rtc_event_disable(NRF_RTC1, NRF_RTC_INT_COMPARE0_MASK);
+ nrf_rtc_int_disable(NRF_RTC1, NRF_RTC_INT_COMPARE0_MASK);
+
+ // // FIXME: always enable I2C pullup and power @startup
+ // // Change for maximum powersave
+ // pinMode(PIN_ENABLE_SENSORS_3V3, OUTPUT);
+ // pinMode(PIN_ENABLE_I2C_PULLUP, OUTPUT);
+
+ // digitalWrite(PIN_ENABLE_SENSORS_3V3, HIGH);
+ // digitalWrite(PIN_ENABLE_I2C_PULLUP, HIGH);
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+
+}
diff --git a/ports/nrf/boards/arduino_nano_33_ble/mpconfigboard.h b/ports/nrf/boards/arduino_nano_33_ble/mpconfigboard.h
new file mode 100644
index 000000000..d34a86243
--- /dev/null
+++ b/ports/nrf/boards/arduino_nano_33_ble/mpconfigboard.h
@@ -0,0 +1,16 @@
+#include "nrfx/hal/nrf_gpio.h"
+
+#define MICROPY_HW_BOARD_NAME "Arduino Nano 33 BLE"
+#define MICROPY_HW_MCU_NAME "nRF52840"
+
+#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
+
+#define DEFAULT_I2C_BUS_SCL (&pin_P0_02)
+#define DEFAULT_I2C_BUS_SDA (&pin_P0_31)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_P0_13)
+#define DEFAULT_SPI_BUS_MOSI (&pin_P0_01)
+#define DEFAULT_SPI_BUS_MISO (&pin_P1_08)
+
+#define DEFAULT_UART_BUS_RX (&pin_P1_10)
+#define DEFAULT_UART_BUS_TX (&pin_P1_03)
diff --git a/ports/nrf/boards/arduino_nano_33_ble/mpconfigboard.mk b/ports/nrf/boards/arduino_nano_33_ble/mpconfigboard.mk
new file mode 100644
index 000000000..d5e38c5b7
--- /dev/null
+++ b/ports/nrf/boards/arduino_nano_33_ble/mpconfigboard.mk
@@ -0,0 +1,15 @@
+USB_VID = 0x2341
+USB_PID = 0x805A
+USB_PRODUCT = "Arduino_Nano_33_BLE"
+USB_MANUFACTURER = "Arduino"
+
+MCU_CHIP = nrf52840
+
+INTERNAL_FLASH_FILESYSTEM = 1
+
+# Allocate two, not just one I2C peripheral, so that we have both
+# on-board and off-board I2C available.
+# When SPIM3 becomes available we'll be able to have two I2C and two SPI peripherals.
+# We use a CFLAGS define here because there are include order issues
+# if we try to include "mpconfigport.h" into nrfx_config.h .
+CFLAGS += -DCIRCUITPY_NRF_NUM_I2C=2
diff --git a/ports/nrf/boards/arduino_nano_33_ble/pins.c b/ports/nrf/boards/arduino_nano_33_ble/pins.c
new file mode 100644
index 000000000..9cdd36933
--- /dev/null
+++ b/ports/nrf/boards/arduino_nano_33_ble/pins.c
@@ -0,0 +1,63 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P1_11) },
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_12) },
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P1_15) },
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_13) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P1_14) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P0_23) },
+ { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P0_21) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_27) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P1_02) },
+
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_04) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_05) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_30) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_29) },
+
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_31) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_31) },
+
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_02) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_02) },
+
+ { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_P0_28) },
+ { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_P0_03) },
+
+ { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_P0_14) },
+ { MP_ROM_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_P0_15) },
+
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P1_01) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P1_08) },
+
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_13) },
+ { MP_ROM_QSTR(MP_QSTR_LED_Y), MP_ROM_PTR(&pin_P0_13) },
+
+ { MP_ROM_QSTR(MP_QSTR_LED_G), MP_ROM_PTR(&pin_P1_09) },
+
+ { MP_ROM_QSTR(MP_QSTR_RGB_LED_R), MP_ROM_PTR(&pin_P0_24) },
+ { MP_ROM_QSTR(MP_QSTR_RGB_LED_G), MP_ROM_PTR(&pin_P0_16) },
+ { MP_ROM_QSTR(MP_QSTR_RGB_LED_B), MP_ROM_PTR(&pin_P0_06) },
+
+ // Power line to LSM9DS1.
+ { MP_ROM_QSTR(MP_QSTR_VDD_ENV), MP_ROM_PTR(&pin_P0_22) },
+
+ // Pullup voltage for SDA1 and SCL1
+ { MP_ROM_QSTR(MP_QSTR_R_PULLUP), MP_ROM_PTR(&pin_P1_00) },
+
+ { MP_ROM_QSTR(MP_QSTR_MIC_PWR), MP_ROM_PTR(&pin_P0_17) },
+ { MP_ROM_QSTR(MP_QSTR_PDMCLK), MP_ROM_PTR(&pin_P0_26) },
+ { MP_ROM_QSTR(MP_QSTR_PDMDIN), MP_ROM_PTR(&pin_P0_25) },
+
+ { MP_ROM_QSTR(MP_QSTR_INT_APDS), MP_ROM_PTR(&pin_P0_19) },
+
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P1_03) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P1_10) },
+
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+};
+
+MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.h b/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.h
index cc441eb0b..7ca9b12ae 100644
--- a/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.h
+++ b/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.h
@@ -29,7 +29,6 @@
#define MICROPY_HW_BOARD_NAME "Adafruit Circuit Playground Bluefruit"
#define MICROPY_HW_MCU_NAME "nRF52840"
-#define MICROPY_PY_SYS_PLATFORM "CircuitPlaygroundBluefruit"
#define FLASH_SIZE (0x100000)
#define FLASH_PAGE_SIZE (4096)
@@ -64,3 +63,5 @@
#define DEFAULT_UART_BUS_RX (&pin_P0_30)
#define DEFAULT_UART_BUS_TX (&pin_P0_14)
+
+#define SPEAKER_ENABLE_PIN (&pin_P1_04)
diff --git a/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.mk b/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.mk
index dbb32629c..f63554e5e 100644
--- a/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.mk
+++ b/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.mk
@@ -3,24 +3,15 @@ USB_PID = 0x8046
USB_PRODUCT = "Circuit Playground Bluefruit"
USB_MANUFACTURER = "Adafruit Industries LLC"
-MCU_SERIES = m4
-MCU_VARIANT = nrf52
-MCU_SUB_VARIANT = nrf52840
MCU_CHIP = nrf52840
-SD ?= s140
-SOFTDEV_VERSION ?= 6.1.0
-
-BOOT_SETTING_ADDR = 0xFF000
-
-ifeq ($(SD),)
- LD_FILE = boards/nrf52840_1M_256k.ld
-else
- LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld
- CIRCUITPY_BLEIO = 1
-endif
-
-NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "GD25Q16C"
+
+# Allocate two, not just one I2C peripheral for CPB, so that we have both
+# on-board and off-board I2C available.
+# When SPIM3 becomes available we'll be able to have two I2C and two SPI peripherals.
+# We use a CFLAGS define here because there are include order issues
+# if we try to include "mpconfigport.h" into nrfx_config.h .
+CFLAGS += -DCIRCUITPY_NRF_NUM_I2C=2
diff --git a/ports/nrf/boards/common.template.ld b/ports/nrf/boards/common.template.ld
new file mode 100644
index 000000000..9fd066de1
--- /dev/null
+++ b/ports/nrf/boards/common.template.ld
@@ -0,0 +1,141 @@
+/*
+ GNU linker script for NRF52840 w/ s140 6.0.0 SoftDevice
+*/
+
+/* Specify the memory areas */
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 /* entire flash, 1 MiB */
+ /* nRF SoftDevice */
+ FLASH_MBR (rx) : ORIGIN = ${MBR_START_ADDR}, LENGTH = ${MBR_SIZE}
+ FLASH_SD (rx) : ORIGIN = ${SD_FLASH_START_ADDR}, LENGTH = ${SD_FLASH_SIZE}
+ FLASH_ISR (rx) : ORIGIN = ${CIRCUITPY_ISR_START_ADDR}, LENGTH = ${CIRCUITPY_ISR_LENGTH}
+ FLASH_FIRMWARE (rx) : ORIGIN = ${CIRCUITPY_FIRMWARE_START_ADDR}, LENGTH = ${CIRCUITPY_FIRMWARE_SIZE}
+ FLASH_BLE_CONFIG (r) : ORIGIN = ${CIRCUITPY_BLE_CONFIG_START_ADDR}, LENGTH = ${CIRCUITPY_BLE_CONFIG_SIZE}
+ FLASH_NVM (r) : ORIGIN = ${CIRCUITPY_INTERNAL_NVM_START_ADDR}, LENGTH = ${CIRCUITPY_INTERNAL_NVM_SIZE}
+ FLASH_FATFS (r) : ORIGIN = ${CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR}, LENGTH = ${CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE}
+ FLASH_BOOTLOADER (rx) : ORIGIN = ${BOOTLOADER_START_ADDR}, LENGTH = ${BOOTLOADER_SIZE}
+ FLASH_BOOTLOADER_SETTINGS (r) : ORIGIN = ${BOOTLOADER_SETTINGS_START_ADDR}, LENGTH = ${BOOTLOADER_SETTINGS_SIZE}
+ RAM (xrw) : ORIGIN = 0x20004000, LENGTH = 0x03C000 /* 240 KiB */
+}
+
+/* produce a link error if there is not this amount of RAM for these sections */
+_minimum_stack_size = 40K;
+_minimum_heap_size = 0;
+
+/* top end of the stack */
+
+/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/
+_estack = ORIGIN(RAM) + LENGTH(RAM);
+
+/* RAM extents for the garbage collector */
+_ram_end = ORIGIN(RAM) + LENGTH(RAM);
+_heap_end = 0x20020000; /* tunable */
+
+/* Flash region for File System */
+__fatfs_flash_start_addr = ORIGIN(FLASH_FATFS);
+__fatfs_flash_length = LENGTH(FLASH_FATFS);
+
+/* define output sections */
+SECTIONS
+{
+ /* The startup code goes first into FLASH */
+ .isr_vector :
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector)) /* Startup code */
+
+ . = ALIGN(4);
+ } >FLASH_ISR
+
+ /* The program code and other data goes into FLASH */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text) /* .text sections (code) */
+ *(.text*) /* .text* sections (code) */
+ *(.rodata) /* .rodata sections (constants, strings, etc.) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ /* *(.glue_7) */ /* glue arm to thumb code */
+ /* *(.glue_7t) */ /* glue thumb to arm code */
+
+ . = ALIGN(4);
+ _etext = .; /* define a global symbol at end of code */
+ } >FLASH_FIRMWARE
+
+ /*
+ .ARM.extab :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } >FLASH_FIRMWARE
+
+ .ARM :
+ {
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ } >FLASH_FIRMWARE
+ */
+
+ /* used by the startup to initialize data */
+ _sidata = .;
+
+ /* This is the initialized data section
+ The program executes knowing that the data is in the RAM
+ but the loader puts the initial values in the FLASH (inidata).
+ It is one task of the startup to copy the initial values from FLASH to RAM. */
+ .data : AT (_sidata)
+ {
+ . = ALIGN(4);
+ _sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
+ _ram_start = .; /* create a global symbol at ram start for garbage collector */
+ *(.data) /* .data sections */
+ *(.data*) /* .data* sections */
+
+ . = ALIGN(4);
+ _edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
+ } >RAM
+
+ /* Uninitialized data section */
+ .bss :
+ {
+ . = ALIGN(4);
+ _sbss = .; /* define a global symbol at bss start; used by startup code */
+ *(.bss)
+ *(.bss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .; /* define a global symbol at bss end; used by startup code and GC */
+ } >RAM
+
+ /* this is to define the start of the heap, and make sure we have a minimum size */
+ .heap :
+ {
+ . = ALIGN(4);
+ PROVIDE ( end = . );
+ PROVIDE ( _end = . );
+ _heap_start = .; /* define a global symbol at heap start */
+ . = . + _minimum_heap_size;
+ } >RAM
+
+ /* this just checks there is enough RAM for the stack */
+ .stack :
+ {
+ . = ALIGN(4);
+ . = . + _minimum_stack_size;
+ . = ALIGN(4);
+ } >RAM
+
+ /* Remove information from the standard libraries */
+ /*
+ /DISCARD/ :
+ {
+ libc.a ( * )
+ libm.a ( * )
+ libgcc.a ( * )
+ }
+ */
+
+ .ARM.attributes 0 : { *(.ARM.attributes) }
+}
diff --git a/ports/nrf/boards/electronut_labs_blip/mpconfigboard.h b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.h
index 6b0813e7d..ed1c32bd3 100644
--- a/ports/nrf/boards/electronut_labs_blip/mpconfigboard.h
+++ b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.h
@@ -32,7 +32,6 @@
#define MICROPY_HW_BOARD_NAME "Electronut Labs Blip"
#define MICROPY_HW_MCU_NAME "nRF52840"
-#define MICROPY_PY_SYS_PLATFORM "ElectronutLabsPapyr"
#define BOARD_HAS_CRYSTAL 1
diff --git a/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk
index 9cddd96ee..f30b308ec 100644
--- a/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk
+++ b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk
@@ -3,28 +3,10 @@ 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_papyr/mpconfigboard.h b/ports/nrf/boards/electronut_labs_papyr/mpconfigboard.h
index 594c3e54c..4c2e7a92c 100644
--- a/ports/nrf/boards/electronut_labs_papyr/mpconfigboard.h
+++ b/ports/nrf/boards/electronut_labs_papyr/mpconfigboard.h
@@ -31,7 +31,6 @@
#define MICROPY_HW_BOARD_NAME "Electronut Labs Papyr"
#define MICROPY_HW_MCU_NAME "nRF52840"
-#define MICROPY_PY_SYS_PLATFORM "ElectronutLabsPapyr"
#define BOARD_HAS_CRYSTAL 1
diff --git a/ports/nrf/boards/electronut_labs_papyr/mpconfigboard.mk b/ports/nrf/boards/electronut_labs_papyr/mpconfigboard.mk
index 5aee244f1..be7175e4e 100644
--- a/ports/nrf/boards/electronut_labs_papyr/mpconfigboard.mk
+++ b/ports/nrf/boards/electronut_labs_papyr/mpconfigboard.mk
@@ -3,20 +3,6 @@ USB_PID = 0x803C
USB_PRODUCT = "Papyr"
USB_MANUFACTURER = "Electronut Labs"
-MCU_SERIES = m4
-MCU_VARIANT = nrf52
-MCU_SUB_VARIANT = nrf52840
MCU_CHIP = nrf52840
-SD ?= s140
-SOFTDEV_VERSION ?= 6.1.0
-BOOT_SETTING_ADDR = 0xFF000
-
-ifeq ($(SD),)
- LD_FILE = boards/nrf52840_1M_256k.ld
-else
- LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld
- CIRCUITPY_BLEIO = 1
-endif
-
-NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 \ No newline at end of file
+INTERNAL_FLASH_FILEYSTEM = 1
diff --git a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h
index 130c5f3e8..b388515e4 100644
--- a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h
+++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h
@@ -29,7 +29,6 @@
#define MICROPY_HW_BOARD_NAME "Adafruit Feather nRF52840 Express"
#define MICROPY_HW_MCU_NAME "nRF52840"
-#define MICROPY_PY_SYS_PLATFORM "Feather52840Express"
#define FLASH_SIZE (0x100000)
#define FLASH_PAGE_SIZE (4096)
diff --git a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk
index 0fef54ef7..84861a1f0 100644
--- a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk
+++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk
@@ -3,23 +3,7 @@ USB_PID = 0x802A
USB_PRODUCT = "Feather nRF52840 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
-MCU_SERIES = m4
-MCU_VARIANT = nrf52
-MCU_SUB_VARIANT = nrf52840
MCU_CHIP = nrf52840
-SD ?= s140
-SOFTDEV_VERSION ?= 6.1.0
-
-BOOT_SETTING_ADDR = 0xFF000
-
-ifeq ($(SD),)
- LD_FILE = boards/nrf52840_1M_256k.ld
-else
- LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld
- CIRCUITPY_BLEIO = 1
-endif
-
-NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
diff --git a/ports/stm32f4/boards/feather_f405/board.c b/ports/nrf/boards/itsybitsy_nrf52840_express/board.c
index 4421970ee..4421970ee 100644
--- a/ports/stm32f4/boards/feather_f405/board.c
+++ b/ports/nrf/boards/itsybitsy_nrf52840_express/board.c
diff --git a/ports/nrf/boards/itsybitsy_nrf52840_express/mpconfigboard.h b/ports/nrf/boards/itsybitsy_nrf52840_express/mpconfigboard.h
new file mode 100644
index 000000000..2f17460ae
--- /dev/null
+++ b/ports/nrf/boards/itsybitsy_nrf52840_express/mpconfigboard.h
@@ -0,0 +1,46 @@
+#include "nrfx/hal/nrf_gpio.h"
+
+#define MICROPY_HW_BOARD_NAME "Adafruit ItsyBitsy nRF52840 Express"
+#define MICROPY_HW_MCU_NAME "nRF52840"
+
+#define FLASH_SIZE (0x100000)
+#define FLASH_PAGE_SIZE (4096)
+
+#define MICROPY_HW_LED_STATUS (&pin_P0_06)
+
+#define MICROPY_HW_APA102_MOSI (&pin_P0_08)
+#define MICROPY_HW_APA102_SCK (&pin_P1_09)
+
+#if QSPI_FLASH_FILESYSTEM
+#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 21)
+#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 22)
+#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(1, 00)
+#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 17)
+#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19)
+#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 23)
+#endif
+
+#if SPI_FLASH_FILESYSTEM
+#define SPI_FLASH_MOSI_PIN &pin_P0_21
+#define SPI_FLASH_MISO_PIN &pin_P0_22
+#define SPI_FLASH_SCK_PIN &pin_P0_19
+#define SPI_FLASH_CS_PIN &pin_P0_23
+#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_14)
+#define DEFAULT_I2C_BUS_SDA (&pin_P0_16)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_P0_13)
+#define DEFAULT_SPI_BUS_MOSI (&pin_P0_15)
+#define DEFAULT_SPI_BUS_MISO (&pin_P0_20)
+
+#define DEFAULT_UART_BUS_RX (&pin_P0_25)
+#define DEFAULT_UART_BUS_TX (&pin_P0_24)
diff --git a/ports/nrf/boards/itsybitsy_nrf52840_express/mpconfigboard.mk b/ports/nrf/boards/itsybitsy_nrf52840_express/mpconfigboard.mk
new file mode 100644
index 000000000..d5587f4b9
--- /dev/null
+++ b/ports/nrf/boards/itsybitsy_nrf52840_express/mpconfigboard.mk
@@ -0,0 +1,13 @@
+USB_VID = 0x239A
+USB_PID = 0x8052
+USB_PRODUCT = "ItsyBitsy nRF52840 Express"
+USB_MANUFACTURER = "Adafruit Industries LLC"
+
+MCU_CHIP = nrf52840
+
+# Don't use up a hardware SPI peripheral for the status DotStar: we only have one or two.
+CIRCUITPY_BITBANG_APA102 = 1
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "GD25Q16C"
diff --git a/ports/nrf/boards/itsybitsy_nrf52840_express/pins.c b/ports/nrf/boards/itsybitsy_nrf52840_express/pins.c
new file mode 100644
index 000000000..364fbfd47
--- /dev/null
+++ b/ports/nrf/boards/itsybitsy_nrf52840_express/pins.c
@@ -0,0 +1,46 @@
+#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_30) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_28) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_31) },
+ { 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_SWITCH), MP_ROM_PTR(&pin_P0_29) },
+
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P0_25) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_25) },
+
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P0_24) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_24) },
+
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P1_02) },
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P0_27) },
+ { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P1_08) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_07) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_05) },
+ { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_26) },
+ { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_11) },
+ { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P0_12) },
+
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_14) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_16) },
+
+ { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_P0_08) },
+ { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_P1_09) },
+
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_13) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_15) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_20) },
+
+ { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P0_06) },
+ { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P0_06) },
+
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+};
+
+MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h
index 093a0df3b..871cbe73d 100644
--- a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h
+++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h
@@ -31,7 +31,6 @@
#define MICROPY_HW_BOARD_NAME "MakerDiary nRF52840 MDK"
#define MICROPY_HW_MCU_NAME "nRF52840"
-#define MICROPY_PY_SYS_PLATFORM "MakerDiary52840MDK"
#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(1, 5)
#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(1, 4)
diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk
index abb0f4946..339575049 100644
--- a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk
+++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk
@@ -3,23 +3,7 @@ USB_PID = 0x802A
USB_PRODUCT = "nRF52840-MDK"
USB_MANUFACTURER = "makerdiary"
-MCU_SERIES = m4
-MCU_VARIANT = nrf52
-MCU_SUB_VARIANT = nrf52840
MCU_CHIP = nrf52840
-SD ?= s140
-SOFTDEV_VERSION ?= 6.1.0
-
-BOOT_SETTING_ADDR = 0xFF000
-
-ifeq ($(SD),)
- LD_FILE = boards/nrf52840_1M_256k.ld
-else
- LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld
- CIRCUITPY_BLEIO = 1
-endif
-
-NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.h b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.h
index 2128428b8..684b2c501 100644
--- a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.h
+++ b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.h
@@ -31,6 +31,5 @@
#define MICROPY_HW_BOARD_NAME "MakerDiary nRF52840 MDK USB Dongle"
#define MICROPY_HW_MCU_NAME "nRF52840"
-#define MICROPY_PY_SYS_PLATFORM "MakerDiary52840MDKDongle"
#define BOARD_HAS_CRYSTAL 1 // according to the schematic we do
diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.mk b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.mk
index 82bbc3bd8..0a29c54e5 100644
--- a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.mk
+++ b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.mk
@@ -3,21 +3,6 @@ USB_PID = 0x802A
USB_PRODUCT = "nRF52840-MDK-Dongle"
USB_MANUFACTURER = "makerdiary"
-MCU_SERIES = m4
-MCU_VARIANT = nrf52
-MCU_SUB_VARIANT = nrf52840
MCU_CHIP = nrf52840
-SD ?= s140
-SOFTDEV_VERSION ?= 6.1.0
-BOOT_SETTING_ADDR = 0xFF000
-BOOT_FILE = boards/$(BOARD)/bootloader/$(SOFTDEV_VERSION)/$(BOARD)_bootloader_$(SOFTDEV_VERSION)_s140
-
-ifeq ($(SD),)
- LD_FILE = boards/nrf52840_1M_256k.ld
-else
- LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld
- CIRCUITPY_BLEIO = 1
-endif
-
-NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
+INTERNAL_FLASH_FILEYSTEM = 1
diff --git a/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.h b/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.h
index 99ed5c785..5188a379f 100644
--- a/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.h
+++ b/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.h
@@ -29,7 +29,6 @@
#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)
diff --git a/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk b/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk
index 4c1c93c10..d421e5210 100644
--- a/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk
+++ b/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk
@@ -3,23 +3,7 @@ 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
diff --git a/ports/nrf/boards/particle_argon/mpconfigboard.h b/ports/nrf/boards/particle_argon/mpconfigboard.h
index 0d74869b1..a4952fc79 100644
--- a/ports/nrf/boards/particle_argon/mpconfigboard.h
+++ b/ports/nrf/boards/particle_argon/mpconfigboard.h
@@ -29,7 +29,6 @@
#define MICROPY_HW_BOARD_NAME "Particle Argon"
#define MICROPY_HW_MCU_NAME "nRF52840"
-#define MICROPY_PY_SYS_PLATFORM "Particle Argon"
#define MICROPY_HW_LED_STATUS (&pin_P1_12)
diff --git a/ports/nrf/boards/particle_argon/mpconfigboard.mk b/ports/nrf/boards/particle_argon/mpconfigboard.mk
index 8d3bb2a28..f8d3d2aca 100644
--- a/ports/nrf/boards/particle_argon/mpconfigboard.mk
+++ b/ports/nrf/boards/particle_argon/mpconfigboard.mk
@@ -3,23 +3,7 @@ USB_PID = 0xc00c
USB_PRODUCT = "Argon"
USB_MANUFACTURER = "Particle"
-MCU_SERIES = m4
-MCU_VARIANT = nrf52
-MCU_SUB_VARIANT = nrf52840
MCU_CHIP = nrf52840
-SD ?= s140
-SOFTDEV_VERSION ?= 6.1.0
-
-BOOT_SETTING_ADDR = 0xFF000
-
-ifeq ($(SD),)
- LD_FILE = boards/nrf52840_1M_256k.ld
-else
- LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld
- CIRCUITPY_BLEIO = 1
-endif
-
-NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
diff --git a/ports/nrf/boards/particle_boron/mpconfigboard.h b/ports/nrf/boards/particle_boron/mpconfigboard.h
index 61af22f58..bab1b3d5c 100644
--- a/ports/nrf/boards/particle_boron/mpconfigboard.h
+++ b/ports/nrf/boards/particle_boron/mpconfigboard.h
@@ -29,7 +29,6 @@
#define MICROPY_HW_BOARD_NAME "Particle Boron"
#define MICROPY_HW_MCU_NAME "nRF52840"
-#define MICROPY_PY_SYS_PLATFORM "Particle Boron"
#define MICROPY_HW_LED_STATUS (&pin_P1_12)
diff --git a/ports/nrf/boards/particle_boron/mpconfigboard.mk b/ports/nrf/boards/particle_boron/mpconfigboard.mk
index 801b9613f..eada97a73 100644
--- a/ports/nrf/boards/particle_boron/mpconfigboard.mk
+++ b/ports/nrf/boards/particle_boron/mpconfigboard.mk
@@ -3,23 +3,7 @@ USB_PID = 0xc00d
USB_PRODUCT = "Boron"
USB_MANUFACTURER = "Particle"
-MCU_SERIES = m4
-MCU_VARIANT = nrf52
-MCU_SUB_VARIANT = nrf52840
MCU_CHIP = nrf52840
-SD ?= s140
-SOFTDEV_VERSION ?= 6.1.0
-
-BOOT_SETTING_ADDR = 0xFF000
-
-ifeq ($(SD),)
- LD_FILE = boards/nrf52840_1M_256k.ld
-else
- LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld
- CIRCUITPY_BLEIO = 1
-endif
-
-NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
diff --git a/ports/nrf/boards/particle_xenon/mpconfigboard.h b/ports/nrf/boards/particle_xenon/mpconfigboard.h
index c2dfffde8..f0d12bb0b 100644
--- a/ports/nrf/boards/particle_xenon/mpconfigboard.h
+++ b/ports/nrf/boards/particle_xenon/mpconfigboard.h
@@ -29,7 +29,6 @@
#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)
diff --git a/ports/nrf/boards/particle_xenon/mpconfigboard.mk b/ports/nrf/boards/particle_xenon/mpconfigboard.mk
index 5cebc423a..6062da378 100644
--- a/ports/nrf/boards/particle_xenon/mpconfigboard.mk
+++ b/ports/nrf/boards/particle_xenon/mpconfigboard.mk
@@ -3,23 +3,7 @@ USB_PID = 0xc00e # argon is 0xc00c
USB_PRODUCT = "Xenon"
USB_MANUFACTURER = "Particle"
-MCU_SERIES = m4
-MCU_VARIANT = nrf52
-MCU_SUB_VARIANT = nrf52840
MCU_CHIP = nrf52840
-SD ?= s140
-SOFTDEV_VERSION ?= 6.1.0
-
-BOOT_SETTING_ADDR = 0xFF000
-
-ifeq ($(SD),)
- LD_FILE = boards/nrf52840_1M_256k.ld
-else
- LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld
- CIRCUITPY_BLEIO = 1
-endif
-
-NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
diff --git a/ports/nrf/boards/pca10056/mpconfigboard.h b/ports/nrf/boards/pca10056/mpconfigboard.h
index eca339a7d..5d0d4d3a5 100644
--- a/ports/nrf/boards/pca10056/mpconfigboard.h
+++ b/ports/nrf/boards/pca10056/mpconfigboard.h
@@ -28,7 +28,6 @@
#define MICROPY_HW_BOARD_NAME "PCA10056 nRF52840-DK"
#define MICROPY_HW_MCU_NAME "nRF52840"
-#define MICROPY_PY_SYS_PLATFORM "nRF52840-DK"
#define MICROPY_HW_LED_STATUS (&pin_P0_13)
diff --git a/ports/nrf/boards/pca10056/mpconfigboard.mk b/ports/nrf/boards/pca10056/mpconfigboard.mk
index 723e7976e..8fd1ef08d 100644
--- a/ports/nrf/boards/pca10056/mpconfigboard.mk
+++ b/ports/nrf/boards/pca10056/mpconfigboard.mk
@@ -3,23 +3,7 @@ USB_PID = 0x802A
USB_PRODUCT = "PCA10056"
USB_MANUFACTURER = "Nordic Semiconductor"
-MCU_SERIES = m4
-MCU_VARIANT = nrf52
-MCU_SUB_VARIANT = nrf52840
MCU_CHIP = nrf52840
-SD ?= s140
-SOFTDEV_VERSION ?= 6.1.0
-
-BOOT_SETTING_ADDR = 0xFF000
-
-ifeq ($(SD),)
- LD_FILE = boards/nrf52840_1M_256k.ld
-else
- LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld
- CIRCUITPY_BLEIO = 1
-endif
-
-NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
diff --git a/ports/nrf/boards/pca10059/mpconfigboard.h b/ports/nrf/boards/pca10059/mpconfigboard.h
index eaca1bf21..18aa66f16 100644
--- a/ports/nrf/boards/pca10059/mpconfigboard.h
+++ b/ports/nrf/boards/pca10059/mpconfigboard.h
@@ -26,6 +26,5 @@
#define MICROPY_HW_BOARD_NAME "PCA10059 nRF52840 Dongle"
#define MICROPY_HW_MCU_NAME "nRF52840"
-#define MICROPY_PY_SYS_PLATFORM "nRF52840-DK"
#define MICROPY_HW_LED_STATUS (&pin_P0_06)
diff --git a/ports/nrf/boards/pca10059/mpconfigboard.mk b/ports/nrf/boards/pca10059/mpconfigboard.mk
index db9d80668..f9ff9c21c 100644
--- a/ports/nrf/boards/pca10059/mpconfigboard.mk
+++ b/ports/nrf/boards/pca10059/mpconfigboard.mk
@@ -3,21 +3,6 @@ USB_PID = 0x802A
USB_PRODUCT = "PCA10059"
USB_MANUFACTURER = "Nordic Semiconductor"
-MCU_SERIES = m4
-MCU_VARIANT = nrf52
-MCU_SUB_VARIANT = nrf52840
MCU_CHIP = nrf52840
-SD ?= s140
-SOFTDEV_VERSION ?= 6.1.0
-BOOT_SETTING_ADDR = 0xFF000
-BOOT_FILE = boards/$(BOARD)/bootloader/$(SOFTDEV_VERSION)/$(BOARD)_bootloader_$(SOFTDEV_VERSION)_s140
-
-ifeq ($(SD),)
- LD_FILE = boards/nrf52840_1M_256k.ld
-else
- LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld
- CIRCUITPY_BLEIO = 1
-endif
-
-NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
+INTERNAL_FLASH_FILEYSTEM = 1
diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.h b/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.h
index 20a99a695..23cce7f8a 100644
--- a/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.h
+++ b/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.h
@@ -28,7 +28,6 @@
#define MICROPY_HW_BOARD_NAME "SparkFun Pro nRF52840 Mini"
#define MICROPY_HW_MCU_NAME "nRF52840"
-#define MICROPY_PY_SYS_PLATFORM "SFE_NRF52840_Mini"
#define DEFAULT_I2C_BUS_SCL (&pin_P0_11)
#define DEFAULT_I2C_BUS_SDA (&pin_P0_08)
diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.mk b/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.mk
index 212a85d57..f66b2eaf7 100644
--- a/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.mk
+++ b/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.mk
@@ -3,22 +3,6 @@ USB_PID = 0x5289
USB_PRODUCT = "SFE_nRF52840_Mini"
USB_MANUFACTURER = "SparkFun Electronics"
-MCU_SERIES = m4
-MCU_VARIANT = nrf52
-MCU_SUB_VARIANT = nrf52840
MCU_CHIP = nrf52840
-SD ?= s140
-SOFTDEV_VERSION ?= 6.1.0
-
-BOOT_SETTING_ADDR = 0xFF000
-
-ifeq ($(SD),)
- LD_FILE = boards/nrf52840_1M_256k.ld
-else
- LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld
- CIRCUITPY_BLEIO = 1
-endif
-
-NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
INTERNAL_FLASH_FILESYSTEM = 1
diff --git a/ports/nrf/common-hal/_bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c
index 76f08b5ed..90837b855 100644
--- a/ports/nrf/common-hal/_bleio/Adapter.c
+++ b/ports/nrf/common-hal/_bleio/Adapter.c
@@ -26,6 +26,7 @@
* THE SOFTWARE.
*/
+#include <stdint.h>
#include <stdio.h>
#include <string.h>
@@ -34,12 +35,20 @@
#include "nrfx_power.h"
#include "nrf_nvic.h"
#include "nrf_sdm.h"
+#include "tick.h"
+#include "py/gc.h"
#include "py/objstr.h"
#include "py/runtime.h"
+#include "supervisor/shared/safe_mode.h"
+#include "supervisor/shared/tick.h"
#include "supervisor/usb.h"
+#include "shared-bindings/_bleio/__init__.h"
#include "shared-bindings/_bleio/Adapter.h"
#include "shared-bindings/_bleio/Address.h"
#include "shared-bindings/nvm/ByteArray.h"
+#include "shared-bindings/_bleio/Connection.h"
+#include "shared-bindings/_bleio/ScanEntry.h"
+#include "shared-bindings/time/__init__.h"
#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS)
#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS)
@@ -51,14 +60,17 @@ const nvm_bytearray_obj_t common_hal_bleio_nvm_obj = {
.type = &nvm_bytearray_type,
},
.len = CIRCUITPY_BLE_CONFIG_SIZE,
- .start_address = CIRCUITPY_BLE_CONFIG_ADDRESS,
+ .start_address = (uint8_t*) CIRCUITPY_BLE_CONFIG_START_ADDR,
};
STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) {
- mp_raise_msg_varg(&mp_type_AssertionError,
- translate("Soft device assert, id: 0x%08lX, pc: 0x%08lX"), id, pc);
+ reset_into_safe_mode(NORDIC_SOFT_DEVICE_ASSERT);
}
+bleio_connection_internal_t connections[BLEIO_TOTAL_CONNECTION_COUNT];
+
+// Linker script provided ram start.
+extern uint32_t _ram_start;
STATIC uint32_t ble_stack_enable(void) {
nrf_clock_lf_cfg_t clock_config = {
#if BOARD_HAS_32KHZ_XTAL
@@ -87,34 +99,56 @@ STATIC uint32_t ble_stack_enable(void) {
// Start with no event handlers, etc.
ble_drv_reset();
- uint32_t app_ram_start;
- app_ram_start = 0x20004000;
+ // Set everything up to have one persistent code editing connection and one user managed
+ // connection. In the future we could move .data and .bss to the other side of the stack and
+ // dynamically adjust for different memory requirements of the SD based on boot.py
+ // configuration.
+ uint32_t app_ram_start = (uint32_t) &_ram_start;
ble_cfg_t ble_conf;
ble_conf.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM;
- ble_conf.conn_cfg.params.gap_conn_cfg.conn_count = BLE_GAP_CONN_COUNT_DEFAULT;
+ ble_conf.conn_cfg.params.gap_conn_cfg.conn_count = BLEIO_TOTAL_CONNECTION_COUNT;
+ // Event length here can influence throughput so perhaps make multiple connection profiles
+ // available.
ble_conf.conn_cfg.params.gap_conn_cfg.event_length = BLE_GAP_EVENT_LENGTH_DEFAULT;
err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_conf, app_ram_start);
- if (err_code != NRF_SUCCESS)
+ if (err_code != NRF_SUCCESS) {
return err_code;
+ }
memset(&ble_conf, 0, sizeof(ble_conf));
- ble_conf.gap_cfg.role_count_cfg.periph_role_count = 1;
+ ble_conf.gap_cfg.role_count_cfg.adv_set_count = 1;
+ ble_conf.gap_cfg.role_count_cfg.periph_role_count = 2;
ble_conf.gap_cfg.role_count_cfg.central_role_count = 1;
err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_conf, app_ram_start);
- if (err_code != NRF_SUCCESS)
+ if (err_code != NRF_SUCCESS) {
return err_code;
+ }
memset(&ble_conf, 0, sizeof(ble_conf));
ble_conf.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM;
ble_conf.conn_cfg.params.gatts_conn_cfg.hvn_tx_queue_size = MAX_TX_IN_PROGRESS;
err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTS, &ble_conf, app_ram_start);
- if (err_code != NRF_SUCCESS)
+ if (err_code != NRF_SUCCESS) {
return err_code;
+ }
+ // Triple the GATT Server attribute size to accomodate both the CircuitPython built-in service
+ // and anything the user does.
+ memset(&ble_conf, 0, sizeof(ble_conf));
+ ble_conf.gatts_cfg.attr_tab_size.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT * 3;
+ err_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_conf, app_ram_start);
+ if (err_code != NRF_SUCCESS) {
+ return err_code;
+ }
+
+ // TODO set ATT_MTU so that the maximum MTU we can negotiate is higher than the default.
+
+ // This sets app_ram_start to the minimum value needed for the settings set above.
err_code = sd_ble_enable(&app_ram_start);
- if (err_code != NRF_SUCCESS)
+ if (err_code != NRF_SUCCESS) {
return err_code;
+ }
ble_gap_conn_params_t gap_conn_params = {
.min_conn_interval = BLE_MIN_CONN_INTERVAL,
@@ -131,11 +165,104 @@ STATIC uint32_t ble_stack_enable(void) {
return err_code;
}
-void common_hal_bleio_adapter_set_enabled(bool enabled) {
- const bool is_enabled = common_hal_bleio_adapter_get_enabled();
+STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
+ bleio_adapter_obj_t *self = (bleio_adapter_obj_t*)self_in;
+
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Adapter event: 0x%04x\n", ble_evt->header.evt_id);
+
+ switch (ble_evt->header.evt_id) {
+ case BLE_GAP_EVT_CONNECTED: {
+ // Find an empty connection. One must always be available because the SD has the same
+ // total connection limit.
+ bleio_connection_internal_t *connection;
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ connection = &connections[i];
+ if (connection->conn_handle == BLE_CONN_HANDLE_INVALID) {
+ break;
+ }
+ }
+
+ // Central has connected.
+ ble_gap_evt_connected_t* connected = &ble_evt->evt.gap_evt.params.connected;
+
+ connection->conn_handle = ble_evt->evt.gap_evt.conn_handle;
+ connection->connection_obj = mp_const_none;
+ connection->pair_status = PAIR_NOT_PAIRED;
+ ble_drv_add_event_handler_entry(&connection->handler_entry, connection_on_ble_evt, connection);
+ self->connection_objs = NULL;
+
+ // See if connection interval set by Central is out of range.
+ // If so, negotiate our preferred range.
+ ble_gap_conn_params_t conn_params;
+ sd_ble_gap_ppcp_get(&conn_params);
+ if (conn_params.min_conn_interval < connected->conn_params.min_conn_interval ||
+ conn_params.min_conn_interval > connected->conn_params.max_conn_interval) {
+ sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params);
+ }
+ self->current_advertising_data = NULL;
+ break;
+ }
+ case BLE_GAP_EVT_DISCONNECTED: {
+ // Find the connection that was disconnected.
+ bleio_connection_internal_t *connection;
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ connection = &connections[i];
+ if (connection->conn_handle == ble_evt->evt.gap_evt.conn_handle) {
+ break;
+ }
+ }
+ ble_drv_remove_event_handler(connection_on_ble_evt, connection);
+ connection->conn_handle = BLE_CONN_HANDLE_INVALID;
+ if (connection->connection_obj != mp_const_none) {
+ bleio_connection_obj_t* obj = connection->connection_obj;
+ obj->connection = NULL;
+ obj->disconnect_reason = ble_evt->evt.gap_evt.params.disconnected.reason;
+ }
+ self->connection_objs = NULL;
+
+ break;
+ }
+
+ case BLE_GAP_EVT_ADV_SET_TERMINATED:
+ self->current_advertising_data = NULL;
+ break;
+
+ default:
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Unhandled adapter event: 0x%04x\n", ble_evt->header.evt_id);
+ return false;
+ break;
+ }
+ return true;
+}
+
+STATIC void get_address(bleio_adapter_obj_t *self, ble_gap_addr_t *address) {
+ check_nrf_error(sd_ble_gap_addr_get(address));
+}
+
+char default_ble_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0, 0 , 0};
+
+STATIC void bleio_adapter_reset_name(bleio_adapter_obj_t *self) {
+ uint8_t len = sizeof(default_ble_name) - 1;
+
+ ble_gap_addr_t local_address;
+ get_address(self, &local_address);
+
+ default_ble_name[len - 4] = nibble_to_hex_lower[local_address.addr[1] >> 4 & 0xf];
+ default_ble_name[len - 3] = nibble_to_hex_lower[local_address.addr[1] & 0xf];
+ default_ble_name[len - 2] = nibble_to_hex_lower[local_address.addr[0] >> 4 & 0xf];
+ default_ble_name[len - 1] = nibble_to_hex_lower[local_address.addr[0] & 0xf];
+ default_ble_name[len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings
+
+ common_hal_bleio_adapter_set_name(self, (char*) default_ble_name);
+}
+
+void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enabled) {
+ const bool is_enabled = common_hal_bleio_adapter_get_enabled(self);
// Don't enable or disable twice
- if ((is_enabled && enabled) || (!is_enabled && !enabled)) {
+ if (is_enabled == enabled) {
return;
}
@@ -146,68 +273,370 @@ void common_hal_bleio_adapter_set_enabled(bool enabled) {
nrfx_power_uninit();
err_code = ble_stack_enable();
-
- // Re-init USB hardware
- init_usb_hardware();
} else {
err_code = sd_softdevice_disable();
+ }
+ // Re-init USB hardware
+ init_usb_hardware();
- // Re-init USB hardware
- init_usb_hardware();
+ check_nrf_error(err_code);
+
+ // Add a handler for incoming peripheral connections.
+ if (enabled) {
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connection_internal_t *connection = &connections[i];
+ connection->conn_handle = BLE_CONN_HANDLE_INVALID;
+ }
+ bleio_adapter_reset_name(self);
+ ble_drv_add_event_handler_entry(&self->handler_entry, adapter_on_ble_evt, self);
+ } else {
+ ble_drv_reset();
+ self->scan_results = NULL;
+ self->current_advertising_data = NULL;
+ self->advertising_data = NULL;
+ self->scan_response_data = NULL;
}
+}
+bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self) {
+ uint8_t is_enabled;
+
+ check_nrf_error(sd_softdevice_is_enabled(&is_enabled));
+
+ return is_enabled;
+}
+
+bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *self) {
+ common_hal_bleio_adapter_set_enabled(self, true);
+
+ ble_gap_addr_t local_address;
+ get_address(self, &local_address);
+
+ bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t);
+ address->base.type = &bleio_address_type;
+
+ common_hal_bleio_address_construct(address, local_address.addr, local_address.addr_type);
+ return address;
+}
+
+mp_obj_str_t* common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self) {
+ uint16_t len = 0;
+ sd_ble_gap_device_name_get(NULL, &len);
+ uint8_t buf[len];
+ uint32_t err_code = sd_ble_gap_device_name_get(buf, &len);
if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to change softdevice state"));
+ return NULL;
}
+ return mp_obj_new_str((char*) buf, len);
}
-bool common_hal_bleio_adapter_get_enabled(void) {
- uint8_t is_enabled;
+void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char* name) {
+ ble_gap_conn_sec_mode_t sec;
+ sec.lv = 0;
+ sec.sm = 0;
+ sd_ble_gap_device_name_set(&sec, (const uint8_t*) name, strlen(name));
+}
+
+STATIC bool scan_on_ble_evt(ble_evt_t *ble_evt, void *scan_results_in) {
+ bleio_scanresults_obj_t *scan_results = (bleio_scanresults_obj_t*)scan_results_in;
+
+ if (ble_evt->header.evt_id == BLE_GAP_EVT_TIMEOUT &&
+ ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN) {
+ shared_module_bleio_scanresults_set_done(scan_results, true);
+ ble_drv_remove_event_handler(scan_on_ble_evt, scan_results);
+ return true;
+ }
- const uint32_t err_code = sd_softdevice_is_enabled(&is_enabled);
+ if (ble_evt->header.evt_id != BLE_GAP_EVT_ADV_REPORT) {
+ return false;
+ }
+ ble_gap_evt_adv_report_t *report = &ble_evt->evt.gap_evt.params.adv_report;
+
+ shared_module_bleio_scanresults_append(scan_results,
+ supervisor_ticks_ms64(),
+ report->type.connectable,
+ report->type.scan_response,
+ report->rssi,
+ report->peer_addr.addr,
+ report->peer_addr.addr_type,
+ report->data.p_data,
+ report->data.len);
+
+ const uint32_t err_code = sd_ble_gap_scan_start(NULL, scan_results->common_hal_data);
if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to get softdevice state"));
+ // TODO: Pass the error into the scan results so it can throw an exception.
+ scan_results->done = true;
}
+ return true;
+}
- return is_enabled;
+mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t* prefixes, size_t prefix_length, bool extended, mp_int_t buffer_size, mp_float_t timeout, mp_float_t interval, mp_float_t window, mp_int_t minimum_rssi, bool active) {
+ if (self->scan_results != NULL) {
+ if (!shared_module_bleio_scanresults_get_done(self->scan_results)) {
+ mp_raise_bleio_BluetoothError(translate("Scan already in progess. Stop with stop_scan."));
+ }
+ self->scan_results = NULL;
+ }
+ self->scan_results = shared_module_bleio_new_scanresults(buffer_size, prefixes, prefix_length, minimum_rssi);
+ size_t max_packet_size = extended ? BLE_GAP_SCAN_BUFFER_EXTENDED_MAX_SUPPORTED : BLE_GAP_SCAN_BUFFER_MAX;
+ uint8_t *raw_data = m_malloc(sizeof(ble_data_t) + max_packet_size, false);
+ ble_data_t * sd_data = (ble_data_t *) raw_data;
+ self->scan_results->common_hal_data = sd_data;
+ sd_data->len = max_packet_size;
+ sd_data->p_data = raw_data + sizeof(ble_data_t);
+
+ ble_drv_add_event_handler(scan_on_ble_evt, self->scan_results);
+
+ uint32_t nrf_timeout = SEC_TO_UNITS(timeout, UNIT_10_MS);
+ if (timeout <= 0.0001) {
+ nrf_timeout = BLE_GAP_SCAN_TIMEOUT_UNLIMITED;
+ }
+
+ ble_gap_scan_params_t scan_params = {
+ .extended = extended,
+ .interval = SEC_TO_UNITS(interval, UNIT_0_625_MS),
+ .timeout = nrf_timeout,
+ .window = SEC_TO_UNITS(window, UNIT_0_625_MS),
+ .scan_phys = BLE_GAP_PHY_1MBPS,
+ .active = active
+ };
+ uint32_t err_code;
+ err_code = sd_ble_gap_scan_start(&scan_params, sd_data);
+
+ if (err_code != NRF_SUCCESS) {
+ self->scan_results = NULL;
+ ble_drv_remove_event_handler(scan_on_ble_evt, self->scan_results);
+ check_nrf_error(err_code);
+ }
+
+ return MP_OBJ_FROM_PTR(self->scan_results);
+}
+
+void common_hal_bleio_adapter_stop_scan(bleio_adapter_obj_t *self) {
+ sd_ble_gap_scan_stop();
+ shared_module_bleio_scanresults_set_done(self->scan_results, true);
+ ble_drv_remove_event_handler(scan_on_ble_evt, self->scan_results);
+ self->scan_results = NULL;
+}
+
+typedef struct {
+ uint16_t conn_handle;
+ volatile bool done;
+} connect_info_t;
+
+STATIC bool connect_on_ble_evt(ble_evt_t *ble_evt, void *info_in) {
+ connect_info_t *info = (connect_info_t*)info_in;
+
+ switch (ble_evt->header.evt_id) {
+ case BLE_GAP_EVT_CONNECTED:
+ info->conn_handle = ble_evt->evt.gap_evt.conn_handle;
+ info->done = true;
+
+ break;
+
+ case BLE_GAP_EVT_TIMEOUT:
+ // Handle will be invalid.
+ info->done = true;
+ break;
+ default:
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Unhandled central event: 0x%04x\n", ble_evt->header.evt_id);
+ return false;
+ break;
+ }
+ return true;
+}
+
+mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout) {
+
+ 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
+ };
+
+ connect_info_t event_info;
+ ble_drv_add_event_handler(connect_on_ble_evt, &event_info);
+ event_info.done = false;
+
+ uint32_t err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_CUSTOM);
+
+ if (err_code != NRF_SUCCESS) {
+ ble_drv_remove_event_handler(connect_on_ble_evt, &event_info);
+ check_nrf_error(err_code);
+ }
+
+ while (!event_info.done) {
+ RUN_BACKGROUND_TASKS;
+ }
+
+ ble_drv_remove_event_handler(connect_on_ble_evt, &event_info);
+
+ if (event_info.conn_handle == BLE_CONN_HANDLE_INVALID) {
+ mp_raise_bleio_BluetoothError(translate("Failed to connect: timeout"));
+ }
+
+ // Make the connection object and return it.
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connection_internal_t *connection = &connections[i];
+ if (connection->conn_handle == event_info.conn_handle) {
+ return bleio_connection_new_from_internal(connection);
+ }
+ }
+
+ mp_raise_bleio_BluetoothError(translate("Failed to connect: internal error"));
+
+ return mp_const_none;
+}
+
+// The nRF SD 6.1.0 can only do one concurrent advertisement so share the advertising handle.
+uint8_t adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
+
+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"));
+ }
}
-void get_address(ble_gap_addr_t *address) {
+uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, float interval, uint8_t *advertising_data, uint16_t advertising_data_len, uint8_t *scan_response_data, uint16_t scan_response_data_len) {
+ if (self->current_advertising_data != NULL && self->current_advertising_data == self->advertising_data) {
+ return NRF_ERROR_BUSY;
+ }
+
+ // If the current advertising data isn't owned by the adapter then it must be an internal
+ // advertisement that we should stop.
+ if (self->current_advertising_data != NULL) {
+ common_hal_bleio_adapter_stop_advertising(self);
+ }
+
uint32_t err_code;
+ 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,
+ };
+
+ const ble_gap_adv_data_t ble_gap_adv_data = {
+ .adv_data.p_data = advertising_data,
+ .adv_data.len = advertising_data_len,
+ .scan_rsp_data.p_data = scan_response_data_len > 0 ? scan_response_data : NULL,
+ .scan_rsp_data.len = scan_response_data_len,
+ };
- common_hal_bleio_adapter_set_enabled(true);
- err_code = sd_ble_gap_addr_get(address);
+ err_code = sd_ble_gap_adv_set_configure(&adv_handle, &ble_gap_adv_data, &adv_params);
+ if (err_code != NRF_SUCCESS) {
+ return err_code;
+ }
+ err_code = sd_ble_gap_adv_start(adv_handle, BLE_CONN_CFG_TAG_CUSTOM);
if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to get local address"));
+ return err_code;
}
+ self->current_advertising_data = advertising_data;
+ return NRF_SUCCESS;
}
-bleio_address_obj_t *common_hal_bleio_adapter_get_address(void) {
- common_hal_bleio_adapter_set_enabled(true);
- ble_gap_addr_t local_address;
- get_address(&local_address);
+void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, mp_float_t interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo) {
+ if (self->current_advertising_data != NULL && self->current_advertising_data == self->advertising_data) {
+ mp_raise_bleio_BluetoothError(translate("Already advertising."));
+ }
+ // interval value has already been validated.
+
+ check_data_fit(advertising_data_bufinfo->len);
+ check_data_fit(scan_response_data_bufinfo->len);
+ // The advertising data buffers must not move, because the SoftDevice depends on them.
+ // So make them long-lived and reuse them onwards.
+ if (self->advertising_data == NULL) {
+ self->advertising_data = (uint8_t *) gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_MAX * sizeof(uint8_t), false, true);
+ }
+ if (self->scan_response_data == NULL) {
+ self->scan_response_data = (uint8_t *) gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_MAX * sizeof(uint8_t), false, true);
+ }
- bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t);
- address->base.type = &bleio_address_type;
+ memcpy(self->advertising_data, advertising_data_bufinfo->buf, advertising_data_bufinfo->len);
+ memcpy(self->scan_response_data, scan_response_data_bufinfo->buf, scan_response_data_bufinfo->len);
- common_hal_bleio_address_construct(address, local_address.addr, local_address.addr_type);
- return address;
+ check_nrf_error(_common_hal_bleio_adapter_start_advertising(self, connectable, interval,
+ self->advertising_data,
+ advertising_data_bufinfo->len,
+ self->scan_response_data,
+ scan_response_data_bufinfo->len));
}
-mp_obj_t common_hal_bleio_adapter_get_default_name(void) {
- common_hal_bleio_adapter_set_enabled(true);
+void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) {
+ if (adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET)
+ return;
+
+ // TODO: Don't actually stop. Switch to advertising CircuitPython if we don't already have a connection.
+ const uint32_t err_code = sd_ble_gap_adv_stop(adv_handle);
+ self->current_advertising_data = NULL;
- ble_gap_addr_t local_address;
- get_address(&local_address);
+ if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) {
+ check_nrf_error(err_code);
+ }
+}
- char name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0, 0 };
+bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self) {
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connection_internal_t *connection = &connections[i];
+ if (connection->conn_handle != BLE_CONN_HANDLE_INVALID) {
+ return true;
+ }
+ }
+ return false;
+}
+
+mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) {
+ if (self->connection_objs != NULL) {
+ return self->connection_objs;
+ }
+ size_t total_connected = 0;
+ mp_obj_t items[BLEIO_TOTAL_CONNECTION_COUNT];
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connection_internal_t *connection = &connections[i];
+ if (connection->conn_handle != BLE_CONN_HANDLE_INVALID) {
+ if (connection->connection_obj == mp_const_none) {
+ connection->connection_obj = bleio_connection_new_from_internal(connection);
+ }
+ items[total_connected] = connection->connection_obj;
+ total_connected++;
+ }
+ }
+ self->connection_objs = mp_obj_new_tuple(total_connected, items);
+ return self->connection_objs;
+}
- name[sizeof(name) - 4] = nibble_to_hex_lower[local_address.addr[1] >> 4 & 0xf];
- name[sizeof(name) - 3] = nibble_to_hex_lower[local_address.addr[1] & 0xf];
- name[sizeof(name) - 2] = nibble_to_hex_lower[local_address.addr[0] >> 4 & 0xf];
- name[sizeof(name) - 1] = nibble_to_hex_lower[local_address.addr[0] & 0xf];
+void bleio_adapter_gc_collect(bleio_adapter_obj_t* adapter) {
+ gc_collect_root((void**)adapter, sizeof(bleio_adapter_obj_t) / sizeof(size_t));
+ gc_collect_root((void**)connections, sizeof(connections) / sizeof(size_t));
+}
- return mp_obj_new_str(name, sizeof(name));
+void bleio_adapter_reset(bleio_adapter_obj_t* adapter) {
+ common_hal_bleio_adapter_stop_scan(adapter);
+ common_hal_bleio_adapter_stop_advertising(adapter);
+ adapter->connection_objs = NULL;
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connection_internal_t *connection = &connections[i];
+ connection->connection_obj = mp_const_none;
+ }
}
diff --git a/ports/nrf/common-hal/_bleio/Adapter.h b/ports/nrf/common-hal/_bleio/Adapter.h
index 5dcc62540..dca443990 100644
--- a/ports/nrf/common-hal/_bleio/Adapter.h
+++ b/ports/nrf/common-hal/_bleio/Adapter.h
@@ -30,9 +30,27 @@
#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ADAPTER_H
#include "py/obj.h"
+#include "py/objtuple.h"
+
+#include "shared-bindings/_bleio/Connection.h"
+#include "shared-bindings/_bleio/ScanResults.h"
+
+#define BLEIO_TOTAL_CONNECTION_COUNT 2
+
+extern bleio_connection_internal_t connections[BLEIO_TOTAL_CONNECTION_COUNT];
typedef struct {
mp_obj_base_t base;
-} super_adapter_obj_t;
+ uint8_t* advertising_data;
+ uint8_t* scan_response_data;
+ uint8_t* current_advertising_data;
+ bleio_scanresults_obj_t* scan_results;
+ mp_obj_t name;
+ mp_obj_tuple_t *connection_objs;
+ ble_drv_evt_handler_entry_t handler_entry;
+} bleio_adapter_obj_t;
+
+void bleio_adapter_gc_collect(bleio_adapter_obj_t* adapter);
+void bleio_adapter_reset(bleio_adapter_obj_t* adapter);
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ADAPTER_H
diff --git a/ports/nrf/common-hal/_bleio/Central.c b/ports/nrf/common-hal/_bleio/Central.c
deleted file mode 100644
index db67b763c..000000000
--- a/ports/nrf/common-hal/_bleio/Central.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <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/__init__.h"
-#include "shared-bindings/_bleio/Adapter.h"
-#include "shared-bindings/_bleio/Central.h"
-
-STATIC void central_on_ble_evt(ble_evt_t *ble_evt, void *central_in) {
- bleio_central_obj_t *central = (bleio_central_obj_t*)central_in;
-
- switch (ble_evt->header.evt_id) {
- case BLE_GAP_EVT_CONNECTED:
- central->conn_handle = ble_evt->evt.gap_evt.conn_handle;
- central->waiting_to_connect = false;
- break;
-
- case BLE_GAP_EVT_TIMEOUT:
- // Handle will be invalid.
- central->waiting_to_connect = false;
- break;
-
- case BLE_GAP_EVT_DISCONNECTED:
- central->conn_handle = BLE_CONN_HANDLE_INVALID;
- break;
-
- case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
- sd_ble_gap_sec_params_reply(central->conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
- break;
-
- case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: {
- ble_gap_evt_conn_param_update_request_t *request =
- &ble_evt->evt.gap_evt.params.conn_param_update_request;
- sd_ble_gap_conn_param_update(central->conn_handle, &request->conn_params);
- break;
- }
- default:
- // For debugging.
- // mp_printf(&mp_plat_print, "Unhandled central event: 0x%04x\n", ble_evt->header.evt_id);
- break;
- }
-}
-
-void common_hal_bleio_central_construct(bleio_central_obj_t *self) {
- common_hal_bleio_adapter_set_enabled(true);
-
- self->remote_service_list = mp_obj_new_list(0, NULL);
- self->conn_handle = BLE_CONN_HANDLE_INVALID;
-}
-
-void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout) {
- common_hal_bleio_adapter_set_enabled(true);
- ble_drv_add_event_handler(central_on_ble_evt, self);
-
- ble_gap_addr_t addr;
-
- addr.addr_type = address->type;
- mp_buffer_info_t address_buf_info;
- mp_get_buffer_raise(address->bytes, &address_buf_info, MP_BUFFER_READ);
- memcpy(addr.addr, (uint8_t *) address_buf_info.buf, NUM_BLEIO_ADDRESS_BYTES);
-
- ble_gap_scan_params_t scan_params = {
- .interval = MSEC_TO_UNITS(100, UNIT_0_625_MS),
- .window = MSEC_TO_UNITS(100, UNIT_0_625_MS),
- .scan_phys = BLE_GAP_PHY_1MBPS,
- // timeout of 0 means no timeout
- .timeout = SEC_TO_UNITS(timeout, UNIT_10_MS),
- };
-
- ble_gap_conn_params_t conn_params = {
- .conn_sup_timeout = MSEC_TO_UNITS(4000, UNIT_10_MS),
- .min_conn_interval = MSEC_TO_UNITS(15, UNIT_1_25_MS),
- .max_conn_interval = MSEC_TO_UNITS(300, UNIT_1_25_MS),
- .slave_latency = 0, // number of conn events
- };
-
- self->waiting_to_connect = true;
-
- uint32_t err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_CUSTOM);
-
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to start connecting, error 0x%04x"), err_code);
- }
-
- while (self->waiting_to_connect) {
- RUN_BACKGROUND_TASKS;
- }
-
- if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
- mp_raise_OSError_msg(translate("Failed to connect: timeout"));
- }
-}
-
-void common_hal_bleio_central_disconnect(bleio_central_obj_t *self) {
- sd_ble_gap_disconnect(self->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
-}
-
-bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self) {
- return self->conn_handle != BLE_CONN_HANDLE_INVALID;
-}
-
-mp_obj_tuple_t *common_hal_bleio_central_discover_remote_services(bleio_central_obj_t *self, mp_obj_t service_uuids_whitelist) {
- common_hal_bleio_device_discover_remote_services(MP_OBJ_FROM_PTR(self), service_uuids_whitelist);
- // Convert to a tuple and then clear the list so the callee will take ownership.
- mp_obj_tuple_t *services_tuple = mp_obj_new_tuple(self->remote_service_list->len,
- self->remote_service_list->items);
- mp_obj_list_clear(self->remote_service_list);
- return services_tuple;
-}
-
-mp_obj_list_t *common_hal_bleio_central_get_remote_services(bleio_central_obj_t *self) {
- return self->remote_service_list;
-}
diff --git a/ports/nrf/common-hal/_bleio/Characteristic.c b/ports/nrf/common-hal/_bleio/Characteristic.c
index e8454d528..9f1255e32 100644
--- a/ports/nrf/common-hal/_bleio/Characteristic.c
+++ b/ports/nrf/common-hal/_bleio/Characteristic.c
@@ -32,7 +32,7 @@
#include "shared-bindings/_bleio/Descriptor.h"
#include "shared-bindings/_bleio/Service.h"
-static volatile bleio_characteristic_obj_t *m_read_characteristic;
+#include "common-hal/_bleio/Adapter.h"
STATIC uint16_t characteristic_get_cccd(uint16_t cccd_handle, uint16_t conn_handle) {
uint16_t cccd;
@@ -46,34 +46,13 @@ STATIC uint16_t characteristic_get_cccd(uint16_t cccd_handle, uint16_t conn_hand
if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING) {
// CCCD is not set, so say that neither Notify nor Indicate is enabled.
cccd = 0;
- } else if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to read CCCD value, err 0x%04x"), err_code);
+ } else {
+ check_nrf_error(err_code);
}
return cccd;
}
-STATIC void characteristic_on_gattc_read_rsp_evt(ble_evt_t *ble_evt, void *param) {
- switch (ble_evt->header.evt_id) {
-
- // More events may be handled later, so keep this as a switch.
-
- case BLE_GATTC_EVT_READ_RSP: {
- ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp;
- if (m_read_characteristic) {
- m_read_characteristic->value = mp_obj_new_bytearray(response->len, response->data);
- }
- // Indicate to busy-wait loop that we've read the attribute value.
- m_read_characteristic = NULL;
- break;
- }
-
- default:
- // For debugging.
- // mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id);
- break;
- }
-}
STATIC void characteristic_gatts_notify_indicate(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, uint16_t hvx_type) {
uint16_t hvx_len = bufinfo->len;
@@ -99,39 +78,18 @@ STATIC void characteristic_gatts_notify_indicate(uint16_t handle, uint16_t conn_
}
// Some real error has occurred.
- mp_raise_OSError_msg_varg(translate("Failed to notify or indicate attribute value, err 0x%04x"), err_code);
- }
-}
-
-STATIC void characteristic_gattc_read(bleio_characteristic_obj_t *characteristic) {
- const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device);
- common_hal_bleio_check_connected(conn_handle);
-
- // Set to NULL in event loop after event.
- m_read_characteristic = characteristic;
-
- ble_drv_add_event_handler(characteristic_on_gattc_read_rsp_evt, characteristic);
-
- const uint32_t err_code = sd_ble_gattc_read(conn_handle, characteristic->handle, 0);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to read attribute value, err 0x%04x"), err_code);
+ check_nrf_error(err_code);
}
-
- while (m_read_characteristic != NULL) {
- RUN_BACKGROUND_TASKS;
- }
-
- ble_drv_remove_event_handler(characteristic_on_gattc_read_rsp_evt, characteristic);
}
-void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo) {
+void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, uint16_t handle, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo) {
self->service = service;
self->uuid = uuid;
self->handle = BLE_GATT_HANDLE_INVALID;
self->props = props;
self->read_perm = read_perm;
self->write_perm = write_perm;
- self->descriptor_list = mp_obj_new_list(0, NULL);
+ self->descriptor_list = NULL;
const mp_int_t max_length_max = fixed_length ? BLE_GATTS_FIX_ATTR_LEN_MAX : BLE_GATTS_VAR_ATTR_LEN_MAX;
if (max_length < 0 || max_length > max_length_max) {
@@ -141,10 +99,18 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self,
self->max_length = max_length;
self->fixed_length = fixed_length;
- common_hal_bleio_characteristic_set_value(self, initial_value_bufinfo);
+ if (service->is_remote) {
+ self->handle = handle;
+ } else {
+ common_hal_bleio_service_add_characteristic(self->service, self, initial_value_bufinfo);
+ }
+
+ if (initial_value_bufinfo != NULL) {
+ common_hal_bleio_characteristic_set_value(self, initial_value_bufinfo);
+ }
}
-mp_obj_list_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self) {
+bleio_descriptor_obj_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self) {
return self->descriptor_list;
}
@@ -152,19 +118,19 @@ bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_character
return self->service;
}
-mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self) {
+size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t* buf, size_t len) {
// Do GATT operations only if this characteristic has been added to a registered service.
if (self->handle != BLE_GATT_HANDLE_INVALID) {
- uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device);
+ uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
if (common_hal_bleio_service_get_is_remote(self->service)) {
// self->value is set by evt handler.
- characteristic_gattc_read(self);
+ return common_hal_bleio_gattc_read(self->handle, conn_handle, buf, len);
} else {
- self->value = common_hal_bleio_gatts_read(self->handle, conn_handle);
+ return common_hal_bleio_gatts_read(self->handle, conn_handle, buf, len);
}
}
- return self->value;
+ return 0;
}
void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) {
@@ -175,39 +141,40 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self,
mp_raise_ValueError(translate("Value length > max_length"));
}
- self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len);
-
// Do GATT operations only if this characteristic has been added to a registered service.
if (self->handle != BLE_GATT_HANDLE_INVALID) {
- uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device);
if (common_hal_bleio_service_get_is_remote(self->service)) {
+ uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
// Last argument is true if write-no-reponse desired.
common_hal_bleio_gattc_write(self->handle, conn_handle, bufinfo,
(self->props & CHAR_PROP_WRITE_NO_RESPONSE));
} else {
-
- bool sent = false;
- uint16_t cccd = 0;
-
- const bool notify = self->props & CHAR_PROP_NOTIFY;
- const bool indicate = self->props & CHAR_PROP_INDICATE;
- if (notify | indicate) {
- cccd = characteristic_get_cccd(self->cccd_handle, conn_handle);
- }
-
- // It's possible that both notify and indicate are set.
- if (notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) {
- characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_NOTIFICATION);
- sent = true;
- }
- if (indicate && (cccd & BLE_GATT_HVX_INDICATION)) {
- characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_INDICATION);
- sent = true;
- }
-
- if (!sent) {
- common_hal_bleio_gatts_write(self->handle, conn_handle, bufinfo);
+ // Always write the value locally even if no connections are active.
+ common_hal_bleio_gatts_write(self->handle, BLE_CONN_HANDLE_INVALID, bufinfo);
+ // Check to see if we need to notify or indicate any active connections.
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connection_internal_t *connection = &connections[i];
+ uint16_t conn_handle = connection->conn_handle;
+ if (connection->conn_handle == BLE_CONN_HANDLE_INVALID) {
+ continue;
+ }
+
+ uint16_t cccd = 0;
+
+ const bool notify = self->props & CHAR_PROP_NOTIFY;
+ const bool indicate = self->props & CHAR_PROP_INDICATE;
+ if (notify | indicate) {
+ cccd = characteristic_get_cccd(self->cccd_handle, conn_handle);
+ }
+
+ // It's possible that both notify and indicate are set.
+ if (notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) {
+ characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_NOTIFICATION);
+ }
+ if (indicate && (cccd & BLE_GATT_HVX_INDICATION)) {
+ characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_INDICATION);
+ }
}
}
}
@@ -246,25 +213,22 @@ void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *
.max_len = descriptor->max_length,
};
- uint32_t err_code = sd_ble_gatts_descriptor_add(self->handle, &desc_attr, &descriptor->handle);
-
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to add descriptor, err 0x%04x"), err_code);
- }
+ check_nrf_error(sd_ble_gatts_descriptor_add(self->handle, &desc_attr, &descriptor->handle));
- mp_obj_list_append(self->descriptor_list, MP_OBJ_FROM_PTR(descriptor));
+ descriptor->next = self->descriptor_list;
+ self->descriptor_list = descriptor;
}
void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate) {
if (self->cccd_handle == BLE_GATT_HANDLE_INVALID) {
- mp_raise_ValueError(translate("No CCCD for this Characteristic"));
+ mp_raise_bleio_BluetoothError(translate("No CCCD for this Characteristic"));
}
if (!common_hal_bleio_service_get_is_remote(self->service)) {
- mp_raise_ValueError(translate("Can't set CCCD on local Characteristic"));
+ mp_raise_bleio_RoleError(translate("Can't set CCCD on local Characteristic"));
}
- const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device);
+ const uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
common_hal_bleio_check_connected(conn_handle);
uint16_t cccd_value =
@@ -293,7 +257,7 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self,
}
// Some real error occurred.
- mp_raise_OSError_msg_varg(translate("Failed to write CCCD, err 0x%04x"), err_code);
+ check_nrf_error(err_code);
}
}
diff --git a/ports/nrf/common-hal/_bleio/Characteristic.h b/ports/nrf/common-hal/_bleio/Characteristic.h
index 3a7691d07..bb8f28495 100644
--- a/ports/nrf/common-hal/_bleio/Characteristic.h
+++ b/ports/nrf/common-hal/_bleio/Characteristic.h
@@ -29,11 +29,12 @@
#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTIC_H
#include "shared-bindings/_bleio/Attribute.h"
+#include "common-hal/_bleio/Descriptor.h"
#include "shared-module/_bleio/Characteristic.h"
#include "common-hal/_bleio/Service.h"
#include "common-hal/_bleio/UUID.h"
-typedef struct {
+typedef struct _bleio_characteristic_obj {
mp_obj_base_t base;
// Will be MP_OBJ_NULL before being assigned to a Service.
bleio_service_obj_t *service;
@@ -45,7 +46,7 @@ typedef struct {
bleio_characteristic_properties_t props;
bleio_attribute_security_mode_t read_perm;
bleio_attribute_security_mode_t write_perm;
- mp_obj_list_t *descriptor_list;
+ bleio_descriptor_obj_t *descriptor_list;
uint16_t user_desc_handle;
uint16_t cccd_handle;
uint16_t sccd_handle;
diff --git a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c
index 95794feec..9f9b453de 100644
--- a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c
+++ b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c
@@ -38,6 +38,8 @@
#include "tick.h"
#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Connection.h"
+#include "supervisor/shared/tick.h"
#include "common-hal/_bleio/CharacteristicBuffer.h"
STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *data, uint16_t len) {
@@ -50,7 +52,7 @@ STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *d
sd_nvic_critical_region_exit(is_nested_critical_region);
}
-STATIC void characteristic_buffer_on_ble_evt(ble_evt_t *ble_evt, void *param) {
+STATIC bool 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: {
@@ -75,7 +77,11 @@ STATIC void characteristic_buffer_on_ble_evt(ble_evt_t *ble_evt, void *param) {
}
break;
}
+ default:
+ return false;
+ break;
}
+ return true;
}
// Assumes that timeout and buffer_size have been validated before call.
@@ -95,10 +101,10 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe
}
int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode) {
- uint64_t start_ticks = ticks_ms;
+ uint64_t start_ticks = supervisor_ticks_ms64();
// Wait for all bytes received or timeout
- while ( (ringbuf_count(&self->ringbuf) < len) && (ticks_ms - start_ticks < self->timeout_ms) ) {
+ while ( (ringbuf_count(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS;
// Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) {
@@ -150,6 +156,7 @@ void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_o
bool common_hal_bleio_characteristic_buffer_connected(bleio_characteristic_buffer_obj_t *self) {
return self->characteristic != NULL &&
self->characteristic->service != NULL &&
- self->characteristic->service->device != NULL &&
- common_hal_bleio_device_get_conn_handle(self->characteristic->service->device) != BLE_CONN_HANDLE_INVALID;
+ (!self->characteristic->service->is_remote ||
+ (self->characteristic->service->connection != MP_OBJ_NULL &&
+ common_hal_bleio_connection_get_connected(self->characteristic->service->connection)));
}
diff --git a/ports/nrf/common-hal/_bleio/Connection.c b/ports/nrf/common-hal/_bleio/Connection.c
new file mode 100644
index 000000000..0e1e187c2
--- /dev/null
+++ b/ports/nrf/common-hal/_bleio/Connection.c
@@ -0,0 +1,630 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "shared-bindings/_bleio/Connection.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#include "ble.h"
+#include "ble_drv.h"
+#include "ble_hci.h"
+#include "nrf_soc.h"
+#include "lib/utils/interrupt_char.h"
+#include "py/gc.h"
+#include "py/objlist.h"
+#include "py/objstr.h"
+#include "py/qstr.h"
+#include "py/runtime.h"
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Adapter.h"
+#include "shared-bindings/_bleio/Attribute.h"
+#include "shared-bindings/_bleio/Characteristic.h"
+#include "shared-bindings/_bleio/Service.h"
+#include "shared-bindings/_bleio/UUID.h"
+
+#define BLE_ADV_LENGTH_FIELD_SIZE 1
+#define BLE_ADV_AD_TYPE_FIELD_SIZE 1
+#define BLE_AD_TYPE_FLAGS_DATA_SIZE 1
+
+static const ble_gap_sec_params_t pairing_sec_params = {
+ .bond = 0,
+ .mitm = 0,
+ .lesc = 0,
+ .keypress = 0,
+ .oob = 0,
+ .io_caps = BLE_GAP_IO_CAPS_NONE,
+ .min_key_size = 7,
+ .max_key_size = 16,
+ .kdist_own = { .enc = 1, .id = 1},
+ .kdist_peer = { .enc = 1, .id = 1},
+};
+
+static volatile bool m_discovery_in_process;
+static volatile bool m_discovery_successful;
+
+static bleio_service_obj_t *m_char_discovery_service;
+static bleio_characteristic_obj_t *m_desc_discovery_characteristic;
+
+bool dump_events = false;
+
+bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
+ bleio_connection_internal_t *self = (bleio_connection_internal_t*)self_in;
+
+ if (BLE_GAP_EVT_BASE <= ble_evt->header.evt_id && ble_evt->header.evt_id <= BLE_GAP_EVT_LAST &&
+ ble_evt->evt.gap_evt.conn_handle != self->conn_handle) {
+ return false;
+ }
+ if (BLE_GATTS_EVT_BASE <= ble_evt->header.evt_id && ble_evt->header.evt_id <= BLE_GATTS_EVT_LAST &&
+ ble_evt->evt.gatts_evt.conn_handle != self->conn_handle) {
+ return false;
+ }
+
+ // For debugging.
+ if (dump_events) {
+ mp_printf(&mp_plat_print, "Connection event: 0x%04x\n", ble_evt->header.evt_id);
+ }
+
+ switch (ble_evt->header.evt_id) {
+ case BLE_GAP_EVT_DISCONNECTED:
+ break;
+ case BLE_GAP_EVT_CONN_PARAM_UPDATE: // 0x12
+ 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_PHY_UPDATE: // 0x22
+ break;
+
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
+ // SoftDevice will respond to a length update request.
+ sd_ble_gap_data_length_update(self->conn_handle, NULL, NULL);
+ break;
+
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE: // 0x24
+ break;
+
+ case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: {
+ // We only handle MTU of size BLE_GATT_ATT_MTU_DEFAULT.
+ sd_ble_gatts_exchange_mtu_reply(self->conn_handle, BLE_GATT_ATT_MTU_DEFAULT);
+ break;
+ }
+
+ case BLE_GATTS_EVT_SYS_ATTR_MISSING:
+ sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
+ break;
+
+ case BLE_GATTS_EVT_HVN_TX_COMPLETE: // Capture this for now. 0x55
+ 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_SEC_PARAMS_REQUEST: {
+ ble_gap_sec_keyset_t keyset = {
+ .keys_own = {
+ .p_enc_key = &self->bonding_keys.own_enc,
+ .p_id_key = NULL,
+ .p_sign_key = NULL,
+ .p_pk = NULL
+ },
+
+ .keys_peer = {
+ .p_enc_key = &self->bonding_keys.peer_enc,
+ .p_id_key = &self->bonding_keys.peer_id,
+ .p_sign_key = NULL,
+ .p_pk = NULL
+ }
+ };
+
+ sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_SUCCESS,
+ &pairing_sec_params, &keyset);
+ break;
+ }
+
+ case BLE_GAP_EVT_LESC_DHKEY_REQUEST:
+ // TODO for LESC pairing:
+ // sd_ble_gap_lesc_dhkey_reply(...);
+ break;
+
+ case BLE_GAP_EVT_AUTH_STATUS: { // 0x19
+ // Pairing process completed
+ ble_gap_evt_auth_status_t* status = &ble_evt->evt.gap_evt.params.auth_status;
+ self->sec_status = status->auth_status;
+ if (status->auth_status == BLE_GAP_SEC_STATUS_SUCCESS) {
+ // TODO _ediv = bonding_keys->own_enc.master_id.ediv;
+ self->pair_status = PAIR_PAIRED;
+ } else {
+ self->pair_status = PAIR_NOT_PAIRED;
+ }
+ break;
+ }
+
+ case BLE_GAP_EVT_SEC_INFO_REQUEST: { // 0x14
+ // Peer asks for the stored keys.
+ // - load key and return if bonded previously.
+ // - Else return NULL --> Initiate key exchange
+ ble_gap_evt_sec_info_request_t* sec_info_request = &ble_evt->evt.gap_evt.params.sec_info_request;
+ (void) sec_info_request;
+ //if ( bond_load_keys(_role, sec_req->master_id.ediv, &bkeys) ) {
+ //sd_ble_gap_sec_info_reply(_conn_hdl, &bkeys.own_enc.enc_info, &bkeys.peer_id.id_info, NULL);
+ //
+ //_ediv = bkeys.own_enc.master_id.ediv;
+ // } else {
+ sd_ble_gap_sec_info_reply(self->conn_handle, NULL, NULL, NULL);
+ // }
+ break;
+ }
+
+ case BLE_GAP_EVT_CONN_SEC_UPDATE: { // 0x1a
+ ble_gap_conn_sec_t* conn_sec = &ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec;
+ if (conn_sec->sec_mode.sm <= 1 && conn_sec->sec_mode.lv <= 1) {
+ // Security setup did not succeed:
+ // mode 0, level 0 means no access
+ // mode 1, level 1 means open link
+ // mode >=1 and/or level >=1 means encryption is set up
+ self->pair_status = PAIR_NOT_PAIRED;
+ } else {
+ //if ( !bond_load_cccd(_role, _conn_hdl, _ediv) ) {
+ if (true) { // TODO: no bonding yet
+ // Initialize system attributes fresh.
+ sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
+ }
+ // Not quite paired yet: wait for BLE_GAP_EVT_AUTH_STATUS SUCCESS.
+ self->ediv = self->bonding_keys.own_enc.master_id.ediv;
+ }
+ break;
+ }
+
+
+ default:
+ // For debugging.
+ if (dump_events) {
+ mp_printf(&mp_plat_print, "Unhandled connection event: 0x%04x\n", ble_evt->header.evt_id);
+ }
+
+ return false;
+ }
+ return true;
+}
+
+void bleio_connection_clear(bleio_connection_internal_t *self) {
+ self->remote_service_list = NULL;
+
+ self->conn_handle = BLE_CONN_HANDLE_INVALID;
+ self->pair_status = PAIR_NOT_PAIRED;
+
+ memset(&self->bonding_keys, 0, sizeof(self->bonding_keys));
+}
+
+bool common_hal_bleio_connection_get_paired(bleio_connection_obj_t *self) {
+ if (self->connection == NULL) {
+ return false;
+ }
+ return self->connection->pair_status == PAIR_PAIRED;
+}
+
+bool common_hal_bleio_connection_get_connected(bleio_connection_obj_t *self) {
+ if (self->connection == NULL) {
+ return false;
+ }
+ return self->connection->conn_handle != BLE_CONN_HANDLE_INVALID;
+}
+
+void common_hal_bleio_connection_disconnect(bleio_connection_internal_t *self) {
+ sd_ble_gap_disconnect(self->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+}
+
+void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, bool bond) {
+ self->pair_status = PAIR_WAITING;
+
+ check_nrf_error(sd_ble_gap_authenticate(self->conn_handle, &pairing_sec_params));
+
+ while (self->pair_status == PAIR_WAITING && !mp_hal_is_interrupted()) {
+ RUN_BACKGROUND_TASKS;
+ }
+ if (mp_hal_is_interrupted()) {
+ return;
+ }
+ check_sec_status(self->sec_status);
+}
+
+
+// service_uuid may be NULL, to discover all services.
+STATIC bool discover_next_services(bleio_connection_internal_t* connection, uint16_t start_handle, ble_uuid_t *service_uuid) {
+ m_discovery_successful = false;
+ m_discovery_in_process = true;
+
+ check_nrf_error(sd_ble_gattc_primary_services_discover(connection->conn_handle,
+ start_handle, service_uuid));
+
+ // Wait for a discovery event.
+ while (m_discovery_in_process) {
+ MICROPY_VM_HOOK_LOOP;
+ }
+ return m_discovery_successful;
+}
+
+STATIC bool discover_next_characteristics(bleio_connection_internal_t* connection, 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(connection->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_connection_internal_t* connection, 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(connection->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_connection_internal_t* connection) {
+ bleio_service_obj_t* tail = connection->remote_service_list;
+
+ 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.
+ bleio_service_from_connection(service, bleio_connection_new_from_internal(connection));
+
+ service->is_remote = true;
+ service->start_handle = gattc_service->handle_range.start_handle;
+ service->end_handle = gattc_service->handle_range.end_handle;
+ service->handle = gattc_service->handle_range.start_handle;
+
+ if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
+ // Known service UUID.
+ bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t);
+ uuid->base.type = &bleio_uuid_type;
+ bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid);
+ service->uuid = uuid;
+ } else {
+ // The discovery response contained a 128-bit UUID that has not yet been registered with the
+ // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
+ // For now, just set the UUID to NULL.
+ service->uuid = NULL;
+ }
+
+ service->next = tail;
+ tail = service;
+ }
+
+ connection->remote_service_list = tail;
+
+ 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_connection_internal_t* connection) {
+ for (size_t i = 0; i < response->count; ++i) {
+ ble_gattc_char_t *gattc_char = &response->chars[i];
+
+ bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t);
+ characteristic->base.type = &bleio_characteristic_type;
+
+ bleio_uuid_obj_t *uuid = NULL;
+
+ if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
+ // Known characteristic UUID.
+ uuid = m_new_obj(bleio_uuid_obj_t);
+ uuid->base.type = &bleio_uuid_type;
+ bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid);
+ } else {
+ // The discovery response contained a 128-bit UUID that has not yet been registered with the
+ // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
+ // For now, just leave the UUID as NULL.
+ }
+
+ bleio_characteristic_properties_t props =
+ (gattc_char->char_props.broadcast ? CHAR_PROP_BROADCAST : 0) |
+ (gattc_char->char_props.indicate ? CHAR_PROP_INDICATE : 0) |
+ (gattc_char->char_props.notify ? CHAR_PROP_NOTIFY : 0) |
+ (gattc_char->char_props.read ? CHAR_PROP_READ : 0) |
+ (gattc_char->char_props.write ? CHAR_PROP_WRITE : 0) |
+ (gattc_char->char_props.write_wo_resp ? CHAR_PROP_WRITE_NO_RESPONSE : 0);
+
+ // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler.
+ common_hal_bleio_characteristic_construct(
+ characteristic, m_char_discovery_service, gattc_char->handle_value, uuid,
+ props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN,
+ GATT_MAX_DATA_LENGTH, false, // max_length, fixed_length: values may not matter for gattc
+ NULL);
+
+ 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_connection_internal_t* connection) {
+ for (size_t i = 0; i < response->count; ++i) {
+ ble_gattc_desc_t *gattc_desc = &response->descs[i];
+
+ // Remember handles for certain well-known descriptors.
+ switch (gattc_desc->uuid.uuid) {
+ case BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG:
+ m_desc_discovery_characteristic->cccd_handle = gattc_desc->handle;
+ break;
+
+ case BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG:
+ m_desc_discovery_characteristic->sccd_handle = gattc_desc->handle;
+ break;
+
+ case BLE_UUID_DESCRIPTOR_CHAR_USER_DESC:
+ m_desc_discovery_characteristic->user_desc_handle = gattc_desc->handle;
+ break;
+
+ default:
+ // TODO: sd_ble_gattc_descriptors_discover() can return things that are not descriptors,
+ // so ignore those.
+ // https://devzone.nordicsemi.com/f/nordic-q-a/49500/sd_ble_gattc_descriptors_discover-is-returning-attributes-that-are-not-descriptors
+ break;
+ }
+
+ bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t);
+ descriptor->base.type = &bleio_descriptor_type;
+
+ bleio_uuid_obj_t *uuid = NULL;
+
+ if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
+ // Known descriptor UUID.
+ uuid = m_new_obj(bleio_uuid_obj_t);
+ uuid->base.type = &bleio_uuid_type;
+ bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid);
+ } else {
+ // The discovery response contained a 128-bit UUID that has not yet been registered with the
+ // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
+ // For now, just leave the UUID as NULL.
+ }
+
+ common_hal_bleio_descriptor_construct(
+ descriptor, m_desc_discovery_characteristic, uuid,
+ SECURITY_MODE_OPEN, SECURITY_MODE_OPEN,
+ GATT_MAX_DATA_LENGTH, false, mp_const_empty_bytes);
+ descriptor->handle = gattc_desc->handle;
+
+ mp_obj_list_append(m_desc_discovery_characteristic->descriptor_list, MP_OBJ_FROM_PTR(descriptor));
+ }
+
+ if (response->count > 0) {
+ m_discovery_successful = true;
+ }
+ m_discovery_in_process = false;
+}
+
+STATIC bool discovery_on_ble_evt(ble_evt_t *ble_evt, mp_obj_t payload) {
+ bleio_connection_internal_t* connection = MP_OBJ_TO_PTR(payload);
+ switch (ble_evt->header.evt_id) {
+ case BLE_GAP_EVT_DISCONNECTED:
+ m_discovery_successful = false;
+ m_discovery_in_process = false;
+ break;
+
+ case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
+ on_primary_srv_discovery_rsp(&ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp, connection);
+ break;
+
+ case BLE_GATTC_EVT_CHAR_DISC_RSP:
+ on_char_discovery_rsp(&ble_evt->evt.gattc_evt.params.char_disc_rsp, connection);
+ break;
+
+ case BLE_GATTC_EVT_DESC_DISC_RSP:
+ on_desc_discovery_rsp(&ble_evt->evt.gattc_evt.params.desc_disc_rsp, connection);
+ break;
+
+ default:
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Unhandled discovery event: 0x%04x\n", ble_evt->header.evt_id);
+ return false;
+ break;
+ }
+ return true;
+}
+
+STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t service_uuids_whitelist) {
+ ble_drv_add_event_handler(discovery_on_ble_evt, self);
+
+ // Start over with an empty list.
+ self->remote_service_list = NULL;
+
+ if (service_uuids_whitelist == mp_const_none) {
+ // List of service UUID's not given, so discover all available services.
+
+ uint16_t next_service_start_handle = BLE_GATT_HANDLE_START;
+
+ while (discover_next_services(self, next_service_start_handle, MP_OBJ_NULL)) {
+ // discover_next_services() appends to remote_services_list.
+
+ // Get the most recently discovered service, and then ask for services
+ // whose handles start after the last attribute handle inside that service.
+ const bleio_service_obj_t *service = self->remote_service_list;
+ next_service_start_handle = service->end_handle + 1;
+ }
+ } else {
+ mp_obj_iter_buf_t iter_buf;
+ mp_obj_t iterable = mp_getiter(service_uuids_whitelist, &iter_buf);
+ mp_obj_t uuid_obj;
+ while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
+ if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
+ mp_raise_TypeError(translate("non-UUID found in service_uuids_whitelist"));
+ }
+ bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj);
+
+ ble_uuid_t nrf_uuid;
+ bleio_uuid_convert_to_nrf_ble_uuid(uuid, &nrf_uuid);
+
+ // Service might or might not be discovered; that's ok. Caller has to check
+ // Central.remote_services to find out.
+ // We only need to call this once for each service to discover.
+ discover_next_services(self, BLE_GATT_HANDLE_START, &nrf_uuid);
+ }
+ }
+
+
+ bleio_service_obj_t *service = self->remote_service_list;
+ while (service != NULL) {
+ // Skip the service if it had an unknown (unregistered) UUID.
+ if (service->uuid == NULL) {
+ service = service->next;
+ 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 = characteristic->descriptor_list;
+ next_desc_start_handle = descriptor->handle + 1;
+ }
+ }
+ service = service->next;
+ }
+
+ // This event handler is no longer needed.
+ ble_drv_remove_event_handler(discovery_on_ble_evt, self);
+
+}
+mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist) {
+ discover_remote_services(self->connection, service_uuids_whitelist);
+ // Convert to a tuple and then clear the list so the callee will take ownership.
+ mp_obj_tuple_t *services_tuple = service_linked_list_to_tuple(self->connection->remote_service_list);
+ self->connection->remote_service_list = NULL;
+
+ return services_tuple;
+}
+
+
+uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self) {
+ if (self == NULL || self->connection == NULL) {
+ return BLE_CONN_HANDLE_INVALID;
+ }
+ return self->connection->conn_handle;
+}
+
+mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t* internal) {
+ if (internal->connection_obj != mp_const_none) {
+ return internal->connection_obj;
+ }
+ bleio_connection_obj_t *connection = m_new_obj(bleio_connection_obj_t);
+ connection->base.type = &bleio_connection_type;
+ connection->connection = internal;
+ internal->connection_obj = connection;
+
+ return MP_OBJ_FROM_PTR(connection);
+}
diff --git a/ports/nrf/common-hal/_bleio/Peripheral.h b/ports/nrf/common-hal/_bleio/Connection.h
index a4f62d288..d5548de45 100644
--- a/ports/nrf/common-hal/_bleio/Peripheral.h
+++ b/ports/nrf/common-hal/_bleio/Connection.h
@@ -25,8 +25,8 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PERIPHERAL_H
-#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PERIPHERAL_H
+#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CONNECTION_H
+#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CONNECTION_H
#include <stdbool.h>
@@ -37,6 +37,7 @@
#include "common-hal/_bleio/__init__.h"
#include "shared-module/_bleio/Address.h"
+#include "common-hal/_bleio/Service.h"
typedef enum {
PAIR_NOT_PAIRED,
@@ -44,24 +45,36 @@ typedef enum {
PAIR_PAIRED,
} pair_status_t;
+// We split the Connection object into two so that the internal mechanics can live outside of the
+// VM. If it were one object, then we'd risk user code seeing a connection object of theirs be
+// reused.
typedef struct {
- mp_obj_base_t base;
- mp_obj_t name;
- volatile uint16_t conn_handle;
- // Services provided by this peripheral.
- mp_obj_list_t *service_list;
+ uint16_t conn_handle;
+ bool is_central;
// Remote services discovered when this peripheral is acting as a client.
- mp_obj_list_t *remote_service_list;
+ bleio_service_obj_t *remote_service_list;
// The advertising data and scan response buffers are held by us, not by the SD, so we must
// maintain them and not change it. If we need to change the contents during advertising,
// there are tricks to get the SD to notice (see DevZone - TBS).
// EDIV: Encrypted Diversifier: Identifies LTK during legacy pairing.
bonding_keys_t bonding_keys;
uint16_t ediv;
- uint8_t* advertising_data;
- uint8_t* scan_response_data;
- uint8_t adv_handle;
pair_status_t pair_status;
-} bleio_peripheral_obj_t;
+ uint8_t sec_status; // Internal security status.
+ mp_obj_t connection_obj;
+ ble_drv_evt_handler_entry_t handler_entry;
+} bleio_connection_internal_t;
+
+typedef struct {
+ mp_obj_base_t base;
+ bleio_connection_internal_t* connection;
+ // The HCI disconnect reason.
+ uint8_t disconnect_reason;
+} bleio_connection_obj_t;
+
+bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in);
+
+uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self);
+mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t* connection);
-#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PERIPHERAL_H
+#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CONNECTION_H
diff --git a/ports/nrf/common-hal/_bleio/Descriptor.c b/ports/nrf/common-hal/_bleio/Descriptor.c
index 137f004ba..faf50c658 100644
--- a/ports/nrf/common-hal/_bleio/Descriptor.c
+++ b/ports/nrf/common-hal/_bleio/Descriptor.c
@@ -33,8 +33,6 @@
#include "shared-bindings/_bleio/Service.h"
#include "shared-bindings/_bleio/UUID.h"
-static volatile bleio_descriptor_obj_t *m_read_descriptor;
-
void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_characteristic_obj_t *characteristic, bleio_uuid_obj_t *uuid, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo) {
self->characteristic = characteristic;
self->uuid = uuid;
@@ -61,62 +59,18 @@ bleio_characteristic_obj_t *common_hal_bleio_descriptor_get_characteristic(bleio
return self->characteristic;
}
-STATIC void descriptor_on_gattc_read_rsp_evt(ble_evt_t *ble_evt, void *param) {
- switch (ble_evt->header.evt_id) {
-
- // More events may be handled later, so keep this as a switch.
-
- case BLE_GATTC_EVT_READ_RSP: {
- ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp;
- if (m_read_descriptor) {
- m_read_descriptor->value = mp_obj_new_bytearray(response->len, response->data);
- }
- // Indicate to busy-wait loop that we've read the attribute value.
- m_read_descriptor = NULL;
- break;
- }
-
- default:
- // For debugging.
- // mp_printf(&mp_plat_print, "Unhandled descriptor event: 0x%04x\n", ble_evt->header.evt_id);
- break;
- }
-}
-
-STATIC void descriptor_gattc_read(bleio_descriptor_obj_t *descriptor) {
- const uint16_t conn_handle =
- common_hal_bleio_device_get_conn_handle(descriptor->characteristic->service->device);
- common_hal_bleio_check_connected(conn_handle);
-
- // Set to NULL in event loop after event.
- m_read_descriptor = descriptor;
-
- ble_drv_add_event_handler(descriptor_on_gattc_read_rsp_evt, descriptor);
-
- const uint32_t err_code = sd_ble_gattc_read(conn_handle, descriptor->handle, 0);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to read attribute value, err 0x%04x"), err_code);
- }
-
- while (m_read_descriptor != NULL) {
- MICROPY_VM_HOOK_LOOP;
- }
-
- ble_drv_remove_event_handler(descriptor_on_gattc_read_rsp_evt, descriptor);
-}
-
-mp_obj_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self) {
+size_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self, uint8_t* buf, size_t len) {
// Do GATT operations only if this descriptor has been registered
if (self->handle != BLE_GATT_HANDLE_INVALID) {
+ uint16_t conn_handle = bleio_connection_get_conn_handle(self->characteristic->service->connection);
if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) {
- descriptor_gattc_read(self);
+ return common_hal_bleio_gattc_read(self->handle, conn_handle, buf, len);
} else {
- self->value = common_hal_bleio_gatts_read(
- self->handle, common_hal_bleio_device_get_conn_handle(self->characteristic->service->device));
+ return common_hal_bleio_gatts_read(self->handle, conn_handle, buf, len);
}
}
- return self->value;
+ return 0;
}
void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buffer_info_t *bufinfo) {
@@ -131,7 +85,7 @@ void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buff
// Do GATT operations only if this descriptor has been registered.
if (self->handle != BLE_GATT_HANDLE_INVALID) {
- uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->characteristic->service->device);
+ uint16_t conn_handle = bleio_connection_get_conn_handle(self->characteristic->service->connection);
if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) {
// false means WRITE_REQ, not write-no-response
common_hal_bleio_gattc_write(self->handle, conn_handle, bufinfo, false);
diff --git a/ports/nrf/common-hal/_bleio/Descriptor.h b/ports/nrf/common-hal/_bleio/Descriptor.h
index 3adb0df18..c70547c08 100644
--- a/ports/nrf/common-hal/_bleio/Descriptor.h
+++ b/ports/nrf/common-hal/_bleio/Descriptor.h
@@ -31,13 +31,15 @@
#include "py/obj.h"
-#include "common-hal/_bleio/Characteristic.h"
#include "common-hal/_bleio/UUID.h"
-typedef struct {
+// Forward declare characteristic because it includes a Descriptor.
+struct _bleio_characteristic_obj;
+
+typedef struct _bleio_descriptor_obj {
mp_obj_base_t base;
// Will be MP_OBJ_NULL before being assigned to a Characteristic.
- bleio_characteristic_obj_t *characteristic;
+ struct _bleio_characteristic_obj *characteristic;
bleio_uuid_obj_t *uuid;
mp_obj_t value;
uint16_t max_length;
@@ -45,6 +47,7 @@ typedef struct {
uint16_t handle;
bleio_attribute_security_mode_t read_perm;
bleio_attribute_security_mode_t write_perm;
+ struct _bleio_descriptor_obj* next;
} bleio_descriptor_obj_t;
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H
diff --git a/ports/nrf/common-hal/_bleio/Peripheral.c b/ports/nrf/common-hal/_bleio/Peripheral.c
deleted file mode 100644
index 9b0f96d48..000000000
--- a/ports/nrf/common-hal/_bleio/Peripheral.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF 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/gc.h"
-#include "py/objlist.h"
-#include "py/objstr.h"
-#include "py/runtime.h"
-#include "shared-bindings/_bleio/__init__.h"
-#include "shared-bindings/_bleio/Adapter.h"
-#include "shared-bindings/_bleio/Attribute.h"
-#include "shared-bindings/_bleio/Characteristic.h"
-#include "shared-bindings/_bleio/Peripheral.h"
-#include "shared-bindings/_bleio/Service.h"
-#include "shared-bindings/_bleio/UUID.h"
-
-#define BLE_ADV_LENGTH_FIELD_SIZE 1
-#define BLE_ADV_AD_TYPE_FIELD_SIZE 1
-#define BLE_AD_TYPE_FLAGS_DATA_SIZE 1
-
-static const ble_gap_sec_params_t pairing_sec_params = {
- .bond = 1,
- .mitm = 0,
- .lesc = 0,
- .keypress = 0,
- .oob = 0,
- .io_caps = BLE_GAP_IO_CAPS_NONE,
- .min_key_size = 7,
- .max_key_size = 16,
- .kdist_own = { .enc = 1, .id = 1},
- .kdist_peer = { .enc = 1, .id = 1},
-};
-
-STATIC void check_data_fit(size_t data_len) {
- if (data_len > BLE_GAP_ADV_SET_DATA_SIZE_MAX) {
- mp_raise_ValueError(translate("Data too large for advertisement packet"));
- }
-}
-
-STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
- bleio_peripheral_obj_t *self = (bleio_peripheral_obj_t*)self_in;
-
- // For debugging.
- // mp_printf(&mp_plat_print, "Peripheral event: 0x%04x\n", ble_evt->header.evt_id);
-
- switch (ble_evt->header.evt_id) {
- case BLE_GAP_EVT_CONNECTED: {
- // Central has connected.
- ble_gap_evt_connected_t* connected = &ble_evt->evt.gap_evt.params.connected;
-
- self->conn_handle = ble_evt->evt.gap_evt.conn_handle;
-
- // See if connection interval set by Central is out of range.
- // If so, negotiate our preferred range.
- ble_gap_conn_params_t conn_params;
- sd_ble_gap_ppcp_get(&conn_params);
- if (conn_params.min_conn_interval < connected->conn_params.min_conn_interval ||
- conn_params.min_conn_interval > connected->conn_params.max_conn_interval) {
- sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params);
- }
- break;
- }
-
- case BLE_GAP_EVT_DISCONNECTED:
- // Central has disconnected.
- self->conn_handle = BLE_CONN_HANDLE_INVALID;
- break;
-
- case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
- ble_gap_phys_t const phys = {
- .rx_phys = BLE_GAP_PHY_AUTO,
- .tx_phys = BLE_GAP_PHY_AUTO,
- };
- sd_ble_gap_phy_update(ble_evt->evt.gap_evt.conn_handle, &phys);
- break;
- }
-
- case BLE_GAP_EVT_ADV_SET_TERMINATED:
- // TODO: Someday may handle timeouts or limit reached.
- break;
-
- case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
- // SoftDevice will respond to a length update request.
- sd_ble_gap_data_length_update(self->conn_handle, NULL, NULL);
- break;
-
- case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: {
- // We only handle MTU of size BLE_GATT_ATT_MTU_DEFAULT.
- sd_ble_gatts_exchange_mtu_reply(self->conn_handle, BLE_GATT_ATT_MTU_DEFAULT);
- break;
- }
-
- case BLE_GATTS_EVT_SYS_ATTR_MISSING:
- sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
- break;
-
- case BLE_GAP_EVT_SEC_PARAMS_REQUEST: {
- ble_gap_sec_keyset_t keyset = {
- .keys_own = {
- .p_enc_key = &self->bonding_keys.own_enc,
- .p_id_key = NULL,
- .p_sign_key = NULL,
- .p_pk = NULL
- },
-
- .keys_peer = {
- .p_enc_key = &self->bonding_keys.peer_enc,
- .p_id_key = &self->bonding_keys.peer_id,
- .p_sign_key = NULL,
- .p_pk = NULL
- }
- };
-
- sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_SUCCESS,
- &pairing_sec_params, &keyset);
- break;
- }
-
- case BLE_GAP_EVT_LESC_DHKEY_REQUEST:
- // TODO for LESC pairing:
- // sd_ble_gap_lesc_dhkey_reply(...);
- break;
-
- case BLE_GAP_EVT_AUTH_STATUS: {
- // Pairing process completed
- ble_gap_evt_auth_status_t* status = &ble_evt->evt.gap_evt.params.auth_status;
- if (BLE_GAP_SEC_STATUS_SUCCESS == status->auth_status) {
- // TODO _ediv = bonding_keys->own_enc.master_id.ediv;
- self->pair_status = PAIR_PAIRED;
- } else {
- self->pair_status = PAIR_NOT_PAIRED;
- }
- break;
- }
-
- case BLE_GAP_EVT_SEC_INFO_REQUEST: {
- // Peer asks for the stored keys.
- // - load key and return if bonded previously.
- // - Else return NULL --> Initiate key exchange
- ble_gap_evt_sec_info_request_t* sec_info_request = &ble_evt->evt.gap_evt.params.sec_info_request;
- (void) sec_info_request;
- //if ( bond_load_keys(_role, sec_req->master_id.ediv, &bkeys) ) {
- //sd_ble_gap_sec_info_reply(_conn_hdl, &bkeys.own_enc.enc_info, &bkeys.peer_id.id_info, NULL);
- //
- //_ediv = bkeys.own_enc.master_id.ediv;
- // } else {
- sd_ble_gap_sec_info_reply(self->conn_handle, NULL, NULL, NULL);
- // }
- break;
- }
-
- case BLE_GAP_EVT_CONN_SEC_UPDATE: {
- ble_gap_conn_sec_t* conn_sec = &ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec;
- if (conn_sec->sec_mode.sm <= 1 && conn_sec->sec_mode.lv <= 1) {
- // Security setup did not succeed:
- // mode 0, level 0 means no access
- // mode 1, level 1 means open link
- // mode >=1 and/or level >=1 means encryption is set up
- self->pair_status = PAIR_NOT_PAIRED;
- } else {
- //if ( !bond_load_cccd(_role, _conn_hdl, _ediv) ) {
- if (true) { // TODO: no bonding yet
- // Initialize system attributes fresh.
- sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
- }
- // Not quite paired yet: wait for BLE_GAP_EVT_AUTH_STATUS SUCCESS.
- self->ediv = self->bonding_keys.own_enc.master_id.ediv;
- }
- break;
- }
-
-
- default:
- // For debugging.
- // mp_printf(&mp_plat_print, "Unhandled peripheral event: 0x%04x\n", ble_evt->header.evt_id);
- break;
- }
-}
-
-void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_t name) {
- common_hal_bleio_adapter_set_enabled(true);
-
- self->service_list = mp_obj_new_list(0, NULL);
- // Used only for discovery when acting as a client.
- self->remote_service_list = mp_obj_new_list(0, NULL);
- self->name = name;
-
- self->conn_handle = BLE_CONN_HANDLE_INVALID;
- self->adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
- self->pair_status = PAIR_NOT_PAIRED;
-
- memset(&self->bonding_keys, 0, sizeof(self->bonding_keys));
-}
-
-void common_hal_bleio_peripheral_add_service(bleio_peripheral_obj_t *self, bleio_service_obj_t *service) {
- ble_uuid_t uuid;
- bleio_uuid_convert_to_nrf_ble_uuid(service->uuid, &uuid);
-
- uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY;
- if (common_hal_bleio_service_get_is_secondary(service)) {
- service_type = BLE_GATTS_SRVC_TYPE_SECONDARY;
- }
-
- const uint32_t err_code = sd_ble_gatts_service_add(service_type, &uuid, &service->handle);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to add service, err 0x%04x"), err_code);
- }
-
- mp_obj_list_append(self->service_list, MP_OBJ_FROM_PTR(service));
-}
-
-mp_obj_list_t *common_hal_bleio_peripheral_get_services(bleio_peripheral_obj_t *self) {
- return self->service_list;
-}
-
-bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self) {
- return self->conn_handle != BLE_CONN_HANDLE_INVALID;
-}
-
-mp_obj_t common_hal_bleio_peripheral_get_name(bleio_peripheral_obj_t *self) {
- return self->name;
-}
-
-void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *self, bool connectable, mp_float_t interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo) {
-
- // interval value has already been validated.
-
- if (connectable) {
- ble_drv_add_event_handler(peripheral_on_ble_evt, self);
- }
-
- common_hal_bleio_adapter_set_enabled(true);
-
- uint32_t err_code;
-
- GET_STR_DATA_LEN(self->name, name_data, name_len);
- if (name_len > 0) {
- // Set device name, and make it available to anyone.
- ble_gap_conn_sec_mode_t sec_mode;
- BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
- err_code = sd_ble_gap_device_name_set(&sec_mode, name_data, name_len);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to set device name, err 0x%04x"), err_code);
-
- }
- }
-
- check_data_fit(advertising_data_bufinfo->len);
- // The advertising data buffers must not move, because the SoftDevice depends on them.
- // So make them long-lived.
- self->advertising_data = (uint8_t *) gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_MAX * sizeof(uint8_t), false, true);
- memcpy(self->advertising_data, advertising_data_bufinfo->buf, advertising_data_bufinfo->len);
-
- check_data_fit(scan_response_data_bufinfo->len);
- self->scan_response_data = (uint8_t *) gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_MAX * sizeof(uint8_t), false, true);
- memcpy(self->scan_response_data, scan_response_data_bufinfo->buf, scan_response_data_bufinfo->len);
-
-
- ble_gap_adv_params_t adv_params = {
- .interval = SEC_TO_UNITS(interval, UNIT_0_625_MS),
- .properties.type = connectable ? BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED
- : BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED,
- .duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED,
- .filter_policy = BLE_GAP_ADV_FP_ANY,
- .primary_phy = BLE_GAP_PHY_1MBPS,
- };
-
- common_hal_bleio_peripheral_stop_advertising(self);
-
- const ble_gap_adv_data_t ble_gap_adv_data = {
- .adv_data.p_data = self->advertising_data,
- .adv_data.len = advertising_data_bufinfo->len,
- .scan_rsp_data.p_data = scan_response_data_bufinfo-> len > 0 ? self->scan_response_data : NULL,
- .scan_rsp_data.len = scan_response_data_bufinfo->len,
- };
-
- err_code = sd_ble_gap_adv_set_configure(&self->adv_handle, &ble_gap_adv_data, &adv_params);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to configure advertising, err 0x%04x"), err_code);
- }
-
- err_code = sd_ble_gap_adv_start(self->adv_handle, BLE_CONN_CFG_TAG_CUSTOM);
-
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to start advertising, err 0x%04x"), err_code);
- }
-}
-
-void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *self) {
- if (self->adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET)
- return;
-
- const uint32_t err_code = sd_ble_gap_adv_stop(self->adv_handle);
-
- if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) {
- mp_raise_OSError_msg_varg(translate("Failed to stop advertising, err 0x%04x"), err_code);
- }
-}
-
-void common_hal_bleio_peripheral_disconnect(bleio_peripheral_obj_t *self) {
- sd_ble_gap_disconnect(self->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
-}
-
-mp_obj_tuple_t *common_hal_bleio_peripheral_discover_remote_services(bleio_peripheral_obj_t *self, mp_obj_t service_uuids_whitelist) {
- common_hal_bleio_device_discover_remote_services(MP_OBJ_FROM_PTR(self), service_uuids_whitelist);
- // Convert to a tuple and then clear the list so the callee will take ownership.
- mp_obj_tuple_t *services_tuple = mp_obj_new_tuple(self->remote_service_list->len,
- self->remote_service_list->items);
- mp_obj_list_clear(self->remote_service_list);
- return services_tuple;
-}
-
-void common_hal_bleio_peripheral_pair(bleio_peripheral_obj_t *self) {
- self->pair_status = PAIR_WAITING;
-
- uint32_t err_code = sd_ble_gap_authenticate(self->conn_handle, &pairing_sec_params);
-
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to start pairing, error 0x%04x"), err_code);
- }
-
- while (self->pair_status == PAIR_WAITING) {
- RUN_BACKGROUND_TASKS;
- }
-
- if (self->pair_status == PAIR_NOT_PAIRED) {
- mp_raise_OSError_msg(translate("Failed to pair"));
- }
-
-
-}
diff --git a/ports/nrf/common-hal/_bleio/Scanner.c b/ports/nrf/common-hal/_bleio/Scanner.c
deleted file mode 100644
index ec73f7eb8..000000000
--- a/ports/nrf/common-hal/_bleio/Scanner.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
- * Copyright (c) 2016 Glenn Ruben Bakke
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <string.h>
-
-#include "ble_drv.h"
-#include "ble_gap.h"
-#include "py/mphal.h"
-#include "py/objlist.h"
-#include "py/runtime.h"
-#include "shared-bindings/_bleio/Adapter.h"
-#include "shared-bindings/_bleio/ScanEntry.h"
-#include "shared-bindings/_bleio/Scanner.h"
-#include "shared-module/_bleio/ScanEntry.h"
-
-static uint8_t m_scan_buffer_data[BLE_GAP_SCAN_BUFFER_MIN];
-
-static ble_data_t m_scan_buffer = {
- m_scan_buffer_data,
- BLE_GAP_SCAN_BUFFER_MIN
-};
-
-STATIC void scanner_on_ble_evt(ble_evt_t *ble_evt, void *scanner_in) {
- bleio_scanner_obj_t *scanner = (bleio_scanner_obj_t*)scanner_in;
- ble_gap_evt_adv_report_t *report = &ble_evt->evt.gap_evt.params.adv_report;
-
- if (ble_evt->header.evt_id != BLE_GAP_EVT_ADV_REPORT) {
- return;
- }
-
- bleio_scanentry_obj_t *entry = m_new_obj(bleio_scanentry_obj_t);
- entry->base.type = &bleio_scanentry_type;
- entry->rssi = report->rssi;
-
- bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t);
- address->base.type = &bleio_address_type;
- common_hal_bleio_address_construct(MP_OBJ_TO_PTR(address),
- report->peer_addr.addr, report->peer_addr.addr_type);
- entry->address = address;
-
- entry->data = mp_obj_new_bytes(report->data.p_data, report->data.len);
-
- mp_obj_list_append(scanner->scan_entries, MP_OBJ_FROM_PTR(entry));
-
- const uint32_t err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to continue scanning, err 0x%04x"), err_code);
- }
-}
-
-void common_hal_bleio_scanner_construct(bleio_scanner_obj_t *self) {
-}
-
-mp_obj_t common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_float_t timeout, mp_float_t interval, mp_float_t window) {
- common_hal_bleio_adapter_set_enabled(true);
- ble_drv_add_event_handler(scanner_on_ble_evt, self);
-
- ble_gap_scan_params_t scan_params = {
- .interval = SEC_TO_UNITS(interval, UNIT_0_625_MS),
- .window = SEC_TO_UNITS(window, UNIT_0_625_MS),
- .scan_phys = BLE_GAP_PHY_1MBPS,
- };
-
- self->scan_entries = mp_obj_new_list(0, NULL);
-
- uint32_t err_code;
- err_code = sd_ble_gap_scan_start(&scan_params, &m_scan_buffer);
-
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to start scanning, err 0x%04x"), err_code);
- }
-
- mp_hal_delay_ms(timeout * 1000);
- sd_ble_gap_scan_stop();
-
- // Return list, and don't hang on to it, so it can be GC'd.
- mp_obj_t entries = self->scan_entries;
- self->scan_entries = MP_OBJ_NULL;
- return entries;
-}
diff --git a/ports/nrf/common-hal/_bleio/Service.c b/ports/nrf/common-hal/_bleio/Service.c
index 650cdc4ec..5918327c1 100644
--- a/ports/nrf/common-hal/_bleio/Service.c
+++ b/ports/nrf/common-hal/_bleio/Service.c
@@ -31,17 +31,42 @@
#include "common-hal/_bleio/__init__.h"
#include "shared-bindings/_bleio/Characteristic.h"
#include "shared-bindings/_bleio/Descriptor.h"
-#include "shared-bindings/_bleio/Peripheral.h"
#include "shared-bindings/_bleio/Service.h"
#include "shared-bindings/_bleio/Adapter.h"
-void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_peripheral_obj_t *peripheral, bleio_uuid_obj_t *uuid, bool is_secondary) {
- self->device = MP_OBJ_FROM_PTR(peripheral);
+uint32_t _common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary, mp_obj_list_t * characteristic_list) {
self->handle = 0xFFFF;
self->uuid = uuid;
- self->characteristic_list = mp_obj_new_list(0, NULL);
+ self->characteristic_list = characteristic_list;
self->is_remote = false;
+ self->connection = NULL;
self->is_secondary = is_secondary;
+
+ ble_uuid_t nordic_uuid;
+ bleio_uuid_convert_to_nrf_ble_uuid(uuid, &nordic_uuid);
+
+ uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY;
+ if (is_secondary) {
+ service_type = BLE_GATTS_SRVC_TYPE_SECONDARY;
+ }
+
+ vm_used_ble = true;
+
+ return sd_ble_gatts_service_add(service_type, &nordic_uuid, &self->handle);
+}
+
+void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary) {
+ check_nrf_error(_common_hal_bleio_service_construct(self, uuid, is_secondary,
+ mp_obj_new_list(0, NULL)));
+}
+
+void bleio_service_from_connection(bleio_service_obj_t *self, mp_obj_t connection) {
+ self->handle = 0xFFFF;
+ self->uuid = NULL;
+ self->characteristic_list = mp_obj_new_list(0, NULL);
+ self->is_remote = true;
+ self->is_secondary = false;
+ self->connection = connection;
}
bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self) {
@@ -60,7 +85,9 @@ bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self) {
return self->is_secondary;
}
-void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic) {
+void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
+ bleio_characteristic_obj_t *characteristic,
+ mp_buffer_info_t *initial_value_bufinfo) {
ble_gatts_char_md_t char_md = {
.char_props.broadcast = (characteristic->props & CHAR_PROP_BROADCAST) ? 1 : 0,
.char_props.read = (characteristic->props & CHAR_PROP_READ) ? 1 : 0,
@@ -93,25 +120,18 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, blei
bleio_attribute_gatts_set_security_mode(&char_attr_md.read_perm, characteristic->read_perm);
bleio_attribute_gatts_set_security_mode(&char_attr_md.write_perm, characteristic->write_perm);
- mp_buffer_info_t char_value_bufinfo;
- mp_get_buffer_raise(characteristic->value, &char_value_bufinfo, MP_BUFFER_READ);
-
ble_gatts_attr_t char_attr = {
.p_uuid = &char_uuid,
.p_attr_md = &char_attr_md,
- .init_len = char_value_bufinfo.len,
- .p_value = char_value_bufinfo.buf,
+ .init_len = 0,
+ .p_value = NULL,
.init_offs = 0,
.max_len = characteristic->max_length,
};
ble_gatts_char_handles_t char_handles;
- uint32_t err_code;
- err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &char_attr, &char_handles);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to add characteristic, err 0x%04x"), err_code);
- }
+ check_nrf_error(sd_ble_gatts_characteristic_add(self->handle, &char_md, &char_attr, &char_handles));
characteristic->user_desc_handle = char_handles.user_desc_handle;
characteristic->cccd_handle = char_handles.cccd_handle;
diff --git a/ports/nrf/common-hal/_bleio/Service.h b/ports/nrf/common-hal/_bleio/Service.h
index a4614b9f5..f101bc825 100644
--- a/ports/nrf/common-hal/_bleio/Service.h
+++ b/ports/nrf/common-hal/_bleio/Service.h
@@ -31,20 +31,22 @@
#include "py/objlist.h"
#include "common-hal/_bleio/UUID.h"
-typedef struct {
+typedef struct bleio_service_obj {
mp_obj_base_t base;
- // Handle for this service.
+ // Handle for the local service.
uint16_t handle;
// True if created during discovery.
bool is_remote;
bool is_secondary;
bleio_uuid_obj_t *uuid;
- // May be a Peripheral, Central, etc.
- mp_obj_t device;
+ mp_obj_t connection;
mp_obj_list_t *characteristic_list;
- // Range of attribute handles of this service.
+ // Range of attribute handles of this remote service.
uint16_t start_handle;
uint16_t end_handle;
+ struct bleio_service_obj* next;
} bleio_service_obj_t;
+void bleio_service_from_connection(bleio_service_obj_t *self, mp_obj_t connection);
+
#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 0e65b7d58..6a3d64305 100644
--- a/ports/nrf/common-hal/_bleio/UUID.c
+++ b/ports/nrf/common-hal/_bleio/UUID.c
@@ -30,6 +30,7 @@
#include "py/runtime.h"
#include "common-hal/_bleio/UUID.h"
+#include "shared-bindings/_bleio/__init__.h"
#include "shared-bindings/_bleio/Adapter.h"
#include "ble.h"
@@ -39,9 +40,7 @@
// If uuid128 is NULL, this is a Bluetooth SIG 16-bit UUID.
// If uuid128 is not NULL, it's a 128-bit (16-byte) UUID, with bytes 12 and 13 zero'd out, where
// the 16-bit part goes. Those 16 bits are passed in uuid16.
-void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, uint8_t uuid128[]) {
- common_hal_bleio_adapter_set_enabled(true);
-
+void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, const uint8_t uuid128[]) {
self->nrf_ble_uuid.uuid = uuid16;
if (uuid128 == NULL) {
self->nrf_ble_uuid.type = BLE_UUID_TYPE_BLE;
@@ -50,10 +49,8 @@ void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, ui
memcpy(vs_uuid.uuid128, uuid128, sizeof(vs_uuid.uuid128));
// Register this vendor-specific UUID. Bytes 12 and 13 will be zero.
- const uint32_t err_code = sd_ble_uuid_vs_add(&vs_uuid, &self->nrf_ble_uuid.type);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to register Vendor-Specific UUID, err 0x%04x"), err_code);
- }
+ check_nrf_error(sd_ble_uuid_vs_add(&vs_uuid, &self->nrf_ble_uuid.type));
+ vm_used_ble = true;
}
}
@@ -65,28 +62,23 @@ uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self) {
return self->nrf_ble_uuid.uuid;
}
-// True if uuid128 has been successfully filled in.
-bool common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]) {
+void common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]) {
uint8_t length;
- const uint32_t err_code = sd_ble_uuid_encode(&self->nrf_ble_uuid, &length, uuid128);
-
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Could not decode ble_uuid, err 0x%04x"), err_code);
- }
- // If not 16 bytes, this is not a 128-bit UUID, so return.
- return length == 16;
+ check_nrf_error(sd_ble_uuid_encode(&self->nrf_ble_uuid, &length, uuid128));
}
-// Returns 0 if this is a 16-bit UUID, otherwise returns a non-zero index
-// into the 128-bit uuid registration table.
-uint32_t common_hal_bleio_uuid_get_uuid128_reference(bleio_uuid_obj_t *self) {
- return self->nrf_ble_uuid.type == BLE_UUID_TYPE_BLE ? 0 : self->nrf_ble_uuid.type;
+void common_hal_bleio_uuid_pack_into(bleio_uuid_obj_t *self, uint8_t* buf) {
+ if (self->nrf_ble_uuid.type == BLE_UUID_TYPE_BLE) {
+ buf[0] = self->nrf_ble_uuid.uuid & 0xff;
+ buf[1] = self->nrf_ble_uuid.uuid >> 8;
+ } else {
+ common_hal_bleio_uuid_get_uuid128(self, buf);
+ }
}
-
void bleio_uuid_construct_from_nrf_ble_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_ble_uuid) {
if (nrf_ble_uuid->type == BLE_UUID_TYPE_UNKNOWN) {
- mp_raise_RuntimeError(translate("Unexpected nrfx uuid type"));
+ mp_raise_bleio_BluetoothError(translate("Unexpected nrfx uuid type"));
}
self->nrf_ble_uuid.uuid = nrf_ble_uuid->uuid;
self->nrf_ble_uuid.type = nrf_ble_uuid->type;
diff --git a/ports/nrf/common-hal/_bleio/__init__.c b/ports/nrf/common-hal/_bleio/__init__.c
index 553044190..7ba3dc8c1 100644
--- a/ports/nrf/common-hal/_bleio/__init__.c
+++ b/ports/nrf/common-hal/_bleio/__init__.c
@@ -26,449 +26,176 @@
* THE SOFTWARE.
*/
+#include <string.h>
+
#include "py/runtime.h"
#include "shared-bindings/_bleio/__init__.h"
#include "shared-bindings/_bleio/Adapter.h"
-#include "shared-bindings/_bleio/Central.h"
#include "shared-bindings/_bleio/Characteristic.h"
+#include "shared-bindings/_bleio/Connection.h"
#include "shared-bindings/_bleio/Descriptor.h"
-#include "shared-bindings/_bleio/Peripheral.h"
#include "shared-bindings/_bleio/Service.h"
#include "shared-bindings/_bleio/UUID.h"
+#include "supervisor/shared/bluetooth.h"
#include "common-hal/_bleio/__init__.h"
-static volatile bool m_discovery_in_process;
-static volatile bool m_discovery_successful;
-
-static bleio_service_obj_t *m_char_discovery_service;
-static bleio_characteristic_obj_t *m_desc_discovery_characteristic;
-
-// Turn off BLE on a reset or reload.
-void bleio_reset() {
- if (common_hal_bleio_adapter_get_enabled()) {
- common_hal_bleio_adapter_set_enabled(false);
- }
-}
-
-// The singleton _bleio.Adapter object, bound to _bleio.adapter
-// It currently only has properties and no state
-const super_adapter_obj_t common_hal_bleio_adapter_obj = {
- .base = {
- .type = &bleio_adapter_type,
- },
-};
-
-void common_hal_bleio_check_connected(uint16_t conn_handle) {
- if (conn_handle == BLE_CONN_HANDLE_INVALID) {
- mp_raise_OSError_msg(translate("Not connected"));
- }
-}
-
-uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device) {
- if (MP_OBJ_IS_TYPE(device, &bleio_peripheral_type)) {
- return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle;
- } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) {
- return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle;
- } else {
- return BLE_CONN_HANDLE_INVALID;
+void check_nrf_error(uint32_t err_code) {
+ if (err_code == NRF_SUCCESS) {
+ return;
}
-}
-
-mp_obj_list_t *common_hal_bleio_device_get_remote_service_list(mp_obj_t device) {
- if (MP_OBJ_IS_TYPE(device, &bleio_peripheral_type)) {
- return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->remote_service_list;
- } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) {
- return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->remote_service_list;
- } else {
- return NULL;
+ switch (err_code) {
+ case NRF_ERROR_TIMEOUT:
+ mp_raise_msg(&mp_type_TimeoutError, NULL);
+ return;
+ default:
+ mp_raise_bleio_BluetoothError(translate("Unknown soft device error: %04x"), err_code);
+ break;
}
}
-// service_uuid may be NULL, to discover all services.
-STATIC bool discover_next_services(mp_obj_t device, uint16_t start_handle, ble_uuid_t *service_uuid) {
- m_discovery_successful = false;
- m_discovery_in_process = true;
-
- uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(device);
- uint32_t err_code = sd_ble_gattc_primary_services_discover(conn_handle, start_handle, service_uuid);
-
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to discover services"));
- }
-
- // Wait for a discovery event.
- while (m_discovery_in_process) {
- MICROPY_VM_HOOK_LOOP;
+void check_gatt_status(uint16_t gatt_status) {
+ if (gatt_status == BLE_GATT_STATUS_SUCCESS) {
+ return;
+ }
+ switch (gatt_status) {
+ case BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION:
+ mp_raise_bleio_SecurityError(translate("Insufficient authentication"));
+ return;
+ case BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION:
+ mp_raise_bleio_SecurityError(translate("Insufficient encryption"));
+ return;
+ default:
+ mp_raise_bleio_BluetoothError(translate("Unknown gatt error: 0x%04x"), gatt_status);
}
- return m_discovery_successful;
}
-STATIC bool discover_next_characteristics(mp_obj_t device, bleio_service_obj_t *service, uint16_t start_handle) {
- m_char_discovery_service = service;
-
- ble_gattc_handle_range_t handle_range;
- handle_range.start_handle = start_handle;
- handle_range.end_handle = service->end_handle;
-
- m_discovery_successful = false;
- m_discovery_in_process = true;
-
- uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(device);
- uint32_t err_code = sd_ble_gattc_characteristics_discover(conn_handle, &handle_range);
- if (err_code != NRF_SUCCESS) {
- return false;
+void check_sec_status(uint8_t sec_status) {
+ if (sec_status == BLE_GAP_SEC_STATUS_SUCCESS) {
+ return;
}
- // Wait for a discovery event.
- while (m_discovery_in_process) {
- MICROPY_VM_HOOK_LOOP;
+ switch (sec_status) {
+ case BLE_GAP_SEC_STATUS_UNSPECIFIED:
+ mp_raise_bleio_SecurityError(translate("Unspecified issue. Can be that the pairing prompt on the other device was declined or ignored."));
+ return;
+ default:
+ mp_raise_bleio_SecurityError(translate("Unknown security error: 0x%04x"), sec_status);
}
- return m_discovery_successful;
}
-STATIC bool discover_next_descriptors(mp_obj_t device, bleio_characteristic_obj_t *characteristic, uint16_t start_handle, uint16_t end_handle) {
- m_desc_discovery_characteristic = characteristic;
-
- ble_gattc_handle_range_t handle_range;
- handle_range.start_handle = start_handle;
- handle_range.end_handle = end_handle;
-
- m_discovery_successful = false;
- m_discovery_in_process = true;
-
- uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(device);
- uint32_t err_code = sd_ble_gattc_descriptors_discover(conn_handle, &handle_range);
- if (err_code != NRF_SUCCESS) {
- return false;
+// Turn off BLE on a reset or reload.
+void bleio_reset() {
+ bleio_adapter_reset(&common_hal_bleio_adapter_obj);
+ if (!vm_used_ble) {
+ return;
}
-
- // Wait for a discovery event.
- while (m_discovery_in_process) {
- MICROPY_VM_HOOK_LOOP;
+ if (common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) {
+ common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, false);
}
- return m_discovery_successful;
+ supervisor_start_bluetooth();
}
-STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, mp_obj_t device) {
- for (size_t i = 0; i < response->count; ++i) {
- ble_gattc_service_t *gattc_service = &response->services[i];
-
- bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t);
- service->base.type = &bleio_service_type;
-
- // Initialize several fields at once.
- common_hal_bleio_service_construct(service, device, NULL, false);
-
- service->is_remote = true;
- service->start_handle = gattc_service->handle_range.start_handle;
- service->end_handle = gattc_service->handle_range.end_handle;
- service->handle = gattc_service->handle_range.start_handle;
-
- if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
- // Known service UUID.
- bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t);
- uuid->base.type = &bleio_uuid_type;
- bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid);
- service->uuid = uuid;
- } else {
- // The discovery response contained a 128-bit UUID that has not yet been registered with the
- // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
- // For now, just set the UUID to NULL.
- service->uuid = NULL;
- }
-
- mp_obj_list_append(common_hal_bleio_device_get_remote_service_list(device), service);
- }
+// The singleton _bleio.Adapter object, bound to _bleio.adapter
+// It currently only has properties and no state
+bleio_adapter_obj_t common_hal_bleio_adapter_obj = {
+ .base = {
+ .type = &bleio_adapter_type,
+ },
+};
- if (response->count > 0) {
- m_discovery_successful = true;
+void common_hal_bleio_check_connected(uint16_t conn_handle) {
+ if (conn_handle == BLE_CONN_HANDLE_INVALID) {
+ mp_raise_bleio_ConnectionError(translate("Not connected"));
}
- m_discovery_in_process = false;
}
-STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, mp_obj_t device) {
- for (size_t i = 0; i < response->count; ++i) {
- ble_gattc_char_t *gattc_char = &response->chars[i];
-
- bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t);
- characteristic->base.type = &bleio_characteristic_type;
-
- bleio_uuid_obj_t *uuid = NULL;
+// GATTS read of a Characteristic or Descriptor.
+size_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_t* buf, size_t len) {
+ // conn_handle might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because
+ // we can still read and write the local value.
- 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.
- }
+ ble_gatts_value_t gatts_value = {
+ .p_value = buf,
+ .len = len,
+ };
- bleio_characteristic_properties_t props =
- (gattc_char->char_props.broadcast ? CHAR_PROP_BROADCAST : 0) |
- (gattc_char->char_props.indicate ? CHAR_PROP_INDICATE : 0) |
- (gattc_char->char_props.notify ? CHAR_PROP_NOTIFY : 0) |
- (gattc_char->char_props.read ? CHAR_PROP_READ : 0) |
- (gattc_char->char_props.write ? CHAR_PROP_WRITE : 0) |
- (gattc_char->char_props.write_wo_resp ? CHAR_PROP_WRITE_NO_RESPONSE : 0);
-
- // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler.
- common_hal_bleio_characteristic_construct(
- characteristic, m_char_discovery_service, uuid, props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN,
- GATT_MAX_DATA_LENGTH, false, // max_length, fixed_length: values may not matter for gattc
- mp_obj_new_list(0, NULL));
- characteristic->handle = gattc_char->handle_value;
-
- mp_obj_list_append(m_char_discovery_service->characteristic_list, MP_OBJ_FROM_PTR(characteristic));
- }
+ check_nrf_error(sd_ble_gatts_value_get(conn_handle, handle, &gatts_value));
- if (response->count > 0) {
- m_discovery_successful = true;
- }
- m_discovery_in_process = false;
+ return gatts_value.len;
}
-STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, mp_obj_t device) {
- for (size_t i = 0; i < response->count; ++i) {
- ble_gattc_desc_t *gattc_desc = &response->descs[i];
-
- // Remember handles for certain well-known descriptors.
- switch (gattc_desc->uuid.uuid) {
- case BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG:
- m_desc_discovery_characteristic->cccd_handle = gattc_desc->handle;
- break;
-
- case BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG:
- m_desc_discovery_characteristic->sccd_handle = gattc_desc->handle;
- break;
-
- case BLE_UUID_DESCRIPTOR_CHAR_USER_DESC:
- m_desc_discovery_characteristic->user_desc_handle = gattc_desc->handle;
- break;
-
- default:
- // TODO: sd_ble_gattc_descriptors_discover() can return things that are not descriptors,
- // so ignore those.
- // https://devzone.nordicsemi.com/f/nordic-q-a/49500/sd_ble_gattc_descriptors_discover-is-returning-attributes-that-are-not-descriptors
- break;
- }
-
- bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t);
- descriptor->base.type = &bleio_descriptor_type;
-
- bleio_uuid_obj_t *uuid = NULL;
-
- if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
- // Known descriptor UUID.
- uuid = m_new_obj(bleio_uuid_obj_t);
- uuid->base.type = &bleio_uuid_type;
- bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid);
- } else {
- // The discovery response contained a 128-bit UUID that has not yet been registered with the
- // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
- // For now, just leave the UUID as NULL.
- }
-
- common_hal_bleio_descriptor_construct(
- descriptor, m_desc_discovery_characteristic, uuid,
- SECURITY_MODE_OPEN, SECURITY_MODE_OPEN,
- GATT_MAX_DATA_LENGTH, false, mp_const_empty_bytes);
- descriptor->handle = gattc_desc->handle;
+void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo) {
+ // conn_handle might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because
+ // we can still read and write the local value.
- mp_obj_list_append(m_desc_discovery_characteristic->descriptor_list, MP_OBJ_FROM_PTR(descriptor));
- }
+ ble_gatts_value_t gatts_value = {
+ .p_value = bufinfo->buf,
+ .len = bufinfo->len,
+ };
- if (response->count > 0) {
- m_discovery_successful = true;
- }
- m_discovery_in_process = false;
+ check_nrf_error(sd_ble_gatts_value_set(conn_handle, handle, &gatts_value));
}
-STATIC void discovery_on_ble_evt(ble_evt_t *ble_evt, mp_obj_t device) {
+typedef struct {
+ uint8_t* buf;
+ size_t len;
+ size_t final_len;
+ uint16_t conn_handle;
+ volatile uint16_t status;
+ volatile bool done;
+} read_info_t;
+
+STATIC bool _on_gattc_read_rsp_evt(ble_evt_t *ble_evt, void *param) {
+ read_info_t* read = param;
switch (ble_evt->header.evt_id) {
- case BLE_GAP_EVT_DISCONNECTED:
- m_discovery_successful = false;
- m_discovery_in_process = false;
- break;
-
- case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
- on_primary_srv_discovery_rsp(&ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp, device);
- break;
- case BLE_GATTC_EVT_CHAR_DISC_RSP:
- on_char_discovery_rsp(&ble_evt->evt.gattc_evt.params.char_disc_rsp, device);
- break;
-
- case BLE_GATTC_EVT_DESC_DISC_RSP:
- on_desc_discovery_rsp(&ble_evt->evt.gattc_evt.params.desc_disc_rsp, device);
+ // More events may be handled later, so keep this as a switch.
+
+ case BLE_GATTC_EVT_READ_RSP: {
+ ble_gattc_evt_t* evt = &ble_evt->evt.gattc_evt;
+ ble_gattc_evt_read_rsp_t *response = &evt->params.read_rsp;
+ if (read && evt->conn_handle == read->conn_handle) {
+ read->status = evt->gatt_status;
+ size_t len = MIN(read->len, response->len);
+ memcpy(read->buf, response->data, len);
+ read->final_len = len;
+ // Indicate to busy-wait loop that we've read the attribute value.
+ read->done = true;
+ }
break;
+ }
default:
// For debugging.
- // mp_printf(&mp_plat_print, "Unhandled discovery event: 0x%04x\n", ble_evt->header.evt_id);
+ // mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id);
+ return false;
break;
}
+ return true;
}
+size_t common_hal_bleio_gattc_read(uint16_t handle, uint16_t conn_handle, uint8_t* buf, size_t len) {
+ common_hal_bleio_check_connected(conn_handle);
-void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t service_uuids_whitelist) {
- mp_obj_list_t *remote_services_list = common_hal_bleio_device_get_remote_service_list(device);
-
- ble_drv_add_event_handler(discovery_on_ble_evt, device);
-
- // Start over with an empty list.
- mp_obj_list_clear(MP_OBJ_FROM_PTR(common_hal_bleio_device_get_remote_service_list(device)));
-
- if (service_uuids_whitelist == mp_const_none) {
- // List of service UUID's not given, so discover all available services.
-
- uint16_t next_service_start_handle = BLE_GATT_HANDLE_START;
-
- while (discover_next_services(device, next_service_start_handle, MP_OBJ_NULL)) {
- // discover_next_services() appends to remote_services_list.
-
- // Get the most recently discovered service, and then ask for services
- // whose handles start after the last attribute handle inside that service.
- const bleio_service_obj_t *service =
- MP_OBJ_TO_PTR(remote_services_list->items[remote_services_list->len - 1]);
- next_service_start_handle = service->end_handle + 1;
- }
- } else {
- mp_obj_iter_buf_t iter_buf;
- mp_obj_t iterable = mp_getiter(service_uuids_whitelist, &iter_buf);
- mp_obj_t uuid_obj;
- while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
- if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
- mp_raise_ValueError(translate("non-UUID found in service_uuids_whitelist"));
- }
- bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj);
-
- ble_uuid_t nrf_uuid;
- bleio_uuid_convert_to_nrf_ble_uuid(uuid, &nrf_uuid);
-
- // Service might or might not be discovered; that's ok. Caller has to check
- // Central.remote_services to find out.
- // We only need to call this once for each service to discover.
- discover_next_services(device, BLE_GATT_HANDLE_START, &nrf_uuid);
- }
- }
-
-
- for (size_t service_idx = 0; service_idx < remote_services_list->len; ++service_idx) {
- bleio_service_obj_t *service = MP_OBJ_TO_PTR(remote_services_list->items[service_idx]);
-
- // Skip the service if it had an unknown (unregistered) UUID.
- if (service->uuid == NULL) {
- continue;
- }
-
- uint16_t next_char_start_handle = service->start_handle;
-
- // Stop when we go past the end of the range of handles for this service or
- // discovery call returns nothing.
- // discover_next_characteristics() appends to the characteristic_list.
- while (next_char_start_handle <= service->end_handle &&
- discover_next_characteristics(device, service, next_char_start_handle)) {
-
-
- // Get the most recently discovered characteristic, and then ask for characteristics
- // whose handles start after the last attribute handle inside that characteristic.
- const bleio_characteristic_obj_t *characteristic =
- MP_OBJ_TO_PTR(service->characteristic_list->items[service->characteristic_list->len - 1]);
- next_char_start_handle = characteristic->handle + 1;
- }
-
- // Got characteristics for this service. Now discover descriptors for each characteristic.
- size_t char_list_len = service->characteristic_list->len;
- for (size_t char_idx = 0; char_idx < char_list_len; ++char_idx) {
- bleio_characteristic_obj_t *characteristic =
- MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx]);
- const bool last_characteristic = char_idx == char_list_len - 1;
- bleio_characteristic_obj_t *next_characteristic = last_characteristic
- ? NULL
- : MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx + 1]);
-
- // Skip the characteristic if it had an unknown (unregistered) UUID.
- if (characteristic->uuid == NULL) {
- continue;
- }
-
- uint16_t next_desc_start_handle = characteristic->handle + 1;
-
- // Don't run past the end of this service or the beginning of the next characteristic.
- uint16_t next_desc_end_handle = next_characteristic == NULL
- ? service->end_handle
- : next_characteristic->handle - 1;
-
- // Stop when we go past the end of the range of handles for this service or
- // discovery call returns nothing.
- // discover_next_descriptors() appends to the descriptor_list.
- while (next_desc_start_handle <= service->end_handle &&
- next_desc_start_handle < next_desc_end_handle &&
- discover_next_descriptors(device, characteristic,
- next_desc_start_handle, next_desc_end_handle)) {
-
- // Get the most recently discovered descriptor, and then ask for descriptors
- // whose handles start after that descriptor's handle.
- const bleio_descriptor_obj_t *descriptor =
- MP_OBJ_TO_PTR(characteristic->descriptor_list->items[characteristic->descriptor_list->len - 1]);
- next_desc_start_handle = descriptor->handle + 1;
- }
- }
- }
-
- // This event handler is no longer needed.
- ble_drv_remove_event_handler(discovery_on_ble_evt, device);
-
-}
-
-// GATTS read of a Characteristic or Descriptor.
-mp_obj_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle) {
- // conn_handle might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because
- // we can still read and write the local value.
-
- mp_buffer_info_t bufinfo;
- ble_gatts_value_t gatts_value = {
- .p_value = NULL,
- .len = 0,
- };
-
- // Read once to find out what size buffer we need, then read again to fill buffer.
-
- mp_obj_t value = mp_const_none;
- uint32_t err_code = sd_ble_gatts_value_get(conn_handle, handle, &gatts_value);
- if (err_code == NRF_SUCCESS) {
- value = mp_obj_new_bytearray_of_zeros(gatts_value.len);
- mp_get_buffer_raise(value, &bufinfo, MP_BUFFER_WRITE);
- gatts_value.p_value = bufinfo.buf;
+ read_info_t read_info;
+ read_info.buf = buf;
+ read_info.len = len;
+ read_info.final_len = 0;
+ read_info.conn_handle = conn_handle;
+ // Set to true by the event handler.
+ read_info.done = false;
+ ble_drv_add_event_handler(_on_gattc_read_rsp_evt, &read_info);
- // Read again, with the correct size of buffer.
- err_code = sd_ble_gatts_value_get(conn_handle, handle, &gatts_value);
- }
+ check_nrf_error(sd_ble_gattc_read(conn_handle, handle, 0));
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to read gatts value, err 0x%04x"), err_code);
+ while (!read_info.done) {
+ RUN_BACKGROUND_TASKS;
}
+ check_gatt_status(read_info.status);
- return value;
-}
-
-void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo) {
- // conn_handle might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because
- // we can still read and write the local value.
-
- ble_gatts_value_t gatts_value = {
- .p_value = bufinfo->buf,
- .len = bufinfo->len,
- };
-
- const uint32_t err_code = sd_ble_gatts_value_set(conn_handle, handle, &gatts_value);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to write gatts value, err 0x%04x"), err_code);
- }
+ ble_drv_remove_event_handler(_on_gattc_read_rsp_evt, &read_info);
+ return read_info.final_len;
}
void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, bool write_no_response) {
@@ -496,7 +223,11 @@ void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buff
}
// Some real error occurred.
- mp_raise_OSError_msg_varg(translate("Failed to write attribute value, err 0x%04x"), err_code);
+ check_nrf_error(err_code);
}
}
+
+void common_hal_bleio_gc_collect(void) {
+ bleio_adapter_gc_collect(&common_hal_bleio_adapter_obj);
+}
diff --git a/ports/nrf/common-hal/_bleio/__init__.h b/ports/nrf/common-hal/_bleio/__init__.h
index cf1a06945..ecacf7c85 100644
--- a/ports/nrf/common-hal/_bleio/__init__.h
+++ b/ports/nrf/common-hal/_bleio/__init__.h
@@ -39,4 +39,12 @@ typedef struct {
// 20 bytes max (23 - 3).
#define GATT_MAX_DATA_LENGTH (BLE_GATT_ATT_MTU_DEFAULT - 3)
+// These helpers raise the appropriate exceptions if the code doesn't equal success.
+void check_nrf_error(uint32_t err_code);
+void check_gatt_status(uint16_t gatt_status);
+void check_sec_status(uint8_t sec_status);
+
+// Track if the user code modified the BLE state to know if we need to undo it on reload.
+bool vm_used_ble;
+
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H
diff --git a/ports/nrf/common-hal/audiobusio/I2SOut.c b/ports/nrf/common-hal/audiobusio/I2SOut.c
index ac369277f..ead92b000 100644
--- a/ports/nrf/common-hal/audiobusio/I2SOut.c
+++ b/ports/nrf/common-hal/audiobusio/I2SOut.c
@@ -108,6 +108,7 @@ void choose_i2s_clocking(audiobusio_i2sout_obj_t *self, uint32_t sample_rate) {
static void i2s_buffer_fill(audiobusio_i2sout_obj_t* self) {
void *buffer = self->buffers[self->next_buffer];
+ void *buffer_start = buffer;
NRF_I2S->TXD.PTR = (uintptr_t)buffer;
self->next_buffer = !self->next_buffer;
size_t bytesleft = self->buffer_length;
@@ -139,14 +140,14 @@ static void i2s_buffer_fill(audiobusio_i2sout_obj_t* self) {
uint16_t *bp = (uint16_t*)buffer;
uint16_t *be = (uint16_t*)(buffer + bytecount);
uint16_t *sp = (uint16_t*)self->sample_data;
- for (; bp != be; bp++) {
+ for (; bp < be;) {
*bp++ = *sp++ + 0x8000;
}
} else {
uint8_t *bp = (uint8_t*)buffer;
uint8_t *be = (uint8_t*)(buffer + bytecount);
uint8_t *sp = (uint8_t*)self->sample_data;
- for (; bp != be; bp++) {
+ for (; bp < be;) {
*bp++ = *sp++ + 0x80;
}
}
@@ -157,15 +158,17 @@ static void i2s_buffer_fill(audiobusio_i2sout_obj_t* self) {
// Find the last frame of real audio data and replicate its samples until
// you have 32 bits worth, which is the fundamental unit of nRF I2S DMA
- if (self->bytes_per_sample == 1 && self->channel_count == 1) {
- // For 8-bit mono, 4 copies of the final sample are required
- self->hold_value = 0x01010101 * *(uint8_t*)(buffer-1);
- } else if (self->bytes_per_sample == 2 && self->channel_count == 2) {
- // For 16-bit stereo, 1 copy of the final sample is required
- self->hold_value = *(uint32_t*)(buffer-4);
- } else {
- // For 8-bit stereo and 16-bit mono, 2 copies of the final sample are required
- self->hold_value = 0x00010001 * *(uint16_t*)(buffer-2);
+ if(buffer != buffer_start) {
+ if (self->bytes_per_sample == 1 && self->channel_count == 1) {
+ // For 8-bit mono, 4 copies of the final sample are required
+ self->hold_value = 0x01010101 * *(uint8_t*)(buffer-1);
+ } else if (self->bytes_per_sample == 2 && self->channel_count == 2) {
+ // For 16-bit stereo, 1 copy of the final sample is required
+ self->hold_value = *(uint32_t*)(buffer-4);
+ } else {
+ // For 8-bit stereo and 16-bit mono, 2 copies of the final sample are required
+ self->hold_value = 0x00010001 * *(uint16_t*)(buffer-2);
+ }
}
// Emulate pausing and stopping by filling the DMA buffer with copies of
@@ -218,6 +221,8 @@ void common_hal_audiobusio_i2sout_deinit(audiobusio_i2sout_obj_t* self) {
if (common_hal_audiobusio_i2sout_deinited(self)) {
return;
}
+ NRF_I2S->TASKS_STOP = 1;
+ NRF_I2S->ENABLE = I2S_ENABLE_ENABLE_Disabled;
reset_pin_number(self->bit_clock_pin_number);
self->bit_clock_pin_number = 0xff;
reset_pin_number(self->word_select_pin_number);
@@ -240,12 +245,20 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t* self,
uint32_t max_buffer_length;
bool single_buffer, samples_signed;
- audiosample_get_buffer_structure(sample, /* single channel */ false,
+ audiosample_get_buffer_structure(sample, /* single channel */ true,
&single_buffer, &samples_signed, &max_buffer_length,
&self->channel_count);
self->single_buffer = single_buffer;
self->samples_signed = samples_signed;
+
+ NRF_I2S->CONFIG.SWIDTH = self->bytes_per_sample == 1
+ ? I2S_CONFIG_SWIDTH_SWIDTH_8Bit
+ : I2S_CONFIG_SWIDTH_SWIDTH_16Bit;
+ NRF_I2S->CONFIG.CHANNELS = self->channel_count == 1
+ ? I2S_CONFIG_CHANNELS_CHANNELS_Left
+ : I2S_CONFIG_CHANNELS_CHANNELS_Stereo;
+
choose_i2s_clocking(self, sample_rate);
/* Allocate buffers based on a maximum duration
* This duration was chosen empirically based on what would
@@ -269,9 +282,6 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t* self,
self->stopping = false;
i2s_buffer_fill(self);
- NRF_I2S->CONFIG.CHANNELS = self->channel_count == 1 ? I2S_CONFIG_CHANNELS_CHANNELS_Left : I2S_CONFIG_CHANNELS_CHANNELS_Stereo;
-
-
NRF_I2S->RXTXD.MAXCNT = self->buffer_length / 4;
NRF_I2S->ENABLE = I2S_ENABLE_ENABLE_Enabled;
diff --git a/ports/nrf/common-hal/busio/I2C.c b/ports/nrf/common-hal/busio/I2C.c
index 71835d16a..8a2ebde3b 100644
--- a/ports/nrf/common-hal/busio/I2C.c
+++ b/ports/nrf/common-hal/busio/I2C.c
@@ -28,13 +28,12 @@
*/
#include "shared-bindings/busio/I2C.h"
+#include "shared-bindings/microcontroller/__init__.h"
#include "py/mperrno.h"
#include "py/runtime.h"
#include "supervisor/shared/translate.h"
#include "nrfx_twim.h"
-#include "nrf_gpio.h"
-
#include "nrfx_spim.h"
#include "nrf_gpio.h"
@@ -107,7 +106,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *
for (size_t i = 0 ; i < MP_ARRAY_SIZE(twim_peripherals); i++) {
if (!twim_peripherals[i].in_use) {
self->twim_peripheral = &twim_peripherals[i];
- self->twim_peripheral->in_use = true;
+ // Mark it as in_use later after other validation is finished.
break;
}
}
@@ -116,10 +115,27 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *
mp_raise_ValueError(translate("All I2C peripherals are in use"));
}
+ // Test that the pins are in a high state. (Hopefully indicating they are pulled up.)
+ nrf_gpio_cfg_input(scl->number, NRF_GPIO_PIN_PULLDOWN);
+ nrf_gpio_cfg_input(sda->number, NRF_GPIO_PIN_PULLDOWN);
+
+ common_hal_mcu_delay_us(10);
+
+ nrf_gpio_cfg_input(scl->number, NRF_GPIO_PIN_NOPULL);
+ nrf_gpio_cfg_input(sda->number, NRF_GPIO_PIN_NOPULL);
+
+ // We must pull up within 3us to achieve 400khz.
+ common_hal_mcu_delay_us(3);
+
+ if (!nrf_gpio_pin_read(sda->number) || !nrf_gpio_pin_read(scl->number)) {
+ reset_pin_number(sda->number);
+ reset_pin_number(scl->number);
+ mp_raise_RuntimeError(translate("SDA or SCL needs a pull up"));
+ }
+
nrfx_twim_config_t config = NRFX_TWIM_DEFAULT_CONFIG;
config.scl = scl->number;
config.sda = sda->number;
-
// change freq. only if it's less than the default 400K
if (frequency < 100000) {
config.frequency = NRF_TWIM_FREQ_100K;
@@ -132,6 +148,8 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *
claim_pin(sda);
claim_pin(scl);
+ // About to init. If we fail after this point, common_hal_busio_i2c_deinit() will set in_use to false.
+ self->twim_peripheral->in_use = true;
nrfx_err_t err = nrfx_twim_init(&self->twim_peripheral->twim, &config, NULL, NULL);
// A soft reset doesn't uninit the driver so we might end up with a invalid state
@@ -152,8 +170,9 @@ bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) {
}
void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
- if (common_hal_busio_i2c_deinited(self))
+ if (common_hal_busio_i2c_deinited(self)) {
return;
+ }
nrfx_twim_uninit(&self->twim_peripheral->twim);
diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c
index 54a66ddbe..9cdc197e7 100644
--- a/ports/nrf/common-hal/busio/UART.c
+++ b/ports/nrf/common-hal/busio/UART.c
@@ -231,10 +231,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
}
size_t rx_bytes = 0;
- uint64_t start_ticks = ticks_ms;
+ uint64_t start_ticks = supervisor_ticks_ms64();
// Wait for all bytes received or timeout
- while ( (ringbuf_count(&self->rbuf) < len) && (ticks_ms - start_ticks < self->timeout_ms) ) {
+ while ( (ringbuf_count(&self->rbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS;
// Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) {
@@ -265,19 +265,6 @@ size_t common_hal_busio_uart_write (busio_uart_obj_t *self, const uint8_t *data,
if ( len == 0 ) return 0;
- uint64_t start_ticks = ticks_ms;
-
- // Wait for on-going transfer to complete
- while ( nrfx_uarte_tx_in_progress(self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) {
- RUN_BACKGROUND_TASKS;
- }
-
- // Time up
- if ( !(ticks_ms - start_ticks < self->timeout_ms) ) {
- *errcode = MP_EAGAIN;
- return MP_STREAM_ERROR;
- }
-
// EasyDMA can only access SRAM
uint8_t * tx_buf = (uint8_t*) data;
if ( !nrfx_is_in_ram(data) ) {
@@ -290,7 +277,8 @@ size_t common_hal_busio_uart_write (busio_uart_obj_t *self, const uint8_t *data,
_VERIFY_ERR(*errcode);
(*errcode) = 0;
- while ( nrfx_uarte_tx_in_progress(self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) {
+ // Wait for write to complete.
+ while ( nrfx_uarte_tx_in_progress(self->uarte) ) {
RUN_BACKGROUND_TASKS;
}
@@ -310,6 +298,14 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat
nrf_uarte_baudrate_set(self->uarte->p_reg, get_nrf_baud(baudrate));
}
+mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) {
+ return (mp_float_t) (self->timeout_ms / 1000.0f);
+}
+
+void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) {
+ self->timeout_ms = timeout * 1000;
+}
+
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
return ringbuf_count(&self->rbuf);
}
diff --git a/ports/nrf/common-hal/microcontroller/Pin.c b/ports/nrf/common-hal/microcontroller/Pin.c
index 3cee784b6..b7931a2e1 100644
--- a/ports/nrf/common-hal/microcontroller/Pin.c
+++ b/ports/nrf/common-hal/microcontroller/Pin.c
@@ -25,6 +25,7 @@
*/
#include "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/digitalio/DigitalInOut.h"
#include "nrf_gpio.h"
#include "py/mphal.h"
@@ -47,6 +48,19 @@ bool speaker_enable_in_use;
STATIC uint32_t claimed_pins[GPIO_COUNT];
STATIC uint32_t never_reset_pins[GPIO_COUNT];
+STATIC void reset_speaker_enable_pin(void) {
+#ifdef SPEAKER_ENABLE_PIN
+ speaker_enable_in_use = false;
+ nrf_gpio_cfg(SPEAKER_ENABLE_PIN->number,
+ NRF_GPIO_PIN_DIR_OUTPUT,
+ NRF_GPIO_PIN_INPUT_DISCONNECT,
+ NRF_GPIO_PIN_NOPULL,
+ NRF_GPIO_PIN_H0H1,
+ NRF_GPIO_PIN_NOSENSE);
+ nrf_gpio_pin_write(SPEAKER_ENABLE_PIN->number, false);
+#endif
+}
+
void reset_all_pins(void) {
for (size_t i = 0; i < GPIO_COUNT; i++) {
claimed_pins[i] = never_reset_pins[i];
@@ -68,10 +82,7 @@ void reset_all_pins(void) {
#endif
// After configuring SWD because it may be shared.
- #ifdef SPEAKER_ENABLE_PIN
- speaker_enable_in_use = false;
- // TODO set pin to out and turn off.
- #endif
+ reset_speaker_enable_pin();
}
// Mark pin as free and return it to a quiescent state.
@@ -91,8 +102,8 @@ void reset_pin_number(uint8_t pin_number) {
}
#endif
#ifdef MICROPY_HW_APA102_MOSI
- if (pin == MICROPY_HW_APA102_MOSI->number ||
- pin == MICROPY_HW_APA102_SCK->number) {
+ if (pin_number == MICROPY_HW_APA102_MOSI->number ||
+ pin_number == MICROPY_HW_APA102_SCK->number) {
apa102_mosi_in_use = apa102_mosi_in_use && pin_number != MICROPY_HW_APA102_MOSI->number;
apa102_sck_in_use = apa102_sck_in_use && pin_number != MICROPY_HW_APA102_SCK->number;
if (!apa102_sck_in_use && !apa102_mosi_in_use) {
@@ -104,10 +115,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(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);
+ reset_speaker_enable_pin();
}
#endif
}
@@ -117,6 +125,14 @@ void never_reset_pin_number(uint8_t pin_number) {
never_reset_pins[nrf_pin_port(pin_number)] |= 1 << nrf_relative_pin_number(pin_number);
}
+void common_hal_never_reset_pin(const mcu_pin_obj_t* pin) {
+ never_reset_pin_number(pin->number);
+}
+
+void common_hal_reset_pin(const mcu_pin_obj_t* pin) {
+ reset_pin_number(pin->number);
+}
+
void claim_pin(const mcu_pin_obj_t* pin) {
// Set bit in claimed_pins bitmask.
claimed_pins[nrf_pin_port(pin->number)] |= 1 << nrf_relative_pin_number(pin->number);
diff --git a/ports/nrf/common-hal/microcontroller/__init__.c b/ports/nrf/common-hal/microcontroller/__init__.c
index eea3d43ce..de924566c 100644
--- a/ports/nrf/common-hal/microcontroller/__init__.c
+++ b/ports/nrf/common-hal/microcontroller/__init__.c
@@ -81,8 +81,8 @@ const mcu_processor_obj_t common_hal_mcu_processor_obj = {
const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = {
.base = {
.type = &nvm_bytearray_type,
- }
- .start_address = CIRCUITPY_INTERNAL_NVM_ADDRESS,
+ },
+ .start_address = (uint8_t*) CIRCUITPY_INTERNAL_NVM_START_ADDR,
.len = CIRCUITPY_INTERNAL_NVM_SIZE,
};
#endif
diff --git a/ports/nrf/common-hal/nvm/ByteArray.c b/ports/nrf/common-hal/nvm/ByteArray.c
index 416768101..d4027a1b1 100644
--- a/ports/nrf/common-hal/nvm/ByteArray.c
+++ b/ports/nrf/common-hal/nvm/ByteArray.c
@@ -52,7 +52,7 @@ static void write_page(uint32_t page_addr, uint32_t offset, uint32_t len, uint8_
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 = self->start_address + start_index;
+ uint32_t address = (uint32_t) self->start_address + start_index;
uint32_t offset = address % FLASH_PAGE_SIZE;
uint32_t page_addr = address - offset;
diff --git a/ports/nrf/common-hal/time/__init__.c b/ports/nrf/common-hal/time/__init__.c
index e3cb481ef..976f519db 100644
--- a/ports/nrf/common-hal/time/__init__.c
+++ b/ports/nrf/common-hal/time/__init__.c
@@ -29,7 +29,7 @@
#include "tick.h"
uint64_t common_hal_time_monotonic(void) {
- return ticks_ms;
+ return supervisor_ticks_ms64();
}
void common_hal_time_delay_ms(uint32_t delay) {
diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h
index 3cb086f31..00d4a51ad 100644
--- a/ports/nrf/mpconfigport.h
+++ b/ports/nrf/mpconfigport.h
@@ -30,6 +30,10 @@
#include "ble_drv.h"
+#ifdef NRF52840
+#define MICROPY_PY_SYS_PLATFORM "nRF52840"
+#endif
+
#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1)
#define MICROPY_PY_FUNCTION_ATTRS (1)
#define MICROPY_PY_IO (1)
@@ -41,10 +45,14 @@
// 24kiB stack
#define CIRCUITPY_DEFAULT_STACK_SIZE 0x6000
-#include "py/circuitpy_mpconfig.h"
+#if INTERNAL_FLASH_FILESYSTEM
+#define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE (64*1024)
+#else
+#define CIRCUITPYINTERNAL_FLASH_FILESYSTEM_SIZE (0)
+#endif
#ifndef CIRCUITPY_INTERNAL_NVM_SIZE
-#define CIRCUITPY_INTERNAL_NVM_SIZE (4096)
+#define CIRCUITPY_INTERNAL_NVM_SIZE (8192)
#endif
#ifndef BOARD_HAS_32KHZ_XTAL
@@ -52,6 +60,55 @@
#define BOARD_HAS_32KHZ_XTAL (1)
#endif
+// Flash layout, starting at 0x00000000
+//
+// SoftDevice
+// ISR
+// firmware
+// BLE config (bonding info, etc.) (optional)
+// microntroller.nvm (optional)
+// internal CIRCUITPY flash filesystem (optional)
+// bootloader (note the MBR at 0x0 redirects to the bootloader here, in high flash)
+// bootloader settings
+
+// Bootloader values from https://github.com/adafruit/Adafruit_nRF52_Bootloader/blob/master/src/linker/s140_v6.ld
+
+// Define these regions starting up from the bottom of flash:
+
+#define MBR_START_ADDR (0x0)
+// MBR_SIZE is from nrf_sdm.h
+#define SD_FLASH_START_ADDR (MBR_START_ADDR + MBR_SIZE)
+
+// SD_FLASH_SIZE is from nrf_sdm.h
+#define ISR_FLASH_START_ADDR (SD_FLASH_START_ADDR + SD_FLASH_SIZE)
+#define ISR_FLASH_SIZE (0x1000) // 4kiB
+
+#define CIRCUITPY_FIRMWARE_START_ADDR (ISR_FLASH_START_ADDR + ISR_FLASH_LENGTH)
+
+// Define these regions starting down from the bootloader:
+
+#define BOOTLOADER_START_ADDR (0x000F4000)
+#define BOOTLOADER_SIZE (0xA000) // 40kiB
+#define BOOTLOADER_SETTINGS_START_ADDR (0x000FF000)
+#define BOOTLOADER_SETTINGS_SIZE (0x1000) // 4kiB
+
+#define FLASH_FATFS_SIZE (256*1024)
+#define FLASH_FATFS_START_ADDR (BOOTLOADER_START_ADDR - FLASH_FATFS_SIZE)
+
+#define CIRCUITPY_INTERNAL_NVM_START_ADDR (FLASH_FATFS_START_ADDR - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define CIRCUITPY_BLE_CONFIG_SIZE (32*1024)
+#define CIRCUITPY_BLE_CONFIG_START_ADDR (CIRCUITPY_INTERNAL_NVM_START_ADDR - CIRCUITPY_BLE_CONFIG_SIZE)
+
+// The firmware space is the space left over between the fixed lower and upper regions.
+#define CIRCUITPY_FIRMWARE_SIZE (CIRCUITPY_BLE_CONFIG_START_ADDR - CIRCUITPY_FIRMWARE_START_ADDR)
+
+#if CIRCUITPY_FIRMWARE_SIZE < 0
+#error No space left in flash for firmware after specifying other regions!
+#endif
+
+#include "py/circuitpy_mpconfig.h"
+
#define MICROPY_PORT_ROOT_POINTERS \
CIRCUITPY_COMMON_ROOT_POINTERS \
ble_drv_evt_handler_entry_t* ble_drv_evt_handler_entries; \
diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk
index 02bde3eff..47cabffb5 100644
--- a/ports/nrf/mpconfigport.mk
+++ b/ports/nrf/mpconfigport.mk
@@ -1,3 +1,7 @@
+# All linking can be done with this common templated linker script, which has
+# parameters that vary based on chip and/or board.
+LD_TEMPLATE_FILE = boards/common.template.ld
+
# 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.
@@ -11,25 +15,58 @@ USB_SERIAL_NUMBER_LENGTH = 16
LONGINT_IMPL = MPZ
# Audio via PWM
+ifndef CIRCUITPY_AUDIOCORE
CIRCUITPY_AUDIOCORE = 1
+endif
+
CIRCUITPY_AUDIOIO = 0
+
+
+# The ifndef's allow overriding in mpconfigboard.mk.
+
+ifndef
+CIRCUITPY_BLEIO = 1
+endif
+
+ifndef CIRCUITPY_AUDIOMIXER
CIRCUITPY_AUDIOMIXER = 1
+endif
+
+ifndef CIRCUITPY_AUDIOPWMIO
CIRCUITPY_AUDIOPWMIO = 1
+endif
+
+ifndef CIRCUITPY_AUDIOBUSIO
CIRCUITPY_AUDIOBUSIO = 1
+endif
# No I2CSlave implementation
CIRCUITPY_I2CSLAVE = 0
-# enable NVM
-CIRCUITPY_NVM = 1
-
# enable RTC
+ifndef CIRCUITPY_RTC
CIRCUITPY_RTC = 1
+endif
# frequencyio not yet implemented
CIRCUITPY_FREQUENCYIO = 0
+# nRF52840-specific
+
+ifeq($(MCU_CHIP),nrf52840)
+MCU_SERIES = m4
+MCU_VARIANT = nrf52
+MCU_SUB_VARIANT = nrf52840
+
+SD ?= s140
+SOFTDEV_VERSION ?= 6.1.0
+
+BOOT_SETTING_ADDR = 0xFF000
+NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
+
# CircuitPython doesn't yet support NFC so force the NFC antenna pins to be GPIO.
# See https://github.com/adafruit/circuitpython/issues/1300
# Defined here because system_nrf52840.c doesn't #include any of our own include files.
CFLAGS += -DCONFIG_NFCT_PINS_AS_GPIOS
+
+endif
diff --git a/ports/nrf/mphalport.c b/ports/nrf/mphalport.c
index bcd9fb114..3885d5a82 100644
--- a/ports/nrf/mphalport.c
+++ b/ports/nrf/mphalport.c
@@ -31,12 +31,13 @@
#include "py/mphal.h"
#include "py/mpstate.h"
#include "py/gc.h"
+#include "supervisor/shared/tick.h"
/*------------------------------------------------------------------*/
/* delay
*------------------------------------------------------------------*/
void mp_hal_delay_ms(mp_uint_t delay) {
- uint64_t start_tick = ticks_ms;
+ uint64_t start_tick = supervisor_ticks_ms64();
uint64_t duration = 0;
while (duration < delay) {
RUN_BACKGROUND_TASKS;
@@ -45,7 +46,7 @@ void mp_hal_delay_ms(mp_uint_t delay) {
MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
break;
}
- duration = (ticks_ms - start_tick);
+ duration = (supervisor_ticks_ms64() - start_tick);
// TODO(tannewt): Go to sleep for a little while while we wait.
}
}
diff --git a/ports/nrf/mphalport.h b/ports/nrf/mphalport.h
index a1929a4ac..8bb351401 100644
--- a/ports/nrf/mphalport.h
+++ b/ports/nrf/mphalport.h
@@ -33,12 +33,11 @@
#include "lib/utils/interrupt_char.h"
#include "nrfx_uarte.h"
#include "py/mpconfig.h"
+#include "supervisor/shared/tick.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_ticks_ms() ((mp_uint_t) supervisor_ticks_ms32())
#define mp_hal_delay_us(us) NRFX_DELAY_US((uint32_t) (us))
bool mp_hal_stdin_any(void);
diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h
index 8fa6721e2..cafec6aa1 100644
--- a/ports/nrf/nrfx_config.h
+++ b/ports/nrf/nrfx_config.h
@@ -5,12 +5,9 @@
#define NRFX_POWER_ENABLED 1
#define NRFX_POWER_CONFIG_IRQ_PRIORITY 7
-// Turn on nrfx supported workarounds for errata in Rev1/Rev2 of nRF52832
-#ifdef NRF52832_XXAA
- #define NRFX_SPIS_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1
-#endif
-
-// NOTE: THIS WORKAROUND CAUSES BLE CODE TO CRASH; tested on 2019-03-11.
+// NOTE: THIS WORKAROUND CAUSES BLE CODE TO CRASH.
+// It doesn't work with the SoftDevice.
+// See https://devzone.nordicsemi.com/f/nordic-q-a/33982/sdk-15-software-crash-during-spi-session
// Turn on nrfx supported workarounds for errata in Rev1 of nRF52840
#ifdef NRF52840_XXAA
// #define NRFX_SPIM3_NRF52840_ANOMALY_198_WORKAROUND_ENABLED 1
@@ -24,11 +21,26 @@
// so out of the box TWIM0/SPIM0 and TWIM1/SPIM1 cannot be shared
// between common-hal/busio/I2C.c and SPI.c.
// We could write an interrupt handler that checks whether it's
-// being used for SPI or I2C, but perhaps two I2C's and 1-2 SPI's are good enough for now.
+// being used for SPI or I2C, but perhaps one I2C and two SPI or two I2C and one SPI
+// are good enough for now.
+
+// CIRCUITPY_NRF_NUM_I2C is 1 or 2 to choose how many I2C (TWIM) peripherals
+// to provide.
+// This can go away once we have SPIM3 working: then we can have two
+// I2C and two SPI.
+#ifndef CIRCUITPY_NRF_NUM_I2C
+#define CIRCUITPY_NRF_NUM_I2C 1
+#endif
+
+#if CIRCUITPY_NRF_NUM_I2C != 1 && CIRCUITPY_NRF_NUM_I2C != 2
+# error CIRCUITPY_NRF_NUM_I2C must be 1 or 2
+#endif
// Enable SPIM1, SPIM2 and SPIM3 (if available)
// No conflict with TWIM0.
+#if CIRCUITPY_NRF_NUM_I2C == 1
#define NRFX_SPIM1_ENABLED 1
+#endif
#define NRFX_SPIM2_ENABLED 1
// DON'T ENABLE SPIM3 DUE TO ANOMALY WORKAROUND FAILURE (SEE ABOVE).
// #ifdef NRF52840_XXAA
@@ -45,10 +57,13 @@
// QSPI
#define NRFX_QSPI_ENABLED 1
-// TWI aka. I2C; enable a single bus: TWIM0 (no conflict with SPIM1 and SPIM2)
+// TWI aka. I2C; always enable TWIM0 (no conflict with SPIM1 and SPIM2)
#define NRFX_TWIM_ENABLED 1
#define NRFX_TWIM0_ENABLED 1
-//#define NRFX_TWIM1_ENABLED 1
+
+#if CIRCUITPY_NRF_NUM_I2C == 2
+#define NRFX_TWIM1_ENABLED 1
+#endif
#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY 7
#define NRFX_TWIM_DEFAULT_CONFIG_FREQUENCY NRF_TWIM_FREQ_400K
diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c
index c69101070..af858aa4a 100644
--- a/ports/nrf/supervisor/port.c
+++ b/ports/nrf/supervisor/port.c
@@ -146,6 +146,14 @@ void reset_cpu(void) {
NVIC_SystemReset();
}
+uint32_t *port_stack_get_limit(void) {
+ return &_ebss;
+}
+
+uint32_t *port_stack_get_top(void) {
+ return &_estack;
+}
+
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) {
diff --git a/ports/nrf/tick.c b/ports/nrf/tick.c
index 1a9e69a8c..ac825a7f1 100644
--- a/ports/nrf/tick.c
+++ b/ports/nrf/tick.c
@@ -26,31 +26,14 @@
#include "tick.h"
-#include "supervisor/shared/autoreload.h"
-#include "supervisor/filesystem.h"
+#include "supervisor/shared/tick.h"
#include "shared-module/gamepad/__init__.h"
#include "shared-bindings/microcontroller/Processor.h"
#include "nrf.h"
-// Global millisecond tick count
-volatile uint64_t ticks_ms = 0;
-
void SysTick_Handler(void) {
- // SysTick interrupt handler called when the SysTick timer reaches zero
- // (every millisecond).
- ticks_ms += 1;
-
-#if CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS > 0
- filesystem_tick();
-#endif
-#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
- autoreload_tick();
-#endif
-#ifdef CIRCUITPY_GAMEPAD_TICKS
- if (!(ticks_ms & CIRCUITPY_GAMEPAD_TICKS)) {
- gamepad_tick();
- }
-#endif
+ // Do things common to all ports when the tick occurs
+ supervisor_tick();
}
void tick_init() {
@@ -61,11 +44,11 @@ void tick_init() {
void tick_delay(uint32_t us) {
uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000;
uint32_t us_between_ticks = SysTick->VAL / ticks_per_us;
- uint64_t start_ms = ticks_ms;
+ uint64_t start_ms = supervisor_ticks_ms64();
while (us > 1000) {
- while (ticks_ms == start_ms) {}
+ while (supervisor_ticks_ms64() == start_ms) {}
us -= us_between_ticks;
- start_ms = ticks_ms;
+ start_ms = supervisor_ticks_ms64();
us_between_ticks = 1000;
}
while (SysTick->VAL > ((us_between_ticks - us) * ticks_per_us)) {}
@@ -74,11 +57,11 @@ void tick_delay(uint32_t us) {
// us counts down!
void current_tick(uint64_t* ms, uint32_t* us_until_ms) {
uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000;
- *ms = ticks_ms;
+ *ms = supervisor_ticks_ms64();
*us_until_ms = SysTick->VAL / ticks_per_us;
}
void wait_until(uint64_t ms, uint32_t us_until_ms) {
uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000;
- while(ticks_ms <= ms && SysTick->VAL / ticks_per_us >= us_until_ms) {}
+ while(supervisor_ticks_ms64() <= ms && SysTick->VAL / ticks_per_us >= us_until_ms) {}
}
diff --git a/ports/nrf/tick.h b/ports/nrf/tick.h
index 838e9fbea..d638ad025 100644
--- a/ports/nrf/tick.h
+++ b/ports/nrf/tick.h
@@ -30,8 +30,6 @@
#include <stdint.h>
-extern volatile uint64_t ticks_ms;
-
extern struct timer_descriptor ms_timer;
void tick_init(void);
diff --git a/ports/stm32f4/Makefile b/ports/stm32f4/Makefile
index 4b660f244..2727ea954 100755
--- a/ports/stm32f4/Makefile
+++ b/ports/stm32f4/Makefile
@@ -121,7 +121,7 @@ LIBS += -lm
endif
# TinyUSB defines
-CFLAGS += -DHSE_VALUE=8000000 -DCFG_TUSB_MCU=OPT_MCU_STM32F4 -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_CDC_TX_BUFSIZE=1024 -DCFG_TUD_MSC_BUFSIZE=4096 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_MIDI_TX_BUFSIZE=128
+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
######################################
diff --git a/shared-bindings/_bleio/Scanner.h b/ports/stm32f4/boards/feather_stm32f405_express/board.c
index cbaa77866..82b0c506e 100644
--- a/shared-bindings/_bleio/Scanner.h
+++ b/ports/stm32f4/boards/feather_stm32f405_express/board.c
@@ -3,8 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2019 Dan Halbert for Adafruit Industries
- * 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
@@ -25,16 +24,16 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H
+#include "boards/board.h"
+#include "mpconfigboard.h"
-#include "py/objtype.h"
-#include "common-hal/_bleio/Scanner.h"
+void board_init(void) {
+}
-extern const mp_obj_type_t bleio_scanner_type;
+bool board_requests_safe_mode(void) {
+ return false;
+}
-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);
+void reset_board(void) {
-#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H
+}
diff --git a/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.h b/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.h
new file mode 100644
index 000000000..a1d83a25a
--- /dev/null
+++ b/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.h
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+//Micropython setup
+
+#define MICROPY_HW_BOARD_NAME "Feather STM32F405 Express"
+#define MICROPY_HW_MCU_NAME "STM32F405RG"
+
+#define FLASH_SIZE (0x100000)
+#define FLASH_PAGE_SIZE (0x4000)
+
+#define MICROPY_HW_NEOPIXEL (&pin_PC00)
+
+// On-board flash
+#define SPI_FLASH_MOSI_PIN (&pin_PB05)
+#define SPI_FLASH_MISO_PIN (&pin_PB04)
+#define SPI_FLASH_SCK_PIN (&pin_PB03)
+#define SPI_FLASH_CS_PIN (&pin_PA15)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PB06)
+#define DEFAULT_I2C_BUS_SDA (&pin_PB07)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PB13)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PB15)
+#define DEFAULT_SPI_BUS_MISO (&pin_PB14)
+
+#define DEFAULT_UART_BUS_RX (&pin_PB11)
+#define DEFAULT_UART_BUS_TX (&pin_PB10)
diff --git a/ports/stm32f4/boards/feather_f405/mpconfigboard.mk b/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.mk
index 789dc0f05..5bad4e81f 100644
--- a/ports/stm32f4/boards/feather_f405/mpconfigboard.mk
+++ b/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.mk
@@ -1,6 +1,6 @@
USB_VID = 0x239A
USB_PID = 0x805A
-USB_PRODUCT = "Feather F405"
+USB_PRODUCT = "Feather STM32F405 Express"
USB_MANUFACTURER = "Adafruit Industries LLC"
USB_DEVICES = "CDC,MSC"
diff --git a/ports/stm32f4/boards/feather_f405/pins.c b/ports/stm32f4/boards/feather_stm32f405_express/pins.c
index 518ab6d2a..180fdd093 100644
--- a/ports/stm32f4/boards/feather_f405/pins.c
+++ b/ports/stm32f4/boards/feather_stm32f405_express/pins.c
@@ -25,5 +25,10 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB10) },
{ MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB11) },
+
+ { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PC00) },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
};
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/stm32f4/boards/feather_f405/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/feather_stm32f405_express/stm32f4xx_hal_conf.h
index a13e5ecfa..8031403a9 100644
--- a/ports/stm32f4/boards/feather_f405/stm32f4xx_hal_conf.h
+++ b/ports/stm32f4/boards/feather_stm32f405_express/stm32f4xx_hal_conf.h
@@ -55,15 +55,15 @@
#define HAL_I2S_MODULE_ENABLED
/* #define HAL_IWDG_MODULE_ENABLED */
/* #define HAL_LTDC_MODULE_ENABLED */
-/* #define HAL_RNG_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_TIM_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED
-/* #define HAL_USART_MODULE_ENABLED */
+#define HAL_USART_MODULE_ENABLED
/* #define HAL_IRDA_MODULE_ENABLED */
/* #define HAL_SMARTCARD_MODULE_ENABLED */
/* #define HAL_WWDG_MODULE_ENABLED */
diff --git a/ports/stm32f4/boards/pyboard_v11/mpconfigboard.h b/ports/stm32f4/boards/pyboard_v11/mpconfigboard.h
index d793a222f..7093442d0 100644
--- a/ports/stm32f4/boards/pyboard_v11/mpconfigboard.h
+++ b/ports/stm32f4/boards/pyboard_v11/mpconfigboard.h
@@ -3,8 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
- * 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
@@ -32,3 +31,7 @@
#define FLASH_SIZE (0x100000)
#define FLASH_PAGE_SIZE (0x4000)
+
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PB06)
+#define DEFAULT_I2C_BUS_SDA (&pin_PB07)
diff --git a/ports/stm32f4/boards/pyboard_v11/pins.c b/ports/stm32f4/boards/pyboard_v11/pins.c
index ccbb58ab9..8783dfcf1 100644
--- a/ports/stm32f4/boards/pyboard_v11/pins.c
+++ b/ports/stm32f4/boards/pyboard_v11/pins.c
@@ -46,5 +46,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB06) },
{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB07) },
+
+ { 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/stm32f4/boards/pyboard_v11/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/pyboard_v11/stm32f4xx_hal_conf.h
index a13e5ecfa..4dc18cb7f 100644
--- a/ports/stm32f4/boards/pyboard_v11/stm32f4xx_hal_conf.h
+++ b/ports/stm32f4/boards/pyboard_v11/stm32f4xx_hal_conf.h
@@ -55,13 +55,13 @@
#define HAL_I2S_MODULE_ENABLED
/* #define HAL_IWDG_MODULE_ENABLED */
/* #define HAL_LTDC_MODULE_ENABLED */
-/* #define HAL_RNG_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_TIM_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED
/* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_IRDA_MODULE_ENABLED */
diff --git a/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h b/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h
index 5bea08975..8a4fe11ad 100644
--- a/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h
+++ b/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h
@@ -3,8 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
- * 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
diff --git a/ports/stm32f4/boards/stm32f411ve_discovery/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/stm32f411ve_discovery/stm32f4xx_hal_conf.h
index b244a69b5..18d9d60eb 100644
--- a/ports/stm32f4/boards/stm32f411ve_discovery/stm32f4xx_hal_conf.h
+++ b/ports/stm32f4/boards/stm32f411ve_discovery/stm32f4xx_hal_conf.h
@@ -61,7 +61,7 @@
/* #define HAL_SD_MODULE_ENABLED */
/* #define HAL_MMC_MODULE_ENABLED */
#define HAL_SPI_MODULE_ENABLED
-/* #define HAL_TIM_MODULE_ENABLED */
+#define HAL_TIM_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED
/* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_IRDA_MODULE_ENABLED */
diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h
index 9e23f1db5..1d47142a8 100644
--- a/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h
+++ b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h
@@ -3,8 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
- * 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
@@ -32,3 +31,6 @@
#define FLASH_SIZE (0x100000)
#define FLASH_PAGE_SIZE (0x4000)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PB10)
+#define DEFAULT_I2C_BUS_SDA (&pin_PB09) \ No newline at end of file
diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk
index 509a24410..d642f243e 100644
--- a/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk
+++ b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk
@@ -2,6 +2,7 @@ USB_VID = 0x239A
USB_PID = 0x8056
USB_PRODUCT = "STM32F412ZG Discovery Board - CPy"
USB_MANUFACTURER = "STMicroelectronics"
+USB_DEVICES = "CDC,MSC,HID"
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/pins.c b/ports/stm32f4/boards/stm32f412zg_discovery/pins.c
index a0b477a47..ab90b0455 100644
--- a/ports/stm32f4/boards/stm32f412zg_discovery/pins.c
+++ b/ports/stm32f4/boards/stm32f412zg_discovery/pins.c
@@ -74,8 +74,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ 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_D1), MP_ROM_PTR(&pin_PG14) }, //USART6 TX
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PG09) }, //USART6 RX
{ 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) },
@@ -88,5 +88,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ 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_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/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h
index 2ad0fee20..f1b401348 100644
--- a/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h
+++ b/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h
@@ -55,13 +55,13 @@
#define HAL_I2S_MODULE_ENABLED
/* #define HAL_IWDG_MODULE_ENABLED */
/* #define HAL_LTDC_MODULE_ENABLED */
-/* #define HAL_RNG_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_TIM_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED
/* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_IRDA_MODULE_ENABLED */
diff --git a/ports/stm32f4/common-hal/analogio/AnalogOut.c b/ports/stm32f4/common-hal/analogio/AnalogOut.c
index 5eb8c2dc0..79ced0492 100644
--- a/ports/stm32f4/common-hal/analogio/AnalogOut.c
+++ b/ports/stm32f4/common-hal/analogio/AnalogOut.c
@@ -40,12 +40,12 @@
#include "stm32f4xx_hal.h"
//DAC is shared between both channels.
-//TODO: store as struct with channel info, automatically turn it off if unused
-//on both channels for power save?
#if HAS_DAC
DAC_HandleTypeDef handle;
#endif
+STATIC bool dac_on[2];
+
void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self,
const mcu_pin_obj_t *pin) {
#if !(HAS_DAC)
@@ -53,8 +53,10 @@ void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self,
#else
if (pin == &pin_PA04) {
self->channel = DAC_CHANNEL_1;
+ self->dac_index = 0;
} else if (pin == &pin_PA05) {
self->channel = DAC_CHANNEL_2;
+ self->dac_index = 1;
} else {
mp_raise_ValueError(translate("Invalid DAC pin supplied"));
}
@@ -82,22 +84,27 @@ void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self,
mp_raise_ValueError(translate("DAC Channel Init Error"));
}
+ dac_on[self->dac_index] = true;
self->pin = pin;
- self->deinited = false;
claim_pin(pin);
#endif
}
bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) {
- return self->deinited;
+ return !dac_on[self->dac_index];
}
void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) {
#if HAS_DAC
reset_pin_number(self->pin->port,self->pin->number);
self->pin = mp_const_none;
- self->deinited = true;
- //TODO: if both are de-inited, should we turn off the DAC?
+ dac_on[self->dac_index] = false;
+
+ //turn off the DAC if both channels are off
+ if(dac_on[0] == false && dac_on[1] == false) {
+ __HAL_RCC_DAC_CLK_DISABLE();
+ HAL_DAC_DeInit(&handle);
+ }
#endif
}
diff --git a/ports/stm32f4/common-hal/analogio/AnalogOut.h b/ports/stm32f4/common-hal/analogio/AnalogOut.h
index 1381d4d3a..61591d0e6 100644
--- a/ports/stm32f4/common-hal/analogio/AnalogOut.h
+++ b/ports/stm32f4/common-hal/analogio/AnalogOut.h
@@ -41,7 +41,7 @@ typedef struct {
#endif
const mcu_pin_obj_t * pin;
uint8_t channel;
- bool deinited;
+ uint8_t dac_index:1;
} analogio_analogout_obj_t;
void analogout_reset(void);
diff --git a/ports/stm32f4/common-hal/busio/SPI.c b/ports/stm32f4/common-hal/busio/SPI.c
index e20bd7a94..b5517f470 100644
--- a/ports/stm32f4/common-hal/busio/SPI.c
+++ b/ports/stm32f4/common-hal/busio/SPI.c
@@ -36,46 +36,37 @@
#include "supervisor/shared/translate.h"
#include "common-hal/microcontroller/Pin.h"
-STATIC bool reserved_spi[6];
-STATIC bool never_reset_spi[6];
+#define MAX_SPI 6 //TODO; replace this as part of periph cleanup
+#define ALL_CLOCKS 0xFF
-void spi_reset(void) {
- #ifdef SPI1
- if(!never_reset_spi[0]) {
- reserved_spi[0] = false;
- __HAL_RCC_SPI1_CLK_DISABLE();
- }
- #endif
+//arrays use 0 based numbering: SPI1 is stored at index 0
+STATIC bool reserved_spi[MAX_SPI];
+STATIC bool never_reset_spi[MAX_SPI];
+
+STATIC void spi_clock_enable(uint8_t mask);
+STATIC void spi_clock_disable(uint8_t mask);
+
+STATIC uint32_t get_busclock(SPI_TypeDef * instance) {
+ //SPI2 and 3 are on PCLK1, if they exist.
#ifdef SPI2
- if(!never_reset_spi[1]) {
- reserved_spi[1] = false;
- __HAL_RCC_SPI2_CLK_DISABLE();
- }
+ if(instance == SPI2) return HAL_RCC_GetPCLK1Freq();
#endif
#ifdef SPI3
- if(!never_reset_spi[2]) {
- reserved_spi[2] = false;
- __HAL_RCC_SPI3_CLK_DISABLE();
- }
- #endif
- #ifdef SPI4
- if(!never_reset_spi[3]) {
- reserved_spi[3] = false;
- __HAL_RCC_SPI4_CLK_DISABLE();
- }
- #endif
- #ifdef SPI5
- if(!never_reset_spi[4]) {
- reserved_spi[4] = false;
- __HAL_RCC_SPI5_CLK_DISABLE();
- }
+ if(instance == SPI3) return HAL_RCC_GetPCLK1Freq();
#endif
- #ifdef SPI6
- if(!never_reset_spi[5]) {
- reserved_spi[5] = false;
- __HAL_RCC_SPI6_CLK_DISABLE();
+ return HAL_RCC_GetPCLK2Freq();
+}
+
+void spi_reset(void) {
+ uint16_t never_reset_mask = 0x00;
+ for(int i=0;i<MAX_SPI;i++) {
+ if (!never_reset_spi[i]) {
+ reserved_spi[i] = 0x00;
+ } else {
+ never_reset_mask |= 1<<i;
+ }
}
- #endif
+ spi_clock_disable(ALL_CLOCKS & ~(never_reset_mask));
}
void common_hal_busio_spi_construct(busio_spi_obj_t *self,
@@ -152,42 +143,8 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
GPIO_InitStruct.Alternate = self->miso->altfn_index;
HAL_GPIO_Init(pin_port(miso->port), &GPIO_InitStruct);
- #ifdef SPI1
- if(SPIx==SPI1) {
- reserved_spi[0] = true;
- __HAL_RCC_SPI1_CLK_ENABLE();
- }
- #endif
- #ifdef SPI2
- if(SPIx==SPI2) {
- reserved_spi[1] = true;
- __HAL_RCC_SPI2_CLK_ENABLE();
- }
- #endif
- #ifdef SPI3
- if(SPIx==SPI3) {
- reserved_spi[2] = true;
- __HAL_RCC_SPI3_CLK_ENABLE();
- }
- #endif
- #ifdef SPI4
- if(SPIx==SPI4) {
- reserved_spi[3] = true;
- __HAL_RCC_SPI4_CLK_ENABLE();
- }
- #endif
- #ifdef SPI5
- if(SPIx==SPI5) {
- reserved_spi[4] = true;
- __HAL_RCC_SPI5_CLK_ENABLE();
- }
- #endif
- #ifdef SPI6
- if(SPIx==SPI6) {
- reserved_spi[5] = true;
- __HAL_RCC_SPI6_CLK_ENABLE();
- }
- #endif
+ spi_clock_enable(1<<(self->sck->spi_index - 1));
+ reserved_spi[self->sck->spi_index - 1] = true;
self->handle.Instance = SPIx;
self->handle.Init.Mode = SPI_MODE_MASTER;
@@ -205,7 +162,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
{
mp_raise_ValueError(translate("SPI Init Error"));
}
- self->baudrate = (HAL_RCC_GetPCLK2Freq()/16);
+ self->baudrate = (get_busclock(SPIx)/16);
self->prescaler = 16;
self->polarity = 0;
self->phase = 1;
@@ -233,42 +190,9 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) {
}
void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {
- #ifdef SPI1
- if(self->handle.Instance==SPI1) {
- reserved_spi[0] = false;
- __HAL_RCC_SPI1_CLK_DISABLE();
- }
- #endif
- #ifdef SPI2
- if(self->handle.Instance==SPI2) {
- reserved_spi[1] = false;
- __HAL_RCC_SPI2_CLK_DISABLE();
- }
- #endif
- #ifdef SPI3
- if(self->handle.Instance==SPI3) {
- reserved_spi[2] = false;
- __HAL_RCC_SPI3_CLK_DISABLE();
- }
- #endif
- #ifdef SPI4
- if(self->handle.Instance==SPI4) {
- reserved_spi[3] = false;
- __HAL_RCC_SPI4_CLK_DISABLE();
- }
- #endif
- #ifdef SPI5
- if(self->handle.Instance==SPI5) {
- reserved_spi[4] = false;
- __HAL_RCC_SPI5_CLK_DISABLE();
- }
- #endif
- #ifdef SPI6
- if(self->handle.Instance==SPI6) {
- reserved_spi[5] = false;
- __HAL_RCC_SPI6_CLK_DISABLE();
- }
- #endif
+ spi_clock_disable(1<<(self->sck->spi_index - 1));
+ reserved_spi[self->sck->spi_index - 1] = true;
+
reset_pin_number(self->sck->pin->port,self->sck->pin->number);
reset_pin_number(self->mosi->pin->port,self->mosi->pin->number);
reset_pin_number(self->miso->pin->port,self->miso->pin->number);
@@ -277,7 +201,7 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {
self->miso = mp_const_none;
}
-static uint32_t stm32_baud_to_spi_div(uint32_t baudrate, uint16_t * prescaler) {
+STATIC uint32_t stm32_baud_to_spi_div(uint32_t baudrate, uint16_t * prescaler, uint32_t busclock) {
static const uint32_t baud_map[8][2] = {
{2,SPI_BAUDRATEPRESCALER_2},
{4,SPI_BAUDRATEPRESCALER_4},
@@ -292,7 +216,7 @@ static uint32_t stm32_baud_to_spi_div(uint32_t baudrate, uint16_t * prescaler) {
uint16_t divisor;
do {
divisor = baud_map[i][0];
- if (baudrate >= (HAL_RCC_GetPCLK2Freq()/divisor)) {
+ if (baudrate >= (busclock/divisor)) {
*prescaler = divisor;
return baud_map[i][1];
}
@@ -312,28 +236,12 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
//Deinit SPI
HAL_SPI_DeInit(&self->handle);
- if (bits == 8) {
- self->handle.Init.DataSize = SPI_DATASIZE_8BIT;
- } else if (bits == 16) {
- self->handle.Init.DataSize = SPI_DATASIZE_16BIT;
- } else {
- return false;
- }
-
- if (polarity) {
- self->handle.Init.CLKPolarity = SPI_POLARITY_HIGH;
- } else {
- self->handle.Init.CLKPolarity = SPI_POLARITY_LOW;
- }
-
- if (phase) {
- self->handle.Init.CLKPhase = SPI_PHASE_2EDGE;
- } else {
- self->handle.Init.CLKPhase = SPI_PHASE_1EDGE;
- }
-
- self->handle.Init.BaudRatePrescaler = stm32_baud_to_spi_div(baudrate, &self->prescaler);
+ self->handle.Init.DataSize = (bits == 16) ? SPI_DATASIZE_16BIT : SPI_DATASIZE_8BIT;
+ self->handle.Init.CLKPolarity = (polarity) ? SPI_POLARITY_HIGH : SPI_POLARITY_LOW;
+ self->handle.Init.CLKPhase = (phase) ? SPI_PHASE_2EDGE : SPI_PHASE_1EDGE;
+ self->handle.Init.BaudRatePrescaler = stm32_baud_to_spi_div(baudrate, &self->prescaler,
+ get_busclock(self->handle.Instance));
self->handle.Init.Mode = SPI_MODE_MASTER;
self->handle.Init.Direction = SPI_DIRECTION_2LINES;
self->handle.Init.NSS = SPI_NSS_SOFT;
@@ -362,10 +270,10 @@ bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) {
// __disable_irq();
// __DMB();
- if (!self->has_lock) {
- grabbed_lock = true;
- self->has_lock = true;
- }
+ if (!self->has_lock) {
+ grabbed_lock = true;
+ self->has_lock = true;
+ }
// __DMB();
// __set_PRIMASK(store_primask);
@@ -412,4 +320,46 @@ uint8_t common_hal_busio_spi_get_phase(busio_spi_obj_t* self) {
uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t* self) {
return self->polarity;
-} \ No newline at end of file
+}
+
+STATIC void spi_clock_enable(uint8_t mask) {
+ #ifdef SPI1
+ if (mask & 1<<0) __HAL_RCC_SPI1_CLK_ENABLE();
+ #endif
+ #ifdef SPI2
+ if (mask & 1<<1) __HAL_RCC_SPI2_CLK_ENABLE();
+ #endif
+ #ifdef SPI3
+ if (mask & 1<<2) __HAL_RCC_SPI3_CLK_ENABLE();
+ #endif
+ #ifdef SPI4
+ if (mask & 1<<3) __HAL_RCC_SPI4_CLK_ENABLE();
+ #endif
+ #ifdef SPI5
+ if (mask & 1<<4) __HAL_RCC_SPI5_CLK_ENABLE();
+ #endif
+ #ifdef SPI6
+ if (mask & 1<<5) __HAL_RCC_SPI6_CLK_ENABLE();
+ #endif
+}
+
+STATIC void spi_clock_disable(uint8_t mask) {
+ #ifdef SPI1
+ if (mask & 1<<0) __HAL_RCC_SPI1_CLK_DISABLE();
+ #endif
+ #ifdef SPI2
+ if (mask & 1<<1) __HAL_RCC_SPI2_CLK_DISABLE();
+ #endif
+ #ifdef SPI3
+ if (mask & 1<<2) __HAL_RCC_SPI3_CLK_DISABLE();
+ #endif
+ #ifdef SPI4
+ if (mask & 1<<3) __HAL_RCC_SPI4_CLK_DISABLE();
+ #endif
+ #ifdef SPI5
+ if (mask & 1<<4) __HAL_RCC_SPI5_CLK_DISABLE();
+ #endif
+ #ifdef SPI6
+ if (mask & 1<<5) __HAL_RCC_SPI6_CLK_DISABLE();
+ #endif
+}
diff --git a/ports/stm32f4/common-hal/busio/UART.c b/ports/stm32f4/common-hal/busio/UART.c
index e1810b131..aa792dae1 100644
--- a/ports/stm32f4/common-hal/busio/UART.c
+++ b/ports/stm32f4/common-hal/busio/UART.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Damien P. George
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -36,45 +36,564 @@
#include "supervisor/shared/translate.h"
#include "tick.h"
+#include "stm32f4xx_hal.h"
-void common_hal_busio_uart_construct(busio_uart_obj_t *self,
- const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
+#define ALL_UARTS 0xFFFF
+
+STATIC bool reserved_uart[MAX_UART];
+int errflag; //Used to restart read halts
+
+STATIC void uart_clock_enable(uint16_t mask);
+STATIC void uart_clock_disable(uint16_t mask);
+STATIC void uart_assign_irq(busio_uart_obj_t* self, USART_TypeDef* USARTx);
+
+void uart_reset(void) {
+ for (uint8_t i = 0; i < MAX_UART; i++) {
+ reserved_uart[i] = false;
+ MP_STATE_PORT(cpy_uart_obj_all)[i] = NULL;
+ }
+ uart_clock_disable(ALL_UARTS);
+}
+
+STATIC USART_TypeDef * assign_uart_or_throw(busio_uart_obj_t* self, bool pin_eval,
+ int uart_index, bool uart_taken) {
+ if (pin_eval) {
+ //assign a root pointer pointer for IRQ
+ MP_STATE_PORT(cpy_uart_obj_all)[uart_index] = self;
+ return mcu_uart_banks[uart_index];
+ } else {
+ if (uart_taken) {
+ mp_raise_ValueError(translate("Hardware in use, try alternative pins"));
+ } else {
+ mp_raise_ValueError(translate("Invalid UART pin selection"));
+ }
+ }
+}
+
+void common_hal_busio_uart_construct(busio_uart_obj_t* self,
+ const mcu_pin_obj_t* tx, const mcu_pin_obj_t* rx, uint32_t baudrate,
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
uint16_t receiver_buffer_size) {
- mp_raise_NotImplementedError(translate("UART not yet supported"));
+
+ //match pins to UART objects
+ USART_TypeDef * USARTx;
+
+ uint8_t tx_len = sizeof(mcu_uart_tx_list)/sizeof(*mcu_uart_tx_list);
+ uint8_t rx_len = sizeof(mcu_uart_rx_list)/sizeof(*mcu_uart_rx_list);
+ bool uart_taken = false;
+ uint8_t uart_index = 0; //origin 0 corrected
+
+ //Can have both pins, or either
+ if ((tx != mp_const_none) && (rx != mp_const_none)) {
+ //normal find loop if both pins exist
+ for (uint i = 0; i < tx_len; i++) {
+ if (mcu_uart_tx_list[i].pin == tx) {
+ //rx
+ for (uint j = 0; j < rx_len; j++) {
+ if (mcu_uart_rx_list[j].pin == rx
+ && mcu_uart_rx_list[j].uart_index == mcu_uart_tx_list[i].uart_index) {
+ //keep looking if the UART is taken, edge case
+ if (reserved_uart[mcu_uart_tx_list[i].uart_index - 1]) {
+ uart_taken = true;
+ continue;
+ }
+ //store pins if not
+ self->tx = &mcu_uart_tx_list[i];
+ self->rx = &mcu_uart_rx_list[j];
+ break;
+ }
+ }
+ }
+ }
+ uart_index = self->tx->uart_index - 1;
+ USARTx = assign_uart_or_throw(self, (self->tx != NULL && self->rx != NULL),
+ uart_index, uart_taken);
+ } else if (tx == mp_const_none) {
+ //If there is no tx, run only rx
+ for (uint i = 0; i < rx_len; i++) {
+ if (mcu_uart_rx_list[i].pin == rx) {
+ //keep looking if the UART is taken, edge case
+ if (reserved_uart[mcu_uart_rx_list[i].uart_index - 1]) {
+ uart_taken = true;
+ continue;
+ }
+ //store pins if not
+ self->rx = &mcu_uart_rx_list[i];
+ break;
+ }
+ }
+ uart_index = self->rx->uart_index - 1;
+ USARTx = assign_uart_or_throw(self, (self->rx != NULL),
+ uart_index, uart_taken);
+ } else if (rx == mp_const_none) {
+ //If there is no rx, run only tx
+ for (uint i = 0; i < tx_len; i++) {
+ if (mcu_uart_tx_list[i].pin == tx) {
+ //keep looking if the UART is taken, edge case
+ if (reserved_uart[mcu_uart_tx_list[i].uart_index - 1]) {
+ uart_taken = true;
+ continue;
+ }
+ //store pins if not
+ self->tx = &mcu_uart_tx_list[i];
+ break;
+ }
+ }
+ uart_index = self->tx->uart_index - 1;
+ USARTx = assign_uart_or_throw(self, (self->tx != NULL),
+ uart_index, uart_taken);
+ } else {
+ //both pins cannot be empty
+ mp_raise_ValueError(translate("Supply at least one UART pin"));
+ }
+
+ //Other errors
+ if ( receiver_buffer_size == 0 ) {
+ mp_raise_ValueError(translate("Invalid buffer size"));
+ }
+ if ( bits != 8 && bits != 9 ) {
+ mp_raise_ValueError(translate("Invalid word/bit length"));
+ }
+ if ( USARTx == NULL) { //this can only be hit if the periph file is wrong
+ mp_raise_ValueError(translate("Internal define error"));
+ }
+
+ //GPIO Init
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if (self->tx != NULL) {
+ GPIO_InitStruct.Pin = pin_mask(tx->number);
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = self->tx->altfn_index;
+ HAL_GPIO_Init(pin_port(tx->port), &GPIO_InitStruct);
+ }
+ if (self->rx != NULL) {
+ GPIO_InitStruct.Pin = pin_mask(rx->number);
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = self->rx->altfn_index;
+ HAL_GPIO_Init(pin_port(rx->port), &GPIO_InitStruct);
+ }
+
+ //reserve uart and enable the peripheral
+ reserved_uart[uart_index] = true;
+ uart_clock_enable(1 << (uart_index));
+ uart_assign_irq(self, USARTx);
+
+ self->handle.Instance = USARTx;
+ self->handle.Init.BaudRate = baudrate;
+ self->handle.Init.WordLength = (bits == 9) ? UART_WORDLENGTH_9B : UART_WORDLENGTH_8B;
+ self->handle.Init.StopBits = (stop > 1) ? UART_STOPBITS_2 : UART_STOPBITS_1;
+ self->handle.Init.Parity = (parity == PARITY_ODD) ? UART_PARITY_ODD :
+ (parity == PARITY_EVEN) ? UART_PARITY_EVEN :
+ UART_PARITY_NONE;
+ self->handle.Init.Mode = (self->tx != NULL && self->rx != NULL) ? UART_MODE_TX_RX :
+ (self->tx != NULL) ? UART_MODE_TX :
+ UART_MODE_RX;
+ self->handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+ self->handle.Init.OverSampling = UART_OVERSAMPLING_16;
+ if (HAL_UART_Init(&self->handle) != HAL_OK)
+ {
+ mp_raise_ValueError(translate("UART Init Error"));
+
+ }
+
+ // Init buffer for rx and claim pins
+ if (self->rx != NULL) {
+ ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
+ if (!self->rbuf.buf) {
+ mp_raise_ValueError(translate("UART Buffer allocation error"));
+ }
+ claim_pin(rx);
+ }
+ if (self->tx != NULL) {
+ claim_pin(tx);
+ }
+ self->baudrate = baudrate;
+ self->timeout_ms = timeout * 1000;
+
+ //start the interrupt series
+ if ((HAL_UART_GetState(&self->handle) & HAL_UART_STATE_BUSY_RX) == HAL_UART_STATE_BUSY_RX) {
+ mp_raise_ValueError(translate("Could not start interrupt, RX busy"));
+ }
+
+ //start the receive interrupt chain
+ HAL_NVIC_DisableIRQ(self->irq); //prevent handle lock contention
+ HAL_UART_Receive_IT(&self->handle, &self->rx_char, 1);
+ HAL_NVIC_SetPriority(self->irq, UART_IRQPRI, UART_IRQSUB_PRI);
+ HAL_NVIC_EnableIRQ(self->irq);
+
+ errflag = HAL_OK;
}
bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) {
- return 0;
+ return self->tx->pin == mp_const_none;
}
void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
+ if (common_hal_busio_uart_deinited(self)) return;
+
+ reset_pin_number(self->tx->pin->port,self->tx->pin->number);
+ reset_pin_number(self->rx->pin->port,self->rx->pin->number);
+ self->tx = mp_const_none;
+ self->rx = mp_const_none;
+ gc_free(self->rbuf.buf);
+ self->rbuf.size = 0;
+ self->rbuf.iput = self->rbuf.iget = 0;
}
-// Read characters.
size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) {
- return 0;
+ if (self->rx == NULL) {
+ mp_raise_ValueError(translate("No RX pin"));
+ }
+
+ size_t rx_bytes = 0;
+ uint64_t start_ticks = supervisor_ticks_ms64();
+
+ // Wait for all bytes received or timeout, same as nrf
+ while ( (ringbuf_count(&self->rbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
+ RUN_BACKGROUND_TASKS;
+ //restart if it failed in the callback
+ if (errflag != HAL_OK) {
+ errflag = HAL_UART_Receive_IT(&self->handle, &self->rx_char, 1);
+ }
+ // Allow user to break out of a timeout with a KeyboardInterrupt.
+ if ( mp_hal_is_interrupted() ) {
+ return 0;
+ }
+ }
+
+ // Halt reception
+ HAL_NVIC_DisableIRQ(self->irq);
+ // copy received data
+ rx_bytes = ringbuf_count(&self->rbuf);
+ rx_bytes = MIN(rx_bytes, len);
+ for (uint16_t i = 0; i < rx_bytes; i++) {
+ data[i] = ringbuf_get(&self->rbuf);
+ }
+ HAL_NVIC_EnableIRQ(self->irq);
+
+ if (rx_bytes == 0) {
+ *errcode = EAGAIN;
+ return MP_STREAM_ERROR;
+ }
+ return rx_bytes;
}
// Write characters.
size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) {
- return 0;
+ if (self->tx == NULL) {
+ mp_raise_ValueError(translate("No TX pin"));
+ }
+ bool write_err = false; //write error shouldn't disable interrupts
+
+ HAL_NVIC_DisableIRQ(self->irq);
+ if (HAL_UART_Transmit(&self->handle, (uint8_t*)data, len, HAL_MAX_DELAY) != HAL_OK) {
+ write_err = true;
+ }
+ HAL_UART_Receive_IT(&self->handle, &self->rx_char, 1);
+ HAL_NVIC_EnableIRQ(self->irq);
+
+ if (write_err) {
+ mp_raise_ValueError(translate("UART write error"));
+ }
+ return len;
+}
+
+void HAL_UART_RxCpltCallback(UART_HandleTypeDef *handle)
+{
+ for (int i = 0; i < 7; i++) {
+ //get context pointer and cast it as struct pointer
+ busio_uart_obj_t * context = (busio_uart_obj_t*)MP_STATE_PORT(cpy_uart_obj_all)[i];
+ if (handle == &context->handle) {
+ //check if transaction is ongoing
+ if ((HAL_UART_GetState(handle) & HAL_UART_STATE_BUSY_RX) == HAL_UART_STATE_BUSY_RX) {
+ return;
+ }
+ ringbuf_put_n(&context->rbuf, &context->rx_char, 1);
+ errflag = HAL_UART_Receive_IT(handle, &context->rx_char, 1);
+
+ return;
+ }
+ }
+}
+
+void HAL_UART_ErrorCallback(UART_HandleTypeDef *UartHandle)
+{
+ if (__HAL_UART_GET_FLAG(UartHandle, UART_FLAG_PE) != RESET) {
+ __HAL_UART_CLEAR_PEFLAG(UartHandle);
+ } else if (__HAL_UART_GET_FLAG(UartHandle, UART_FLAG_FE) != RESET) {
+ __HAL_UART_CLEAR_FEFLAG(UartHandle);
+ } else if (__HAL_UART_GET_FLAG(UartHandle, UART_FLAG_NE) != RESET) {
+ __HAL_UART_CLEAR_NEFLAG(UartHandle);
+ } else if (__HAL_UART_GET_FLAG(UartHandle, UART_FLAG_ORE) != RESET) {
+ __HAL_UART_CLEAR_OREFLAG(UartHandle);
+ }
+ //restart serial read after an error
+ for (int i = 0; i < 7; i++) {
+ busio_uart_obj_t * context = (busio_uart_obj_t *)MP_STATE_PORT(cpy_uart_obj_all)[i];
+ if (UartHandle == &context->handle) {
+ HAL_UART_Receive_IT(UartHandle, &context->rx_char, 1);
+ return;
+ }
+ }
+
}
uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) {
- return 0;
+ return self->baudrate;
}
void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) {
+ //Don't reset if it's the same value
+ if (baudrate == self->baudrate) return;
+
+ //Otherwise de-init and set new rate
+ if (HAL_UART_DeInit(&self->handle) != HAL_OK) {
+ mp_raise_ValueError(translate("UART De-init error"));
+ }
+ self->handle.Init.BaudRate = baudrate;
+ if (HAL_UART_Init(&self->handle) != HAL_OK) {
+ mp_raise_ValueError(translate("UART Re-init error"));
+ }
+
+ self->baudrate = baudrate;
+}
+
+mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) {
+ return (mp_float_t) (self->timeout_ms / 1000.0f);
+}
+
+void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) {
+ self->timeout_ms = timeout * 1000;
}
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
- return 0;
+ return ringbuf_count(&self->rbuf);
}
void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
+ // Halt reception
+ HAL_NVIC_DisableIRQ(self->irq);
+ ringbuf_clear(&self->rbuf);
+ HAL_NVIC_EnableIRQ(self->irq);
}
bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) {
- return 0;
+ return __HAL_UART_GET_FLAG(&self->handle, UART_FLAG_TXE);
+}
+
+STATIC void call_hal_irq(int uart_num) {
+ //Create casted context pointer
+ busio_uart_obj_t * context = (busio_uart_obj_t*)MP_STATE_PORT(cpy_uart_obj_all)[uart_num - 1];
+ if (context != NULL) {
+ HAL_NVIC_ClearPendingIRQ(context->irq);
+ HAL_UART_IRQHandler(&context->handle);
+ }
+}
+
+// UART/USART IRQ handlers
+void USART1_IRQHandler(void) {
+ call_hal_irq(1);
+}
+
+void USART2_IRQHandler(void) {
+ call_hal_irq(2);
+}
+
+void USART3_IRQHandler(void) {
+ call_hal_irq(3);
+}
+
+void UART4_IRQHandler(void) {
+ call_hal_irq(4);
+}
+
+void UART5_IRQHandler(void) {
+ call_hal_irq(5);
+}
+
+void USART6_IRQHandler(void) {
+ call_hal_irq(6);
+}
+
+STATIC void uart_clock_enable(uint16_t mask) {
+ #ifdef USART1
+ if (mask & (1 << 0)) {
+ __HAL_RCC_USART1_FORCE_RESET();
+ __HAL_RCC_USART1_RELEASE_RESET();
+ __HAL_RCC_USART1_CLK_ENABLE();
+ }
+ #endif
+ #ifdef USART2
+ if (mask & (1 << 1)) {
+ __HAL_RCC_USART2_FORCE_RESET();
+ __HAL_RCC_USART2_RELEASE_RESET();
+ __HAL_RCC_USART2_CLK_ENABLE();
+ }
+ #endif
+ #ifdef USART3
+ if (mask & (1 << 2)) {
+ __HAL_RCC_USART3_FORCE_RESET();
+ __HAL_RCC_USART3_RELEASE_RESET();
+ __HAL_RCC_USART3_CLK_ENABLE();
+ }
+ #endif
+ #ifdef UART4
+ if (mask & (1 << 3)) {
+ __HAL_RCC_UART4_FORCE_RESET();
+ __HAL_RCC_UART4_RELEASE_RESET();
+ __HAL_RCC_UART4_CLK_ENABLE();
+ }
+ #endif
+ #ifdef UART5
+ if (mask & (1 << 4)) {
+ __HAL_RCC_UART5_FORCE_RESET();
+ __HAL_RCC_UART5_RELEASE_RESET();
+ __HAL_RCC_UART5_CLK_ENABLE();
+ }
+ #endif
+ #ifdef USART6
+ if (mask & (1 << 5)) {
+ __HAL_RCC_USART6_FORCE_RESET();
+ __HAL_RCC_USART6_RELEASE_RESET();
+ __HAL_RCC_USART6_CLK_ENABLE();
+ }
+ #endif
+ #ifdef UART7
+ if (mask & (1 << 6)) {
+ __HAL_RCC_UART7_FORCE_RESET();
+ __HAL_RCC_UART7_RELEASE_RESET();
+ __HAL_RCC_UART7_CLK_ENABLE();
+ }
+ #endif
+ #ifdef UART8
+ if (mask & (1 << 7)) {
+ __HAL_RCC_UART8_FORCE_RESET();
+ __HAL_RCC_UART8_RELEASE_RESET();
+ __HAL_RCC_UART8_CLK_ENABLE();
+ }
+ #endif
+ #ifdef UART9
+ if (mask & (1 << 8)) {
+ __HAL_RCC_UART9_FORCE_RESET();
+ __HAL_RCC_UART9_RELEASE_RESET();
+ __HAL_RCC_UART9_CLK_ENABLE();
+ }
+ #endif
+ #ifdef UART10
+ if (mask & (1 << 9)) {
+ __HAL_RCC_UART10_FORCE_RESET();
+ __HAL_RCC_UART10_RELEASE_RESET();
+ __HAL_RCC_UART10_CLK_ENABLE();
+ }
+ #endif
+}
+
+STATIC void uart_clock_disable(uint16_t mask) {
+ #ifdef USART1
+ if (mask & (1 << 0)) {
+ __HAL_RCC_USART1_FORCE_RESET();
+ __HAL_RCC_USART1_RELEASE_RESET();
+ __HAL_RCC_USART1_CLK_DISABLE();
+ }
+ #endif
+ #ifdef USART2
+ if (mask & (1 << 1)) {
+ __HAL_RCC_USART2_FORCE_RESET();
+ __HAL_RCC_USART2_RELEASE_RESET();
+ __HAL_RCC_USART2_CLK_DISABLE();
+ }
+ #endif
+ #ifdef USART3
+ if (mask & (1 << 2)) {
+ __HAL_RCC_USART3_FORCE_RESET();
+ __HAL_RCC_USART3_RELEASE_RESET();
+ __HAL_RCC_USART3_CLK_DISABLE();
+ }
+ #endif
+ #ifdef UART4
+ if (mask & (1 << 3)) {
+ __HAL_RCC_UART4_FORCE_RESET();
+ __HAL_RCC_UART4_RELEASE_RESET();
+ __HAL_RCC_UART4_CLK_DISABLE();
+ }
+ #endif
+ #ifdef UART5
+ if (mask & (1 << 4)) {
+ __HAL_RCC_UART5_FORCE_RESET();
+ __HAL_RCC_UART5_RELEASE_RESET();
+ __HAL_RCC_UART5_CLK_DISABLE();
+ }
+ #endif
+ #ifdef USART6
+ if (mask & (1 << 5)) {
+ __HAL_RCC_USART6_FORCE_RESET();
+ __HAL_RCC_USART6_RELEASE_RESET();
+ __HAL_RCC_USART6_CLK_DISABLE();
+ }
+ #endif
+ #ifdef UART7
+ if (mask & (1 << 6)) {
+ __HAL_RCC_UART7_FORCE_RESET();
+ __HAL_RCC_UART7_RELEASE_RESET();
+ __HAL_RCC_UART7_CLK_DISABLE();
+ }
+ #endif
+ #ifdef UART8
+ if (mask & (1 << 7)) {
+ __HAL_RCC_UART8_FORCE_RESET();
+ __HAL_RCC_UART8_RELEASE_RESET();
+ __HAL_RCC_UART8_CLK_DISABLE();
+ }
+ #endif
+ #ifdef UART9
+ if (mask & (1 << 8)) {
+ __HAL_RCC_UART9_FORCE_RESET();
+ __HAL_RCC_UART9_RELEASE_RESET();
+ __HAL_RCC_UART9_CLK_DISABLE();
+ }
+ #endif
+ #ifdef UART10
+ if (mask & (1 << 9)) {
+ __HAL_RCC_UART10_FORCE_RESET();
+ __HAL_RCC_UART10_RELEASE_RESET();
+ __HAL_RCC_UART10_CLK_DISABLE();
+ }
+ #endif
+}
+
+STATIC void uart_assign_irq(busio_uart_obj_t *self, USART_TypeDef * USARTx) {
+ #ifdef USART1
+ if (USARTx == USART1) self->irq = USART1_IRQn;
+ #endif
+ #ifdef USART2
+ if (USARTx == USART2) self->irq = USART2_IRQn;
+ #endif
+ #ifdef USART3
+ if (USARTx == USART3) self->irq = USART3_IRQn;
+ #endif
+ #ifdef UART4
+ if (USARTx == UART4) self->irq = UART4_IRQn;
+ #endif
+ #ifdef UART5
+ if (USARTx == UART5) self->irq = UART5_IRQn;
+ #endif
+ #ifdef USART6
+ if (USARTx == USART6) self->irq = USART6_IRQn;
+ #endif
+ #ifdef UART7
+ if (USARTx == UART7) self->irq = UART7_IRQn;
+ #endif
+ #ifdef UART8
+ if (USARTx == UART8) self->irq = UART8_IRQn;
+ #endif
+ #ifdef UART9
+ if (USARTx == UART9) self->irq = UART9_IRQn;
+ #endif
+ #ifdef UART10
+ if (USARTx == UART10) self->irq = UART10_IRQn;
+ #endif
}
diff --git a/ports/stm32f4/common-hal/busio/UART.h b/ports/stm32f4/common-hal/busio/UART.h
index 699233934..cde5fadd0 100644
--- a/ports/stm32f4/common-hal/busio/UART.h
+++ b/ports/stm32f4/common-hal/busio/UART.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Scott Shawcroft
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -28,19 +28,33 @@
#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_UART_H
#include "common-hal/microcontroller/Pin.h"
+#include "stm32f4/periph.h"
+#include "stm32f4xx_hal.h"
#include "py/obj.h"
+#include "py/ringbuf.h"
+
+#ifndef UART_IRQPRI
+#define UART_IRQPRI 1
+#endif
+#ifndef UART_IRQSUB_PRI
+#define UART_IRQSUB_PRI 0
+#endif
typedef struct {
mp_obj_base_t base;
- uint8_t rx_pin;
- uint8_t tx_pin;
- uint8_t character_bits;
- bool rx_error;
+ UART_HandleTypeDef handle;
+ IRQn_Type irq;
+ const mcu_uart_tx_obj_t *tx;
+ const mcu_uart_rx_obj_t *rx;
+
+ ringbuf_t rbuf;
+ uint8_t rx_char;
+
uint32_t baudrate;
uint32_t timeout_ms;
- uint32_t buffer_length;
- uint8_t* buffer;
} busio_uart_obj_t;
+void uart_reset(void);
+
#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_UART_H
diff --git a/ports/stm32f4/common-hal/microcontroller/Pin.c b/ports/stm32f4/common-hal/microcontroller/Pin.c
index 5761d7fb1..21290e03c 100644
--- a/ports/stm32f4/common-hal/microcontroller/Pin.c
+++ b/ports/stm32f4/common-hal/microcontroller/Pin.c
@@ -26,11 +26,17 @@
*/
#include "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "supervisor/shared/rgb_led_status.h"
#include "py/mphal.h"
#include "stm32f4/pins.h"
#include "stm32f4xx_hal.h"
+#ifdef MICROPY_HW_NEOPIXEL
+bool neopixel_in_use;
+#endif
+
#if MCU_PACKAGE == 144
#define GPIO_PORT_COUNT 7
GPIO_TypeDef * ports[GPIO_PORT_COUNT] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG};
@@ -53,6 +59,10 @@ void reset_all_pins(void) {
for (uint8_t i = 0; i < GPIO_PORT_COUNT; i++) {
HAL_GPIO_DeInit(ports[i], ~never_reset_pins[i]);
}
+
+ #ifdef MICROPY_HW_NEOPIXEL
+ neopixel_in_use = false;
+ #endif
}
// Mark pin as free and return it to a quiescent state.
@@ -60,21 +70,40 @@ void reset_pin_number(uint8_t pin_port, uint8_t pin_number) {
if (pin_port == 0x0F) {
return;
}
-
- // Clear claimed bit.
+ // Clear claimed bit & reset
claimed_pins[pin_port] &= ~(1<<pin_number);
- // Reset the pin
HAL_GPIO_DeInit(ports[pin_port], 1<<pin_number);
-}
+ #ifdef MICROPY_HW_NEOPIXEL
+ if (pin_port == MICROPY_HW_NEOPIXEL->port && pin_number == MICROPY_HW_NEOPIXEL->number) {
+ neopixel_in_use = false;
+ rgb_led_status_init();
+ return;
+ }
+ #endif
+}
void never_reset_pin_number(uint8_t pin_port, uint8_t pin_number) {
never_reset_pins[pin_port] |= 1<<pin_number;
}
+void common_hal_never_reset_pin(const mcu_pin_obj_t* pin) {
+ never_reset_pin_number(pin->port, pin->number);
+}
+
+void common_hal_reset_pin(const mcu_pin_obj_t* pin) {
+ reset_pin_number(pin->port, pin->number);
+}
+
void claim_pin(const mcu_pin_obj_t* pin) {
// Set bit in claimed_pins bitmask.
claimed_pins[pin->port] |= 1<<pin->number;
+
+ #ifdef MICROPY_HW_NEOPIXEL
+ if (pin == MICROPY_HW_NEOPIXEL) {
+ neopixel_in_use = true;
+ }
+ #endif
}
bool pin_number_is_free(uint8_t pin_port, uint8_t pin_number) {
@@ -82,6 +111,12 @@ bool pin_number_is_free(uint8_t pin_port, uint8_t pin_number) {
}
bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) {
+ #ifdef MICROPY_HW_NEOPIXEL
+ if (pin == MICROPY_HW_NEOPIXEL) {
+ return !neopixel_in_use;
+ }
+ #endif
+
return pin_number_is_free(pin->port, pin->number);
}
diff --git a/ports/stm32f4/common-hal/microcontroller/Pin.h b/ports/stm32f4/common-hal/microcontroller/Pin.h
index 0c3fb375f..c4c9be6a8 100644
--- a/ports/stm32f4/common-hal/microcontroller/Pin.h
+++ b/ports/stm32f4/common-hal/microcontroller/Pin.h
@@ -31,6 +31,14 @@
#include "peripherals/stm32f4/pins.h"
+#ifdef MICROPY_HW_NEOPIXEL
+extern bool neopixel_in_use;
+#endif
+#ifdef MICROPY_HW_APA102_MOSI
+extern bool apa102_sck_in_use;
+extern bool apa102_mosi_in_use;
+#endif
+
void reset_all_pins(void);
// reset_pin_number takes the pin number instead of the pointer so that objects don't
// need to store a full pointer.
diff --git a/ports/stm32f4/common-hal/microcontroller/__init__.c b/ports/stm32f4/common-hal/microcontroller/__init__.c
index 4a6fdc388..ffab5d1e5 100644
--- a/ports/stm32f4/common-hal/microcontroller/__init__.c
+++ b/ports/stm32f4/common-hal/microcontroller/__init__.c
@@ -39,17 +39,56 @@
#include "supervisor/filesystem.h"
#include "supervisor/shared/safe_mode.h"
-// This routine should work even when interrupts are disabled. Used by OneWire
-// for precise timing.
+#include "stm32f4xx_hal.h"
+
+//tested divisor value for busy loop in us delay
+#define LOOP_TICKS 12
+
+STATIC uint32_t get_us(void) {
+ uint32_t ticks_per_us = HAL_RCC_GetSysClockFreq()/1000000;
+ uint32_t micros, sys_cycles;
+ do {
+ micros = supervisor_ticks_ms32();
+ sys_cycles = SysTick->VAL; //counts backwards
+ } while (micros != supervisor_ticks_ms32()); //try again if ticks_ms rolled over
+ return (micros * 1000) + (ticks_per_us * 1000 - sys_cycles) / ticks_per_us;
+}
+
void common_hal_mcu_delay_us(uint32_t delay) {
- //TODO: implement equivalent of mp_hal_delay_us(delay);
- //this is fairly annoying in the STM32 HAL
+ if (__get_PRIMASK() == 0x00000000) {
+ //by default use ticks_ms
+ uint32_t start = get_us();
+ while (get_us()-start < delay) {
+ __asm__ __volatile__("nop");
+ }
+ } else {
+ //when SysTick is disabled, approximate with busy loop
+ const uint32_t ucount = HAL_RCC_GetSysClockFreq() / 1000000 * delay / LOOP_TICKS;
+ for (uint32_t count = 0; ++count <= ucount;) {
+ }
+ }
}
-void common_hal_mcu_disable_interrupts() {
+volatile uint32_t nesting_count = 0;
+
+void common_hal_mcu_disable_interrupts(void) {
+ __disable_irq();
+ __DMB();
+ nesting_count++;
}
-void common_hal_mcu_enable_interrupts() {
+void common_hal_mcu_enable_interrupts(void) {
+ if (nesting_count == 0) {
+ // This is very very bad because it means there was mismatched disable/enables so we
+ // "HardFault".
+ asm("bkpt");
+ }
+ nesting_count--;
+ if (nesting_count > 0) {
+ return;
+ }
+ __DMB();
+ __enable_irq();
}
void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
@@ -58,7 +97,7 @@ void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
}
void common_hal_mcu_reset(void) {
- filesystem_flush();
+ filesystem_flush(); //TODO: implement as part of flash improvements
NVIC_SystemReset();
}
diff --git a/ports/stm32f4/common-hal/neopixel_write/__init__.c b/ports/stm32f4/common-hal/neopixel_write/__init__.c
new file mode 100644
index 000000000..fd46825d0
--- /dev/null
+++ b/ports/stm32f4/common-hal/neopixel_write/__init__.c
@@ -0,0 +1,96 @@
+/*
+ * 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/mphal.h"
+#include "shared-bindings/neopixel_write/__init__.h"
+
+#include "tick.h"
+#include "common-hal/microcontroller/Pin.h"
+#include "stm32f4xx_hal.h"
+#include "stm32f4xx_ll_gpio.h"
+
+uint64_t next_start_tick_ms = 0;
+uint32_t next_start_tick_us = 1000;
+
+//sysclock divisors
+#define MAGIC_800_INT 900000 // ~1.11 us -> 1.2 field
+#define MAGIC_800_T0H 2800000 // ~0.36 us -> 0.44 field
+#define MAGIC_800_T1H 1350000 // ~0.74 us -> 0.84 field
+
+void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout, uint8_t *pixels,
+ uint32_t numBytes) {
+ uint8_t *p = pixels, *end = p + numBytes, pix = *p++, mask = 0x80;
+ uint32_t start = 0;
+ uint32_t cyc = 0;
+
+ //assumes 800_000Hz frequency
+ //Theoretical values here are 800_000 -> 1.25us, 2500000->0.4us, 1250000->0.8us
+ //But they don't work, possibly due to bad optimization? Use tested magic values instead
+ uint32_t sys_freq = HAL_RCC_GetSysClockFreq();
+ uint32_t interval = sys_freq/MAGIC_800_INT;
+ uint32_t t0 = (sys_freq/MAGIC_800_T0H);
+ uint32_t t1 = (sys_freq/MAGIC_800_T1H);
+
+ // This must be called while interrupts are on in case we're waiting for a
+ // future ms tick.
+ wait_until(next_start_tick_ms, next_start_tick_us);
+
+ GPIO_TypeDef * p_port = pin_port(digitalinout->pin->port);
+ uint32_t p_mask = pin_mask(digitalinout->pin->number);
+
+ __disable_irq();
+ // Enable DWT in debug core. Useable when interrupts disabled, as opposed to Systick->VAL
+ //ITM->LAR = 0xC5ACCE55; //this should be required but isn't
+ CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
+ DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
+ DWT->CYCCNT = 0;
+
+ for(;;) {
+ start = DWT->CYCCNT;
+ LL_GPIO_SetOutputPin(p_port, p_mask);
+ cyc = (pix & mask) ? t1 : t0;
+ while(DWT->CYCCNT - start < cyc);
+ LL_GPIO_ResetOutputPin(p_port, p_mask);
+ if(!(mask >>= 1)) {
+ if(p >= end) break;
+ pix = *p++;
+ mask = 0x80;
+ }
+ while(DWT->CYCCNT - start < interval); //wait for interval to finish
+ }
+
+ // Enable interrupts again
+ __enable_irq();
+
+ // Update the next start.
+ current_tick(&next_start_tick_ms, &next_start_tick_us);
+ if (next_start_tick_us < 100) {
+ next_start_tick_ms += 1;
+ next_start_tick_us = 100 - next_start_tick_us;
+ } else {
+ next_start_tick_us -= 100;
+ }
+}
diff --git a/ports/stm32f4/common-hal/os/__init__.c b/ports/stm32f4/common-hal/os/__init__.c
index aa80a02f5..0b3153286 100644
--- a/ports/stm32f4/common-hal/os/__init__.c
+++ b/ports/stm32f4/common-hal/os/__init__.c
@@ -30,6 +30,11 @@
#include "py/objstr.h"
#include "py/objtuple.h"
+#include "py/mperrno.h"
+#include "py/runtime.h"
+#include "stm32f4xx_hal.h"
+#include "stm32f4/periph.h"
+
STATIC const qstr os_uname_info_fields[] = {
MP_QSTR_sysname, MP_QSTR_nodename,
MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine
@@ -56,11 +61,35 @@ mp_obj_t common_hal_os_uname(void) {
return (mp_obj_t)&os_uname_info_obj;
}
+#define RNG_TIMEOUT 5
+
bool common_hal_os_urandom(uint8_t *buffer, uint32_t length) {
+ #if (HAS_TRNG)
+ //init the RNG
+ __HAL_RCC_RNG_CLK_ENABLE();
+ RNG_HandleTypeDef handle;
+ handle.Instance = RNG;
+ if (HAL_RNG_Init(&handle) != HAL_OK) mp_raise_ValueError(translate("RNG Init Error"));
- for (uint32_t i = 0; i < length; i++) {
- buffer[i] = 4; //read in my coffee dregs; the truest random number, chosen by Nrthalotep
- //todo: spurn the gods, replace with actual code.
+ //Assign bytes
+ for (uint i = 0; i < length; i++) {
+ uint32_t temp;
+ uint32_t start = HAL_GetTick();
+ //the HAL function has a timeout, but it isn't long enough, and isn't adjustable
+ while(!(__HAL_RNG_GET_FLAG(&handle,RNG_FLAG_DRDY)) && ((HAL_GetTick() - start) < RNG_TIMEOUT));
+ //
+ if (HAL_RNG_GenerateRandomNumber(&handle, &temp) != HAL_OK) {
+ mp_raise_ValueError(translate("Random number generation error"));
+ }
+ *buffer = (uint8_t)temp;
}
+
+ //shut down the peripheral
+ if (HAL_RNG_DeInit(&handle) != HAL_OK) mp_raise_ValueError(translate("RNG DeInit Error"));
+ __HAL_RCC_RNG_CLK_DISABLE();
+
return true;
+ #else
+ return false;
+ #endif
} \ No newline at end of file
diff --git a/ports/stm32f4/common-hal/pulseio/PWMOut.c b/ports/stm32f4/common-hal/pulseio/PWMOut.c
new file mode 100644
index 000000000..16b1b5b89
--- /dev/null
+++ b/ports/stm32f4/common-hal/pulseio/PWMOut.c
@@ -0,0 +1,399 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ * Uses code from Micropython, Copyright (c) 2013-2016 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdint.h>
+#include "py/runtime.h"
+#include "common-hal/pulseio/PWMOut.h"
+#include "shared-bindings/pulseio/PWMOut.h"
+#include "supervisor/shared/translate.h"
+
+#include "shared-bindings/microcontroller/__init__.h"
+#include "stm32f4xx_hal.h"
+#include "common-hal/microcontroller/Pin.h"
+
+#define ALL_CLOCKS 0xFFFF
+
+STATIC uint8_t reserved_tim[TIM_BANK_ARRAY_LEN];
+STATIC uint32_t tim_frequencies[TIM_BANK_ARRAY_LEN];
+STATIC bool never_reset_tim[TIM_BANK_ARRAY_LEN];
+
+STATIC void tim_clock_enable(uint16_t mask);
+STATIC void tim_clock_disable(uint16_t mask);
+
+// Get the frequency (in Hz) of the source clock for the given timer.
+// On STM32F405/407/415/417 there are 2 cases for how the clock freq is set.
+// If the APB prescaler is 1, then the timer clock is equal to its respective
+// APB clock. Otherwise (APB prescaler > 1) the timer clock is twice its
+// respective APB clock. See DM00031020 Rev 4, page 115.
+STATIC uint32_t timer_get_source_freq(uint32_t tim_id) {
+ uint32_t source, clk_div;
+ if (tim_id == 1 || (8 <= tim_id && tim_id <= 11)) {
+ // TIM{1,8,9,10,11} are on APB2
+ source = HAL_RCC_GetPCLK2Freq();
+ clk_div = RCC->CFGR & RCC_CFGR_PPRE2;
+ } else {
+ // TIM{2,3,4,5,6,7,12,13,14} are on APB1
+ source = HAL_RCC_GetPCLK1Freq();
+ clk_div = RCC->CFGR & RCC_CFGR_PPRE1;
+ }
+ if (clk_div != 0) {
+ // APB prescaler for this timer is > 1
+ source *= 2;
+ }
+ return source;
+}
+
+STATIC uint32_t timer_get_internal_duty(uint16_t duty, uint32_t period) {
+ //duty cycle is duty/0xFFFF fraction x (number of pulses per period)
+ return (duty*period)/((1<<16)-1);
+}
+
+STATIC void timer_get_optimal_divisors(uint32_t*period, uint32_t*prescaler,
+ uint32_t frequency, uint32_t source_freq) {
+ //Find the largest possible period supported by this frequency
+ for (int i=0; i<(1 << 16);i++) {
+ *period = source_freq/(i*frequency);
+ if (*period < (1 << 16) && *period>=2) {
+ *prescaler = i;
+ break;
+ }
+ }
+ if (*prescaler == 0) {
+ mp_raise_ValueError(translate("Invalid frequency supplied"));
+ }
+}
+
+void pwmout_reset(void) {
+ uint16_t never_reset_mask = 0x00;
+ for(int i=0;i<TIM_BANK_ARRAY_LEN;i++) {
+ if (!never_reset_tim[i]) {
+ reserved_tim[i] = 0x00;
+ tim_frequencies[i] = 0x00;
+ } else {
+ never_reset_mask |= 1<<i;
+ }
+ }
+ tim_clock_disable(ALL_CLOCKS & ~(never_reset_mask));
+}
+
+void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) {
+ for(size_t i = 0 ; i < TIM_BANK_ARRAY_LEN; i++) {
+ if (mcu_tim_banks[i] == self->handle.Instance) {
+ never_reset_tim[i] = true;
+ never_reset_pin_number(self->tim->pin->port, self->tim->pin->number);
+ break;
+ }
+ }
+}
+
+void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self) {
+ for(size_t i = 0 ; i < TIM_BANK_ARRAY_LEN; i++) {
+ if (mcu_tim_banks[i] == self->handle.Instance) {
+ never_reset_tim[i] = false;
+ break;
+ }
+ }
+}
+
+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) {
+ TIM_TypeDef * TIMx;
+ uint8_t tim_num = sizeof(mcu_tim_pin_list)/sizeof(*mcu_tim_pin_list);
+ bool tim_chan_taken = false;
+ bool tim_taken_f_mismatch = false;
+ bool var_freq_mismatch = false;
+ bool first_time_setup = true;
+
+ for(uint i = 0; i < tim_num; i++) {
+ mcu_tim_pin_obj_t l_tim = mcu_tim_pin_list[i];
+ uint8_t l_tim_index = l_tim.tim_index-1;
+ uint8_t l_tim_channel = l_tim.channel_index-1;
+
+ //if pin is same
+ if (l_tim.pin == pin) {
+ //check if the timer has a channel active
+ if (reserved_tim[l_tim_index] != 0) {
+ //is it the same channel? (or all channels reserved by a var-freq)
+ if (reserved_tim[l_tim_index] & 1<<(l_tim_channel)) {
+ tim_chan_taken = true;
+ continue; //keep looking, might be another viable option
+ }
+ //If the frequencies are the same it's ok
+ if (tim_frequencies[l_tim_index] != frequency) {
+ tim_taken_f_mismatch = true;
+ continue; //keep looking
+ }
+ //you can't put a variable frequency on a partially reserved timer
+ if (variable_frequency) {
+ var_freq_mismatch = true;
+ continue; //keep looking
+ }
+ first_time_setup = false; //skip setting up the timer
+ }
+ //No problems taken, so set it up
+ self->tim = &l_tim;
+ break;
+ }
+ }
+
+ //handle valid/invalid timer instance
+ if (self->tim!=NULL) {
+ //create instance
+ TIMx = mcu_tim_banks[self->tim->tim_index-1];
+ //reserve timer/channel
+ if (variable_frequency) {
+ reserved_tim[self->tim->tim_index-1] = 0x0F;
+ } else {
+ reserved_tim[self->tim->tim_index-1] |= 1<<(self->tim->channel_index-1);
+ }
+ tim_frequencies[self->tim->tim_index-1] = frequency;
+ } else { //no match found
+ if (tim_chan_taken) {
+ mp_raise_ValueError(translate("No more timers available on this pin."));
+ } else if (tim_taken_f_mismatch) {
+ mp_raise_ValueError(translate("Frequency must be the same as as the existing PWMOut using this timer"));
+ } else if (var_freq_mismatch) {
+ mp_raise_ValueError(translate("Cannot vary frequency on a timer that is already in use"));
+ } else {
+ mp_raise_ValueError(translate("Invalid pins"));
+ }
+ }
+
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ GPIO_InitStruct.Pin = pin_mask(pin->number);
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ GPIO_InitStruct.Alternate = self->tim->altfn_index;
+ HAL_GPIO_Init(pin_port(pin->port), &GPIO_InitStruct);
+
+ tim_clock_enable(1<<(self->tim->tim_index - 1));
+
+ //translate channel into handle value
+ self->channel = 4 * (self->tim->channel_index - 1);
+
+ uint32_t prescaler = 0; //prescaler is 15 bit
+ uint32_t period = 0; //period is 16 bit
+ timer_get_optimal_divisors(&period, &prescaler,frequency,timer_get_source_freq(self->tim->tim_index));
+
+ //Timer init
+ self->handle.Instance = TIMx;
+ self->handle.Init.Period = period - 1;
+ self->handle.Init.Prescaler = prescaler - 1;
+ self->handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+ self->handle.Init.CounterMode = TIM_COUNTERMODE_UP;
+ self->handle.Init.RepetitionCounter = 0;
+
+ //only run init if this is the first instance of this timer
+ if (first_time_setup) {
+ if (HAL_TIM_PWM_Init(&self->handle) != HAL_OK) {
+ mp_raise_ValueError(translate("Could not initialize timer"));
+ }
+ }
+
+ //Channel/PWM init
+ self->chan_handle.OCMode = TIM_OCMODE_PWM1;
+ self->chan_handle.Pulse = timer_get_internal_duty(duty, period);
+ self->chan_handle.OCPolarity = TIM_OCPOLARITY_LOW;
+ self->chan_handle.OCFastMode = TIM_OCFAST_DISABLE;
+ self->chan_handle.OCNPolarity = TIM_OCNPOLARITY_LOW; // needed for TIM1 and TIM8
+ self->chan_handle.OCIdleState = TIM_OCIDLESTATE_SET; // needed for TIM1 and TIM8
+ self->chan_handle.OCNIdleState = TIM_OCNIDLESTATE_SET; // needed for TIM1 and TIM8
+ if (HAL_TIM_PWM_ConfigChannel(&self->handle, &self->chan_handle, self->channel) != HAL_OK) {
+ mp_raise_ValueError(translate("Could not initialize channel"));
+ }
+ if (HAL_TIM_PWM_Start(&self->handle, self->channel) != HAL_OK) {
+ mp_raise_ValueError(translate("Could not start PWM"));
+ }
+
+ self->variable_frequency = variable_frequency;
+ self->frequency = frequency;
+ self->duty_cycle = duty;
+ self->period = period;
+
+ return PWMOUT_OK;
+}
+
+bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) {
+ return self->tim == mp_const_none;
+}
+
+void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) {
+ if (common_hal_pulseio_pwmout_deinited(self)) {
+ return;
+ }
+ //var freq shuts down entire timer, others just their channel
+ if (self->variable_frequency) {
+ reserved_tim[self->tim->tim_index-1] = 0x00;
+ } else {
+ reserved_tim[self->tim->tim_index-1] &= ~(1<<self->tim->channel_index);
+ HAL_TIM_PWM_Stop(&self->handle, self->channel);
+ }
+ reset_pin_number(self->tim->pin->port,self->tim->pin->number);
+ self->tim = mp_const_none;
+
+ //if reserved timer has no active channels, we can disable it
+ if (!reserved_tim[self->tim->tim_index-1]) {
+ tim_frequencies[self->tim->tim_index-1] = 0x00;
+ tim_clock_disable(1<<(self->tim->tim_index-1));
+ }
+}
+
+void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty) {
+ uint32_t internal_duty_cycle = timer_get_internal_duty(duty, self->period);
+ __HAL_TIM_SET_COMPARE(&self->handle, self->channel, internal_duty_cycle);
+ self->duty_cycle = duty;
+}
+
+uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) {
+ return self->duty_cycle;
+}
+
+void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_t frequency) {
+ //don't halt setup for the same frequency
+ if (frequency == self->frequency) return;
+
+ uint32_t prescaler = 0;
+ uint32_t period = 0;
+ timer_get_optimal_divisors(&period, &prescaler,frequency,timer_get_source_freq(self->tim->tim_index));
+
+ //shut down
+ HAL_TIM_PWM_Stop(&self->handle, self->channel);
+
+ //Only change altered values
+ self->handle.Init.Period = period - 1;
+ self->handle.Init.Prescaler = prescaler - 1;
+
+ //restart everything, adjusting for new speed
+ if (HAL_TIM_PWM_Init(&self->handle) != HAL_OK) {
+ mp_raise_ValueError(translate("Could not re-init timer"));
+ }
+
+ self->chan_handle.Pulse = timer_get_internal_duty(self->duty_cycle, period);
+
+ if (HAL_TIM_PWM_ConfigChannel(&self->handle, &self->chan_handle, self->channel) != HAL_OK) {
+ mp_raise_ValueError(translate("Could not re-init channel"));
+ }
+ if (HAL_TIM_PWM_Start(&self->handle, self->channel) != HAL_OK) {
+ mp_raise_ValueError(translate("Could not restart PWM"));
+ }
+
+ tim_frequencies[self->tim->tim_index-1] = frequency;
+ self->frequency = frequency;
+ self->period = period;
+}
+
+uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self) {
+ return self->frequency;
+}
+
+bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self) {
+ return self->variable_frequency;
+}
+
+STATIC void tim_clock_enable(uint16_t mask) {
+ #ifdef TIM1
+ if (mask & 1<<0) __HAL_RCC_TIM1_CLK_ENABLE();
+ #endif
+ #ifdef TIM2
+ if (mask & 1<<1) __HAL_RCC_TIM2_CLK_ENABLE();
+ #endif
+ #ifdef TIM3
+ if (mask & 1<<2) __HAL_RCC_TIM3_CLK_ENABLE();
+ #endif
+ #ifdef TIM4
+ if (mask & 1<<3) __HAL_RCC_TIM4_CLK_ENABLE();
+ #endif
+ #ifdef TIM5
+ if (mask & 1<<4) __HAL_RCC_TIM5_CLK_ENABLE();
+ #endif
+ //6 and 7 are reserved ADC timers
+ #ifdef TIM8
+ if (mask & 1<<7) __HAL_RCC_TIM8_CLK_ENABLE();
+ #endif
+ #ifdef TIM9
+ if (mask & 1<<8) __HAL_RCC_TIM9_CLK_ENABLE();
+ #endif
+ #ifdef TIM10
+ if (mask & 1<<9) __HAL_RCC_TIM10_CLK_ENABLE();
+ #endif
+ #ifdef TIM11
+ if (mask & 1<<10) __HAL_RCC_TIM11_CLK_ENABLE();
+ #endif
+ #ifdef TIM12
+ if (mask & 1<<11) __HAL_RCC_TIM12_CLK_ENABLE();
+ #endif
+ #ifdef TIM13
+ if (mask & 1<<12) __HAL_RCC_TIM13_CLK_ENABLE();
+ #endif
+ #ifdef TIM14
+ if (mask & 1<<13) __HAL_RCC_TIM14_CLK_ENABLE();
+ #endif
+}
+
+STATIC void tim_clock_disable(uint16_t mask) {
+ #ifdef TIM1
+ if (mask & 1<<0) __HAL_RCC_TIM1_CLK_DISABLE();
+ #endif
+ #ifdef TIM2
+ if (mask & 1<<1) __HAL_RCC_TIM2_CLK_DISABLE();
+ #endif
+ #ifdef TIM3
+ if (mask & 1<<2) __HAL_RCC_TIM3_CLK_DISABLE();
+ #endif
+ #ifdef TIM4
+ if (mask & 1<<3) __HAL_RCC_TIM4_CLK_DISABLE();
+ #endif
+ #ifdef TIM5
+ if (mask & 1<<4) __HAL_RCC_TIM5_CLK_DISABLE();
+ #endif
+ //6 and 7 are reserved ADC timers
+ #ifdef TIM8
+ if (mask & 1<<7) __HAL_RCC_TIM8_CLK_DISABLE();
+ #endif
+ #ifdef TIM9
+ if (mask & 1<<8) __HAL_RCC_TIM9_CLK_DISABLE();
+ #endif
+ #ifdef TIM10
+ if (mask & 1<<9) __HAL_RCC_TIM10_CLK_DISABLE();
+ #endif
+ #ifdef TIM11
+ if (mask & 1<<10) __HAL_RCC_TIM11_CLK_DISABLE();
+ #endif
+ #ifdef TIM12
+ if (mask & 1<<11) __HAL_RCC_TIM12_CLK_DISABLE();
+ #endif
+ #ifdef TIM13
+ if (mask & 1<<12) __HAL_RCC_TIM13_CLK_DISABLE();
+ #endif
+ #ifdef TIM14
+ if (mask & 1<<13) __HAL_RCC_TIM14_CLK_DISABLE();
+ #endif
+}
diff --git a/ports/stm32f4/common-hal/pulseio/PWMOut.h b/ports/stm32f4/common-hal/pulseio/PWMOut.h
new file mode 100644
index 000000000..59fc04e5f
--- /dev/null
+++ b/ports/stm32f4/common-hal/pulseio/PWMOut.h
@@ -0,0 +1,51 @@
+/*
+ * 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_COMMON_HAL_PULSEIO_PWMOUT_H
+#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_PULSEIO_PWMOUT_H
+
+#include "common-hal/microcontroller/Pin.h"
+
+#include "stm32f4xx_hal.h"
+#include "stm32f4/periph.h"
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ TIM_HandleTypeDef handle;
+ TIM_OC_InitTypeDef chan_handle;
+ const mcu_tim_pin_obj_t *tim;
+ uint8_t channel: 7;
+ bool variable_frequency: 1;
+ uint16_t duty_cycle;
+ uint32_t frequency;
+ uint32_t period;
+} pulseio_pwmout_obj_t;
+
+void pwmout_reset(void);
+
+#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_PULSEIO_PWMOUT_H
diff --git a/ports/stm32f4/common-hal/pulseio/PulseIn.c b/ports/stm32f4/common-hal/pulseio/PulseIn.c
new file mode 100644
index 000000000..068936bdd
--- /dev/null
+++ b/ports/stm32f4/common-hal/pulseio/PulseIn.c
@@ -0,0 +1,79 @@
+/*
+ * 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 "common-hal/pulseio/PulseIn.h"
+#include <stdint.h>
+#include <string.h>
+#include "py/mpconfig.h"
+#include "py/gc.h"
+#include "py/runtime.h"
+#include "shared-bindings/microcontroller/__init__.h"
+#include "shared-bindings/pulseio/PulseIn.h"
+#include "tick.h"
+
+void pulsein_reset(void) {
+}
+
+void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, const mcu_pin_obj_t* pin,
+ uint16_t maxlen, bool idle_state) {
+ mp_raise_NotImplementedError(translate("PulseIn not yet supported"));
+}
+
+bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self) {
+ return true;
+}
+
+void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) {
+}
+
+void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) {
+}
+
+void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, uint16_t trigger_duration) {
+}
+
+void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) {
+}
+
+uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index) {
+ return 0;
+}
+
+uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) {
+ return 0;
+}
+
+uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) {
+ return 0;
+}
+
+bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self) {
+ return 0;
+}
+
+uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) {
+ return 0;
+}
diff --git a/ports/stm32f4/common-hal/pulseio/PulseIn.h b/ports/stm32f4/common-hal/pulseio/PulseIn.h
new file mode 100644
index 000000000..2538b07ab
--- /dev/null
+++ b/ports/stm32f4/common-hal/pulseio/PulseIn.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 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_PULSEIO_PULSEIN_H
+#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_PULSEIO_PULSEIN_H
+
+#include "common-hal/microcontroller/Pin.h"
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+
+ uint8_t pin;
+ bool idle_state;
+ bool paused;
+ volatile bool first_edge;
+
+ uint16_t* buffer;
+ uint16_t maxlen;
+
+ volatile uint16_t start;
+ volatile uint16_t len;
+ volatile uint16_t last_us;
+ volatile uint64_t last_ms;
+} pulseio_pulsein_obj_t;
+
+void pulsein_reset(void);
+
+#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_PULSEIO_PULSEIN_H
diff --git a/ports/stm32f4/common-hal/pulseio/PulseOut.c b/ports/stm32f4/common-hal/pulseio/PulseOut.c
new file mode 100644
index 000000000..d393afc5c
--- /dev/null
+++ b/ports/stm32f4/common-hal/pulseio/PulseOut.c
@@ -0,0 +1,55 @@
+/*
+ * 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 "common-hal/pulseio/PulseOut.h"
+
+#include <stdint.h>
+
+#include "py/mpconfig.h"
+#include "py/gc.h"
+#include "py/runtime.h"
+#include "shared-bindings/pulseio/PulseOut.h"
+#include "shared-bindings/pulseio/PWMOut.h"
+#include "supervisor/shared/translate.h"
+
+
+void pulseout_reset() {
+}
+
+void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
+ const pulseio_pwmout_obj_t* carrier) {
+ mp_raise_NotImplementedError(translate("PulseOut not yet supported"));
+}
+
+bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self) {
+ return true;
+}
+
+void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) {
+}
+
+void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) {
+}
diff --git a/ports/nrf/common-hal/_bleio/Central.h b/ports/stm32f4/common-hal/pulseio/PulseOut.h
index 01f7faca7..45823d28a 100644
--- a/ports/nrf/common-hal/_bleio/Central.h
+++ b/ports/stm32f4/common-hal/pulseio/PulseOut.h
@@ -3,8 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2019 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
+ * 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
@@ -25,20 +24,19 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CENTRAL_H
-#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CENTRAL_H
+#ifndef MICROPY_INCLUDED_STM32F4_COMMON_HAL_PULSEIO_PULSEOUT_H
+#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_PULSEIO_PULSEOUT_H
-#include <stdbool.h>
+#include "common-hal/microcontroller/Pin.h"
+#include "common-hal/pulseio/PWMOut.h"
-#include "py/objlist.h"
-#include "shared-module/_bleio/Address.h"
+#include "py/obj.h"
typedef struct {
mp_obj_base_t base;
- volatile bool waiting_to_connect;
- volatile uint16_t conn_handle;
- // Services discovered after connecting to a remote peripheral.
- mp_obj_list_t *remote_service_list;
-} bleio_central_obj_t;
+ const pulseio_pwmout_obj_t *pwmout;
+} pulseio_pulseout_obj_t;
-#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CENTRAL_H
+void pulseout_reset(void);
+
+#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_PULSEIO_PULSEOUT_H
diff --git a/ports/stm32f4/common-hal/pulseio/__init__.c b/ports/stm32f4/common-hal/pulseio/__init__.c
new file mode 100644
index 000000000..2bee925bc
--- /dev/null
+++ b/ports/stm32f4/common-hal/pulseio/__init__.c
@@ -0,0 +1 @@
+// No pulseio module functions.
diff --git a/ports/stm32f4/common-hal/time/__init__.c b/ports/stm32f4/common-hal/time/__init__.c
index e3cb481ef..976f519db 100644
--- a/ports/stm32f4/common-hal/time/__init__.c
+++ b/ports/stm32f4/common-hal/time/__init__.c
@@ -29,7 +29,7 @@
#include "tick.h"
uint64_t common_hal_time_monotonic(void) {
- return ticks_ms;
+ return supervisor_ticks_ms64();
}
void common_hal_time_delay_ms(uint32_t delay) {
diff --git a/ports/stm32f4/mpconfigport.h b/ports/stm32f4/mpconfigport.h
index 543a55942..7737bda8d 100644
--- a/ports/stm32f4/mpconfigport.h
+++ b/ports/stm32f4/mpconfigport.h
@@ -39,7 +39,10 @@
#include "py/circuitpy_mpconfig.h"
+#define MAX_UART 10 //how many UART are implemented
+
#define MICROPY_PORT_ROOT_POINTERS \
+ void *cpy_uart_obj_all[MAX_UART]; \
CIRCUITPY_COMMON_ROOT_POINTERS
#endif // __INCLUDED_MPCONFIGPORT_H
diff --git a/ports/stm32f4/mpconfigport.mk b/ports/stm32f4/mpconfigport.mk
index ffe586898..3ae0daaa0 100644
--- a/ports/stm32f4/mpconfigport.mk
+++ b/ports/stm32f4/mpconfigport.mk
@@ -15,16 +15,56 @@ LONGINT_IMPL = MPZ
#Reduced feature set for early port
CIRCUITPY_MINIMAL_BUILD = 1
+# The ifndef's allow overriding in mpconfigboard.mk.
+
+ifndef CIRCUITPY_BOARD
CIRCUITPY_BOARD = 1
+endif
+
+ifndef CIRCUITPY_DIGITALIO
CIRCUITPY_DIGITALIO = 1
+endif
+
+ifndef CIRCUITPY_ANALOGIO
CIRCUITPY_ANALOGIO = 1
+endif
+
+ifndef CIRCUITPY_MICROCONTROLLER
CIRCUITPY_MICROCONTROLLER = 1
+endif
+
+ifndef CIRCUITPY_BUSIO
CIRCUITPY_BUSIO = 1
+endif
+
+ifndef CIRCUITPY_PULSEIO
+CIRCUITPY_PULSEIO = 1
+endif
+
+ifndef CIRCUITPY_OS
CIRCUITPY_OS = 1
+endif
+
+ifndef CIRCUITPY_STORAGE
CIRCUITPY_STORAGE = 1
+endif
+
+ifndef CIRCUITPY_RANDOM
CIRCUITPY_RANDOM = 1
+endif
+
+ifndef CRICUITPY_USB_HID
CIRCUITPY_USB_HID = 1
+endif
+
+ifndef CIRCUITPY_USB_MIDI
CIRCUITPY_USB_MIDI = 1
+endif
+
+ifndef CIRCUITPY_NEOPIXEL_WRITE
+CIRCUITPY_NEOPIXEL_WRITE = 1
+endif
+
#ifeq ($(MCU_SUB_VARIANT), stm32f412zx)
#endif
diff --git a/ports/stm32f4/mphalport.c b/ports/stm32f4/mphalport.c
index ea864e7ce..f78e9c750 100644
--- a/ports/stm32f4/mphalport.c
+++ b/ports/stm32f4/mphalport.c
@@ -31,11 +31,13 @@
#include "py/mpstate.h"
#include "py/gc.h"
+#include "supervisor/shared/tick.h"
+
/*------------------------------------------------------------------*/
/* delay
*------------------------------------------------------------------*/
void mp_hal_delay_ms(mp_uint_t delay) {
- uint64_t start_tick = ticks_ms;
+ uint64_t start_tick = supervisor_ticks_ms64();
uint64_t duration = 0;
while (duration < delay) {
#ifdef MICROPY_VM_HOOK_LOOP
@@ -46,7 +48,7 @@ void mp_hal_delay_ms(mp_uint_t delay) {
MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
break;
}
- duration = (ticks_ms - start_tick);
+ duration = (supervisor_ticks_ms64() - 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
index 131f2751d..df2f0ca65 100644
--- a/ports/stm32f4/mphalport.h
+++ b/ports/stm32f4/mphalport.h
@@ -32,12 +32,10 @@
#include "lib/utils/interrupt_char.h"
#include "py/mpconfig.h"
+#include "supervisor/shared/tick.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_ticks_ms() ((mp_uint_t) supervisor_ticks_ms32())
//#define mp_hal_delay_us(us) NRFX_DELAY_US((uint32_t) (us))
bool mp_hal_stdin_any(void);
diff --git a/ports/stm32f4/peripherals/stm32f4/periph.h b/ports/stm32f4/peripherals/stm32f4/periph.h
index 82f179147..0d1374e85 100644
--- a/ports/stm32f4/peripherals/stm32f4/periph.h
+++ b/ports/stm32f4/peripherals/stm32f4/periph.h
@@ -34,8 +34,8 @@
#include "stm32f4/pins.h"
// I2C
-//TODO: these objects should be condensed into a single 'periph_pin' unless we
-//find a compelling reason to store more unique data in them.
+// TODO: these objects should be condensed into a single 'periph_pin' unless we
+// find a compelling reason to store more unique data in them.
typedef struct {
uint8_t i2c_index:4; // Index of the I2C unit (1 to 3)
@@ -65,8 +65,8 @@ typedef struct {
}
// SPI
-//TODO: these objects should be condensed into a single 'periph_pin' unless we
-//find a compelling reason to store more unique data in them.
+// TODO: these objects should be condensed into a single 'periph_pin' unless we
+// find a compelling reason to store more unique data in them.
typedef struct {
uint8_t spi_index:4; //Up to 6 SPI units
@@ -99,15 +99,56 @@ typedef struct {
.pin = spi_pin, \
}
+// UART
+// TODO: these objects should be condensed into a single 'periph_pin' unless we
+// find a compelling reason to store more unique data in them.
+
+typedef struct {
+ uint8_t uart_index:4;
+ uint8_t altfn_index:4;
+ const mcu_pin_obj_t * pin;
+} mcu_uart_tx_obj_t;
+
+typedef struct {
+ uint8_t uart_index:4;
+ uint8_t altfn_index:4;
+ const mcu_pin_obj_t * pin;
+} mcu_uart_rx_obj_t;
+
+#define UART(index, alt, uart_pin) \
+{ \
+ .uart_index = index, \
+ .altfn_index = alt, \
+ .pin = uart_pin, \
+}
+
+//Timers
+typedef struct {
+ uint8_t tim_index:4;
+ uint8_t altfn_index:4;
+ uint8_t channel_index:4;
+ const mcu_pin_obj_t * pin;
+} mcu_tim_pin_obj_t;
+
+#define TIM(index, alt, channel, tim_pin) \
+{ \
+ .tim_index = index, \
+ .altfn_index = alt, \
+ .channel_index = channel, \
+ .pin = tim_pin, \
+}
+
//Starter Lines
#ifdef STM32F411xE
#define HAS_DAC 0
+#define HAS_TRNG 0
#include "stm32f411xe/periph.h"
#endif
#ifdef STM32F412Zx
#define HAS_DAC 0
+#define HAS_TRNG 1
#include "stm32f412zx/periph.h"
#endif
@@ -115,6 +156,7 @@ typedef struct {
#ifdef STM32F405xx
#define HAS_DAC 1
+#define HAS_TRNG 1
#include "stm32f405xx/periph.h"
#endif
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/clocks.c b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/clocks.c
index 74eeb4b24..c259f54fa 100644
--- a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/clocks.c
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/clocks.c
@@ -48,7 +48,7 @@ void stm32f4_peripherals_clocks_init(void) {
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 12;
RCC_OscInitStruct.PLL.PLLN = 336;
- RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
+ RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
@@ -57,7 +57,7 @@ void stm32f4_peripherals_clocks_init(void) {
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.c b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.c
index 7b0a54e55..bc03f7c7b 100644
--- a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.c
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.c
@@ -85,4 +85,110 @@ const mcu_spi_nss_obj_t mcu_spi_nss_list[6] = {
SPI(3, 6, &pin_PA04),
SPI(3, 6, &pin_PA15),
};
-//UART, Etc
+
+USART_TypeDef * mcu_uart_banks[MAX_UART] = {USART1, USART2, USART3, UART4, UART5, USART6};
+bool mcu_uart_has_usart[MAX_UART] = {true, true, true, false, false, true};
+
+const mcu_uart_tx_obj_t mcu_uart_tx_list[12] = {
+ UART(4, 8, &pin_PA00),
+ UART(2, 7, &pin_PA02),
+ UART(1, 7, &pin_PA09),
+ UART(1, 7, &pin_PB06),
+ UART(3, 7, &pin_PB10),
+ UART(6, 8, &pin_PC06),
+ UART(3, 7, &pin_PC10),
+ UART(4, 8, &pin_PC10),
+ UART(5, 8, &pin_PC12),
+ UART(2, 7, &pin_PD05),
+ UART(3, 7, &pin_PD08),
+ UART(6, 8, &pin_PG14),
+};
+
+const mcu_uart_rx_obj_t mcu_uart_rx_list[12] = {
+ UART(4, 8, &pin_PA01),
+ UART(2, 7, &pin_PA03),
+ UART(1, 7, &pin_PA10),
+ UART(1, 7, &pin_PB07),
+ UART(3, 7, &pin_PB11),
+ UART(6, 8, &pin_PC07),
+ UART(3, 7, &pin_PC11),
+ UART(4, 8, &pin_PC11),
+ UART(5, 8, &pin_PD02),
+ UART(2, 7, &pin_PD06),
+ UART(3, 7, &pin_PD09),
+ UART(6, 8, &pin_PG09),
+};
+
+//Timers
+//TIM6 and TIM7 are basic timers that are only used by DAC, and don't have pins
+TIM_TypeDef * mcu_tim_banks[14] = {TIM1, TIM2, TIM3, TIM4, TIM5, NULL, NULL, TIM8, TIM9, TIM10,
+ TIM11, TIM12, TIM13, TIM14};
+
+const mcu_tim_pin_obj_t mcu_tim_pin_list[56] = {
+ TIM(2,1,1,&pin_PA00),
+ TIM(5,2,1,&pin_PA00),
+ TIM(2,1,2,&pin_PA01),
+ TIM(5,2,2,&pin_PA01),
+ TIM(2,1,3,&pin_PA02),
+ TIM(5,2,3,&pin_PA02),
+ TIM(2,1,4,&pin_PA03),
+ TIM(5,2,4,&pin_PA03),
+ TIM(9,3,1,&pin_PA02),
+ TIM(9,3,2,&pin_PA03),
+ TIM(3,2,1,&pin_PA06),
+ TIM(13,9,1,&pin_PA06),
+ TIM(3,2,2,&pin_PA07),
+ TIM(14,9,1,&pin_PA07),
+ TIM(1,1,1,&pin_PA08),
+ TIM(1,1,2,&pin_PA09),
+ TIM(1,1,3,&pin_PA10),
+ TIM(1,1,4,&pin_PA11),
+ TIM(2,1,1,&pin_PA15),
+ TIM(3,2,3,&pin_PB00),
+ TIM(3,2,4,&pin_PB01),
+ TIM(2,1,2,&pin_PB03),
+ TIM(3,2,1,&pin_PB04),
+ TIM(3,2,2,&pin_PB05),
+ TIM(4,2,1,&pin_PB06),
+ TIM(4,2,2,&pin_PB07),
+ TIM(4,2,3,&pin_PB08),
+ TIM(10,2,1,&pin_PB08),
+ TIM(4,2,4,&pin_PB09),
+ TIM(11,2,1,&pin_PB09),
+ TIM(2,1,3,&pin_PB10),
+ TIM(2,1,4,&pin_PB11),
+ TIM(12,9,1,&pin_PB14),
+ TIM(12,9,2,&pin_PB15),
+ TIM(3,2,1,&pin_PC06),
+ TIM(3,2,2,&pin_PC07),
+ TIM(3,2,3,&pin_PC08),
+ TIM(3,2,4,&pin_PC09),
+ TIM(8,3,1,&pin_PC06),
+ TIM(8,3,2,&pin_PC07),
+ TIM(8,3,3,&pin_PC08),
+ TIM(8,3,4,&pin_PC09),
+ TIM(4,2,1,&pin_PD12),
+ TIM(4,2,2,&pin_PD13),
+ TIM(4,2,3,&pin_PD14),
+ TIM(4,2,4,&pin_PD15),
+ TIM(9,3,1,&pin_PE05),
+ TIM(9,3,2,&pin_PE06),
+ TIM(1,1,1,&pin_PE09),
+ TIM(1,1,2,&pin_PE11),
+ TIM(1,1,3,&pin_PE13),
+ TIM(1,1,4,&pin_PE14),
+ TIM(10,3,1,&pin_PF06),
+ TIM(11,3,1,&pin_PF07),
+ TIM(13,9,1,&pin_PF08),
+ TIM(14,9,1,&pin_PF09),
+ // TIM(12,9,1,&pin_PH06), //TODO: include these when pin map is expanded
+ // TIM(12,9,2,&pin_PH09),
+ // TIM(5,2,1,&pin_PH10),
+ // TIM(5,2,2,&pin_PH11),
+ // TIM(5,2,3,&pin_PH12),
+ // TIM(5,2,4,&pin_PI00),
+ // TIM(8,3,4,&pin_PI02),
+ // TIM(8,3,1,&pin_PI05),
+ // TIM(8,3,2,&pin_PI06),
+ // TIM(8,3,3,&pin_PI07),
+};
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.h b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.h
index cb9b33f6e..e87e79857 100644
--- a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.h
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.h
@@ -41,5 +41,17 @@ extern const mcu_spi_mosi_obj_t mcu_spi_mosi_list[6];
extern const mcu_spi_miso_obj_t mcu_spi_miso_list[6];
extern const mcu_spi_nss_obj_t mcu_spi_nss_list[6];
+//UART
+extern USART_TypeDef * mcu_uart_banks[MAX_UART];
+extern bool mcu_uart_has_usart[MAX_UART];
+
+extern const mcu_uart_tx_obj_t mcu_uart_tx_list[12];
+extern const mcu_uart_rx_obj_t mcu_uart_rx_list[12];
+
+//Timers
+#define TIM_BANK_ARRAY_LEN 14
+#define TIM_PIN_ARRAY_LEN 56
+TIM_TypeDef * mcu_tim_banks[TIM_BANK_ARRAY_LEN];
+const mcu_tim_pin_obj_t mcu_tim_pin_list[TIM_PIN_ARRAY_LEN];
#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F405XX_PERIPH_H \ No newline at end of file
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.c b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.c
index f0966f785..b7d9edf4f 100644
--- a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.c
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.c
@@ -119,4 +119,76 @@ const mcu_spi_nss_obj_t mcu_spi_nss_list[12] = {
SPI(5, 6, &pin_PE11)
};
-//UART, Etc
+USART_TypeDef * mcu_uart_banks[MAX_UART] = {USART1, USART2, NULL, NULL, NULL, USART6};
+bool mcu_uart_has_usart[MAX_UART] = {true, true, false, false, false, true};
+
+const mcu_uart_tx_obj_t mcu_uart_tx_list[7] = {
+ UART(2, 7, &pin_PA02),
+ UART(1, 7, &pin_PA09),
+ UART(1, 7, &pin_PA15),
+ UART(6, 8, &pin_PA11),
+ UART(1, 7, &pin_PB06),
+ UART(6, 8, &pin_PC06),
+ UART(2, 7, &pin_PD05),
+};
+
+const mcu_uart_rx_obj_t mcu_uart_rx_list[7] = {
+ UART(2, 7, &pin_PA03),
+ UART(1, 7, &pin_PA10),
+ UART(6, 8, &pin_PA12),
+ UART(1, 7, &pin_PB03),
+ UART(1, 7, &pin_PB07),
+ UART(6, 8, &pin_PC07),
+ UART(2, 7, &pin_PD06),
+};
+
+//Timers
+//TIM6 and TIM7 are basic timers that are only used by DAC, and don't have pins
+TIM_TypeDef * mcu_tim_banks[14] = {TIM1, TIM2, TIM3, TIM4, TIM5, NULL, NULL, NULL, TIM9, TIM10,
+ TIM11, NULL, NULL, NULL};
+
+const mcu_tim_pin_obj_t mcu_tim_pin_list[44] = {
+ TIM(2,1,1,&pin_PA00),
+ TIM(5,2,1,&pin_PA00),
+ TIM(2,1,2,&pin_PA01),
+ TIM(5,2,2,&pin_PA01),
+ TIM(2,1,3,&pin_PA02),
+ TIM(5,2,3,&pin_PA02),
+ TIM(2,1,4,&pin_PA03),
+ TIM(5,2,4,&pin_PA03),
+ TIM(9,3,1,&pin_PA02),
+ TIM(9,3,2,&pin_PA03),
+ TIM(3,2,1,&pin_PA06),
+ TIM(3,2,2,&pin_PA07),
+ TIM(1,1,1,&pin_PA08),
+ TIM(1,1,2,&pin_PA09),
+ TIM(1,1,3,&pin_PA10),
+ TIM(1,1,4,&pin_PA11),
+ TIM(2,1,1,&pin_PA15),
+ TIM(3,2,3,&pin_PB00),
+ TIM(3,2,4,&pin_PB01),
+ TIM(2,1,2,&pin_PB03),
+ TIM(3,2,1,&pin_PB04),
+ TIM(3,2,2,&pin_PB05),
+ TIM(4,2,1,&pin_PB06),
+ TIM(4,2,2,&pin_PB07),
+ TIM(4,2,3,&pin_PB08),
+ TIM(10,2,1,&pin_PB08),
+ TIM(4,2,4,&pin_PB09),
+ TIM(11,2,1,&pin_PB09),
+ TIM(2,1,3,&pin_PB10),
+ TIM(3,2,1,&pin_PC06),
+ TIM(3,2,2,&pin_PC07),
+ TIM(3,2,3,&pin_PC08),
+ TIM(3,2,4,&pin_PC09),
+ TIM(4,2,1,&pin_PD12),
+ TIM(4,2,2,&pin_PD13),
+ TIM(4,2,3,&pin_PD14),
+ TIM(4,2,4,&pin_PD15),
+ TIM(9,3,1,&pin_PE05),
+ TIM(9,3,2,&pin_PE06),
+ TIM(1,1,1,&pin_PE09),
+ TIM(1,1,2,&pin_PE11),
+ TIM(1,1,3,&pin_PE13),
+ TIM(1,1,4,&pin_PE14),
+};
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.h b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.h
index 08efa14ca..d657d73b6 100644
--- a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.h
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.h
@@ -41,4 +41,17 @@ extern const mcu_spi_mosi_obj_t mcu_spi_mosi_list[14];
extern const mcu_spi_miso_obj_t mcu_spi_miso_list[12];
extern const mcu_spi_nss_obj_t mcu_spi_nss_list[12];
+//UART
+extern USART_TypeDef * mcu_uart_banks[MAX_UART];
+extern bool mcu_uart_has_usart[MAX_UART];
+
+extern const mcu_uart_tx_obj_t mcu_uart_tx_list[7];
+extern const mcu_uart_rx_obj_t mcu_uart_rx_list[7];
+
+//Timers
+#define TIM_BANK_ARRAY_LEN 14
+#define TIM_PIN_ARRAY_LEN 44
+TIM_TypeDef * mcu_tim_banks[TIM_BANK_ARRAY_LEN];
+const mcu_tim_pin_obj_t mcu_tim_pin_list[TIM_PIN_ARRAY_LEN];
+
#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411VE_PERIPH_H \ No newline at end of file
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.c b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.c
index ea94719ec..f5effa80e 100644
--- a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.c
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.c
@@ -120,4 +120,104 @@ const mcu_spi_nss_obj_t mcu_spi_nss_list[12] = {
SPI(5, 6, &pin_PE11)
};
-//UART, Etc
+//UART
+
+USART_TypeDef * mcu_uart_banks[MAX_UART] = {USART1, USART2, USART3, NULL, NULL, USART6};
+bool mcu_uart_has_usart[MAX_UART] = {true, true, true, false, false, true};
+
+const mcu_uart_tx_obj_t mcu_uart_tx_list[11] = {
+ UART(2, 7, &pin_PA02),
+ UART(1, 7, &pin_PA09),
+ UART(1, 7, &pin_PA15),
+ UART(6, 8, &pin_PA11),
+ UART(1, 7, &pin_PB06),
+ UART(3, 7, &pin_PB10),
+ UART(6, 8, &pin_PC06),
+ UART(3, 7, &pin_PC10),
+ UART(2, 7, &pin_PD05),
+ UART(3, 7, &pin_PD08),
+ UART(6, 8, &pin_PG14),
+};
+
+const mcu_uart_rx_obj_t mcu_uart_rx_list[12] = {
+ UART(2, 7, &pin_PA03),
+ UART(1, 7, &pin_PA10),
+ UART(6, 8, &pin_PA12),
+ UART(1, 7, &pin_PB03),
+ UART(1, 7, &pin_PB07),
+ UART(3, 7, &pin_PB11),
+ UART(3, 7, &pin_PC05),
+ UART(6, 8, &pin_PC07),
+ UART(3, 7, &pin_PC11),
+ UART(2, 7, &pin_PD06),
+ UART(3, 7, &pin_PD09),
+ UART(6, 8, &pin_PG09),
+};
+
+//Timers
+//TIM6 and TIM7 are basic timers that are only used by DAC, and don't have pins
+TIM_TypeDef * mcu_tim_banks[14] = {TIM1, TIM2, TIM3, TIM4, TIM5, NULL, NULL, TIM8, TIM9, TIM10,
+ TIM11, TIM12, TIM13, TIM14};
+
+const mcu_tim_pin_obj_t mcu_tim_pin_list[60] = {
+ TIM(2,1,1,&pin_PA00),
+ TIM(5,2,1,&pin_PA00),
+ TIM(2,1,2,&pin_PA01),
+ TIM(5,2,2,&pin_PA01),
+ TIM(2,1,3,&pin_PA02),
+ TIM(5,2,3,&pin_PA02),
+ TIM(2,1,4,&pin_PA03),
+ TIM(5,2,4,&pin_PA03),
+ TIM(9,3,1,&pin_PA02),
+ TIM(9,3,2,&pin_PA03),
+ TIM(3,2,1,&pin_PA06),
+ TIM(13,9,1,&pin_PA06),
+ TIM(3,2,2,&pin_PA07),
+ TIM(14,9,1,&pin_PA07),
+ TIM(1,1,1,&pin_PA08),
+ TIM(1,1,2,&pin_PA09),
+ TIM(1,1,3,&pin_PA10),
+ TIM(1,1,4,&pin_PA11),
+ TIM(2,1,1,&pin_PA15),
+ TIM(3,2,3,&pin_PB00),
+ TIM(3,2,4,&pin_PB01),
+ TIM(2,1,2,&pin_PB03),
+ TIM(3,2,1,&pin_PB04),
+ TIM(3,2,2,&pin_PB05),
+ TIM(4,2,1,&pin_PB06),
+ TIM(4,2,2,&pin_PB07),
+ TIM(4,2,3,&pin_PB08),
+ TIM(10,2,1,&pin_PB08),
+ TIM(4,2,4,&pin_PB09),
+ TIM(11,2,1,&pin_PB09),
+ TIM(2,1,3,&pin_PB10),
+ TIM(2,1,4,&pin_PB11),
+ TIM(12,9,1,&pin_PB14),
+ TIM(12,9,2,&pin_PB15),
+ TIM(3,2,1,&pin_PC06),
+ TIM(3,2,2,&pin_PC07),
+ TIM(3,2,3,&pin_PC08),
+ TIM(3,2,4,&pin_PC09),
+ TIM(8,3,1,&pin_PC06),
+ TIM(8,3,2,&pin_PC07),
+ TIM(8,3,3,&pin_PC08),
+ TIM(8,3,4,&pin_PC09),
+ TIM(4,2,1,&pin_PD12),
+ TIM(4,2,2,&pin_PD13),
+ TIM(4,2,3,&pin_PD14),
+ TIM(4,2,4,&pin_PD15),
+ TIM(9,3,1,&pin_PE05),
+ TIM(9,3,2,&pin_PE06),
+ TIM(1,1,1,&pin_PE09),
+ TIM(1,1,2,&pin_PE11),
+ TIM(1,1,3,&pin_PE13),
+ TIM(1,1,4,&pin_PE14),
+ TIM(10,3,1,&pin_PF06),
+ TIM(11,3,1,&pin_PF07),
+ TIM(13,9,1,&pin_PF08),
+ TIM(14,9,1,&pin_PF09),
+ TIM(5,2,1,&pin_PF03),
+ TIM(5,2,2,&pin_PF04),
+ TIM(5,2,3,&pin_PF05),
+ TIM(5,2,4,&pin_PF10),
+};
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.h b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.h
index d12bbba93..e0141e6da 100644
--- a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.h
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.h
@@ -42,4 +42,17 @@ extern const mcu_spi_mosi_obj_t mcu_spi_mosi_list[14];
extern const mcu_spi_miso_obj_t mcu_spi_miso_list[12];
extern const mcu_spi_nss_obj_t mcu_spi_nss_list[12];
+//UART
+extern USART_TypeDef * mcu_uart_banks[MAX_UART];
+extern bool mcu_uart_has_usart[MAX_UART];
+
+extern const mcu_uart_tx_obj_t mcu_uart_tx_list[11];
+extern const mcu_uart_rx_obj_t mcu_uart_rx_list[12];
+
+//Timers
+#define TIM_BANK_ARRAY_LEN 14
+#define TIM_PIN_ARRAY_LEN 60
+TIM_TypeDef * mcu_tim_banks[TIM_BANK_ARRAY_LEN];
+const mcu_tim_pin_obj_t mcu_tim_pin_list[TIM_PIN_ARRAY_LEN];
+
#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411VE_PERIPH_H \ No newline at end of file
diff --git a/ports/stm32f4/supervisor/port.c b/ports/stm32f4/supervisor/port.c
index df7a6ca42..df5a70cd1 100644
--- a/ports/stm32f4/supervisor/port.c
+++ b/ports/stm32f4/supervisor/port.c
@@ -33,6 +33,8 @@
#include "common-hal/microcontroller/Pin.h"
#include "common-hal/busio/I2C.h"
#include "common-hal/busio/SPI.h"
+#include "common-hal/busio/UART.h"
+#include "common-hal/pulseio/PWMOut.h"
#include "stm32f4/clocks.h"
#include "stm32f4/gpio.h"
@@ -40,12 +42,12 @@
#include "stm32f4xx_hal.h"
safe_mode_t port_init(void) {
- HAL_Init();
+ HAL_Init();
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
- stm32f4_peripherals_clocks_init();
- stm32f4_peripherals_gpio_init();
+ stm32f4_peripherals_clocks_init();
+ stm32f4_peripherals_gpio_init();
tick_init();
board_init();
@@ -54,9 +56,11 @@ safe_mode_t port_init(void) {
}
void reset_port(void) {
- reset_all_pins();
+ reset_all_pins();
i2c_reset();
spi_reset();
+ uart_reset();
+ pwmout_reset();
}
void reset_to_bootloader(void) {
@@ -64,7 +68,15 @@ void reset_to_bootloader(void) {
}
void reset_cpu(void) {
- NVIC_SystemReset();
+ NVIC_SystemReset();
+}
+
+uint32_t *port_stack_get_limit(void) {
+ return &_ebss;
+}
+
+uint32_t *port_stack_get_top(void) {
+ return &_estack;
}
extern uint32_t _ebss;
@@ -78,7 +90,7 @@ uint32_t port_get_saved_word(void) {
}
void HardFault_Handler(void) {
- reset_into_safe_mode(HARD_CRASH);
+ reset_into_safe_mode(HARD_CRASH);
while (true) {
asm("nop;");
}
diff --git a/ports/stm32f4/tick.c b/ports/stm32f4/tick.c
index b417df305..f4adf183a 100644
--- a/ports/stm32f4/tick.c
+++ b/ports/stm32f4/tick.c
@@ -26,52 +26,43 @@
#include "tick.h"
-#include "supervisor/shared/autoreload.h"
#include "supervisor/filesystem.h"
-#include "shared-module/gamepad/__init__.h"
+#include "supervisor/shared/tick.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
-#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
- autoreload_tick();
-#endif
-#ifdef CIRCUITPY_GAMEPAD_TICKS
- if (!(ticks_ms & CIRCUITPY_GAMEPAD_TICKS)) {
- gamepad_tick();
- }
-#endif
+ // Do things common to all ports when the tick occurs
+ supervisor_tick();
}
uint32_t HAL_GetTick(void) //override ST HAL
{
- return (uint32_t)ticks_ms;
+ return (uint32_t)supervisor_ticks_ms32();
}
void tick_init() {
uint32_t ticks_per_ms = SystemCoreClock/ 1000;
SysTick_Config(ticks_per_ms); // interrupt is enabled
+
+ NVIC_EnableIRQ(SysTick_IRQn);
+ // Bump up the systick interrupt so nothing else interferes with timekeeping.
+ NVIC_SetPriority(SysTick_IRQn, 0);
+ NVIC_SetPriority(OTG_FS_IRQn, 1);
}
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;
+ uint64_t start_ms = supervisor_ticks_ms64();
while (us > 1000) {
- while (ticks_ms == start_ms) {}
+ while (supervisor_ticks_ms64() == start_ms) {}
us -= us_between_ticks;
- start_ms = ticks_ms;
+ start_ms = supervisor_ticks_ms64();
us_between_ticks = 1000;
}
while (SysTick->VAL > ((us_between_ticks - us) * ticks_per_us)) {}
@@ -80,11 +71,11 @@ void tick_delay(uint32_t 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;
+ *ms = supervisor_ticks_ms32();
*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) {}
+ while(supervisor_ticks_ms64() <= ms && SysTick->VAL / ticks_per_us >= us_until_ms) {}
}
diff --git a/ports/stm32f4/tick.h b/ports/stm32f4/tick.h
index e4772fa2c..999acc7a3 100644
--- a/ports/stm32f4/tick.h
+++ b/ports/stm32f4/tick.h
@@ -30,8 +30,6 @@
#include <stdint.h>
-extern volatile uint64_t ticks_ms;
-
extern struct timer_descriptor ms_timer;
void tick_init(void);
diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk
index 915310f83..34c097e36 100644
--- a/py/circuitpy_defns.mk
+++ b/py/circuitpy_defns.mk
@@ -229,12 +229,10 @@ SRC_COMMON_HAL_ALL = \
_bleio/__init__.c \
_bleio/Adapter.c \
_bleio/Attribute.c \
- _bleio/Central.c \
_bleio/Characteristic.c \
_bleio/CharacteristicBuffer.c \
+ _bleio/Connection.c \
_bleio/Descriptor.c \
- _bleio/Peripheral.c \
- _bleio/Scanner.c \
_bleio/Service.c \
_bleio/UUID.c \
analogio/AnalogIn.c \
@@ -306,6 +304,7 @@ SRC_SHARED_MODULE_ALL = \
_bleio/Address.c \
_bleio/Attribute.c \
_bleio/ScanEntry.c \
+ _bleio/ScanResults.c \
_pixelbuf/PixelBuf.c \
_pixelbuf/__init__.c \
_stage/Layer.c \
diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h
index 227376ead..cf21d26dd 100644
--- a/py/circuitpy_mpconfig.h
+++ b/py/circuitpy_mpconfig.h
@@ -28,11 +28,12 @@
// sure that the same feature set and settings are used, such as in atmel-samd
// and nrf.
-#include <stdint.h>
-
#ifndef __INCLUDED_MPCONFIG_CIRCUITPY_H
#define __INCLUDED_MPCONFIG_CIRCUITPY_H
+#include <stdint.h>
+#include <stdatomic.h>
+
// This is CircuitPython.
#define CIRCUITPY 1
@@ -56,8 +57,8 @@
#define MICROPY_COMP_MODULE_CONST (1)
#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0)
#define MICROPY_DEBUG_PRINTERS (0)
-#define MICROPY_EMIT_INLINE_THUMB (0)
-#define MICROPY_EMIT_THUMB (0)
+#define MICROPY_EMIT_INLINE_THUMB (CIRCUITPY_ENABLE_MPY_NATIVE)
+#define MICROPY_EMIT_THUMB (CIRCUITPY_ENABLE_MPY_NATIVE)
#define MICROPY_EMIT_X64 (0)
#define MICROPY_ENABLE_DOC_STRING (0)
#define MICROPY_ENABLE_FINALISER (1)
@@ -139,7 +140,6 @@
#define MICROPY_VFS_FAT (MICROPY_VFS)
#define MICROPY_READER_VFS (MICROPY_VFS)
-
// type definitions for the specific machine
#define BYTES_PER_WORD (4)
@@ -213,6 +213,10 @@ typedef long mp_off_t;
#define MP_SSIZE_MAX (0x7fffffff)
#endif
+#if INTERNAL_FLASH_FILESYSTEM == 0 && QSPI_FLASH_FILESYSTEM == 0 && SPI_FLASH_FILESYSTEM == 0 && !CIRCUITPY_MINIMAL_BUILD
+#error No *_FLASH_FILESYSTEM set!
+#endif
+
// These CIRCUITPY_xxx values should all be defined in the *.mk files as being on or off.
// So if any are not defined in *.mk, they'll throw an error here.
@@ -652,14 +656,14 @@ extern const struct _mp_obj_module_t ustack_module;
FLASH_ROOT_POINTERS \
NETWORK_ROOT_POINTERS \
-void run_background_tasks(void);
-#define RUN_BACKGROUND_TASKS (run_background_tasks())
+void supervisor_run_background_tasks_if_tick(void);
+#define RUN_BACKGROUND_TASKS (supervisor_run_background_tasks_if_tick())
// TODO: Used in wiznet5k driver, but may not be needed in the long run.
#define MICROPY_THREAD_YIELD()
-#define MICROPY_VM_HOOK_LOOP run_background_tasks();
-#define MICROPY_VM_HOOK_RETURN run_background_tasks();
+#define MICROPY_VM_HOOK_LOOP RUN_BACKGROUND_TASKS;
+#define MICROPY_VM_HOOK_RETURN RUN_BACKGROUND_TASKS;
// CIRCUITPY_AUTORELOAD_DELAY_MS = 0 will completely disable autoreload.
#ifndef CIRCUITPY_AUTORELOAD_DELAY_MS
diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk
index c0548abfa..8ab6b1288 100644
--- a/py/circuitpy_mpconfig.mk
+++ b/py/circuitpy_mpconfig.mk
@@ -33,15 +33,19 @@
ifndef CIRCUITPY_FULL_BUILD
ifeq ($(CIRCUITPY_SMALL_BUILD),1)
CIRCUITPY_FULL_BUILD = 0
- CFLAGS += -DCIRCUITPY_FULL_BUILD=0
else
CIRCUITPY_FULL_BUILD = 1
- CFLAGS += -DCIRCUITPY_FULL_BUILD=1
endif
endif
+CFLAGS += -DCIRCUITPY_FULL_BUILD=$(CIRCUITPY_FULL_BUILD)
# Setting CIRCUITPY_MINIMAL_BUILD = 1 will disable all features
# Use for for early stage or highly restricted ports
+ifndef CIRCUITPY_MINIMAL_BUILD
+CIRCUITPY_MINIMAL_BUILD = 0
+endif
+CFLAGS += -DCIRCUITPY_MINIMAL_BUILD=$(CIRCUITPY_MINIMAL_BUILD)
+
ifndef CIRCUITPY_DEFAULT_BUILD
ifeq ($(CIRCUITPY_MINIMAL_BUILD),1)
CIRCUITPY_FULL_BUILD = 0
@@ -50,12 +54,14 @@ ifndef CIRCUITPY_DEFAULT_BUILD
CIRCUITPY_DEFAULT_BUILD = 1
endif
endif
+CFLAGS += -DCIRCUITPY_DEFAULT_BUILD=$(CIRCUITPY_DEFAULT_BUILD)
# Some features have no unique HAL component, and thus there's never
-# a reason to not include them.
+# a reason to not include them.
ifndef CIRCUITPY_ALWAYS_BUILD
CIRCUITPY_ALWAYS_BUILD = 1
endif
+CFLAGS += -DCIRCUITPY_ALWAYS_BUILD=$(CIRCUITPY_ALWAYS_BUILD)
# All builtin modules are listed below, with default values (0 for off, 1 for on)
@@ -169,7 +175,7 @@ CIRCUITPY_NEOPIXEL_WRITE = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_NEOPIXEL_WRITE=$(CIRCUITPY_NEOPIXEL_WRITE)
-# Only certain boards support NETWORK (Ethernet)
+# Enabled on SAMD51. Won't fit on SAMD21 builds. Not tested on nRF or STM32F4 builds.
ifndef CIRCUITPY_NETWORK
CIRCUITPY_NETWORK = 0
endif
@@ -306,3 +312,9 @@ ifndef CIRCUITPY_SERIAL_UART
CIRCUITPY_SERIAL_UART = 0
endif
CFLAGS += -DCIRCUITPY_SERIAL_UART=$(CIRCUITPY_SERIAL_UART)
+
+# Enabled micropython.native decorator (experimental)
+ifndef CIRCUITPY_ENABLE_MPY_NATIVE
+CIRCUITPY_ENABLE_MPY_NATIVE = 0
+endif
+CFLAGS += -DCIRCUITPY_ENABLE_MPY_NATIVE=$(CIRCUITPY_ENABLE_MPY_NATIVE)
diff --git a/py/compile.c b/py/compile.c
index 1218aa07e..77715d3fe 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -775,13 +775,22 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_
qstr attr = MP_PARSE_NODE_LEAF_ARG(name_nodes[1]);
if (attr == MP_QSTR_bytecode) {
*emit_options = MP_EMIT_OPT_BYTECODE;
-#if MICROPY_EMIT_NATIVE
+ // @micropython.native decorator.
} else if (attr == MP_QSTR_native) {
+ // Different from MicroPython: native doesn't raise SyntaxError if native support isn't
+ // compiled, it just passes through the function unmodified.
+ #if MICROPY_EMIT_NATIVE
*emit_options = MP_EMIT_OPT_NATIVE_PYTHON;
+ #else
+ return true;
+ #endif
+ #if MICROPY_EMIT_NATIVE
+ // @micropython.viper decorator.
} else if (attr == MP_QSTR_viper) {
*emit_options = MP_EMIT_OPT_VIPER;
-#endif
+ #endif
#if MICROPY_EMIT_INLINE_ASM
+ // @micropython.asm_thumb decorator.
} else if (attr == ASM_DECORATOR_QSTR) {
*emit_options = MP_EMIT_OPT_ASM;
#endif
@@ -3207,7 +3216,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
}
if (pass > MP_PASS_SCOPE) {
mp_int_t bytesize = MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]);
- for (uint j = 1; j < n_args; j++) {
+ for (int j = 1; j < n_args; j++) {
if (!MP_PARSE_NODE_IS_SMALL_INT(pn_arg[j])) {
compile_syntax_error(comp, nodes[i], translate("'data' requires integer arguments"));
return;
diff --git a/py/emitnative.c b/py/emitnative.c
index 67b0025c6..6d23bf097 100644
--- a/py/emitnative.c
+++ b/py/emitnative.c
@@ -58,6 +58,22 @@
#define DEBUG_printf(...) (void)0
#endif
+#ifndef N_X64
+ #define N_X64 (0)
+#endif
+#ifndef N_X86
+ #define N_X86 (0)
+#endif
+#ifndef N_THUMB
+ #define N_THUMB (0)
+#endif
+#ifndef N_ARM
+ #define N_ARM (0)
+#endif
+#ifndef N_XTENSA
+ #define N_XTENSA (0)
+#endif
+
// wrapper around everything in this file
#if N_X64 || N_X86 || N_THUMB || N_ARM || N_XTENSA
@@ -443,10 +459,12 @@ STATIC void emit_native_end_pass(emit_t *emit) {
type_sig |= (emit->local_vtype[i] & 0xf) << (i * 4 + 4);
}
+ #pragma GCC diagnostic ignored "-Wcast-align"
mp_emit_glue_assign_native(emit->scope->raw_code,
emit->do_viper_types ? MP_CODE_NATIVE_VIPER : MP_CODE_NATIVE_PY,
f, f_len, (mp_uint_t*)((byte*)f + emit->const_table_offset),
emit->scope->num_pos_args, emit->scope->scope_flags, type_sig);
+ #pragma GCC diagnostic pop
}
}
diff --git a/py/gc.c b/py/gc.c
index ac584d5d2..a8a5fde12 100755
--- a/py/gc.c
+++ b/py/gc.c
@@ -53,9 +53,6 @@
// detect untraced object still in use
#define CLEAR_ON_SWEEP (0)
-#define WORDS_PER_BLOCK ((MICROPY_BYTES_PER_GC_BLOCK) / BYTES_PER_WORD)
-#define BYTES_PER_BLOCK (MICROPY_BYTES_PER_GC_BLOCK)
-
// ATB = allocation table byte
// 0b00 = FREE -- free block
// 0b01 = HEAD -- head of a chain of blocks
@@ -209,13 +206,6 @@ bool gc_is_locked(void) {
return MP_STATE_MEM(gc_lock_depth) != 0;
}
-// ptr should be of type void*
-#define VERIFY_PTR(ptr) ( \
- ((uintptr_t)(ptr) & (BYTES_PER_BLOCK - 1)) == 0 /* must be aligned on a block */ \
- && ptr >= (void*)MP_STATE_MEM(gc_pool_start) /* must be above start of pool */ \
- && ptr < (void*)MP_STATE_MEM(gc_pool_end) /* must be below end of pool */ \
- )
-
#ifndef TRACE_MARK
#if DEBUG_PRINT
#define TRACE_MARK(block, ptr) DEBUG_printf("gc_mark(%p)\n", ptr)
diff --git a/py/gc.h b/py/gc.h
index 02bf45158..cd63ba94c 100644
--- a/py/gc.h
+++ b/py/gc.h
@@ -29,8 +29,19 @@
#include <stdint.h>
#include "py/mpconfig.h"
+#include "py/mpstate.h"
#include "py/misc.h"
+#define WORDS_PER_BLOCK ((MICROPY_BYTES_PER_GC_BLOCK) / BYTES_PER_WORD)
+#define BYTES_PER_BLOCK (MICROPY_BYTES_PER_GC_BLOCK)
+
+// ptr should be of type void*
+#define VERIFY_PTR(ptr) ( \
+ ((uintptr_t)(ptr) & (BYTES_PER_BLOCK - 1)) == 0 /* must be aligned on a block */ \
+ && ptr >= (void*)MP_STATE_MEM(gc_pool_start) /* must be above start of pool */ \
+ && ptr < (void*)MP_STATE_MEM(gc_pool_end) /* must be below end of pool */ \
+ )
+
void gc_init(void *start, void *end);
void gc_deinit(void);
diff --git a/py/gc_long_lived.c b/py/gc_long_lived.c
index 49bf1fcd7..01c22a7af 100755
--- a/py/gc_long_lived.c
+++ b/py/gc_long_lived.c
@@ -126,6 +126,11 @@ mp_obj_t make_obj_long_lived(mp_obj_t obj, uint8_t max_depth){
if (obj == NULL) {
return obj;
}
+ // If not in the GC pool, do nothing. This can happen (at least) when
+ // there are frozen mp_type_bytes objects in ROM.
+ if (!VERIFY_PTR((void *)obj)) {
+ return obj;
+ }
if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_bc)) {
mp_obj_fun_bc_t *fun_bc = MP_OBJ_TO_PTR(obj);
return MP_OBJ_FROM_PTR(make_fun_bc_long_lived(fun_bc, max_depth));
diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py
index 8e3835d86..0d667959d 100644
--- a/py/makeqstrdata.py
+++ b/py/makeqstrdata.py
@@ -103,14 +103,10 @@ def compute_huffman_coding(translations, qstrs, compression_filename):
# go through each qstr and print it out
for _, _, qstr in qstrs.values():
all_strings.append(qstr)
- all_strings_concat = "".join(all_strings).encode("utf-8")
+ all_strings_concat = "".join(all_strings)
counts = collections.Counter(all_strings_concat)
- # add other values
- for i in range(256):
- if i not in counts:
- counts[i] = 0
cb = huffman.codebook(counts.items())
- values = bytearray()
+ values = []
length_count = {}
renumbered = 0
last_l = None
@@ -124,26 +120,27 @@ def compute_huffman_coding(translations, qstrs, compression_filename):
if last_l:
renumbered <<= (l - last_l)
canonical[ch] = '{0:0{width}b}'.format(renumbered, width=l)
- if chr(ch) in C_ESCAPES:
- s = C_ESCAPES[chr(ch)]
- else:
- s = chr(ch)
- print("//", ch, s, counts[ch], canonical[ch], renumbered)
+ s = C_ESCAPES.get(ch, ch)
+ print("//", ord(ch), s, counts[ch], canonical[ch], renumbered)
renumbered += 1
last_l = l
lengths = bytearray()
- for i in range(1, max(length_count) + 1):
+ print("// length count", length_count)
+ for i in range(1, max(length_count) + 2):
lengths.append(length_count.get(i, 0))
+ print("// values", values, "lengths", len(lengths), lengths)
+ print("// estimated total memory size", len(lengths) + 2*len(values) + sum(len(cb[u]) for u in all_strings_concat))
print("//", values, lengths)
+ values_type = "uint16_t" if max(ord(u) for u in values) > 255 else "uint8_t"
with open(compression_filename, "w") as f:
f.write("const uint8_t lengths[] = {{ {} }};\n".format(", ".join(map(str, lengths))))
- f.write("const uint8_t values[256] = {{ {} }};\n".format(", ".join(map(str, values))))
+ f.write("const {} values[] = {{ {} }};\n".format(values_type, ", ".join(str(ord(u)) for u in values)))
return values, lengths
def decompress(encoding_table, length, encoded):
values, lengths = encoding_table
#print(l, encoded)
- dec = bytearray(length)
+ dec = []
this_byte = 0
this_bit = 7
b = encoded[this_byte]
@@ -173,14 +170,14 @@ def decompress(encoding_table, length, encoded):
searched_length += lengths[bit_length]
v = values[searched_length + bits - max_code]
- dec[i] = v
- return dec
+ dec.append(v)
+ return ''.join(dec)
def compress(encoding_table, decompressed):
- if not isinstance(decompressed, bytes):
+ if not isinstance(decompressed, str):
raise TypeError()
values, lengths = encoding_table
- enc = bytearray(len(decompressed) * 2)
+ enc = bytearray(len(decompressed) * 3)
#print(decompressed)
#print(lengths)
current_bit = 7
@@ -228,7 +225,7 @@ def compress(encoding_table, decompressed):
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)
+ print("Note: compression increased length", repr(decompressed), len(decompressed), current_byte, file=sys.stderr)
return enc[:current_byte]
def qstr_escape(qst):
@@ -347,9 +344,9 @@ def print_qstr_data(encoding_table, qcfgs, qstrs, i18ns):
total_text_compressed_size = 0
for original, translation in i18ns:
translation_encoded = translation.encode("utf-8")
- compressed = compress(encoding_table, translation_encoded)
+ compressed = compress(encoding_table, translation)
total_text_compressed_size += len(compressed)
- decompressed = decompress(encoding_table, len(translation_encoded), compressed).decode("utf-8")
+ decompressed = decompress(encoding_table, len(translation_encoded), compressed)
for c in C_ESCAPES:
decompressed = decompressed.replace(c, C_ESCAPES[c])
print("TRANSLATION(\"{}\", {}, {{ {} }}) // {}".format(original, len(translation_encoded)+1, ", ".join(["0x{:02x}".format(x) for x in compressed]), decompressed))
diff --git a/py/objfun.c b/py/objfun.c
index b8364815b..7e5899456 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -546,7 +546,7 @@ STATIC mp_uint_t convert_obj_for_inline_asm(mp_obj_t obj) {
STATIC mp_obj_t fun_asm_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_obj_fun_asm_t *self = self_in;
- mp_arg_check_num(n_args, n_kw, self->n_args, self->n_args, false);
+ mp_arg_check_num_kw_array(n_args, n_kw, self->n_args, self->n_args, false);
void *fun = MICROPY_MAKE_POINTER_CALLABLE(self->fun_data);
diff --git a/py/py.mk b/py/py.mk
index 17cb79264..e1367ef1d 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -307,7 +307,7 @@ $(HEADER_BUILD)/mpversion.h: FORCE | $(HEADER_BUILD)
# build a list of registered modules for py/objmodule.c.
$(HEADER_BUILD)/moduledefs.h: $(SRC_QSTR) $(QSTR_GLOBAL_DEPENDENCIES) | $(HEADER_BUILD)/mpversion.h
- @$(ECHO) "GEN $@"
+ @$(STEPECHO) "GEN $@"
$(Q)$(PYTHON) $(PY_SRC)/makemoduledefs.py --vpath="., $(TOP), $(USER_C_MODULES)" $(SRC_QSTR) > $@
SRC_QSTR += $(HEADER_BUILD)/moduledefs.h
diff --git a/py/ringbuf.h b/py/ringbuf.h
index 5f82cc096..7fc35d266 100644
--- a/py/ringbuf.h
+++ b/py/ringbuf.h
@@ -99,4 +99,11 @@ static inline void ringbuf_put_n(ringbuf_t* r, uint8_t* buf, uint8_t bufsize)
}
}
}
+
+static inline void ringbuf_get_n(ringbuf_t* r, uint8_t* buf, uint8_t bufsize)
+{
+ for(uint8_t i=0; i < bufsize; i++) {
+ buf[i] = ringbuf_get(r);
+ }
+}
#endif // MICROPY_INCLUDED_PY_RINGBUF_H
diff --git a/py/runtime.c b/py/runtime.c
index 9968f26e0..a786619bf 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -31,8 +31,6 @@
#include "extmod/vfs.h"
-// #include "py/mpstate.h"
-// #include "py/nlr.h"
#include "py/parsenum.h"
#include "py/compile.h"
#include "py/objstr.h"
diff --git a/py/vm.c b/py/vm.c
index b5f53ee9a..353fc8810 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -758,7 +758,7 @@ unwind_jump:;
} else {
PUSH(value); // push the next iteration value
}
- DISPATCH();
+ DISPATCH_WITH_PEND_EXC_CHECK();
}
// matched against: SETUP_EXCEPT, SETUP_FINALLY, SETUP_WITH
diff --git a/shared-bindings/_bleio/Adapter.c b/shared-bindings/_bleio/Adapter.c
index 0caca96b8..7e2a5f05b 100644
--- a/shared-bindings/_bleio/Adapter.c
+++ b/shared-bindings/_bleio/Adapter.c
@@ -25,22 +25,45 @@
* THE SOFTWARE.
*/
+#include <string.h>
+
#include "py/objproperty.h"
+#include "py/runtime.h"
#include "shared-bindings/_bleio/Address.h"
#include "shared-bindings/_bleio/Adapter.h"
+#define ADV_INTERVAL_MIN (0.0020f)
+#define ADV_INTERVAL_MIN_STRING "0.0020"
+#define ADV_INTERVAL_MAX (10.24f)
+#define ADV_INTERVAL_MAX_STRING "10.24"
+// 20ms is recommended by Apple
+#define ADV_INTERVAL_DEFAULT (0.1f)
+
+#define INTERVAL_DEFAULT (0.1f)
+#define INTERVAL_MIN (0.0025f)
+#define INTERVAL_MIN_STRING "0.0025"
+#define INTERVAL_MAX (40.959375f)
+#define INTERVAL_MAX_STRING "40.959375"
+#define WINDOW_DEFAULT (0.1f)
+
//| .. currentmodule:: _bleio
//|
-//| :class:`Adapter` --- BLE adapter information
+//| :class:`Adapter` --- BLE adapter
//| ----------------------------------------------------
//|
-//| Get current status of the BLE adapter
+//| The Adapter manages the discovery and connection to other nearby Bluetooth Low Energy devices.
+//| This part of the Bluetooth Low Energy Specification is known as Generic Access Profile (GAP).
//|
-//| Usage::
+//| Discovery of other devices happens during a scanning process that listens for small packets of
+//| information, known as advertisements, that are broadcast unencrypted. The advertising packets
+//| have two different uses. The first is to broadcast a small piece of data to anyone who cares and
+//| and nothing more. These are known as Beacons. The second class of advertisement is to promote
+//| additional functionality available after the devices establish a connection. For example, a
+//| BLE keyboard may advertise that it can provide key information, but not what the key info is.
//|
-//| import _bleio
-//| _bleio.adapter.enabled = True
-//| print(_bleio.adapter.address)
+//| The built-in BLE adapter can do both parts of this process: it can scan for other device
+//| advertisements and it can advertise its own data. Furthermore, Adapters can accept incoming
+//| connections and also initiate connections.
//|
//| .. class:: Adapter()
@@ -49,19 +72,19 @@
//| Use `_bleio.adapter` to access the sole instance available.
//|
-//| .. attribute:: adapter.enabled
+//| .. attribute:: enabled
//|
-//| State of the BLE adapter.
+//| State of the BLE adapter.
//|
STATIC mp_obj_t bleio_adapter_get_enabled(mp_obj_t self) {
- return mp_obj_new_bool(common_hal_bleio_adapter_get_enabled());
+ return mp_obj_new_bool(common_hal_bleio_adapter_get_enabled(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_enabled_obj, bleio_adapter_get_enabled);
static mp_obj_t bleio_adapter_set_enabled(mp_obj_t self, mp_obj_t value) {
const bool enabled = mp_obj_is_true(value);
- common_hal_bleio_adapter_set_enabled(enabled);
+ common_hal_bleio_adapter_set_enabled(self, enabled);
return mp_const_none;
}
@@ -74,12 +97,12 @@ const mp_obj_property_t bleio_adapter_enabled_obj = {
(mp_obj_t)&mp_const_none_obj },
};
-//| .. attribute:: adapter.address
+//| .. attribute:: address
//|
-//| MAC address of the BLE adapter. (read-only)
+//| MAC address of the BLE adapter. (read-only)
//|
STATIC mp_obj_t bleio_adapter_get_address(mp_obj_t self) {
- return MP_OBJ_FROM_PTR(common_hal_bleio_adapter_get_address());
+ return MP_OBJ_FROM_PTR(common_hal_bleio_adapter_get_address(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_address_obj, bleio_adapter_get_address);
@@ -91,29 +114,259 @@ const mp_obj_property_t bleio_adapter_address_obj = {
(mp_obj_t)&mp_const_none_obj },
};
-//| .. attribute:: adapter.default_name
+//| .. attribute:: name
+//|
+//| name of the BLE adapter used once connected. Not used in advertisements.
+//| The name is "CIRCUITPY" + the last four hex digits of ``adapter.address``,
+//| to make it easy to distinguish multiple CircuitPython boards.
+//|
+STATIC mp_obj_t bleio_adapter_get_name(mp_obj_t self) {
+ return MP_OBJ_FROM_PTR(common_hal_bleio_adapter_get_name(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_name_obj, bleio_adapter_get_name);
+
+
+STATIC mp_obj_t bleio_adapter_set_name(mp_obj_t self, mp_obj_t new_name) {
+ common_hal_bleio_adapter_set_name(self, mp_obj_str_get_str(new_name));
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(bleio_adapter_set_name_obj, bleio_adapter_set_name);
+
+const mp_obj_property_t bleio_adapter_name_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_adapter_get_name_obj,
+ (mp_obj_t)&bleio_adapter_set_name_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+//| .. method:: start_advertising(data, *, scan_response=None, connectable=True, interval=0.1)
+//|
+//| Starts advertising until `stop_advertising` is called or if connectable, another device
+//| connects to us.
+//|
+//| :param buf data: advertising data packet bytes
+//| :param buf scan_response: scan response data packet bytes. ``None`` if no scan response is needed.
+//| :param bool connectable: If `True` then other devices are allowed to connect to this peripheral.
+//| :param float interval: advertising interval, in seconds
+//|
+STATIC mp_obj_t bleio_adapter_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_data, ARG_scan_response, ARG_connectable, ARG_interval };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_scan_response, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
+ { MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ mp_buffer_info_t data_bufinfo;
+ mp_get_buffer_raise(args[ARG_data].u_obj, &data_bufinfo, MP_BUFFER_READ);
+
+ // Pass an empty buffer if scan_response not provided.
+ mp_buffer_info_t scan_response_bufinfo = { 0 };
+ if (args[ARG_scan_response].u_obj != mp_const_none) {
+ mp_get_buffer_raise(args[ARG_scan_response].u_obj, &scan_response_bufinfo, MP_BUFFER_READ);
+ }
+
+ if (args[ARG_interval].u_obj == MP_OBJ_NULL) {
+ args[ARG_interval].u_obj = mp_obj_new_float(ADV_INTERVAL_DEFAULT);
+ }
+
+ const mp_float_t interval = mp_obj_float_get(args[ARG_interval].u_obj);
+ if (interval < ADV_INTERVAL_MIN || interval > ADV_INTERVAL_MAX) {
+ mp_raise_ValueError_varg(translate("interval must be in range %s-%s"),
+ ADV_INTERVAL_MIN_STRING, ADV_INTERVAL_MAX_STRING);
+ }
+
+ common_hal_bleio_adapter_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_adapter_start_advertising_obj, 2, bleio_adapter_start_advertising);
+
+//| .. method:: stop_advertising()
+//|
+//| Stop sending advertising packets.
+STATIC mp_obj_t bleio_adapter_stop_advertising(mp_obj_t self_in) {
+ bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ common_hal_bleio_adapter_stop_advertising(self);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_stop_advertising_obj, bleio_adapter_stop_advertising);
+
+//| .. method:: start_scan(prefixes=b"", \*, buffer_size=512, extended=False, timeout=None, interval=0.1, window=0.1, minimum_rssi=-80, active=True)
+//|
+//| Starts a BLE scan and returns an iterator of results. Advertisements and scan responses are
+//| filtered and returned separately.
+//|
+//| :param sequence prefixes: Sequence of byte string prefixes to filter advertising packets
+//| with. A packet without an advertising structure that matches one of the prefixes is
+//| ignored. Format is one byte for length (n) and n bytes of prefix and can be repeated.
+//| :param int buffer_size: the maximum number of advertising bytes to buffer.
+//| :param bool extended: When True, support extended advertising packets. Increasing buffer_size is recommended when this is set.
+//| :param float timeout: the scan timeout in seconds. If None, will scan until `stop_scan` is called.
+//| :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.
+//| :param int minimum_rssi: the minimum rssi of entries to return.
+//| :param bool active: retrieve scan responses for scannable advertisements.
+//| :returns: an iterable of `_bleio.ScanEntry` objects
+//| :rtype: iterable
+//|
+STATIC mp_obj_t bleio_adapter_start_scan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_prefixes, ARG_buffer_size, ARG_extended, ARG_timeout, ARG_interval, ARG_window, ARG_minimum_rssi, ARG_active };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_prefixes, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 512} },
+ { MP_QSTR_extended, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
+ { MP_QSTR_timeout, 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_QSTR_window, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_minimum_rssi, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -80} },
+ { MP_QSTR_active, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
+ };
+
+ bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ mp_float_t timeout = 0;
+ if (args[ARG_timeout].u_obj != mp_const_none) {
+ 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"));
+ }
+
+ mp_buffer_info_t prefix_bufinfo;
+ prefix_bufinfo.len = 0;
+ if (args[ARG_prefixes].u_obj != MP_OBJ_NULL) {
+ mp_get_buffer_raise(args[ARG_prefixes].u_obj, &prefix_bufinfo, MP_BUFFER_READ);
+ if (gc_nbytes(prefix_bufinfo.buf) == 0) {
+ mp_raise_ValueError(translate("Prefix buffer must be on the heap"));
+ }
+ }
+
+ return common_hal_bleio_adapter_start_scan(self, prefix_bufinfo.buf, prefix_bufinfo.len, args[ARG_extended].u_bool, args[ARG_buffer_size].u_int, timeout, interval, window, args[ARG_minimum_rssi].u_int, args[ARG_active].u_bool);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_adapter_start_scan_obj, 1, bleio_adapter_start_scan);
+
+//| .. method:: stop_scan()
+//|
+//| Stop the current scan.
+STATIC mp_obj_t bleio_adapter_stop_scan(mp_obj_t self_in) {
+ bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ common_hal_bleio_adapter_stop_scan(self);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_stop_scan_obj, bleio_adapter_stop_scan);
+
+//| .. attribute:: connected
//|
-//| default_name of the BLE adapter. (read-only)
-//| The name is "CIRCUITPY" + the last four hex digits of ``adapter.address``,
-//| to make it easy to distinguish multiple CircuitPython boards.
+//| True when the adapter is connected to another device regardless of who initiated the
+//| connection. (read-only)
//|
-STATIC mp_obj_t bleio_adapter_get_default_name(mp_obj_t self) {
- return common_hal_bleio_adapter_get_default_name();
+STATIC mp_obj_t bleio_adapter_get_connected(mp_obj_t self) {
+ return mp_obj_new_bool(common_hal_bleio_adapter_get_connected(self));
}
-MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_default_name_obj, bleio_adapter_get_default_name);
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_connected_obj, bleio_adapter_get_connected);
-const mp_obj_property_t bleio_adapter_default_name_obj = {
+const mp_obj_property_t bleio_adapter_connected_obj = {
.base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_adapter_get_default_name_obj,
+ .proxy = { (mp_obj_t)&bleio_adapter_get_connected_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj },
};
+//| .. attribute:: connections
+//|
+//| Tuple of active connections including those initiated through
+//| :py:meth:`_bleio.Adapter.connect`. (read-only)
+//|
+STATIC mp_obj_t bleio_adapter_get_connections(mp_obj_t self) {
+ return common_hal_bleio_adapter_get_connections(self);
+}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_connections_obj, bleio_adapter_get_connections);
+
+const mp_obj_property_t bleio_adapter_connections_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_adapter_get_connections_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+//| .. method:: connect(address, *, timeout)
+//|
+//| Attempts a connection to the device with the given address.
+//|
+//| :param Address address: The address of the peripheral to connect to
+//| :param float/int timeout: Try to connect for timeout seconds.
+//|
+STATIC mp_obj_t bleio_adapter_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_address, ARG_timeout };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ if (!MP_OBJ_IS_TYPE(args[ARG_address].u_obj, &bleio_address_type)) {
+ mp_raise_TypeError(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);
+
+ return common_hal_bleio_adapter_connect(self, address, timeout);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_adapter_connect_obj, 2, bleio_adapter_connect);
+
+
STATIC const mp_rom_map_elem_t bleio_adapter_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_enabled), MP_ROM_PTR(&bleio_adapter_enabled_obj) },
{ MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_adapter_address_obj) },
- { MP_ROM_QSTR(MP_QSTR_default_name), MP_ROM_PTR(&bleio_adapter_default_name_obj) },
+ { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_adapter_name_obj) },
+
+ { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_adapter_start_advertising_obj) },
+ { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_adapter_stop_advertising_obj) },
+
+ { MP_ROM_QSTR(MP_QSTR_start_scan), MP_ROM_PTR(&bleio_adapter_start_scan_obj) },
+ { MP_ROM_QSTR(MP_QSTR_stop_scan), MP_ROM_PTR(&bleio_adapter_stop_scan_obj) },
+
+ { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_adapter_connect_obj) },
+
+ { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_adapter_connected_obj) },
+ { MP_ROM_QSTR(MP_QSTR_connections), MP_ROM_PTR(&bleio_adapter_connections_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_adapter_locals_dict, bleio_adapter_locals_dict_table);
diff --git a/shared-bindings/_bleio/Adapter.h b/shared-bindings/_bleio/Adapter.h
index 932fc9c95..4340d82c1 100644
--- a/shared-bindings/_bleio/Adapter.h
+++ b/shared-bindings/_bleio/Adapter.h
@@ -28,13 +28,33 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H
+#include <stdint.h>
+
+#include "common-hal/_bleio/Adapter.h"
+
+#include "py/objstr.h"
#include "shared-module/_bleio/Address.h"
const mp_obj_type_t bleio_adapter_type;
-extern bool common_hal_bleio_adapter_get_enabled(void);
-extern void common_hal_bleio_adapter_set_enabled(bool enabled);
-extern bleio_address_obj_t *common_hal_bleio_adapter_get_address(void);
-extern mp_obj_t common_hal_bleio_adapter_get_default_name(void);
+extern bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self);
+extern void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enabled);
+extern bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self);
+extern bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *self);
+
+extern mp_obj_str_t* common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self);
+extern void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char* name);
+
+extern uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, float interval, uint8_t *advertising_data, uint16_t advertising_data_len, uint8_t *scan_response_data, uint16_t scan_response_data_len);
+
+extern void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, mp_float_t interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo);
+void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self);
+
+mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t* prefixes, size_t prefix_length, bool extended, mp_int_t buffer_size, mp_float_t timeout, mp_float_t interval, mp_float_t window, mp_int_t minimum_rssi, bool active);
+void common_hal_bleio_adapter_stop_scan(bleio_adapter_obj_t *self);
+
+bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self);
+mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self);
+mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H
diff --git a/shared-bindings/_bleio/Address.c b/shared-bindings/_bleio/Address.c
index cdee02b5d..c31eb604b 100644
--- a/shared-bindings/_bleio/Address.c
+++ b/shared-bindings/_bleio/Address.c
@@ -114,10 +114,11 @@ const mp_obj_property_t bleio_address_address_bytes_obj = {
};
//| .. attribute:: type
-//|
+//|
//| The address type (read-only).
-//| One of the integer values: `PUBLIC`, `RANDOM_STATIC`,
-//| `RANDOM_PRIVATE_RESOLVABLE`, or `RANDOM_PRIVATE_NON_RESOLVABLE`.
+//|
+//| 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);
@@ -159,6 +160,28 @@ STATIC mp_obj_t bleio_address_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_o
}
}
+//| .. method:: __hash__()
+//|
+//| Returns a hash for the Address data.
+//|
+STATIC mp_obj_t bleio_address_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
+ switch (op) {
+ // Two Addresses are equal if their address bytes and address_type are equal
+ case MP_UNARY_OP_HASH: {
+ mp_obj_t bytes = common_hal_bleio_address_get_address_bytes(MP_OBJ_TO_PTR(self_in));
+ GET_STR_HASH(bytes, h);
+ if (h == 0) {
+ GET_STR_DATA_LEN(bytes, data, len);
+ h = qstr_compute_hash(data, len);
+ }
+ h ^= common_hal_bleio_address_get_type(MP_OBJ_TO_PTR(self_in));
+ return MP_OBJ_NEW_SMALL_INT(h);
+ }
+ default:
+ return MP_OBJ_NULL; // op not supported
+ }
+}
+
STATIC void bleio_address_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_buffer_info_t buf_info;
@@ -205,6 +228,7 @@ const mp_obj_type_t bleio_address_type = {
.name = MP_QSTR_Address,
.make_new = bleio_address_make_new,
.print = bleio_address_print,
+ .unary_op = bleio_address_unary_op,
.binary_op = bleio_address_binary_op,
.locals_dict = (mp_obj_dict_t*)&bleio_address_locals_dict
};
diff --git a/shared-bindings/_bleio/Central.c b/shared-bindings/_bleio/Central.c
deleted file mode 100644
index 084f40cd6..000000000
--- a/shared-bindings/_bleio/Central.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
- * Copyright (c) 2016 Glenn Ruben Bakke
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <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 == 'InterestingPeripheral':
-//| my_entry = entry
-//| break
-//|
-//| if not my_entry:
-//| raise Exception("'InterestingPeripheral' not found")
-//|
-//| central = _bleio.Central()
-//| central.connect(my_entry.address, 10) # timeout after 10 seconds
-//| remote_services = central.discover_remote_services()
-//|
-
-//| .. class:: Central()
-//|
-//| Create a new Central object.
-//|
-STATIC mp_obj_t bleio_central_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- mp_arg_check_num(n_args, kw_args, 0, 0, false);
-
- bleio_central_obj_t *self = m_new_obj(bleio_central_obj_t);
- self->base.type = &bleio_central_type;
-
- common_hal_bleio_central_construct(self);
-
- return MP_OBJ_FROM_PTR(self);
-}
-
-//| .. method:: connect(address, timeout, *, service_uuids_whitelist=None)
-//| Attempts a connection to the remote peripheral.
-//|
-//| :param Address address: The address of the peripheral to connect to
-//| :param float/int timeout: Try to connect for timeout seconds.
-//|
-STATIC mp_obj_t bleio_central_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- bleio_central_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
-
- enum { ARG_address, ARG_timeout, ARG_service_uuids_whitelist };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_OBJ },
- { MP_QSTR_timeout, MP_ARG_REQUIRED | MP_ARG_OBJ },
- };
-
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- if (!MP_OBJ_IS_TYPE(args[ARG_address].u_obj, &bleio_address_type)) {
- mp_raise_ValueError(translate("Expected an Address"));
- }
-
- bleio_address_obj_t *address = MP_OBJ_TO_PTR(args[ARG_address].u_obj);
- mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj);
-
- // common_hal_bleio_central_connect() will validate that services is an iterable or None.
- common_hal_bleio_central_connect(self, address, timeout);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_central_connect_obj, 3, bleio_central_connect);
-
-
-//| .. method:: disconnect()
-//|
-//| Disconnects from the remote peripheral.
-//|
-STATIC mp_obj_t bleio_central_disconnect(mp_obj_t self_in) {
- bleio_central_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- common_hal_bleio_central_disconnect(self);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_disconnect_obj, bleio_central_disconnect);
-
-//| .. method:: discover_remote_services(service_uuids_whitelist=None)
-//| Do BLE discovery for all services or for the given service UUIDS,
-//| to find their handles and characteristics, and return the discovered services.
-//| `Peripheral.connected` must be True.
-//|
-//| :param iterable service_uuids_whitelist: an iterable of :py:class:~`UUID` objects for the services
-//| provided by the peripheral that you want to use.
-//| The peripheral may provide more services, but services not listed are ignored
-//| and will not be returned.
-//|
-//| If service_uuids_whitelist is None, then all services will undergo discovery, which can be slow.
-//|
-//| If the service UUID is 128-bit, or its characteristic UUID's are 128-bit, you
-//| you must have already created a :py:class:~`UUID` object for that UUID in order for the
-//| service or characteristic to be discovered. Creating the UUID causes the UUID to be registered
-//| for use. (This restriction may be lifted in the future.)
-//|
-//| :return: A tuple of services provided by the remote peripheral.
-//|
-STATIC mp_obj_t bleio_central_discover_remote_services(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- bleio_central_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
-
- enum { ARG_service_uuids_whitelist };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_service_uuids_whitelist, MP_ARG_OBJ, {.u_obj = mp_const_none} },
- };
-
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- if (!common_hal_bleio_central_get_connected(self)) {
- mp_raise_ValueError(translate("Not connected"));
- }
-
- return MP_OBJ_FROM_PTR(common_hal_bleio_central_discover_remote_services(
- MP_OBJ_FROM_PTR(self),
- args[ARG_service_uuids_whitelist].u_obj));
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_central_discover_remote_services_obj, 1, bleio_central_discover_remote_services);
-
-//| .. attribute:: connected
-//|
-//| True if connected to a remove peripheral.
-//|
-STATIC mp_obj_t bleio_central_get_connected(mp_obj_t self_in) {
- bleio_central_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return mp_obj_new_bool(common_hal_bleio_central_get_connected(self));
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_get_connected_obj, bleio_central_get_connected);
-
-const mp_obj_property_t bleio_central_connected_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_central_get_connected_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-STATIC const mp_rom_map_elem_t bleio_central_locals_dict_table[] = {
- // Methods
- { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_central_connect_obj) },
- { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_central_disconnect_obj) },
- { MP_ROM_QSTR(MP_QSTR_discover_remote_services), MP_ROM_PTR(&bleio_central_discover_remote_services_obj) },
-
- // Properties
- { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_central_connected_obj) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(bleio_central_locals_dict, bleio_central_locals_dict_table);
-
-const mp_obj_type_t bleio_central_type = {
- { &mp_type_type },
- .name = MP_QSTR_Central,
- .make_new = bleio_central_make_new,
- .locals_dict = (mp_obj_dict_t*)&bleio_central_locals_dict
-};
diff --git a/shared-bindings/_bleio/Characteristic.c b/shared-bindings/_bleio/Characteristic.c
index 198155589..7fcf274da 100644
--- a/shared-bindings/_bleio/Characteristic.c
+++ b/shared-bindings/_bleio/Characteristic.c
@@ -45,8 +45,8 @@
//|
//| There is no regular constructor for a Characteristic. A new local Characteristic can be created
//| and attached to a Service by calling `add_to_service()`.
-//| Remote Characteristic objects are created by `Central.discover_remote_services()`
-//| or `Peripheral.discover_remote_services()` as part of remote Services.
+//| Remote Characteristic objects are created by `Connection.discover_remote_services()`
+//| as part of remote Services.
//|
//| .. method:: add_to_service(service, uuid, *, properties=0, read_perm=`Attribute.OPEN`, write_perm=`Attribute.OPEN`, max_length=20, fixed_length=False, initial_value=None)
@@ -94,12 +94,12 @@ STATIC mp_obj_t bleio_characteristic_add_to_service(size_t n_args, const mp_obj_
const mp_obj_t service_obj = args[ARG_service].u_obj;
if (!MP_OBJ_IS_TYPE(service_obj, &bleio_service_type)) {
- mp_raise_ValueError(translate("Expected a Service"));
+ mp_raise_TypeError(translate("Expected a Service"));
}
const mp_obj_t uuid_obj = args[ARG_uuid].u_obj;
if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
- mp_raise_ValueError(translate("Expected a UUID"));
+ mp_raise_TypeError(translate("Expected a UUID"));
}
const bleio_characteristic_properties_t properties = args[ARG_properties].u_int;
@@ -134,12 +134,10 @@ STATIC mp_obj_t bleio_characteristic_add_to_service(size_t n_args, const mp_obj_
// Range checking on max_length arg is done by the common_hal layer, because
// it may vary depending on underlying BLE implementation.
common_hal_bleio_characteristic_construct(
- characteristic, MP_OBJ_TO_PTR(service_obj), MP_OBJ_TO_PTR(uuid_obj),
+ characteristic, MP_OBJ_TO_PTR(service_obj), 0, MP_OBJ_TO_PTR(uuid_obj),
properties, read_perm, write_perm,
max_length, fixed_length, &initial_value_bufinfo);
- common_hal_bleio_service_add_characteristic(service_obj, characteristic);
-
return MP_OBJ_FROM_PTR(characteristic);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_characteristic_add_to_service_fun_obj, 3, bleio_characteristic_add_to_service);
@@ -170,7 +168,8 @@ const mp_obj_property_t bleio_characteristic_properties_obj = {
//| .. attribute:: uuid
//|
//| The UUID of this characteristic. (read-only)
-//| Will be ``None`` if the 128-bit UUID for this characteristic is not known.
+//|
+//| 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);
@@ -194,7 +193,9 @@ 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);
- return common_hal_bleio_characteristic_get_value(self);
+ uint8_t temp[512];
+ size_t actual_len = common_hal_bleio_characteristic_get_value(self, temp, sizeof(temp));
+ return mp_obj_new_bytearray(actual_len, temp);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_value_obj, bleio_characteristic_get_value);
@@ -224,8 +225,20 @@ const mp_obj_property_t bleio_characteristic_value_obj = {
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);
+ bleio_descriptor_obj_t *descriptors = common_hal_bleio_characteristic_get_descriptor_list(self);
+ bleio_descriptor_obj_t *head = descriptors;
+ size_t len = 0;
+ while (head != NULL) {
+ len++;
+ head = head->next;
+ }
+ mp_obj_tuple_t * t = MP_OBJ_TO_PTR(mp_obj_new_tuple(len, NULL));
+ head = descriptors;
+ for (size_t i = len - 1; i >= 0; i--) {
+ t->items[i] = MP_OBJ_FROM_PTR(head);
+ head = head->next;
+ }
+ return MP_OBJ_FROM_PTR(t);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_descriptors_obj, bleio_characteristic_get_descriptors);
@@ -282,7 +295,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_characteristic_set_cccd_obj, 1, bleio_ch
STATIC const mp_rom_map_elem_t bleio_characteristic_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_add_to_service), MP_ROM_PTR(&bleio_characteristic_add_to_service_obj) },
- { MP_ROM_QSTR(MP_QSTR_properties), MP_ROM_PTR(&bleio_characteristic_get_properties_obj) },
+ { MP_ROM_QSTR(MP_QSTR_properties), MP_ROM_PTR(&bleio_characteristic_properties_obj) },
{ MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_characteristic_uuid_obj) },
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&bleio_characteristic_value_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_cccd), MP_ROM_PTR(&bleio_characteristic_set_cccd_obj) },
diff --git a/shared-bindings/_bleio/Characteristic.h b/shared-bindings/_bleio/Characteristic.h
index a816c6050..c4356fd4b 100644
--- a/shared-bindings/_bleio/Characteristic.h
+++ b/shared-bindings/_bleio/Characteristic.h
@@ -36,12 +36,12 @@
extern const mp_obj_type_t bleio_characteristic_type;
-extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo);
-extern mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self);
+extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, uint16_t handle, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo);
+extern size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t* buf, size_t len);
extern void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo);
extern bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties(bleio_characteristic_obj_t *self);
extern bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self);
-extern mp_obj_list_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self);
+extern bleio_descriptor_obj_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self);
extern bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_characteristic_obj_t *self);
extern void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *self, bleio_descriptor_obj_t *descriptor);
extern void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate);
diff --git a/shared-bindings/_bleio/CharacteristicBuffer.c b/shared-bindings/_bleio/CharacteristicBuffer.c
index 9cc708eb7..e7524da2d 100644
--- a/shared-bindings/_bleio/CharacteristicBuffer.c
+++ b/shared-bindings/_bleio/CharacteristicBuffer.c
@@ -30,13 +30,14 @@
#include "py/runtime.h"
#include "py/stream.h"
+#include "shared-bindings/_bleio/__init__.h"
#include "shared-bindings/_bleio/CharacteristicBuffer.h"
#include "shared-bindings/_bleio/UUID.h"
#include "shared-bindings/util.h"
STATIC void raise_error_if_not_connected(bleio_characteristic_buffer_obj_t *self) {
if (!common_hal_bleio_characteristic_buffer_connected(self)) {
- mp_raise_ValueError(translate("Not connected"));
+ mp_raise_bleio_ConnectionError(translate("Not connected"));
}
}
@@ -83,7 +84,7 @@ STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type,
}
if (!MP_OBJ_IS_TYPE(characteristic, &bleio_characteristic_type)) {
- mp_raise_ValueError(translate("Expected a Characteristic"));
+ mp_raise_TypeError(translate("Expected a Characteristic"));
}
bleio_characteristic_buffer_obj_t *self = m_new_obj(bleio_characteristic_buffer_obj_t);
@@ -151,9 +152,6 @@ STATIC mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t r
bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self);
raise_error_if_not_connected(self);
- if (!common_hal_bleio_characteristic_buffer_connected(self)) {
- mp_raise_ValueError(translate("Not connected"));
- }
mp_uint_t ret;
if (request == MP_IOCTL_POLL) {
mp_uint_t flags = arg;
diff --git a/shared-bindings/_bleio/Connection.c b/shared-bindings/_bleio/Connection.c
new file mode 100644
index 000000000..da2fbff28
--- /dev/null
+++ b/shared-bindings/_bleio/Connection.c
@@ -0,0 +1,216 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "shared-bindings/_bleio/Connection.h"
+
+#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/__init__.h"
+#include "shared-bindings/_bleio/Adapter.h"
+#include "shared-bindings/_bleio/Address.h"
+#include "shared-bindings/_bleio/Characteristic.h"
+#include "shared-bindings/_bleio/Service.h"
+
+//| .. currentmodule:: _bleio
+//|
+//| :class:`Connection` -- A BLE connection
+//| =========================================================
+//|
+//| A BLE connection to another device. Used to discover and interact with services on the other
+//| device.
+//|
+//| Usage::
+//|
+//| import _bleio
+//|
+//| my_entry = None
+//| for entry in _bleio.adapter.scan(2.5):
+//| if entry.name is not None and entry.name == 'InterestingPeripheral':
+//| my_entry = entry
+//| break
+//|
+//| if not my_entry:
+//| raise Exception("'InterestingPeripheral' not found")
+//|
+//| connection = _bleio.adapter.connect(my_entry.address, timeout=10)
+//|
+
+STATIC void ensure_connected(bleio_connection_obj_t *self) {
+ if (!common_hal_bleio_connection_get_connected(self)) {
+ mp_raise_bleio_ConnectionError(translate("Connection has been disconnected and can no longer be used. Create a new connection."));
+ }
+}
+
+//| .. class:: Connection()
+//|
+//| Connections cannot be made directly. Instead, to initiate a connection use `Adapter.connect`.
+//| Connections may also be made when another device initiates a connection. To use a Connection
+//| created by a peer, read the `Adapter.connections` property.
+//|
+//| .. method:: disconnect()
+//|
+//| Disconnects from the remote peripheral.
+//|
+STATIC mp_obj_t bleio_connection_disconnect(mp_obj_t self_in) {
+ bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ ensure_connected(self);
+
+ common_hal_bleio_connection_disconnect(self->connection);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_disconnect_obj, bleio_connection_disconnect);
+
+
+//| .. method:: pair(*, bond=True)
+//|
+//| Pair to the peer to improve security.
+//|
+STATIC mp_obj_t bleio_connection_pair(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_connection_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_bond };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_bond, MP_ARG_BOOL, {.u_bool = true} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ ensure_connected(self);
+
+ common_hal_bleio_connection_pair(self->connection, args[ARG_bond].u_bool);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_connection_pair_obj, 1, bleio_connection_pair);
+
+//| .. method:: discover_remote_services(service_uuids_whitelist=None)
+//|
+//| Do BLE discovery for all services or for the given service UUIDS,
+//| to find their handles and characteristics, and return the discovered services.
+//| `Connection.connected` must be True.
+//|
+//| :param iterable service_uuids_whitelist:
+//|
+//| an iterable of :py:class:~`UUID` objects for the services provided by the peripheral
+//| that you want to use.
+//|
+//| The peripheral may provide more services, but services not listed are ignored
+//| and will not be returned.
+//|
+//| If service_uuids_whitelist is None, then all services will undergo discovery, which can be
+//| slow.
+//|
+//| If the service UUID is 128-bit, or its characteristic UUID's are 128-bit, you
+//| you must have already created a :py:class:~`UUID` object for that UUID in order for the
+//| service or characteristic to be discovered. Creating the UUID causes the UUID to be
+//| registered for use. (This restriction may be lifted in the future.)
+//|
+//| :return: A tuple of `_bleio.Service` objects provided by the remote peripheral.
+//|
+STATIC mp_obj_t bleio_connection_discover_remote_services(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_connection_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_service_uuids_whitelist };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_service_uuids_whitelist, MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ ensure_connected(self);
+
+ return MP_OBJ_FROM_PTR(common_hal_bleio_connection_discover_remote_services(
+ self,
+ args[ARG_service_uuids_whitelist].u_obj));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_connection_discover_remote_services_obj, 1, bleio_connection_discover_remote_services);
+
+//| .. attribute:: connected
+//|
+//| True if connected to the remote peer.
+//|
+STATIC mp_obj_t bleio_connection_get_connected(mp_obj_t self_in) {
+ bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(common_hal_bleio_connection_get_connected(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_get_connected_obj, bleio_connection_get_connected);
+
+const mp_obj_property_t bleio_connection_connected_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_connection_get_connected_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+
+//| .. attribute:: paired
+//|
+//| True if paired to the remote peer.
+//|
+STATIC mp_obj_t bleio_connection_get_paired(mp_obj_t self_in) {
+ bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(common_hal_bleio_connection_get_paired(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_get_paired_obj, bleio_connection_get_paired);
+
+const mp_obj_property_t bleio_connection_paired_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_connection_get_paired_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC const mp_rom_map_elem_t bleio_connection_locals_dict_table[] = {
+ // Methods
+ { MP_ROM_QSTR(MP_QSTR_pair), MP_ROM_PTR(&bleio_connection_pair_obj) },
+ { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_connection_disconnect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_discover_remote_services), MP_ROM_PTR(&bleio_connection_discover_remote_services_obj) },
+
+ // Properties
+ { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_connection_connected_obj) },
+ { MP_ROM_QSTR(MP_QSTR_paired), MP_ROM_PTR(&bleio_connection_paired_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(bleio_connection_locals_dict, bleio_connection_locals_dict_table);
+
+const mp_obj_type_t bleio_connection_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Connection,
+ .locals_dict = (mp_obj_dict_t*)&bleio_connection_locals_dict,
+ .unary_op = mp_generic_unary_op,
+};
diff --git a/shared-bindings/_bleio/Central.h b/shared-bindings/_bleio/Connection.h
index 85d788654..f7eee180f 100644
--- a/shared-bindings/_bleio/Central.h
+++ b/shared-bindings/_bleio/Connection.h
@@ -25,19 +25,19 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CONNECTION_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CONNECTION_H
#include "py/objtuple.h"
-#include "common-hal/_bleio/Central.h"
+#include "common-hal/_bleio/Connection.h"
#include "common-hal/_bleio/Service.h"
-extern const mp_obj_type_t bleio_central_type;
+extern const mp_obj_type_t bleio_connection_type;
-extern void common_hal_bleio_central_construct(bleio_central_obj_t *self);
-extern void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout);
-extern void common_hal_bleio_central_disconnect(bleio_central_obj_t *self);
-extern bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self);
-extern mp_obj_tuple_t *common_hal_bleio_central_discover_remote_services(bleio_central_obj_t *self, mp_obj_t service_uuids_whitelist);
+extern void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, bool bond);
+extern void common_hal_bleio_connection_disconnect(bleio_connection_internal_t *self);
+extern bool common_hal_bleio_connection_get_connected(bleio_connection_obj_t *self);
+extern bool common_hal_bleio_connection_get_paired(bleio_connection_obj_t *self);
+extern mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist);
-#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CONNECTION_H
diff --git a/shared-bindings/_bleio/Descriptor.c b/shared-bindings/_bleio/Descriptor.c
index 0ab9fe8e9..f7b6b5bbf 100644
--- a/shared-bindings/_bleio/Descriptor.c
+++ b/shared-bindings/_bleio/Descriptor.c
@@ -46,9 +46,8 @@
//|
//| There is no regular constructor for a Descriptor. A new local Descriptor can be created
//| and attached to a Characteristic by calling `add_to_characteristic()`.
-//| Remote Descriptor objects are created by `Central.discover_remote_services()`
-//| or `Peripheral.discover_remote_services()` as part of remote Characteristics
-//| in the remote Services that are discovered.
+//| Remote Descriptor objects are created by `Connection.discover_remote_services()`
+//| as part of remote Characteristics in the remote Services that are discovered.
//|
//| .. classmethod:: add_to_characteristic(characteristic, uuid, *, read_perm=`Attribute.OPEN`, write_perm=`Attribute.OPEN`, max_length=20, fixed_length=False, initial_value=b'')
//|
@@ -90,12 +89,12 @@ STATIC mp_obj_t bleio_descriptor_add_to_characteristic(size_t n_args, const mp_o
const mp_obj_t characteristic_obj = args[ARG_characteristic].u_obj;
if (!MP_OBJ_IS_TYPE(characteristic_obj, &bleio_characteristic_type)) {
- mp_raise_ValueError(translate("Expected a Characteristic"));
+ mp_raise_TypeError(translate("Expected a Characteristic"));
}
const mp_obj_t uuid_obj = args[ARG_uuid].u_obj;
if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
- mp_raise_ValueError(translate("Expected a UUID"));
+ mp_raise_TypeError(translate("Expected a UUID"));
}
const bleio_attribute_security_mode_t read_perm = args[ARG_read_perm].u_int;
@@ -180,7 +179,9 @@ const mp_obj_property_t bleio_descriptor_characteristic_obj = {
STATIC mp_obj_t bleio_descriptor_get_value(mp_obj_t self_in) {
bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return common_hal_bleio_descriptor_get_value(self);
+ uint8_t temp[512];
+ size_t actual_len = common_hal_bleio_descriptor_get_value(self, temp, sizeof(temp));
+ return mp_obj_new_bytearray(actual_len, temp);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_value_obj, bleio_descriptor_get_value);
diff --git a/shared-bindings/_bleio/Descriptor.h b/shared-bindings/_bleio/Descriptor.h
index 7544bdb17..273cb1c1e 100644
--- a/shared-bindings/_bleio/Descriptor.h
+++ b/shared-bindings/_bleio/Descriptor.h
@@ -38,7 +38,7 @@ extern const mp_obj_type_t bleio_descriptor_type;
extern void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_characteristic_obj_t *characteristic, bleio_uuid_obj_t *uuid, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo);
extern bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self);
extern bleio_characteristic_obj_t *common_hal_bleio_descriptor_get_characteristic(bleio_descriptor_obj_t *self);
-extern mp_obj_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self);
+extern size_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self, uint8_t* buf, size_t len);
extern void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buffer_info_t *bufinfo);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H
diff --git a/shared-bindings/_bleio/Peripheral.c b/shared-bindings/_bleio/Peripheral.c
deleted file mode 100644
index 0bf292744..000000000
--- a/shared-bindings/_bleio/Peripheral.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
- * Copyright (c) 2016 Glenn Ruben Bakke
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <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/Characteristic.h"
-#include "shared-bindings/_bleio/Peripheral.h"
-#include "shared-bindings/_bleio/Service.h"
-#include "shared-bindings/_bleio/UUID.h"
-#include "shared-module/_bleio/ScanEntry.h"
-
-#include "common-hal/_bleio/Peripheral.h"
-
-#define ADV_INTERVAL_MIN (0.0020f)
-#define ADV_INTERVAL_MIN_STRING "0.0020"
-#define ADV_INTERVAL_MAX (10.24f)
-#define ADV_INTERVAL_MAX_STRING "10.24"
-// 20ms is recommended by Apple
-#define ADV_INTERVAL_DEFAULT (0.1f)
-
-//| .. currentmodule:: _bleio
-//|
-//| :class:`Peripheral` -- A BLE peripheral device
-//| =========================================================
-//|
-//| Implement a BLE peripheral which runs locally.
-//| Set up using the supplied services, and then allow advertising to be started and stopped.
-//|
-//| Usage::
-//|
-//| from _bleio import Characteristic, Peripheral, Service
-//| from adafruit_ble.advertising import ServerAdvertisement
-//|
-//| # Create a peripheral and start it up.
-//| peripheral = _bleio.Peripheral()
-//|
-//| # Create a Service and add it to this Peripheral.
-//| service = Service.add_to_peripheral(peripheral, _bleio.UUID(0x180f))
-//|
-//| # Create a Characteristic and add it to the Service.
-//| characteristic = Characteristic.add_to_service(service,
-//| _bleio.UUID(0x2919), properties=Characteristic.READ | Characteristic.NOTIFY)
-//|
-//| adv = ServerAdvertisement(peripheral)
-//| peripheral.start_advertising(adv.advertising_data_bytes, scan_response=adv.scan_response_bytes)
-//|
-//| while not peripheral.connected:
-//| # Wait for connection.
-//| pass
-//|
-//| .. class:: Peripheral(name=None)
-//|
-//| Create a new Peripheral object.
-//|
-//| :param str name: The name used when advertising this peripheral. If name is None,
-//| _bleio.adapter.default_name will be used.
-//|
-STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- enum { ARG_name };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_name, MP_ARG_OBJ, {.u_obj = mp_const_none} },
- };
-
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- bleio_peripheral_obj_t *self = m_new_obj(bleio_peripheral_obj_t);
- self->base.type = &bleio_peripheral_type;
-
- mp_obj_t name = args[ARG_name].u_obj;
- if (name == mp_const_none) {
- name = common_hal_bleio_adapter_get_default_name();
- } else if (!MP_OBJ_IS_STR(name)) {
- mp_raise_ValueError(translate("name must be a string"));
- }
-
- common_hal_bleio_peripheral_construct(self, name);
-
- return MP_OBJ_FROM_PTR(self);
-}
-
-//| .. attribute:: connected (read-only)
-//|
-//| True if connected to a BLE Central device.
-//|
-STATIC mp_obj_t bleio_peripheral_get_connected(mp_obj_t self_in) {
- bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return mp_obj_new_bool(common_hal_bleio_peripheral_get_connected(self));
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_connected_obj, bleio_peripheral_get_connected);
-
-const mp_obj_property_t bleio_peripheral_connected_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_peripheral_get_connected_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-//| .. attribute:: services
-//|
-//| A tuple of :py:class:`Service` objects offered by this peripheral. (read-only)
-//|
-STATIC mp_obj_t bleio_peripheral_get_services(mp_obj_t self_in) {
- bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
- // Return list as a tuple so user won't be able to change it.
- mp_obj_list_t *services_list = common_hal_bleio_peripheral_get_services(self);
- return mp_obj_new_tuple(services_list->len, services_list->items);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_services_obj, bleio_peripheral_get_services);
-
-const mp_obj_property_t bleio_peripheral_services_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_peripheral_get_services_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-//| .. attribute:: name
-//|
-//| The peripheral's name, included when advertising. (read-only)
-//|
-STATIC mp_obj_t bleio_peripheral_get_name(mp_obj_t self_in) {
- bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return common_hal_bleio_peripheral_get_name(self);
-}
-MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_name_obj, bleio_peripheral_get_name);
-
-const mp_obj_property_t bleio_peripheral_name_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_peripheral_get_name_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-//| .. method:: start_advertising(data, *, scan_response=None, connectable=True, interval=0.1)
-//|
-//| Starts advertising the peripheral. The peripheral's name and
-//| services are included in the advertisement packets.
-//|
-//| :param buf data: advertising data packet bytes
-//| :param buf scan_response: scan response data packet bytes. ``None`` if no scan response is needed.
-//| :param bool connectable: If `True` then other devices are allowed to connect to this peripheral.
-//| :param float interval: advertising interval, in seconds
-//|
-STATIC mp_obj_t bleio_peripheral_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
-
- enum { ARG_data, ARG_scan_response, ARG_connectable, ARG_interval };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ },
- { MP_QSTR_scan_response, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
- { MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
- { MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
- };
-
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- mp_buffer_info_t data_bufinfo;
- mp_get_buffer_raise(args[ARG_data].u_obj, &data_bufinfo, MP_BUFFER_READ);
-
- // Pass an empty buffer if scan_response not provided.
- mp_buffer_info_t scan_response_bufinfo = { 0 };
- if (args[ARG_scan_response].u_obj != mp_const_none) {
- mp_get_buffer_raise(args[ARG_scan_response].u_obj, &scan_response_bufinfo, MP_BUFFER_READ);
- }
-
- if (args[ARG_interval].u_obj == MP_OBJ_NULL) {
- args[ARG_interval].u_obj = mp_obj_new_float(ADV_INTERVAL_DEFAULT);
- }
-
- const mp_float_t interval = mp_obj_float_get(args[ARG_interval].u_obj);
- if (interval < ADV_INTERVAL_MIN || interval > ADV_INTERVAL_MAX) {
- mp_raise_ValueError_varg(translate("interval must be in range %s-%s"),
- ADV_INTERVAL_MIN_STRING, ADV_INTERVAL_MAX_STRING);
- }
-
- common_hal_bleio_peripheral_start_advertising(self, args[ARG_connectable].u_bool, interval,
- &data_bufinfo, &scan_response_bufinfo);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_peripheral_start_advertising_obj, 2, bleio_peripheral_start_advertising);
-
-//| .. method:: stop_advertising()
-//|
-//| Stop sending advertising packets.
-STATIC mp_obj_t bleio_peripheral_stop_advertising(mp_obj_t self_in) {
- bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- common_hal_bleio_peripheral_stop_advertising(self);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_stop_advertising_obj, bleio_peripheral_stop_advertising);
-
-//| .. method:: disconnect()
-//|
-//| Disconnects from the remote central.
-//| Normally the central initiates a disconnection. Use this only
-//| if necessary for your application.
-//|
-STATIC mp_obj_t bleio_peripheral_disconnect(mp_obj_t self_in) {
- bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- common_hal_bleio_peripheral_disconnect(self);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_disconnect_obj, bleio_peripheral_disconnect);
-
-//| .. method:: discover_remote_services(service_uuids_whitelist=None)
-//| Do BLE discovery for all services or for the given service UUIDS,
-//| to find their handles and characteristics, and return the discovered services.
-//| `Peripheral.connected` must be True.
-//|
-//| :param iterable service_uuids_whitelist: an iterable of :py:class:~`UUID` objects for the services
-//| provided by the peripheral that you want to use.
-//| The peripheral may provide more services, but services not listed are ignored
-//| and will not be returned.
-//|
-//| If service_uuids_whitelist is None, then all services will undergo discovery, which can be slow.
-//|
-//| If the service UUID is 128-bit, or its characteristic UUID's are 128-bit, you
-//| you must have already created a :py:class:~`UUID` object for that UUID in order for the
-//| service or characteristic to be discovered. Creating the UUID causes the UUID to be registered
-//| for use. (This restriction may be lifted in the future.)
-//|
-//| Thought it is unusual for a peripheral to act as a BLE client, it can do so, and
-//| needs to be able to do discovery on its peer (a central).
-//| Examples include a peripheral accessing a central that provides Current Time Service,
-//| Apple Notification Center Service, or Battery Service.
-//|
-//| :return: A tuple of services provided by the remote central.
-//|
-STATIC mp_obj_t bleio_peripheral_discover_remote_services(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
-
- enum { ARG_service_uuids_whitelist };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_service_uuids_whitelist, MP_ARG_OBJ, {.u_obj = mp_const_none} },
- };
-
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- if (!common_hal_bleio_peripheral_get_connected(self)) {
- mp_raise_ValueError(translate("Not connected"));
- }
-
- return MP_OBJ_FROM_PTR(common_hal_bleio_peripheral_discover_remote_services(
- MP_OBJ_FROM_PTR(self),
- args[ARG_service_uuids_whitelist].u_obj));
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_peripheral_discover_remote_services_obj, 1, bleio_peripheral_discover_remote_services);
-
-//| .. method:: pair()
-//|
-//| Request pairing with connected central.
-STATIC mp_obj_t bleio_peripheral_pair(mp_obj_t self_in) {
- bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- common_hal_bleio_peripheral_pair(self);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_pair_obj, bleio_peripheral_pair);
-
-STATIC const mp_rom_map_elem_t bleio_peripheral_locals_dict_table[] = {
- // Methods
- { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_peripheral_start_advertising_obj) },
- { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_peripheral_stop_advertising_obj) },
- { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_peripheral_disconnect_obj) },
- { MP_ROM_QSTR(MP_QSTR_discover_remote_services), MP_ROM_PTR(&bleio_peripheral_discover_remote_services_obj) },
- { MP_ROM_QSTR(MP_QSTR_pair), MP_ROM_PTR(&bleio_peripheral_pair_obj) },
-
- // Properties
- { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_peripheral_connected_obj) },
- { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_peripheral_name_obj) },
- { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_peripheral_services_obj) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(bleio_peripheral_locals_dict, bleio_peripheral_locals_dict_table);
-
-const mp_obj_type_t bleio_peripheral_type = {
- { &mp_type_type },
- .name = MP_QSTR_Peripheral,
- .make_new = bleio_peripheral_make_new,
- .locals_dict = (mp_obj_dict_t*)&bleio_peripheral_locals_dict
-};
diff --git a/shared-bindings/_bleio/Peripheral.h b/shared-bindings/_bleio/Peripheral.h
deleted file mode 100644
index bc56a9338..000000000
--- a/shared-bindings/_bleio/Peripheral.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H
-
-#include "py/objtuple.h"
-#include "common-hal/_bleio/Peripheral.h"
-#include "common-hal/_bleio/Service.h"
-
-extern const mp_obj_type_t bleio_peripheral_type;
-
-extern void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_t name);
-extern void common_hal_bleio_peripheral_add_service(bleio_peripheral_obj_t *self, bleio_service_obj_t *service);
-extern mp_obj_list_t *common_hal_bleio_peripheral_get_services(bleio_peripheral_obj_t *self);
-extern bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self);
-extern mp_obj_t common_hal_bleio_peripheral_get_name(bleio_peripheral_obj_t *self);
-extern void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *device, bool connectable, float interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo);
-extern void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *device);
-extern void common_hal_bleio_peripheral_disconnect(bleio_peripheral_obj_t *device);
-extern mp_obj_tuple_t *common_hal_bleio_peripheral_discover_remote_services(bleio_peripheral_obj_t *self, mp_obj_t service_uuids_whitelist);
-extern void common_hal_bleio_peripheral_pair(bleio_peripheral_obj_t *device);
-
-#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H
diff --git a/shared-bindings/_bleio/ScanEntry.c b/shared-bindings/_bleio/ScanEntry.c
index bec380d03..d03cd6fb5 100644
--- a/shared-bindings/_bleio/ScanEntry.c
+++ b/shared-bindings/_bleio/ScanEntry.c
@@ -29,6 +29,7 @@
#include <string.h>
#include "py/objproperty.h"
+#include "py/runtime.h"
#include "shared-bindings/_bleio/Address.h"
#include "shared-bindings/_bleio/ScanEntry.h"
#include "shared-bindings/_bleio/UUID.h"
@@ -36,14 +37,43 @@
//| .. currentmodule:: _bleio
//|
-//| :class:`ScanEntry` -- BLE scan response entry
+//| :class:`ScanEntry` -- BLE scan data
//| =========================================================
//|
-//| Encapsulates information about a device that was received as a
-//| response to a BLE scan request. This object may only be created
-//| by a `_bleio.Scanner`: it has no user-visible constructor.
+//| Encapsulates information about a device that was received during scanning. It can be
+//| advertisement or scan response data. This object may only be created by a `_bleio.ScanResults`:
+//| it has no user-visible constructor.
//|
+//| .. class:: ScanEntry()
+//|
+//| Cannot be instantiated directly. Use `_bleio.Adapter.start_scan`.
+//|
+//| .. method:: matches(prefixes, *, all=True)
+//|
+//| Returns True if the ScanEntry matches all prefixes when ``all`` is True. This is stricter
+//| than the scan filtering which accepts any advertisements that match any of the prefixes
+//| where all is False.
+//|
+STATIC mp_obj_t bleio_scanentry_matches(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_prefixes, ARG_all };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_prefixes, MP_ARG_OBJ | MP_ARG_REQUIRED },
+ { MP_QSTR_all, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[ARG_prefixes].u_obj, &bufinfo, MP_BUFFER_READ);
+ return mp_obj_new_bool(common_hal_bleio_scanentry_matches(self, bufinfo.buf, bufinfo.len, args[ARG_all].u_bool));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_scanentry_matches_obj, 2, bleio_scanentry_matches);
+
//| .. attribute:: address
//|
//| The address of the device (read-only), of type `_bleio.Address`.
@@ -95,11 +125,47 @@ const mp_obj_property_t bleio_scanentry_rssi_obj = {
(mp_obj_t)&mp_const_none_obj },
};
+//| .. attribute:: connectable
+//|
+//| True if the device can be connected to. (read-only)
+//|
+STATIC mp_obj_t scanentry_get_connectable(mp_obj_t self_in) {
+ bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ return mp_obj_new_bool(common_hal_bleio_scanentry_get_connectable(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_connectable_obj, scanentry_get_connectable);
+
+const mp_obj_property_t bleio_scanentry_connectable_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_scanentry_get_connectable_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+//| .. attribute:: scan_response
+//|
+//| True if the entry was a scan response. (read-only)
+//|
+STATIC mp_obj_t scanentry_get_scan_response(mp_obj_t self_in) {
+ bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ return mp_obj_new_bool(common_hal_bleio_scanentry_get_scan_response(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_scan_response_obj, scanentry_get_scan_response);
+
+const mp_obj_property_t bleio_scanentry_scan_response_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_scanentry_get_scan_response_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
STATIC const mp_rom_map_elem_t bleio_scanentry_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_scanentry_address_obj) },
{ MP_ROM_QSTR(MP_QSTR_advertisement_bytes), MP_ROM_PTR(&bleio_scanentry_advertisement_bytes_obj) },
{ MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&bleio_scanentry_rssi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_connectable), MP_ROM_PTR(&bleio_scanentry_connectable_obj) },
+ { MP_ROM_QSTR(MP_QSTR_scan_response), MP_ROM_PTR(&bleio_scanentry_scan_response_obj) },
+ { MP_ROM_QSTR(MP_QSTR_matches), MP_ROM_PTR(&bleio_scanentry_matches_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_scanentry_locals_dict, bleio_scanentry_locals_dict_table);
diff --git a/shared-bindings/_bleio/ScanEntry.h b/shared-bindings/_bleio/ScanEntry.h
index 8af1f050a..9aeaf20d3 100644
--- a/shared-bindings/_bleio/ScanEntry.h
+++ b/shared-bindings/_bleio/ScanEntry.h
@@ -37,5 +37,8 @@ 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);
+bool common_hal_bleio_scanentry_get_connectable(bleio_scanentry_obj_t *self);
+bool common_hal_bleio_scanentry_get_scan_response(bleio_scanentry_obj_t *self);
+bool common_hal_bleio_scanentry_matches(bleio_scanentry_obj_t *self, uint8_t* prefixes, size_t prefixes_len, bool all);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H
diff --git a/shared-bindings/_bleio/ScanResults.c b/shared-bindings/_bleio/ScanResults.c
new file mode 100644
index 000000000..dcece3d5d
--- /dev/null
+++ b/shared-bindings/_bleio/ScanResults.c
@@ -0,0 +1,72 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 Glenn Ruben Bakke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+
+#include "py/objproperty.h"
+#include "py/runtime.h"
+#include "shared-bindings/_bleio/ScanResults.h"
+
+//| .. currentmodule:: _bleio
+//|
+//| :class:`ScanResults` -- An Iterator over BLE scanning results
+//| ===============================================================
+//|
+//| Iterates over advertising data received while scanning. This object is always created
+//| by a `_bleio.Adapter`: it has no user-visible constructor.
+//|
+STATIC mp_obj_t scanresults_iternext(mp_obj_t self_in) {
+ mp_check_self(MP_OBJ_IS_TYPE(self_in, &bleio_scanresults_type));
+ bleio_scanresults_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_obj_t scan_entry = common_hal_bleio_scanresults_next(self);
+ if (scan_entry != mp_const_none) {
+ return scan_entry;
+ }
+ return MP_OBJ_STOP_ITERATION;
+}
+
+//| .. class:: ScanResults()
+//|
+//| Cannot be instantiated directly. Use `_bleio.Adapter.start_scan`.
+//|
+//| .. method:: __iter__()
+//|
+//| Returns itself since it is the iterator.
+//|
+//| .. method:: __next__()
+//|
+//| Returns the next `_bleio.ScanEntry`. Blocks if none have been received and scanning is still
+//| active. Raises `StopIteration` if scanning is finished and no other results are available.
+//|
+
+const mp_obj_type_t bleio_scanresults_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_ScanResults,
+ .getiter = mp_identity_getiter,
+ .iternext = scanresults_iternext,
+};
diff --git a/ports/nrf/common-hal/_bleio/Scanner.h b/shared-bindings/_bleio/ScanResults.h
index 3768a52cb..a8c88c215 100644
--- a/ports/nrf/common-hal/_bleio/Scanner.h
+++ b/shared-bindings/_bleio/ScanResults.h
@@ -5,6 +5,7 @@
*
* 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
@@ -25,16 +26,14 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SCANNER_H
-#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SCANNER_H
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANRESULTS_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANRESULTS_H
#include "py/obj.h"
+#include "shared-module/_bleio/ScanResults.h"
-typedef struct {
- mp_obj_base_t base;
- mp_obj_t scan_entries;
- uint16_t interval;
- uint16_t window;
-} bleio_scanner_obj_t;
+extern const mp_obj_type_t bleio_scanresults_type;
-#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SCANNER_H
+mp_obj_t common_hal_bleio_scanresults_next(bleio_scanresults_obj_t *self);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANRESULTS_H
diff --git a/shared-bindings/_bleio/Scanner.c b/shared-bindings/_bleio/Scanner.c
deleted file mode 100644
index 94cec9752..000000000
--- a/shared-bindings/_bleio/Scanner.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "py/objproperty.h"
-#include "py/runtime.h"
-#include "shared-bindings/_bleio/ScanEntry.h"
-#include "shared-bindings/_bleio/Scanner.h"
-
-#define INTERVAL_DEFAULT (0.1f)
-#define INTERVAL_MIN (0.0025f)
-#define INTERVAL_MIN_STRING "0.0025"
-#define INTERVAL_MAX (40.959375f)
-#define INTERVAL_MAX_STRING "40.959375"
-#define WINDOW_DEFAULT (0.1f)
-
-//| .. currentmodule:: _bleio
-//|
-//| :class:`Scanner` -- scan for nearby BLE devices
-//| =========================================================
-//|
-//| Scan for nearby BLE devices.
-//|
-//| Usage::
-//|
-//| import _bleio
-//| scanner = _bleio.Scanner()
-//| entries = scanner.scan(2.5) # Scan for 2.5 seconds
-//|
-
-//| .. class:: Scanner()
-//|
-//| Create a new Scanner object.
-//|
-STATIC mp_obj_t bleio_scanner_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args) {
- mp_arg_check_num(n_args, kw_args, 0, 0, false);
-
- bleio_scanner_obj_t *self = m_new_obj(bleio_scanner_obj_t);
- self->base.type = type;
-
- common_hal_bleio_scanner_construct(self);
-
- return MP_OBJ_FROM_PTR(self);
-}
-
-//| .. method:: scan(timeout, \*, interval=0.1, window=0.1)
-//|
-//| Performs a BLE scan.
-//|
-//| :param float timeout: the scan timeout in seconds
-//| :param float interval: the interval (in seconds) between the start of two consecutive scan windows
-//| Must be in the range 0.0025 - 40.959375 seconds.
-//| :param float window: the duration (in seconds) to scan a single BLE channel.
-//| window must be <= interval.
-//| :returns: an iterable of `ScanEntry` objects
-//| :rtype: iterable
-//|
-STATIC mp_obj_t bleio_scanner_scan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- enum { ARG_timeout, ARG_interval, ARG_window };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_timeout, MP_ARG_REQUIRED | MP_ARG_OBJ },
- { MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
- { MP_QSTR_window, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
- };
-
- bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- const mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj);
-
- if (args[ARG_interval].u_obj == MP_OBJ_NULL) {
- args[ARG_interval].u_obj = mp_obj_new_float(INTERVAL_DEFAULT);
- }
-
- if (args[ARG_window].u_obj == MP_OBJ_NULL) {
- args[ARG_window].u_obj = mp_obj_new_float(WINDOW_DEFAULT);
- }
-
- const mp_float_t interval = mp_obj_float_get(args[ARG_interval].u_obj);
- if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
- mp_raise_ValueError_varg(translate("interval must be in range %s-%s"), INTERVAL_MIN_STRING, INTERVAL_MAX_STRING);
- }
-
- const mp_float_t window = mp_obj_float_get(args[ARG_window].u_obj);
- if (window > interval) {
- mp_raise_ValueError(translate("window must be <= interval"));
- }
-
- return common_hal_bleio_scanner_scan(self, timeout, interval, window);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_scanner_scan_obj, 2, bleio_scanner_scan);
-
-
-STATIC const mp_rom_map_elem_t bleio_scanner_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&bleio_scanner_scan_obj) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(bleio_scanner_locals_dict, bleio_scanner_locals_dict_table);
-
-const mp_obj_type_t bleio_scanner_type = {
- { &mp_type_type },
- .name = MP_QSTR_Scanner,
- .make_new = bleio_scanner_make_new,
- .locals_dict = (mp_obj_dict_t*)&bleio_scanner_locals_dict
-};
diff --git a/shared-bindings/_bleio/Service.c b/shared-bindings/_bleio/Service.c
index da5633f2a..43679393a 100644
--- a/shared-bindings/_bleio/Service.c
+++ b/shared-bindings/_bleio/Service.c
@@ -29,58 +29,42 @@
#include "py/objproperty.h"
#include "py/runtime.h"
#include "shared-bindings/_bleio/Characteristic.h"
-#include "shared-bindings/_bleio/Peripheral.h"
#include "shared-bindings/_bleio/Service.h"
#include "shared-bindings/_bleio/UUID.h"
//| .. currentmodule:: _bleio
//|
-//| :class:`Service` -- BLE service
+//| :class:`Service` -- BLE GATT Service
//| =========================================================
//|
//| Stores information about a BLE service and its characteristics.
//|
-//| .. class:: Service
+//| .. class:: Service(uuid, *, secondary=False)
//|
-//| There is no regular constructor for a Service. A new local Service can be created
-//| and attached to a Peripheral by calling `add_to_peripheral()`.
-//| Remote Service objects are created by `Central.discover_remote_services()`
-//| or `Peripheral.discover_remote_services()`.
+//| Create a new Service identified by the specified UUID. It can be accessed by all
+//| connections. This is known as a Service server. Client Service objects are created via
+//| `Connection.discover_remote_services`.
//|
-//| .. classmethod:: add_to_peripheral(peripheral, uuid, *, secondary=False)
+//| To mark the Service as secondary, pass `True` as :py:data:`secondary`.
//|
-//| Create a new Service object, identitied by the specified UUID, and add it
-//| to the given Peripheral.
-//|
-//| To mark the service as secondary, pass `True` as :py:data:`secondary`.
-//|
-//| :param Peripheral peripheral: The peripheral that will provide this service
-//| :param UUID uuid: The uuid of the service
-//| :param bool secondary: If the service is a secondary one
+//| :param UUID uuid: The uuid of the service
+//| :param bool secondary: If the service is a secondary one
//
-//| :return: the new Service
+//| :return: the new Service
//|
-STATIC mp_obj_t bleio_service_add_to_peripheral(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- // class is arg[0], which we can ignore.
-
- enum { ARG_peripheral, ARG_uuid, ARG_secondary };
+STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_uuid, ARG_secondary };
static const mp_arg_t allowed_args[] = {
- { MP_QSTR_peripheral, MP_ARG_REQUIRED | MP_ARG_OBJ,},
{ MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_secondary, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- const mp_obj_t peripheral_obj = args[ARG_peripheral].u_obj;
- if (!MP_OBJ_IS_TYPE(peripheral_obj, &bleio_peripheral_type)) {
- mp_raise_ValueError(translate("Expected a Peripheral"));
- }
+ mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
const mp_obj_t uuid_obj = args[ARG_uuid].u_obj;
if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
- mp_raise_ValueError(translate("Expected a UUID"));
+ mp_raise_TypeError(translate("Expected a UUID"));
}
const bool is_secondary = args[ARG_secondary].u_bool;
@@ -88,19 +72,15 @@ STATIC mp_obj_t bleio_service_add_to_peripheral(size_t n_args, const mp_obj_t *p
bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t);
service->base.type = &bleio_service_type;
- common_hal_bleio_service_construct(
- service, MP_OBJ_TO_PTR(peripheral_obj), MP_OBJ_TO_PTR(uuid_obj), is_secondary);
-
- common_hal_bleio_peripheral_add_service(peripheral_obj, service);
+ common_hal_bleio_service_construct(service, MP_OBJ_TO_PTR(uuid_obj), is_secondary);
return MP_OBJ_FROM_PTR(service);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_service_add_to_peripheral_fun_obj, 3, bleio_service_add_to_peripheral);
-STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(bleio_service_add_to_peripheral_obj, MP_ROM_PTR(&bleio_service_add_to_peripheral_fun_obj));
//| .. attribute:: characteristics
//|
-//| A tuple of :py:class:`Characteristic` designating the characteristics that are offered by this service. (read-only)
+//| A tuple of :py:class:`Characteristic` designating the characteristics that are offered by
+//| this service. (read-only)
//|
STATIC mp_obj_t bleio_service_get_characteristics(mp_obj_t self_in) {
bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -156,7 +136,8 @@ const mp_obj_property_t bleio_service_secondary_obj = {
//| .. attribute:: uuid
//|
//| The UUID of this service. (read-only)
-//| Will be ``None`` if the 128-bit UUID for this service is not known.
+//|
+//| 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);
@@ -175,10 +156,10 @@ 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_add_to_peripheral), MP_ROM_PTR(&bleio_service_add_to_peripheral_obj) },
{ MP_ROM_QSTR(MP_QSTR_characteristics), MP_ROM_PTR(&bleio_service_characteristics_obj) },
{ MP_ROM_QSTR(MP_QSTR_secondary), MP_ROM_PTR(&bleio_service_secondary_obj) },
{ MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_service_uuid_obj) },
+ { MP_ROM_QSTR(MP_QSTR_remote), MP_ROM_PTR(&bleio_service_remote_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_service_locals_dict, bleio_service_locals_dict_table);
@@ -196,6 +177,25 @@ STATIC void bleio_service_print(const mp_print_t *print, mp_obj_t self_in, mp_pr
const mp_obj_type_t bleio_service_type = {
{ &mp_type_type },
.name = MP_QSTR_Service,
+ .make_new = bleio_service_make_new,
.print = bleio_service_print,
.locals_dict = (mp_obj_dict_t*)&bleio_service_locals_dict
};
+
+// Helper for classes that store lists of services.
+mp_obj_tuple_t* service_linked_list_to_tuple(bleio_service_obj_t * services) {
+ // Return list as a tuple so user won't be able to change it.
+ bleio_service_obj_t *head = services;
+ size_t len = 0;
+ while (head != NULL) {
+ len++;
+ head = head->next;
+ }
+ mp_obj_tuple_t * t = MP_OBJ_TO_PTR(mp_obj_new_tuple(len, NULL));
+ head = services;
+ for (int32_t i = len - 1; i >= 0; i--) {
+ t->items[i] = MP_OBJ_FROM_PTR(head);
+ head = head->next;
+ }
+ return t;
+}
diff --git a/shared-bindings/_bleio/Service.h b/shared-bindings/_bleio/Service.h
index e061bcffc..273c6bd98 100644
--- a/shared-bindings/_bleio/Service.h
+++ b/shared-bindings/_bleio/Service.h
@@ -28,16 +28,24 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
-#include "common-hal/_bleio/Peripheral.h"
+#include "common-hal/_bleio/Characteristic.h"
+#include "common-hal/_bleio/Connection.h"
#include "common-hal/_bleio/Service.h"
+#include "py/objtuple.h"
+
const mp_obj_type_t bleio_service_type;
-extern void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_peripheral_obj_t *peripheral, bleio_uuid_obj_t *uuid, bool is_secondary);
+// Private version that doesn't allocate on the heap
+extern uint32_t _common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary, mp_obj_list_t * characteristic_list);
+extern void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary);
+extern void common_hal_bleio_service_from_remote_service(bleio_service_obj_t *self, bleio_connection_obj_t* connection, bleio_uuid_obj_t *uuid, bool is_secondary);
extern bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self);
extern mp_obj_list_t *common_hal_bleio_service_get_characteristic_list(bleio_service_obj_t *self);
extern bool common_hal_bleio_service_get_is_remote(bleio_service_obj_t *self);
extern bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self);
-extern void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic);
+extern void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *initial_value_bufinfo);
+
+mp_obj_tuple_t* service_linked_list_to_tuple(bleio_service_obj_t * services);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
diff --git a/shared-bindings/_bleio/UUID.c b/shared-bindings/_bleio/UUID.c
index 3c0889aad..dd3415902 100644
--- a/shared-bindings/_bleio/UUID.c
+++ b/shared-bindings/_bleio/UUID.c
@@ -156,9 +156,10 @@ STATIC mp_obj_t bleio_uuid_get_uuid128(mp_obj_t self_in) {
bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint8_t uuid128[16];
- if (!common_hal_bleio_uuid_get_uuid128(self, uuid128)) {
+ if (common_hal_bleio_uuid_get_size(self) != 128) {
mp_raise_AttributeError(translate("not a 128-bit UUID"));
}
+ common_hal_bleio_uuid_get_uuid128(self, uuid128);
return mp_obj_new_bytes(uuid128, 16);
}
@@ -192,10 +193,42 @@ const mp_obj_property_t bleio_uuid_size_obj = {
(mp_obj_t)&mp_const_none_obj},
};
+
+//| .. method:: pack_into(buffer, offset=0)
+//|
+//| Packs the UUID into the given buffer at the given offset.
+//|
+STATIC mp_obj_t bleio_uuid_pack_into(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_buffer, ARG_offset };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_buffer, MP_ARG_OBJ | MP_ARG_REQUIRED },
+ { MP_QSTR_offset, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE);
+
+ size_t offset = args[ARG_offset].u_int;
+ if (offset + common_hal_bleio_uuid_get_size(self) / 8 > bufinfo.len) {
+ mp_raise_ValueError(translate("Buffer + offset too small %d %d %d"));
+ }
+
+ common_hal_bleio_uuid_pack_into(self, bufinfo.buf + offset);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_uuid_pack_into_obj, 2, bleio_uuid_pack_into);
+
STATIC const mp_rom_map_elem_t bleio_uuid_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_uuid16), MP_ROM_PTR(&bleio_uuid_uuid16_obj) },
{ MP_ROM_QSTR(MP_QSTR_uuid128), MP_ROM_PTR(&bleio_uuid_uuid128_obj) },
{ MP_ROM_QSTR(MP_QSTR_size), MP_ROM_PTR(&bleio_uuid_size_obj) },
+ { MP_ROM_QSTR(MP_QSTR_pack_into), MP_ROM_PTR(&bleio_uuid_pack_into_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_uuid_locals_dict, bleio_uuid_locals_dict_table);
@@ -231,13 +264,19 @@ STATIC mp_obj_t bleio_uuid_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
//|
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.
+ // Two UUID's are equal if their uuid16 values match or their uuid128 values match.
case MP_BINARY_OP_EQUAL:
if (MP_OBJ_IS_TYPE(rhs_in, &bleio_uuid_type)) {
- return mp_obj_new_bool(
- common_hal_bleio_uuid_get_uuid16(lhs_in) == common_hal_bleio_uuid_get_uuid16(rhs_in) &&
- common_hal_bleio_uuid_get_uuid128_reference(lhs_in) ==
- common_hal_bleio_uuid_get_uuid128_reference(rhs_in));
+ if (common_hal_bleio_uuid_get_size(lhs_in) == 16 &&
+ common_hal_bleio_uuid_get_size(rhs_in) == 16) {
+ return mp_obj_new_bool(common_hal_bleio_uuid_get_uuid16(lhs_in) ==
+ common_hal_bleio_uuid_get_uuid16(rhs_in));
+ }
+ uint8_t lhs[16];
+ uint8_t rhs[16];
+ common_hal_bleio_uuid_get_uuid128(lhs_in, lhs);
+ common_hal_bleio_uuid_get_uuid128(rhs_in, rhs);
+ return mp_obj_new_bool(memcmp(lhs, rhs, sizeof(lhs)) == 0);
} else {
return mp_const_false;
}
diff --git a/shared-bindings/_bleio/UUID.h b/shared-bindings/_bleio/UUID.h
index 46ac54ff3..1490737a7 100644
--- a/shared-bindings/_bleio/UUID.h
+++ b/shared-bindings/_bleio/UUID.h
@@ -34,10 +34,11 @@ void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
extern const mp_obj_type_t bleio_uuid_type;
-extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, uint8_t uuid128[]);
+extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, const uint8_t uuid128[]);
extern uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self);
extern bool common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]);
-extern uint32_t common_hal_bleio_uuid_get_uuid128_reference(bleio_uuid_obj_t *self);
extern uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self);
+void common_hal_bleio_uuid_pack_into(bleio_uuid_obj_t *self, uint8_t* buf);
+
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H
diff --git a/shared-bindings/_bleio/__init__.c b/shared-bindings/_bleio/__init__.c
index f207be8cf..ba2454da4 100644
--- a/shared-bindings/_bleio/__init__.c
+++ b/shared-bindings/_bleio/__init__.c
@@ -26,16 +26,17 @@
* THE SOFTWARE.
*/
+#include "py/objexcept.h"
+#include "py/runtime.h"
#include "shared-bindings/_bleio/__init__.h"
#include "shared-bindings/_bleio/Address.h"
#include "shared-bindings/_bleio/Attribute.h"
-#include "shared-bindings/_bleio/Central.h"
#include "shared-bindings/_bleio/Characteristic.h"
#include "shared-bindings/_bleio/CharacteristicBuffer.h"
+#include "shared-bindings/_bleio/Connection.h"
#include "shared-bindings/_bleio/Descriptor.h"
-#include "shared-bindings/_bleio/Peripheral.h"
#include "shared-bindings/_bleio/ScanEntry.h"
-#include "shared-bindings/_bleio/Scanner.h"
+#include "shared-bindings/_bleio/ScanResults.h"
#include "shared-bindings/_bleio/Service.h"
#include "shared-bindings/_bleio/UUID.h"
@@ -64,43 +65,108 @@
//| Address
//| Adapter
//| Attribute
-//| Central
//| Characteristic
//| CharacteristicBuffer
+//| Connection
//| Descriptor
-//| Peripheral
//| ScanEntry
-//| Scanner
+//| ScanResults
//| Service
//| UUID
//|
//| .. attribute:: adapter
//|
-//| BLE Adapter information, such as enabled state as well as MAC
-//| address.
+//| BLE Adapter used to manage device discovery and connections.
//| This object is the sole instance of `_bleio.Adapter`.
//|
+//| .. class:: BluetoothError(Exception)
+//|
+//| Catch all exception for Bluetooth related errors.
+//|
+MP_DEFINE_BLEIO_EXCEPTION(BluetoothError, Exception)
+
+NORETURN void mp_raise_bleio_BluetoothError(const compressed_string_t* fmt, ...) {
+ va_list argptr;
+ va_start(argptr,fmt);
+ mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_bleio_BluetoothError, fmt, argptr);
+ va_end(argptr);
+ nlr_raise(exception);
+}
+
+//| .. class:: ConnectionError(BluetoothError)
+//|
+//| Raised when a connection is unavailable.
+//|
+MP_DEFINE_BLEIO_EXCEPTION(ConnectionError, bleio_BluetoothError)
+NORETURN void mp_raise_bleio_ConnectionError(const compressed_string_t* fmt, ...) {
+ va_list argptr;
+ va_start(argptr,fmt);
+ mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_bleio_ConnectionError, fmt, argptr);
+ va_end(argptr);
+ nlr_raise(exception);
+}
+
+//| .. class:: RoleError(BluetoothError)
+//|
+//| Raised when a resource is used as the mismatched role. For example, if a local CCCD is
+//| attempted to be set but they can only be set when remote.
+//|
+MP_DEFINE_BLEIO_EXCEPTION(RoleError, bleio_BluetoothError)
+NORETURN void mp_raise_bleio_RoleError(const compressed_string_t* msg) {
+ mp_raise_msg(&mp_type_bleio_RoleError, msg);
+}
+
+//| .. class:: SecurityError(BluetoothError)
+//|
+//| Raised when a security related error occurs.
+//|
+MP_DEFINE_BLEIO_EXCEPTION(SecurityError, bleio_BluetoothError)
+NORETURN void mp_raise_bleio_SecurityError(const compressed_string_t* fmt, ...) {
+ va_list argptr;
+ va_start(argptr,fmt);
+ mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_bleio_SecurityError, fmt, argptr);
+ va_end(argptr);
+ nlr_raise(exception);
+}
+
STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = {
+ // Name must be the first entry so that the exception printing below is correct.
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__bleio) },
+ { MP_ROM_QSTR(MP_QSTR_Adapter), MP_ROM_PTR(&bleio_adapter_type) },
{ MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) },
{ MP_ROM_QSTR(MP_QSTR_Attribute), MP_ROM_PTR(&bleio_attribute_type) },
- { MP_ROM_QSTR(MP_QSTR_Central), MP_ROM_PTR(&bleio_central_type) },
+ { MP_ROM_QSTR(MP_QSTR_Connection), MP_ROM_PTR(&bleio_connection_type) },
{ MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) },
{ MP_ROM_QSTR(MP_QSTR_CharacteristicBuffer), MP_ROM_PTR(&bleio_characteristic_buffer_type) },
{ MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) },
- { MP_ROM_QSTR(MP_QSTR_Peripheral), MP_ROM_PTR(&bleio_peripheral_type) },
{ MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) },
- { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) },
+ { MP_ROM_QSTR(MP_QSTR_ScanResults), MP_ROM_PTR(&bleio_scanresults_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) },
+
+ // Errors
+ { MP_ROM_QSTR(MP_QSTR_BluetoothError), MP_ROM_PTR(&mp_type_bleio_BluetoothError) },
+ { MP_ROM_QSTR(MP_QSTR_ConnectionError), MP_ROM_PTR(&mp_type_bleio_ConnectionError) },
+ { MP_ROM_QSTR(MP_QSTR_RoleError), MP_ROM_PTR(&mp_type_bleio_RoleError) },
+ { MP_ROM_QSTR(MP_QSTR_SecurityError), MP_ROM_PTR(&mp_type_bleio_SecurityError) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table);
+void bleio_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) {
+ mp_print_kind_t k = kind & ~PRINT_EXC_SUBCLASS;
+ bool is_subclass = kind & PRINT_EXC_SUBCLASS;
+ if (!is_subclass && (k == PRINT_EXC)) {
+ mp_print_str(print, qstr_str(MP_OBJ_QSTR_VALUE(bleio_module_globals_table[0].value)));
+ mp_print_str(print, ".");
+ }
+ mp_obj_exception_print(print, o_in, kind);
+}
+
const mp_obj_module_t bleio_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&bleio_module_globals,
diff --git a/shared-bindings/_bleio/__init__.h b/shared-bindings/_bleio/__init__.h
index 67379ae2e..5256bdaa0 100644
--- a/shared-bindings/_bleio/__init__.h
+++ b/shared-bindings/_bleio/__init__.h
@@ -36,17 +36,41 @@
#include "common-hal/_bleio/__init__.h"
#include "common-hal/_bleio/Adapter.h"
-extern const super_adapter_obj_t common_hal_bleio_adapter_obj;
+extern bleio_adapter_obj_t common_hal_bleio_adapter_obj;
-extern void common_hal_bleio_check_connected(uint16_t conn_handle);
+void bleio_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind);
-extern uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device);
-extern mp_obj_list_t *common_hal_bleio_device_get_remote_service_list(mp_obj_t device);
-extern void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t service_uuids_whitelist);
+#define MP_DEFINE_BLEIO_EXCEPTION(exc_name, base_name) \
+const mp_obj_type_t mp_type_bleio_ ## exc_name = { \
+ { &mp_type_type }, \
+ .name = MP_QSTR_ ## exc_name, \
+ .print = bleio_exception_print, \
+ .make_new = mp_obj_exception_make_new, \
+ .attr = mp_obj_exception_attr, \
+ .parent = &mp_type_ ## base_name, \
+};
-extern mp_obj_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle);
-extern void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo);
-extern void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, bool write_no_response);
+extern const mp_obj_type_t mp_type_bleio_BluetoothError;
+extern const mp_obj_type_t mp_type_bleio_ConnectionError;
+extern const mp_obj_type_t mp_type_bleio_RoleError;
+extern const mp_obj_type_t mp_type_bleio_SecurityError;
+NORETURN void mp_raise_bleio_BluetoothError(const compressed_string_t* msg, ...);
+NORETURN void mp_raise_bleio_ConnectionError(const compressed_string_t* msg, ...);
+NORETURN void mp_raise_bleio_RoleError(const compressed_string_t* msg);
+NORETURN void mp_raise_bleio_SecurityError(const compressed_string_t* msg, ...);
+
+void common_hal_bleio_check_connected(uint16_t conn_handle);
+
+uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device);
+mp_obj_list_t *common_hal_bleio_device_get_remote_service_list(mp_obj_t device);
+void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t service_uuids_whitelist);
+
+size_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_t* buf, size_t len);
+void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo);
+size_t common_hal_bleio_gattc_read(uint16_t handle, uint16_t conn_handle, uint8_t* buf, size_t len);
+void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, bool write_no_response);
+
+void common_hal_bleio_gc_collect(void);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO___INIT___H
diff --git a/shared-bindings/_pixelbuf/__init__.c b/shared-bindings/_pixelbuf/__init__.c
index 48b9f1cef..eb0cb2984 100644
--- a/shared-bindings/_pixelbuf/__init__.c
+++ b/shared-bindings/_pixelbuf/__init__.c
@@ -55,7 +55,7 @@
//| .. class:: ByteOrder()
//|
-//| Classes representing byteorders for circuitpython
+//| Classes representing byteorders for CircuitPython
//| .. attribute:: bpp
@@ -284,7 +284,7 @@ PIXELBUF_BYTEORDER(LBRG, 4, 3, 1, 2, 0, false, true)
//| * **bpp** 4
//| * **has_luminosity** True
//|
-//| Actual format commonly used by DotStar (5 bit luninance value)
+//| Actual format commonly used by DotStar (5 bit luminance value)
PIXELBUF_BYTEORDER(LBGR, 4, 3, 2, 1, 0, false, true)
STATIC const mp_rom_map_elem_t pixelbuf_module_globals_table[] = {
diff --git a/shared-bindings/audiobusio/I2SOut.c b/shared-bindings/audiobusio/I2SOut.c
index 2cd2b6728..8f7382fde 100644
--- a/shared-bindings/audiobusio/I2SOut.c
+++ b/shared-bindings/audiobusio/I2SOut.c
@@ -62,7 +62,7 @@
//| import time
//| import math
//|
-//| # Generate one period of sine wav.
+//| # Generate one period of sine wave.
//| length = 8000 // 440
//| sine_wave = array.array("H", [0] * length)
//| for i in range(length):
@@ -117,7 +117,7 @@ STATIC mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_a
assert_pin(data_obj, false);
const mcu_pin_obj_t *data = MP_OBJ_TO_PTR(data_obj);
- audiobusio_i2sout_obj_t *self = m_new_obj(audiobusio_i2sout_obj_t);
+ audiobusio_i2sout_obj_t *self = m_new_obj_with_finaliser(audiobusio_i2sout_obj_t);
self->base.type = &audiobusio_i2sout_type;
common_hal_audiobusio_i2sout_construct(self, bit_clock, word_select, data, args[ARG_left_justified].u_bool);
@@ -268,6 +268,7 @@ const mp_obj_property_t audiobusio_i2sout_paused_obj = {
STATIC const mp_rom_map_elem_t audiobusio_i2sout_locals_dict_table[] = {
// Methods
+ { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&audiobusio_i2sout_deinit_obj) },
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiobusio_i2sout_deinit_obj) },
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiobusio_i2sout___exit___obj) },
diff --git a/shared-bindings/audioio/__init__.c b/shared-bindings/audioio/__init__.c
index 7fa37d5c5..02a5fe1ee 100644
--- a/shared-bindings/audioio/__init__.c
+++ b/shared-bindings/audioio/__init__.c
@@ -68,7 +68,7 @@
//|
//| For compatibility with CircuitPython 4.x, some builds allow the items in
//| `audiocore` to be imported from `audioio`. This will be removed for all
-//| boards in a future build of CicuitPython.
+//| boards in a future build of CircuitPython.
//|
STATIC const mp_rom_map_elem_t audioio_module_globals_table[] = {
diff --git a/shared-bindings/board/__init__.c b/shared-bindings/board/__init__.c
index 47e2d64bc..3dda59fb8 100644
--- a/shared-bindings/board/__init__.c
+++ b/shared-bindings/board/__init__.c
@@ -93,6 +93,12 @@ MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi);
//|
//| Returns the `busio.UART` object for the board designated TX and RX pins. It is a singleton.
//|
+//| The object created uses the default parameter values for `busio.UART`. If you need to set
+//| parameters that are not changeable after creation, such as ``receiver_buffer_size``,
+//| do not use `board.UART()`; instead create a `busio.UART` object explicitly with the
+//| desired parameters.
+//|
+//|
#if BOARD_UART
mp_obj_t board_uart(void) {
mp_obj_t singleton = common_hal_board_get_uart();
diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c
index 3bd89e2e2..50a95beb2 100644
--- a/shared-bindings/busio/I2C.c
+++ b/shared-bindings/busio/I2C.c
@@ -60,6 +60,10 @@
//| :param int frequency: The clock frequency in Hertz
//| :param int timeout: The maximum clock stretching timeut - (used only for bitbangio.I2C; ignored for busio.I2C)
//|
+//| .. note:: On the nRF52840, only one I2C object may be created,
+//| except on the Circuit Playground Bluefruit, which allows two,
+//| one for the onboard accelerometer, and one for offboard use.
+//|
STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t);
self->base.type = &busio_i2c_type;
diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c
index d47bf499a..d1791bef3 100644
--- a/shared-bindings/busio/SPI.c
+++ b/shared-bindings/busio/SPI.c
@@ -154,11 +154,12 @@ STATIC void check_for_deinit(busio_spi_obj_t *self) {
//| within spec for the SAMD21.
//|
//| .. note:: On the nRF52840, these baudrates are available: 125kHz, 250kHz, 1MHz, 2MHz, 4MHz,
-//| and 8MHz. 16MHz and 32MHz are also available, but only on the first
-//| `busio.SPI` object you create. Two more ``busio.SPI`` objects can be created, but they are restricted
-//| to 8MHz maximum. This is a hardware restriction: there is only one high-speed SPI peripheral.
+//| and 8MHz.
//| If you pick a a baudrate other than one of these, the nearest lower
//| baudrate will be chosen, with a minimum of 125kHz.
+//| Two SPI objects may be created, except on the Circuit Playground Bluefruit,
+//| which allows only one (to allow for an additional I2C object).
+//|
STATIC mp_obj_t busio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits };
static const mp_arg_t allowed_args[] = {
diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c
index c7eef8c43..7a3b48e89 100644
--- a/shared-bindings/busio/UART.c
+++ b/shared-bindings/busio/UART.c
@@ -57,7 +57,7 @@
//| :param int bits: the number of bits per byte, 7, 8 or 9.
//| :param Parity parity: the parity used for error checking.
//| :param int stop: the number of stop bits, 1 or 2.
-//| :param float timeout: the timeout in seconds to wait for the first character and between subsequent characters. Raises ``ValueError`` if timeout >100 seconds.
+//| :param float timeout: the timeout in seconds to wait for the first character and between subsequent characters when reading. Raises ``ValueError`` if timeout >100 seconds.
//| :param int receiver_buffer_size: the character length of the read buffer (0 to disable). (When a character is 9 bits the buffer will be 2 * receiver_buffer_size bytes.)
//|
//| *New in CircuitPython 4.0:* ``timeout`` has incompatibly changed units from milliseconds to seconds.
@@ -69,6 +69,12 @@ typedef struct {
extern const busio_uart_parity_obj_t busio_uart_parity_even_obj;
extern const busio_uart_parity_obj_t busio_uart_parity_odd_obj;
+STATIC void validate_timeout(mp_float_t timeout) {
+ if (timeout < (mp_float_t) 0.0f || timeout > (mp_float_t) 100.0f) {
+ mp_raise_ValueError(translate("timeout must be 0.0-100.0 seconds"));
+ }
+}
+
STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
// Always initially allocate the UART object within the long-lived heap.
// This is needed to avoid crashes with certain UART implementations which
@@ -116,9 +122,7 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co
}
mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj);
- if (timeout > (mp_float_t)100.0) {
- mp_raise_ValueError(translate("timeout >100 (units are now seconds, not msecs)"));
- }
+ validate_timeout(timeout);
common_hal_busio_uart_construct(self, tx, rx,
args[ARG_baudrate].u_int, bits, parity, stop, timeout,
@@ -286,6 +290,35 @@ const mp_obj_property_t busio_uart_in_waiting_obj = {
(mp_obj_t)&mp_const_none_obj},
};
+//| .. attribute:: timeout
+//|
+//| The current timeout, in seconds (float).
+//|
+STATIC mp_obj_t busio_uart_obj_get_timeout(mp_obj_t self_in) {
+ busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+ return mp_obj_new_float(common_hal_busio_uart_get_timeout(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_get_timeout_obj, busio_uart_obj_get_timeout);
+
+STATIC mp_obj_t busio_uart_obj_set_timeout(mp_obj_t self_in, mp_obj_t timeout) {
+ busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+ mp_float_t timeout_float = mp_obj_get_float(timeout);
+ validate_timeout(timeout_float);
+ common_hal_busio_uart_set_timeout(self, timeout_float);
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(busio_uart_set_timeout_obj, busio_uart_obj_set_timeout);
+
+
+const mp_obj_property_t busio_uart_timeout_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&busio_uart_get_timeout_obj,
+ (mp_obj_t)&busio_uart_set_timeout_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
//| .. method:: reset_input_buffer()
//|
//| Discard any unread characters in the input buffer.
@@ -355,8 +388,9 @@ STATIC const mp_rom_map_elem_t busio_uart_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_reset_input_buffer), MP_ROM_PTR(&busio_uart_reset_input_buffer_obj) },
// Properties
- { MP_ROM_QSTR(MP_QSTR_baudrate), MP_ROM_PTR(&busio_uart_baudrate_obj) },
- { MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&busio_uart_in_waiting_obj) },
+ { MP_ROM_QSTR(MP_QSTR_baudrate), MP_ROM_PTR(&busio_uart_baudrate_obj) },
+ { MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&busio_uart_in_waiting_obj) },
+ { MP_ROM_QSTR(MP_QSTR_timeout), MP_ROM_PTR(&busio_uart_timeout_obj) },
// Nested Enum-like Classes.
{ MP_ROM_QSTR(MP_QSTR_Parity), MP_ROM_PTR(&busio_uart_parity_type) },
diff --git a/shared-bindings/busio/UART.h b/shared-bindings/busio/UART.h
index 776a996be..cfd2c800c 100644
--- a/shared-bindings/busio/UART.h
+++ b/shared-bindings/busio/UART.h
@@ -57,7 +57,8 @@ extern size_t common_hal_busio_uart_write(busio_uart_obj_t *self,
extern uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self);
extern void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate);
-
+extern mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self);
+extern void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout);
extern uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self);
extern void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self);
diff --git a/shared-bindings/microcontroller/Pin.h b/shared-bindings/microcontroller/Pin.h
index ed831b258..2d15dd5c5 100644
--- a/shared-bindings/microcontroller/Pin.h
+++ b/shared-bindings/microcontroller/Pin.h
@@ -37,5 +37,7 @@ void assert_pin(mp_obj_t obj, bool none_ok);
void assert_pin_free(const mcu_pin_obj_t* pin);
bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin);
+void common_hal_never_reset_pin(const mcu_pin_obj_t* pin);
+void common_hal_reset_pin(const mcu_pin_obj_t* pin);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_PIN_H
diff --git a/shared-bindings/pulseio/PWMOut.c b/shared-bindings/pulseio/PWMOut.c
index 40981e0a8..53b88c61a 100644
--- a/shared-bindings/pulseio/PWMOut.c
+++ b/shared-bindings/pulseio/PWMOut.c
@@ -162,6 +162,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pwmout___exit___obj, 4, 4, pu
//| 16 bit value that dictates how much of one cycle is high (1) versus low
//| (0). 0xffff will always be high, 0 will always be low and 0x7fff will
//| be half high and then half low.
+//|
+//| Depending on how PWM is implemented on a specific board, the internal
+//| representation for duty cycle might have less than 16 bits of resolution.
+//| Reading this property will return the value from the internal representation,
+//| so it may differ from the value set.
STATIC mp_obj_t pulseio_pwmout_obj_get_duty_cycle(mp_obj_t self_in) {
pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self);
@@ -193,6 +198,12 @@ const mp_obj_property_t pulseio_pwmout_duty_cycle_obj = {
//| 32 bit value that dictates the PWM frequency in Hertz (cycles per
//| second). Only writeable when constructed with ``variable_frequency=True``.
//|
+//| Depending on how PWM is implemented on a specific board, the internal value
+//| for the PWM's duty cycle may need to be recalculated when the frequency
+//| changes. In these cases, the duty cycle is automatically recalculated
+//| from the original duty cycle value. This should happen without any need
+//| to manually re-set the duty cycle.
+//|
STATIC mp_obj_t pulseio_pwmout_obj_get_frequency(mp_obj_t self_in) {
pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self);
diff --git a/shared-bindings/rtc/RTC.c b/shared-bindings/rtc/RTC.c
index 17dccdb03..3ff09a4ec 100644
--- a/shared-bindings/rtc/RTC.c
+++ b/shared-bindings/rtc/RTC.c
@@ -57,7 +57,23 @@ STATIC mp_obj_t rtc_rtc_make_new(const mp_obj_type_t *type, size_t n_args, const
//| .. attribute:: datetime
//|
-//| The date and time of the RTC.
+//| The current date and time of the RTC as a `time.struct_time`.
+//|
+//| This must be set to the current date and time whenever the board loses power::
+//|
+//| import rtc
+//| import time
+//|
+//| r = rtc.RTC()
+//| r.datetime = rtctime.struct_time((2019, 5, 29, 15, 14, 15, 0, -1, -1))
+//|
+//|
+//| Once set, the RTC will automatically update this value as time passes. You can read this
+//| property to get a snapshot of the current time::
+//|
+//| current_time = r.datetime
+//| print(current_time)
+//| # struct_time(tm_year=2019, tm_month=5, ...)
//|
STATIC mp_obj_t rtc_rtc_obj_get_datetime(mp_obj_t self_in) {
timeutils_struct_time_t tm;
@@ -83,9 +99,10 @@ const mp_obj_property_t rtc_rtc_datetime_obj = {
//| .. attribute:: calibration
//|
-//| The RTC calibration value.
+//| The RTC calibration value as an `int`.
+//|
//| A positive value speeds up the clock and a negative value slows it down.
-//| Range and value is hardware specific, but one step is often approx. 1 ppm.
+//| Range and value is hardware specific, but one step is often approximately 1 ppm.
//|
STATIC mp_obj_t rtc_rtc_obj_get_calibration(mp_obj_t self_in) {
int calibration = common_hal_rtc_get_calibration();
diff --git a/shared-bindings/rtc/__init__.c b/shared-bindings/rtc/__init__.c
index ac67a7131..22eda9b66 100644
--- a/shared-bindings/rtc/__init__.c
+++ b/shared-bindings/rtc/__init__.c
@@ -36,12 +36,13 @@
//|
//| .. module:: rtc
//| :synopsis: Real Time Clock
-//| :platform: SAMD21
+//| :platform: SAMD21, SAMD51, nRF52
//|
-//| The `rtc` module provides support for a Real Time Clock.
-//| It also backs the `time.time()` and `time.localtime()` functions using the onboard RTC if present.
+//| The `rtc` module provides support for a Real Time Clock. You can access and manage the
+//| RTC using :class:`rtc.RTC`. It also backs the :func:`time.time` and :func:`time.localtime`
+//| functions using the onboard RTC if present.
//|
-//| Libraries
+//| Classes
//|
//| .. toctree::
//| :maxdepth: 3
@@ -63,10 +64,9 @@ mp_obj_t rtc_get_time_source_time(void) {
//| .. function:: set_time_source(rtc)
//|
-//| Sets the rtc time source used by time.localtime().
-//| The default is `rtc.RTC()`.
-//|
-//| Example usage::
+//| Sets the RTC time source used by :func:`time.localtime`.
+//| The default is :class:`rtc.RTC`, but it's useful to use this to override the
+//| time source for testing purposes. For example::
//|
//| import rtc
//| import time
diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c
index 2654de09a..b3e4604b5 100644
--- a/shared-bindings/time/__init__.c
+++ b/shared-bindings/time/__init__.c
@@ -85,9 +85,9 @@ MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep);
#if MICROPY_PY_COLLECTIONS
mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
if (n_args != 1 || (kw_args != NULL && kw_args->used > 0)) {
- mp_raise_TypeError(translate("time.struct_time() takes exactly 1 argument"));
+ return namedtuple_make_new(type, n_args, args, kw_args);
}
- if (!MP_OBJ_IS_TYPE(args[0], &mp_type_tuple) || ((mp_obj_tuple_t*) MP_OBJ_TO_PTR(args[0]))->len != 9) {
+ if (mp_obj_get_type(args[0])->getiter != mp_obj_tuple_getiter || ((mp_obj_tuple_t*) MP_OBJ_TO_PTR(args[0]))->len != 9) {
mp_raise_TypeError(translate("time.struct_time() takes a 9-sequence"));
}
diff --git a/shared-module/_bleio/ScanEntry.c b/shared-module/_bleio/ScanEntry.c
index 8dfa17f31..785209c4a 100644
--- a/shared-module/_bleio/ScanEntry.c
+++ b/shared-module/_bleio/ScanEntry.c
@@ -37,9 +37,50 @@ 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) {
- return self->data;
+ return MP_OBJ_FROM_PTR(self->data);
}
mp_int_t common_hal_bleio_scanentry_get_rssi(bleio_scanentry_obj_t *self) {
return self->rssi;
}
+
+bool common_hal_bleio_scanentry_get_connectable(bleio_scanentry_obj_t *self) {
+ return self->connectable;
+}
+
+bool common_hal_bleio_scanentry_get_scan_response(bleio_scanentry_obj_t *self) {
+ return self->scan_response;
+}
+
+bool bleio_scanentry_data_matches(const uint8_t* data, size_t len, const uint8_t* prefixes, size_t prefixes_length, bool any) {
+ if (prefixes_length == 0) {
+ return true;
+ }
+ size_t i = 0;
+ while(i < prefixes_length) {
+ uint8_t prefix_length = prefixes[i];
+ i += 1;
+ size_t j = 0;
+ while (j < len) {
+ uint8_t structure_length = data[j];
+ j += 1;
+ if (structure_length == 0) {
+ break;
+ }
+ if (structure_length >= prefix_length && memcmp(data + j, prefixes + i, prefix_length) == 0) {
+ if (any) {
+ return true;
+ }
+ } else if (!any) {
+ return false;
+ }
+ j += structure_length;
+ }
+ i += prefix_length;
+ }
+ return !any;
+}
+
+bool common_hal_bleio_scanentry_matches(bleio_scanentry_obj_t *self, const uint8_t* prefixes, size_t prefixes_len, bool all) {
+ return bleio_scanentry_data_matches(self->data->data, self->data->len, prefixes, prefixes_len, !all);
+}
diff --git a/shared-module/_bleio/ScanEntry.h b/shared-module/_bleio/ScanEntry.h
index 1e798d78f..94361a397 100644
--- a/shared-module/_bleio/ScanEntry.h
+++ b/shared-module/_bleio/ScanEntry.h
@@ -29,14 +29,19 @@
#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H
#include "py/obj.h"
+#include "py/objstr.h"
#include "shared-bindings/_bleio/Address.h"
typedef struct {
mp_obj_base_t base;
bool connectable;
+ bool scan_response;
int8_t rssi;
bleio_address_obj_t *address;
- mp_obj_t data;
+ mp_obj_str_t *data;
+ uint64_t time_received;
} bleio_scanentry_obj_t;
+bool bleio_scanentry_data_matches(const uint8_t* data, size_t len, const uint8_t* prefixes, size_t prefix_length, bool any);
+
#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H
diff --git a/shared-module/_bleio/ScanResults.c b/shared-module/_bleio/ScanResults.c
new file mode 100644
index 000000000..7ea0c165f
--- /dev/null
+++ b/shared-module/_bleio/ScanResults.c
@@ -0,0 +1,139 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 Glenn Ruben Bakke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+
+#include "lib/utils/interrupt_char.h"
+#include "py/objstr.h"
+#include "py/runtime.h"
+#include "shared-bindings/_bleio/ScanEntry.h"
+#include "shared-bindings/_bleio/ScanResults.h"
+
+bleio_scanresults_obj_t* shared_module_bleio_new_scanresults(size_t buffer_size, uint8_t* prefixes, size_t prefixes_len, mp_int_t minimum_rssi) {
+ bleio_scanresults_obj_t* self = m_new_obj(bleio_scanresults_obj_t);
+ self->base.type = &bleio_scanresults_type;
+ ringbuf_alloc(&self->buf, buffer_size, false);
+ self->prefixes = prefixes;
+ self->prefix_length = prefixes_len;
+ self->minimum_rssi = minimum_rssi;
+ return self;
+}
+
+mp_obj_t common_hal_bleio_scanresults_next(bleio_scanresults_obj_t *self) {
+ while (ringbuf_count(&self->buf) == 0 && !self->done && !mp_hal_is_interrupted()) {
+ RUN_BACKGROUND_TASKS;
+ }
+ if (ringbuf_count(&self->buf) == 0 || mp_hal_is_interrupted()) {
+ return mp_const_none;
+ }
+
+ // Create a ScanEntry out of the data on the buffer.
+ uint8_t type = ringbuf_get(&self->buf);
+ bool connectable = (type & (1 << 0)) != 0;
+ bool scan_response = (type & (1 << 1)) != 0;
+ uint64_t ticks_ms;
+ ringbuf_get_n(&self->buf, (uint8_t*) &ticks_ms, sizeof(ticks_ms));
+ uint8_t rssi = ringbuf_get(&self->buf);
+ uint8_t peer_addr[NUM_BLEIO_ADDRESS_BYTES];
+ ringbuf_get_n(&self->buf, peer_addr, sizeof(peer_addr));
+ uint8_t addr_type = ringbuf_get(&self->buf);
+ uint16_t len;
+ ringbuf_get_n(&self->buf, (uint8_t*) &len, sizeof(len));
+
+ mp_obj_str_t *o = MP_OBJ_TO_PTR(mp_obj_new_bytes_of_zeros(len));
+ ringbuf_get_n(&self->buf, (uint8_t*) o->data, len);
+
+ bleio_scanentry_obj_t *entry = m_new_obj(bleio_scanentry_obj_t);
+ entry->base.type = &bleio_scanentry_type;
+ entry->rssi = rssi;
+
+ bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t);
+ address->base.type = &bleio_address_type;
+ common_hal_bleio_address_construct(MP_OBJ_TO_PTR(address), peer_addr, addr_type);
+ entry->address = address;
+
+ entry->data = o;
+ entry->time_received = ticks_ms;
+ entry->connectable = connectable;
+ entry->scan_response = scan_response;
+
+ return MP_OBJ_FROM_PTR(entry);
+}
+
+
+void shared_module_bleio_scanresults_append(bleio_scanresults_obj_t* self,
+ uint64_t ticks_ms,
+ bool connectable,
+ bool scan_response,
+ int8_t rssi,
+ uint8_t *peer_addr,
+ uint8_t addr_type,
+ uint8_t *data,
+ uint16_t len) {
+ int32_t packet_size = sizeof(uint8_t) + sizeof(ticks_ms) + sizeof(rssi) + NUM_BLEIO_ADDRESS_BYTES +
+ sizeof(addr_type) + sizeof(len) + len;
+ int32_t empty_space = self->buf.size - ringbuf_count(&self->buf);
+ if (packet_size >= empty_space) {
+ // We can't fit the packet so skip it.
+ return;
+ }
+ // Filter the packet.
+ if (rssi < self->minimum_rssi) {
+ return;
+ }
+
+ // If any prefixes are provided, then only include packets that include at least one of them.
+ if (!bleio_scanentry_data_matches(data, len, self->prefixes, self->prefix_length, true)) {
+ return;
+ }
+ uint8_t type = 0;
+ if (connectable) {
+ type |= 1 << 0;
+ }
+ if (scan_response) {
+ type |= 1 << 1;
+ }
+
+ // Add the packet to the buffer.
+ ringbuf_put(&self->buf, type);
+ ringbuf_put_n(&self->buf, (uint8_t*) &ticks_ms, sizeof(ticks_ms));
+ ringbuf_put(&self->buf, rssi);
+ ringbuf_put_n(&self->buf, peer_addr, NUM_BLEIO_ADDRESS_BYTES);
+ ringbuf_put(&self->buf, addr_type);
+ ringbuf_put_n(&self->buf, (uint8_t*) &len, sizeof(len));
+ ringbuf_put_n(&self->buf, data, len);
+}
+
+bool shared_module_bleio_scanresults_get_done(bleio_scanresults_obj_t* self) {
+ return self->done;
+}
+
+void shared_module_bleio_scanresults_set_done(bleio_scanresults_obj_t* self, bool done) {
+ self->done = done;
+ self->common_hal_data = NULL;
+}
diff --git a/shared-module/_bleio/ScanResults.h b/shared-module/_bleio/ScanResults.h
new file mode 100644
index 000000000..8912357a9
--- /dev/null
+++ b/shared-module/_bleio/ScanResults.h
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANRESULTS_H
+#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANRESULTS_H
+
+#include <stdint.h>
+
+#include "py/obj.h"
+#include "py/ringbuf.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ // Pointers that needs to live until the scan is done.
+ void* common_hal_data;
+ ringbuf_t buf;
+ // Prefixes is a length encoded array of prefixes.
+ uint8_t* prefixes;
+ size_t prefix_length;
+ mp_int_t minimum_rssi;
+ bool active;
+ bool done;
+} bleio_scanresults_obj_t;
+
+bleio_scanresults_obj_t* shared_module_bleio_new_scanresults(size_t buffer_size, uint8_t* prefixes, size_t prefixes_len, mp_int_t minimum_rssi);
+
+bool shared_module_bleio_scanresults_get_done(bleio_scanresults_obj_t* self);
+void shared_module_bleio_scanresults_set_done(bleio_scanresults_obj_t* self, bool done);
+
+void shared_module_bleio_scanresults_append(bleio_scanresults_obj_t* self,
+ uint64_t ticks_ms,
+ bool connectable,
+ bool scan_result,
+ int8_t rssi,
+ uint8_t *peer_addr,
+ uint8_t addr_type,
+ uint8_t* data,
+ uint16_t len);
+
+#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANRESULTS_H
diff --git a/shared-module/bitbangio/SPI.c b/shared-module/bitbangio/SPI.c
index 6d3a28523..d02adf34f 100644
--- a/shared-module/bitbangio/SPI.c
+++ b/shared-module/bitbangio/SPI.c
@@ -43,6 +43,8 @@ void shared_module_bitbangio_spi_construct(bitbangio_spi_obj_t *self,
if (result != DIGITALINOUT_OK) {
mp_raise_ValueError(translate("Clock pin init failed."));
}
+ common_hal_digitalio_digitalinout_switch_to_output(&self->clock, self->polarity == 1, DRIVE_MODE_PUSH_PULL);
+
if (mosi != mp_const_none) {
result = common_hal_digitalio_digitalinout_construct(&self->mosi, mosi);
if (result != DIGITALINOUT_OK) {
@@ -50,8 +52,11 @@ void shared_module_bitbangio_spi_construct(bitbangio_spi_obj_t *self,
mp_raise_ValueError(translate("MOSI pin init failed."));
}
self->has_mosi = true;
+ common_hal_digitalio_digitalinout_switch_to_output(&self->mosi, false, DRIVE_MODE_PUSH_PULL);
}
+
if (miso != mp_const_none) {
+ // Starts out as input by default, no need to change.
result = common_hal_digitalio_digitalinout_construct(&self->miso, miso);
if (result != DIGITALINOUT_OK) {
common_hal_digitalio_digitalinout_deinit(&self->clock);
diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c
index dd07d7190..914bc4313 100644
--- a/shared-module/board/__init__.c
+++ b/shared-module/board/__init__.c
@@ -101,7 +101,7 @@ mp_obj_t common_hal_board_create_uart(void) {
const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RX);
const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_TX);
- common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1000, 64);
+ common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1.0f, 64);
MP_STATE_VM(shared_uart_bus) = MP_OBJ_FROM_PTR(self);
return MP_STATE_VM(shared_uart_bus);
}
diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c
index 06b81f2f8..11db0f8ff 100644
--- a/shared-module/displayio/Display.c
+++ b/shared-module/displayio/Display.c
@@ -35,6 +35,7 @@
#include "shared-module/displayio/__init__.h"
#include "shared-module/displayio/display_core.h"
#include "supervisor/shared/display.h"
+#include "supervisor/shared/tick.h"
#include "supervisor/usb.h"
#include <stdint.h>
@@ -113,7 +114,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
if (result != PWMOUT_OK) {
self->backlight_inout.base.type = &digitalio_digitalinout_type;
common_hal_digitalio_digitalinout_construct(&self->backlight_inout, backlight_pin);
- never_reset_pin_number(backlight_pin->number);
+ common_hal_never_reset_pin(backlight_pin);
} else {
self->backlight_pwm.base.type = &pulseio_pwmout_type;
common_hal_pulseio_pwmout_never_reset(&self->backlight_pwm);
@@ -313,7 +314,7 @@ uint16_t common_hal_displayio_display_get_rotation(displayio_display_obj_t* self
bool common_hal_displayio_display_refresh(displayio_display_obj_t* self, uint32_t target_ms_per_frame, uint32_t maximum_ms_per_real_frame) {
if (!self->auto_refresh && !self->first_manual_refresh) {
- uint64_t current_time = ticks_ms;
+ uint64_t current_time = supervisor_ticks_ms64();
uint32_t current_ms_since_real_refresh = current_time - self->core.last_refresh;
// Test to see if the real frame time is below our minimum.
if (current_ms_since_real_refresh > maximum_ms_per_real_frame) {
@@ -327,7 +328,7 @@ bool common_hal_displayio_display_refresh(displayio_display_obj_t* self, uint32_
}
uint32_t remaining_time = target_ms_per_frame - (current_ms_since_real_refresh % target_ms_per_frame);
// We're ahead of the game so wait until we align with the frame rate.
- while (ticks_ms - self->last_refresh_call < remaining_time) {
+ while (supervisor_ticks_ms64() - self->last_refresh_call < remaining_time) {
RUN_BACKGROUND_TASKS;
}
}
@@ -350,20 +351,20 @@ STATIC void _update_backlight(displayio_display_obj_t* self) {
if (!self->auto_brightness || self->updating_backlight) {
return;
}
- if (ticks_ms - self->last_backlight_refresh < 100) {
+ if (supervisor_ticks_ms64() - self->last_backlight_refresh < 100) {
return;
}
// TODO(tannewt): Fade the backlight based on it's existing value and a target value. The target
// should account for ambient light when possible.
common_hal_displayio_display_set_brightness(self, 1.0);
- self->last_backlight_refresh = ticks_ms;
+ self->last_backlight_refresh = supervisor_ticks_ms64();
}
void displayio_display_background(displayio_display_obj_t* self) {
_update_backlight(self);
- if (self->auto_refresh && (ticks_ms - self->core.last_refresh) > self->native_ms_per_frame) {
+ if (self->auto_refresh && (supervisor_ticks_ms64() - self->core.last_refresh) > self->native_ms_per_frame) {
_refresh_display(self);
}
}
diff --git a/shared-module/displayio/EPaperDisplay.c b/shared-module/displayio/EPaperDisplay.c
index efbd9f3dd..91d4bb7f9 100644
--- a/shared-module/displayio/EPaperDisplay.c
+++ b/shared-module/displayio/EPaperDisplay.c
@@ -26,6 +26,7 @@
#include "shared-bindings/displayio/EPaperDisplay.h"
+#include "py/gc.h"
#include "py/runtime.h"
#include "shared-bindings/displayio/ColorConverter.h"
#include "shared-bindings/displayio/FourWire.h"
@@ -35,6 +36,7 @@
#include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/__init__.h"
#include "supervisor/shared/display.h"
+#include "supervisor/shared/tick.h"
#include "supervisor/usb.h"
#include <stdint.h>
@@ -82,7 +84,7 @@ void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t*
if (busy_pin != NULL) {
self->busy.base.type = &digitalio_digitalinout_type;
common_hal_digitalio_digitalinout_construct(&self->busy, busy_pin);
- never_reset_pin_number(busy_pin->number);
+ common_hal_never_reset_pin(busy_pin);
}
// Clear the color memory if it isn't in use.
@@ -175,7 +177,7 @@ uint32_t common_hal_displayio_epaperdisplay_get_time_to_refresh(displayio_epaper
return 0;
}
// Refresh at seconds per frame rate.
- uint32_t elapsed_time = ticks_ms - self->core.last_refresh;
+ uint32_t elapsed_time = supervisor_ticks_ms64() - self->core.last_refresh;
if (elapsed_time > self->milliseconds_per_frame) {
return 0;
}
@@ -298,7 +300,7 @@ bool displayio_epaperdisplay_refresh_area(displayio_epaperdisplay_obj_t* self, c
}
bool common_hal_displayio_epaperdisplay_refresh(displayio_epaperdisplay_obj_t* self) {
-
+
if (self->refreshing && self->busy.base.type == &digitalio_digitalinout_type) {
if (common_hal_digitalio_digitalinout_get_value(&self->busy) != self->busy_state) {
self->refreshing = false;
@@ -339,7 +341,7 @@ void displayio_epaperdisplay_background(displayio_epaperdisplay_obj_t* self) {
bool busy = common_hal_digitalio_digitalinout_get_value(&self->busy);
refresh_done = busy != self->busy_state;
} else {
- refresh_done = ticks_ms - self->core.last_refresh > self->refresh_time;
+ refresh_done = supervisor_ticks_ms64() - self->core.last_refresh > self->refresh_time;
}
if (refresh_done) {
self->refreshing = false;
@@ -365,6 +367,8 @@ void release_epaperdisplay(displayio_epaperdisplay_obj_t* self) {
void displayio_epaperdisplay_collect_ptrs(displayio_epaperdisplay_obj_t* self) {
displayio_display_core_collect_ptrs(&self->core);
+ gc_collect_ptr(self->start_sequence);
+ gc_collect_ptr(self->stop_sequence);
}
bool maybe_refresh_epaperdisplay(void) {
diff --git a/shared-module/displayio/FourWire.c b/shared-module/displayio/FourWire.c
index fcc4c1a20..92d4507dd 100644
--- a/shared-module/displayio/FourWire.c
+++ b/shared-module/displayio/FourWire.c
@@ -31,6 +31,7 @@
#include "py/gc.h"
#include "shared-bindings/busio/SPI.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/display_core.h"
@@ -61,12 +62,12 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self,
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_never_reset_pin(reset);
common_hal_displayio_fourwire_reset(self);
}
- never_reset_pin_number(command->number);
- never_reset_pin_number(chip_select->number);
+ common_hal_never_reset_pin(command);
+ common_hal_never_reset_pin(chip_select);
}
void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self) {
@@ -74,9 +75,9 @@ void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self) {
common_hal_busio_spi_deinit(self->bus);
}
- reset_pin_number(self->command.pin->number);
- reset_pin_number(self->chip_select.pin->number);
- reset_pin_number(self->reset.pin->number);
+ common_hal_reset_pin(self->command.pin);
+ common_hal_reset_pin(self->chip_select.pin);
+ common_hal_reset_pin(self->reset.pin);
}
bool common_hal_displayio_fourwire_reset(mp_obj_t obj) {
diff --git a/shared-module/displayio/I2CDisplay.c b/shared-module/displayio/I2CDisplay.c
index d9452dc50..280476f19 100644
--- a/shared-module/displayio/I2CDisplay.c
+++ b/shared-module/displayio/I2CDisplay.c
@@ -33,6 +33,7 @@
#include "py/runtime.h"
#include "shared-bindings/busio/I2C.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/display_core.h"
@@ -42,12 +43,22 @@
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) {
+ // Reset the display before probing
+ self->reset.base.type = &mp_type_NoneType;
+ if (reset != NULL) {
+ self->reset.base.type = &digitalio_digitalinout_type;
+ common_hal_digitalio_digitalinout_construct(&self->reset, reset);
+ common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL);
+ common_hal_never_reset_pin(reset);
+ common_hal_displayio_i2cdisplay_reset(self);
+ }
+
// 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
+ // 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
@@ -55,15 +66,6 @@ void common_hal_displayio_i2cdisplay_construct(displayio_i2cdisplay_obj_t* self,
gc_never_free(self->bus);
self->address = device_address;
-
- self->reset.base.type = &mp_type_NoneType;
- if (reset != NULL) {
- self->reset.base.type = &digitalio_digitalinout_type;
- common_hal_digitalio_digitalinout_construct(&self->reset, reset);
- common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL);
- never_reset_pin_number(reset->number);
- common_hal_displayio_i2cdisplay_reset(self);
- }
}
void common_hal_displayio_i2cdisplay_deinit(displayio_i2cdisplay_obj_t* self) {
@@ -71,7 +73,7 @@ void common_hal_displayio_i2cdisplay_deinit(displayio_i2cdisplay_obj_t* self) {
common_hal_busio_i2c_deinit(self->bus);
}
- reset_pin_number(self->reset.pin->number);
+ common_hal_reset_pin(self->reset.pin);
}
bool common_hal_displayio_i2cdisplay_reset(mp_obj_t obj) {
diff --git a/shared-module/displayio/display_core.c b/shared-module/displayio/display_core.c
index a73ea81d1..658daa8d6 100644
--- a/shared-module/displayio/display_core.c
+++ b/shared-module/displayio/display_core.c
@@ -35,6 +35,7 @@
#include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/__init__.h"
#include "supervisor/shared/display.h"
+#include "supervisor/shared/tick.h"
#include <stdint.h>
#include <string.h>
@@ -281,7 +282,7 @@ void displayio_display_core_set_region_to_update(displayio_display_core_t* self,
}
void displayio_display_core_start_refresh(displayio_display_core_t* self) {
- self->last_refresh = ticks_ms;
+ self->last_refresh = supervisor_ticks_ms64();
}
void displayio_display_core_finish_refresh(displayio_display_core_t* self) {
@@ -289,7 +290,7 @@ void displayio_display_core_finish_refresh(displayio_display_core_t* self) {
displayio_group_finish_refresh(self->current_group);
}
self->full_refresh = false;
- self->last_refresh = ticks_ms;
+ self->last_refresh = supervisor_ticks_ms64();
}
void release_display_core(displayio_display_core_t* self) {
diff --git a/shared-module/network/__init__.c b/shared-module/network/__init__.c
index 96648b260..925e9a2a3 100644
--- a/shared-module/network/__init__.c
+++ b/shared-module/network/__init__.c
@@ -31,6 +31,8 @@
#include "py/mphal.h"
#include "py/mperrno.h"
+#include "supervisor/shared/tick.h"
+
#include "shared-bindings/random/__init__.h"
#include "shared-module/network/__init__.h"
@@ -53,7 +55,7 @@ void network_module_deinit(void) {
void network_module_background(void) {
static uint32_t next_tick = 0;
- uint32_t this_tick = ticks_ms;
+ uint32_t this_tick = supervisor_ticks_ms32();
if (this_tick < next_tick) return;
next_tick = this_tick + 1000;
diff --git a/shared-module/usb_hid/Device.c b/shared-module/usb_hid/Device.c
index bed7d163f..8744f2ed3 100644
--- a/shared-module/usb_hid/Device.c
+++ b/shared-module/usb_hid/Device.c
@@ -30,6 +30,7 @@
#include "shared-bindings/usb_hid/Device.h"
#include "shared-module/usb_hid/Device.h"
#include "supervisor/shared/translate.h"
+#include "supervisor/shared/tick.h"
#include "tusb.h"
uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self) {
@@ -46,8 +47,8 @@ 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_ready() ) {
+ uint64_t end_ticks = supervisor_ticks_ms64() + 2000;
+ while ( (supervisor_ticks_ms64() < end_ticks) && !tud_hid_ready() ) {
RUN_BACKGROUND_TASKS;
}
diff --git a/supervisor/port.h b/supervisor/port.h
index 1430c6a50..c8a011978 100644
--- a/supervisor/port.h
+++ b/supervisor/port.h
@@ -54,6 +54,12 @@ void reset_board(void);
// Reset to the bootloader
void reset_to_bootloader(void);
+// Get stack limit address
+uint32_t *port_stack_get_limit(void);
+
+// Get stack top address
+uint32_t *port_stack_get_top(void);
+
// Save and retrieve a word from memory that is preserved over reset. Used for safe mode.
void port_set_saved_word(uint32_t);
uint32_t port_get_saved_word(void);
diff --git a/supervisor/shared/autoreload.c b/supervisor/shared/autoreload.c
index 14b21902c..a6212c1a9 100644
--- a/supervisor/shared/autoreload.c
+++ b/supervisor/shared/autoreload.c
@@ -76,3 +76,11 @@ void autoreload_stop() {
autoreload_delay_ms = 0;
reload_requested = false;
}
+
+void autoreload_now() {
+ if (!autoreload_enabled || autoreload_suspended || reload_requested) {
+ return;
+ }
+ mp_raise_reload_exception();
+ reload_requested = true;
+}
diff --git a/supervisor/shared/autoreload.h b/supervisor/shared/autoreload.h
index bcb100151..fbd482c19 100644
--- a/supervisor/shared/autoreload.h
+++ b/supervisor/shared/autoreload.h
@@ -43,4 +43,6 @@ bool autoreload_is_enabled(void);
void autoreload_suspend(void);
void autoreload_resume(void);
+void autoreload_now(void);
+
#endif // MICROPY_INCLUDED_SUPERVISOR_AUTORELOAD_H
diff --git a/supervisor/shared/bluetooth.c b/supervisor/shared/bluetooth.c
new file mode 100644
index 000000000..02258de74
--- /dev/null
+++ b/supervisor/shared/bluetooth.c
@@ -0,0 +1,340 @@
+/*
+ * 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 <string.h>
+
+#include "extmod/vfs.h"
+#include "extmod/vfs_fat.h"
+
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Adapter.h"
+#include "shared-bindings/_bleio/Characteristic.h"
+#include "shared-bindings/_bleio/Service.h"
+#include "shared-bindings/_bleio/UUID.h"
+
+#include "common-hal/_bleio/__init__.h"
+
+#include "supervisor/shared/autoreload.h"
+
+#include "py/mpstate.h"
+
+bleio_service_obj_t supervisor_ble_service;
+bleio_uuid_obj_t supervisor_ble_service_uuid;
+bleio_characteristic_obj_t supervisor_ble_version_characteristic;
+bleio_uuid_obj_t supervisor_ble_version_uuid;
+bleio_characteristic_obj_t supervisor_ble_filename_characteristic;
+bleio_uuid_obj_t supervisor_ble_filename_uuid;
+bleio_characteristic_obj_t supervisor_ble_length_characteristic;
+bleio_uuid_obj_t supervisor_ble_length_uuid;
+bleio_characteristic_obj_t supervisor_ble_contents_characteristic;
+bleio_uuid_obj_t supervisor_ble_contents_uuid;
+const uint8_t circuitpython_base_uuid[16] = {0x6e, 0x68, 0x74, 0x79, 0x50, 0x74, 0x69, 0x75, 0x63, 0x72, 0x69, 0x43, 0x00, 0x00, 0xaf, 0xad };
+uint8_t circuitpython_advertising_data[] = { 0x02, 0x01, 0x06, 0x02, 0x0a, 0x00, 0x11, 0x07, 0x6e, 0x68, 0x74, 0x79, 0x50, 0x74, 0x69, 0x75, 0x63, 0x72, 0x69, 0x43, 0x00, 0x01, 0xaf, 0xad, 0x06, 0x08, 0x43, 0x49, 0x52, 0x43, 0x55 };
+uint8_t circuitpython_scan_response_data[15] = {0x0e, 0x09, 0x43, 0x49, 0x52, 0x43, 0x55, 0x49, 0x54, 0x50, 0x59, 0x00, 0x00, 0x00, 0x00};
+mp_obj_list_t service_list;
+mp_obj_t service_list_items[1];
+mp_obj_list_t characteristic_list;
+mp_obj_t characteristic_list_items[4];
+
+void supervisor_bluetooth_start_advertising(void) {
+ bool is_connected = common_hal_bleio_adapter_get_connected(&common_hal_bleio_adapter_obj);
+ if (is_connected) {
+ return;
+ }
+ // TODO: switch to Adafruit short UUID for the advertisement and add manufacturing data to distinguish ourselves from arduino.
+ _common_hal_bleio_adapter_start_advertising(&common_hal_bleio_adapter_obj,
+ true,
+ 1.0,
+ circuitpython_advertising_data,
+ sizeof(circuitpython_advertising_data),
+ circuitpython_scan_response_data,
+ sizeof(circuitpython_scan_response_data));
+}
+
+void supervisor_start_bluetooth(void) {
+ common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, true);
+
+ supervisor_ble_service_uuid.base.type = &bleio_uuid_type;
+ common_hal_bleio_uuid_construct(&supervisor_ble_service_uuid, 0x0100, circuitpython_base_uuid);
+
+ // We know we'll only be 1 characteristic so we can statically allocate it.
+ characteristic_list.base.type = &mp_type_list;
+ characteristic_list.alloc = sizeof(characteristic_list_items) / sizeof(characteristic_list_items[0]);
+ characteristic_list.len = 0;
+ characteristic_list.items = characteristic_list_items;
+ mp_seq_clear(characteristic_list.items, 0, characteristic_list.alloc, sizeof(*characteristic_list.items));
+
+ _common_hal_bleio_service_construct(&supervisor_ble_service, &supervisor_ble_service_uuid, false /* is secondary */, &characteristic_list);
+
+ // File length
+ supervisor_ble_version_uuid.base.type = &bleio_uuid_type;
+ common_hal_bleio_uuid_construct(&supervisor_ble_version_uuid, 0x0203, circuitpython_base_uuid);
+ common_hal_bleio_characteristic_construct(&supervisor_ble_version_characteristic,
+ &supervisor_ble_service,
+ 0, // handle (for remote only)
+ &supervisor_ble_version_uuid,
+ CHAR_PROP_READ,
+ SECURITY_MODE_OPEN,
+ SECURITY_MODE_NO_ACCESS,
+ 4, // max length
+ true, // fixed length
+ NULL); // no initial value
+
+ uint32_t version = 1;
+ mp_buffer_info_t bufinfo;
+ bufinfo.buf = &version;
+ bufinfo.len = sizeof(version);
+ common_hal_bleio_characteristic_set_value(&supervisor_ble_version_characteristic, &bufinfo);
+
+ // Active filename.
+ supervisor_ble_filename_uuid.base.type = &bleio_uuid_type;
+ common_hal_bleio_uuid_construct(&supervisor_ble_filename_uuid, 0x0200, circuitpython_base_uuid);
+ common_hal_bleio_characteristic_construct(&supervisor_ble_filename_characteristic,
+ &supervisor_ble_service,
+ 0, // handle (for remote only)
+ &supervisor_ble_filename_uuid,
+ CHAR_PROP_READ | CHAR_PROP_WRITE,
+ SECURITY_MODE_OPEN,
+ SECURITY_MODE_OPEN,
+ 500, // max length
+ false, // fixed length
+ NULL); // no initial value
+
+ char code_py[] = "/code.py";
+ bufinfo.buf = code_py;
+ bufinfo.len = sizeof(code_py);
+ common_hal_bleio_characteristic_set_value(&supervisor_ble_filename_characteristic, &bufinfo);
+
+ // File length
+ supervisor_ble_length_uuid.base.type = &bleio_uuid_type;
+ common_hal_bleio_uuid_construct(&supervisor_ble_length_uuid, 0x0202, circuitpython_base_uuid);
+ common_hal_bleio_characteristic_construct(&supervisor_ble_length_characteristic,
+ &supervisor_ble_service,
+ 0, // handle (for remote only)
+ &supervisor_ble_length_uuid,
+ CHAR_PROP_NOTIFY | CHAR_PROP_READ,
+ SECURITY_MODE_OPEN,
+ SECURITY_MODE_NO_ACCESS,
+ 4, // max length
+ true, // fixed length
+ NULL); // no initial value
+
+ // File actions
+ supervisor_ble_contents_uuid.base.type = &bleio_uuid_type;
+ common_hal_bleio_uuid_construct(&supervisor_ble_contents_uuid, 0x0201, circuitpython_base_uuid);
+ common_hal_bleio_characteristic_construct(&supervisor_ble_contents_characteristic,
+ &supervisor_ble_service,
+ 0, // handle (for remote only)
+ &supervisor_ble_contents_uuid,
+ CHAR_PROP_NOTIFY | CHAR_PROP_WRITE_NO_RESPONSE | CHAR_PROP_WRITE,
+ SECURITY_MODE_OPEN,
+ SECURITY_MODE_OPEN,
+ 500, // max length
+ false, // fixed length
+ NULL); // no initial value
+
+ supervisor_bluetooth_start_advertising();
+ vm_used_ble = false;
+}
+
+FIL active_file;
+volatile bool new_filename;
+volatile bool run_ble_background;
+bool was_connected;
+
+void update_file_length(void) {
+ int32_t file_length = -1;
+ mp_buffer_info_t bufinfo;
+ bufinfo.buf = &file_length;
+ bufinfo.len = sizeof(file_length);
+ if (active_file.obj.fs != 0) {
+ file_length = (int32_t) f_size(&active_file);
+ }
+ common_hal_bleio_characteristic_set_value(&supervisor_ble_length_characteristic, &bufinfo);
+}
+
+void open_current_file(void) {
+ if (active_file.obj.fs != 0) {
+ return;
+ }
+ uint16_t max_len = supervisor_ble_filename_characteristic.max_length;
+ uint8_t path[max_len];
+ size_t length = common_hal_bleio_characteristic_get_value(&supervisor_ble_filename_characteristic, path, max_len - 1);
+ path[length] = '\0';
+
+ FATFS *fs = &((fs_user_mount_t *) MP_STATE_VM(vfs_mount_table)->obj)->fatfs;
+ f_open(fs, &active_file, (char*) path, FA_READ | FA_WRITE);
+
+ update_file_length();
+}
+
+void close_current_file(void) {
+ f_close(&active_file);
+}
+
+uint32_t current_command[1024 / sizeof(uint32_t)];
+volatile size_t current_offset;
+
+void supervisor_bluetooth_background(void) {
+ if (!run_ble_background) {
+ return;
+ }
+ bool is_connected = common_hal_bleio_adapter_get_connected(&common_hal_bleio_adapter_obj);
+ if (!was_connected && is_connected) {
+ open_current_file();
+ } else if (was_connected && !is_connected) {
+ close_current_file();
+ new_filename = false;
+ }
+ was_connected = is_connected;
+ run_ble_background = false;
+ if (!is_connected) {
+ supervisor_bluetooth_start_advertising();
+ return;
+ }
+ if (new_filename) {
+ close_current_file();
+ open_current_file();
+
+ new_filename = false;
+ // get length and set the characteristic for it
+ }
+ uint16_t current_length = ((uint16_t*) current_command)[0];
+ if (current_length > 0 && current_length == current_offset) {
+ uint16_t command = ((uint16_t *) current_command)[1];
+
+ if (command == 1) {
+ uint16_t max_len = 20; //supervisor_ble_contents_characteristic.max_length;
+ uint8_t buf[max_len];
+ mp_buffer_info_t bufinfo;
+ bufinfo.buf = buf;
+ f_lseek(&active_file, 0);
+ while (f_read(&active_file, buf, max_len, &bufinfo.len) == FR_OK) {
+ if (bufinfo.len == 0) {
+ break;
+ }
+ common_hal_bleio_characteristic_set_value(&supervisor_ble_contents_characteristic, &bufinfo);
+ }
+ } else if (command == 2) { // patch
+ uint32_t offset = current_command[1];
+ uint32_t remove_length = current_command[2];
+ uint32_t insert_length = current_command[3];
+ uint32_t file_length = (int32_t) f_size(&active_file);
+ //uint32_t data_shift_length = fileLength - offset - remove_length;
+ int32_t data_shift = insert_length - remove_length;
+ uint32_t new_length = file_length + data_shift;
+
+ // TODO: Make these loops smarter to read and write on sector boundaries.
+ if (data_shift < 0) {
+ for (uint32_t shift_offset = offset + insert_length; shift_offset < new_length; shift_offset++) {
+ uint8_t data;
+ UINT actual;
+ f_lseek(&active_file, shift_offset - data_shift);
+ f_read(&active_file, &data, 1, &actual);
+ f_lseek(&active_file, shift_offset);
+ f_write(&active_file, &data, 1, &actual);
+ }
+ f_truncate(&active_file);
+ } else if (data_shift > 0) {
+ f_lseek(&active_file, file_length);
+ // Fill end with 0xff so we don't need to erase.
+ uint8_t data = 0xff;
+ for (size_t i = 0; i < (size_t) data_shift; i++) {
+ UINT actual;
+ f_write(&active_file, &data, 1, &actual);
+ }
+ for (uint32_t shift_offset = new_length - 1; shift_offset >= offset + insert_length ; shift_offset--) {
+ UINT actual;
+ f_lseek(&active_file, shift_offset - data_shift);
+ f_read(&active_file, &data, 1, &actual);
+ f_lseek(&active_file, shift_offset);
+ f_write(&active_file, &data, 1, &actual);
+ }
+ }
+
+ f_lseek(&active_file, offset);
+ uint8_t* data = (uint8_t *) (current_command + 4);
+ UINT written;
+ f_write(&active_file, data, insert_length, &written);
+ f_sync(&active_file);
+ // Notify the new file length.
+ update_file_length();
+
+ // Trigger an autoreload
+ autoreload_now();
+ }
+ current_offset = 0;
+ }
+}
+
+// This happens in an interrupt so we need to be quick.
+bool supervisor_bluetooth_hook(ble_evt_t *ble_evt) {
+ // Catch writes to filename or contents. Length is read-only.
+
+ bool done = false;
+ switch (ble_evt->header.evt_id) {
+ case BLE_GAP_EVT_CONNECTED:
+ // We run our background task even if it wasn't us connected to because we may want to
+ // advertise if the user code stopped advertising.
+ run_ble_background = true;
+ break;
+ case BLE_GAP_EVT_DISCONNECTED:
+ run_ble_background = true;
+ break;
+ case BLE_GATTS_EVT_WRITE: {
+ // A client wrote to a 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 == supervisor_ble_contents_characteristic.handle) {
+ // Handle events
+ //write_to_ringbuf(self, evt_write->data, evt_write->len);
+ // First packet includes a uint16_t le for length at the start.
+ uint16_t current_length = ((uint16_t*) current_command)[0];
+ memcpy(((uint8_t*) current_command) + current_offset, evt_write->data, evt_write->len);
+ current_offset += evt_write->len;
+ current_length = ((uint16_t*) current_command)[0];
+ if (current_offset == current_length) {
+ run_ble_background = true;
+ done = true;
+ }
+ } else if (evt_write->handle == supervisor_ble_filename_characteristic.handle) {
+ new_filename = true;
+ run_ble_background = true;
+ done = true;
+ } else {
+ return done;
+ }
+ break;
+ }
+
+ default:
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Unhandled peripheral event: 0x%04x\n", ble_evt->header.evt_id);
+ break;
+ }
+ return done;
+}
diff --git a/supervisor/shared/bluetooth.h b/supervisor/shared/bluetooth.h
new file mode 100644
index 000000000..7ebcb953f
--- /dev/null
+++ b/supervisor/shared/bluetooth.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SUPERVISOR_SHARED_BLUETOOTH_H
+#define MICROPY_INCLUDED_SUPERVISOR_SHARED_BLUETOOTH_H
+
+void supervisor_start_bluetooth(void);
+bool supervisor_bluetooth_hook(ble_evt_t *ble_evt);
+void supervisor_bluetooth_background(void);
+
+#endif \ No newline at end of file
diff --git a/supervisor/shared/external_flash/devices.h b/supervisor/shared/external_flash/devices.h
index 05091ad8c..08d0a78fd 100644
--- a/supervisor/shared/external_flash/devices.h
+++ b/supervisor/shared/external_flash/devices.h
@@ -300,6 +300,23 @@ typedef struct {
.write_status_register_split = false, \
}
+// Settings for the Winbond W25Q32JV-IQ 4MiB SPI flash.
+// Datasheet: https://www.mouser.com/datasheet/2/949/w25q32jv_revg_03272018_plus-1489806.pdf
+#define W25Q32JV_IQ {\
+ .total_size = (1 << 22), /* 4 MiB */ \
+ .start_up_time_us = 5000, \
+ .manufacturer_id = 0xef, \
+ .memory_type = 0x40, \
+ .capacity = 0x16, \
+ .max_clock_speed_mhz = 133, \
+ .quad_enable_bit_mask = 0x02, \
+ .has_sector_protection = false, \
+ .supports_fast_read = true, \
+ .supports_qspi = true, \
+ .supports_qspi_writes = true, \
+ .write_status_register_split = false, \
+}
+
// Settings for the Winbond W25Q64JV-IM 8MiB SPI flash. Note that JV-IQ has a different .memory_type (0x40)
// Datasheet: http://www.winbond.com/resource-files/w25q64jv%20revj%2003272018%20plus.pdf
#define W25Q64JV_IM {\
diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c
index c50d7f4ee..92727f6fb 100644
--- a/supervisor/shared/filesystem.c
+++ b/supervisor/shared/filesystem.c
@@ -69,6 +69,19 @@ static void make_empty_file(FATFS *fatfs, const char *path) {
f_close(&fp);
}
+
+static void make_sample_code_file(FATFS *fatfs) {
+ #if CIRCUITPY_FULL_BUILD
+ FIL fs;
+ UINT char_written = 0;
+ const byte buffer[] = "print('Hello World!')\n";
+ //Create or modify existing code.py file
+ f_open(fatfs, &fs, "/code.py", FA_WRITE | FA_CREATE_ALWAYS);
+ f_write(&fs, buffer, sizeof(buffer) - 1, &char_written);
+ f_close(&fs);
+ #endif
+}
+
// we don't make this function static because it needs a lot of stack and we
// want it to be executed without using stack within main() function
void filesystem_init(bool create_allowed, bool force_create) {
@@ -98,6 +111,8 @@ void filesystem_init(bool create_allowed, bool force_create) {
make_empty_file(&vfs_fat->fatfs, "/.metadata_never_index");
make_empty_file(&vfs_fat->fatfs, "/.Trashes");
make_empty_file(&vfs_fat->fatfs, "/.fseventsd/no_log");
+ // make a sample code.py file
+ make_sample_code_file(&vfs_fat->fatfs);
// create empty lib directory
f_mkdir(&vfs_fat->fatfs, "/lib");
diff --git a/supervisor/shared/memory.c b/supervisor/shared/memory.c
index 11133415d..38040d11d 100755
--- a/supervisor/shared/memory.c
+++ b/supervisor/shared/memory.c
@@ -25,6 +25,7 @@
*/
#include "supervisor/memory.h"
+#include "supervisor/port.h"
#include <stddef.h>
@@ -36,12 +37,10 @@ static supervisor_allocation allocations[CIRCUITPY_SUPERVISOR_ALLOC_COUNT];
// We use uint32_t* to ensure word (4 byte) alignment.
uint32_t* low_address;
uint32_t* high_address;
-extern uint32_t _ebss;
-extern uint32_t _estack;
void memory_init(void) {
- low_address = &_ebss;
- high_address = &_estack;
+ low_address = port_stack_get_limit();
+ high_address = port_stack_get_top();
}
void free_memory(supervisor_allocation* allocation) {
diff --git a/supervisor/shared/rgb_led_colors.h b/supervisor/shared/rgb_led_colors.h
index 48994ad62..c723fbab3 100644
--- a/supervisor/shared/rgb_led_colors.h
+++ b/supervisor/shared/rgb_led_colors.h
@@ -1,12 +1,18 @@
-#define BLACK 0x000000
-#define GREEN 0x003000
-#define BLUE 0x000030
-#define CYAN 0x003030
-#define RED 0x300000
-#define ORANGE 0x302000
-#define YELLOW 0x303000
-#define PURPLE 0x300030
-#define WHITE 0x303030
+
+#define COLOR(r, g, b) (((r) << 16) | ((g) << 8) | (b))
+// For brightness == 255 (full). This will be adjusted downward for various different RGB indicators,
+// which vary in brightness.
+#define INTENSITY (0x30)
+
+#define BLACK COLOR(0, 0, 0)
+#define GREEN COLOR(0, INTENSITY, 0)
+#define BLUE COLOR(0, 0, INTENSITY)
+#define CYAN COLOR(0, INTENSITY, INTENSITY)
+#define RED COLOR(INTENSITY, 0, 0)
+#define ORANGE COLOR(INTENSITY, INTENSITY*2/3, 0)
+#define YELLOW COLOR(INTENSITY, INTENSITY, 0)
+#define PURPLE COLOR(INTENSITY, 0, INTENSITY)
+#define WHITE COLOR(INTENSITY, INTENSITY, INTENSITY)
#define BOOT_RUNNING BLUE
#define MAIN_RUNNING GREEN
diff --git a/supervisor/shared/rgb_led_status.c b/supervisor/shared/rgb_led_status.c
index 4d9371516..f751a7ffd 100644
--- a/supervisor/shared/rgb_led_status.c
+++ b/supervisor/shared/rgb_led_status.c
@@ -25,8 +25,9 @@
*/
#include "mphalport.h"
-#include "common-hal/microcontroller/Pin.h"
+#include "shared-bindings/microcontroller/Pin.h"
#include "rgb_led_status.h"
+#include "supervisor/shared/tick.h"
#ifdef MICROPY_HW_NEOPIXEL
uint8_t rgb_status_brightness = 63;
@@ -38,7 +39,7 @@ static digitalio_digitalinout_obj_t status_neopixel;
#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
-uint8_t rgb_status_brightness = 255;
+uint8_t rgb_status_brightness = 50;
#define APA102_BUFFER_LENGTH 12
static uint8_t status_apa102_color[APA102_BUFFER_LENGTH] = {0, 0, 0, 0, 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0xff};
@@ -46,10 +47,18 @@ static uint8_t status_apa102_color[APA102_BUFFER_LENGTH] = {0, 0, 0, 0, 0xff, 0,
#if CIRCUITPY_BITBANG_APA102
#include "shared-bindings/bitbangio/SPI.h"
#include "shared-module/bitbangio/types.h"
-static bitbangio_spi_obj_t status_apa102;
+static bitbangio_spi_obj_t status_apa102 = {
+ .base = {
+ .type = &bitbangio_spi_type,
+ },
+};
#else
#include "shared-bindings/busio/SPI.h"
-busio_spi_obj_t status_apa102;
+busio_spi_obj_t status_apa102 = {
+ .base = {
+ .type = &busio_spi_type,
+ },
+};
#endif
#endif
@@ -59,9 +68,21 @@ busio_spi_obj_t status_apa102;
#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;
+pulseio_pwmout_obj_t rgb_status_r = {
+ .base = {
+ .type = &pulseio_pwmout_type,
+ },
+};
+pulseio_pwmout_obj_t rgb_status_g = {
+ .base = {
+ .type = &pulseio_pwmout_type,
+ },
+};
+pulseio_pwmout_obj_t rgb_status_b = {
+ .base = {
+ .type = &pulseio_pwmout_type,
+ },
+};
uint8_t rgb_status_brightness = 0xFF;
@@ -74,8 +95,14 @@ uint16_t status_rgb_color[3] = {
static uint32_t current_status_color = 0;
#endif
-
+static bool rgb_led_status_init_in_progress = false;
void rgb_led_status_init() {
+ if (rgb_led_status_init_in_progress) {
+ // Avoid recursion.
+ return;
+ }
+ rgb_led_status_init_in_progress = true;
+
#ifdef MICROPY_HW_NEOPIXEL
common_hal_digitalio_digitalinout_construct(&status_neopixel, MICROPY_HW_NEOPIXEL);
// Pretend we aren't using the pins. digitalio.DigitalInOut
@@ -91,15 +118,15 @@ void rgb_led_status_init() {
mp_const_none);
#else
if (!common_hal_busio_spi_deinited(&status_apa102)) {
- // Don't use spi_deinit because that leads to infinite
- // recursion because reset_pin_number may call
- // rgb_led_status_init.
- spi_m_sync_disable(&status_apa102.spi_desc);
+ // This may call us recursively if common_hal_reset_pin() is called,
+ // The rgb_led_status_init_in_progress guard will prevent further recursion.
+ common_hal_busio_spi_deinit(&status_apa102);
}
common_hal_busio_spi_construct(&status_apa102,
MICROPY_HW_APA102_SCK,
MICROPY_HW_APA102_MOSI,
mp_const_none);
+ common_hal_busio_spi_never_reset(&status_apa102);
#endif
// Pretend we aren't using the pins. bitbangio.SPI will
// mark them as used.
@@ -149,15 +176,17 @@ void rgb_led_status_init() {
current_status_color = 0x1000000; // Not a valid color
new_status_color(rgb);
#endif
+
+ rgb_led_status_init_in_progress = false;
}
void reset_status_led() {
#ifdef MICROPY_HW_NEOPIXEL
- reset_pin_number(MICROPY_HW_NEOPIXEL->number);
+ common_hal_reset_pin(MICROPY_HW_NEOPIXEL);
#endif
#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
- reset_pin_number(MICROPY_HW_APA102_MOSI->number);
- reset_pin_number(MICROPY_HW_APA102_SCK->number);
+ common_hal_reset_pin(MICROPY_HW_APA102_MOSI);
+ common_hal_reset_pin(MICROPY_HW_APA102_SCK);
#endif
#if defined(CP_RGB_STATUS_LED)
// TODO: Support sharing status LED with user.
@@ -332,7 +361,7 @@ void prep_rgb_status_animation(const pyexec_result_t* result,
rgb_status_animation_t* status) {
#if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
new_status_color(ALL_DONE);
- status->pattern_start = ticks_ms;
+ status->pattern_start = supervisor_ticks_ms32();
status->safe_mode = safe_mode;
status->found_main = found_main;
status->total_exception_cycle = 0;
@@ -377,11 +406,11 @@ 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)) || (defined(CP_RGB_STATUS_LED))
- uint32_t tick_diff = ticks_ms - status->pattern_start;
+ uint32_t tick_diff = supervisor_ticks_ms32() - status->pattern_start;
if (status->ok) {
// All is good. Ramp ALL_DONE up and down.
if (tick_diff > ALL_GOOD_CYCLE_MS) {
- status->pattern_start = ticks_ms;
+ status->pattern_start = supervisor_ticks_ms32();
tick_diff = 0;
}
@@ -396,7 +425,7 @@ void tick_rgb_status_animation(rgb_status_animation_t* status) {
}
} else {
if (tick_diff > status->total_exception_cycle) {
- status->pattern_start = ticks_ms;
+ status->pattern_start = supervisor_ticks_ms32();
tick_diff = 0;
}
// First flash the file color.
diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c
index d8d3ab379..363181da0 100644
--- a/supervisor/shared/safe_mode.c
+++ b/supervisor/shared/safe_mode.c
@@ -34,6 +34,7 @@
#include "supervisor/shared/rgb_led_colors.h"
#include "supervisor/shared/rgb_led_status.h"
#include "supervisor/shared/translate.h"
+#include "supervisor/shared/tick.h"
#define SAFE_MODE_DATA_GUARD 0xad0000af
#define SAFE_MODE_DATA_GUARD_MASK 0xff0000ff
@@ -59,14 +60,14 @@ safe_mode_t wait_for_safe_mode_reset(void) {
common_hal_digitalio_digitalinout_construct(&status_led, MICROPY_HW_LED_STATUS);
common_hal_digitalio_digitalinout_switch_to_output(&status_led, true, DRIVE_MODE_PUSH_PULL);
#endif
- uint64_t start_ticks = ticks_ms;
+ uint64_t start_ticks = supervisor_ticks_ms64();
uint64_t diff = 0;
while (diff < 700) {
#ifdef MICROPY_HW_LED_STATUS
// Blink on for 100, off for 100, on for 100, off for 100 and on for 200
common_hal_digitalio_digitalinout_set_value(&status_led, diff > 100 && diff / 100 != 2 && diff / 100 != 4);
#endif
- diff = ticks_ms - start_ticks;
+ diff = supervisor_ticks_ms64() - start_ticks;
}
#ifdef MICROPY_HW_LED_STATUS
common_hal_digitalio_digitalinout_deinit(&status_led);
diff --git a/supervisor/shared/safe_mode.h b/supervisor/shared/safe_mode.h
index ee0723cff..8c5dcd9c5 100644
--- a/supervisor/shared/safe_mode.h
+++ b/supervisor/shared/safe_mode.h
@@ -37,7 +37,8 @@ typedef enum {
MICROPY_NLR_JUMP_FAIL,
MICROPY_FATAL_ERROR,
GC_ALLOC_OUTSIDE_VM,
- PROGRAMMATIC_SAFE_MODE
+ PROGRAMMATIC_SAFE_MODE,
+ NORDIC_SOFT_DEVICE_ASSERT
} safe_mode_t;
safe_mode_t wait_for_safe_mode_reset(void);
diff --git a/supervisor/shared/stack.c b/supervisor/shared/stack.c
index 311fa31b2..dcecf2067 100755
--- a/supervisor/shared/stack.c
+++ b/supervisor/shared/stack.c
@@ -29,6 +29,7 @@
#include "py/mpconfig.h"
#include "py/runtime.h"
#include "supervisor/cpu.h"
+#include "supervisor/port.h"
#include "supervisor/shared/safe_mode.h"
extern uint32_t _estack;
@@ -43,7 +44,7 @@ void allocate_stack(void) {
mp_uint_t regs[10];
mp_uint_t sp = cpu_get_regs_and_sp(regs);
- mp_uint_t c_size = (uint32_t) &_estack - sp;
+ mp_uint_t c_size = (uint32_t) port_stack_get_top() - sp;
stack_alloc = allocate_memory(c_size + next_stack_size + EXCEPTION_STACK_SIZE, true);
if (stack_alloc == NULL) {
diff --git a/supervisor/shared/tick.c b/supervisor/shared/tick.c
new file mode 100644
index 000000000..69256081c
--- /dev/null
+++ b/supervisor/shared/tick.c
@@ -0,0 +1,94 @@
+/*
+ * 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 "supervisor/shared/tick.h"
+#include "supervisor/filesystem.h"
+#include "supervisor/shared/autoreload.h"
+
+static volatile uint64_t ticks_ms;
+static volatile uint32_t background_ticks_ms32;
+
+#if CIRCUITPY_GAMEPAD
+#include "shared-module/gamepad/__init__.h"
+#endif
+
+#if CIRCUITPY_GAMEPADSHIFT
+#include "shared-module/gamepadshift/__init__.h"
+#endif
+
+#include "shared-bindings/microcontroller/__init__.h"
+
+void supervisor_tick(void) {
+
+ ticks_ms ++;
+
+#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)) {
+ #if CIRCUITPY_GAMEPAD
+ gamepad_tick();
+ #endif
+ #if CIRCUITPY_GAMEPADSHIFT
+ gamepadshift_tick();
+ #endif
+ }
+#endif
+}
+
+uint64_t supervisor_ticks_ms64() {
+ uint64_t result;
+ common_hal_mcu_disable_interrupts();
+ result = ticks_ms;
+ common_hal_mcu_enable_interrupts();
+ return result;
+}
+
+uint32_t supervisor_ticks_ms32() {
+ return ticks_ms;
+}
+
+extern void run_background_tasks(void);
+
+void supervisor_run_background_tasks_if_tick() {
+ uint32_t now32 = ticks_ms;
+
+ if (now32 == background_ticks_ms32) {
+ return;
+ }
+ background_ticks_ms32 = now32;
+
+ run_background_tasks();
+}
+
+void supervisor_fake_tick() {
+ uint32_t now32 = ticks_ms;
+ background_ticks_ms32 = (now32 - 1);
+}
diff --git a/supervisor/shared/tick.h b/supervisor/shared/tick.h
new file mode 100644
index 000000000..7ce8281ba
--- /dev/null
+++ b/supervisor/shared/tick.h
@@ -0,0 +1,67 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Jeff Epler for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef __INCLUDED_SUPERVISOR_TICK_H
+#define __INCLUDED_SUPERVISOR_TICK_H
+
+#include <stdint.h>
+
+/** @brief To be called once every ms
+ *
+ * The port must call supervisor_tick once per millisecond to perform regular tasks.
+ * This is called from the SysTick interrupt or similar, and is safe to call in an
+ * interrupt context.
+ */
+extern void supervisor_tick(void);
+/** @brief Cause background tasks to be called soon
+ *
+ * Normally, background tasks are only run once per tick. For other cases where
+ * an event noticed from an interrupt context needs to be completed by a background
+ * task activity, the interrupt can call supervisor_fake_tick.
+ */
+extern void supervisor_fake_tick(void);
+/** @brief Get the lower 32 bits of the time in milliseconds
+ *
+ * This can be more efficient than supervisor_ticks_ms64, for sites where a wraparound
+ * of ~49.5 days is not harmful.
+ */
+extern uint32_t supervisor_ticks_ms32(void);
+/** @brief Get the full time in milliseconds
+ *
+ * Because common ARM mcus cannot atomically work with 64-bit quantities, this
+ * function must briefly disable interrupts in order to return the value. If
+ * only relative durations of less than about ~49.5 days need to be considered,
+ * then it may be possible to use supervisor_ticks_ms64 instead.
+ */
+extern uint64_t supervisor_ticks_ms64(void);
+/** @brief Run background ticks, but only about every millisecond.
+ *
+ * Normally, this is not called directly. Instead use the RUN_BACKGROUND_TASKS
+ * macro.
+ */
+extern void supervisor_run_background_if_tick(void);
+
+#endif
diff --git a/supervisor/shared/translate.c b/supervisor/shared/translate.c
index aa5e4517c..187d5ff8a 100644
--- a/supervisor/shared/translate.c
+++ b/supervisor/shared/translate.c
@@ -42,12 +42,28 @@ void serial_write_compressed(const compressed_string_t* compressed) {
serial_write(decompressed);
}
+STATIC int put_utf8(char *buf, int u) {
+ if(u <= 0x7f) {
+ *buf = u;
+ return 1;
+ } else if(u <= 0x07ff) {
+ *buf++ = 0b11000000 | (u >> 6);
+ *buf = 0b10000000 | (u & 0b00111111);
+ return 2;
+ } else { // u <= 0xffff)
+ *buf++ = 0b11000000 | (u >> 12);
+ *buf = 0b10000000 | ((u >> 6) & 0b00111111);
+ *buf = 0b10000000 | (u & 0b00111111);
+ return 3;
+ }
+}
+
char* decompress(const compressed_string_t* compressed, char* decompressed) {
uint8_t this_byte = 0;
uint8_t this_bit = 7;
uint8_t b = compressed->data[this_byte];
// Stop one early because the last byte is always NULL.
- for (uint16_t i = 0; i < compressed->length - 1; i++) {
+ for (uint16_t i = 0; i < compressed->length - 1;) {
uint32_t bits = 0;
uint8_t bit_length = 0;
uint32_t max_code = lengths[0];
@@ -72,7 +88,7 @@ char* decompress(const compressed_string_t* compressed, char* decompressed) {
max_code = (max_code << 1) + lengths[bit_length];
searched_length += lengths[bit_length];
}
- decompressed[i] = values[searched_length + bits - max_code];
+ i += put_utf8(decompressed + i, values[searched_length + bits - max_code]);
}
decompressed[compressed->length-1] = '\0';
diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk
index f576bc546..87d506b3b 100644
--- a/supervisor/supervisor.mk
+++ b/supervisor/supervisor.mk
@@ -10,26 +10,36 @@ SRC_SUPERVISOR = \
supervisor/shared/safe_mode.c \
supervisor/shared/stack.c \
supervisor/shared/status_leds.c \
+ supervisor/shared/tick.c \
supervisor/shared/translate.c
ifndef $(NO_USB)
NO_USB = $(wildcard supervisor/usb.c)
endif
-ifneq ($(INTERNAL_FLASH_FILESYSTEM),)
- CFLAGS += -DINTERNAL_FLASH_FILESYSTEM=$(INTERNAL_FLASH_FILESYSTEM)
+ifndef INTERNAL_FLASH_FILESYSTEM
+INTERNAL_FLASH_FILESYSTEM = 0
+endif
+CFLAGS += -DINTERNAL_FLASH_FILESYSTEM=$(INTERNAL_FLASH_FILESYSTEM)
+
+ifndef QSPI_FLASH_FILESYSTEM
+QSPI_FLASH_FILESYSTEM = 0
endif
-ifneq ($(QSPI_FLASH_FILESYSTEM),)
# EXPRESS_BOARD is obsolete and should be removed when samd-peripherals is updated.
- CFLAGS += -DQSPI_FLASH_FILESYSTEM=$(QSPI_FLASH_FILESYSTEM) -DEXPRESS_BOARD
+CFLAGS += -DQSPI_FLASH_FILESYSTEM=$(QSPI_FLASH_FILESYSTEM) -DEXPRESS_BOARD
+
+ifndef SPI_FLASH_FILESYSTEM
+SPI_FLASH_FILESYSTEM = 0
endif
-ifneq ($(SPI_FLASH_FILESYSTEM),)
# EXPRESS_BOARD is obsolete and should be removed when samd-peripherals is updated.
- CFLAGS += -DSPI_FLASH_FILESYSTEM=$(SPI_FLASH_FILESYSTEM) -DEXPRESS_BOARD
+CFLAGS += -DSPI_FLASH_FILESYSTEM=$(SPI_FLASH_FILESYSTEM) -DEXPRESS_BOARD
+
+ifeq ($(CIRCUITPY_BLEIO),1)
+ SRC_SUPERVISOR += supervisor/shared/bluetooth.c
endif
# Choose which flash filesystem impl to use.
-# (Right now INTERNAL_FLASH_FILESYSTEM and SPI_FLASH_FILESYSTEM are mutually exclusive.
+# (Right now INTERNAL_FLASH_FILESYSTEM and (Q)SPI_FLASH_FILESYSTEM are mutually exclusive.
# But that might not be true in the future.)
ifdef EXTERNAL_FLASH_DEVICES
CFLAGS += -DEXTERNAL_FLASH_DEVICES=$(EXTERNAL_FLASH_DEVICES) \
@@ -87,6 +97,10 @@ else
CFLAGS += -DUSB_AVAILABLE
endif
+ifndef USB_INTERFACE_NAME
+USB_INTERFACE_NAME = "CircuitPython"
+endif
+
ifndef USB_DEVICES
USB_DEVICES = "CDC,MSC,AUDIO,HID"
endif
@@ -141,6 +155,7 @@ USB_DESCRIPTOR_ARGS = \
--vid $(USB_VID)\
--pid $(USB_PID)\
--serial_number_length $(USB_SERIAL_NUMBER_LENGTH)\
+ --interface_name $(USB_INTERFACE_NAME)\
--devices $(USB_DEVICES)\
--hid_devices $(USB_HID_DEVICES)\
--msc_max_packet_size $(USB_MSC_MAX_PACKET_SIZE)\
diff --git a/tools/build_board_info.py b/tools/build_board_info.py
index efa481a63..710cdb0c2 100644
--- a/tools/build_board_info.py
+++ b/tools/build_board_info.py
@@ -48,6 +48,7 @@ extension_by_board = {
aliases_by_board = {
"circuitplayground_express": ["circuitplayground_express_4h", "circuitplayground_express_digikey_pycon2019"],
+ "pybadge": ["edgebadge"],
"gemma_m0": ["gemma_m0_pycon2018"],
"pewpew10": ["pewpew13"]
}
diff --git a/tools/build_memory_info.py b/tools/build_memory_info.py
index a8f84bbb6..0dcd5f6e4 100644
--- a/tools/build_memory_info.py
+++ b/tools/build_memory_info.py
@@ -50,7 +50,7 @@ regions = {}
with open(sys.argv[1], "r") as f:
for line in f:
line = line.strip()
- if line.startswith(("FLASH", "RAM")):
+ if line.startswith(("FLASH_FIRMWARE", "RAM")):
regions[line.split()[0]] = line.split("=")[-1]
for region in regions:
@@ -61,10 +61,10 @@ for region in regions:
space = M_PATTERN.sub(M_REPLACE, space)
regions[region] = eval(space)
-free_flash = regions["FLASH"] - text - data
+free_flash = regions["FLASH_FIRMWARE"] - text - data
free_ram = regions["RAM"] - data - bss
-print(free_flash, "bytes free in flash out of", regions["FLASH"], "bytes (", regions["FLASH"] / 1024, "kb ).")
-print(free_ram, "bytes free in ram for stack out of", regions["RAM"], "bytes (", regions["RAM"] / 1024, "kb ).")
+print("{} bytes free in flash firmware space out of {} bytes ({}kB).".format(free_flash, regions["FLASH_FIRMWARE"], regions["FLASH_FIRMWARE"] / 1024))
+print("{} bytes free in ram for stack out of {} bytes ({}kB).".format(free_ram, regions["RAM"], regions["RAM"] / 1024))
print()
# Check that we have free flash space. GCC doesn't fail when the text + data
diff --git a/tools/gen_ld_files.py b/tools/gen_ld_files.py
index fc80d46c9..c2ac812bc 100755
--- a/tools/gen_ld_files.py
+++ b/tools/gen_ld_files.py
@@ -17,26 +17,39 @@ args = parser.parse_args()
defines = {}
-# We're looking for lines like this:
-# <expression> ///DEFINE_VALUE NAME_OF_VALUE <optional Python lambda expression to transform value>
-VALUE_LINE_RE = re.compile(r'^([^/].*); ///DEFINE_VALUE (\w+)(.*)$')
-
+#
+REMOVE_UL_RE = re.compile('([0-9]+)UL')
+def remove_UL(s):
+ return REMOVE_UL_RE.sub(r'\1', s)
+
+# We skip all lines before
+# // START_LD_DEFINES
+# Then we look for lines like this:
+# /*NAME_OF_VALUE=*/ NAME_OF_VALUE;
+VALUE_LINE_RE = re.compile(r'^/\*\s*(\w+)\s*=\*/\s*(.*);\s*$')
+
+start_processing = False
for line in args.defines:
- match = VALUE_LINE_RE.match(line.strip())
- if match:
- value = match.group(1).strip()
- name = match.group(2)
- lambda_exp = match.group(3).strip()
- # Apply the given lambda to the value if it is present, else just store the value.
- defines[match.group(2)] = eval(lambda_exp)(value) if lambda_exp else value
-
-#print(defines)
+ line = line.strip()
+ if line == '// START_LD_DEFINES':
+ start_processing = True
+ continue
+ if start_processing:
+ match = VALUE_LINE_RE.match(line)
+ if match:
+ name = match.group(1)
+ value = match.group(2).strip()
+ defines[name] = remove_UL(value)
+
fail = False
for template_file in args.template_files:
ld_template_basename = os.path.basename(template_file.name)
ld_pathname = os.path.join(args.out_dir, ld_template_basename.replace('.template.ld', '.ld'))
with open(ld_pathname, 'w') as output:
+ for k,v in defines.items():
+ print('/*', k, '=', v, '*/', file=output)
+ print(file=output)
try:
output.write(Template(template_file.read()).substitute(defines))
except KeyError as e:
diff --git a/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py
index 21a480f99..5e25528f9 100644
--- a/tools/gen_usb_descriptor.py
+++ b/tools/gen_usb_descriptor.py
@@ -8,6 +8,7 @@ sys.path.append("../../tools/usb_descriptor")
from adafruit_usb_descriptor import audio, audio10, cdc, hid, midi, msc, standard, util
import hid_report_descriptors
+DEFAULT_INTERFACE_NAME = 'CircuitPython'
ALL_DEVICES='CDC,MSC,AUDIO,HID'
ALL_DEVICES_SET=frozenset(ALL_DEVICES.split(','))
DEFAULT_DEVICES='CDC,MSC,AUDIO,HID'
@@ -32,6 +33,9 @@ parser.add_argument('--devices', type=lambda l: tuple(l.split(',')), default=DEF
help='devices to include in descriptor (AUDIO includes MIDI support)')
parser.add_argument('--hid_devices', type=lambda l: tuple(l.split(',')), default=DEFAULT_HID_DEVICES,
help='HID devices to include in HID report descriptor')
+parser.add_argument('--interface_name', type=str,
+ help='The name/prefix to use in the interface descriptions',
+ default=DEFAULT_INTERFACE_NAME)
parser.add_argument('--msc_max_packet_size', type=int, default=64,
help='Max packet size for MSC')
parser.add_argument('--no-renumber_endpoints', dest='renumber_endpoints', action='store_false',
@@ -151,7 +155,7 @@ cdc_comm_interface = standard.InterfaceDescriptor(
bInterfaceClass=cdc.CDC_CLASS_COMM, # Communications Device Class
bInterfaceSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model
bInterfaceProtocol=cdc.CDC_PROTOCOL_NONE,
- iInterface=StringIndex.index("CircuitPython CDC control"),
+ iInterface=StringIndex.index("{} CDC control".format(args.interface_name)),
subdescriptors=[
cdc.Header(
description="CDC comm",
@@ -172,7 +176,7 @@ cdc_comm_interface = standard.InterfaceDescriptor(
cdc_data_interface = standard.InterfaceDescriptor(
description="CDC data",
bInterfaceClass=cdc.CDC_CLASS_DATA,
- iInterface=StringIndex.index("CircuitPython CDC data"),
+ iInterface=StringIndex.index("{} CDC data".format(args.interface_name)),
subdescriptors=[
standard.EndpointDescriptor(
description="CDC data out",
@@ -192,7 +196,7 @@ msc_interfaces = [
bInterfaceClass=msc.MSC_CLASS,
bInterfaceSubClass=msc.MSC_SUBCLASS_TRANSPARENT,
bInterfaceProtocol=msc.MSC_PROTOCOL_BULK,
- iInterface=StringIndex.index("CircuitPython Mass Storage"),
+ iInterface=StringIndex.index("{} Mass Storage".format(args.interface_name)),
subdescriptors=[
standard.EndpointDescriptor(
description="MSC in",
@@ -256,7 +260,7 @@ hid_interfaces = [
bInterfaceClass=hid.HID_CLASS,
bInterfaceSubClass=hid.HID_SUBCLASS_NOBOOT,
bInterfaceProtocol=hid.HID_PROTOCOL_NONE,
- iInterface=StringIndex.index("CircuitPython HID"),
+ iInterface=StringIndex.index("{} HID".format(args.interface_name)),
subdescriptors=[
hid.HIDDescriptor(
description="HID",
@@ -272,9 +276,9 @@ hid_interfaces = [
# USB OUT -> midi_in_jack_emb -> midi_out_jack_ext -> CircuitPython
midi_in_jack_emb = midi.InJackDescriptor(
- description="MIDI PC -> CircuitPython",
+ description="MIDI PC -> {}".format(args.interface_name),
bJackType=midi.JACK_TYPE_EMBEDDED,
- iJack=StringIndex.index("CircuitPython usb_midi.ports[0]"))
+ iJack=StringIndex.index("{} usb_midi.ports[0]".format(args.interface_name)))
midi_out_jack_ext = midi.OutJackDescriptor(
description="MIDI data out to user code.",
bJackType=midi.JACK_TYPE_EXTERNAL,
@@ -287,10 +291,10 @@ midi_in_jack_ext = midi.InJackDescriptor(
bJackType=midi.JACK_TYPE_EXTERNAL,
iJack=0)
midi_out_jack_emb = midi.OutJackDescriptor(
- description="MIDI PC <- CircuitPython",
+ description="MIDI PC <- {}".format(args.interface_name),
bJackType=midi.JACK_TYPE_EMBEDDED,
input_pins=[(midi_in_jack_ext, 1)],
- iJack=StringIndex.index("CircuitPython usb_midi.ports[1]"))
+ iJack=StringIndex.index("{} usb_midi.ports[1]".format(args.interface_name)))
audio_midi_interface = standard.InterfaceDescriptor(
@@ -298,7 +302,7 @@ audio_midi_interface = standard.InterfaceDescriptor(
bInterfaceClass=audio.AUDIO_CLASS_DEVICE,
bInterfaceSubClass=audio.AUDIO_SUBCLASS_MIDI_STREAMING,
bInterfaceProtocol=audio.AUDIO_PROTOCOL_V1,
- iInterface=StringIndex.index("CircuitPython MIDI"),
+ iInterface=StringIndex.index("{} MIDI".format(args.interface_name)),
subdescriptors=[
midi.Header(
jacks_and_elements=[
@@ -309,12 +313,12 @@ audio_midi_interface = standard.InterfaceDescriptor(
],
),
standard.EndpointDescriptor(
- description="MIDI data out to CircuitPython",
+ description="MIDI data out to {}".format(args.interface_name),
bEndpointAddress=args.midi_ep_num_out | standard.EndpointDescriptor.DIRECTION_OUT,
bmAttributes=standard.EndpointDescriptor.TYPE_BULK),
midi.DataEndpointDescriptor(baAssocJack=[midi_in_jack_emb]),
standard.EndpointDescriptor(
- description="MIDI data in from CircuitPython",
+ description="MIDI data in from {}".format(args.interface_name),
bEndpointAddress=args.midi_ep_num_in | standard.EndpointDescriptor.DIRECTION_IN,
bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
bInterval = 0x0),
@@ -334,7 +338,7 @@ audio_control_interface = standard.InterfaceDescriptor(
bInterfaceClass=audio.AUDIO_CLASS_DEVICE,
bInterfaceSubClass=audio.AUDIO_SUBCLASS_CONTROL,
bInterfaceProtocol=audio.AUDIO_PROTOCOL_V1,
- iInterface=StringIndex.index("CircuitPython Audio"),
+ iInterface=StringIndex.index("{} Audio".format(args.interface_name)),
subdescriptors=[
cs_ac_interface,
])