Appiko
sensepi_cam_trigger.c
1 /*
2  * sensepi_cam_trigger.c : Module to handle camera triggering related functionality
3  * Copyright (C) 2019 Appiko
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
19 #include "sensepi_cam_trigger.h"
20 
21 #include "sensepi_ble.h"
22 
23 #include "pir_sense.h"
24 #include "led_sense.h"
25 #include "mcp4012_x.h"
26 #include "ms_timer.h"
27 #include "led_ui.h"
28 #include "out_pattern_gen.h"
29 #include "log.h"
30 
31 #include "hal_pin_analog_input.h"
32 #include "hal_nop_delay.h"
33 #include "hal_gpio.h"
34 
35 #include "nrf_util.h"
36 #include "nrf_assert.h"
37 #include "common_util.h"
38 
39 #include "stdint.h"
40 #include "stdbool.h"
41 #include "string.h"
42 
43 #include "boards.h"
44 #include "sensepi_store_config.h"
45 
46 #define DEBUG_PRINT 0
47 
49 #define LED_WAIT_TIME_MS 301
50 
51 #define PIR_SENSE_INTERVAL_MS 40
52 
54 #define PIR_THRESHOLD_MULTIPLY_FACTOR 8
55 
57 #define LIGHT_THRESHOLD_MULTIPLY_FACTOR 32
58 
59 #define LIGHT_SENSE_INTERVAL_MS (5*60*1000)
60 
61 #define LIGHT_SENSE_INTERVAL_TICKS (MS_TIMER_TICKS_MS(LIGHT_SENSE_INTERVAL_MS))
62 
64 #define SENSE_FEEDBACK_TIMEOUT_MS (9.8*60*1000)
65 
67 #define SENSE_FEEDBACK_TIMEOUT_TICKS (MS_TIMER_TICKS_MS(SENSE_FEEDBACK_TIMEOUT_MS))
68 
69 #define SENSEPI_CAM_TRIGGER_MS_TIMER_USED MS_TIMER2
70 /*Data_Process module MACROS*/
72 #define NUM_PIN_OUT 2
73 
74 #define SIZE_OF_BYTE 8
75 
76 #define MODE_POS 0
77 
78 #define INPUT1_POS 1
79 
80 #define INPUT2_POS 3
81 
82 #define MODE_MSK 0x000000FF
83 
84 #define INPUT1_MSK 0x00FFFF00
85 
86 #define INPUT2_MSK 0xFF000000
87 
89 #define SINGLE_SHOT_TRANSITIONS 2
90 
91 #define SINGLE_SHOT_DURATION MS_TIMER_TICKS_MS(250)
92 
93 #define BULB_SHOT_TRANSITIONS 2
94 
95 #define FOCUS_TRANSITIONS 2
96 
97 #define TIMER_VIDEO_TRANSITIONS 3
98 
99 #define VIDEO_START_PULSE MS_TIMER_TICKS_MS(250)
100 
101 #define VIDEO_END_PULSE MS_TIMER_TICKS_MS(300)
102 
103 #define NO_OF_VIDEO_EXTN_ALLOWED 3
104 
105 #define VIDEO_PIR_ON 2000
106 
110 typedef enum
111 {
113  MODE_SINGLE_SHOT,
115  MODE_MULTISHOT,
117  MODE_BULB,
119  MODE_VIDEO,
121  MODE_FOCUS,
123  MODE_NONE,
124 }
125 operational_mode_t;
126 
130 typedef enum
131 {
132  PIR_IDLE,
133  TIMER_IDLE,
134  VIDEO_IDLE,
135  MAX_STATES,
136 }
137 cam_trig_state_t;
141 #define VIDEO_ETXN_CONFIG TIMER_IDLE
142 
146 static pir_sense_cfg config_pir;
148 static out_gen_config_t out_gen_config[MAX_STATES];
150 static uint32_t video_extn_ticks;
152 static bool pir_on_flag = false;
154 static uint32_t sense_count;
156 static bool sense_feedback = false;
158 static bool is_light_sense_on = false;
160 static const bool out_gen_end_all_on[OUT_GEN_MAX_NUM_OUT] = {1,1,1,1};
162 static const bool multishot_generic[OUT_GEN_MAX_NUM_OUT][OUT_GEN_MAX_TRANSITIONS] =
163  {
164  {0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},
165  {0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},
166  {0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},
167  {0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1}
168  };
169 
170 /*PIR related functions*/
175 void pir_set_state(bool state);
179 void pir_handler(int32_t adc_val);
184 void pir_handler_video(int32_t adc_val);
188 void out_gen_config_updater_pir(void);
189 
190 /*Timer related functions*/
195 void timer_set_state(bool state);
199 void timer_handler(void);
203 void out_gen_config_updater_timer(void);
204 
205 /*out_pattern_gen related functions*/
210 void out_gen_done_handler(uint32_t out_gen_state);
211 
212 /*Light Sense related functions*/
216 void light_sense_init(void);
221 void light_sense_set_state(bool state);
229 bool light_sense_light_check(oper_time_t oper_time);
230 
231 /*Module manager related function*/
232 //Module manager is part of program which will enable or disable the
233 //PIR or timer at start event, add_ticks event and stop event
239 void module_manager_start_check(void);
243 void module_manager_disable_all(void);
244 
254 void out_gen_config_single_shot(cam_trig_state_t data_process_mode);
261 void out_gen_config_multi_shot(cam_trig_state_t data_process_mode,
262  uint32_t burst_duration, uint32_t burst_num);
268 void out_gen_config_bulb_expo(cam_trig_state_t data_process_mode, uint32_t bulb_time);
273 void out_gen_config_focus_only(cam_trig_state_t data_process_mode);
278 void out_gen_config_none(cam_trig_state_t data_process_mode);
279 //Suggest some good name for this function.
285 void out_gen_config_part_video_end();
290 void out_gen_config_part_video_extn(uint32_t extn_len);
296 void out_gen_config_part_video_start(uint32_t video_len);
302 void out_gen_config_full_video(cam_trig_state_t data_process_mode, uint32_t video_len);
303 
304 //function definitions
310 void debug_print_bool_array(bool (* next)[OUT_GEN_MAX_TRANSITIONS], char * str)
311 {
312 #if DEBUG_PRINT
313  log_printf("%s\n", str);
314  for(uint32_t row = 0; row< NUM_PIN_OUT; row++)
315  {
316  for(uint32_t arr_p = 0; arr_p<OUT_GEN_MAX_TRANSITIONS; arr_p++)
317  {
318  log_printf("%x ", next[row][arr_p]);
319  }
320  log_printf("\n");
321  }
322  log_printf("\n");
323 #endif
324 }
325 
326 void pir_set_state(bool state)
327 {
328  log_printf("%s %x\n",__func__, state);
329  if(state == true)
330  {
331  pir_sense_start(&config_pir);
332  }
333  else
334  {
335  pir_sense_stop();
336  }
337 }
338 
339 void pir_handler(int32_t adc_val)
340 {
341  log_printf("%s", __func__);
342  log_printf(" %d\n", adc_val);
343  pir_set_state(false);
344  if(out_gen_is_on() == false)
345  {
346  if(sense_feedback == true)
347  {
348  led_ui_single_start(LED_SEQ_PIR_PULSE, LED_UI_HIGH_PRIORITY, true);
349  }
350  out_gen_start(&out_gen_config[PIR_IDLE]);
351  }
352 }
353 
354 void pir_handler_video(int32_t adc_val)
355 {
356  log_printf("%s", __func__);
357  log_printf(" %d\n", adc_val);
358  pir_set_state(false);
359  static uint32_t no_of_extn_remain;
360  if(out_gen_is_on() == false)
361  {
362  if(sense_feedback == true)
363  {
364  led_ui_single_start(LED_SEQ_PIR_PULSE, LED_UI_HIGH_PRIORITY, true);
365  }
366  no_of_extn_remain = NO_OF_VIDEO_EXTN_ALLOWED;
367  out_gen_start(&out_gen_config[PIR_IDLE]);
368  }
369  else if(no_of_extn_remain > 0)
370  {
371  uint32_t ticks_done = out_gen_get_ticks ();
372  if(ticks_done < video_extn_ticks)
373  {
374  out_gen_config[VIDEO_ETXN_CONFIG].transitions_durations[0] =
375  (video_extn_ticks - ticks_done);
376  }
377  else
378  {
379  out_gen_config[VIDEO_ETXN_CONFIG].transitions_durations[0] =
380  video_extn_ticks;
381  }
382  out_gen_start(&out_gen_config[VIDEO_ETXN_CONFIG]);
383  no_of_extn_remain--;
384  }
385 }
386 
387 void out_gen_config_updater_pir()
388 {
389  uint32_t config_mode = config.config_sensepi->pir_conf.mode;
390  uint32_t mode = ((config_mode & MODE_MSK)
391  >> (MODE_POS * SIZE_OF_BYTE));
392  uint32_t input1 = ((config_mode & INPUT1_MSK)
393  >> (INPUT1_POS * SIZE_OF_BYTE));
394  uint32_t input2 = ((config_mode & INPUT2_MSK)
395  >> (INPUT2_POS * SIZE_OF_BYTE));
396  uint32_t single_input = config_mode>> (INPUT1_POS * SIZE_OF_BYTE);
397  switch((operational_mode_t)mode)
398  {
399  case MODE_SINGLE_SHOT:
400  {
401  out_gen_config_single_shot(PIR_IDLE);
402  break;
403  }
404  case MODE_MULTISHOT:
405  {
406  out_gen_config_multi_shot(PIR_IDLE, input1, input2);
407  break;
408  }
409  case MODE_BULB :
410  {
411  //Using both input 1 and input 2
412  out_gen_config_bulb_expo(PIR_IDLE, single_input);
413  break;
414  }
415  case MODE_VIDEO :
416  {
417  if(input2 == 0)
418  {
419  out_gen_config_full_video (PIR_IDLE, input1);
420  }
421  else
422  {
423  out_gen_config_part_video_start(input1);
424  out_gen_config_part_video_extn(input2);
425  out_gen_config_part_video_end(input2);
426  }
427  break;
428  }
429  case MODE_FOCUS :
430  {
431  out_gen_config_focus_only(PIR_IDLE);
432  break;
433  }
434  case MODE_NONE:
435  {
436  out_gen_config_none(PIR_IDLE);
437  }
438  }
439 }
440 
441 void timer_set_state(bool state)
442 {
443  if(state == true)
444  {
445  if(ms_timer_get_on_status (SENSEPI_CAM_TRIGGER_MS_TIMER_USED) == false)
446  {
447  ms_timer_start(SENSEPI_CAM_TRIGGER_MS_TIMER_USED, MS_REPEATED_CALL,
448  MS_TIMER_TICKS_MS(config.config_sensepi->timer_conf.timer_interval * 100),
449  timer_handler);
450  }
451  }
452  else
453  {
454  ms_timer_stop(SENSEPI_CAM_TRIGGER_MS_TIMER_USED);
455  }
456 }
457 
458 void timer_handler()
459 {
460  if(out_gen_is_on () == false)
461  {
462  out_gen_start(&out_gen_config[TIMER_IDLE]);
463  }
464 }
465 
466 void out_gen_config_updater_timer(void)
467 {
468  uint32_t config_mode = config.config_sensepi->timer_conf.mode;
469  uint32_t mode = ((config_mode & MODE_MSK)
470  >> (MODE_POS * SIZE_OF_BYTE));
471  uint32_t input1 = ((config_mode & INPUT1_MSK)
472  >> (INPUT1_POS * SIZE_OF_BYTE));
473  uint32_t input2 = ((config_mode & INPUT2_MSK)
474  >> (INPUT2_POS * SIZE_OF_BYTE));
475  uint32_t single_input = config_mode>> (INPUT1_POS * SIZE_OF_BYTE);
476  switch((operational_mode_t)mode)
477  {
478  case MODE_SINGLE_SHOT:
479  {
480  out_gen_config_single_shot(TIMER_IDLE);
481  break;
482  }
483  case MODE_MULTISHOT:
484  {
485  out_gen_config_multi_shot(TIMER_IDLE, input1, input2);
486  break;
487  }
488  case MODE_BULB :
489  {
490  //Using both input 1 and input 2
491  out_gen_config_bulb_expo(TIMER_IDLE, single_input);
492  break;
493  }
494  case MODE_VIDEO :
495  {
496  out_gen_config_full_video(TIMER_IDLE,input1);
497  break;
498  }
499  case MODE_FOCUS :
500  {
501  out_gen_config_focus_only(TIMER_IDLE);
502  break;
503  }
504  case MODE_NONE:
505  {
506  out_gen_config_none(PIR_IDLE);
507  }
508  }
509 }
510 
511 void out_gen_done_handler (uint32_t out_gen_state)
512 {
513  log_printf("%s",__func__);
514  log_printf(" %d\n", out_gen_state);
515  switch((cam_trig_state_t)out_gen_state)
516  {
517  case PIR_IDLE :
518  {
519  pir_set_state(pir_on_flag);
520  break;
521  }
522  case TIMER_IDLE :
523  {
524  if(config.config_sensepi->trig_conf == PIR_AND_TIMER)
525  {
526  pir_set_state(pir_on_flag);
527  }
528  break;
529  }
530  case VIDEO_IDLE :
531  {
532  out_gen_start(&out_gen_config[VIDEO_IDLE]);
533  pir_set_state(pir_on_flag);
534  break;
535  }
536  case MAX_STATES :
537  {
538  log_printf("Something went seriously wrong..!!\n");
539  break;
540  }
541  }
542 }
543 
544 void light_sense_init(void)
545 {
546  log_printf("%s\n",__func__);
549  config.led_sense_off_val);
550 }
551 
552 void light_sense_set_state(bool state)
553 {
554  if(state == true)
555  {
556  led_sense_cfg_input(true);
557  //To make sure that the green LED is ready to sense light
558  hal_nop_delay_ms(LED_WAIT_TIME_MS);
559  }
560  else
561  {
562  led_sense_cfg_input(false);
563  }
564 }
565 
566 bool light_sense_light_check(oper_time_t oper_time)
567 {
568  log_printf("%d\n", __func__);
569 
570  uint8_t light_sense_config = oper_time.day_or_night;
571  uint32_t light_threshold =
572  (uint32_t)((oper_time.threshold) * LIGHT_THRESHOLD_MULTIPLY_FACTOR);
573 
574  uint32_t light_intensity = led_sense_get();
575  log_printf("Light Intensity : %d\n", light_intensity);
576 
577  static bool light_check_flag = 0;
578  //Day and its brighter than the threshold
579  if(((light_sense_config == 1) && (light_intensity >= light_threshold))
580  || //Night and its dimmer than the threshold
581  ((light_sense_config == 0) && (light_intensity <= light_threshold)))
582  {
583  light_check_flag = 1;
584  }
585  else
586  {
587  light_check_flag = 0;
588  }
589  return light_check_flag;
590 }
591 
592 void module_manager_start_check(void)
593 {
594  log_printf("%s\n", __func__);
595  //Switch off PIR module so that light sensing can happen
596  pir_set_state(false);
597  bool light_flag;
598  switch(config.config_sensepi->trig_conf)
599  {
600  case PIR_ONLY :
601  {
602  light_flag = light_sense_light_check(config.config_sensepi->pir_conf.oper_time);
603  pir_on_flag = light_flag;
604  pir_set_state(light_flag);
605 
606  break;
607  }
608  case TIMER_ONLY :
609  {
610  light_flag = light_sense_light_check(config.config_sensepi->timer_conf.oper_time);
611  timer_set_state(light_flag);
612 
613  break;
614  }
615  case PIR_AND_TIMER :
616  {
617  light_flag = light_sense_light_check(config.config_sensepi->pir_conf.oper_time);
618  pir_on_flag = light_flag;
619 
620  light_flag = light_sense_light_check(config.config_sensepi->timer_conf.oper_time);
621  timer_set_state(light_flag);
622  pir_set_state(pir_on_flag);
623 
624  break;
625  }
626  }
627 
628 }
629 
630 void module_manager_disable_all(void)
631 {
632  pir_set_state(false);
633  timer_set_state(false);
634  light_sense_set_state(false);
635 }
636 
637 void out_gen_config_single_shot(cam_trig_state_t data_process_mode)
638 {
639  log_printf("%s\n", __func__);
640  uint32_t number_of_transition = SINGLE_SHOT_TRANSITIONS;
641  int32_t time_remain;
642 
643  if(data_process_mode == PIR_IDLE)
644  {
645  time_remain = MS_TIMER_TICKS_MS(config.config_sensepi->pir_conf.intr_trig_timer * 100)
646  - (SINGLE_SHOT_DURATION);
647  if((int32_t)time_remain <= 0)
648  {
649  time_remain = 0;
650  }
651  }
652  else if(data_process_mode == TIMER_IDLE)
653  {
654  time_remain = 0;
655  }
656 
657  out_gen_config_t local_out_gen_config =
658  {
659  .num_transitions = number_of_transition,
660  .done_handler = out_gen_done_handler,
661  .out_gen_state = data_process_mode,
662  .transitions_durations = { SINGLE_SHOT_DURATION, time_remain },
663  .next_out = {{0, 1, 1},
664  {0, 1, 1}},
665  };
666 
667  debug_print_bool_array(local_out_gen_config.next_out, "single shot");
668  memcpy(&out_gen_config[data_process_mode],&local_out_gen_config,
669  sizeof(out_gen_config_t));
670 }
671 
672 void out_gen_config_multi_shot(cam_trig_state_t data_process_mode,
673  uint32_t burst_duration, uint32_t burst_num)
674 {
675  log_printf("%s\n", __func__);
676  int32_t time_remain;
677  uint32_t number_of_transition = SINGLE_SHOT_TRANSITIONS * burst_num;
678  //Time for trigger pulse and time till next trigger for each burst
679  uint32_t repeat_delay_array[SINGLE_SHOT_TRANSITIONS] = {SINGLE_SHOT_DURATION,
680  MS_TIMER_TICKS_MS(burst_duration * 100) - SINGLE_SHOT_DURATION};
681  out_gen_config_t local_out_gen_config =
682  {
683  .num_transitions = number_of_transition,
684  .done_handler = out_gen_done_handler,
685  .out_gen_state = data_process_mode,
686  };
687 
688  for(uint32_t i = 0; i< burst_num; i++)
689  {
690  memcpy(local_out_gen_config.transitions_durations + i*SINGLE_SHOT_TRANSITIONS,
691  repeat_delay_array, SINGLE_SHOT_TRANSITIONS*sizeof(uint32_t));
692 
693  for(uint32_t j = 0; j < NUM_PIN_OUT; j++)
694  {
695  memcpy(*(local_out_gen_config.next_out +j),*(multishot_generic + j),
696  burst_num* SINGLE_SHOT_TRANSITIONS*sizeof(bool));
697  //An extra '1' at the end for the remaining of the inter-trigger time
698  local_out_gen_config.next_out[j][burst_num* SINGLE_SHOT_TRANSITIONS] = 1;
699  }
700  }
701 
702  if(data_process_mode == PIR_IDLE)
703  {
704  time_remain = MS_TIMER_TICKS_MS(config.config_sensepi->pir_conf.intr_trig_timer * 100)
705  - SINGLE_SHOT_DURATION*burst_num -
706  (MS_TIMER_TICKS_MS(burst_duration * 100) - SINGLE_SHOT_DURATION)*(burst_num - 1);
707  if((int32_t)time_remain <= 0)
708  {
709  time_remain = 1;
710  }
711  }
712  else if(data_process_mode == TIMER_IDLE)
713  {
714  time_remain = 1;
715  }
716  // Last interval for the '1' signal till 'time till next trigger' elapses
717  local_out_gen_config.transitions_durations[number_of_transition-1] = time_remain;
718 
719 
720  debug_print_bool_array(local_out_gen_config.next_out, "multi shot");
721  memcpy(&out_gen_config[data_process_mode], &local_out_gen_config,
722  sizeof(out_gen_config_t));
723 }
724 
725 void out_gen_config_bulb_expo(cam_trig_state_t data_process_mode, uint32_t bulb_time)
726 {
727  log_printf("%s\n", __func__);
728  int32_t time_remain;
729  uint32_t number_of_transition = BULB_SHOT_TRANSITIONS;
730  uint32_t bulb_time_ticks = MS_TIMER_TICKS_MS((bulb_time*100));
731 
732  if(data_process_mode == PIR_IDLE)
733  {
734  time_remain = MS_TIMER_TICKS_MS(config.config_sensepi->pir_conf.intr_trig_timer * 100)
735  - bulb_time_ticks ;
736  if((int32_t)time_remain <= 0)
737  {
738  time_remain = 1;
739  }
740  }
741  else if(data_process_mode == TIMER_IDLE)
742  {
743  time_remain = 0;
744  }
745 
746  out_gen_config_t local_out_gen_config =
747  {
748  .num_transitions = number_of_transition,
749  .done_handler = out_gen_done_handler,
750  .out_gen_state = data_process_mode,
751  .transitions_durations =
752  {bulb_time_ticks, time_remain},
753  .next_out = { {0, 1, 1},
754  {0, 1, 1} },
755  };
756 
757  debug_print_bool_array(local_out_gen_config.next_out, "bulb mode");
758  memcpy(&out_gen_config[data_process_mode],&local_out_gen_config,
759  sizeof(out_gen_config_t));
760 }
761 
762 void out_gen_config_full_video(cam_trig_state_t data_process_mode, uint32_t video_len)
763 {
764  int32_t time_remain;
765  video_len = video_len*1000;
766  if(data_process_mode == TIMER_IDLE)
767  {
768  time_remain = config.config_sensepi->timer_conf.timer_interval*100 -
769  video_len - VIDEO_START_PULSE -VIDEO_END_PULSE;
770  }
771  video_len = (time_remain < 0) ?
772  (config.config_sensepi->timer_conf.timer_interval*100 - 1000) :
773  video_len;
774  out_gen_config_t local_out_gen_config =
775  {
776  .num_transitions = TIMER_VIDEO_TRANSITIONS,
777  .next_out = {{0,1,0,1},
778  {1,1,1,1}},
779  .transitions_durations = {VIDEO_START_PULSE,
780  MS_TIMER_TICKS_MS(video_len),
781  VIDEO_END_PULSE},
782  .done_handler = out_gen_done_handler,
783  .out_gen_state = data_process_mode,
784 
785  };
786  debug_print_bool_array(local_out_gen_config.next_out, "Timer video mode");
787  memcpy(&out_gen_config[data_process_mode],&local_out_gen_config,
788  sizeof(out_gen_config_t));
789 
790 
791 }
792 
793 void out_gen_config_part_video_start(uint32_t video_len)
794 {
795  config_pir.handler = pir_handler_video;
796  video_len = video_len * 1000;
797  int video_len_check = video_len - VIDEO_PIR_ON;
798  video_len = (video_len_check <= 0) ? 0 : video_len_check;
799  out_gen_config_t local_out_gen_config =
800  {
801  .num_transitions = SINGLE_SHOT_TRANSITIONS,
802  .next_out = {{0,1,1}
803  ,{1,1,1}},
804  .transitions_durations = {VIDEO_START_PULSE,
805  (MS_TIMER_TICKS_MS(video_len))},
806  .done_handler = out_gen_done_handler,
807  .out_gen_state = VIDEO_IDLE,
808  };
809  debug_print_bool_array(local_out_gen_config.next_out, "PIR video mode");
810  memcpy(&out_gen_config[PIR_IDLE],&local_out_gen_config,
811  sizeof(out_gen_config_t));
812 }
813 
814 void out_gen_config_part_video_extn (uint32_t extn_len)
815 {
816  video_extn_ticks = MS_TIMER_TICKS_MS(extn_len * 1000);
817  out_gen_config_t local_out_gen_config =
818  {
819  .num_transitions = 1,
820  .next_out = {{1,1}, {1,1}},
821  .transitions_durations = {video_extn_ticks},
822  .done_handler = out_gen_done_handler,
823  .out_gen_state = VIDEO_IDLE,
824  };
825  debug_print_bool_array(local_out_gen_config.next_out, "PIR video extension");
826  memcpy(&out_gen_config[VIDEO_ETXN_CONFIG],&local_out_gen_config,
827  sizeof(out_gen_config_t));
828 
829 }
830 
831 void out_gen_config_part_video_end()
832 {
833  out_gen_config_t local_out_gen_config =
834  {
835  .num_transitions = SINGLE_SHOT_TRANSITIONS,
836  .next_out = {{1,0,1},
837  {1,1,1}},
838  .transitions_durations = {MS_TIMER_TICKS_MS(VIDEO_PIR_ON), VIDEO_END_PULSE,},
839  .done_handler = out_gen_done_handler,
840  .out_gen_state = PIR_IDLE,
841  };
842  debug_print_bool_array(local_out_gen_config.next_out, "PIR video mode");
843  memcpy(&out_gen_config[VIDEO_IDLE],&local_out_gen_config,
844  sizeof(out_gen_config_t));
845 }
846 
847 void out_gen_config_focus_only(cam_trig_state_t data_process_mode)
848 {
849  log_printf("%s\n", __func__);
850  int32_t time_remain;
851  uint32_t number_of_transition = FOCUS_TRANSITIONS;
852 
853  if(data_process_mode == PIR_IDLE)
854  {
855  time_remain = MS_TIMER_TICKS_MS(config.config_sensepi->pir_conf.intr_trig_timer * 100)
856  - SINGLE_SHOT_DURATION ;
857  if((int32_t)time_remain <= 0)
858  {
859  time_remain = 1;
860  }
861  }
862  else if(data_process_mode == TIMER_IDLE)
863  {
864  time_remain = 1;
865  }
866 
867  out_gen_config_t local_out_gen_config =
868  {
869  .num_transitions = number_of_transition,
870  .done_handler = out_gen_done_handler,
871  .out_gen_state = data_process_mode,
872  .transitions_durations =
873  {SINGLE_SHOT_DURATION ,time_remain},
874  .next_out = { {0, 1, 1},
875  {1, 1, 1} },
876  };
877 
878  debug_print_bool_array(local_out_gen_config.next_out, "focus mode");
879  memcpy(&out_gen_config[data_process_mode],&local_out_gen_config,
880  sizeof(out_gen_config_t));
881 }
882 
883 void out_gen_config_none(cam_trig_state_t data_process_mode)
884 {
885  out_gen_config_t local_out_gen_config =
886  {
887  .num_transitions = 1,
888  .done_handler = out_gen_done_handler,
889  .out_gen_state = data_process_mode,
890  .transitions_durations = {1},
891  .next_out = { {1},
892  {1} },
893  };
894 
895  memcpy(&out_gen_config[data_process_mode],&local_out_gen_config,
896  sizeof(out_gen_config_t));
897 }
898 
900 {
901  log_printf("%s\n", __func__);
902  ASSERT(config_sensepi_cam_trigger->signal_pin_num == NUM_PIN_OUT);
903  memcpy(&config, config_sensepi_cam_trigger, sizeof(config));
904  light_sense_init();
905  mcp4012_init(config.amp_cs_pin, config.amp_ud_pin, config.amp_spi_sck_pin);
906  pir_sense_cfg local_config_pir =
907  {
909  config.pir_sense_offset_input,
910  ((uint32_t)config.config_sensepi->pir_conf.threshold)*PIR_THRESHOLD_MULTIPLY_FACTOR,
911  APP_IRQ_PRIORITY_HIGH, pir_handler,
912  };
913  memcpy(&config_pir, &local_config_pir, sizeof(pir_sense_cfg));
914  out_gen_init(NUM_PIN_OUT, config.signal_out_pin_array,
915  (bool *) out_gen_end_all_on);
916 }
917 
918 void sensepi_cam_trigger_update(sensepi_config_t * update_config)
919 {
920  log_printf("%s\n", __func__);
921  memcpy(config.config_sensepi, update_config, sizeof(sensepi_config_t));
922 }
923 
925 {
926  log_printf("%s\n", __func__);
927 
928  if(memcmp (config.config_sensepi, sensepi_store_config_get_last_config(),
929  sizeof(sensepi_config_t)) != 0)
930  {
931  sensepi_store_config_write (config.config_sensepi);
932  }
933  sense_count = 0;
934  sense_feedback = true;
935  oper_time_t pir_oper_time = config.config_sensepi->pir_conf.oper_time;
936  oper_time_t timer_oper_time = config.config_sensepi->timer_conf.oper_time;
937  bool pir_light_flag = true;
938  bool timer_light_flag = true;
939  if(config.config_sensepi->trig_conf != PIR_ONLY)
940  {
941  if((timer_oper_time.day_or_night == 1 && timer_oper_time.threshold == 0b0000000)||
942  (timer_oper_time.day_or_night == 0 && timer_oper_time.threshold == 0b1111111))
943  {
944  timer_light_flag = false;
945  }
946  else
947  {
948  timer_light_flag = true;
949  }
950  }
951  else
952  {
953  timer_light_flag = false;
954  }
955  if(config.config_sensepi->trig_conf != TIMER_ONLY)
956  {
957  if((pir_oper_time.day_or_night == 1 && pir_oper_time.threshold == 0b0000000)||
958  (pir_oper_time.day_or_night == 0 && pir_oper_time.threshold == 0b1111111))
959  {
960  pir_light_flag = false;
961  }
962  else
963  {
964  pir_light_flag = true;
965  }
966  }
967  else
968  {
969  pir_light_flag = false;
970  }
971  is_light_sense_on = pir_light_flag || timer_light_flag;
972 
973  config_pir.threshold = ((uint32_t) config.config_sensepi->pir_conf.threshold)
974  *PIR_THRESHOLD_MULTIPLY_FACTOR;
975  config_pir.handler = pir_handler;
976 
977  mcp4012_set_value(config.config_sensepi->pir_conf.amplification);
978 
979  out_gen_config_updater_timer();
980  out_gen_config_updater_pir();
981 
982  light_sense_set_state(true);
983  module_manager_start_check();
984 }
985 
986 void sensepi_cam_trigger_add_tick(uint32_t interval)
987 {
988  static uint32_t light_sense_count = 0;
989 
990  log_printf("%s\n", __func__);
991  log_printf("SensePi Add ticks : %d\n", interval);
992 
993  sense_count += interval;
994  if(sense_count > SENSE_FEEDBACK_TIMEOUT_TICKS)
995  {
996  sense_feedback = false;
997  }
998 
999  light_sense_count += interval;
1000  if(light_sense_count > LIGHT_SENSE_INTERVAL_TICKS && sense_feedback == false
1001  && is_light_sense_on == true)
1002  {
1003  module_manager_start_check();
1004  light_sense_count = (light_sense_count - LIGHT_SENSE_INTERVAL_TICKS);
1005  }
1006 }
1007 
1009 {
1010  log_printf("%s\n",__func__);
1011  module_manager_disable_all();
1012  out_gen_stop((bool *) out_gen_end_all_on);
1014 }
1015 
1017 {
1018  log_printf("%s\n", __func__);
1019  return (config.config_sensepi);
1020 }
uint32_t amp_ud_pin
Value at which LED is off.
void sensepi_cam_trigger_stop()
Function to stop PIR sensing.
void pir_sense_stop(void)
Disable the peripherals involved - SAADC, PPIs and RTC0.
Definition: pir_sense.c:125
void sensepi_cam_trigger_add_tick(uint32_t interval)
Function to decide what to decide at current tick.
uint32_t transitions_durations[OUT_GEN_MAX_TRANSITIONS]
1 dimensional array containing the durations in terms of LFCLK frequency ticks for the transitions.
uint32_t amp_spi_sck_pin
Pin number for CSbar pin for MCP4012.
uint32_t amp_cs_pin
Pin number for UDbar pin for MCP4012.
LED_UI_HIGH_PRIORITY.
Definition: led_ui.h:43
void led_ui_single_start(led_sequences seq, led_ui_priority_t priority, bool reset)
Start a sequence to play once.
Definition: led_ui.c:236
uint32_t num_transitions
The number of transitions in this pattern.
bool next_out[OUT_GEN_MAX_NUM_OUT][OUT_GEN_MAX_TRANSITIONS]
A 2 dimensional boolean array containing the next digital output value for the various transitions ac...
uint32_t pir_sense_offset_input
Pin number for PIR signal output.
uint32_t led_sense_out_pin
Pin number for PIR offset output.
Repeated call of the timer.
Definition: ms_timer.h:83
void led_sense_init(uint32_t led_out_pin, uint32_t led_sense_analog_pin, uint32_t led_off_val)
Initialize the LED light sensing module.
Definition: led_sense.c:27
void sensepi_cam_trigger_init(sensepi_cam_trigger_init_config_t *config_sensepi_cam_trigger)
Function to initiate SensePi_PIR module.
Trigger only on motion detection.
Definition: sensepi_ble.h:51
sensepi_config_t * sensepi_store_config_get_last_config()
#define MS_TIMER_TICKS_MS(ms)
Definition: ms_timer.h:64
void out_gen_init(uint32_t num_out, uint32_t *out_pins, bool *out_init_value)
Initialize the output pattern generator module with the information of the pins on which the pattern ...
void out_gen_stop(bool *out_vals)
Stop the output pattern generation and sets the output pins as specified in the arguments.
bool ms_timer_get_on_status(ms_timer_num id)
Definition: ms_timer.c:186
#define ASSERT(expression)
Macro for runtime assertion of an expression. If the expression is false the assert_nrf_callback func...
Definition: nrf_assert.h:48
bool out_gen_is_on(void)
To know if the output pattern generator module is on.
void pir_sense_start(pir_sense_cfg *init)
Definition: pir_sense.c:57
sensepi_config_t * sensepi_cam_trigger_get_sensepi_config()
Function to get the current configuration to send it to mobile app.
void(* handler)(int32_t adc_val)
The interrupt priority for calling the handler.
Definition: pir_sense.h:103
void led_ui_type_stop_all(led_ui_seq_t type)
Stop all sequence of a particular type.
Definition: led_ui.c:275
#define PIR_SENSE_INTERVAL_MS
Definition: main.c:102
void sensepi_cam_trigger_update(sensepi_config_t *update_config)
Function to update the configuration at every instance when it is changed in the program.
Run a sequence repeatedly.
Definition: led_ui.h:50
uint32_t led_sense_off_val
Pin number for light sensing.
uint32_t pir_sense_signal_input
Configuration received from mobile app.
void mcp4012_init(uint32_t CS_bar_pin_no, uint32_t UD_bar_pin_no, uint32_t SCK_pin_no)
This function is used to initialize MCP4012 in our program. This will set wiper value of MCP4012 to z...
Definition: mcp4012_x.c:69
void led_sense_cfg_input(bool is_input_on)
Configure the LED as either an light sensing input device or as an light emitting actuation device.
Definition: led_sense.c:38
#define OUT_GEN_MAX_TRANSITIONS
uint32_t threshold
The analog input number of PIR offset.
Definition: pir_sense.h:100
Trigger only on timer.
Definition: sensepi_ble.h:50
void sensepi_store_config_write(sensepi_config_t *latest_config)
Function to write the sensepi_config_t at address location received from get_next_location().
void mcp4012_set_value(uint32_t value_sent_by_user)
This function is used to set the value of MCP4012 wiper value.
Definition: mcp4012_x.c:79
void ms_timer_start(ms_timer_num id, ms_timer_mode mode, uint64_t ticks, void(*handler)(void))
Definition: ms_timer.c:134
Configuration structure for output pattern generation.
uint32_t led_sense_analog_in_pin
Pin number for LED driving pin.
#define OUT_GEN_MAX_NUM_OUT
void out_gen_start(out_gen_config_t *out_gen_config)
Start the generation of the pattern with the information provided.
uint32_t out_gen_get_ticks(void)
Function to get ticks since last call of out_gen_start.
Strcture to configure SensePi_PIR module.
Stucture for passing the configuration for initializing the PIR Sense module.
Definition: pir_sense.h:96
uint32_t led_sense_get(void)
Get the light value by measuring the voltage a LED's anode.
Definition: led_sense.c:55
void ms_timer_stop(ms_timer_num id)
Definition: ms_timer.c:173
void sensepi_cam_trigger_start()
Function to start PIR sensing.