BlueToe
an alternative GATT/BLE implementation
Loading...
Searching...
No Matches
nrf.hpp
1#ifndef BLUETOE_BINDINGS_NRF_HPP
2#define BLUETOE_BINDINGS_NRF_HPP
3
4#include <bluetoe/meta_types.hpp>
5#include <bluetoe/default_pdu_layout.hpp>
6
7#include <nrf.h>
8
9namespace bluetoe
10{
11 namespace nrf52_details {
12 void gpio_debug_hfxo_stopped();
13 void init_calibration_timer();
14 void deassign_hfxo();
15 }
16
20 namespace nrf
21 {
22 /*
23 * Some aliases that can be used in the debugger
24 */
25 static NRF_RADIO_Type* const nrf_radio = NRF_RADIO;
26 static NRF_TIMER_Type* const nrf_timer = NRF_TIMER0;
27 static NRF_TIMER_Type* const nrf_cb_timer = NRF_TIMER1;
28 static NRF_CLOCK_Type* const nrf_clock = NRF_CLOCK;
29 static NRF_TEMP_Type* const nrf_temp = NRF_TEMP;
30 static NRF_RTC_Type* const nrf_rtc = NRF_RTC0;
31 static NRF_CCM_Type* const nrf_ccm = NRF_CCM;
32 static NRF_AAR_Type* const nrf_aar = NRF_AAR;
33 static NRF_PPI_Type* const nrf_ppi = NRF_PPI;
34 static NRF_RNG_Type* const nrf_random = NRF_RNG;
35 static NRF_ECB_Type* const nrf_aes = NRF_ECB;
36 static NRF_GPIOTE_Type* const nrf_gpiote = NRF_GPIOTE;
37 static NVIC_Type* const nvic = NVIC;
38
39 static constexpr auto lfxo_clk_freq = 32768;
40
41 /*
42 * Interrupt priorities
43 */
44 static constexpr uint32_t nrf_interrupt_prio_ble = 0;
45 static constexpr uint32_t nrf_interrupt_prio_user_cb = 1 << ( __NVIC_PRIO_BITS - 1 );
46 static constexpr uint32_t nrf_interrupt_prio_calibrate_rtc = nrf_interrupt_prio_user_cb - 1;
47
48 namespace nrf_details {
49 struct radio_option_meta_type : ::bluetoe::details::binding_option_meta_type {};
53
54 static void start_high_frequency_clock()
55 {
56 // This tasks starts the high frequency crystal oscillator (HFXO)
57 nrf_clock->TASKS_HFCLKSTART = 1;
58
59 // TODO: do not wait busy
60 // Issue: do not poll for readiness of the high frequency clock #63
61 while ( !nrf_clock->EVENTS_HFCLKSTARTED )
62 ;
63
64 nrf_clock->EVENTS_HFCLKSTARTED = 0;
65 }
66
67 inline void start_lfclock_and_rtc()
68 {
69 nrf_clock->EVENTS_LFCLKSTARTED = 0;
70 nrf_clock->TASKS_LFCLKSTART = 1;
71
72 while ( nrf_clock->EVENTS_LFCLKSTARTED == 0 )
73 ;
74
75 // https://infocenter.nordicsemi.com/topic/errata_nRF52840_Rev3/ERR/nRF52840/Rev3/latest/anomaly_840_20.html#anomaly_840_20
76 nrf_rtc->TASKS_STOP = 0;
77 nrf_rtc->TASKS_START = 1;
78
79 // Configure the RTC to generate these two events
80 // Overflow flag does not harm the power performance much and is used for
81 // debugging.
82 nrf_rtc->EVTEN =
83 ( RTC_EVTEN_COMPARE0_Enabled << RTC_EVTEN_COMPARE0_Pos )
84 | ( RTC_EVTEN_COMPARE1_Enabled << RTC_EVTEN_COMPARE1_Pos )
85 | ( RTC_EVTEN_OVRFLW_Enabled << RTC_EVTEN_OVRFLW_Pos );
86 }
87 }
88
99 {
102
103 static void start_clocks()
104 {
105 nrf_details::start_high_frequency_clock();
106
107 nrf_clock->LFCLKSRC = CLOCK_LFCLKSRCCOPY_SRC_Synth << CLOCK_LFCLKSRCCOPY_SRC_Pos;
108 nrf_details::start_lfclock_and_rtc();
109 }
110
111 static void stop_high_frequency_crystal_oscilator()
112 {
113 }
115 };
116
125 {
128
129 static void start_clocks()
130 {
131 nrf_details::start_high_frequency_clock();
132
133 nrf_clock->LFCLKSRC = CLOCK_LFCLKSRCCOPY_SRC_Xtal << CLOCK_LFCLKSRCCOPY_SRC_Pos;
134 nrf_details::start_lfclock_and_rtc();
135 }
136
137 static void stop_high_frequency_crystal_oscilator()
138 {
139 nrf_clock->TASKS_HFCLKSTOP = 1;
140
141# if defined BLUETOE_NRF52_RADIO_DEBUG
142 bluetoe::nrf52_details::gpio_debug_hfxo_stopped();
143# endif
144
145 }
147 };
148
163 {
166
167 static void start_clocks()
168 {
169 nrf_details::start_high_frequency_clock();
170
171 nrf_clock->LFCLKSRC = CLOCK_LFCLKSRCCOPY_SRC_RC << CLOCK_LFCLKSRCCOPY_SRC_Pos;
172 nrf_details::start_lfclock_and_rtc();
173 nrf52_details::init_calibration_timer();
174 }
175
176 static void stop_high_frequency_crystal_oscilator()
177 {
178 nrf52_details::deassign_hfxo();
179 }
181 };
182
201 template < unsigned StartupTimeMicroSeconds >
203 {
206
207 static constexpr unsigned value = StartupTimeMicroSeconds;
209 };
210
217
229 };
230 }
231
232 namespace nrf_details
233 {
234 struct encrypted_pdu_layout : bluetoe::link_layer::details::layout_base< encrypted_pdu_layout >
235 {
237 static constexpr std::size_t header_size = sizeof( std::uint16_t );
238
239 using bluetoe::link_layer::details::layout_base< encrypted_pdu_layout >::header;
240
241 static std::uint16_t header( const std::uint8_t* pdu )
242 {
243 return ::bluetoe::details::read_16bit( pdu );
244 }
245
246 static void header( std::uint8_t* pdu, std::uint16_t header_value )
247 {
248 ::bluetoe::details::write_16bit( pdu, header_value );
249 }
250
251 static std::pair< std::uint8_t*, std::uint8_t* > body( const link_layer::read_buffer& pdu )
252 {
253 assert( pdu.size >= header_size );
254
255 return { &pdu.buffer[ header_size + 1 ], &pdu.buffer[ pdu.size ] };
256 }
257
258 static std::pair< const std::uint8_t*, const std::uint8_t* > body( const link_layer::write_buffer& pdu )
259 {
260 assert( pdu.size >= header_size );
261
262 return { &pdu.buffer[ header_size + 1 ], &pdu.buffer[ pdu.size ] };
263 }
264
265 static constexpr std::size_t data_channel_pdu_memory_size( std::size_t payload_size )
266 {
267 return header_size + payload_size + 1;
268 }
270 };
271 }
272}
273
274#endif
275
configure the low frequency clock to run from the RC oscilator.
Definition: nrf.hpp:163
configure the high frequency crystal oscillator startup time
Definition: nrf.hpp:203
configures the radio::run() function to return on every interrupt
Definition: nrf.hpp:225
configure the low frequency clock to be sourced from a crystal oscilator
Definition: nrf.hpp:125
configure the low frequency clock to be sourced out of the high frequency clock
Definition: nrf.hpp:99