diff --git a/ports/nrf/common-hal/bleio/Adapter.c b/ports/nrf/common-hal/bleio/Adapter.c index 936dfcb9b0..70e87cf787 100644 --- a/ports/nrf/common-hal/bleio/Adapter.c +++ b/ports/nrf/common-hal/bleio/Adapter.c @@ -39,17 +39,37 @@ #include "supervisor/usb.h" #include "shared-bindings/bleio/Adapter.h" #include "shared-bindings/bleio/Address.h" +#include "mpconfigboard.h" // for BOARD_HAS_CRYSTAL STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) { mp_raise_msg_varg(&mp_type_AssertionError, translate("Soft device assert, id: 0x%08lX, pc: 0x%08lX"), id, pc); } +static inline bool board_has_crystal(void) { +#ifdef BOARD_HAS_CRYSTAL + return BOARD_HAS_CRYSTAL == 1; +#else + return false; +#endif +} + STATIC uint32_t ble_stack_enable(void) { - nrf_clock_lf_cfg_t clock_config = { - .source = NRF_CLOCK_LF_SRC_XTAL, - .accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM - }; + nrf_clock_lf_cfg_t clock_config; + + // Set low-frequency clock source to be either an external 32.768kHz crystal if one exists on the board + // or an internal 32.768 kHz RC oscillator otherwise + if (board_has_crystal()) { + clock_config = (nrf_clock_lf_cfg_t){ + .source = NRF_CLOCK_LF_SRC_XTAL, + .accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM}; + } else { + clock_config = (nrf_clock_lf_cfg_t){ + .source = NRF_CLOCK_LF_SRC_RC, + .rc_ctiv = 16, + .rc_temp_ctiv = 2, + .accuracy = NRF_CLOCK_LF_ACCURACY_250_PPM}; + } uint32_t err_code = sd_softdevice_enable(&clock_config, softdevice_assert_handler); if (err_code != NRF_SUCCESS) diff --git a/ports/nrf/peripherals/nrf/clocks.c b/ports/nrf/peripherals/nrf/clocks.c index 4acb878db9..de9eec6b58 100644 --- a/ports/nrf/peripherals/nrf/clocks.c +++ b/ports/nrf/peripherals/nrf/clocks.c @@ -26,11 +26,21 @@ */ #include "nrfx.h" +#include "mpconfigboard.h" // for BOARD_HAS_CRYSTAL + +static inline bool board_has_crystal(void) { +#ifdef BOARD_HAS_CRYSTAL + return BOARD_HAS_CRYSTAL == 1; +#else + return false; +#endif +} void nrf_peripherals_clocks_init(void) { - // Set low-frequency clock source to be crystal. If there's a crystalless board, this will need to be - // generalized. - NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk); + // Set low-frequency clock source to be either an external 32.768kHz crystal if one exists on the board + // or an internal 32.768 kHz RC oscillator otherwise + uint32_t clock_src = board_has_crystal() ? CLOCK_LFCLKSRC_SRC_Xtal : CLOCK_LFCLKSRC_SRC_RC; + NRF_CLOCK->LFCLKSRC = (uint32_t)((clock_src << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk); NRF_CLOCK->TASKS_LFCLKSTART = 1UL; // Wait for clocks to start.