Nordic Semiconductor nRF5 AirFuel SDK  version 2.2.0
wireless_debug.c
Go to the documentation of this file.
1 /* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
2  *
3  * The information contained herein is property of Nordic Semiconductor ASA.
4  * Terms and conditions of usage are described in detail in NORDIC
5  * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
6  *
7  * Licensees are granted free, non-transferable use of the information. NO
8  * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
9  * the file.
10  *
11  */
12 
15 #include <stdint.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include "nrf_assert.h"
19 #include "nrf_soc.h"
20 #include "nrf_gzll.h"
21 #include "app_error.h"
22 #include "debug.h"
23 #include "wireless_debug.h"
24 #include "wireless_debug_config.h"
25 #include "softdevice_handler.h"
26 
27 //void notification_cb(nrf_impl_notification_t notification);
28 /*lint -e526 "Symbol RADIO_IRQHandler not defined" */
29 void RADIO_IRQHandler(void);
30 
31 #define PIPE_NUMBER 0
32 #define TX_PAYLOAD_LENGTH 32
33 #define ACK_PAYLOAD_LENGTH 32
34 #ifdef WDBGPTU
35 #define WDBG_TIMESLOT_LEN 15000
36 #else
37 #define WDBG_TIMESLOT_LEN 25000
38 #endif
39 #define WDBG_TIMESLOT_SUSPEND_GZLL 4000
40 #define WDBG_TIMESLOT_REQUEST_END 1000
41 #define WDBG_TIMESLOT_TIMEOUT 1000000
42 
43 static nrf_radio_request_t m_timeslot_request;
44 static uint32_t m_slot_length;
45 static volatile bool m_cmd_received = false;
46 static volatile bool m_gzll_initialized = false;
47 
48 static nrf_radio_signal_callback_return_param_t signal_callback_return_param;
50 
54 static void m_configure_next_event(void)
55 {
57  m_timeslot_request.request_type = NRF_RADIO_REQ_TYPE_EARLIEST;
58  m_timeslot_request.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
59  m_timeslot_request.params.earliest.priority = NRF_RADIO_PRIORITY_NORMAL;
60  m_timeslot_request.params.earliest.length_us = m_slot_length;
61  m_timeslot_request.params.earliest.timeout_us = WDBG_TIMESLOT_TIMEOUT;
62 }
63 
67 void sys_evt_dispatch(uint32_t evt_id)
68 {
69  uint32_t err_code;
70 
71  switch (evt_id)
72  {
73  case NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN:
74  ASSERT(false);
75  break;
76 
77  case NRF_EVT_RADIO_SESSION_IDLE:
78  ASSERT(false);
79  break;
80 
81  case NRF_EVT_RADIO_SESSION_CLOSED:
82  ASSERT(false);
83  break;
84 
85  case NRF_EVT_RADIO_BLOCKED:
87  err_code = sd_radio_request(&m_timeslot_request);
88  APP_ERROR_CHECK(err_code);
89  break;
90 
91  case NRF_EVT_RADIO_CANCELED:
93  err_code = sd_radio_request(&m_timeslot_request);
94  APP_ERROR_CHECK(err_code);
95  break;
96 
97  default:
98  break;
99  }
100 }
101 
105 static void m_on_start(void)
106 {
107  volatile bool res; // Volatile to stop compiler warning
108  uint8_t channels[NRF_GZLL_CHANNEL_TABLE_SIZE] = NRF_GZLL_CHANNELS;
109 
110  if (!m_gzll_initialized)
111  {
112  res = nrf_gzll_init(NRF_GZLL_MODE_DEVICE);
113  ASSERT(res);
114  res = nrf_gzll_set_device_channel_selection_policy(NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_CURRENT);
115  ASSERT(res);
116  res = nrf_gzll_set_xosc_ctl(NRF_GZLL_XOSC_CTL_MANUAL);
117  ASSERT(res);
118  res = nrf_gzll_set_max_tx_attempts(0);
119  ASSERT(res);
120  res = nrf_gzll_set_base_address_0(NRF_GZLL_BASE_ADDRESS_0);
121  ASSERT(res);
122  res = nrf_gzll_set_channel_table(channels, NRF_GZLL_CHANNEL_TABLE_SIZE);
123  ASSERT(res);
124  res = nrf_gzll_enable();
125  ASSERT(res);
126  m_gzll_initialized = true;
127  }
128  else
129  {
130  res = nrf_gzll_set_mode(NRF_GZLL_MODE_DEVICE);
131  ASSERT(res);
132  }
133  NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
134  NRF_TIMER0->CC[0] = m_slot_length - WDBG_TIMESLOT_SUSPEND_GZLL;
135  NVIC_EnableIRQ(TIMER0_IRQn);
136 }
137 
141 static void m_on_multitimer(void)
142 {
143  if (NRF_TIMER0->EVENTS_COMPARE[0] == 1)
144  {
145  NRF_TIMER0->EVENTS_COMPARE[0] = 0;
146  if (nrf_gzll_get_mode() != NRF_GZLL_MODE_SUSPEND)
147  {
148  (void)nrf_gzll_set_mode(NRF_GZLL_MODE_SUSPEND);
149  NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
150  NRF_TIMER0->CC[0] = m_slot_length - WDBG_TIMESLOT_REQUEST_END;
151  }
152  else
153  {
154  ASSERT(nrf_gzll_get_mode() == NRF_GZLL_MODE_SUSPEND);
156  signal_callback_return_param.params.request.p_next = &m_timeslot_request;
157  signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END;
158  }
159  }
160 }
161 
165 nrf_radio_signal_callback_return_param_t * m_radio_callback(uint8_t signal_type)
166 {
167  signal_callback_return_param.params.request.p_next = NULL;
168  signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
169 
170  switch(signal_type)
171  {
172  case NRF_RADIO_CALLBACK_SIGNAL_TYPE_START:
173  m_on_start();
174  break;
175 
176  case NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO:
178  break;
179 
180  case NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0:
181  m_on_multitimer();
182  break;
183  }
185 }
186 
190 uint32_t sd_radio_init(void)
191 {
192  uint32_t err_code;
193  err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
194  APP_ERROR_CHECK(err_code);
195  err_code = sd_radio_session_open(m_radio_callback);
196  if (err_code != NRF_SUCCESS)
197  return err_code;
199  err_code = sd_radio_request(&m_timeslot_request);
200  if (err_code != NRF_SUCCESS)
201  {
202  (void)sd_radio_session_close();
203  return err_code;
204  }
205  return NRF_SUCCESS;
206 }
207 
211 void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
212 {
213  uint32_t ack_payload_length = ACK_PAYLOAD_LENGTH;
214  if (tx_info.payload_received_in_ack)
215  {
216  if (nrf_gzll_fetch_packet_from_rx_fifo(pipe, ack_payload, &ack_payload_length))
217  {
218  ASSERT(ack_payload_length == 1);
219  m_cmd_received = true;
220  }
221  }
222 }
223 
227 void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
228 {
229 }
230 
234 void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info)
235 {
236 }
237 
242 {
243 }
244 
249 {
250  return m_cmd_received;
251 }
252 
256 char get_debug_cmd(void)
257 {
258  char cmd = ack_payload[0];
259  m_cmd_received = false;
260  return cmd;
261 }
uint32_t sd_radio_init(void)
Initialize this module.
#define WDBG_TIMESLOT_LEN
Radio timeslot length (PRU)
static uint32_t m_slot_length
Radio timeslot length.
void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info)
GZLL data packet received callback.
static uint8_t ack_payload[ACK_PAYLOAD_LENGTH]
Buffer for the ACK payload.
static void m_configure_next_event(void)
Fill in m_timeslot_request for next event.
void RADIO_IRQHandler(void)
Radio IRQ Handler.
#define ACK_PAYLOAD_LENGTH
GZLL Ack payload length.
static volatile bool m_gzll_initialized
Set to true when gzll is initialized.
#define WDBG_TIMESLOT_TIMEOUT
Radio timeslot timeout (us)
nrf_radio_signal_callback_return_param_t * m_radio_callback(uint8_t signal_type)
Radio session callback.
void nrf_gzll_disabled(void)
GZLL Disabled callback.
void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
GZLL Transmission failed callback.
bool debug_cmd_available(void)
Call this function to check if a command is received.
static void m_on_multitimer(void)
Called when NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0 received.
static void m_on_start(void)
Called when NRF_RADIO_CALLBACK_SIGNAL_TYPE_START received.
static volatile bool m_cmd_received
Set to true when a command is received.
void sys_evt_dispatch(uint32_t evt_id)
SOC events handler.
static nrf_radio_request_t m_timeslot_request
Passed to the sd_radio_request function.
static nrf_radio_signal_callback_return_param_t signal_callback_return_param
Return value for the Radio session callback function.
#define WDBG_TIMESLOT_SUSPEND_GZLL
Suspend GZLL 400us before radio timeslot ends.
void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
GZLL ACK received callback.
#define NRF_GZLL_CHANNEL_TABLE_SIZE
#define WDBG_TIMESLOT_REQUEST_END
Request end 1000us before radio timeslot ends.
char get_debug_cmd(void)
Clear the m_cmd_received and return the received command.