]> cloudbase.mooo.com Git - irmp-demo.git/blame - irmp-main.c
Inital commit
[irmp-demo.git] / irmp-main.c
CommitLineData
b1a276a1
L
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
33static 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
68uint32_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
90void 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
132void 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
162int 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
309void 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
326void 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
336int 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