Nordic Semiconductor nRF5 AirFuel SDK  version 2.2.0
ptu_sensors.c File Reference
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "ptu_sensors.h"
#include "nrf_assert.h"
#include "ptu_registry.h"
#include "ptu_test_mux.h"

Go to the source code of this file.

Macros

#define PTU_SIZEOF_LOAD_VAL_BUF   8
 Size of P_TX_IN load variation buffer.
 
#define PTU_SENSORS_PTX_LOAD_VARIATION_MAX_PERIOD_MS   15
 Maximum allowed period for having a 100Hz +/- 20% load variation.
 
#define PTU_SENSORS_PTX_LOAD_VARIATION_MIN_PERIOD_MS   6
 Minimum allowed period for having a 100Hz +/- 20% load variation.
 
#define PTU_SENSORS_PTX_LOAD_VARIATION_MAX_PERIOD_TICKS   APP_TIMER_TICKS(PTU_SENSORS_PTX_LOAD_VARIATION_MAX_PERIOD_MS, APP_TIMER_PRESCALER)
 Max allowed period in ticks.
 
#define PTU_SENSORS_PTX_LOAD_VARIATION_MIN_PERIOD_TICKS   APP_TIMER_TICKS(PTU_SENSORS_PTX_LOAD_VARIATION_MIN_PERIOD_MS, APP_TIMER_PRESCALER)
 Min allowed period in ticks.
 
#define PREV(val)   ((val - 1) < 0 ? PTU_SIZEOF_LOAD_VAL_BUF - 1 : (val - 1))
 Get previous index in circular buffer.
 
#define NEXT(val)   ((val + 1) % PTU_SIZEOF_LOAD_VAL_BUF)
 Get next index in circular buffer.
 
#define GOTO_NEXT_IDX(idx)   (idx = NEXT(idx))
 Circular buffer index update.
 
#define GET_BIT(val, idx)   ((val >> idx) & 1)
 Read bit value.
 

Functions

API implementation
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 called. More...
 
uint32_t ptu_sensors_read (void)
 Read sensors. This function should typically be called regularly by a timer and can generate events by calling ptu_evt_handler(). More...
 
uint32_t ptu_sensors_data_get (const ptu_sensor_data_t **sensors_data)
 Get the latest data read from the PTU sensors. More...
 
void ptu_sensors_clear_long_beacon_extension_load_variation_buffer (void)
 Empty buffer containing load variation sample data for Long Beacon Extension.
 
bool ptu_sensors_valid_long_beacon_extension_load_variation_found (void)
 Check if a valid PTX load variation has occured. More...
 

Static functions and variables

typedef struct ptu_load_var_measurement_s ptu_sensors_load_variation_sample_t
 Struct representing a single P_TX sample.
 
static ptu_sensors_load_variation_sample_t m_lbe_samples [PTU_SIZEOF_LOAD_VAL_BUF]
 Buffer used for storing P_TX_IN load variation data.
 
static ptu_sensor_data_t m_ptu_sensor_data
 The latest version of the sensor data.
 
static ptu_sm_handler_t m_sm_handler
 State machine event handler.
 
 APP_TIMER_DEF (m_load_var_detected_timer_id)
 Load variation detect timer ID.
 
static void m_load_var_detect ()
 
static void m_rogue_object_detect (void)
 
static void m_load_var_detected_timer_handler (void *p_context)
 
static bool m_find_first_top (uint8_t *p_first_top, uint8_t last_updated_idx)
 
static bool m_find_bottom (uint8_t *p_bottom, uint8_t first_top)
 
static bool m_find_second_top_and_validate (uint8_t first_top, uint8_t bottom)
 
static void m_save_ptx_sample (uint8_t last_updated_index)
 

Function Documentation

static void m_load_var_detect ( )
static

Function storing measured resonator impedance to buffer and using max/min values of this buffer to determine whether a load variation has been detected.

Definition at line 62 of file ptu_sensors.c.

63 {
64  static bool m_res_imp_buf_filled_once = false;
65  static uint8_t m_res_imp_buf_index = 0;
66  static uint16_t m_res_imp_buf[PTU_Z_MEAS_BUF_LENGTH];
67  uint16_t res_impedance_max = 0;
68  uint16_t res_impedance_min = 0xffff;
69  uint16_t res_impedance_var_max = 0;
70  uint32_t err_code;
71 
72  // Save samples to array
73  m_res_imp_buf[m_res_imp_buf_index] = m_ptu_sensor_data.res_impedance;
74 
75  m_res_imp_buf_index++;
76 
77  if(m_res_imp_buf_index == PTU_Z_MEAS_BUF_LENGTH)
78  {
79  m_res_imp_buf_filled_once = true;
80  }
81 
82  m_res_imp_buf_index = (m_res_imp_buf_index % PTU_Z_MEAS_BUF_LENGTH);
83 
84  // Only detect load variation after buffer has been filled at least once
85  if(m_res_imp_buf_filled_once)
86  {
87  // Find max and min values in buffer
88  for (uint8_t i=0; i < PTU_Z_MEAS_BUF_LENGTH; i++)
89  {
90  if(m_res_imp_buf[i] > res_impedance_max)
91  {
92  res_impedance_max = m_res_imp_buf[i];
93  }
94 
95  if(m_res_imp_buf[i] < res_impedance_min)
96  {
97  res_impedance_min = m_res_imp_buf[i];
98  }
99  }
100 
101  res_impedance_var_max = (res_impedance_max - res_impedance_min);
102 
103  if(res_impedance_var_max > PTU_Z_TX_IN_LOAD_DETECT)
104  {
106  err_code = app_timer_stop(m_load_var_detected_timer_id);
107  APP_ERROR_CHECK(err_code);
108  err_code = app_timer_start(m_load_var_detected_timer_id, APP_TIMER_TICKS(PTU_LOAD_VARIATION_DETECT_LIFETIME_MS, APP_TIMER_PRESCALER), NULL);
109  APP_ERROR_CHECK(err_code);
110  }
111  }
112 }
#define PTU_LOAD_VARIATION_DETECT_LIFETIME_MS
Definition: ptu_config.h:70
static ptu_sensor_data_t m_ptu_sensor_data
The latest version of the sensor data.
Definition: ptu_sensors.c:53
#define PTU_Z_TX_IN_LOAD_DETECT
Definition: ptu_config.h:72
uint16_t res_impedance
#define APP_TIMER_PRESCALER
Definition: pru.h:33
#define PTU_Z_MEAS_BUF_LENGTH
Definition: ptu_config.h:79
static void m_rogue_object_detect ( void  )
static

Function detecting rogue object based on power delievered to power amplifier and reported power consumption from registered PRUs.

Definition at line 118 of file ptu_sensors.c.

119 {
120  uint32_t i;
121  uint32_t err_code;
122  ptu_reg_item_t * p_reg_item = NULL;
123  uint32_t reported_power_sum = 0;
124  uint32_t poweramp_input_power = (m_ptu_sensor_data.v_ina*m_ptu_sensor_data.i_ina)/ 100000 ;//[1/10 W/]
125 
126  for(i=0;i<PTU_MAX_CONNECTIONS; i++)
127  {
128  err_code = ptu_reg_item_get_from_index(i, &p_reg_item);
129  APP_ERROR_CHECK(err_code);
130 
131  if(p_reg_item->state == REG_ITEM_STATE_REGISTERED)
132  {
133  reported_power_sum += p_reg_item->prev_pru_dynamic.prect;
134  }
135  }
136 
137  if((poweramp_input_power * PTU_POWER_EFFICIENCY) > (reported_power_sum + PTU_ROGUE_OBJECT_DETECT_THRESHOLD))
138  {
140  }
141  else
142  {
144  }
145 }
Registry item.
Definition: ptu_registry.h:47
static ptu_sensor_data_t m_ptu_sensor_data
The latest version of the sensor data.
Definition: ptu_sensors.c:53
uint32_t ptu_reg_item_get_from_index(uint8_t index, ptu_reg_item_t **item_p)
Get registry item from index in database. Index must be < PTU_MAX_CONNECTIONS.
Definition: ptu_registry.c:126
#define PTU_POWER_EFFICIENCY
Definition: ptu_hw_config.h:43
pru_dynamic_t prev_pru_dynamic
Definition: ptu_registry.h:54
#define PTU_MAX_CONNECTIONS
Definition: ptu_config.h:29
ptu_reg_item_state_t state
Definition: ptu_registry.h:49
uint16_t prect
Definition: wpt.h:178
#define PTU_ROGUE_OBJECT_DETECT_THRESHOLD
Definition: ptu_config.h:175
static void m_load_var_detected_timer_handler ( void *  p_context)
static

Load variation detect timer handler.

Parameters
p_contextcontext data.

Definition at line 151 of file ptu_sensors.c.

152 {
154 }
static ptu_sensor_data_t m_ptu_sensor_data
The latest version of the sensor data.
Definition: ptu_sensors.c:53
static bool m_find_first_top ( uint8_t *  p_first_top,
uint8_t  last_updated_idx 
)
static

Locate the first sample where the the next value is smaller.

Parameters
p_first_topPointer to where the resulting index will be stored.
last_updated_idxTells what index was last updated.
Returns
true if top is found.

Definition at line 162 of file ptu_sensors.c.

163 {
164  uint8_t i;
165 
166  for ( i = NEXT(last_updated_idx); i != last_updated_idx ; GOTO_NEXT_IDX(i))
167  {
168  // Find index where previous value was smaller, and next value is smaller or equal to current
169  if(m_lbe_samples[i].val > m_lbe_samples[NEXT(i)].val)
170  {
171  *p_first_top = i;
172  return true;
173  }
174  }
175 
176  return false;
177 }
#define GOTO_NEXT_IDX(idx)
Circular buffer index update.
Definition: ptu_sensors.c:36
#define NEXT(val)
Get next index in circular buffer.
Definition: ptu_sensors.c:35
static ptu_sensors_load_variation_sample_t m_lbe_samples[PTU_SIZEOF_LOAD_VAL_BUF]
Buffer used for storing P_TX_IN load variation data.
Definition: ptu_sensors.c:50
static bool m_find_bottom ( uint8_t *  p_bottom,
uint8_t  first_top 
)
static

Locate the first sample where PTX delta from first top is sufficient for Long Beacon Extension.

Parameters
p_bottomPointer to where the resulting index will be stored.
first_topIndex of first top sample.
Returns
true if bottom is found.

Definition at line 185 of file ptu_sensors.c.

186 {
187  uint32_t i;
188 
189  for( i = NEXT(first_top); (i != first_top) && (m_lbe_samples[first_top].val - m_lbe_samples[i].val < PTU_P_TX_IN_LOAD_DETECT); GOTO_NEXT_IDX(i))
190  {
192  return false;
193  }
194 
195  *p_bottom = i;
196 
197  return true;
198 }
#define PTU_P_TX_IN_LOAD_DETECT
Definition: ptu_config.h:73
#define PTU_SENSORS_PTX_LOAD_VARIATION_MAX_PERIOD_TICKS
Max allowed period in ticks.
Definition: ptu_sensors.c:32
uint32_t ticks_diff(uint32_t ticks_now, uint32_t ticks_old)
Definition: common.c:78
#define GOTO_NEXT_IDX(idx)
Circular buffer index update.
Definition: ptu_sensors.c:36
#define NEXT(val)
Get next index in circular buffer.
Definition: ptu_sensors.c:35
static ptu_sensors_load_variation_sample_t m_lbe_samples[PTU_SIZEOF_LOAD_VAL_BUF]
Buffer used for storing P_TX_IN load variation data.
Definition: ptu_sensors.c:50
static bool m_find_second_top_and_validate ( uint8_t  first_top,
uint8_t  bottom 
)
static

Locate the second top in the extended beacon sample list, and check if the load variation is valid.

This function will start looking at the first sample AFTER the given first top. The initial bottom is assumed to be the first sample AFTER the given first top. However, if the current sample has lower value than the previous one, it will be assigned as the new bottom.

The function will return immediately when it sees a valid load variation.

Parameters
first_topIndex of first top sample.
bottomPointer to current bottom sample..
Returns
true if valid load variation is found

Definition at line 214 of file ptu_sensors.c.

215 {
216  uint32_t diff;
217  int8_t i;
218 
219  i = bottom;
220 
221  // Find first point that has large enough P_TX diff from bottom, and that has the correct distance from the first top
222  do
223  {
224  GOTO_NEXT_IDX(i);
225 
226  if(m_lbe_samples[i].val < m_lbe_samples[bottom].val) // we have found a lower bottom, this will not be a second top
227  {
228  bottom = i;
229 
230  // The bottom can not be the second top, jump to next sample.
231  continue;
232  }
233 
234  // If we see a sample with value lower than the previous sample OR (the sample has the same value
235  // as the previous sample AND it is not the same value as the bottom sample), return 'false'
236  // as the sample we are looking at might be part of different load variation period or the duty cycle
237  // of the current period is incorrect.
238  else if( m_lbe_samples[PREV(i)].val > m_lbe_samples[i].val ||
239  (m_lbe_samples[PREV(i)].val == m_lbe_samples[i].val && m_lbe_samples[i].val != m_lbe_samples[bottom].val))
240  return false;
241 
242  diff = ticks_diff(m_lbe_samples[i].ticks, m_lbe_samples[first_top].ticks);
243 
244  if((diff <= PTU_SENSORS_PTX_LOAD_VARIATION_MAX_PERIOD_TICKS && // Timing is correct
246  m_lbe_samples[i].val - m_lbe_samples[bottom].val >= PTU_P_TX_IN_LOAD_DETECT)// Variation from bottom is sufficient
247  {
248  return true;
249  }
250 
251  // Make sure we only iterate once over the circular buffer.
252  // We can not compare the ticks to see if we have gone through the circular buffer as you might have overflow situations in the ticks value.
253  }while(i != first_top);
254 
255  return false;
256 }
#define PTU_P_TX_IN_LOAD_DETECT
Definition: ptu_config.h:73
#define PTU_SENSORS_PTX_LOAD_VARIATION_MAX_PERIOD_TICKS
Max allowed period in ticks.
Definition: ptu_sensors.c:32
uint32_t ticks_diff(uint32_t ticks_now, uint32_t ticks_old)
Definition: common.c:78
#define PTU_SENSORS_PTX_LOAD_VARIATION_MIN_PERIOD_TICKS
Min allowed period in ticks.
Definition: ptu_sensors.c:33
#define GOTO_NEXT_IDX(idx)
Circular buffer index update.
Definition: ptu_sensors.c:36
static ptu_sensors_load_variation_sample_t m_lbe_samples[PTU_SIZEOF_LOAD_VAL_BUF]
Buffer used for storing P_TX_IN load variation data.
Definition: ptu_sensors.c:50
#define PREV(val)
Get previous index in circular buffer.
Definition: ptu_sensors.c:34
static void m_save_ptx_sample ( uint8_t  last_updated_index)
static

Store current ticks and ptx value in a list of samples

Parameters
last_updated_indexWhere should we store the sample

Definition at line 263 of file ptu_sensors.c.

264 {
265  uint32_t err_code, curr_ticks;
266 
268  APP_ERROR_CHECK(err_code);
269 
270  err_code = app_timer_cnt_get(&curr_ticks);
271  APP_ERROR_CHECK(err_code);
272 
273  // Store sample with current PTX value and timestamp
274  m_lbe_samples[last_updated_index].val = m_ptu_sensor_data.p_tx_in;
275  m_lbe_samples[last_updated_index].ticks = curr_ticks;
276 }
static ptu_sensor_data_t m_ptu_sensor_data
The latest version of the sensor data.
Definition: ptu_sensors.c:53
uint32_t ptu_tmux_ptx_get(uint16_t *p_ptx)
Test wrapper for ptu_hal_ptx_get().
Definition: ptu_test_mux.c:107
static ptu_sensors_load_variation_sample_t m_lbe_samples[PTU_SIZEOF_LOAD_VAL_BUF]
Buffer used for storing P_TX_IN load variation data.
Definition: ptu_sensors.c:50