Appiko
hal_clocks.c
1 
19 #include "hal_clocks.h"
20 #include "log.h"
21 #include "nrf_peripherals.h"
22 
23 void lfclk_init(lfclk_src_t lfclk_src)
24 {
25  if((NRF_CLOCK->LFCLKSTAT & //Clock is running
26  (CLOCK_LFCLKSTAT_STATE_Running << CLOCK_LFCLKSTAT_STATE_Pos)) &&
27  //Correct source is already set
28  ((NRF_CLOCK->LFCLKSTAT & CLOCK_LFCLKSTAT_SRC_Msk) == lfclk_src))
29  {
30  //Already in the required configuration
31  return;
32  }
33 
34  NRF_CLOCK->LFCLKSRC = (lfclk_src << CLOCK_LFCLKSRC_SRC_Pos);
35  NRF_CLOCK->INTENSET = CLOCK_INTENSET_LFCLKSTARTED_Msk;
36  NVIC_ClearPendingIRQ(POWER_CLOCK_IRQn);
37 
38  // Enable wake-up on any event or interrupt (even disabled)
39  SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
40 
41  NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
42  (void)NRF_CLOCK->EVENTS_LFCLKSTARTED;
43  NRF_CLOCK->TASKS_LFCLKSTART = 1;
44  /* Wait for the external oscillator to start up. */
45  while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
46  {
47  __WFE();
48  }
49  /* Clear the event and the pending interrupt */
50  NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
51  (void)NRF_CLOCK->EVENTS_LFCLKSTARTED;
52  NVIC_ClearPendingIRQ(POWER_CLOCK_IRQn);
53  NRF_CLOCK->INTENCLR = CLOCK_INTENCLR_LFCLKSTARTED_Msk;
54 
55  // Enable wake-up on only enabled interrupts
56  SCB->SCR &= (~(SCB_SCR_SEVONPEND_Msk));
57 
58  //Due to errata
59  NRF_RTC0->TASKS_STOP = 0;
60  NRF_RTC1->TASKS_STOP = 0;
61 #if RTC_COUNT == 3
62  NRF_RTC2->TASKS_STOP = 0;
63 #endif
64 }
65 
66 void lfclk_deinit(void)
67 {
68  NRF_CLOCK->TASKS_LFCLKSTOP = 1;
69 }
70 
72 {
73  /* Check if 16 MHz crystal oscillator is already running. */
74  if(NRF_CLOCK->HFCLKSTAT !=
75  ((CLOCK_HFCLKSTAT_STATE_Running << CLOCK_HFCLKSTAT_STATE_Pos) |
76  (CLOCK_HFCLKSTAT_SRC_Xtal << CLOCK_HFCLKSTAT_SRC_Pos)))
77  {
78  NRF_CLOCK->INTENSET = CLOCK_INTENSET_HFCLKSTARTED_Msk;
79  // Enable wake-up on event
80  SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
81 
82  NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
83  (void) NRF_CLOCK->EVENTS_HFCLKSTARTED;
84  NRF_CLOCK->TASKS_HFCLKSTART = 1;
85  /* Wait for the external oscillator to start up. */
86  while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
87  {
88  __WFE();
89  }
90  /* Clear the event and the pending interrupt */
91  NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
92  (void) NRF_CLOCK->EVENTS_HFCLKSTARTED;
93  NVIC_ClearPendingIRQ(POWER_CLOCK_IRQn);
94  NRF_CLOCK->INTENCLR = CLOCK_INTENCLR_HFCLKSTARTED_Msk;
95 
96  // Enable wake-up on only enabled interrupts
97  SCB->SCR &= (~(SCB_SCR_SEVONPEND_Msk));
98  }
99 }
100 
102 {
103  /* Check if 16 MHz crystal oscillator is already running. */
104  if(NRF_CLOCK->HFCLKSTAT !=
105  ((CLOCK_HFCLKSTAT_STATE_Running << CLOCK_HFCLKSTAT_STATE_Pos) |
106  (CLOCK_HFCLKSTAT_SRC_Xtal << CLOCK_HFCLKSTAT_SRC_Pos)))
107  {
108  NRF_CLOCK->TASKS_HFCLKSTART = 1;
109  }
110 }
111 
113 {
114  /* Check if 16 MHz crystal oscillator is already running. */
115  if(NRF_CLOCK->HFCLKSTAT !=
116  ((CLOCK_HFCLKSTAT_STATE_Running << CLOCK_HFCLKSTAT_STATE_Pos) |
117  (CLOCK_HFCLKSTAT_SRC_Xtal << CLOCK_HFCLKSTAT_SRC_Pos)))
118  {
119  /* Wait for the external oscillator to start up. */
120  while (NRF_CLOCK->HFCLKSTAT !=
121  ((CLOCK_HFCLKSTAT_STATE_Running << CLOCK_HFCLKSTAT_STATE_Pos) |
122  (CLOCK_HFCLKSTAT_SRC_Xtal << CLOCK_HFCLKSTAT_SRC_Pos)))
123  {
124 
125  }
126  /* Clear the event and the pending interrupt */
127  NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
128  (void) NRF_CLOCK->EVENTS_HFCLKSTARTED;
129  }
130 }
131 
133 {
134  NRF_CLOCK->TASKS_HFCLKSTOP = 1;
135 }
lfclk_src_t
Definition: hal_clocks.h:36
void hfclk_xtal_deinit(void)
Function to de-initialize the HF clock from using the crystal. RC oscillator will be used to generate...
Definition: hal_clocks.c:132
void lfclk_init(lfclk_src_t lfclk_src)
Function to initialize the LF clock.
Definition: hal_clocks.c:23
void hfclk_xtal_init_nonblocking(void)
Function to initialize the HF clock to use the crystal. This function returns immediately after trigg...
Definition: hal_clocks.c:101
void hfclk_block_till_xtal(void)
Blocks until the HF crystal oscillator is running.
Definition: hal_clocks.c:112
void lfclk_deinit(void)
Function to de-initialize the LF clock. Saves a bit of power as LF clock is not running,...
Definition: hal_clocks.c:66
void hfclk_xtal_init_blocking(void)
Function to start the crystal oscillator to be used for HF clock. This function blocks until the crys...
Definition: hal_clocks.c:71