Appiko
tssp_detect.c
1 
19 #include "tssp_detect.h"
20 #include "hal_gpio.h"
21 #include "common_util.h"
22 #include "hal_clocks.h"
23 #include "nrf_util.h"
24 #include "stddef.h"
25 #include "log.h"
26 
27 #if ISR_MANAGER == 1
28 #include "isr_manager.h"
29 #endif
30 
32 #define TSSP_DETECT_RTC_USED CONCAT_2(NRF_RTC, RTC_USED_TSSP_DETECT)
33 
35 #define TSSP_DETECT_EGU_USED CONCAT_2(NRF_EGU,EGU_USED_TSSP_DETECT)
36 
38 #define PPI_CHANNEL_USED_RTC PPI_CH_USED_TSSP_DETECT_1
39 
41 #define PPI_CHANNEL_USED_EGU PPI_CH_USED_TSSP_DETECT_2
42 
44 #define GPIOTE_CHANNEL_USED GPIOTE_CH_USED_TSSP_DETECT
45 
47 #define WINDOW_RTC_CHANNEL 2
48 
49 #define SYNC_ON_RTC_CHANNEL 0
50 
51 #define SYNC_OFF_RTC_CHANNEL 1
52 
53 #define EGU_CHANNEL_USED EGU_CHANNEL_USED_TSSP_DETECT
54 
55 #define HALF_TSSP_ENABLE_DURATION TSSP_DETECT_TICKS_MS(2)
56 
57 
58 #ifndef ENABLE
59 #define ENABLE 1
60 #endif
61 
62 #ifndef DISABLE
63 #define DISABLE 0
64 #endif
65 
67 uint32_t tssp_en_pin;
69 uint32_t tssp_rx_pin;
70 
71 uint32_t tssp_sync_ms;
72 
74 static bool is_pulse_detect_req = false;
75 
77 static bool is_window_detect_req = false;
78 
81 void (*missed_handler)(void);
82 
84 void (*detect_handler)(uint32_t ticks);
85 
86 void tssp_detect_init (tssp_detect_config_t * tssp_detect_config)
87 {
88  tssp_en_pin = tssp_detect_config->rx_en_pin;
89  hal_gpio_cfg_output (tssp_en_pin, DISABLE);
90  tssp_rx_pin = tssp_detect_config->rx_in_pin;
91  hal_gpio_cfg_input (tssp_rx_pin,
93 
94  if(tssp_detect_config->tssp_missed_handler != NULL)
95  {
96  is_window_detect_req = true;
97  missed_handler = tssp_detect_config->tssp_missed_handler;
98  TSSP_DETECT_RTC_USED->PRESCALER = ROUNDED_DIV(LFCLK_FREQ, TSSP_DETECT_FREQ) - 1;
99  TSSP_DETECT_RTC_USED->CC[WINDOW_RTC_CHANNEL] = TSSP_DETECT_TICKS_MS(tssp_detect_config->window_duration_ticks);
100  TSSP_DETECT_RTC_USED->INTENSET |= ENABLE << (WINDOW_RTC_CHANNEL+16);
101 
102  NRF_PPI->CH[PPI_CHANNEL_USED_RTC].EEP = (uint32_t) &NRF_GPIOTE->EVENTS_IN[GPIOTE_CHANNEL_USED];
103  NRF_PPI->CH[PPI_CHANNEL_USED_RTC].TEP = (uint32_t) &TSSP_DETECT_RTC_USED->TASKS_CLEAR;
104 
105  }
106  else
107  {
108  is_window_detect_req = false;
109  }
110  if(tssp_detect_config->tssp_detect_handler != NULL)
111  {
112  is_pulse_detect_req = true;
113 
114  detect_handler = tssp_detect_config->tssp_detect_handler;
115 
116  TSSP_DETECT_EGU_USED->INTENSET |= ENABLE << EGU_CHANNEL_USED;
117  NVIC_SetPriority (SWI0_EGU0_IRQn, APP_IRQ_PRIORITY_HIGHEST);
118  NVIC_EnableIRQ (SWI0_IRQn);
119  NVIC_ClearPendingIRQ (SWI0_IRQn);
120 
121  NRF_PPI->CH[PPI_CHANNEL_USED_EGU].EEP = (uint32_t) &NRF_GPIOTE->EVENTS_IN[GPIOTE_CHANNEL_USED];
122  NRF_PPI->CH[PPI_CHANNEL_USED_EGU].TEP = (uint32_t) &TSSP_DETECT_EGU_USED->TASKS_TRIGGER[EGU_CHANNEL_USED];
123  }
124  else
125  {
126  is_pulse_detect_req = false;
127  }
128 
129 }
130 
132 {
133 
134  is_window_detect_req = true;
135 
136 
137  TSSP_DETECT_RTC_USED->INTENSET |= ENABLE << (WINDOW_RTC_CHANNEL+16);
138  NRF_PPI->CHENSET |= 1 << PPI_CHANNEL_USED_RTC;
139 
140  NRF_GPIOTE->EVENTS_IN[GPIOTE_CHANNEL_USED] = 0;
141 
142  NRF_GPIOTE->CONFIG[GPIOTE_CHANNEL_USED] =
143  GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos|
144  GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos|
145  ((tssp_rx_pin << GPIOTE_CONFIG_PSEL_Pos)
146  & GPIOTE_CONFIG_PSEL_Msk);
147 
148  TSSP_DETECT_RTC_USED->EVENTS_COMPARE[WINDOW_RTC_CHANNEL] = 0;
149  (void) TSSP_DETECT_RTC_USED->EVENTS_COMPARE[WINDOW_RTC_CHANNEL];
150 
151  TSSP_DETECT_RTC_USED->TASKS_START = 1;
152  NVIC_SetPriority (RTC0_IRQn, APP_IRQ_PRIORITY_HIGHEST);
153  NVIC_EnableIRQ (RTC0_IRQn);
154 }
155 
157 {
158  is_pulse_detect_req = false;
159  if((is_pulse_detect_req == false) && (is_window_detect_req == false))
160  {
161  NRF_GPIOTE->CONFIG[GPIOTE_CHANNEL_USED] =
162  GPIOTE_CONFIG_MODE_Disabled << GPIOTE_CONFIG_MODE_Pos|
163  GPIOTE_CONFIG_POLARITY_None << GPIOTE_CONFIG_POLARITY_Pos|
164  ((tssp_rx_pin << GPIOTE_CONFIG_PSEL_Pos)
165  & GPIOTE_CONFIG_PSEL_Msk);
166 
167  hal_gpio_pin_write (tssp_en_pin, DISABLE);
168  }
169  NRF_PPI->CHENCLR |= 1 << PPI_CHANNEL_USED_EGU;
170 }
171 
173 {
174  is_window_detect_req = false;
175  if((is_pulse_detect_req == false) && (is_window_detect_req == false))
176  {
177  NRF_GPIOTE->CONFIG[GPIOTE_CHANNEL_USED] =
178  GPIOTE_CONFIG_MODE_Disabled << GPIOTE_CONFIG_MODE_Pos|
179  GPIOTE_CONFIG_POLARITY_None << GPIOTE_CONFIG_POLARITY_Pos|
180  ((tssp_rx_pin << GPIOTE_CONFIG_PSEL_Pos)
181  & GPIOTE_CONFIG_PSEL_Msk);
182 
183  hal_gpio_pin_write (tssp_en_pin, DISABLE);
184  }
185  TSSP_DETECT_RTC_USED->INTENCLR |= ENABLE << (WINDOW_RTC_CHANNEL+16) |
186  ENABLE << (SYNC_ON_RTC_CHANNEL+16) |
187  ENABLE << (SYNC_OFF_RTC_CHANNEL+16);
188  NRF_PPI->CHENCLR |= 1 << PPI_CHANNEL_USED_RTC;
189  NVIC_DisableIRQ (RTC0_IRQn);
190 
191  TSSP_DETECT_RTC_USED->TASKS_CLEAR = 1;
192  (void) TSSP_DETECT_RTC_USED->TASKS_CLEAR;
193  TSSP_DETECT_RTC_USED->TASKS_STOP = 1;
194 }
195 
197 {
198  is_pulse_detect_req = true;
199  TSSP_DETECT_RTC_USED->TASKS_START = 1;
200  NRF_GPIOTE->EVENTS_IN[GPIOTE_CHANNEL_USED] = 0;
201 
202  NRF_GPIOTE->CONFIG[GPIOTE_CHANNEL_USED] =
203  GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos|
204  GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos|
205  ((tssp_rx_pin << GPIOTE_CONFIG_PSEL_Pos)
206  & GPIOTE_CONFIG_PSEL_Msk);
207 
208  hal_gpio_pin_write (tssp_en_pin, ENABLE);
209 
210  TSSP_DETECT_EGU_USED->INTENSET |= ENABLE << EGU_CHANNEL_USED;
211  NRF_PPI->CHENSET |= 1 << PPI_CHANNEL_USED_EGU;
212 }
213 
214 void tssp_detect_window_sync (uint32_t sync_ms)
215 {
216  tssp_sync_ms = (sync_ms);
217 
218  uint32_t rtc_counter;
219  rtc_counter = TSSP_DETECT_RTC_USED->COUNTER ;
220  TSSP_DETECT_RTC_USED->CC[SYNC_ON_RTC_CHANNEL] =
221  (rtc_counter + (tssp_sync_ms - HALF_TSSP_ENABLE_DURATION)) ;
222  (void) TSSP_DETECT_RTC_USED->CC[SYNC_ON_RTC_CHANNEL];
223  TSSP_DETECT_RTC_USED->INTENSET |= ENABLE << (SYNC_ON_RTC_CHANNEL+16);
224  TSSP_DETECT_RTC_USED->EVENTS_COMPARE[SYNC_ON_RTC_CHANNEL] = 0;
225 
226  TSSP_DETECT_RTC_USED->CC[SYNC_OFF_RTC_CHANNEL] = HALF_TSSP_ENABLE_DURATION;
227  (void) TSSP_DETECT_RTC_USED->CC[SYNC_OFF_RTC_CHANNEL];
228  TSSP_DETECT_RTC_USED->INTENSET |= ENABLE << (SYNC_OFF_RTC_CHANNEL+16);
229  TSSP_DETECT_RTC_USED->EVENTS_COMPARE[SYNC_OFF_RTC_CHANNEL] = 0;
230 
231 }
232 
233 #if ISR_MANAGER == 1
234 void tssp_detect_swi_Handler (void)
235 #else
236 void SWI0_IRQHandler ()
237 #endif
238 {
239 #if ISR_MANAGER == 0
240  TSSP_DETECT_EGU_USED->EVENTS_TRIGGERED[EGU_CHANNEL_USED] = 0;
241  (void) TSSP_DETECT_EGU_USED->EVENTS_TRIGGERED[EGU_CHANNEL_USED];
242 #endif
243  NRF_PPI->CHENCLR |= 1 << PPI_CHANNEL_USED_EGU;
244  detect_handler ( TSSP_DETECT_RTC_USED->COUNTER );
245 }
246 
247 #if ISR_MANAGER == 1
248 void tssp_detect_rtc_Handler (void)
249 #else
250 void RTC0_IRQHandler (void)
251 #endif
252 {
253  if(TSSP_DETECT_RTC_USED->EVENTS_COMPARE[SYNC_ON_RTC_CHANNEL] == 1)
254  {
255 #if ISR_MANAGER == 0
256  TSSP_DETECT_RTC_USED->EVENTS_COMPARE[SYNC_ON_RTC_CHANNEL] = 0;
257  (void) TSSP_DETECT_RTC_USED->EVENTS_COMPARE[SYNC_ON_RTC_CHANNEL];
258 #endif
259  hal_gpio_pin_write (tssp_en_pin, ENABLE);
260  TSSP_DETECT_RTC_USED->CC[SYNC_OFF_RTC_CHANNEL] = HALF_TSSP_ENABLE_DURATION;
261 
262  }
263  if(TSSP_DETECT_RTC_USED->EVENTS_COMPARE[SYNC_OFF_RTC_CHANNEL] == 1)
264  {
265 #if ISR_MANAGER == 0
266  TSSP_DETECT_RTC_USED->EVENTS_COMPARE[SYNC_OFF_RTC_CHANNEL] = 0;
267  (void) TSSP_DETECT_RTC_USED->EVENTS_COMPARE[SYNC_OFF_RTC_CHANNEL];
268 #endif
269  hal_gpio_pin_write (tssp_en_pin, DISABLE);
270  TSSP_DETECT_RTC_USED->CC[SYNC_ON_RTC_CHANNEL] = (tssp_sync_ms - HALF_TSSP_ENABLE_DURATION);
271  }
272  if(TSSP_DETECT_RTC_USED->EVENTS_COMPARE[WINDOW_RTC_CHANNEL] == 1)
273  {
274 #if ISR_MANAGER == 0
275  TSSP_DETECT_RTC_USED->EVENTS_COMPARE[WINDOW_RTC_CHANNEL] = 0;
276  (void) TSSP_DETECT_RTC_USED->EVENTS_COMPARE[WINDOW_RTC_CHANNEL];
277 #endif
278  missed_handler ();
279  TSSP_DETECT_RTC_USED->TASKS_CLEAR = 1;
280  (void) TSSP_DETECT_RTC_USED->TASKS_CLEAR;
281  }
282 }
void tssp_detect_window_stop(void)
Function to stop IR missed window detection.
Definition: tssp_detect.c:172
void(* tssp_missed_handler)(void)
Definition: tssp_detect.h:92
void tssp_detect_pulse_detect()
Function to start module is pulse detecting mode.
Definition: tssp_detect.c:196
#define TSSP_DETECT_TICKS_MS(ms)
Definition: tssp_detect.h:70
#define GPIOTE_CHANNEL_USED
Preemption priority IRQ.
Definition: main.c:71
void(* tssp_detect_handler)(uint32_t ticks)
Definition: tssp_detect.h:95
void tssp_detect_init(tssp_detect_config_t *tssp_detect_config)
Function to initialize IR detect sub-module.
Definition: tssp_detect.c:86
void tssp_detect_window_sync(uint32_t sync_ms)
Function to Synchronize TSSP detector to IR transmitter which is being used.
Definition: tssp_detect.c:214
Structure to store information required to use this module.
Definition: tssp_detect.h:76
HAL_GPIO_PULL_UP.
Definition: hal_gpio.h:39
uint32_t window_duration_ticks
Definition: tssp_detect.h:88
#define LFCLK_FREQ
Frequency of the low frequency clock is 32.768 kHz.
Definition: hal_clocks.h:43
void tssp_detect_pulse_stop()
Function to stop IR pulse detection.
Definition: tssp_detect.c:156
#define ROUNDED_DIV(A, B)
Rounded integer division where the result is the integer closest to the answer instead of flooring th...
Definition: common_util.h:80
void tssp_detect_window_detect()
Function to start IR pulse detection.
Definition: tssp_detect.c:131