Nordic Semiconductor nRF5 AirFuel SDK  version 2.2.0
ptu_power_sharing.c
Go to the documentation of this file.
1 /* Copyright (c) 2012 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 #include <math.h>
18 
19 #include "nrf_assert.h"
20 #include "ptu_conn_man.h"
21 #include "ptu_power_sharing.h"
22 
23 /******************************************************************************/
26 /******************************************************************************/
27 
29 #define REG_DEVICE_CAN_ADJUST_POWER(DEV) \
30  (DEV->prev_pru_static.info_adj_power_capability && \
31  !DEV->p_adj_disabled && \
32  !DEV->active_p_adj_cooldown)
33 
34 
37 typedef struct
38 {
39  uint32_t granted_prect_sum; // Sum of granted Prect to PRUs (including PRUs waiting to allow to draw power)
40  int32_t available_power; // Max available PTU power - granted_prect_sum
41  bool pending_power_adjust; // We are waiting for a "power adjusted response" from one or more PRUs
42  bool prus_waiting; // One or more PRUs are waiting to be allowed to use power
43  bool temperature_warning; // PTU temperature warning active.
44 } ptu_pctl_status_t;
45 
46 static ptu_pctl_status_t m_pctl_status; // Status variables
48 
54 {
55  uint32_t err_code;
56 
58  {
59  reg_item_p -> prev_ctl.time_set = BLE_WPTS_TIME_SET_BITVAL;
60  }
61 
62  else
63  {
64  reg_item_p -> prev_ctl.time_set = CTL_TIME_SET_DENIED;
65  }
66 
67  do{
68  reg_item_p->pending_ctl_write = true;
69  err_code = ble_wpts_c_send_pru_control(&reg_item_p->ble_wpts_c, &reg_item_p->prev_ctl);
70  } while(err_code == BLE_ERROR_NO_TX_PACKETS);
71 }
72 
81 static uint8_t m_get_prect(uint8_t prect_max, ctl_adj_power_t power_adjust)
82 {
83  uint8_t retval = 0;
84 
85  switch(power_adjust)
86  {
88  retval = prect_max;
89  break;
91  retval = (uint8_t)ceil(prect_max * 0.66);
92  break;
94  retval = (uint8_t)ceil(prect_max * 0.33);
95  break;
97  retval = 25;
98  break;
99  default:
100  ASSERT(false);
101  break;
102  }
103  return retval;
104 }
105 
112 static uint8_t m_prect_max_get(ptu_reg_item_t * reg_item)
113 {
114  ASSERT(reg_item != NULL);
115  uint8_t retval = 0;
116 
118  retval = m_get_prect(reg_item->prev_pru_static.prect_max, reg_item->prev_ctl.adj_power);
119  else
120  retval = reg_item->prev_pru_static.prect_max;
121 
122  return retval;
123 }
124 
132 static uint8_t m_prect_diff_after_inc_get(ptu_reg_item_t * reg_item)
133 {
134  ASSERT(reg_item != NULL);
135  ctl_adj_power_t incremented_power_level = reg_item->prev_ctl.adj_power;
136  switch(reg_item->prev_ctl.adj_power)
137  {
139  return 0;
141  incremented_power_level = CTL_ADJ_POWER_MAX_VAL;
142  break;
144  incremented_power_level = CTL_ADJ_POWER_66_PCT_VAL;
145  break;
147  incremented_power_level = CTL_ADJ_POWER_33_PCT_VAL;
148  break;
149  default:
150  ASSERT(false);
151  }
152 
153  return m_get_prect(reg_item->prev_pru_static.prect_max, incremented_power_level)
154  - m_get_prect(reg_item->prev_pru_static.prect_max, reg_item->prev_ctl.adj_power);
155 }
156 
157 
158 
166 {
167  uint32_t err_code;
168 
170  reg_item->active_p_adj_cooldown = true;
171  err_code = app_timer_cnt_get(&(reg_item->p_adj_time));
172  APP_ERROR_CHECK(err_code);
173  reg_item->adjusted_power = false;
174  reg_item->p_rect_before_p_adj = reg_item->prev_pru_dynamic.vrect * reg_item->prev_pru_dynamic.irect;
175 }
176 
182 static bool m_pru_decrease_power()
183 {
184  ptu_reg_item_t* match_reg_item;
185  ptu_reg_item_t* registered_devices[PTU_MAX_CONNECTIONS];
186  uint8_t n_reg_devices = ptu_reg_registered_devices_get(registered_devices);
187 
188  match_reg_item = NULL;
189 
190  for(uint8_t i = 0; i < n_reg_devices; i++)
191  {
192 
193  if(REG_DEVICE_CAN_ADJUST_POWER(registered_devices[i]) && \
194  (registered_devices[i]->prev_ctl.adj_power == CTL_ADJ_POWER_MAX_VAL))
195  {
196  match_reg_item = registered_devices[i];
197  match_reg_item->prev_adj_power = CTL_ADJ_POWER_MAX_VAL;
198  match_reg_item->prev_ctl.adj_power = CTL_ADJ_POWER_66_PCT_VAL;
199  break;
200  }
201  }
202 
203  if(match_reg_item == NULL)
204  {
205  for(uint8_t i = 0; i < n_reg_devices; i++)
206  {
207  if(REG_DEVICE_CAN_ADJUST_POWER(registered_devices[i]) && \
208  (registered_devices[i]->prev_ctl.adj_power == CTL_ADJ_POWER_66_PCT_VAL))
209  {
210  match_reg_item = registered_devices[i];
211  match_reg_item->prev_adj_power = CTL_ADJ_POWER_66_PCT_VAL;
212  match_reg_item->prev_ctl.adj_power = CTL_ADJ_POWER_33_PCT_VAL;
213  break;
214  }
215  }
216  }
217 
218  if(match_reg_item == NULL)
219  {
220  for(uint8_t i = 0; i < n_reg_devices; i++)
221  {
222  if(REG_DEVICE_CAN_ADJUST_POWER(registered_devices[i]) && \
223  (registered_devices[i]->prev_ctl.adj_power == CTL_ADJ_POWER_33_PCT_VAL))
224  {
225  match_reg_item = registered_devices[i];
226  match_reg_item->prev_adj_power = CTL_ADJ_POWER_33_PCT_VAL;
227  match_reg_item->prev_ctl.adj_power = CTL_ADJ_POWER_2_5_W_VAL;
228  break;
229  }
230  }
231  }
232 
233  if(match_reg_item != NULL)
234  {
235  m_send_power_adjust_command(match_reg_item);
236  return true;
237  }
238  else
239  {
240  return false;
241  }
242 }
243 
249 static bool m_pru_increase_power()
250 {
251  ptu_reg_item_t* match_reg_item;
252  ptu_reg_item_t* registered_devices[PTU_MAX_CONNECTIONS];
253  uint8_t n_reg_devices = ptu_reg_registered_devices_get(registered_devices);
254 
255  match_reg_item = NULL;
256 
257  for(uint8_t i = 0; i < n_reg_devices; i++)
258  {
259  if(REG_DEVICE_CAN_ADJUST_POWER(registered_devices[i]) && \
260  (registered_devices[i]->prev_ctl.adj_power == CTL_ADJ_POWER_2_5_W_VAL) && \
261  (m_prect_diff_after_inc_get(registered_devices[i]) <= m_pctl_status.available_power))
262  {
263  match_reg_item = registered_devices[i];
264  match_reg_item->prev_adj_power = CTL_ADJ_POWER_2_5_W_VAL;
265  match_reg_item->prev_ctl.adj_power = CTL_ADJ_POWER_33_PCT_VAL;
266  break;
267  }
268  }
269 
270  if(match_reg_item == NULL)
271  {
272  for(uint8_t i = 0; i < n_reg_devices; i++)
273  {
274  if(REG_DEVICE_CAN_ADJUST_POWER(registered_devices[i]) && \
275  (registered_devices[i]->prev_ctl.adj_power == CTL_ADJ_POWER_33_PCT_VAL) && \
276  (m_prect_diff_after_inc_get(registered_devices[i]) <= m_pctl_status.available_power))
277  {
278  match_reg_item = registered_devices[i];
279  match_reg_item->prev_adj_power = CTL_ADJ_POWER_33_PCT_VAL;
280  match_reg_item->prev_ctl.adj_power = CTL_ADJ_POWER_66_PCT_VAL;
281  break;
282  }
283  }
284  }
285 
286  if(match_reg_item == NULL)
287  {
288  for(uint8_t i = 0; i < n_reg_devices; i++)
289  {
290  if(REG_DEVICE_CAN_ADJUST_POWER(registered_devices[i]) && \
291  (registered_devices[i]->prev_ctl.adj_power == CTL_ADJ_POWER_66_PCT_VAL) &&\
292  (m_prect_diff_after_inc_get(registered_devices[i]) <= m_pctl_status.available_power))
293  {
294  match_reg_item = registered_devices[i];
295  match_reg_item->prev_adj_power = CTL_ADJ_POWER_66_PCT_VAL;
296  match_reg_item->prev_ctl.adj_power = CTL_ADJ_POWER_MAX_VAL;
297  break;
298  }
299  }
300  }
301 
302  if(match_reg_item != NULL)
303  {
304  m_send_power_adjust_command(match_reg_item);
305  return true;
306  }
307  else
308  {
309  return false;
310  }
311 }
312 
318 static bool m_pru_deny_power()
319 {
320  ptu_reg_item_t * match_reg_item;
321  ptu_reg_item_t* registered_devices[PTU_MAX_CONNECTIONS];
322  uint8_t n_reg_devices = ptu_reg_registered_devices_get(registered_devices);
323 
324  for(uint8_t i = 0; i < n_reg_devices; i++)
325  {
326  if(registered_devices[i]->prev_ctl.permissions == CTL_PERMISSION_PERMITTED)
327  {
328  match_reg_item = registered_devices[i];
329  match_reg_item->prev_ctl.enable_pru_output = 0;
330  match_reg_item->prev_ctl.enable_pru_charge_indicator = 0;
331  match_reg_item->prev_ctl.permissions = m_pctl_status.temperature_warning ? CTL_PERMISSION_DENIED_HIGH_TEMP : CTL_PERMISSION_DENIED_POWER;
333  return true;
334  }
335  }
336 
337  return false;
338 }
339 
345 {
346  ptu_reg_item_t* registered_devices[PTU_MAX_CONNECTIONS];
347  uint8_t nof_devices = ptu_reg_registered_devices_get(registered_devices);
348  uint8_t nof_devices_being_charged = 0;
349 
350  for(uint8_t i = 0; i < nof_devices; ++i)
351  {
352  if(registered_devices[i]->prev_ctl.enable_pru_output == 1 || registered_devices[i]->pending_ctl_write)
353  nof_devices_being_charged++;
354  }
355 
356  ASSERT(nof_devices_being_charged <= PTU_MAX_DEVICES);
357 
358  return nof_devices_being_charged == PTU_MAX_DEVICES;
359 }
360 
367 static bool m_pru_allow_power()
368 {
369  ptu_reg_item_t* registered_devices[PTU_MAX_CONNECTIONS];
370  ptu_reg_item_t * match_reg_item;
371  uint8_t n_reg_devices = ptu_reg_registered_devices_get(registered_devices);
372 
373  for(uint8_t i = 0; i < n_reg_devices; i++)
374  {
375  if(registered_devices[i]->prev_ctl.permissions != CTL_PERMISSION_PERMITTED && \
376  m_prect_max_get(registered_devices[i]) <= m_pctl_status.available_power && \
377  registered_devices[i]->adjusted_power)
378  {
379  match_reg_item = registered_devices[i];
380  match_reg_item->prev_ctl.enable_pru_output = 1;
381  match_reg_item->prev_ctl.enable_pru_charge_indicator = 1;
384  return true;
385  }
386  }
387 
388  return false;
389 }
390 
391 
403 {
404  // If we can not adjust power on new device (of any reason), return MAX_VAL, and regular Power Sharing between
405  // already connected PRUs will take place.
406  ctl_adj_power_t power_adjust = CTL_ADJ_POWER_MAX_VAL;
407  uint8_t current_adjust_val = 0;
408  uint8_t prect_33_percent = (uint8_t)(new_reg_item_p->prev_pru_static.prect_max * 0.33);
409  uint8_t prect_66_percent = prect_33_percent * 2;
410  // See wether PTU has enough power for 66% or 33% of P_RECT_MAX
411  if(prect_66_percent <= m_pctl_status.available_power)
412  {
413  current_adjust_val = prect_66_percent;
414  power_adjust = CTL_ADJ_POWER_66_PCT_VAL;
415  }
416 
417  else if(prect_33_percent <= m_pctl_status.available_power)
418  {
419  current_adjust_val = prect_33_percent;
420  power_adjust = CTL_ADJ_POWER_33_PCT_VAL;
421  }
422 
423  // What is biggest, our fraction of the P_RECT_MAX, or 2.5W ?
424  // In any case, make sure PTU has enough to power left
425  if(current_adjust_val < 25 && m_pctl_status.available_power >= 25)
426  power_adjust = CTL_ADJ_POWER_2_5_W_VAL;
427 
428  return power_adjust;
429 }
430 
431 
434 static void m_status_update(void)
435 {
436  ptu_reg_item_t* registered_devices[PTU_MAX_CONNECTIONS];
437  uint8_t n_reg_devices = ptu_reg_registered_devices_get(registered_devices);
438  m_pctl_status.granted_prect_sum = 0;
439  m_pctl_status.pending_power_adjust = false;
440  m_pctl_status.prus_waiting = false;
441 
442  for(uint8_t i = 0; i < n_reg_devices; i++)
443  {
444  if(registered_devices[i]->prev_pru_static.info_adj_power_capability &&
445  !(registered_devices[i]->p_adj_disabled) &&
446  !(registered_devices[i]->prev_pru_dynamic.adjust_power_response) &&
447  registered_devices[i]->prev_ctl.adj_power != CTL_ADJ_POWER_MAX_VAL)
448  {
449  m_pctl_status.pending_power_adjust = true;
450  }
451 
452  // Potential power adjust
453  if(registered_devices[i]->pending_ctl_write)
454  {
455  m_pctl_status.pending_power_adjust = true;
456  }
457 
458  // If any PRUs are denied to start charging.
459  if(registered_devices[i]->prev_ctl.permissions != BLE_WPTS_PERMISSION_PERMITTED)
460  {
461  m_pctl_status.prus_waiting = true;
462  }
463 
464  if(registered_devices[i]->prev_ctl.permissions == BLE_WPTS_PERMISSION_PERMITTED)
465  {
466  m_pctl_status.granted_prect_sum += m_prect_max_get(registered_devices[i]);
467  }
468  }
469 
470  m_pctl_status.available_power = (int32_t) (PTU_PTX_IN_MAX * PTU_POWER_EFFICIENCY);
471 
472  // If we have a temperature warning we reduce the total power the PTU can source
473  // by PTU_PTX_IN_TEMP_WARNING_DEC %.
474  if(m_pctl_status.temperature_warning)
475  {
476  m_pctl_status.available_power *= (100 - PTU_PTX_IN_TEMP_WARNING_DEC);
477  m_pctl_status.available_power /= 100;
478  }
479 
480  m_pctl_status.available_power -= m_pctl_status.granted_prect_sum;
481 }
482 
483 
486 static void m_charge_disable_all()
487 {
488  ptu_reg_item_t* registered_devices[PTU_MAX_CONNECTIONS];
489  uint8_t n_reg_devices = ptu_reg_registered_devices_get(registered_devices);
490 
491  for(uint8_t i = 0; i < n_reg_devices ; i++)
492  {
493  registered_devices[i]->prev_ctl.enable_pru_output = 0;
494  registered_devices[i]->prev_ctl.enable_pru_charge_indicator = 0;
495  m_ble_wpts_c_send_pru_control_wait_buffer(registered_devices[i]);
496  registered_devices[i]->pending_charge_disable = true;
497  }
498 }
499 
502 static void m_charge_complete_update(ptu_reg_item_t * p_reg_item, ble_wpts_c_evt_t * const p_wpts_c_evt)
503 {
504  if(p_reg_item->charged && ptu_reg_all_charged())
505  {
507  m_sm_handler(PTU_SM_SIGNAL_PRU_ALL_CHARGE_COMPLETE);
508  }
509 }
510 
519 {
520  int32_t diff, required_diff;
521 
522  required_diff = ((int32_t)m_get_prect(item->prev_pru_static.prect_max, item->prev_adj_power)) \
523  - ((int32_t)m_get_prect(item->prev_pru_static.prect_max, item->prev_ctl.adj_power));
524  diff = (int32_t)(item->prev_pru_dynamic.vout * item->prev_pru_dynamic.iout) - item->p_rect_before_p_adj;
525 
528  diff == required_diff;
529 }
530 
534 static void m_update_pru_p_adj_status(void)
535 {
536  uint32_t err_code, diff;
537  ptu_reg_item_t* registered_devices[PTU_MAX_CONNECTIONS];
538  uint8_t n_reg_devices = ptu_reg_registered_devices_get(registered_devices);
539  uint32_t current_time;
540 
541  err_code = app_timer_cnt_get(&current_time);
542  APP_ERROR_CHECK(err_code);
543 
544  for(uint8_t i = 0; i < n_reg_devices; ++i)
545  {
546  if(registered_devices[i] != NULL)
547  {
548  diff = ticks_diff(current_time, registered_devices[i]->p_adj_time);
549 
550  // Is power adjust cooldown period finished?
551  if(registered_devices[i]->active_p_adj_cooldown && \
552  diff >= APP_TIMER_TICKS(PTU_P_ADJ_CMD_COOLDOWN_MS, APP_TIMER_PRESCALER))
553  registered_devices[i]->active_p_adj_cooldown = false;
554 
555  // Is the PRU not responding to the last power adjust command?
556  if(diff >= APP_TIMER_TICKS(PTU_ADJUSTED_POWER_BIT_TIMEOUT_MS, APP_TIMER_PRESCALER) \
557  && !(registered_devices[i]->adjusted_power || m_adjusted_power_sensed(registered_devices[i])))
558  {
559  registered_devices[i]->prev_ctl.adj_power = registered_devices[i]->prev_adj_power; // Assume PRU will remain at previous power level.
560  registered_devices[i]->p_adj_disabled = true; // Do not send any more power adjust commands to PRU.
561 
562  // If this was the initial power adjust command and PRU does not respond, disconnect it.
563  if(registered_devices[i]->prev_ctl.permissions == CTL_PERMISSION_PERMITTED_WAITING && registered_devices[i]->prev_ctl.adj_power != CTL_ADJ_POWER_MAX_VAL)
564  ptu_cm_remove_device(registered_devices[i]);
565  }
566  }
567  }
568 }
569 
574 static void m_allow_pru_to_charge(ptu_reg_item_t * reg_item_p)
575 {
576  reg_item_p -> prev_ctl.enable_pru_output = 1;
577  reg_item_p -> prev_ctl.enable_pru_charge_indicator = 1;
578  reg_item_p -> prev_ctl.adj_power = CTL_ADJ_POWER_MAX_VAL;
579  reg_item_p -> prev_ctl.permissions = CTL_PERMISSION_PERMITTED;
581 }
582 
589 static void m_deny(ptu_reg_item_t * reg_item_p, ctl_perm_t permissions)
590 {
591  reg_item_p -> prev_ctl.enable_pru_output = 0;
592 
593  // It is only in the case where PRU is too large Category that PRU charge could NEVER happen
594  if(permissions == BLE_WPTS_PERMISSION_DENIED_CLASS)
595  reg_item_p -> prev_ctl.enable_pru_charge_indicator = 0;
596  else
597  reg_item_p -> prev_ctl.enable_pru_charge_indicator = 1;
598 
599  reg_item_p -> prev_ctl.permissions = permissions;
601  ptu_cm_remove_device(reg_item_p);
602 }
603 
610 {
611  reg_item_p -> prev_ctl.enable_pru_output = 0;
612  reg_item_p -> prev_ctl.enable_pru_charge_indicator = 1;
613  reg_item_p -> prev_ctl.permissions = CTL_PERMISSION_PERMITTED_WAITING;
614  reg_item_p -> prev_ctl.adj_power = m_attempt_to_get_prect_within_available_resources(reg_item_p);
615  m_send_power_adjust_command(reg_item_p);
616 }
617 
621 static void m_handle_new_device(ptu_reg_item_t * reg_item_p)
622 {
623  if(reg_item_p -> prev_pru_static.pru_category > (PTU_CLASS + 2)) // PTU Class 2 = 1, Class 2 supports Category 3 PRU, hence " + 2 "
624  m_deny(reg_item_p, CTL_PERMISSION_DENIED_CLASS);
625 
628 
629  else if(m_pctl_status.available_power < reg_item_p->prev_pru_static.prect_max || m_pctl_status.pending_power_adjust)
630  {
631  // If new device supports power adjustment, make an attempt to adjust its power.
632  if(reg_item_p->prev_pru_static.info_adj_power_capability == 1)
634 
635  // Otherwise, adjust PTU can never fulfill the PRUs power demand, and it should be rejected.
636  else
637  m_deny(reg_item_p, CTL_PERMISSION_DENIED_POWER);
638  }
639 
640  else
641  m_allow_pru_to_charge(reg_item_p);
642 }
643 
646 /******************************************************************************/
649 /******************************************************************************/
651 {
652  if(sm_handler == NULL)
653  return NRF_ERROR_INVALID_PARAM;
654 
655  m_sm_handler = sm_handler;
656  memset(&m_pctl_status, 0, sizeof(ptu_pctl_status_t));
657 
658  return NRF_SUCCESS;
659 }
660 
662 {
663  m_pctl_status.temperature_warning = warning;
664 }
665 
667 {
668  ptu_reg_item_t * new_reg_item_p = ptu_reg_item_get_from_conn_handle(p_wpts_c->conn_handle);
669 
671 
672  if (new_reg_item_p != NULL)
673  {
674  // Perform charge_complete control
675  if(p_wpts_c_evt->type == BLE_WPTS_C_EVT_PRU_ALERT ||
677  {
678  m_charge_complete_update(new_reg_item_p, p_wpts_c_evt);
679  m_status_update();
680 
681  if(p_wpts_c_evt->data.pru_dynamic.adjust_power_response == 1)
682  new_reg_item_p->adjusted_power = true;
683  }
684 
685  // Whenever we receive a PRU dynamic update we might wanna adjust power.
686  switch(p_wpts_c_evt->type)
687  {
689 
690  // If we have a new device to register.
691  if(new_reg_item_p->state != REG_ITEM_STATE_REGISTERED)
692  {
693  m_handle_new_device(new_reg_item_p);
694  }
695 
696  else
697  {
698  if(!m_pctl_status.pending_power_adjust)
699  {
700  // If we have in sum have granted PRUs to consume more power than we can give
701  if(m_pctl_status.available_power < 0)
702  {
703  // Attempt to instruct PRUs to reduce power
704  if(!m_pru_decrease_power())
705  {
706  // If not possible to reduce PRU power, we have to deny some PRUs to use power.
707  (void)m_pru_deny_power();
708  }
709  }
710  // If any PRUs has been denied to start charging
711  else if(m_pctl_status.prus_waiting)
712  {
713  // Attempt to allow denied PRUs start charging.
714  if(!m_pru_allow_power())
715  {
716  // If this was not possible we try to reduce power to the other PRUs.
717  (void)m_pru_decrease_power();
718  }
719  }
720  else
721  {
722  // We have power "left". We allow PRUs to consume more power.
723  (void)m_pru_increase_power();
724  }
725  }
726  }
727  break;
729  new_reg_item_p->pending_ctl_write = false;
730  break;
731  default:
732  break;
733  }
734  }
735 }
736 
uint16_t irect
Definition: wpt.h:168
pru_control_t prev_ctl
Definition: ptu_registry.h:55
#define PTU_MAX_DEVICES
Definition: ptu_config.h:30
uint8_t info_adj_power_capability
Definition: wpt.h:104
Registry item.
Definition: ptu_registry.h:47
static bool m_adjusted_power_sensed(ptu_reg_item_t *item)
See if PRU has adjusted power by looking at the I_RECT and V_RECT values from PRU dynamic params...
#define BLE_WPTS_PERMISSION_PERMITTED
PRU Control characteristic Permission field values.
#define PTU_PTX_IN_MAX
Definition: ptu_hw_config.h:31
union ble_wpts_c_evt_t::@1 data
uint16_t conn_handle
Definition: ble_wpts_c.h:66
WPT Service Client structure. This contains various status information for the service.
Definition: ble_wpts_c.h:57
void(* ptu_sm_handler_t)(ptu_sm_signal_type_t signal)
Definition: ptu.h:30
uint8_t ptu_reg_registered_devices_get(ptu_reg_item_t **registered_devices)
Get handles for all registered devices.
Definition: ptu_registry.c:254
uint16_t vout
Definition: wpt.h:169
uint8_t adjust_power_response
Definition: wpt.h:177
uint32_t ticks_diff(uint32_t ticks_now, uint32_t ticks_old)
Definition: common.c:78
ble_wpts_c_t ble_wpts_c
Definition: ptu_registry.h:52
static void m_ble_wpts_c_send_pru_control_wait_buffer(ptu_reg_item_t *reg_item_p)
Sends the control packet in prev_ctl to a PRU.
uint16_t vrect
Definition: wpt.h:167
uint8_t enable_pru_output
Definition: wpt.h:81
#define BLE_WPTS_PRU_DYNAMIC_OPTION_IOUT_BITPOS
ctl_perm_t
Permissions fields in control packet.
Definition: wpt.h:52
uint16_t iout
Definition: wpt.h:170
uint8_t adv_flags
Definition: ptu_registry.h:50
static void m_handle_new_device(ptu_reg_item_t *reg_item_p)
Handle the power sharing of a new PRU.
#define PTU_PTX_IN_TEMP_WARNING_DEC
Definition: ptu_hw_config.h:90
#define PTU_POWER_EFFICIENCY
Definition: ptu_hw_config.h:43
ctl_adj_power_t prev_adj_power
Definition: ptu_registry.h:57
#define BLE_WPTS_TIME_SET_BITVAL
Definition: ptu_config.h:278
uint8_t pending_ctl_write
Definition: ptu_registry.h:65
static bool m_max_number_of_devices_is_being_charged(void)
Check if the maximum number of PRUs is being charged.
static void m_charge_disable_all()
Disable PRU output for all connected PRUs.
static bool m_pru_decrease_power()
Search for PRUs having "adjust power" capability and send control packet instructing the PRU to reduc...
uint8_t charged
Definition: ptu_registry.h:66
#define PTU_CLASS
Definition: ptu_hw_config.h:30
static void m_deny(ptu_reg_item_t *reg_item_p, ctl_perm_t permissions)
Update registry item and issue control packet for denying PRU charge. Will remove device from registr...
#define BLE_WPTS_PRU_DYNAMIC_OPTION_VOUT_BITPOS
PRU Dynamic Parameter characteristic Option field.
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...
int32_t p_rect_before_p_adj
Definition: ptu_registry.h:61
uint8_t p_adj_disabled
Definition: ptu_registry.h:69
static bool m_pru_deny_power()
Search for PRUs being permitted to enable charge output and send control packet denying the PRU to do...
ble_wpts_c_evt_type_t type
Definition: ble_wpts_c.h:46
ctl_perm_t permissions
Definition: wpt.h:84
#define PTU_ADJUSTED_POWER_BIT_TIMEOUT_MS
Definition: ptu_config.h:42
static bool m_pru_increase_power()
Search for PRUs having "adjust power" capability and send control packet allowing the PRU to increase...
static bool m_pru_allow_power()
Search for PRUs not being permitted to enable charge output and send control packet allowing the PRU ...
pru_static_t prev_pru_static
Definition: ptu_registry.h:53
bool ptu_reg_all_charged(void)
Function returning true if all items in registry are charged or there are not items in registry...
Definition: ptu_registry.c:273
WPT Service Client event.
Definition: ble_wpts_c.h:44
static void m_permit_with_waiting_time_and_adjust(ptu_reg_item_t *reg_item_p)
Allow PRU to charge with adjusted power draw. Update registry item and issue control packet indicatin...
#define REG_DEVICE_CAN_ADJUST_POWER(DEV)
Check if a device is capable of receiving power adjust commands.
#define APP_TIMER_PRESCALER
Definition: pru.h:33
uint8_t pending_charge_disable
Definition: ptu_registry.h:67
static ctl_adj_power_t m_attempt_to_get_prect_within_available_resources(ptu_reg_item_t *new_reg_item_p)
See if it is possible to adjust power drain from a not yet registerred PRU so that it fits within the...
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
static ptu_sm_handler_t m_sm_handler
State machine event handler.
Definition: ptu_sensors.c:55
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.
uint32_t p_adj_time
Definition: ptu_registry.h:60
uint8_t optional_fields
Definition: wpt.h:166
static void m_send_power_adjust_command(ptu_reg_item_t *reg_item)
Transmits a PRU control packet, and performs all required bookkeeping related to performing the power...
ctl_adj_power_t
Power adjust settings in control packet.
Definition: wpt.h:42
uint8_t enable_pru_charge_indicator
Definition: wpt.h:82
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
uint8_t active_p_adj_cooldown
Definition: ptu_registry.h:62
pru_dynamic_t pru_dynamic
Definition: ble_wpts_c.h:51
static void m_update_pru_p_adj_status(void)
Update cooldown values for all PRUs which has received a power adjust command recently. Also checks for PRUs that does not respond with power adjust bit correctly after being sent a power adjust command.
#define BLE_WPTS_PERMISSION_DENIED_CLASS
static uint8_t m_get_prect(uint8_t prect_max, ctl_adj_power_t power_adjust)
Get truncated value for adjusted power.
#define PTU_MAX_CONNECTIONS
Definition: ptu_config.h:29
static void m_charge_complete_update(ptu_reg_item_t *p_reg_item, ble_wpts_c_evt_t *const p_wpts_c_evt)
Check if all PRUs are done charging, in which case all will be disabled.
static void m_status_update(void)
Collect status information from all PRUs and update m_pctl_status.
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.
uint32_t ble_wpts_c_send_pru_control(ble_wpts_c_t *p_wpts_c, pru_control_t *p_wpts_pru_control)
Send a PRU Control message to the PRU server.
Definition: ble_wpts_c.c:366
static uint8_t m_prect_diff_after_inc_get(ptu_reg_item_t *reg_item)
Get the maximum increased Prect if we step up the allowed Prect for the PRU with one step...
ptu_reg_item_state_t state
Definition: ptu_registry.h:49
#define PTU_P_ADJ_CMD_COOLDOWN_MS
Definition: ptu_config.h:41
static void m_allow_pru_to_charge(ptu_reg_item_t *reg_item_p)
Update registry item and issue control packet for allowing PRU to charge.
ctl_adj_power_t adj_power
Definition: wpt.h:83
static uint8_t m_prect_max_get(ptu_reg_item_t *reg_item)
Get the maximum Prect in [100 mW] for a PRU.
#define BLE_WPTS_ADV_FLAG_TIME_SET_SUPPORT_BITMSK
uint8_t adjusted_power
Definition: ptu_registry.h:63
#define BLE_WPTS_ADV_FLAG_TIME_SET_SUPPORT_BITPOS
uint8_t prect_max
Definition: wpt.h:95