From 80abd2d6455f868d1678cddfdd82ee46588eb2a8 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 3 Dec 2021 18:19:13 -0500 Subject: [PATCH 01/18] Use a longer clock stretching timeout for RP2040 zero-byte I2C writes --- ports/raspberrypi/common-hal/busio/I2C.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ports/raspberrypi/common-hal/busio/I2C.c b/ports/raspberrypi/common-hal/busio/I2C.c index 96038b4241..87c78814c2 100644 --- a/ports/raspberrypi/common-hal/busio/I2C.c +++ b/ports/raspberrypi/common-hal/busio/I2C.c @@ -109,8 +109,11 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, // set up as GPIO by the bitbangio.I2C object. // // Sets pins to open drain, high, and input. + // + // Do not use the default supplied clock stretching timeout here. + // It is too short for some devices. Use the busio timeout instead. shared_module_bitbangio_i2c_construct(&self->bitbangio_i2c, scl, sda, - frequency, timeout); + frequency, BUS_TIMEOUT_US); self->baudrate = i2c_init(self->peripheral, frequency); From f49271b472786a6cb82ffd4083ef744c555f2a38 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Sat, 4 Dec 2021 11:34:49 -0600 Subject: [PATCH 02/18] disable interrupts inside of ports raspberrypi common hal --- ports/raspberrypi/common-hal/nvm/ByteArray.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ports/raspberrypi/common-hal/nvm/ByteArray.c b/ports/raspberrypi/common-hal/nvm/ByteArray.c index 6908cbeabf..e045f4365b 100644 --- a/ports/raspberrypi/common-hal/nvm/ByteArray.c +++ b/ports/raspberrypi/common-hal/nvm/ByteArray.c @@ -31,6 +31,7 @@ #include "py/runtime.h" #include "src/rp2_common/hardware_flash/include/hardware/flash.h" +#include "shared-bindings/microcontroller/__init__.h" extern uint32_t __flash_binary_start; static const uint32_t flash_binary_start = (uint32_t)&__flash_binary_start; @@ -71,6 +72,8 @@ void common_hal_nvm_bytearray_get_bytes(const nvm_bytearray_obj_t *self, bool common_hal_nvm_bytearray_set_bytes(const nvm_bytearray_obj_t *self, uint32_t start_index, uint8_t *values, uint32_t len) { + // disable interrupts to prevent core hang on rp2040 + common_hal_mcu_disable_interrupts(); uint8_t values_in[len]; common_hal_nvm_bytearray_get_bytes(self, start_index, len, values_in); @@ -99,5 +102,6 @@ bool common_hal_nvm_bytearray_set_bytes(const nvm_bytearray_obj_t *self, erase_and_write_sector(start_index, len, values); } + common_hal_mcu_enable_interrupts(); return true; } From 5e7c1328b04b7745a2699110bee360a48948923f Mon Sep 17 00:00:00 2001 From: foamyguy Date: Sat, 4 Dec 2021 12:21:51 -0600 Subject: [PATCH 03/18] disable interrupts inside of write_page and erase_write_sector --- ports/raspberrypi/common-hal/nvm/ByteArray.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ports/raspberrypi/common-hal/nvm/ByteArray.c b/ports/raspberrypi/common-hal/nvm/ByteArray.c index e045f4365b..655361deea 100644 --- a/ports/raspberrypi/common-hal/nvm/ByteArray.c +++ b/ports/raspberrypi/common-hal/nvm/ByteArray.c @@ -43,6 +43,9 @@ uint32_t common_hal_nvm_bytearray_get_length(const nvm_bytearray_obj_t *self) { } static void write_page(uint32_t page_addr, uint32_t offset, uint32_t len, uint8_t *bytes) { + // disable interrupts to prevent core hang on rp2040 + common_hal_mcu_disable_interrupts(); + // Write a whole page to flash, buffering it first and then erasing and rewriting it // since we can only write a whole page at a time. if (offset == 0 && len == FLASH_PAGE_SIZE) { @@ -53,9 +56,13 @@ static void write_page(uint32_t page_addr, uint32_t offset, uint32_t len, uint8_ memcpy(buffer + offset, bytes, len); flash_range_program(RMV_OFFSET(page_addr), buffer, FLASH_PAGE_SIZE); } + common_hal_mcu_enable_interrupts(); } static void erase_and_write_sector(uint32_t address, uint32_t len, uint8_t *bytes) { + // disable interrupts to prevent core hang on rp2040 + common_hal_mcu_disable_interrupts(); + // Write a whole sector to flash, buffering it first and then erasing and rewriting it // since we can only erase a whole sector at a time. uint8_t buffer[FLASH_SECTOR_SIZE]; @@ -63,6 +70,7 @@ static void erase_and_write_sector(uint32_t address, uint32_t len, uint8_t *byte memcpy(buffer + address, bytes, len); flash_range_erase(RMV_OFFSET(CIRCUITPY_INTERNAL_NVM_START_ADDR), FLASH_SECTOR_SIZE); flash_range_program(RMV_OFFSET(CIRCUITPY_INTERNAL_NVM_START_ADDR), buffer, FLASH_SECTOR_SIZE); + common_hal_mcu_enable_interrupts(); } void common_hal_nvm_bytearray_get_bytes(const nvm_bytearray_obj_t *self, @@ -72,8 +80,6 @@ void common_hal_nvm_bytearray_get_bytes(const nvm_bytearray_obj_t *self, bool common_hal_nvm_bytearray_set_bytes(const nvm_bytearray_obj_t *self, uint32_t start_index, uint8_t *values, uint32_t len) { - // disable interrupts to prevent core hang on rp2040 - common_hal_mcu_disable_interrupts(); uint8_t values_in[len]; common_hal_nvm_bytearray_get_bytes(self, start_index, len, values_in); @@ -102,6 +108,5 @@ bool common_hal_nvm_bytearray_set_bytes(const nvm_bytearray_obj_t *self, erase_and_write_sector(start_index, len, values); } - common_hal_mcu_enable_interrupts(); return true; } From fa37ee64844fefc770fca3f4a5a7c1253c8e580a Mon Sep 17 00:00:00 2001 From: foamyguy Date: Sat, 4 Dec 2021 14:14:23 -0600 Subject: [PATCH 04/18] limit disable interrupts to flash calls --- ports/raspberrypi/common-hal/nvm/ByteArray.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/ports/raspberrypi/common-hal/nvm/ByteArray.c b/ports/raspberrypi/common-hal/nvm/ByteArray.c index 655361deea..a6c8a5ad6a 100644 --- a/ports/raspberrypi/common-hal/nvm/ByteArray.c +++ b/ports/raspberrypi/common-hal/nvm/ByteArray.c @@ -43,31 +43,32 @@ uint32_t common_hal_nvm_bytearray_get_length(const nvm_bytearray_obj_t *self) { } static void write_page(uint32_t page_addr, uint32_t offset, uint32_t len, uint8_t *bytes) { - // disable interrupts to prevent core hang on rp2040 - common_hal_mcu_disable_interrupts(); - // Write a whole page to flash, buffering it first and then erasing and rewriting it // since we can only write a whole page at a time. if (offset == 0 && len == FLASH_PAGE_SIZE) { + // disable interrupts to prevent core hang on rp2040 + common_hal_mcu_disable_interrupts(); flash_range_program(RMV_OFFSET(page_addr), bytes, FLASH_PAGE_SIZE); + common_hal_mcu_enable_interrupts(); } else { uint8_t buffer[FLASH_PAGE_SIZE]; memcpy(buffer, (uint8_t *)page_addr, FLASH_PAGE_SIZE); memcpy(buffer + offset, bytes, len); + common_hal_mcu_disable_interrupts(); flash_range_program(RMV_OFFSET(page_addr), buffer, FLASH_PAGE_SIZE); + common_hal_mcu_enable_interrupts(); } - common_hal_mcu_enable_interrupts(); + } static void erase_and_write_sector(uint32_t address, uint32_t len, uint8_t *bytes) { - // disable interrupts to prevent core hang on rp2040 - common_hal_mcu_disable_interrupts(); - // Write a whole sector to flash, buffering it first and then erasing and rewriting it // since we can only erase a whole sector at a time. uint8_t buffer[FLASH_SECTOR_SIZE]; memcpy(buffer, (uint8_t *)CIRCUITPY_INTERNAL_NVM_START_ADDR, FLASH_SECTOR_SIZE); memcpy(buffer + address, bytes, len); + // disable interrupts to prevent core hang on rp2040 + common_hal_mcu_disable_interrupts(); flash_range_erase(RMV_OFFSET(CIRCUITPY_INTERNAL_NVM_START_ADDR), FLASH_SECTOR_SIZE); flash_range_program(RMV_OFFSET(CIRCUITPY_INTERNAL_NVM_START_ADDR), buffer, FLASH_SECTOR_SIZE); common_hal_mcu_enable_interrupts(); From 92bb909bf069c0e4caebf3082eece0272a0bafe8 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sun, 5 Dec 2021 14:42:24 -0500 Subject: [PATCH 05/18] add a frequencyin_reset() for VM restart --- .../common-hal/frequencyio/FrequencyIn.c | 44 ++++++++++++------- .../common-hal/frequencyio/FrequencyIn.h | 9 +--- ports/atmel-samd/supervisor/port.c | 10 ++++- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c b/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c index f973db90b0..57b173e72c 100644 --- a/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +++ b/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c @@ -54,12 +54,23 @@ #endif static frequencyio_frequencyin_obj_t *active_frequencyins[TC_INST_NUM]; -volatile uint8_t reference_tc = 0xff; +volatile uint8_t reference_tc; #ifdef SAM_D5X_E5X static uint8_t dpll_gclk; #endif -void frequencyin_emergency_cancel_capture(uint8_t index) { +void frequencyin_reset(void) { + for (uint8_t i = 0; i < TC_INST_NUM; i++) { + active_frequencyins[i] = NULL; + } + + reference_tc = 0xff; + #ifdef SAM_D5X_E5X + dpll_gclk = 0xff; + #endif +} + +static void frequencyin_emergency_cancel_capture(uint8_t index) { frequencyio_frequencyin_obj_t* self = active_frequencyins[index]; NVIC_DisableIRQ(self->TC_IRQ); @@ -93,7 +104,7 @@ void frequencyin_interrupt_handler(uint8_t index) { uint64_t current_ns = common_hal_time_monotonic_ns(); - for (uint8_t i = 0; i <= (TC_INST_NUM - 1); i++) { + for (uint8_t i = 0; i < TC_INST_NUM; i++) { if (active_frequencyins[i] != NULL) { frequencyio_frequencyin_obj_t* self = active_frequencyins[i]; Tc* tc = tc_insts[self->tc_index]; @@ -143,7 +154,7 @@ void frequencyin_interrupt_handler(uint8_t index) { ref_tc->COUNT16.INTFLAG.reg |= TC_INTFLAG_OVF; } -void frequencyin_reference_tc_init() { +static void frequencyin_reference_tc_init(void) { if (reference_tc == 0xff) { return; } @@ -154,9 +165,6 @@ void frequencyin_reference_tc_init() { // use the DPLL we setup so that the reference_tc and freqin_tc(s) // are using the same clock frequency. #ifdef SAM_D5X_E5X - if (dpll_gclk == 0xff) { - frequencyin_samd51_start_dpll(); - } set_timer_handler(true, reference_tc, TC_HANDLER_FREQUENCYIN); turn_on_clocks(true, reference_tc, dpll_gclk); #endif @@ -178,7 +186,7 @@ void frequencyin_reference_tc_init() { #endif } -bool frequencyin_reference_tc_enabled() { +static bool frequencyin_reference_tc_enabled(void) { if (reference_tc == 0xff) { return false; } @@ -186,7 +194,7 @@ bool frequencyin_reference_tc_enabled() { return tc->COUNT16.CTRLA.bit.ENABLE; } -void frequencyin_reference_tc_enable(bool enable) { +static void frequencyin_reference_tc_enable(bool enable) { if (reference_tc == 0xff) { return; } @@ -195,15 +203,15 @@ void frequencyin_reference_tc_enable(bool enable) { } #ifdef SAM_D5X_E5X -void frequencyin_samd51_start_dpll() { +static bool frequencyin_samd51_start_dpll(void) { if (clock_get_enabled(0, GCLK_SOURCE_DPLL1)) { - return; + return true; } uint8_t free_gclk = find_free_gclk(1); if (free_gclk == 0xff) { dpll_gclk = 0xff; - return; + return false; } GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL1].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(free_gclk); @@ -228,23 +236,25 @@ void frequencyin_samd51_start_dpll() { while (!(OSCCTRL->Dpll[1].DPLLSTATUS.bit.LOCK || OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY)) {} enable_clock_generator(free_gclk, GCLK_GENCTRL_SRC_DPLL1_Val, 1); dpll_gclk = free_gclk; + return true; } -void frequencyin_samd51_stop_dpll() { +static void frequencyin_samd51_stop_dpll(void) { if (!clock_get_enabled(0, GCLK_SOURCE_DPLL1)) { return; } - disable_clock_generator(dpll_gclk); + if (dpll_gclk != 0xff) { + disable_clock_generator(dpll_gclk); + dpll_gclk = 0xff; + } GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL1].reg = 0; OSCCTRL->Dpll[1].DPLLCTRLA.reg = 0; OSCCTRL->Dpll[1].DPLLRATIO.reg = 0; OSCCTRL->Dpll[1].DPLLCTRLB.reg = 0; - while (OSCCTRL->Dpll[1].DPLLSYNCBUSY.bit.ENABLE) { } - dpll_gclk = 0xff; } #endif @@ -421,7 +431,7 @@ void common_hal_frequencyio_frequencyin_deinit(frequencyio_frequencyin_obj_t* se self->pin = NO_PIN; bool check_active = false; - for (uint8_t i = 0; i <= (TC_INST_NUM - 1); i++) { + for (uint8_t i = 0; i < TC_INST_NUM; i++) { if (active_frequencyins[i] != NULL) { check_active = true; } diff --git a/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.h b/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.h index 53b9f2d2d1..b1d5a58bdb 100644 --- a/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.h +++ b/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.h @@ -46,14 +46,7 @@ typedef struct { } frequencyio_frequencyin_obj_t; void frequencyin_interrupt_handler(uint8_t index); -void frequencyin_emergency_cancel_capture(uint8_t index); -void frequencyin_reference_tc_init(void); -void frequencyin_reference_tc_enable(bool enable); -bool frequencyin_reference_tc_enabled(void); -#ifdef SAM_D5X_E5X -void frequencyin_samd51_start_dpll(void); -void frequencyin_samd51_stop_dpll(void); -#endif +void frequencyin_reset(void); #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_FREQUENCYIO_FREQUENCYIN_H diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index ccff352443..3298e691ab 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -71,6 +71,10 @@ #include "common-hal/busio/__init__.h" #endif +#if CIRCUITPY_FREQUENCYIO +#include "common-hal/frequencyio/FrequencyIn.h" +#endif + #include "common-hal/microcontroller/Pin.h" #if CIRCUITPY_PULSEIO @@ -388,6 +392,10 @@ void reset_port(void) { i2sout_reset(); #endif + #if CIRCUITPY_FREQUENCYIO + frequencyin_reset(); + #endif + #if CIRCUITPY_TOUCHIO && CIRCUITPY_TOUCHIO_USE_NATIVE touchin_reset(); #endif @@ -399,7 +407,7 @@ void reset_port(void) { #if CIRCUITPY_PWMIO pwmout_reset(); #endif - #if CIRCUITPY_PWMIO || CIRCUITPY_AUDIOIO + #if CIRCUITPY_PWMIO || CIRCUITPY_AUDIOIO || CIRCUITPY_FREQUENCYIO reset_timers(); #endif From 5fe4c3bec90435a036083aea6e4a347333876fb5 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sun, 5 Dec 2021 21:16:46 -0500 Subject: [PATCH 06/18] fix mistaken use of PWM channel for slice --- .../common-hal/audiopwmio/PWMAudioOut.c | 2 +- .../raspberrypi/common-hal/countio/Counter.c | 11 ++-- ports/raspberrypi/common-hal/pwmio/PWMOut.c | 52 +++++++++---------- ports/raspberrypi/common-hal/pwmio/PWMOut.h | 24 ++++----- 4 files changed, 45 insertions(+), 44 deletions(-) diff --git a/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c index 0654037d66..4b4c365385 100644 --- a/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +++ b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c @@ -207,7 +207,7 @@ void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self, uint32_t tx_register = (uint32_t)&pwm_hw->slice[self->left_pwm.slice].cc; if (self->stereo) { // Shift the destination if we are outputting to both PWM channels. - tx_register += self->left_pwm.channel * sizeof(uint16_t); + tx_register += self->left_pwm.ab_channel * sizeof(uint16_t); } self->pacing_timer = pacing_timer; diff --git a/ports/raspberrypi/common-hal/countio/Counter.c b/ports/raspberrypi/common-hal/countio/Counter.c index bbf71f996e..fe7dd545f8 100644 --- a/ports/raspberrypi/common-hal/countio/Counter.c +++ b/ports/raspberrypi/common-hal/countio/Counter.c @@ -25,8 +25,8 @@ void common_hal_countio_counter_construct(countio_counter_obj_t *self, mp_raise_RuntimeError(translate("PWM slice already in use")); } - uint8_t channel = pwm_gpio_to_channel(self->pin_a); - if (!pwmio_claim_slice_channels(self->slice_num)) { + uint8_t ab_channel = pwm_gpio_to_channel(self->pin_a); + if (!pwmio_claim_slice_ab_channels(self->slice_num)) { mp_raise_RuntimeError(translate("PWM slice channel A already in use")); } @@ -69,7 +69,7 @@ void common_hal_countio_counter_deinit(countio_counter_obj_t *self) { pwm_set_enabled(self->slice_num, false); pwm_set_irq_enabled(self->slice_num, false); - pwmio_release_slice_channels(self->slice_num); + pwmio_release_slice_ab_channels(self->slice_num); reset_pin_number(self->pin_a); @@ -98,13 +98,14 @@ void common_hal_countio_counter_reset(countio_counter_obj_t *self) { void counter_interrupt_handler(void) { uint32_t mask = pwm_get_irq_status_mask(); - uint8_t i = 1, pos = 1; + uint8_t i = 1; + uint8_t pos = 0; while (!(i & mask)) { i = i << 1; ++pos; } - countio_counter_obj_t *self = MP_STATE_PORT(counting)[pos - 1]; + countio_counter_obj_t *self = MP_STATE_PORT(counting)[pos]; if (self != NULL) { pwm_clear_irq(self->slice_num); self->count += 65536; diff --git a/ports/raspberrypi/common-hal/pwmio/PWMOut.c b/ports/raspberrypi/common-hal/pwmio/PWMOut.c index 27e9bd4d03..3ef4fb57f3 100644 --- a/ports/raspberrypi/common-hal/pwmio/PWMOut.c +++ b/ports/raspberrypi/common-hal/pwmio/PWMOut.c @@ -42,7 +42,7 @@ uint32_t target_slice_frequencies[NUM_PWM_SLICES]; uint32_t slice_variable_frequency; -#define CHANNELS_PER_SLICE 2 +#define AB_CHANNELS_PER_SLICE 2 static uint32_t channel_use; static uint32_t never_reset_channel; @@ -58,11 +58,11 @@ static uint32_t never_reset_channel; // So 65534 should be the maximum top value, and we'll set CC to be TOP+1 as appropriate. #define MAX_TOP 65534 -static uint32_t _mask(uint8_t slice, uint8_t channel) { - return 1 << (slice * CHANNELS_PER_SLICE + channel); +static uint32_t _mask(uint8_t slice, uint8_t ab_channel) { + return 1 << (slice * AB_CHANNELS_PER_SLICE + ab_channel); } -bool pwmio_claim_slice_channels(uint8_t slice) { +bool pwmio_claim_slice_ab_channels(uint8_t slice) { uint32_t channel_use_mask_a = _mask(slice, 0); uint32_t channel_use_mask_b = _mask(slice, 1); @@ -78,37 +78,37 @@ bool pwmio_claim_slice_channels(uint8_t slice) { return true; } -void pwmio_release_slice_channels(uint8_t slice) { +void pwmio_release_slice_ab_channels(uint8_t slice) { uint32_t channel_mask = _mask(slice, 0); channel_use &= ~channel_mask; channel_mask = _mask(slice, 1); channel_use &= ~channel_mask; } -void pwmout_never_reset(uint8_t slice, uint8_t channel) { - never_reset_channel |= _mask(slice, channel); +void pwmout_never_reset(uint8_t slice, uint8_t ab_channel) { + never_reset_channel |= _mask(slice, ab_channel); } -void pwmout_reset_ok(uint8_t slice, uint8_t channel) { - never_reset_channel &= ~_mask(slice, channel); +void pwmout_reset_ok(uint8_t slice, uint8_t ab_channel) { + never_reset_channel &= ~_mask(slice, ab_channel); } void common_hal_pwmio_pwmout_never_reset(pwmio_pwmout_obj_t *self) { - pwmout_never_reset(self->slice, self->channel); + pwmout_never_reset(self->slice, self->ab_channel); never_reset_pin_number(self->pin->number); } void common_hal_pwmio_pwmout_reset_ok(pwmio_pwmout_obj_t *self) { - pwmout_reset_ok(self->slice, self->channel); + pwmout_reset_ok(self->slice, self->ab_channel); } void pwmout_reset(void) { // Reset all slices for (size_t slice = 0; slice < NUM_PWM_SLICES; slice++) { bool reset = true; - for (size_t channel = 0; channel < CHANNELS_PER_SLICE; channel++) { - uint32_t channel_use_mask = _mask(slice, channel); + for (size_t ab_channel = 0; ab_channel < AB_CHANNELS_PER_SLICE; ab_channel++) { + uint32_t channel_use_mask = _mask(slice, ab_channel); if ((never_reset_channel & channel_use_mask) != 0) { reset = false; continue; @@ -124,8 +124,8 @@ void pwmout_reset(void) { } } -pwmout_result_t pwmout_allocate(uint8_t slice, uint8_t channel, bool variable_frequency, uint32_t frequency) { - uint32_t channel_use_mask = _mask(slice, channel); +pwmout_result_t pwmout_allocate(uint8_t slice, uint8_t ab_channel, bool variable_frequency, uint32_t frequency) { + uint32_t channel_use_mask = _mask(slice, ab_channel); // Check the channel first. if ((channel_use & channel_use_mask) != 0) { @@ -171,15 +171,15 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self, } uint8_t slice = pwm_gpio_to_slice_num(pin->number); - uint8_t channel = pwm_gpio_to_channel(pin->number); + uint8_t ab_channel = pwm_gpio_to_channel(pin->number); - int r = pwmout_allocate(slice, channel, variable_frequency, frequency); + int r = pwmout_allocate(slice, ab_channel, variable_frequency, frequency); if (r != PWMOUT_OK) { return r; } self->slice = slice; - self->channel = channel; + self->ab_channel = ab_channel; if (target_slice_frequencies[slice] != frequency) { // Reset the counter and compare values. @@ -202,11 +202,11 @@ bool common_hal_pwmio_pwmout_deinited(pwmio_pwmout_obj_t *self) { return self->pin == NULL; } -void pwmout_free(uint8_t slice, uint8_t channel) { - uint32_t channel_mask = _mask(slice, channel); +void pwmout_free(uint8_t slice, uint8_t ab_channel) { + uint32_t channel_mask = _mask(slice, ab_channel); channel_use &= ~channel_mask; never_reset_channel &= ~channel_mask; - uint32_t slice_mask = ((1 << CHANNELS_PER_SLICE) - 1) << (slice * CHANNELS_PER_SLICE); + uint32_t slice_mask = ((1 << AB_CHANNELS_PER_SLICE) - 1) << (slice * AB_CHANNELS_PER_SLICE); if ((channel_use & slice_mask) == 0) { target_slice_frequencies[slice] = 0; slice_variable_frequency &= ~(1 << slice); @@ -218,7 +218,7 @@ void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t *self) { if (common_hal_pwmio_pwmout_deinited(self)) { return; } - pwmout_free(self->slice, self->channel); + pwmout_free(self->slice, self->ab_channel); reset_pin_number(self->pin->number); self->pin = NULL; } @@ -235,13 +235,13 @@ extern void common_hal_pwmio_pwmout_set_duty_cycle(pwmio_pwmout_obj_t *self, uin compare_count = ((uint32_t)duty * self->top + MAX_TOP / 2) / MAX_TOP; } // compare_count is the CC register value, which should be TOP+1 for 100% duty cycle. - pwm_set_chan_level(self->slice, self->channel, compare_count); + pwm_set_chan_level(self->slice, self->ab_channel, compare_count); // Wait for wrap so that we know our new cc value has been applied. Clear // the internal interrupt and then wait for it to be set. Worst case, we // wait a full cycle. - pwm_hw->intr = 1 << self->channel; - while ((pwm_hw->en & (1 << self->channel)) != 0 && - (pwm_hw->intr & (1 << self->channel)) == 0 && + pwm_hw->intr = 1 << self->slice; + while ((pwm_hw->en & (1 << self->slice)) != 0 && + (pwm_hw->intr & (1 << self->slice)) == 0 && !mp_hal_is_interrupted()) { } } diff --git a/ports/raspberrypi/common-hal/pwmio/PWMOut.h b/ports/raspberrypi/common-hal/pwmio/PWMOut.h index c7707762e4..0d179934d0 100644 --- a/ports/raspberrypi/common-hal/pwmio/PWMOut.h +++ b/ports/raspberrypi/common-hal/pwmio/PWMOut.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PWMIO_PWMOUT_H -#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PWMIO_PWMOUT_H +#ifndef MICROPY_INCLUDED_RASPBERRY_PI_COMMON_HAL_PWMIO_PWMOUT_H +#define MICROPY_INCLUDED_RASPBERRY_PI_COMMON_HAL_PWMIO_PWMOUT_H #include "common-hal/microcontroller/Pin.h" @@ -34,8 +34,8 @@ typedef struct { mp_obj_base_t base; const mcu_pin_obj_t *pin; - uint8_t slice; - uint8_t channel; + uint8_t slice; // 0-7 + uint8_t ab_channel; // 0-1: A or B slice channel bool variable_frequency; uint16_t duty_cycle; uint32_t actual_frequency; @@ -46,13 +46,13 @@ void pwmout_reset(void); // Private API for AudioPWMOut. void pwmio_pwmout_set_top(pwmio_pwmout_obj_t *self, uint16_t top); // Private APIs for RGBMatrix -enum pwmout_result_t pwmout_allocate(uint8_t slice, uint8_t channel, bool variable_frequency, uint32_t frequency); -void pwmout_free(uint8_t slice, uint8_t channel); -void pwmout_never_reset(uint8_t slice, uint8_t channel); -void pwmout_reset_ok(uint8_t slice, uint8_t channel); +enum pwmout_result_t pwmout_allocate(uint8_t slice, uint8_t ab_channel, bool variable_frequency, uint32_t frequency); +void pwmout_free(uint8_t slice, uint8_t ab_channel); +void pwmout_never_reset(uint8_t slice, uint8_t ab_channel); +void pwmout_reset_ok(uint8_t slice, uint8_t ab_channel); -// Private API for countio to claim both channels on a slice -bool pwmio_claim_slice_channels(uint8_t slice); -void pwmio_release_slice_channels(uint8_t slice); +// Private API for countio to claim both ab_channels on a slice +bool pwmio_claim_slice_ab_channels(uint8_t slice); +void pwmio_release_slice_ab_channels(uint8_t slice); -#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PWMIO_PWMOUT_H +#endif // MICROPY_INCLUDED_RASPBERRY_PI_COMMON_HAL_PWMIO_PWMOUT_H From 4a4c5d7ab8926ab44a4d59e95a106ff8225b69b1 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sun, 5 Dec 2021 21:37:00 -0500 Subject: [PATCH 07/18] formatting updates for updated black --- tests/extmod/utimeq1.py | 1 - tools/pydfu.py | 1 - 2 files changed, 2 deletions(-) diff --git a/tests/extmod/utimeq1.py b/tests/extmod/utimeq1.py index 234d7a31dd..ddbc969afb 100644 --- a/tests/extmod/utimeq1.py +++ b/tests/extmod/utimeq1.py @@ -17,7 +17,6 @@ if DEBUG: def dprint(*v): print(*v) - else: def dprint(*v): diff --git a/tools/pydfu.py b/tools/pydfu.py index 26e40f5613..ce34b08a58 100755 --- a/tools/pydfu.py +++ b/tools/pydfu.py @@ -83,7 +83,6 @@ if "length" in inspect.getfullargspec(usb.util.get_string).args: def get_string(dev, index): return usb.util.get_string(dev, 255, index) - else: # PyUSB 1.0.0.b2 dropped the length argument def get_string(dev, index): From da1c330d99dd157c7a57e1f8b7cee9dc7a1a826b Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 6 Dec 2021 08:40:54 -0500 Subject: [PATCH 08/18] formatting updates for updated black --- tests/extmod/utimeq1.py | 1 - tools/pydfu.py | 1 - 2 files changed, 2 deletions(-) diff --git a/tests/extmod/utimeq1.py b/tests/extmod/utimeq1.py index 234d7a31dd..ddbc969afb 100644 --- a/tests/extmod/utimeq1.py +++ b/tests/extmod/utimeq1.py @@ -17,7 +17,6 @@ if DEBUG: def dprint(*v): print(*v) - else: def dprint(*v): diff --git a/tools/pydfu.py b/tools/pydfu.py index 26e40f5613..ce34b08a58 100755 --- a/tools/pydfu.py +++ b/tools/pydfu.py @@ -83,7 +83,6 @@ if "length" in inspect.getfullargspec(usb.util.get_string).args: def get_string(dev, index): return usb.util.get_string(dev, 255, index) - else: # PyUSB 1.0.0.b2 dropped the length argument def get_string(dev, index): From c43e0bd2db03d4f3b03e7512f044b8fa0f45b3f6 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 6 Dec 2021 09:54:15 -0500 Subject: [PATCH 09/18] uncrustify fixes --- ports/broadcom/qstrdefsport.h | 3 +++ ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ports/broadcom/qstrdefsport.h b/ports/broadcom/qstrdefsport.h index ca01f8037c..6b44d1062b 100644 --- a/ports/broadcom/qstrdefsport.h +++ b/ports/broadcom/qstrdefsport.h @@ -26,6 +26,9 @@ // qstrs specific to this port, only needed if they aren't auto-generated +// Prevent uncrustify from modifying these lines. +// *FORMAT-OFF* + // Entries for sys.path Q(/sd) Q(/sd/lib) diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c b/ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c index adc4ae1b01..c6d9b581b3 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c +++ b/ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c @@ -86,7 +86,7 @@ void board_init(void) { common_hal_busio_spi_never_reset(spi); - displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; + displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; bus->base.type = &displayio_fourwire_type; common_hal_displayio_fourwire_construct( @@ -99,7 +99,7 @@ void board_init(void) { 0, // polarity 0 // phase ); - displayio_display_obj_t* display = &displays[0].display; + displayio_display_obj_t *display = &displays[0].display; display->base.type = &displayio_display_type; // workaround as board_init() is called before reset_port() in main.c From ee1987d34ba375e766c1b93a5d0722a08c569a17 Mon Sep 17 00:00:00 2001 From: Kong Wai Weng Date: Mon, 6 Dec 2021 23:12:53 +0800 Subject: [PATCH 10/18] Added Maker Nano RP2040 to branch 7.1.x. --- .../boards/cytron_maker_nano_rp2040/board.c | 40 ++++++++++++++ .../cytron_maker_nano_rp2040/mpconfigboard.h | 12 ++++ .../cytron_maker_nano_rp2040/mpconfigboard.mk | 15 +++++ .../pico-sdk-configboard.h | 4 ++ .../boards/cytron_maker_nano_rp2040/pins.c | 55 +++++++++++++++++++ 5 files changed, 126 insertions(+) create mode 100644 ports/raspberrypi/boards/cytron_maker_nano_rp2040/board.c create mode 100644 ports/raspberrypi/boards/cytron_maker_nano_rp2040/mpconfigboard.h create mode 100644 ports/raspberrypi/boards/cytron_maker_nano_rp2040/mpconfigboard.mk create mode 100644 ports/raspberrypi/boards/cytron_maker_nano_rp2040/pico-sdk-configboard.h create mode 100644 ports/raspberrypi/boards/cytron_maker_nano_rp2040/pins.c diff --git a/ports/raspberrypi/boards/cytron_maker_nano_rp2040/board.c b/ports/raspberrypi/boards/cytron_maker_nano_rp2040/board.c new file mode 100644 index 0000000000..b583e7bf11 --- /dev/null +++ b/ports/raspberrypi/boards/cytron_maker_nano_rp2040/board.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Wai Weng for Cytron Technologies + * + * 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/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} + +void board_deinit(void) { +} diff --git a/ports/raspberrypi/boards/cytron_maker_nano_rp2040/mpconfigboard.h b/ports/raspberrypi/boards/cytron_maker_nano_rp2040/mpconfigboard.h new file mode 100644 index 0000000000..2d182e78c9 --- /dev/null +++ b/ports/raspberrypi/boards/cytron_maker_nano_rp2040/mpconfigboard.h @@ -0,0 +1,12 @@ +#define MICROPY_HW_BOARD_NAME "Cytron Maker Nano RP2040" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO1) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO0) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO18) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO19) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO16) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) diff --git a/ports/raspberrypi/boards/cytron_maker_nano_rp2040/mpconfigboard.mk b/ports/raspberrypi/boards/cytron_maker_nano_rp2040/mpconfigboard.mk new file mode 100644 index 0000000000..fc5f8ead36 --- /dev/null +++ b/ports/raspberrypi/boards/cytron_maker_nano_rp2040/mpconfigboard.mk @@ -0,0 +1,15 @@ +USB_VID = 0x2E8A +USB_PID = 0x100f +USB_PRODUCT = "Maker Nano RP2040" +USB_MANUFACTURER = "Cytron" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" + +CIRCUITPY__EVE = 1 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SimpleIO diff --git a/ports/raspberrypi/boards/cytron_maker_nano_rp2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/cytron_maker_nano_rp2040/pico-sdk-configboard.h new file mode 100644 index 0000000000..a41131dd22 --- /dev/null +++ b/ports/raspberrypi/boards/cytron_maker_nano_rp2040/pico-sdk-configboard.h @@ -0,0 +1,4 @@ +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/cytron_maker_nano_rp2040/pins.c b/ports/raspberrypi/boards/cytron_maker_nano_rp2040/pins.c new file mode 100644 index 0000000000..19b4ffc6fa --- /dev/null +++ b/ports/raspberrypi/boards/cytron_maker_nano_rp2040/pins.c @@ -0,0 +1,55 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_RGB), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_BUZZER), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_GP29_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); From 7e21344cf08200573fa3f882021717497419fa1f Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 6 Dec 2021 22:34:43 -0500 Subject: [PATCH 12/18] fix FrequencyIn for crystalless boards and simplify clock logic --- .../common-hal/frequencyio/FrequencyIn.c | 55 +++++++++++++------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c b/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c index 57b173e72c..62dbc13f65 100644 --- a/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +++ b/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c @@ -57,6 +57,11 @@ static frequencyio_frequencyin_obj_t *active_frequencyins[TC_INST_NUM]; volatile uint8_t reference_tc; #ifdef SAM_D5X_E5X static uint8_t dpll_gclk; + +#if !BOARD_HAS_CRYSTAL +static uint8_t osculp32k_gclk; +#endif + #endif void frequencyin_reset(void) { @@ -67,6 +72,11 @@ void frequencyin_reset(void) { reference_tc = 0xff; #ifdef SAM_D5X_E5X dpll_gclk = 0xff; + + #if !BOARD_HAS_CRYSTAL + osculp32k_gclk = 0xff; + #endif + #endif } @@ -208,34 +218,38 @@ static bool frequencyin_samd51_start_dpll(void) { return true; } - uint8_t free_gclk = find_free_gclk(1); - if (free_gclk == 0xff) { - dpll_gclk = 0xff; + dpll_gclk = find_free_gclk(1); + if (dpll_gclk == 0xff) { return false; } - GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL1].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(free_gclk); // TC4-7 can only have a max of 100MHz source // DPLL1 frequency equation with [X]OSC32K as source: 98.304MHz = 32768(2999 + 1 + 0/32) // Will also enable the Lock Bypass due to low-frequency sources causing DPLL unlocks // as outlined in the Errata (1.12.1) OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0) | OSCCTRL_DPLLRATIO_LDR(2999); -#if BOARD_HAS_CRYSTAL - // we can use XOSC32K directly as the source - OSC32KCTRL->XOSC32K.bit.EN32K = 1; - OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK(1) | OSCCTRL_DPLLCTRLB_LBYPASS; -#else - // can't use OSCULP32K directly; need to setup a GCLK as a reference, - // which must be done in samd/clocks.c to avoid waiting for sync - return; - //OSC32KCTRL->OSCULP32K.bit.EN32K = 1; - //OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK(0); -#endif - OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE; +#if BOARD_HAS_CRYSTAL + // we can use XOSC32K directly as the source. It has already been initialized in clocks.c + OSCCTRL->Dpll[1].DPLLCTRLB.reg = + OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC32_Val) | OSCCTRL_DPLLCTRLB_LBYPASS; +#else + // We can't use OSCULP32K directly. Set up a GCLK controlled by it + // Then use that GCLK as the reference oscillator for the DPLL. + osculp32k_gclk = find_free_gclk(1); + if (osculp32k_gclk == 0xff) { + return false; + } + enable_clock_generator(osculp32k_gclk, GCLK_GENCTRL_SRC_OSCULP32K_Val, 1); + GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL1].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(OSCCTRL_GCLK_ID_FDPLL1); + OSCCTRL->Dpll[1].DPLLCTRLB.reg = + OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_GCLK_Val) | OSCCTRL_DPLLCTRLB_LBYPASS; +#endif + + OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE; while (!(OSCCTRL->Dpll[1].DPLLSTATUS.bit.LOCK || OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY)) {} - enable_clock_generator(free_gclk, GCLK_GENCTRL_SRC_DPLL1_Val, 1); - dpll_gclk = free_gclk; + + enable_clock_generator(dpll_gclk, GCLK_GENCTRL_SRC_DPLL1_Val, 1); return true; } @@ -249,6 +263,11 @@ static void frequencyin_samd51_stop_dpll(void) { dpll_gclk = 0xff; } + if (osculp32k_gclk != 0xff) { + disable_clock_generator(osculp32k_gclk); + osculp32k_gclk = 0xff; + } + GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL1].reg = 0; OSCCTRL->Dpll[1].DPLLCTRLA.reg = 0; OSCCTRL->Dpll[1].DPLLRATIO.reg = 0; From e0e3224253a133bd815121695547a5918ed59adc Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 7 Dec 2021 15:42:31 -0500 Subject: [PATCH 14/18] forgot a check for BOARD_HAS_CRYSTAL --- ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c b/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c index 62dbc13f65..0bc0bc214e 100644 --- a/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +++ b/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c @@ -263,10 +263,12 @@ static void frequencyin_samd51_stop_dpll(void) { dpll_gclk = 0xff; } + #if !BOARD_HAS_CRYSTAL if (osculp32k_gclk != 0xff) { disable_clock_generator(osculp32k_gclk); osculp32k_gclk = 0xff; } + #endif GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL1].reg = 0; OSCCTRL->Dpll[1].DPLLCTRLA.reg = 0; From 981e3705b8f0a4c8fec6c56a152d43fb4859b374 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 7 Dec 2021 15:57:06 -0800 Subject: [PATCH 15/18] Pass ci_fetch_deps.py the sha rather than ref The remote ref may be out of date and not get the right branch history in some cases. actions/checkout also fetches based on sha --- .github/workflows/build.yml | 8 ++++---- .github/workflows/create_website_pr.yml | 2 +- .github/workflows/ports_windows.yml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index daa9e02a8e..f8d16129b5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,7 +35,7 @@ jobs: with: python-version: 3.8 - name: Get CP deps - run: python tools/ci_fetch_deps.py test ${{ github.ref }} + run: python tools/ci_fetch_deps.py test ${{ github.sha }} - name: CircuitPython version run: | git describe --dirty --tags || git log --parents HEAD~4.. @@ -141,7 +141,7 @@ jobs: with: python-version: 3.8 - name: Get CP deps - run: python tools/ci_fetch_deps.py mpy-cross-mac ${{ github.ref }} + run: python tools/ci_fetch_deps.py mpy-cross-mac ${{ github.sha }} - name: CircuitPython version run: | git describe --dirty --tags @@ -197,7 +197,7 @@ jobs: submodules: false fetch-depth: 1 - name: Get CP deps - run: python tools/ci_fetch_deps.py docs ${{ github.ref }} + run: python tools/ci_fetch_deps.py docs ${{ github.sha }} - name: CircuitPython version run: | git describe --dirty --tags @@ -269,7 +269,7 @@ jobs: submodules: false fetch-depth: 1 - name: Get CP deps - run: python tools/ci_fetch_deps.py ${{ matrix.board }} ${{ github.ref }} + run: python tools/ci_fetch_deps.py ${{ matrix.board }} ${{ github.sha }} - name: Install dependencies run: | sudo apt-get install -y gettext diff --git a/.github/workflows/create_website_pr.yml b/.github/workflows/create_website_pr.yml index ad33cca136..007cfbd402 100644 --- a/.github/workflows/create_website_pr.yml +++ b/.github/workflows/create_website_pr.yml @@ -25,7 +25,7 @@ jobs: with: python-version: 3.8 - name: Get CP deps - run: python tools/ci_fetch_deps.py website ${{ github.ref }} + run: python tools/ci_fetch_deps.py website ${{ github.sha }} - name: Install deps run: | pip install -r requirements-dev.txt diff --git a/.github/workflows/ports_windows.yml b/.github/workflows/ports_windows.yml index 8491c4026d..6339746066 100644 --- a/.github/workflows/ports_windows.yml +++ b/.github/workflows/ports_windows.yml @@ -70,7 +70,7 @@ jobs: submodules: false fetch-depth: 1 - name: Get CP deps - run: python tools/ci_fetch_deps.py windows ${{ github.ref }} + run: python tools/ci_fetch_deps.py windows ${{ github.sha }} - name: CircuitPython version run: | git describe --dirty --tags From 474986ff406e0114c541c3c0c44f393244a7503a Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 7 Dec 2021 22:39:17 -0500 Subject: [PATCH 16/18] restore BLEIO HCI background task --- devices/ble_hci/common-hal/_bleio/__init__.c | 2 +- devices/ble_hci/common-hal/_bleio/__init__.h | 2 +- supervisor/shared/tick.c | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/devices/ble_hci/common-hal/_bleio/__init__.c b/devices/ble_hci/common-hal/_bleio/__init__.c index 4a439e8dd2..d8a222ecfe 100644 --- a/devices/ble_hci/common-hal/_bleio/__init__.c +++ b/devices/ble_hci/common-hal/_bleio/__init__.c @@ -107,6 +107,6 @@ void common_hal_bleio_gc_collect(void) { } -void bleio_background(void) { +void bleio_hci_background(void) { bleio_adapter_background(&common_hal_bleio_adapter_obj); } diff --git a/devices/ble_hci/common-hal/_bleio/__init__.h b/devices/ble_hci/common-hal/_bleio/__init__.h index 18bf71834f..f9caf7c5b5 100644 --- a/devices/ble_hci/common-hal/_bleio/__init__.h +++ b/devices/ble_hci/common-hal/_bleio/__init__.h @@ -34,7 +34,7 @@ #include "att.h" #include "hci.h" -void bleio_background(void); +void bleio_hci_background(void); void bleio_reset(void); typedef struct { diff --git a/supervisor/shared/tick.c b/supervisor/shared/tick.c index 40c1ef11e3..94b9d4d15e 100644 --- a/supervisor/shared/tick.c +++ b/supervisor/shared/tick.c @@ -37,6 +37,10 @@ #include "supervisor/shared/autoreload.h" #include "supervisor/shared/stack.h" +#if CIRCUITPY_BLEIO_HCI +#include "common-hal/_bleio/__init__.h" +#endif + #if CIRCUITPY_DISPLAYIO #include "shared-module/displayio/__init__.h" #endif @@ -69,6 +73,10 @@ static void supervisor_background_tasks(void *unused) { assert_heap_ok(); + #if CIRCUITPY_BLEIO_HCI + bleio_hci_background(); + #endif + #if CIRCUITPY_DISPLAYIO displayio_background(); #endif From 7bcfbe30bf608ad5bb395f8f40b755dd91223818 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 8 Dec 2021 11:57:15 -0500 Subject: [PATCH 18/18] shrink some boards --- ports/stm/boards/espruino_pico/mpconfigboard.mk | 1 + ports/stm/boards/pyb_nano_v2/mpconfigboard.mk | 1 + ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk | 5 ++--- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ports/stm/boards/espruino_pico/mpconfigboard.mk b/ports/stm/boards/espruino_pico/mpconfigboard.mk index a078b4841a..6e4da86dd7 100644 --- a/ports/stm/boards/espruino_pico/mpconfigboard.mk +++ b/ports/stm/boards/espruino_pico/mpconfigboard.mk @@ -20,6 +20,7 @@ LD_FILE = boards/STM32F401xd_fs.ld CIRCUITPY_AESIO = 0 CIRCUITPY_AUDIOCORE = 0 CIRCUITPY_AUDIOPWMIO = 0 +CIRCUITPY_BLEIO_HCI = 0 CIRCUITPY_BUSDEVICE = 0 CIRCUITPY_BITMAPTOOLS = 0 CIRCUITPY_FRAMEBUFFERIO = 0 diff --git a/ports/stm/boards/pyb_nano_v2/mpconfigboard.mk b/ports/stm/boards/pyb_nano_v2/mpconfigboard.mk index 29bfd62620..3ba45e0c5b 100644 --- a/ports/stm/boards/pyb_nano_v2/mpconfigboard.mk +++ b/ports/stm/boards/pyb_nano_v2/mpconfigboard.mk @@ -17,6 +17,7 @@ LD_FILE = boards/STM32F411_fs.ld CIRCUITPY_AUDIOCORE = 0 CIRCUITPY_AUDIOPWMIO = 0 CIRCUITPY_BITMAPTOOLS = 0 +CIRCUITPY_BLEIO_HCI = 0 CIRCUITPY_BUSDEVICE = 0 CIRCUITPY_GIFIO = 0 CIRCUITPY_KEYPAD = 0 diff --git a/ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk b/ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk index 61e372b2c3..0929841ea5 100644 --- a/ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk +++ b/ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk @@ -15,8 +15,7 @@ LD_FILE = boards/STM32F411_fs.ld # Too big for the flash CIRCUITPY_AUDIOCORE = 0 CIRCUITPY_AUDIOPWMIO = 0 -CIRCUITPY_KEYPAD = 0 -CIRCUITPY_MIDI = 0 -CIRCUITPY_MSGPACK = 0 CIRCUITPY_BITMAPTOOLS = 0 +CIRCUITPY_BLEIO_HCI = 0 +CIRCUITPY_MSGPACK = 0 CIRCUITPY_VECTORIO = 0