Nordic Semiconductor nRF5 AirFuel SDK  version 2.2.0
main.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 
19 #include <stdint.h>
20 
21 #include "debug.h"
22 #include "softdevice_handler.h"
23 #include "app_profile.h"
24 #include "pru_sensors.h"
25 #include "pru_hw_config.h"
26 #include "pru_config.h"
27 #include "nrf_assert.h"
28 #include "app_print.h"
29 #include "app_util_platform.h"
30 #include "nrf_nvic.h"
31 
32 #ifdef DFU_SUPPORT
33  #include "common_hal_buttons.h"
34 #endif
35 
36 
37 // Assert setup
38 #define DEAD_BEEF 0xDEADBEEF
40 #define VRECT_MEAS_INTERVAL APP_TIMER_TICKS(50, APP_TIMER_PRESCALER)
42 #define VRECT_MEAS_INTERVAL APP_TIMER_TICKS(50, APP_TIMER_PRESCALER)
43 #define PRU_MULTI_PROFILE_TIMER_OP_QUEUE_SIZE (8 + PRU_MAX_APP_TIMERS)
45 static nrf_clock_lf_cfg_t clk_cfg = {
46  .source = NRF_CLOCK_LF_SRC_XTAL,
47  .xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM};
49 static bool m_connected = false;
51 APP_TIMER_DEF(m_vrect_read_timer);
53 static bool m_profile_has_been_switched = false;
55 static const ble_gap_addr_t PRU_ADDR = {.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC,
56  .addr = {0xe4, 0x33, 0xba, 0xab, 0xea, 0xee}};
58 static const ble_gap_addr_t APP_PROFILE_ADDR = {.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC,
59  .addr = {0xc9, 0xff, 0xcc, 0xee, 0x11, 0xcc}};
62 static ble_enable_params_t m_ble_enable_params = {.common_enable_params.vs_uuid_count = BLE_UUID_VS_COUNT_DEFAULT,
63  .gap_enable_params.periph_conn_count = 1,
64  .gatts_enable_params.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT};
65 
66 
68 typedef enum {
69  PROFILE_WPT,
70  PROFILE_APPLICATION,
72 
73 device_profile_t m_current_profile = PROFILE_APPLICATION;
83 static void m_ble_evt_dispatch(ble_evt_t * p_ble_evt)
84 {
85  switch(p_ble_evt->header.evt_id)
86  {
87  case BLE_GAP_EVT_CONNECTED:
88  m_connected = true;
89  break;
90  }
91 
92  switch(m_current_profile)
93  {
94  case PROFILE_WPT:
95  pru_on_ble_evt(p_ble_evt);
96  break;
97 
98  case PROFILE_APPLICATION:
99  app_profile_on_ble_evt(p_ble_evt);
100  break;
101  }
102 }
103 
105 static void m_sys_evt_dispatch(uint32_t evt)
106 {
108 }
109 
114 static void m_ble_stack_init(void)
115 {
116  uint32_t err_code;
117 
118  SOFTDEVICE_HANDLER_INIT(&clk_cfg, NULL);
119 
120  err_code = softdevice_enable(&m_ble_enable_params);
121  APP_ERROR_CHECK(err_code);
122 
123  err_code = softdevice_ble_evt_handler_set(m_ble_evt_dispatch);
124  APP_ERROR_CHECK(err_code);
125 
126  err_code = softdevice_sys_evt_handler_set(m_sys_evt_dispatch);
127  APP_ERROR_CHECK(err_code);
128 
129  // It is important that this is set to the same priority as the
130  // timers in the system.
131  err_code = sd_nvic_SetPriority(SD_EVT_IRQn, APP_IRQ_PRIORITY_LOW);
132  APP_ERROR_CHECK(err_code);
133 }
134 
136 static void vrect_read_timeout_handler(void * p_context)
137 {
138  uint32_t err_code;
139  const pru_sensor_data_t * p_data;
140 
142 
143  p_data = pru_sensors_data_get();
144  if(p_data->vrect > PRU_VRECT_UVLO)
145  {
146  // Switch from application profile to PRU
148 
149  err_code = app_timer_stop_all();
150  APP_ERROR_CHECK(err_code);
151 
152  err_code = sd_softdevice_disable();
153  APP_ERROR_CHECK(err_code);
154 
155 
156  m_current_profile = PROFILE_WPT;
157 
159 
160  m_connected = false;
161 
162  }
163 }
164 
165 
167 static void m_timers_init(void)
168 {
169  uint32_t err_code;
170 
172 
173  err_code = app_timer_create(&m_vrect_read_timer, APP_TIMER_MODE_REPEATED, vrect_read_timeout_handler);
174  APP_ERROR_CHECK(err_code);
175 }
176 
178 static void m_on_pru_sm_evt(pru_sm_signal_type_t signal, const pru_sm_state_vars_t * p_state_vars)
179 {
180  uint32_t err_code;
181 
182  if( (p_state_vars->prev_state != p_state_vars->current_state) && (p_state_vars->current_state == PRU_SM_STATE_NULL))
183  {
184  // First stop all timers
185  err_code = app_timer_stop_all();
186  APP_ERROR_CHECK(err_code);
187 
188  // Disable softdevice to clear all settings
189  err_code = sd_softdevice_disable();
190  APP_ERROR_CHECK(err_code);
191 
192  // Start application profile
193  err_code = app_timer_start(m_vrect_read_timer, VRECT_MEAS_INTERVAL, NULL);
194  APP_ERROR_CHECK(err_code);
195 
196  m_current_profile = PROFILE_APPLICATION;
197 
199 
200  m_connected = false;
201  }
202 }
203 
207 int main()
208 {
209  uint32_t err_code;
210 
211  pru_sensors_init(NULL); // Initialize sensors with NULL value to allow sensor reading, event generation will not be enabled.
213  m_timers_init();
214 
215 #ifdef DFU_SUPPORT
216  // Set up button used for entering DFU mode
218 #endif
219 
220  err_code = app_timer_start(m_vrect_read_timer, VRECT_MEAS_INTERVAL, NULL);
221  APP_ERROR_CHECK(err_code);
222 
224 
227 
228  // We need to get to main context before switching profile in order to ensure that all
229  // softdevice events has been handled.
230  while(1)
231  {
233  {
234  (void)sd_softdevice_enable(&clk_cfg, app_error_fault_handler);
235 
236  err_code = softdevice_enable(&m_ble_enable_params);
237  APP_ERROR_CHECK(err_code);
238 
239  if(m_current_profile == PROFILE_WPT)
240  {
241  err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &PRU_ADDR);
242  APP_ERROR_CHECK(err_code);
243 
244  pru_start();
245  }
246  else
247  {
248  err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &APP_PROFILE_ADDR);
249  APP_ERROR_CHECK(err_code);
250 
252  }
254  }
255 
256  #ifdef DEBUG_OUT_ENABLE
257  debug();
258  #endif
259  }
260 }
261 
262 
264 //lint -restore
State machine state variables.
Definition: pru_sm.h:55
void pru_on_ble_evt(ble_evt_t *p_ble_evt)
Handle BLE event.
Definition: pru.c:510
static void m_ble_stack_init(void)
BLE stack initialization.
Definition: main.c:114
static bool m_profile_has_been_switched
Definition: main.c:53
static void m_ble_evt_dispatch(ble_evt_t *p_ble_evt)
Dispatches a BLE stack event to all profiles.
Definition: main.c:83
void app_profile_start(void)
Start profile. Is called every time profile is activated.
Definition: ble_app_hrs.c:736
static void m_sys_evt_dispatch(uint32_t evt)
Dispatch system events to all profiles that require it.
Definition: main.c:105
void app_profile_on_ble_evt(ble_evt_t *p_ble_evt)
Handle BLE event.
Definition: ble_app_hrs.c:726
int main()
Application main function.
Definition: main.c:90
void common_hal_buttons_init(uint32_t button_press_duration_ms, uint8_t app_timer_prescaler)
Initialize button functionality. Used only for starting DFU.
void pru_init(app_sm_evt_handler_t sm_evt_handler)
Initialize PRU. This function must be called before any other PRU function can be called...
Definition: pru.c:480
#define PRU_MULTI_PROFILE_TIMER_OP_QUEUE_SIZE
Definition: main.c:43
void pru_sensors_read_all(void)
Read PRU sensors.
Definition: pru_sensors.c:51
void app_profile_stop(void)
Stop profile. Note: Needs to set the softdevice in a state where it is ok to initialize PRU profile...
Definition: ble_app_hrs.c:752
void pru_sensors_init(pru_sm_handler_t pru_sm_handler)
Initialize sensors and read default values.
Definition: pru_sensors.c:42
device_profile_t
Enum representing the current active profile.
Definition: main.c:68
device_profile_t m_current_profile
Definition: main.c:73
static bool m_connected
Definition: main.c:49
const pru_sensor_data_t * pru_sensors_data_get(void)
Get the latest data from the PRU sensors.
Definition: pru_sensors.c:146
Definition of PRU reporting data.
Definition: pru_sensors.h:26
static nrf_clock_lf_cfg_t clk_cfg
Definition: main.c:45
pru_sm_state_t prev_state
Definition: pru_sm.h:57
pru_sm_state_t current_state
Definition: pru_sm.h:58
void app_profile_on_sys_evt(uint32_t sys_evt)
Handle system event.
Definition: ble_app_hrs.c:731
static void m_timers_init(void)
Init timers required by this module.
Definition: main.c:167
#define VRECT_MEAS_INTERVAL
Definition: main.c:42
void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
Callback function for asserts in the SoftDevice.
static const ble_gap_addr_t PRU_ADDR
Definition: main.c:55
#define APP_TIMER_PRESCALER
Definition: pru.h:33
pru_sm_signal_type_t
PRU state machine signal type.
Definition: pru_sm.h:36
#define PRU_BUTTON_PRESS_LENGTH_DFU_MS
Definition: pru_config.h:42
APP_TIMER_DEF(m_vrect_read_timer)
#define PRU_VRECT_UVLO
Definition: pru_hw_config.h:24
static ble_enable_params_t m_ble_enable_params
BLE Enable params.
Definition: main.c:62
void debug(void)
Process debug commands.
Definition: pru_debug.c:564
void pru_start(void)
Enable the PRU profile. When enabled sensor reading and signal generation will be enabled...
Definition: pru.c:487
static const ble_gap_addr_t APP_PROFILE_ADDR
Definition: main.c:58
static void vrect_read_timeout_handler(void *p_context)
Handler for reading VRECT.
Definition: main.c:136
void app_profile_init(void)
Initialize profile. Is only called once.
Definition: ble_app_hrs.c:716
static void m_on_pru_sm_evt(pru_sm_signal_type_t signal, const pru_sm_state_vars_t *p_state_vars)
PRU state machine event handler. Used to see when charging has stopped.
Definition: main.c:178