Skip to content

Commit bfc7fa2

Browse files
committed
mcu/nrf5340: Add API to switch lpclk in the runtime
1 parent 5c01915 commit bfc7fa2

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

hw/mcu/nordic/nrf5340/include/mcu/nrf5340_clock.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,20 @@ int nrf5340_clock_hfxo_request(void);
4343
*/
4444
int nrf5340_clock_hfxo_release(void);
4545

46+
/**
47+
* Request low frequency clock source change.
48+
*
49+
* @param clksrc Value to determine requested clock source
50+
* This parameter can be one of the following values:
51+
* @arg CLOCK_LFCLKSTAT_SRC_LFRC - 32.768 kHz RC oscillator
52+
* @arg CLOCK_LFCLKSTAT_SRC_LFXO - 32.768 kHz crystal oscillator
53+
* @arg CLOCK_LFCLKSTAT_SRC_LFSYNT - 32.768 kHz synthesized from HFCLK
54+
*
55+
* @return int 0: clock source was already as requested. 1: clock source
56+
* changed.
57+
*/
58+
int nrf5340_set_lf_clock_source(uint32_t clksrc);
59+
4660
/**
4761
* Request HFCLK192M clock be turned on. Note that each request must have a
4862
* corresponding release.

hw/mcu/nordic/nrf5340/src/nrf5340_clock.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,58 @@ nrf5340_clock_hfclk192m_release(void)
100100

101101
return stopped;
102102
}
103+
104+
int
105+
nrf5340_set_lf_clock_source(uint32_t clksrc)
106+
{
107+
uint32_t regmsk;
108+
uint32_t regval;
109+
110+
regmsk = CLOCK_LFCLKSTAT_STATE_Msk | CLOCK_LFCLKSTAT_SRC_Msk;
111+
regval = CLOCK_LFCLKSTAT_STATE_Running << CLOCK_LFCLKSTAT_STATE_Pos;
112+
113+
regval |= clksrc << CLOCK_LFCLKSTAT_SRC_Pos;
114+
115+
/* Check if this clock source isn't already running */
116+
if ((NRF_CLOCK->LFCLKSTAT & regmsk) == regval) {
117+
return 0;
118+
}
119+
120+
/*
121+
* Request HFXO if LFSYNTH is going to be set as source. If LFSYNTH is going to be
122+
* replaced with other source, release HFXO.
123+
*/
124+
if (clksrc == CLOCK_LFCLKSTAT_SRC_LFSYNT) {
125+
if ((NRF_CLOCK->HFCLKSTAT & CLOCK_HFCLKSTAT_STATE_Msk) !=
126+
(CLOCK_HFCLKSTAT_STATE_Running << CLOCK_HFCLKSTAT_STATE_Pos)) {
127+
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
128+
nrf5340_clock_hfxo_request();
129+
while (1) {
130+
if ((NRF_CLOCK->EVENTS_HFCLKSTARTED) != 0) {
131+
break;
132+
}
133+
}
134+
} else {
135+
nrf5340_clock_hfxo_request();
136+
}
137+
} else if ((NRF_CLOCK->LFCLKSTAT & CLOCK_LFCLKSTAT_SRC_Msk) ==
138+
CLOCK_LFCLKSTAT_SRC_LFSYNT) {
139+
nrf5340_clock_hfxo_release();
140+
}
141+
142+
NRF_CLOCK->TASKS_LFCLKSTOP = 1;
143+
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
144+
NRF_CLOCK->LFCLKSRC = clksrc;
145+
NRF_CLOCK->TASKS_LFCLKSTART = 1;
146+
147+
/* Wait here till started! */
148+
while (1) {
149+
if (NRF_CLOCK->EVENTS_LFCLKSTARTED) {
150+
if ((NRF_CLOCK->LFCLKSTAT & regmsk) == regval) {
151+
break;
152+
}
153+
}
154+
}
155+
156+
return 1;
157+
}

0 commit comments

Comments
 (0)