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