]>
Commit | Line | Data |
---|---|---|
1 | /*---------------------------------------------------------------------------------------------------------------------------------------------------\r | |
2 | * irmp-main-stm32.c - demo main module to test IRMP decoder on STM32\r | |
3 | *\r | |
4 | * Copyright (c) 2009-2016 Frank Meyer - frank(at)fli4l.de\r | |
5 | *\r | |
6 | * $Id: irmp-main-stm32.c,v 1.2 2016/01/12 21:15:16 fm Exp $\r | |
7 | *\r | |
8 | * This demo module is runnable on STM32\r | |
9 | *\r | |
10 | * This program is free software; you can redistribute it and/or modify\r | |
11 | * it under the terms of the GNU General Public License as published by\r | |
12 | * the Free Software Foundation; either version 2 of the License, or\r | |
13 | * (at your option) any later version.\r | |
14 | *---------------------------------------------------------------------------------------------------------------------------------------------------\r | |
15 | */\r | |
16 | \r | |
17 | #include "config.h"\r | |
18 | #include "timer.h"\r | |
19 | #include "serial.h"\r | |
20 | #include "irmp.h"\r | |
21 | #include <libopencm3/stm32/rcc.h>\r | |
22 | #include <libopencm3/stm32/gpio.h>\r | |
23 | #include <stdio.h>\r | |
24 | \r | |
25 | #ifndef USE_OPENCM3_API\r | |
26 | #define USE_OPENCM3_API 1\r | |
27 | #endif\r | |
28 | \r | |
29 | #ifndef DEBUG_IRMP_TIMER_INT\r | |
30 | #define DEBUG_IRMP_TIMER_INT 0\r | |
31 | #endif\r | |
32 | \r | |
33 | static void setup_clock_and_gpios(void)\r | |
34 | {\r | |
35 | /* Clock setup */\r | |
36 | /* Default clock is 8MHz HSI */\r | |
37 | //rcc_clock_setup_in_hse_8mhz_out_24mhz();\r | |
38 | rcc_clock_setup_in_hse_8mhz_out_72mhz();\r | |
39 | \r | |
40 | /* GPIO setup */\r | |
41 | /* Only the on board led is configured here */\r | |
42 | \r | |
43 | rcc_periph_clock_enable(RCC_LED_PORT);\r | |
44 | \r | |
45 | /* Set GPIO13 (in GPIO port C) to 'output push-pull'. */\r | |
46 | /* Manually: */\r | |
47 | // GPIOC_CRH = (GPIO_CNF_OUTPUT_PUSHPULL << (((12 - 8) * 4) + 2));\r | |
48 | // GPIOC_CRH |= (GPIO_MODE_OUTPUT_2_MHZ << ((12 - 8) * 4));\r | |
49 | /* Using API functions: */\r | |
50 | gpio_set(LED_PORT, LED_PIN); /* set output register high (led off) */\r | |
51 | gpio_set_mode(LED_PORT, GPIO_MODE_OUTPUT_2_MHZ,\r | |
52 | GPIO_CNF_OUTPUT_PUSHPULL, LED_PIN);\r | |
53 | }\r | |
54 | \r | |
55 | /*--------------------------------------------------------------------------*/\r | |
56 | /* IRMP */\r | |
57 | /*--------------------------------------------------------------------------*/\r | |
58 | \r | |
59 | #define TIM_IRMP_CR1 TIM_CR1(TIM_IRMP)\r | |
60 | #define TIM_IRMP_DIER TIM_DIER(TIM_IRMP)\r | |
61 | #define TIM_IRMP_SR TIM_SR(TIM_IRMP)\r | |
62 | #define TIM_IRMP_ARR TIM_ARR(TIM_IRMP)\r | |
63 | #define RCC_TIM_IRMP CONCAT(RCC_TIM, IRMP_TIMER)\r | |
64 | #define NVIC_TIM_IRMP_IRQ CONCAT(CONCAT(NVIC_TIM, IRMP_TIMER), _IRQ)\r | |
65 | #define IRMP_TIMER_ISR CONCAT(CONCAT(tim, IRMP_TIMER), _isr)\r | |
66 | \r | |
67 | \r | |
68 | uint32_t timer_internal_clock_get(uint32_t timer_peripheral)\r | |
69 | {\r | |
70 | uint32_t timer_frequency;\r | |
71 | uint32_t ppre;\r | |
72 | \r | |
73 | /* Get preripheral bus frequency and prescaler mask */\r | |
74 | if (timer_peripheral == TIM1 || timer_peripheral == TIM8) {\r | |
75 | /* Advanced timers TIM1 and TIM8 are on APB2 */\r | |
76 | ppre = RCC_CFGR_PPRE2;\r | |
77 | timer_frequency = rcc_apb2_frequency;\r | |
78 | } else {\r | |
79 | /* Other timers are on APB1 */\r | |
80 | ppre = RCC_CFGR_PPRE1;\r | |
81 | timer_frequency = rcc_apb1_frequency;\r | |
82 | }\r | |
83 | /* Timer clock is doubled, if the APB prescaler is greater than 1 */\r | |
84 | if ((RCC_CFGR & ppre) != 0)\r | |
85 | timer_frequency *= 2;\r | |
86 | \r | |
87 | return timer_frequency;\r | |
88 | }\r | |
89 | \r | |
90 | void irmp_timer_init (void)\r | |
91 | {\r | |
92 | #if DEBUG_IRMP_TIMER_INT\r | |
93 | /* Output pin for debugging */\r | |
94 | rcc_periph_clock_enable(RCC_GPIOA);\r | |
95 | gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,\r | |
96 | GPIO_CNF_OUTPUT_PUSHPULL, GPIO2);\r | |
97 | #endif\r | |
98 | /* Enable timer clock. */\r | |
99 | rcc_periph_clock_enable(RCC_TIM_IRMP);\r | |
100 | nvic_set_priority(NVIC_TIM_IRMP_IRQ, 4*16);\r | |
101 | nvic_enable_irq(NVIC_TIM_IRMP_IRQ);\r | |
102 | \r | |
103 | #if USE_OPENCM3_API /* Using API functions: */\r | |
104 | \r | |
105 | /* Timer global mode:\r | |
106 | * - No divider\r | |
107 | * - Alignment edge\r | |
108 | * - Direction up\r | |
109 | * (These are actually default values after reset, so this call\r | |
110 | * is strictly unnecessary, but demos the api for alternative settings)\r | |
111 | */\r | |
112 | timer_set_mode(TIM_IRMP, TIM_CR1_CKD_CK_INT,\r | |
113 | TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);\r | |
114 | timer_set_period(TIM_IRMP, timer_internal_clock_get(TIM_IRMP) / F_INTERRUPTS);\r | |
115 | /* Enable Channel 1 compare interrupt to recalculate compare values */\r | |
116 | timer_enable_irq(TIM_IRMP, TIM_DIER_UIE);\r | |
117 | /* Counter enable. */\r | |
118 | timer_enable_counter(TIM_IRMP);\r | |
119 | \r | |
120 | #else /* Manually */\r | |
121 | \r | |
122 | TIM_IRMP_CR1 = TIM_CR1_CKD_CK_INT | TIM_CR1_CMS_EDGE | TIM_CR1_DIR_UP;\r | |
123 | TIM_IRMP_ARR = timer_internal_clock_get(TIM_IRMP) / F_INTERRUPTS;\r | |
124 | \r | |
125 | /* Enable Timer interrupt and timer */\r | |
126 | TIM_IRMP_DIER = TIM_DIER_UIE;\r | |
127 | TIM_IRMP_CR1 |= TIM_CR1_CEN;\r | |
128 | \r | |
129 | #endif\r | |
130 | }\r | |
131 | \r | |
132 | void IRMP_TIMER_ISR(void)\r | |
133 | {\r | |
134 | #if DEBUG_IRMP_TIMER_INT\r | |
135 | # if USE_OPENCM3_API /* Using API functions: */\r | |
136 | \r | |
137 | gpio_clear(GPIOA, GPIO2);\r | |
138 | /* Clear update interrupt flag. */\r | |
139 | timer_clear_flag(TIM_IRMP, TIM_SR_UIF);\r | |
140 | # else /* Manually */\r | |
141 | GPIO_BRR(GPIOA) = GPIO2;\r | |
142 | # endif\r | |
143 | #endif\r | |
144 | /* Clear update interrupt flag. */\r | |
145 | TIM_IRMP_SR = ~TIM_SR_UIF;\r | |
146 | \r | |
147 | (void) irmp_ISR(); // call irmp ISR\r | |
148 | \r | |
149 | // call other timer interrupt routines...\r | |
150 | \r | |
151 | #if DEBUG_IRMP_TIMER_INT\r | |
152 | # if USE_OPENCM3_API /* Using API functions: */\r | |
153 | gpio_set(GPIOA, GPIO2);\r | |
154 | # else /* Manually */\r | |
155 | GPIO_BSRR(GPIOA) = GPIO2;\r | |
156 | # endif\r | |
157 | #endif\r | |
158 | }\r | |
159 | \r | |
160 | /*--------------------------------------------------------------------------*/\r | |
161 | \r | |
162 | int irmp_protocol_is_supported(int proto)\r | |
163 | {\r | |
164 | #if IRMP_SUPPORT_SIRCS_PROTOCOL\r | |
165 | if (proto == IRMP_SIRCS_PROTOCOL) return 1;\r | |
166 | #endif\r | |
167 | #if IRMP_SUPPORT_NEC_PROTOCOL\r | |
168 | if (proto == IRMP_NEC_PROTOCOL) return 1;\r | |
169 | #endif\r | |
170 | #if IRMP_SUPPORT_SAMSUNG_PROTOCOL\r | |
171 | if (proto == IRMP_SAMSUNG_PROTOCOL) return 1;\r | |
172 | #endif\r | |
173 | #if IRMP_SUPPORT_KASEIKYO_PROTOCOL\r | |
174 | if (proto == IRMP_KASEIKYO_PROTOCOL) return 1;\r | |
175 | #endif\r | |
176 | #if IRMP_SUPPORT_JVC_PROTOCOL\r | |
177 | if (proto == IRMP_JVC_PROTOCOL) return 1;\r | |
178 | #endif\r | |
179 | #if IRMP_SUPPORT_NEC16_PROTOCOL\r | |
180 | if (proto == IRMP_NEC16_PROTOCOL) return 1;\r | |
181 | #endif\r | |
182 | #if IRMP_SUPPORT_NEC42_PROTOCOL\r | |
183 | if (proto == IRMP_NEC42_PROTOCOL) return 1;\r | |
184 | #endif\r | |
185 | #if IRMP_SUPPORT_MATSUSHITA_PROTOCOL\r | |
186 | if (proto == IRMP_MATSUSHITA_PROTOCOL) return 1;\r | |
187 | #endif\r | |
188 | #if IRMP_SUPPORT_DENON_PROTOCOL\r | |
189 | if (proto == IRMP_DENON_PROTOCOL) return 1;\r | |
190 | #endif\r | |
191 | #if IRMP_SUPPORT_RC5_PROTOCOL\r | |
192 | if (proto == IRMP_RC5_PROTOCOL) return 1;\r | |
193 | #endif\r | |
194 | #if IRMP_SUPPORT_RC6_PROTOCOL\r | |
195 | if (proto == IRMP_RC6_PROTOCOL) return 1;\r | |
196 | #endif\r | |
197 | #if IRMP_SUPPORT_IR60_PROTOCOL\r | |
198 | if (proto == IRMP_IR60_PROTOCOL) return 1;\r | |
199 | #endif\r | |
200 | #if IRMP_SUPPORT_GRUNDIG_PROTOCOL\r | |
201 | if (proto == IRMP_GRUNDIG_PROTOCOL) return 1;\r | |
202 | #endif\r | |
203 | #if IRMP_SUPPORT_SIEMENS_PROTOCOL\r | |
204 | if (proto == IRMP_SIEMENS_PROTOCOL) return 1;\r | |
205 | #endif\r | |
206 | #if IRMP_SUPPORT_NOKIA_PROTOCOL\r | |
207 | if (proto == IRMP_NOKIA_PROTOCOL) return 1;\r | |
208 | #endif\r | |
209 | #if IRMP_SUPPORT_BOSE_PROTOCOL\r | |
210 | if (proto == IRMP_BOSE_PROTOCOL) return 1;\r | |
211 | #endif\r | |
212 | #if IRMP_SUPPORT_KATHREIN_PROTOCOL\r | |
213 | if (proto == IRMP_KATHREIN_PROTOCOL) return 1;\r | |
214 | #endif\r | |
215 | #if IRMP_SUPPORT_NUBERT_PROTOCOL\r | |
216 | if (proto == IRMP_NUBERT_PROTOCOL) return 1;\r | |
217 | #endif\r | |
218 | #if IRMP_SUPPORT_FAN_PROTOCOL\r | |
219 | if (proto == IRMP_FAN_PROTOCOL) return 1;\r | |
220 | #endif\r | |
221 | #if IRMP_SUPPORT_SPEAKER_PROTOCOL\r | |
222 | if (proto == IRMP_SPEAKER_PROTOCOL) return 1;\r | |
223 | #endif\r | |
224 | #if IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL\r | |
225 | if (proto == IRMP_BANG_OLUFSEN_PROTOCOL) return 1;\r | |
226 | #endif\r | |
227 | #if IRMP_SUPPORT_RECS80_PROTOCOL\r | |
228 | if (proto == IRMP_RECS80_PROTOCOL) return 1;\r | |
229 | #endif\r | |
230 | #if IRMP_SUPPORT_RECS80EXT_PROTOCOL\r | |
231 | if (proto == IRMP_RECS80EXT_PROTOCOL) return 1;\r | |
232 | #endif\r | |
233 | #if IRMP_SUPPORT_THOMSON_PROTOCOL\r | |
234 | if (proto == IRMP_THOMSON_PROTOCOL) return 1;\r | |
235 | #endif\r | |
236 | #if IRMP_SUPPORT_NIKON_PROTOCOL\r | |
237 | if (proto == IRMP_NIKON_PROTOCOL) return 1;\r | |
238 | #endif\r | |
239 | #if IRMP_SUPPORT_NETBOX_PROTOCOL\r | |
240 | if (proto == IRMP_NETBOX_PROTOCOL) return 1;\r | |
241 | #endif\r | |
242 | #if IRMP_SUPPORT_ORTEK_PROTOCOL\r | |
243 | if (proto == IRMP_ORTEK_PROTOCOL) return 1;\r | |
244 | #endif\r | |
245 | #if IRMP_SUPPORT_TELEFUNKEN_PROTOCOL\r | |
246 | if (proto == IRMP_TELEFUNKEN_PROTOCOL) return 1;\r | |
247 | #endif\r | |
248 | #if IRMP_SUPPORT_FDC_PROTOCOL\r | |
249 | if (proto == IRMP_FDC_PROTOCOL) return 1;\r | |
250 | #endif\r | |
251 | #if IRMP_SUPPORT_RCCAR_PROTOCOL\r | |
252 | if (proto == IRMP_RCCAR_PROTOCOL) return 1;\r | |
253 | #endif\r | |
254 | #if IRMP_SUPPORT_ROOMBA_PROTOCOL\r | |
255 | if (proto == IRMP_ROOMBA_PROTOCOL) return 1;\r | |
256 | #endif\r | |
257 | #if IRMP_SUPPORT_RUWIDO_PROTOCOL\r | |
258 | if (proto == IRMP_RUWIDO_PROTOCOL) return 1;\r | |
259 | #endif\r | |
260 | #if IRMP_SUPPORT_A1TVBOX_PROTOCOL\r | |
261 | if (proto == IRMP_A1TVBOX_PROTOCOL) return 1;\r | |
262 | #endif\r | |
263 | #if IRMP_SUPPORT_LEGO_PROTOCOL\r | |
264 | if (proto == IRMP_LEGO_PROTOCOL) return 1;\r | |
265 | #endif\r | |
266 | #if IRMP_SUPPORT_RCMM_PROTOCOL\r | |
267 | if (proto == IRMP_RCMM_PROTOCOL) return 1;\r | |
268 | #endif\r | |
269 | #if IRMP_SUPPORT_LGAIR_PROTOCOL\r | |
270 | if (proto == IRMP_LGAIR_PROTOCOL) return 1;\r | |
271 | #endif\r | |
272 | #if IRMP_SUPPORT_SAMSUNG48_PROTOCOL\r | |
273 | if (proto == IRMP_SAMSUNG48_PROTOCOL) return 1;\r | |
274 | #endif\r | |
275 | #if IRMP_SUPPORT_MERLIN_PROTOCOL\r | |
276 | if (proto == IRMP_MERLIN_PROTOCOL) return 1;\r | |
277 | #endif\r | |
278 | #if IRMP_SUPPORT_PENTAX_PROTOCOL\r | |
279 | if (proto == IRMP_PENTAX_PROTOCOL) return 1;\r | |
280 | #endif\r | |
281 | #if IRMP_SUPPORT_S100_PROTOCOL\r | |
282 | if (proto == IRMP_S100_PROTOCOL) return 1;\r | |
283 | #endif\r | |
284 | #if IRMP_SUPPORT_ACP24_PROTOCOL\r | |
285 | if (proto == IRMP_ACP24_PROTOCOL) return 1;\r | |
286 | #endif\r | |
287 | #if IRMP_SUPPORT_TECHNICS_PROTOCOL\r | |
288 | if (proto == IRMP_TECHNICS_PROTOCOL) return 1;\r | |
289 | #endif\r | |
290 | #if IRMP_SUPPORT_PANASONIC_PROTOCOL\r | |
291 | if (proto == IRMP_PANASONIC_PROTOCOL) return 1;\r | |
292 | #endif\r | |
293 | #if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL\r | |
294 | if (proto == IRMP_MITSU_HEAVY_PROTOCOL) return 1;\r | |
295 | #endif\r | |
296 | #if IRMP_SUPPORT_VINCENT_PROTOCOL\r | |
297 | if (proto == IRMP_VINCENT_PROTOCOL) return 1;\r | |
298 | #endif\r | |
299 | #if IRMP_SUPPORT_SAMSUNGAH_PROTOCOL\r | |
300 | if (proto == IRMP_SAMSUNGAH_PROTOCOL) return 1;\r | |
301 | #endif\r | |
302 | #if IRMP_SUPPORT_RADIO1_PROTOCOL\r | |
303 | if (proto == IRMP_RADIO1_PROTOCOL) return 1;\r | |
304 | #endif\r | |
305 | \r | |
306 | return 0;\r | |
307 | }\r | |
308 | \r | |
309 | void print_supported_protocols(void)\r | |
310 | {\r | |
311 | printf("Supported IR protocols:");\r | |
312 | for (int i = 0; i <= IRMP_N_PROTOCOLS; i++) {\r | |
313 | if (irmp_protocol_is_supported(i)) {\r | |
314 | #if IRMP_PROTOCOL_NAMES == 1\r | |
315 | printf(" %s", irmp_protocol_names[i]);\r | |
316 | #else\r | |
317 | printf(" %d", i);\r | |
318 | #endif\r | |
319 | }\r | |
320 | }\r | |
321 | printf("\n");\r | |
322 | }\r | |
323 | \r | |
324 | /*--------------------------------------------------------------------------*/\r | |
325 | \r | |
326 | void led_blink(void)\r | |
327 | {\r | |
328 | static uint32_t ts;\r | |
329 | \r | |
330 | if (get_timer(ts) >= 500) {\r | |
331 | ts = get_timer(0);\r | |
332 | gpio_toggle(LED_PORT, LED_PIN);\r | |
333 | }\r | |
334 | }\r | |
335 | \r | |
336 | int main (void)\r | |
337 | {\r | |
338 | IRMP_DATA irmp_data;\r | |
339 | \r | |
340 | setup_clock_and_gpios();\r | |
341 | setvbuf(stdout, NULL, _IONBF, 0);\r | |
342 | serial_setup(CON_BAUDRATE);\r | |
343 | \r | |
344 | printf("\nIRMP on STM32F103 with libopencm3 demo\n"\r | |
345 | " System frequency: %luHz\n"\r | |
346 | "IRMP timer input frequency (CK_INT): %luHz\n"\r | |
347 | " IRMP interrupt frequency: %uHz\n",\r | |
348 | rcc_ahb_frequency, timer_internal_clock_get(TIM_IRMP), F_INTERRUPTS);\r | |
349 | \r | |
350 | systick_setup();\r | |
351 | irmp_timer_init(); // initialize timer for irmp\r | |
352 | irmp_init(); // initialize irmp\r | |
353 | \r | |
354 | print_supported_protocols();\r | |
355 | for (;;)\r | |
356 | {\r | |
357 | led_blink();\r | |
358 | if (irmp_get_data (&irmp_data))\r | |
359 | {\r | |
360 | printf("protocol: 0x%.2x", irmp_data.protocol);\r | |
361 | #if IRMP_PROTOCOL_NAMES == 1\r | |
362 | printf(" %-11s", irmp_protocol_names[irmp_data.protocol]);\r | |
363 | #endif\r | |
364 | printf(" adress: 0x%.4x command: 0x%.4x flags: 0x%.2x\n",\r | |
365 | irmp_data.address, irmp_data.command, irmp_data.flags);\r | |
366 | }\r | |
367 | }\r | |
368 | }\r |