Skip to content

Commit 389e7cc

Browse files
authored
Merge pull request adafruit#2072 from bmeisels/nrf-no-crystal-support
Add support for nrf boards that don't have an external crystal
2 parents 42143ca + fe2ec6c commit 389e7cc

2 files changed

Lines changed: 37 additions & 7 deletions

File tree

ports/nrf/common-hal/bleio/Adapter.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,37 @@
3939
#include "supervisor/usb.h"
4040
#include "shared-bindings/bleio/Adapter.h"
4141
#include "shared-bindings/bleio/Address.h"
42+
#include "mpconfigboard.h" // for BOARD_HAS_CRYSTAL
4243

4344
STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) {
4445
mp_raise_msg_varg(&mp_type_AssertionError,
4546
translate("Soft device assert, id: 0x%08lX, pc: 0x%08lX"), id, pc);
4647
}
4748

49+
static inline bool board_has_crystal(void) {
50+
#ifdef BOARD_HAS_CRYSTAL
51+
return BOARD_HAS_CRYSTAL == 1;
52+
#else
53+
return false;
54+
#endif
55+
}
56+
4857
STATIC uint32_t ble_stack_enable(void) {
49-
nrf_clock_lf_cfg_t clock_config = {
50-
.source = NRF_CLOCK_LF_SRC_XTAL,
51-
.accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM
52-
};
58+
nrf_clock_lf_cfg_t clock_config;
59+
60+
// Set low-frequency clock source to be either an external 32.768kHz crystal if one exists on the board
61+
// or an internal 32.768 kHz RC oscillator otherwise
62+
if (board_has_crystal()) {
63+
clock_config = (nrf_clock_lf_cfg_t){
64+
.source = NRF_CLOCK_LF_SRC_XTAL,
65+
.accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM};
66+
} else {
67+
clock_config = (nrf_clock_lf_cfg_t){
68+
.source = NRF_CLOCK_LF_SRC_RC,
69+
.rc_ctiv = 16,
70+
.rc_temp_ctiv = 2,
71+
.accuracy = NRF_CLOCK_LF_ACCURACY_250_PPM};
72+
}
5373

5474
uint32_t err_code = sd_softdevice_enable(&clock_config, softdevice_assert_handler);
5575
if (err_code != NRF_SUCCESS)

ports/nrf/peripherals/nrf/clocks.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,21 @@
2626
*/
2727

2828
#include "nrfx.h"
29+
#include "mpconfigboard.h" // for BOARD_HAS_CRYSTAL
30+
31+
static inline bool board_has_crystal(void) {
32+
#ifdef BOARD_HAS_CRYSTAL
33+
return BOARD_HAS_CRYSTAL == 1;
34+
#else
35+
return false;
36+
#endif
37+
}
2938

3039
void nrf_peripherals_clocks_init(void) {
31-
// Set low-frequency clock source to be crystal. If there's a crystalless board, this will need to be
32-
// generalized.
33-
NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk);
40+
// Set low-frequency clock source to be either an external 32.768kHz crystal if one exists on the board
41+
// or an internal 32.768 kHz RC oscillator otherwise
42+
uint32_t clock_src = board_has_crystal() ? CLOCK_LFCLKSRC_SRC_Xtal : CLOCK_LFCLKSRC_SRC_RC;
43+
NRF_CLOCK->LFCLKSRC = (uint32_t)((clock_src << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk);
3444
NRF_CLOCK->TASKS_LFCLKSTART = 1UL;
3545

3646
// Wait for clocks to start.

0 commit comments

Comments
 (0)