ruuvi.drivers.c ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
Loading...
Searching...
No Matches
ruuvi_nrf5_sdk15_communication_radio.c
Go to the documentation of this file.
1
13#if RUUVI_NRF5_SDK15_RADIO_ENABLED
14#include "ruuvi_driver_error.h"
18
19
20#include <stdbool.h>
21#include <stdint.h>
22#include "nordic_common.h"
23#include "nrf_soc.h"
24#include "nrf_sdh.h"
25#include "nrf_sdh_ble.h"
26#include "nrf_sdm.h"
27#include "ble_advdata.h"
28#include "ble_radio_notification.h"
29#include "sdk_errors.h"
30
32static ri_radio_activity_interrupt_fp_t on_radio_activity_callback = NULL;
33static ri_radio_modulation_t m_modulation; //<! Modulation for radio ops.
34
36#ifndef PHY_RAM_START
37# define PHY_RAM_START 0x20000000
38#endif
39
48static void on_radio_evt (bool active)
49{
50 // Convert to Ruuvi enum
51 ri_radio_activity_evt_t evt = active ?
53
54 // Call common event handler if set
55 if (NULL != on_radio_activity_callback) { on_radio_activity_callback (evt); }
56}
57
59{
60 rd_status_t status = RD_SUCCESS;
61 ret_code_t err_code = NRF_SUCCESS;
62
63 if (ri_radio_is_init())
64 {
65 status |= RD_ERROR_INVALID_STATE;
66 }
67 else if (!ri_radio_supports (modulation))
68 {
69 status |= RD_ERROR_INVALID_PARAM;
70 }
71 else
72 {
73 err_code = nrf_sdh_enable_request();
74 RD_ERROR_CHECK (err_code, NRF_SUCCESS);
75 // Configure the BLE stack using the default settings.
76 // Fetch the start address of the application RAM.
77 uint32_t ram_start = 0;
78 // As of SD 6.1.1, only one advertising configuration is allowed.
79 err_code |= nrf_sdh_ble_default_cfg_set (RUUVI_NRF5_SDK15_BLE4_STACK_CONN_TAG,
80 &ram_start);
81 RD_ERROR_CHECK (err_code, NRF_SUCCESS);
82 // TODO - find the correct way to define large enough GATT queue for extended GATT event.
83 //ble_cfg_t conn_cfg = { 0 };
84 //conn_cfg.conn_cfg.conn_cfg_tag = RUUVI_NRF5_SDK15_BLE4_STACK_CONN_TAG;
85 //err_code |= sd_ble_cfg_set (BLE_CONN_CFG_GATTS, &conn_cfg, ram_start);
86 // Enable BLE stack.
87 err_code |= nrf_sdh_ble_enable (&ram_start);
88 // Enable connection event extension for faster data rate
89 static ble_opt_t opt = {0};
90 opt.common_opt.conn_evt_ext.enable = true;
91 err_code |= sd_ble_opt_set (BLE_COMMON_OPT_CONN_EVT_EXT, &opt);
92 RD_ERROR_CHECK (err_code, NRF_SUCCESS);
93 // Initialize radio interrupts
94 err_code |= ble_radio_notification_init (RUUVI_NRF5_SDK15_RADIO_IRQ_PRIORITY,
95 NRF_RADIO_NOTIFICATION_DISTANCE_800US,
96 on_radio_evt);
97 // Store desired modulation
98 m_modulation = modulation;
99 }
100
101 return ruuvi_nrf5_sdk15_to_ruuvi_error (err_code) | status;
102}
103
105{
106 // Ask everything nicely to shut down.
107 nrf_sdh_disable_request();
108 // Shut everything down by force.
109 sd_softdevice_disable();
110 on_radio_activity_callback = NULL;
111 return RD_SUCCESS;
112}
113
124rd_status_t ri_radio_address_get (uint64_t * const address)
125{
126 uint32_t status = NRF_SUCCESS;
127 rd_status_t err_code = RD_SUCCESS;
128 uint64_t mac = 0;
129
130 if (!ri_radio_is_init())
131 {
132 // Random static BLE address has 2 top bits set
133 mac |= (uint64_t) ( (NRF_FICR->DEVICEADDR[0] >> 0) & 0xFF) << 0;
134 mac |= (uint64_t) ( (NRF_FICR->DEVICEADDR[0] >> 8) & 0xFF) << 8;
135 mac |= (uint64_t) ( (NRF_FICR->DEVICEADDR[0] >> 16) & 0xFF) << 16;
136 mac |= (uint64_t) ( (NRF_FICR->DEVICEADDR[0] >> 24) & 0xFF) << 24;
137 mac |= (uint64_t) ( (NRF_FICR->DEVICEADDR[1] >> 0) & 0xFF) << 32;
138 mac |= (uint64_t) ( (NRF_FICR->DEVICEADDR[1] >> 8 | 0xC0) & 0xFF) << 40;
139 }
140 else
141 {
142 ble_gap_addr_t addr;
143 addr.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC;
144 status |= sd_ble_gap_addr_get (&addr);
145 mac |= (uint64_t) (addr.addr[0]) << 0;
146 mac |= (uint64_t) (addr.addr[1]) << 8;
147 mac |= (uint64_t) (addr.addr[2]) << 16;
148 mac |= (uint64_t) (addr.addr[3]) << 24;
149 mac |= (uint64_t) (addr.addr[4]) << 32;
150 mac |= (uint64_t) (addr.addr[5]) << 40;
151 }
152
153 *address = mac;
154 return ruuvi_nrf5_sdk15_to_ruuvi_error (status) | err_code;
155}
156
157rd_status_t ri_radio_address_set (const uint64_t address)
158{
159 ble_gap_addr_t addr;
160 addr.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC;
161 addr.addr[0] = address >> 0;
162 addr.addr[1] = address >> 8;
163 addr.addr[2] = address >> 16;
164 addr.addr[3] = address >> 24;
165 addr.addr[4] = address >> 32;
166 addr.addr[5] = address >> 40;
167 return ruuvi_nrf5_sdk15_to_ruuvi_error (sd_ble_gap_addr_set (&addr));
168}
169
170
172{
173 // Warn user if CB is not NULL and non-null pointer is set, do not overwrite previous pointer.
174 if (NULL != handler && NULL != on_radio_activity_callback)
175 {
177 }
178 else
179 {
180 on_radio_activity_callback = handler;
181 }
182}
183
184bool ri_radio_is_init (void)
185{
186 return nrf_sdh_is_enabled();
187}
188
190{
191 rd_status_t err_code = RD_SUCCESS;
192
193 if (NULL == p_modulation)
194 {
195 err_code = RD_ERROR_NULL;
196 }
197 else if (!ri_radio_is_init())
198 {
199 err_code = RD_ERROR_INVALID_STATE;
200 }
201 else
202 {
203 *p_modulation = m_modulation;
204 }
205
206 return err_code;
207}
208
209
210uint8_t ruuvi_nrf5_sdk15_radio_phy_get (void)
211{
212 uint8_t nrf_modulation = BLE_GAP_PHY_NOT_SET;
213 ri_radio_modulation_t modulation;
214 rd_status_t err_code = ri_radio_get_modulation (&modulation);
215
216 if (RD_SUCCESS == err_code)
217 {
218 switch (modulation)
219 {
221 nrf_modulation = BLE_GAP_PHY_CODED;
222 break;
223
225 nrf_modulation = BLE_GAP_PHY_1MBPS;
226 break;
227
229 nrf_modulation = BLE_GAP_PHY_2MBPS;
230 break;
231
232 default:
233 nrf_modulation = BLE_GAP_PHY_NOT_SET;
234 break;
235 }
236 }
237
238 return nrf_modulation;
239}
240
241void ruuvi_nrf5_sdk15_radio_channels_set (uint8_t * const nrf_channels,
242 const ri_radio_channels_t channels)
243{
244 memset (nrf_channels, 0, sizeof (ble_gap_ch_mask_t));
245 nrf_channels[4] |= (!channels.channel_37) << 5;
246 nrf_channels[4] |= (!channels.channel_38) << 6;
247 nrf_channels[4] |= (!channels.channel_39) << 7;
248}
249
251{
252 bool supported = false;
253
254 switch (modulation)
255 {
257# if S140
258 supported = true;
259# else
260 supported = false;
261# endif
262 break;
263
265 supported = true;
266 break;
267
269 supported = true;
270 break;
271
272 default:
273 supported = false;
274 break;
275 }
276
277 return supported;
278}
279
280#endif
#define RD_ERROR_INVALID_PARAM
Invalid Parameter.
#define RD_ERROR_NULL
Null Pointer.
#define RD_ERROR_FATAL
Program should always reset after this.
uint32_t rd_status_t
bitfield for representing errors
rd_status_t ruuvi_nrf5_sdk15_to_ruuvi_error(const ret_code_t error)
convert nrf5 sdk15 error code into Ruuvi error code.
#define RD_ERROR_CHECK(error, mask)
Shorthand macro for calling the rd_error_check with current file & line.
#define RD_SUCCESS
Internal Error.
#define RD_ERROR_INVALID_STATE
Invalid state, operation disallowed in this state.
void ri_radio_activity_callback_set(const ri_radio_activity_interrupt_fp_t handler)
Setup radio activity interrupt.
rd_status_t ri_radio_get_modulation(ri_radio_modulation_t *const p_modulation)
Get the modulation used by application.
bool ri_radio_is_init()
Check if radio is initialized.
ri_radio_activity_evt_t
radio activity event type.
rd_status_t ri_radio_init(const ri_radio_modulation_t modulation)
Enable radio stack for an user. This function also starts radio activity callbacks internally.
rd_status_t ri_radio_uninit()
Release radio stack.
rd_status_t ri_radio_address_get(uint64_t *const address)
bool ri_radio_supports(ri_radio_modulation_t modulation)
Check if radio supports given modulation.
void(* ri_radio_activity_interrupt_fp_t)(const ri_radio_activity_evt_t evt)
Type of radio activity interrupt. This is common to all radio modules, i,e, the callback gets called ...
ri_radio_modulation_t
type of radio modulation to be used.
rd_status_t ri_radio_address_set(uint64_t const address)
@ RI_RADIO_AFTER
Event is after radio activity, i.e. radio was turned off.
@ RI_RADIO_BEFORE
Event is before radio goes active, i.e. radio turns on soon.
@ RI_RADIO_BLE_1MBPS
"Normal" BLE 4 modulation
@ RI_RADIO_BLE_2MBPS
"Fast BLE". Advertising uses 1MBPS primary advertisement followed by 2 MBit/s extended advertisement.
@ RI_RADIO_BLE_125KBPS
Also known as BLE Long Range S=8.
#define RUUVI_NRF5_SDK15_RADIO_IRQ_PRIORITY
priorities 0,1, 4,5 are reserved by SD
#define RUUVI_NRF5_SDK15_BLE4_STACK_CONN_TAG
< Check if NRF_NFC is required
Header to enable and disable module compilation.
Ruuvi error codes and error check function.
Bitfield to describe related sensor data.
uint8_t channel_37
BLE channel 37, 2402 MHz.
uint8_t channel_39
BLE channel 39, 2480 MHz.
uint8_t channel_38
BLE channel 38, 2426 MHz.