Nordic Semiconductor nRF5 AirFuel SDK  version 2.2.0
ptu.c
Go to the documentation of this file.
1 /* Copyright (c) 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 <string.h>
17 
18 #include "ptu.h"
19 #include "nrf_assert.h"
20 #include "ptu_test_mux.h"
21 #include "ptu_sensors.h"
22 #include "ptu_conn_man.h"
23 #include "ptu_power_ctl.h"
24 #include "ptu_power_sharing.h"
25 #include "ptu_beacons.h"
26 #include "ptu_latching_fault.h"
28 
29 /******************************************************************************/
32 /******************************************************************************/
33 
34 APP_TIMER_DEF(m_pru_dyn_read_timer_id);
35 APP_TIMER_DEF(m_ptu_sensor_timer_id);
43 {
44  uint32_t err_code;
45 
46  (void)ptu_sm_execute(signal, &m_state);
47 
48  // Notify application of state machine signal
49  if(m_app_sm_evt_handler != NULL)
50  m_app_sm_evt_handler(signal, &m_state);
51 
52  // If state changed
53  if(m_state.current_state != m_state.prev_state)
54  {
55  switch(m_state.current_state)
56  {
57  case PTU_SM_STATE_CONFIGURATION:
58  m_ptu_sm_execute(PTU_SM_SIGNAL_CONFIGURATION_COMPLETE);
59  break;
60 
61  case PTU_SM_STATE_POWER_SAVE:
62  if(ptu_reg_n_entries_get() > 0)
64 
67  break;
68 
69  case PTU_SM_STATE_LOW_POWER:
71  APP_ERROR_CHECK(err_code);
72 
73  err_code = ptu_tmux_poweramp_enable_set(true);
74  APP_ERROR_CHECK(err_code);
75  break;
76 
77  case PTU_SM_STATE_POWER_TRANSFER:
79  APP_ERROR_CHECK(err_code);
80 
81  err_code = ptu_tmux_poweramp_enable_set(true);
82  APP_ERROR_CHECK(err_code);
83  break;
84 
85  case PTU_SM_STATE_LOCAL_FAULT:
86  err_code = ptu_tmux_poweramp_enable_set(false);
87  APP_ERROR_CHECK(err_code);
88 
91  break;
92 
93  case PTU_SM_STATE_LATCH_FAULT:
94  err_code = ptu_tmux_poweramp_enable_set(false);
95  APP_ERROR_CHECK(err_code);
96 
99 
100  err_code = ptu_latching_fault_entered(m_state.prev_state);
101  APP_ERROR_CHECK(err_code);
102  break;
103 
104  default:
105  break;
106  }
107  }
108 }
109 
114 static void m_ptu_pru_dyn_read_timer_handler(void * p_context)
115 {
116  uint32_t err_code;
117 
120  {
122 
123  #if(PTU_CCA_ROGUE_DETECT_ENABLE == true)
124  const ptu_sensor_data_t * sensors_data;
125  err_code = ptu_sensors_data_get(&sensors_data);
126  APP_ERROR_CHECK(err_code);
127 
128  if(sensors_data->rogue_obj_detected)
129  {
130  m_ptu_sm_execute(PTU_SM_SIGNAL_ROGUE_OBJECT_DETECTED);
131  }
132  #endif
133 
134  if(ptu_reg_n_entries_get() == 0)
135  {
136  m_ptu_sm_execute(PTU_SM_SIGNAL_ALL_DEVICES_DISCONNECTED);
137  }
138  }
139 }
140 
146 static void m_ptu_sensor_timer_handler(void * p_context)
147 {
148  const ptu_sensor_data_t * sensors_data;
149 
150  uint32_t err_code;
151  err_code = ptu_sensors_read();
152  APP_ERROR_CHECK(err_code);
153  err_code = ptu_sensors_data_get(&sensors_data);
154  APP_ERROR_CHECK(err_code);
156 }
157 
160 static void m_alert_handler(ble_wpts_c_t * p_wpts_c, ble_wpts_c_evt_t * const p_wpts_c_evt)
161 {
162  ptu_reg_item_t *p_reg_item;
163  pru_alert_bits_t * p_pru_alert;
164 
165  p_reg_item = ptu_reg_item_get_from_conn_handle(p_wpts_c->conn_handle);
166 
167  if(p_reg_item != NULL)
168  {
169  ASSERT( (p_wpts_c_evt->type == BLE_WPTS_C_EVT_PRU_DYNAMIC_READ_RESP) ||
170  (p_wpts_c_evt->type == BLE_WPTS_C_EVT_PRU_ALERT) );
171 
172  if (p_wpts_c_evt->type == BLE_WPTS_C_EVT_PRU_DYNAMIC_READ_RESP)
173  {
174  p_pru_alert = &(p_wpts_c_evt->data.pru_dynamic.alerts);
175  }
176  else
177  {
178  p_pru_alert = &(p_wpts_c_evt->data.pru_alert.alerts);
179  }
180 
181  p_reg_item->charged = p_pru_alert->charge_complete || p_pru_alert->wired_charge_detect;
182 
183  // System error
184  if(p_pru_alert->pru_over_voltage ||
185  p_pru_alert->pru_over_current ||
186  p_pru_alert->pru_over_temperature )
187  {
188  m_ptu_sm_execute(PTU_SM_SIGNAL_SYSTEM_ERROR);
189  return;
190  }
191  }
192 }
193 
196 static void m_wpts_evt_handler(ble_wpts_c_t * p_wpts_c, ble_wpts_c_evt_t * const p_wpts_c_evt)
197 {
198  static bool m_test_mode = false;
199  uint32_t calc_var;
200 
201  if(p_wpts_c_evt->gatt_status == BLE_GATT_STATUS_SUCCESS)
202  {
204  ASSERT(p_reg_item != NULL);
205 
206  switch (p_wpts_c_evt->type)
207  {
209  break;
210 
213  break;
214 
216  break;
217 
219  // Copy received parameters to registry
220  memcpy(&p_reg_item->prev_pru_dynamic, &p_wpts_c_evt->data.pru_dynamic, sizeof(pru_dynamic_t));
221 
222  // Update VRECT_STATIC_MIN, VRECT_STATIC_HIGH and VRECT_SET parameters if required.
226  {
228  }
229 
233  {
235  }
236 
240  {
241  p_reg_item->prev_pru_static.vrect_set = p_reg_item->prev_pru_dynamic.vrect_set_dyn;
242  }
243 
244  if(m_test_mode) // If PTU was told to enter test mode during registration
246 
247  // Derive prect from vrect * irect and write to registry
248  calc_var = p_reg_item->prev_pru_dynamic.irect; // [mA]
249  calc_var *= (uint32_t)p_reg_item->prev_pru_dynamic.vrect; // [mA] * [mV] -> [uW]
250  p_reg_item->prev_pru_dynamic.prect = (calc_var / 100000); // [(1/10)W];
251 
252  // Derive PRU power utilization and write to registry
253  p_reg_item->prev_pru_dynamic.putil =
254  (uint8_t)(((uint32_t)p_reg_item->prev_pru_dynamic.prect * 100)/ // * 100 to make it %
255  ((uint32_t)p_reg_item->prev_pru_static.prect_max));
256 
257  // Process alert field
258  m_alert_handler(p_wpts_c, p_wpts_c_evt);
259 
260  p_reg_item->pending_dyn_read = false;
261  break;
262 
264  if(p_reg_item->pending_charge_disable)
265  {
266  p_reg_item->pending_charge_disable = false;
267  ptu_cm_remove_device(p_reg_item);
268  }
269  break;
270 
272  m_alert_handler(p_wpts_c, p_wpts_c_evt);
273  break;
274 
275  default:
276  break;
277  }
278  ptu_cm_on_wpt_service_evt(p_wpts_c, p_wpts_c_evt);
279  ptu_power_sharing_on_wpt_service_evt(p_wpts_c, p_wpts_c_evt);
280  }
281 }
282 
285 static void m_services_init(void)
286 {
287  uint32_t err_code;
288  ble_wpts_c_init_t wpts_c_init;
289 
290  wpts_c_init.evt_handler = m_wpts_evt_handler;
291 
292  err_code = ble_wpts_c_init(&wpts_c_init);
293  APP_ERROR_CHECK(err_code);
294 }
295 
296 
299 static void m_timers_init(void)
300 {
301  uint32_t err_code;
302 
303  // Instantiate sensor reading timer
304  err_code = app_timer_create(&m_ptu_sensor_timer_id, APP_TIMER_MODE_REPEATED, m_ptu_sensor_timer_handler);
305  APP_ERROR_CHECK(err_code);
306 
307  // Instantiate PRU dyn read timer
308  err_code = app_timer_create(&m_pru_dyn_read_timer_id, APP_TIMER_MODE_REPEATED, m_ptu_pru_dyn_read_timer_handler);
309  APP_ERROR_CHECK(err_code);
310 }
311 
314 /******************************************************************************/
317 /******************************************************************************/
318 
319 void ptu_on_ble_evt(ble_evt_t * p_ble_evt)
320 {
321  ptu_reg_item_t * reg_item;
322 
323  ptu_cm_on_ble_evt(p_ble_evt);
324 
325  if ((reg_item = ptu_reg_item_get_from_conn_handle(p_ble_evt->evt.common_evt.conn_handle)) != NULL)
326  {
327  ble_wpts_c_on_ble_evt(&reg_item->ble_wpts_c, p_ble_evt);
328  }
329 }
330 
331 void ptu_init(app_sm_evt_handler_t sm_evt_handler)
332 {
333  uint32_t err_code;
334 
335  m_app_sm_evt_handler = sm_evt_handler;
336 
337  m_timers_init();
338 
339  m_services_init();
340 
341  ptu_reg_init();
342 
343  err_code = ptu_cm_init(m_ptu_sm_execute);
344  APP_ERROR_CHECK(err_code);
345 
347  APP_ERROR_CHECK(err_code);
348 
350  APP_ERROR_CHECK(err_code);
351 
353 
355  APP_ERROR_CHECK(err_code);
356 
358  APP_ERROR_CHECK(err_code);
359 
360  err_code = tmux_init(); // Initializes HAL as well
361  APP_ERROR_CHECK(err_code);
362 }
363 
364 void ptu_start(void)
365 {
366  uint32_t err_code;
367 
368  err_code = TIMER_START(m_ptu_sensor_timer_id, PTU_SENSORS_READ_INTERVAL_MS, NULL);
369  APP_ERROR_CHECK(err_code);
370  err_code = TIMER_START(m_pru_dyn_read_timer_id, PTU_PRU_DYN_READ_INTERVAL_MS, NULL);
371  APP_ERROR_CHECK(err_code);
372 
373  m_ptu_sm_execute(PTU_SM_SIGNAL_CONFIGURATION_COMPLETE);
374 }
375 
376 
377 #ifdef DFU_SUPPORT
378 // Implement functions required by the DFU functionality
379 
380 void terminate(void)
381 {
383 }
384 
385 bool dfu_check(void)
386 {
387  return (ptu_reg_n_entries_get() == 0);
388 }
389 #endif //DFU_SUPPORT
390 
static void m_services_init(void)
Initialize Client Service.
Definition: ptu.c:285
uint16_t irect
Definition: wpt.h:168
ble_wpts_c_evt_handler_t evt_handler
Definition: ble_wpts_c.h:76
static void m_alert_handler(ble_wpts_c_t *p_wpts_c, ble_wpts_c_evt_t *const p_wpts_c_evt)
Handle PRU alert.
Definition: ptu.c:160
#define PTU_MS_FROM_BEACON_STOP_TO_ACTIVATE_DISTANT_LIST
Definition: ptu_config.h:46
Registry item.
Definition: ptu_registry.h:47
pru_alert_bits_t alerts
Definition: wpt.h:175
#define PTU_SENSORS_READ_INTERVAL_MS
Definition: ptu_config.h:36
union ble_wpts_c_evt_t::@1 data
uint8_t putil
Definition: wpt.h:179
uint16_t conn_handle
Definition: ble_wpts_c.h:66
uint8_t wired_charge_detect
Definition: wpt.h:139
WPT Service Client structure. This contains various status information for the service.
Definition: ble_wpts_c.h:57
uint32_t ptu_sensors_read(void)
Read sensors. This function should typically be called regularly by a timer and can generate events b...
Definition: ptu_sensors.c:303
#define PTU_PRU_DYN_READ_INTERVAL_MS
Definition: ptu_config.h:37
ble_wpts_c_t ble_wpts_c
Definition: ptu_registry.h:52
uint16_t gatt_status
Definition: ble_wpts_c.h:47
State machine state variables.
Definition: ptu_sm.h:67
void ptu_power_ctrl_adjust(void)
Perform power control adjustments.
#define BLE_WPTS_PRU_DYNAMIC_OPTION_VRECT_MIN_DYN_BITPOS
uint32_t ptu_cm_init(ptu_sm_handler_t sm_handler)
Initialize connection manager.
Definition: ptu_conn_man.c:861
static ptu_sm_state_vars_t m_state
Definition: ptu.c:36
uint16_t vrect
Definition: wpt.h:167
uint32_t ptu_sensors_init(ptu_sm_handler_t sm_handler)
Initialize PTU Sensors. This function must be called before any other PTU Sensors function can be cal...
Definition: ptu_sensors.c:284
bool dfu_check(void)
Needs to be implemented by application. Check if it is OK to jump to the DFU application.
Definition: ptu.c:385
uint8_t ptu_reg_n_entries_get(void)
Get the number of devices currently in registry. This will include all connected devices, as well as all devices which is currently being registered.
Definition: ptu_registry.c:268
uint16_t vrect_set_dyn
Definition: wpt.h:173
ptu_sm_signal_type_t
PTU signal type.
Definition: ptu_sm.h:48
static void m_ptu_pru_dyn_read_timer_handler(void *p_context)
Definition: ptu.c:114
uint32_t ptu_latching_fault_entered(ptu_sm_state_t previous)
Handle the entry of latching fault state.
uint32_t ble_wpts_c_init(const ble_wpts_c_init_t *p_wpts_c_init)
Initialize the WPT Service Client.
Definition: ble_wpts_c.c:354
void ptu_cm_disconnect_all(void)
Disconnect all PRUs.
pru_alert_t pru_alert
Definition: ble_wpts_c.h:52
void terminate(void)
Needs to be implemented by application. Perform all requried actions before jump to DFU application c...
Definition: ptu.c:380
uint16_t vrect_high_dyn
Definition: wpt.h:174
static void m_ptu_sensor_timer_handler(void *p_context)
Handler of sensor timer.
Definition: ptu.c:146
void ptu_beacons_init(void)
Initialize beacons handling.
Definition: ptu_beacons.c:192
#define BLE_WPTS_PRU_DYNAMIC_OPTION_VRECT_SET_DYN_BITPOS
static void m_timers_init(void)
Initialize timers.
Definition: ptu.c:299
ptu_sm_state_t prev_state
Definition: ptu_sm.h:69
Alert field used in both Alert Characteristic and Dynamic Parameters Characteristic.
Definition: wpt.h:132
uint32_t ptu_tmux_poweramp_enable_set(bool enable)
Test wrapper for ptu_hal_poweramp_enable_set().
Definition: ptu_test_mux.c:69
uint32_t ptu_power_ctrl_set_poweramp_input(uint16_t level)
Perform power control adjustments.
#define PTU_POWERAMP_INPUT_NOMINAL
Definition: ptu_hw_config.h:72
ptu_tester_command_t tester_command
Definition: wpt.h:180
uint16_t vrect_min_dyn
Definition: wpt.h:172
void ptu_cm_on_ble_evt(ble_evt_t *p_ble_evt)
BLE event handler.
Definition: ptu_conn_man.c:894
uint8_t charged
Definition: ptu_registry.h:66
void ptu_start(void)
Start ptu profile. Here "start" means that profile can start generating events through ptu_evt_handle...
Definition: ptu.c:364
uint16_t vrect_high_static
Definition: wpt.h:97
pru_static_t pru_static
Definition: ble_wpts_c.h:50
void ptu_power_sharing_temperature_warning_set(bool warning)
Inform power control module that PTU is having a high temperature warning. When this occurs the power...
void ptu_cm_scan_disable(void)
Disable scanning.
void(* app_sm_evt_handler_t)(pru_sm_signal_type_t signal, const pru_sm_state_vars_t *p_state_vars)
Definition: pru.h:29
ptu_sm_state_t current_state
Definition: ptu_sm.h:70
ble_wpts_c_evt_type_t type
Definition: ble_wpts_c.h:46
static void m_wpts_evt_handler(ble_wpts_c_t *p_wpts_c, ble_wpts_c_evt_t *const p_wpts_c_evt)
Handle WPT client service event.
Definition: ptu.c:196
uint8_t pru_over_voltage
Definition: wpt.h:134
#define BLE_WPTS_PRU_INFO_PTU_TEST_MODE_ENABLED_VAL
#define BLE_WPTS_PRU_DYNAMIC_OPTION_VRECT_HIGH_DYN_BITPOS
WPT Service Client init structure. This contains all options and data needed for initialization of th...
Definition: ble_wpts_c.h:74
uint8_t pru_over_current
Definition: wpt.h:135
pru_static_t prev_pru_static
Definition: ptu_registry.h:53
void ptu_on_ble_evt(ble_evt_t *p_ble_evt)
Dispatches a BLE stack event to PTU.
Definition: ptu.c:319
void ptu_cm_scan_enable(void)
Enable scanning.
uint8_t pru_over_temperature
Definition: wpt.h:136
#define BLE_WPTS_PRU_DYNAMIC_OPTION_VRECT_SET_DYN_BITMSK
WPT Service Client event.
Definition: ble_wpts_c.h:44
#define BLE_WPTS_PRU_DYNAMIC_OPTION_VRECT_MIN_DYN_BITMSK
uint32_t ptu_dlh_init(ptu_dlh_init_t const *p_init)
Check if device with provided address is in the distant list.
void ble_wpts_c_on_ble_evt(ble_wpts_c_t *p_wpts_c, ble_evt_t *p_ble_evt)
WPT Service Client BLE stack event handler.
Definition: ble_wpts_c.c:311
uint8_t pending_charge_disable
Definition: ptu_registry.h:67
#define TIMER_START(timer_id, ms, p_ctx)
Definition: wpt.h:32
void ptu_reg_init(void)
Initialize registry database.
Definition: ptu_registry.c:91
ptu_reg_item_t * ptu_reg_item_get_from_conn_handle(uint16_t conn_handle)
Get registry item from connection handle.
Definition: ptu_registry.c:137
void ptu_power_sharing_on_wpt_service_evt(ble_wpts_c_t *p_wpts_c, ble_wpts_c_evt_t *const p_wpts_c_evt)
Handle service events.
void ptu_cm_dynamic_read_all(void)
Issue read request for the PRU dynamic characteristic to all registerred PRUs.
APP_TIMER_DEF(m_pru_dyn_read_timer_id)
uint16_t vrect_min_static
Definition: wpt.h:96
uint32_t ptu_sensors_data_get(const ptu_sensor_data_t **sensors_data)
Get the latest data read from the PTU sensors.
Definition: ptu_sensors.c:404
static void m_ptu_sm_execute(ptu_sm_signal_type_t signal)
Used when executing state machine events.
Definition: ptu.c:42
uint8_t optional_fields
Definition: wpt.h:166
uint16_t vrect_set
Definition: wpt.h:98
uint8_t pending_dyn_read
Definition: ptu_registry.h:64
pru_dynamic_t prev_pru_dynamic
Definition: ptu_registry.h:54
void ptu_cm_remove_device(ptu_reg_item_t *reg_item_p)
Disconnect and/or unregister any device.
Definition: ptu_conn_man.c:836
pru_dynamic_t pru_dynamic
Definition: ble_wpts_c.h:51
bool ptu_cm_mode_trans_in_progress(void)
Get mode transition status.
Definition: ptu_conn_man.c:855
uint8_t info_ptu_test_mode
Definition: wpt.h:106
uint32_t ptu_latching_fault_init(ptu_sm_handler_t sm_handler)
Initialize latching fault module.
void ptu_init(app_sm_evt_handler_t sm_evt_handler)
Initialize PTU. This function must be called before any other PTU function can be called...
Definition: ptu.c:331
uint32_t tmux_init(void)
Initialize the PTU's test multiplexer.
Definition: pru_test_mux.c:53
#define BLE_WPTS_PRU_DYNAMIC_OPTION_VRECT_HIGH_DYN_BITMSK
void ptu_cm_on_wpt_service_evt(ble_wpts_c_t *p_wpts_c, ble_wpts_c_evt_t *const p_wpts_c_evt)
Handle service events.
Definition: ptu_conn_man.c:952
uint32_t ptu_power_sharing_init(ptu_sm_handler_t sm_handler)
Initialize power sharing module.
#define BLE_WPTS_BITFIELD_READ(bitfield, msk, pos)
Read bitfield.
void ptu_power_ctrl_set_itx_val(ptu_tester_command_t cmd)
Handle PTU tester power adjustment command.
#define PTU_POWERAMP_INPUT_START
Definition: ptu_hw_config.h:66
uint16_t prect
Definition: wpt.h:178
pru_alert_bits_t alerts
Definition: wpt.h:147
static app_sm_evt_handler_t m_app_sm_evt_handler
Definition: ptu.c:37
uint8_t charge_complete
Definition: wpt.h:138
PRU Dynamic Parameter structure.
Definition: wpt.h:164
Definition of PTU sensor data.
Definition: ptu_hw_config.h:99
ptu_sm_state_t ptu_sm_execute(ptu_sm_signal_type_t signal, ptu_sm_state_vars_t *p_state)
State machine input signal handler.
Definition: ptu_sm.c:94
uint8_t prect_max
Definition: wpt.h:95
void ptu_beacons_start(void)
Start PTU Beacons.
Definition: ptu_beacons.c:187