diff options
50 files changed, 513 insertions, 123 deletions
diff --git a/.travis.yml b/.travis.yml index 9bfcd61f0..9a058aa64 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,20 +12,32 @@ git: # pip packages, and so forth. By gathering activities together in optimal # ways, the "run time" and "total time" of the travis jobs can be minimized. # -# Since at the time of writing Travis generally starts 5 or 6 jobs, the -# builds have been organized into 5 groups of *approximately* equal durations. -# Additionally, the jobs that need extra SDKs are also organized together. +# Builds are organized so some will complete quickly, and others are of +# approximately equal size. Try not to freeze out other Travis users. +# +# Board names are in alphabetical order for easy finding, but grouped by +# Adafruit/modified-Adafruit and Other. Ideally they'd be separated into +# separate jobs, but there are too many. # # When adding new boards, take a look on the travis CI page # https://travis-ci.org/adafruit/circuitpython to which build that installs # that SDK is shortest and add it there. In the case of major re-organizations, # just try to make the builds "about equal in run time" env: - - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="trinket_m0_haxpress circuitplayground_express mini_sam_m4 grandcentral_m4_express capablerobot_usbhub pygamer pca10056 pca10059 feather_nrf52840_express metro_nrf52840_express circuitplayground_bluefruit makerdiary_nrf52840_mdk makerdiary_nrf52840_mdk_usb_dongle particle_boron particle_argon particle_xenon sparkfun_nrf52840_mini electronut_labs_papyr electronut_labs_blip" TRAVIS_SDK=arm:nrf - - TRAVIS_BOARDS="metro_m0_express metro_m4_express metro_m4_airlift_lite pirkey_m0 trellis_m4_express trinket_m0 sparkfun_lumidrive sparkfun_redboard_turbo bast_pro_mini_m0 datum_distance pyruler" TRAVIS_SDK=arm - - TRAVIS_BOARDS="cp32-m4 feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow sam32 uchip escornabot_makech pygamer_advance datum_imu snekboard" TRAVIS_SDK=arm - - TRAVIS_BOARDS="feather_m0_supersized feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300 arduino_mkrzero pewpew10 kicksat-sprite ugame10 robohatmm1_m0 robohatmm1_m4 datum_light" TRAVIS_SDK=arm - - TRAVIS_BOARDS="datalore_ip_m4 circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express catwan_usbstick pyportal sparkfun_samd21_mini sparkfun_samd21_dev pybadge pybadge_airlift datum_weather pyportal_titano" TRAVIS_SDK=arm + # Non-board tasks + - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="" + # Adafruit and Nordic nRF boards + - TRAVIS_BOARDS="circuitplayground_bluefruit feather_nrf52840_express metro_nrf52840_express pca10056 pca10059" TRAVIS_SDK=arm + # Other nRF boards + - TRAVIS_BOARDS="electronut_labs_blip electronut_labs_papyr makerdiary_nrf52840_mdk makerdiary_nrf52840_mdk_usb_dongle particle_argon particle_boron particle_xenon sparkfun_nrf52840_mini" TRAVIS_SDK=arm + # Adafruit and modified Adafruit SAMD21 (M0) + Other SAMD21 (M0) + - TRAVIS_BOARDS="circuitplayground_express circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m0_supersized feather_radiofruit_zigbee gemma_m0 hallowing_m0_express " TRAVIS_SDK=arm + - TRAVIS_BOARDS="itsybitsy_m0_express metro_m0_express pirkey_m0 pyruler trinket_m0 trinket_m0_haxpress arduino_mkr1300 arduino_mkrzero arduino_zero bast_pro_mini_m0 catwan_usbstick datum_distance datum_imu datum_weather" TRAVIS_SDK=arm + - TRAVIS_BOARDS="escornabot_makech meowmeow pewpew10 robohatmm1_m0 snekboard sparkfun_lumidrive sparkfun_redboard_turbo sparkfun_samd21_dev sparkfun_samd21_mini uchip ugame10" TRAVIS_SDK=arm + # Adafruit SAMD51 (M4) + Other SAMD51 + - TRAVIS_BOARDS="feather_m4_express grandcentral_m4_express itsybitsy_m4_express metro_m4_airlift_lite metro_m4_express pybadge pybadge_airlift pygamer pygamer_advance" TRAVIS_SDK=arm + - TRAVIS_BOARDS="pyportal pyportal_titano trellis_m4_express capablerobot_usbhub cp32-m4 datalore_ip_m4 datum_light kicksat-sprite mini_sam_m4 robohatmm1_m4 sam32" TRAVIS_SDK=arm + addons: artifacts: diff --git a/locale/ID.po b/locale/ID.po index 9041b4cb0..d8758374e 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -1138,7 +1138,7 @@ msgid "Slices not supported" msgstr "" #: ports/nrf/common-hal/bleio/Adapter.c -#, c-format +#, fuzzy, c-format msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "Dukungan soft device, id: 0x%08lX, pc: 0x%08l" @@ -2284,6 +2284,14 @@ msgstr "panjang data string memiliki keganjilan (odd-length)" msgid "offset out of bounds" msgstr "modul tidak ditemukan" +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c #: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index fa189db79..2ccb77d5f 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-08-20 13:01-0400\n" +"POT-Creation-Date: 2019-08-20 13:06-0400\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" @@ -2248,6 +2248,14 @@ msgstr "" msgid "offset out of bounds" msgstr "" +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c #: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" diff --git a/locale/de_DE.po b/locale/de_DE.po index aadff2ac9..a90e5c46e 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -2295,6 +2295,14 @@ msgstr "String mit ungerader Länge" msgid "offset out of bounds" msgstr "offset außerhalb der Grenzen" +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c #: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" diff --git a/locale/en_US.po b/locale/en_US.po index 1b1c44d86..c7599388f 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -2248,6 +2248,14 @@ msgstr "" msgid "offset out of bounds" msgstr "" +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c #: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" diff --git a/locale/en_x_pirate.po b/locale/en_x_pirate.po index c6bb116e5..34bb307f3 100644 --- a/locale/en_x_pirate.po +++ b/locale/en_x_pirate.po @@ -2252,6 +2252,14 @@ msgstr "" msgid "offset out of bounds" msgstr "" +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c #: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" diff --git a/locale/es.po b/locale/es.po index 8be76c9df..5a4f270ef 100644 --- a/locale/es.po +++ b/locale/es.po @@ -635,7 +635,7 @@ 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 -#, c-format +#, fuzzy, c-format msgid "Failed to read attribute value, err 0x%04x" msgstr "Error al leer valor del atributo, err 0x%04" @@ -2311,6 +2311,14 @@ msgstr "string de longitud impar" msgid "offset out of bounds" msgstr "address fuera de límites" +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c #: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" diff --git a/locale/fil.po b/locale/fil.po index 93afc5998..65b73cc6d 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -2320,6 +2320,14 @@ msgstr "odd-length string" msgid "offset out of bounds" msgstr "wala sa sakop ang address" +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c #: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" diff --git a/locale/fr.po b/locale/fr.po index 4a1b9c312..cf35d2044 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -2356,6 +2356,14 @@ msgstr "chaîne de longueur impaire" msgid "offset out of bounds" msgstr "adresse hors limites" +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c #: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" diff --git a/locale/it_IT.po b/locale/it_IT.po index f8080fe85..96227d0ce 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -112,7 +112,7 @@ msgid "'%s' expects {r0, r1, ...}" msgstr "'%s' aspetta un registro" #: py/emitinlinextensa.c -#, c-format +#, fuzzy, c-format msgid "'%s' integer %d is not within range %d..%d" msgstr "intero '%s' non è nell'intervallo %d..%d" @@ -1566,7 +1566,7 @@ msgid "can't assign to expression" msgstr "impossibile assegnare all'espressione" #: py/obj.c -#, c-format +#, fuzzy, c-format msgid "can't convert %s to complex" msgstr "non è possibile convertire a complex" @@ -2316,6 +2316,14 @@ msgstr "stringa di lunghezza dispari" msgid "offset out of bounds" msgstr "indirizzo fuori limite" +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c #: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" @@ -2637,7 +2645,7 @@ msgid "unindent does not match any outer indentation level" msgstr "" #: py/objstr.c -#, c-format +#, fuzzy, c-format msgid "unknown conversion specifier %c" msgstr "specificatore di conversione %s sconosciuto" diff --git a/locale/pl.po b/locale/pl.po index 33a825239..7a242835d 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -559,12 +559,12 @@ msgid "Failed sending command." msgstr "" #: ports/nrf/sd_mutex.c -#, c-format +#, fuzzy, c-format msgid "Failed to acquire mutex, err 0x%04x" msgstr "Nie udało się uzyskać blokady, błąd 0x$04x" #: ports/nrf/common-hal/bleio/Service.c -#, c-format +#, fuzzy, c-format msgid "Failed to add characteristic, err 0x%04x" msgstr "Nie udało się dodać charakterystyki, błąd 0x$04x" @@ -2273,6 +2273,14 @@ msgstr "łańcuch o nieparzystej długości" msgid "offset out of bounds" msgstr "offset poza zakresem" +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c #: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index aed356137..2a5b62ec1 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -2274,6 +2274,14 @@ msgstr "" msgid "offset out of bounds" msgstr "" +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c #: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index d3bfa2fe7..67f329080 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -2287,6 +2287,14 @@ msgstr "jīshù zìfú chuàn" msgid "offset out of bounds" msgstr "piānlí biānjiè" +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: 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" @@ -2607,7 +2615,7 @@ msgid "unknown conversion specifier %c" msgstr "wèizhī de zhuǎnhuàn biāozhù %c" #: py/objstr.c -#, c-format +#, fuzzy, c-format msgid "unknown format code '%c' for object of type '%s'" msgstr "lèixíng '%s' duìxiàng wèizhī de géshì dàimǎ '%c'" diff --git a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c index da5c220a8..76010a684 100644 --- a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c +++ b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -408,9 +408,7 @@ uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* se // If wait_counts exceeds the max count, buffer has probably stopped filling; // DMA may have missed an I2S trigger event. while (!event_interrupt_active(event_channel) && ++wait_counts < MAX_WAIT_COUNTS) { - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif + RUN_BACKGROUND_TASKS; } // The mic is running all the time, so we don't need to wait the usual 10msec or 100msec diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.c b/ports/atmel-samd/common-hal/audioio/AudioOut.c index a75abd324..90f1aa41f 100644 --- a/ports/atmel-samd/common-hal/audioio/AudioOut.c +++ b/ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -69,9 +69,7 @@ static void ramp_value(uint16_t start, uint16_t end) { DAC->DATA.reg = value; DAC->DATABUF.reg = value; common_hal_mcu_delay_us(50); - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif + RUN_BACKGROUND_TASKS; } } #endif @@ -94,9 +92,7 @@ static void ramp_value(uint16_t start, uint16_t end) { DAC->DATABUF[1].reg = value; common_hal_mcu_delay_us(50); - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif + RUN_BACKGROUND_TASKS; } } #endif diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c index f04594842..2505e894a 100644 --- a/ports/atmel-samd/common-hal/busio/UART.c +++ b/ports/atmel-samd/common-hal/busio/UART.c @@ -291,13 +291,11 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t // Reset the timeout on every character read. start_ticks = ticks_ms; } -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP ; + RUN_BACKGROUND_TASKS; // Allow user to break out of a timeout with a KeyboardInterrupt. if (mp_hal_is_interrupted()) { break; } -#endif // If we are zero timeout, make sure we don't loop again (in the event // we read in under 1ms) if (self->timeout_ms == 0) { @@ -339,9 +337,7 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, done = true; break; } - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif + RUN_BACKGROUND_TASKS; } if (!done) { diff --git a/ports/atmel-samd/common-hal/pulseio/PulseOut.c b/ports/atmel-samd/common-hal/pulseio/PulseOut.c index 528a5c808..8b8bc6dc6 100644 --- a/ports/atmel-samd/common-hal/pulseio/PulseOut.c +++ b/ports/atmel-samd/common-hal/pulseio/PulseOut.c @@ -198,9 +198,7 @@ void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pu while(pulse_index < length) { // Do other things while we wait. The interrupts will handle sending the // signal. - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif + RUN_BACKGROUND_TASKS; } tc->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_STOP; diff --git a/ports/atmel-samd/common-hal/touchio/TouchIn.c b/ports/atmel-samd/common-hal/touchio/TouchIn.c index 0658c1d05..908d8d722 100644 --- a/ports/atmel-samd/common-hal/touchio/TouchIn.c +++ b/ports/atmel-samd/common-hal/touchio/TouchIn.c @@ -52,9 +52,7 @@ static uint16_t get_raw_reading(touchio_touchin_obj_t *self) { while (!adafruit_ptc_is_conversion_finished(PTC)) { // wait - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif + RUN_BACKGROUND_TASKS; } return adafruit_ptc_get_conversion_result(PTC); diff --git a/ports/atmel-samd/mphalport.c b/ports/atmel-samd/mphalport.c index 5c34a576a..957bf6073 100644 --- a/ports/atmel-samd/mphalport.c +++ b/ports/atmel-samd/mphalport.c @@ -53,9 +53,7 @@ void mp_hal_delay_ms(mp_uint_t delay) { uint64_t start_tick = ticks_ms; uint64_t duration = 0; while (duration < delay) { - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif + RUN_BACKGROUND_TASKS; // Check to see if we've been CTRL-Ced by autoreload or the user. if(MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) || MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 9da2c498d..9a461f9d8 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -95,8 +95,7 @@ ifeq ($(DEBUG), 1) CFLAGS += -fno-inline -fno-ipa-sra else CFLAGS += -Os -DNDEBUG - # TODO: Test with -flto - ### CFLAGS += -flto + CFLAGS += -flto -flto-partition=none endif @@ -185,8 +184,7 @@ SRC_C += \ # USB source files for nrf52840 ifeq ($(MCU_SUB_VARIANT),nrf52840) SRC_C += \ - lib/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c \ - lib/tinyusb/src/portable/nordic/nrf5x/hal_nrf5x.c + lib/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c endif SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ diff --git a/ports/nrf/bluetooth/ble_uart.c b/ports/nrf/bluetooth/ble_uart.c index 91d10cff1..d83cf3980 100644 --- a/ports/nrf/bluetooth/ble_uart.c +++ b/ports/nrf/bluetooth/ble_uart.c @@ -138,9 +138,7 @@ void ble_uart_init(void) { m_cccd_enabled = false; while (!m_cccd_enabled) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif + RUN_BACKGROUND_TASKS; } } @@ -150,9 +148,7 @@ bool ble_uart_connected(void) { char ble_uart_rx_chr(void) { while (isBufferEmpty(&m_rx_ring_buffer)) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif + RUN_BACKGROUND_TASKS; } uint8_t byte; diff --git a/ports/nrf/common-hal/audiobusio/I2SOut.c b/ports/nrf/common-hal/audiobusio/I2SOut.c new file mode 100644 index 000000000..8be1fb2f8 --- /dev/null +++ b/ports/nrf/common-hal/audiobusio/I2SOut.c @@ -0,0 +1,70 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/audiobusio/I2SOut.h" + +#include "py/obj.h" +#include "py/runtime.h" + +void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t* self, + const mcu_pin_obj_t* bit_clock, const mcu_pin_obj_t* word_select, + const mcu_pin_obj_t* data, bool left_justified) { + mp_raise_NotImplementedError(NULL); +} + +bool common_hal_audiobusio_i2sout_deinited(audiobusio_i2sout_obj_t* self) { + mp_raise_NotImplementedError(NULL); +} + +void common_hal_audiobusio_i2sout_deinit(audiobusio_i2sout_obj_t* self) { + mp_raise_NotImplementedError(NULL); +} + +void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t* self, + mp_obj_t sample, bool loop) { + mp_raise_NotImplementedError(NULL); +} + +void common_hal_audiobusio_i2sout_pause(audiobusio_i2sout_obj_t* self) { + mp_raise_NotImplementedError(NULL); +} + +void common_hal_audiobusio_i2sout_resume(audiobusio_i2sout_obj_t* self) { + mp_raise_NotImplementedError(NULL); +} + +bool common_hal_audiobusio_i2sout_get_paused(audiobusio_i2sout_obj_t* self) { + mp_raise_NotImplementedError(NULL); +} + +void common_hal_audiobusio_i2sout_stop(audiobusio_i2sout_obj_t* self) { + mp_raise_NotImplementedError(NULL); +} + +bool common_hal_audiobusio_i2sout_get_playing(audiobusio_i2sout_obj_t* self) { + mp_raise_NotImplementedError(NULL); +} diff --git a/ports/nrf/common-hal/audiobusio/I2SOut.h b/ports/nrf/common-hal/audiobusio/I2SOut.h new file mode 100644 index 000000000..01c944e72 --- /dev/null +++ b/ports/nrf/common-hal/audiobusio/I2SOut.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_AUDIOBUSIO_I2SOUT_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_AUDIOBUSIO_I2SOUT_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} audiobusio_i2sout_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_AUDIOBUSIO_I2SOUT_H diff --git a/ports/nrf/common-hal/audiobusio/PDMIn.c b/ports/nrf/common-hal/audiobusio/PDMIn.c new file mode 100644 index 000000000..a7f9c9d74 --- /dev/null +++ b/ports/nrf/common-hal/audiobusio/PDMIn.c @@ -0,0 +1,130 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "common-hal/audiobusio/PDMIn.h" +#include "shared-bindings/microcontroller/Pin.h" + +#include "py/runtime.h" + +__attribute__((used)) +NRF_PDM_Type *nrf_pdm = NRF_PDM; + +static uint32_t dummy_buffer[4]; + +void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t* self, + const mcu_pin_obj_t* clock_pin, + const mcu_pin_obj_t* data_pin, + uint32_t sample_rate, + uint8_t bit_depth, + bool mono, + uint8_t oversample) { + assert_pin_free(clock_pin); + assert_pin_free(data_pin); + claim_pin(clock_pin); + claim_pin(data_pin); + + self->mono = mono; + self->clock_pin_number = clock_pin->number; + self->data_pin_number = data_pin->number; + + if (sample_rate != 16000) { + mp_raise_ValueError(translate("only sample_rate=16000 is supported")); + } + if (bit_depth != 16) { + mp_raise_ValueError(translate("only bit_depth=16 is supported")); + } + nrf_pdm->PSEL.CLK = self->clock_pin_number; + nrf_pdm->PSEL.DIN = self->data_pin_number; + nrf_pdm->PDMCLKCTRL = PDM_PDMCLKCTRL_FREQ_Default; // For Ratio64 + nrf_pdm->RATIO = PDM_RATIO_RATIO_Ratio64; + nrf_pdm->GAINL = PDM_GAINL_GAINL_DefaultGain; + nrf_pdm->GAINR = PDM_GAINR_GAINR_DefaultGain; + nrf_pdm->ENABLE = 1; + + nrf_pdm->SAMPLE.PTR = (uintptr_t)&dummy_buffer; + nrf_pdm->SAMPLE.MAXCNT = 1; + nrf_pdm->TASKS_START = 1; +} + +bool common_hal_audiobusio_pdmin_deinited(audiobusio_pdmin_obj_t* self) { + return !self->clock_pin_number; +} + +void common_hal_audiobusio_pdmin_deinit(audiobusio_pdmin_obj_t* self) { + nrf_pdm->ENABLE = 0; + + reset_pin_number(self->clock_pin_number); + self->clock_pin_number = 0; + reset_pin_number(self->data_pin_number); + self->data_pin_number = 0; +} + +uint8_t common_hal_audiobusio_pdmin_get_bit_depth(audiobusio_pdmin_obj_t* self) { + return 16; +} + +uint32_t common_hal_audiobusio_pdmin_get_sample_rate(audiobusio_pdmin_obj_t* self) { + return 16000; +} + +uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* self, + uint16_t* output_buffer, uint32_t output_buffer_length) { + // Note: Adafruit's module has SELECT pulled to GND, which makes the DATA + // valid when the CLK is low, therefore it must be sampled on the rising edge. + if (self->mono) { + nrf_pdm->MODE = PDM_MODE_OPERATION_Stereo | PDM_MODE_EDGE_LeftRising; + } else { + nrf_pdm->MODE = PDM_MODE_OPERATION_Mono | PDM_MODE_EDGE_LeftRising; + } + + // step 1. Redirect to real buffer + nrf_pdm->SAMPLE.PTR = (uintptr_t)output_buffer; + nrf_pdm->SAMPLE.MAXCNT = output_buffer_length; + + // a delay is the safest simple way to ensure that the above requested sample has started + mp_hal_delay_us(200); + nrf_pdm->EVENTS_END = 0; + + // step 2. Registers are double buffered, so pre-redirect back to dummy buffer + nrf_pdm->SAMPLE.PTR = (uintptr_t)&dummy_buffer; + nrf_pdm->SAMPLE.MAXCNT = 1; + + // Step 3. wait for PDM to end + while (!nrf_pdm->EVENTS_END) { + MICROPY_VM_HOOK_LOOP; + } + + // Step 4. They want unsigned + for (uint32_t i=0; i<output_buffer_length; i++) { + output_buffer[i] += 32768; + } + + if (self->mono) { + return (output_buffer_length / 2) * 2; + } else { + return (output_buffer_length / 4) * 4; + } +} diff --git a/ports/nrf/common-hal/audiobusio/PDMIn.h b/ports/nrf/common-hal/audiobusio/PDMIn.h new file mode 100644 index 000000000..d921e42ff --- /dev/null +++ b/ports/nrf/common-hal/audiobusio/PDMIn.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_AUDIOBUSIO_AUDIOOUT_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_AUDIOBUSIO_AUDIOOUT_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint8_t clock_pin_number, data_pin_number; + bool mono; +} audiobusio_pdmin_obj_t; + +#endif diff --git a/ports/nrf/common-hal/audiobusio/__init__.c b/ports/nrf/common-hal/audiobusio/__init__.c new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ports/nrf/common-hal/audiobusio/__init__.c diff --git a/ports/nrf/common-hal/bleio/Central.c b/ports/nrf/common-hal/bleio/Central.c index d771437d6..3c5d97784 100644 --- a/ports/nrf/common-hal/bleio/Central.c +++ b/ports/nrf/common-hal/bleio/Central.c @@ -115,7 +115,7 @@ void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_o } while (self->waiting_to_connect) { - MICROPY_VM_HOOK_LOOP; + RUN_BACKGROUND_TASKS; } if (self->conn_handle == BLE_CONN_HANDLE_INVALID) { diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index f8b6ce06c..45e8d2495 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -94,7 +94,7 @@ STATIC void characteristic_gatts_notify_indicate(uint16_t handle, uint16_t conn_ // TX buffer is full // We could wait for an event indicating the write is complete, but just retrying is easier. if (err_code == NRF_ERROR_RESOURCES) { - MICROPY_VM_HOOK_LOOP; + RUN_BACKGROUND_TASKS; continue; } @@ -118,7 +118,7 @@ STATIC void characteristic_gattc_read(bleio_characteristic_obj_t *characteristic } while (m_read_characteristic != NULL) { - MICROPY_VM_HOOK_LOOP; + RUN_BACKGROUND_TASKS; } ble_drv_remove_event_handler(characteristic_on_gattc_read_rsp_evt, characteristic); @@ -258,7 +258,7 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, // Write without reponse will return NRF_ERROR_RESOURCES if too many writes are pending. if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES) { // We could wait for an event indicating the write is complete, but just retrying is easier. - MICROPY_VM_HOOK_LOOP; + RUN_BACKGROUND_TASKS; continue; } diff --git a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/bleio/CharacteristicBuffer.c index a6d834d7d..64ab5e8a7 100644 --- a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c +++ b/ports/nrf/common-hal/bleio/CharacteristicBuffer.c @@ -99,7 +99,7 @@ int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_ // Wait for all bytes received or timeout while ( (ringbuf_count(&self->ringbuf) < len) && (ticks_ms - start_ticks < self->timeout_ms) ) { - MICROPY_VM_HOOK_LOOP; + RUN_BACKGROUND_TASKS; // Allow user to break out of a timeout with a KeyboardInterrupt. if ( mp_hal_is_interrupted() ) { return 0; diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index b9e9e5538..54a66ddbe 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -235,13 +235,11 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t // Wait for all bytes received or timeout while ( (ringbuf_count(&self->rbuf) < len) && (ticks_ms - start_ticks < self->timeout_ms) ) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP ; + RUN_BACKGROUND_TASKS; // Allow user to break out of a timeout with a KeyboardInterrupt. if ( mp_hal_is_interrupted() ) { return 0; } -#endif } // prevent conflict with uart irq @@ -271,9 +269,7 @@ size_t common_hal_busio_uart_write (busio_uart_obj_t *self, const uint8_t *data, // Wait for on-going transfer to complete while ( nrfx_uarte_tx_in_progress(self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif + RUN_BACKGROUND_TASKS; } // Time up @@ -295,9 +291,7 @@ size_t common_hal_busio_uart_write (busio_uart_obj_t *self, const uint8_t *data, (*errcode) = 0; while ( nrfx_uarte_tx_in_progress(self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif + RUN_BACKGROUND_TASKS; } if ( !nrfx_is_in_ram(data) ) { diff --git a/ports/nrf/common-hal/neopixel_write/__init__.c b/ports/nrf/common-hal/neopixel_write/__init__.c index 78e0038e8..3b67778a6 100644 --- a/ports/nrf/common-hal/neopixel_write/__init__.c +++ b/ports/nrf/common-hal/neopixel_write/__init__.c @@ -200,9 +200,7 @@ void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout // But we have to wait for the flag to be set. while ( !nrf_pwm_event_check(pwm, NRF_PWM_EVENT_SEQEND0) ) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif + RUN_BACKGROUND_TASKS; } // Before leave we clear the flag for the event. diff --git a/ports/nrf/common-hal/pulseio/PulseOut.c b/ports/nrf/common-hal/pulseio/PulseOut.c index be5deca9f..d0433247a 100644 --- a/ports/nrf/common-hal/pulseio/PulseOut.c +++ b/ports/nrf/common-hal/pulseio/PulseOut.c @@ -155,9 +155,7 @@ void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pu while(pulse_array_index < length) { // Do other things while we wait. The interrupts will handle sending the // signal. - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif + RUN_BACKGROUND_TASKS; } nrfx_timer_disable(timer); diff --git a/ports/nrf/device/nrf52/startup_nrf52840.c b/ports/nrf/device/nrf52/startup_nrf52840.c index 30634a1b5..8e1c36012 100644 --- a/ports/nrf/device/nrf52/startup_nrf52840.c +++ b/ports/nrf/device/nrf52/startup_nrf52840.c @@ -116,7 +116,7 @@ void CRYPTOCELL_IRQHandler (void) __attribute__ ((weak, alias("Default_Han void SPIM3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); void PWM3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); -const func __Vectors[] __attribute__ ((section(".isr_vector"))) = { +const func __Vectors[] __attribute__ ((used, section(".isr_vector"))) = { (func)&_estack, Reset_Handler, NMI_Handler, diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk index 57879bbaa..55920b3f4 100644 --- a/ports/nrf/mpconfigport.mk +++ b/ports/nrf/mpconfigport.mk @@ -14,9 +14,7 @@ LONGINT_IMPL = MPZ CIRCUITPY_AUDIOCORE = 1 CIRCUITPY_AUDIOIO = 0 CIRCUITPY_AUDIOPWMIO = 1 - -# No I2S yet. -CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_AUDIOBUSIO = 1 # No I2CSlave implementation CIRCUITPY_I2CSLAVE = 0 diff --git a/ports/nrf/mphalport.c b/ports/nrf/mphalport.c index 7d9463d0b..bcd9fb114 100644 --- a/ports/nrf/mphalport.c +++ b/ports/nrf/mphalport.c @@ -39,9 +39,7 @@ void mp_hal_delay_ms(mp_uint_t delay) { uint64_t start_tick = ticks_ms; uint64_t duration = 0; while (duration < delay) { - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif + RUN_BACKGROUND_TASKS; // Check to see if we've been CTRL-Ced by autoreload or the user. if(MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) || MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { diff --git a/ports/nrf/sd_mutex.c b/ports/nrf/sd_mutex.c index 7682ffa62..b3162e6af 100644 --- a/ports/nrf/sd_mutex.c +++ b/ports/nrf/sd_mutex.c @@ -37,9 +37,7 @@ void sd_mutex_acquire_check(nrf_mutex_t* p_mutex) { void sd_mutex_acquire_wait(nrf_mutex_t* p_mutex) { while (sd_mutex_acquire(p_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif + RUN_BACKGROUND_TASKS; } } diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 1dbca8c61..393b7600c 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -596,8 +596,8 @@ extern const struct _mp_obj_module_t ustack_module; WIZNET_MODULE \ PEW_MODULE \ PIXELBUF_MODULE \ - PULSEIO_MODULE \ PS2IO_MODULE \ + PULSEIO_MODULE \ RANDOM_MODULE \ RE_MODULE \ ROTARYIO_MODULE \ @@ -645,6 +645,7 @@ extern const struct _mp_obj_module_t ustack_module; NETWORK_ROOT_POINTERS \ void run_background_tasks(void); +#define RUN_BACKGROUND_TASKS (run_background_tasks()) // TODO: Used in wiznet5k driver, but may not be needed in the long run. #define MICROPY_THREAD_YIELD() diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 7469fbf3f..949cd1d18 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -74,6 +74,12 @@ CIRCUITPY_AUDIOIO = $(CIRCUITPY_FULL_BUILD) endif CFLAGS += -DCIRCUITPY_AUDIOIO=$(CIRCUITPY_AUDIOIO) +ifndef CIRCUITPY_AUDIOIO_COMPAT +CIRCUITPY_AUDIOIO_COMPAT = $(CIRCUITPY_AUDIOIO) +endif +CFLAGS += -DCIRCUITPY_AUDIOIO_COMPAT=$(CIRCUITPY_AUDIOIO_COMPAT) + + ifndef CIRCUITPY_AUDIOPWMIO CIRCUITPY_AUDIOPWMIO = 0 endif diff --git a/shared-bindings/_stage/__init__.c b/shared-bindings/_stage/__init__.c index 485fa80c5..6096f6b6d 100644 --- a/shared-bindings/_stage/__init__.c +++ b/shared-bindings/_stage/__init__.c @@ -96,9 +96,7 @@ STATIC mp_obj_t stage_render(size_t n_args, const mp_obj_t *args) { } while (!displayio_display_begin_transaction(display)) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP ; -#endif + RUN_BACKGROUND_TASKS; } displayio_area_t area; area.x1 = x0; diff --git a/shared-bindings/audiocore/WaveFile.c b/shared-bindings/audiocore/WaveFile.c index edb190d3a..1b3a94ff3 100644 --- a/shared-bindings/audiocore/WaveFile.c +++ b/shared-bindings/audiocore/WaveFile.c @@ -39,13 +39,16 @@ //| ======================================================== //| //| A .wav file prepped for audio playback. Only mono and stereo files are supported. Samples must -//| be 8 bit unsigned or 16 bit signed. +//| be 8 bit unsigned or 16 bit signed. If a buffer is provided, it will be used instead of allocating +//| an internal buffer. //| -//| .. class:: WaveFile(file) +//| .. class:: WaveFile(file[, buffer]) //| //| Load a .wav file for playback with `audioio.AudioOut` or `audiobusio.I2SOut`. //| //| :param typing.BinaryIO file: Already opened wave file +//| :param bytearray buffer: Optional pre-allocated buffer, that will be split in half and used for double-buffering of the data. If not provided, two 512 byte buffers are allocated internally. +//| //| //| Playing a wave file from flash:: //| @@ -69,15 +72,23 @@ //| print("stopped") //| STATIC mp_obj_t audioio_wavefile_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - mp_arg_check_num(n_args, kw_args, 1, 1, false); + mp_arg_check_num(n_args, kw_args, 1, 2, false); audioio_wavefile_obj_t *self = m_new_obj(audioio_wavefile_obj_t); self->base.type = &audioio_wavefile_type; - if (MP_OBJ_IS_TYPE(args[0], &mp_type_fileio)) { - common_hal_audioio_wavefile_construct(self, MP_OBJ_TO_PTR(args[0])); - } else { + if (!MP_OBJ_IS_TYPE(args[0], &mp_type_fileio)) { mp_raise_TypeError(translate("file must be a file opened in byte mode")); } + uint8_t *buffer = NULL; + size_t buffer_size = 0; + if (n_args >= 2) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE); + buffer = bufinfo.buf; + buffer_size = bufinfo.len; + } + common_hal_audioio_wavefile_construct(self, MP_OBJ_TO_PTR(args[0]), + buffer, buffer_size); return MP_OBJ_FROM_PTR(self); } diff --git a/shared-bindings/audiocore/WaveFile.h b/shared-bindings/audiocore/WaveFile.h index d2572318b..f4a172319 100644 --- a/shared-bindings/audiocore/WaveFile.h +++ b/shared-bindings/audiocore/WaveFile.h @@ -35,7 +35,7 @@ extern const mp_obj_type_t audioio_wavefile_type; void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self, - pyb_file_obj_t* file); + pyb_file_obj_t* file, uint8_t *buffer, size_t buffer_size); void common_hal_audioio_wavefile_deinit(audioio_wavefile_obj_t* self); bool common_hal_audioio_wavefile_deinited(audioio_wavefile_obj_t* self); diff --git a/shared-bindings/audioio/__init__.c b/shared-bindings/audioio/__init__.c index 3fecf2708..bd771dda2 100644 --- a/shared-bindings/audioio/__init__.c +++ b/shared-bindings/audioio/__init__.c @@ -33,6 +33,12 @@ #include "shared-bindings/audioio/__init__.h" #include "shared-bindings/audioio/AudioOut.h" +#ifdef CIRCUITPY_AUDIOIO_COMPAT +#include "shared-bindings/audiocore/Mixer.h" +#include "shared-bindings/audiocore/RawSample.h" +#include "shared-bindings/audiocore/WaveFile.h" +#endif + //| :mod:`audioio` --- Support for audio input and output //| ====================================================== //| @@ -57,10 +63,19 @@ //| Since CircuitPython 5, `Mixer`, `RawSample` and `WaveFile` are moved //| to :mod:`audiocore`. //| +//| For compatibility with CircuitPython 4.x, some builds allow the items in +//| `audiocore` to be imported from `audioio`. This will be removed for all +//| boards in a future build of CicuitPython. +//| STATIC const mp_rom_map_elem_t audioio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audioio) }, { MP_ROM_QSTR(MP_QSTR_AudioOut), MP_ROM_PTR(&audioio_audioout_type) }, +#ifdef CIRCUITPY_AUDIOIO_COMPAT + { MP_ROM_QSTR(MP_QSTR_Mixer), MP_ROM_PTR(&audioio_mixer_type) }, + { MP_ROM_QSTR(MP_QSTR_RawSample), MP_ROM_PTR(&audioio_rawsample_type) }, + { MP_ROM_QSTR(MP_QSTR_WaveFile), MP_ROM_PTR(&audioio_wavefile_type) }, +#endif }; STATIC MP_DEFINE_CONST_DICT(audioio_module_globals, audioio_module_globals_table); diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index af64a2028..0d41359ee 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -119,9 +119,7 @@ STATIC mp_obj_t displayio_fourwire_obj_send(mp_obj_t self, mp_obj_t command_obj, // Wait for display bus to be available. while (!common_hal_displayio_fourwire_begin_transaction(self)) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP ; -#endif + RUN_BACKGROUND_TASKS; } common_hal_displayio_fourwire_send(self, true, &command, 1); common_hal_displayio_fourwire_send(self, false, ((uint8_t*) bufinfo.buf), bufinfo.len); diff --git a/shared-bindings/displayio/I2CDisplay.c b/shared-bindings/displayio/I2CDisplay.c index 1f74e8c9e..9ef989d71 100644 --- a/shared-bindings/displayio/I2CDisplay.c +++ b/shared-bindings/displayio/I2CDisplay.c @@ -111,9 +111,7 @@ STATIC mp_obj_t displayio_i2cdisplay_obj_send(mp_obj_t self, mp_obj_t command_ob // Wait for display bus to be available. while (!common_hal_displayio_i2cdisplay_begin_transaction(self)) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP ; -#endif + RUN_BACKGROUND_TASKS; } uint8_t full_command[bufinfo.len + 1]; full_command[0] = command; diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c index 00a96d230..c29c79fff 100644 --- a/shared-bindings/displayio/ParallelBus.c +++ b/shared-bindings/displayio/ParallelBus.c @@ -122,9 +122,7 @@ STATIC mp_obj_t displayio_parallelbus_obj_send(mp_obj_t self, mp_obj_t command_o // Wait for display bus to be available. while (!common_hal_displayio_parallelbus_begin_transaction(self)) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP ; -#endif + RUN_BACKGROUND_TASKS; } common_hal_displayio_parallelbus_send(self, true, &command, 1); common_hal_displayio_parallelbus_send(self, false, ((uint8_t*) bufinfo.buf), bufinfo.len); diff --git a/shared-bindings/i2cslave/I2CSlave.c b/shared-bindings/i2cslave/I2CSlave.c index 2598accbb..c98ea52e0 100644 --- a/shared-bindings/i2cslave/I2CSlave.c +++ b/shared-bindings/i2cslave/I2CSlave.c @@ -182,7 +182,7 @@ STATIC mp_obj_t i2cslave_i2c_slave_request(size_t n_args, const mp_obj_t *pos_ar bool is_read; bool is_restart; - MICROPY_VM_HOOK_LOOP + RUN_BACKGROUND_TASKS; if (mp_hal_is_interrupted()) { return mp_const_none; } @@ -337,7 +337,7 @@ STATIC mp_obj_t i2cslave_i2c_slave_request_read(size_t n_args, const mp_obj_t *p uint8_t *buffer = NULL; uint64_t timeout_end = common_hal_time_monotonic() + 10 * 1000; while (common_hal_time_monotonic() < timeout_end) { - MICROPY_VM_HOOK_LOOP + RUN_BACKGROUND_TASKS; if (mp_hal_is_interrupted()) { break; } @@ -382,7 +382,7 @@ STATIC mp_obj_t i2cslave_i2c_slave_request_write(mp_obj_t self_in, mp_obj_t buf_ mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); for (size_t i = 0; i < bufinfo.len; i++) { - MICROPY_VM_HOOK_LOOP + RUN_BACKGROUND_TASKS; if (mp_hal_is_interrupted()) { break; } diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index f34cb9c46..2654de09a 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -236,9 +236,16 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { return rtc_get_time_source_time(); } - mp_int_t secs = mp_obj_int_get_checked(args[0]); - if (secs < EPOCH1970_EPOCH2000_DIFF_SECS) + mp_obj_t arg = args[0]; + if (mp_obj_is_float(arg)) { + arg = mp_obj_new_int_from_float(mp_obj_get_float(arg)); + } + + mp_int_t secs = mp_obj_get_int(arg); + + if (secs < EPOCH1970_EPOCH2000_DIFF_SECS) { mp_raise_msg(&mp_type_OverflowError, translate("timestamp out of range for platform time_t")); + } timeutils_struct_time_t tm; timeutils_seconds_since_epoch_to_struct_time(secs, &tm); @@ -270,8 +277,9 @@ STATIC mp_obj_t time_mktime(mp_obj_t t) { mp_raise_TypeError(translate("function takes exactly 9 arguments")); } - if (mp_obj_get_int(elem[0]) < 2000) + if (mp_obj_get_int(elem[0]) < 2000) { mp_raise_msg(&mp_type_OverflowError, translate("timestamp out of range for platform time_t")); + } mp_uint_t secs = timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]), mp_obj_get_int(elem[3]), mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5])); diff --git a/shared-module/audiocore/WaveFile.c b/shared-module/audiocore/WaveFile.c index 810d9c33b..df5d4b61d 100644 --- a/shared-module/audiocore/WaveFile.c +++ b/shared-module/audiocore/WaveFile.c @@ -46,7 +46,9 @@ struct wave_format_chunk { }; void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self, - pyb_file_obj_t* file) { + pyb_file_obj_t* file, + uint8_t *buffer, + size_t buffer_size) { // Load the wave self->file = file; uint8_t chunk_header[16]; @@ -84,7 +86,6 @@ void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self, } // Get the sample_rate self->sample_rate = format.sample_rate; - self->len = 256; self->channel_count = format.num_channels; self->bits_per_sample = format.bits_per_sample; @@ -111,21 +112,31 @@ void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self, // Try to allocate two buffers, one will be loaded from file and the other // DMAed to DAC. - self->buffer = m_malloc(self->len, false); - if (self->buffer == NULL) { - common_hal_audioio_wavefile_deinit(self); - mp_raise_msg(&mp_type_MemoryError, translate("Couldn't allocate first buffer")); - } + if (buffer_size) { + self->len = buffer_size / 2; + self->buffer = buffer; + self->second_buffer = buffer + self->len; + } else { + self->len = 256; + self->buffer = m_malloc(self->len, false); + if (self->buffer == NULL) { + common_hal_audioio_wavefile_deinit(self); + mp_raise_msg(&mp_type_MemoryError, + translate("Couldn't allocate first buffer")); + } - self->second_buffer = m_malloc(self->len, false); - if (self->second_buffer == NULL) { - common_hal_audioio_wavefile_deinit(self); - mp_raise_msg(&mp_type_MemoryError, translate("Couldn't allocate second buffer")); + self->second_buffer = m_malloc(self->len, false); + if (self->second_buffer == NULL) { + common_hal_audioio_wavefile_deinit(self); + mp_raise_msg(&mp_type_MemoryError, + translate("Couldn't allocate second buffer")); + } } } void common_hal_audioio_wavefile_deinit(audioio_wavefile_obj_t* self) { self->buffer = NULL; + self->second_buffer = NULL; } bool common_hal_audioio_wavefile_deinited(audioio_wavefile_obj_t* self) { diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index aa36ee982..c23c66b8b 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -85,9 +85,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, uint32_t i = 0; while (!self->begin_transaction(self->bus)) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP ; -#endif + RUN_BACKGROUND_TASKS; } while (i < init_sequence_len) { uint8_t *cmd = init_sequence + i; @@ -242,7 +240,7 @@ int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* sel uint64_t last_refresh = self->last_refresh; // Don't try to refresh if we got an exception. while (last_refresh == self->last_refresh && MP_STATE_VM(mp_pending_exception) == NULL) { - MICROPY_VM_HOOK_LOOP + RUN_BACKGROUND_TASKS; } return 0; } diff --git a/tools/check_translations.py b/tools/check_translations.py index 4bea040bf..7c008d3da 100644 --- a/tools/check_translations.py +++ b/tools/check_translations.py @@ -16,8 +16,10 @@ for po_filename in po_filenames: po_file = polib.pofile(po_filename) po_ids = set([x.msgid for x in po_file]) - if all_ids - po_ids: + missing = all_ids - po_ids + if missing: print("Missing message id. Please run `make translate`") + print(missing) sys.exit(-1) else: print("ok") |
