1 | /*---------------------------------------------------------------------------------------------------------------------------------------------------
|
2 | * main.c - demo main module to test irmp decoder
|
3 | *
|
4 | * Copyright (c) 2009-2015 Frank Meyer - frank(at)fli4l.de
|
5 | *
|
6 | * $Id: main.c,v 1.27 2015/02/27 10:19:20 fm Exp $
|
7 | *
|
8 | * This demo module is runnable on AVRs and LM4F120 Launchpad (ARM Cortex M4)
|
9 | *
|
10 | * ATMEGA88 @ 8 MHz internal RC Osc with BODLEVEL 4.3V: lfuse: 0xE2 hfuse: 0xDC efuse: 0xF9
|
11 | * ATMEGA88 @ 8 MHz external Crystal Osc with BODLEVEL 4.3V: lfuse: 0xFF hfuse: 0xDC efuse: 0xF9
|
12 | *
|
13 | * This program is free software; you can redistribute it and/or modify
|
14 | * it under the terms of the GNU General Public License as published by
|
15 | * the Free Software Foundation; either version 2 of the License, or
|
16 | * (at your option) any later version.
|
17 | *---------------------------------------------------------------------------------------------------------------------------------------------------
|
18 | */
|
19 | // matzetronics addition with Peter Fleurys LCD Library
|
20 | // undef this for UART output
|
21 | #define LCD_OUTPUT
|
22 | #include "irmp.h"
|
23 |
|
24 |
|
25 | #ifdef LCD_OUTPUT
|
26 | #include <stdlib.h>
|
27 | #include "lcd.h"
|
28 |
|
29 | #endif
|
30 |
|
31 | #ifndef F_CPU
|
32 | #error F_CPU unknown
|
33 | #endif
|
34 |
|
35 | /*---------------------------------------------------------------------------------------------------------------------------------------------------
|
36 | * ATMEL AVR part:
|
37 | *---------------------------------------------------------------------------------------------------------------------------------------------------
|
38 | */
|
39 | #if defined (ATMEL_AVR)
|
40 |
|
41 | #include "irmp.h"
|
42 | #define BAUD 9600L
|
43 | #include <util/setbaud.h>
|
44 |
|
45 | #ifdef UBRR0H
|
46 |
|
47 | #define UART0_UBRRH UBRR0H
|
48 | #define UART0_UBRRL UBRR0L
|
49 | #define UART0_UCSRA UCSR0A
|
50 | #define UART0_UCSRB UCSR0B
|
51 | #define UART0_UCSRC UCSR0C
|
52 | #define UART0_UDRE_BIT_VALUE (1<<UDRE0)
|
53 | #define UART0_UCSZ1_BIT_VALUE (1<<UCSZ01)
|
54 | #define UART0_UCSZ0_BIT_VALUE (1<<UCSZ00)
|
55 | #ifdef URSEL0
|
56 | #define UART0_URSEL_BIT_VALUE (1<<URSEL0)
|
57 | #else
|
58 | #define UART0_URSEL_BIT_VALUE (0)
|
59 | #endif
|
60 | #define UART0_TXEN_BIT_VALUE (1<<TXEN0)
|
61 | #define UART0_UDR UDR0
|
62 | #define UART0_U2X U2X0
|
63 |
|
64 | #else
|
65 |
|
66 | #define UART0_UBRRH UBRRH
|
67 | #define UART0_UBRRL UBRRL
|
68 | #define UART0_UCSRA UCSRA
|
69 | #define UART0_UCSRB UCSRB
|
70 | #define UART0_UCSRC UCSRC
|
71 | #define UART0_UDRE_BIT_VALUE (1<<UDRE)
|
72 | #define UART0_UCSZ1_BIT_VALUE (1<<UCSZ1)
|
73 | #define UART0_UCSZ0_BIT_VALUE (1<<UCSZ0)
|
74 | #ifdef URSEL
|
75 | #define UART0_URSEL_BIT_VALUE (1<<URSEL)
|
76 | #else
|
77 | #define UART0_URSEL_BIT_VALUE (0)
|
78 | #endif
|
79 | #define UART0_TXEN_BIT_VALUE (1<<TXEN)
|
80 | #define UART0_UDR UDR
|
81 | #define UART0_U2X U2X
|
82 |
|
83 | #endif //UBRR0H
|
84 | /// UART/LCD
|
85 | #ifndef LCD_OUTPUT
|
86 | static void
|
87 | uart_init (void)
|
88 | {
|
89 | UART0_UBRRH = UBRRH_VALUE; // set baud rate
|
90 | UART0_UBRRL = UBRRL_VALUE;
|
91 |
|
92 | #if USE_2X
|
93 | UART0_UCSRA |= (1<<UART0_U2X);
|
94 | #else
|
95 | UART0_UCSRA &= ~(1<<UART0_U2X);
|
96 | #endif
|
97 |
|
98 | UART0_UCSRC = UART0_UCSZ1_BIT_VALUE | UART0_UCSZ0_BIT_VALUE | UART0_URSEL_BIT_VALUE;
|
99 | UART0_UCSRB |= UART0_TXEN_BIT_VALUE; // enable UART TX
|
100 | }
|
101 |
|
102 | static void
|
103 | uart_putc (unsigned char ch)
|
104 | {
|
105 | while (!(UART0_UCSRA & UART0_UDRE_BIT_VALUE))
|
106 | {
|
107 | ;
|
108 | }
|
109 |
|
110 | UART0_UDR = ch;
|
111 | }
|
112 |
|
113 | static void
|
114 | uart_puts (char * s)
|
115 | {
|
116 | while (*s)
|
117 | {
|
118 | uart_putc (*s);
|
119 | s++;
|
120 | }
|
121 | }
|
122 |
|
123 | static void
|
124 | uart_puts_P (PGM_P s)
|
125 | {
|
126 | uint8_t ch;
|
127 |
|
128 | while ((ch = pgm_read_byte(s)) != '\0')
|
129 | {
|
130 | uart_putc (ch);
|
131 | s++;
|
132 | }
|
133 | }
|
134 | static char *
|
135 | itoh (char * buf, uint8_t digits, uint16_t number)
|
136 | {
|
137 | for (buf[digits] = 0; digits--; number >>= 4)
|
138 | {
|
139 | buf[digits] = "0123456789ABCDEF"[number & 0x0F];
|
140 | }
|
141 | return buf;
|
142 | }
|
143 | #else
|
144 | // Console//LCD utilities
|
145 | static void printspc(void)
|
146 | {
|
147 | lcd_putc(' ');
|
148 | }
|
149 | /* Some basic routines to print hecadecimal and
|
150 | * decimal numbers plus some conversion stuff
|
151 | */
|
152 | // table unfortunately needs to reside in RAM for now
|
153 | char hextable[18] = "0123456789ABCDEF";
|
154 | // very simple output to hex
|
155 | static void printbyte(const uint8_t data)
|
156 | {
|
157 | lcd_putc(hextable[data >> 4]);
|
158 | lcd_putc(hextable[data & 0x0f]);
|
159 | }
|
160 | static void printword(const uint16_t data)
|
161 | {
|
162 | printbyte(data >> 8);
|
163 | printbyte(data);
|
164 | }
|
165 |
|
166 | #endif
|
167 |
|
168 | static void
|
169 | timer1_init (void)
|
170 | {
|
171 | #if defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__) // ATtiny45 / ATtiny85:
|
172 |
|
173 | #if F_CPU >= 16000000L
|
174 | OCR1C = (F_CPU / F_INTERRUPTS / 8) - 1; // compare value: 1/15000 of CPU frequency, presc = 8
|
175 | TCCR1 = (1 << CTC1) | (1 << CS12); // switch CTC Mode on, set prescaler to 8
|
176 | #else
|
177 | OCR1C = (F_CPU / F_INTERRUPTS / 4) - 1; // compare value: 1/15000 of CPU frequency, presc = 4
|
178 | TCCR1 = (1 << CTC1) | (1 << CS11) | (1 << CS10); // switch CTC Mode on, set prescaler to 4
|
179 | #endif
|
180 |
|
181 | #else // ATmegaXX:
|
182 | OCR1A = (F_CPU / F_INTERRUPTS) - 1; // compare value: 1/15000 of CPU frequency
|
183 | TCCR1B = (1 << WGM12) | (1 << CS10); // switch CTC Mode on, set prescaler to 1
|
184 | #endif
|
185 |
|
186 | #ifdef TIMSK1
|
187 | TIMSK1 = 1 << OCIE1A; // OCIE1A: Interrupt by timer compare
|
188 | #else
|
189 | TIMSK = 1 << OCIE1A; // OCIE1A: Interrupt by timer compare
|
190 | #endif
|
191 | }
|
192 |
|
193 | #ifdef TIM1_COMPA_vect // ATtiny84
|
194 | #define COMPA_VECT TIM1_COMPA_vect
|
195 | #else
|
196 | #define COMPA_VECT TIMER1_COMPA_vect // ATmega
|
197 | #endif
|
198 |
|
199 | ISR(COMPA_VECT) // Timer1 output compare A interrupt service routine, called every 1/15000 sec
|
200 | {
|
201 | (void) irmp_ISR(); // call irmp ISR
|
202 | // call other timer interrupt routines...
|
203 | }
|
204 |
|
205 |
|
206 | int
|
207 | main (void)
|
208 | {
|
209 | IRMP_DATA irmp_data;
|
210 | #ifndef LCD_OUTPUT
|
211 | char buf[3];
|
212 | #endif
|
213 | irmp_init(); // initialize irmp
|
214 | timer1_init(); // initialize timer1
|
215 | #ifdef LCD_OUTPUT
|
216 | /* initialize display, cursor off */
|
217 | lcd_init(LCD_DISP_ON_CURSOR);
|
218 | lcd_home();
|
219 | lcd_puts_P("IRMP Dekoder\n");
|
220 | _delay_ms(1000);
|
221 | lcd_clrscr();
|
222 | #else
|
223 | uart_init(); // initialize uart
|
224 | #endif
|
225 | sei (); // enable interrupts
|
226 |
|
227 | for (;;)
|
228 | {
|
229 | if (irmp_get_data (&irmp_data))
|
230 | #ifndef LCD_OUTPUT
|
231 | {
|
232 | uart_puts_P (PSTR("protocol: 0x"));
|
233 | itoh (buf, 2, irmp_data.protocol);
|
234 | uart_puts (buf);
|
235 |
|
236 | #if IRMP_PROTOCOL_NAMES == 1
|
237 | uart_puts_P (PSTR(" "));
|
238 | uart_puts_P (pgm_read_word (&(irmp_protocol_names[irmp_data.protocol])));
|
239 | #endif
|
240 |
|
241 | uart_puts_P (PSTR(" address: 0x"));
|
242 | itoh (buf, 4, irmp_data.address);
|
243 | uart_puts (buf);
|
244 |
|
245 | uart_puts_P (PSTR(" command: 0x"));
|
246 | itoh (buf, 4, irmp_data.command);
|
247 | uart_puts (buf);
|
248 |
|
249 | uart_puts_P (PSTR(" flags: 0x"));
|
250 | itoh (buf, 2, irmp_data.flags);
|
251 | uart_puts (buf);
|
252 |
|
253 | uart_puts_P (PSTR("\r\n"));
|
254 | }
|
255 | #else
|
256 | {
|
257 | lcd_gotoxy(0,0); printbyte(irmp_data.protocol); printspc();
|
258 | lcd_gotoxy(3,0); printword(irmp_data.address); printspc();
|
259 | lcd_gotoxy(8,0); printword(irmp_data.command); printspc();
|
260 | lcd_gotoxy(0,1); printbyte(irmp_data.flags); printspc();
|
261 | }
|
262 | #endif
|
263 | }
|
264 | }
|
265 |
|
266 | /*---------------------------------------------------------------------------------------------------------------------------------------------------
|
267 | * LM4F120 Launchpad (ARM Cortex M4):
|
268 | *---------------------------------------------------------------------------------------------------------------------------------------------------
|
269 | */
|
270 | #elif defined(STELLARIS_ARM_CORTEX_M4)
|
271 |
|
272 | void
|
273 | timer1_init (void)
|
274 | {
|
275 | SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
|
276 | TimerConfigure(TIMER1_BASE, TIMER_CFG_32_BIT_PER);
|
277 |
|
278 | TimerLoadSet(TIMER1_BASE, TIMER_A, (F_CPU / F_INTERRUPTS) -1);
|
279 | IntEnable(INT_TIMER1A);
|
280 | TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
|
281 | TimerEnable(TIMER1_BASE, TIMER_A);
|
282 | // Important: Timer1IntHandler has to be configured in startup_ccs.c !
|
283 | }
|
284 |
|
285 | void
|
286 | Timer1IntHandler(void) // Timer1 Interrupt Handler
|
287 | {
|
288 | (void) irmp_ISR(); // call irmp ISR
|
289 | // call other timer interrupt routines...
|
290 | }
|
291 |
|
292 | int
|
293 | main (void)
|
294 | {
|
295 | IRMP_DATA irmp_data;
|
296 |
|
297 | ROM_FPUEnable();
|
298 | ROM_FPUStackingEnable();
|
299 | ROM_SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
|
300 |
|
301 | irmp_init(); // initialize irmp
|
302 | timer1_init(); // initialize timer1
|
303 | sei (); // enable interrupts
|
304 |
|
305 | for (;;)
|
306 | {
|
307 | if (irmp_get_data (&irmp_data))
|
308 | {
|
309 | // ir signal decoded, do something here...
|
310 | // irmp_data.protocol is the protocol, see irmp.h
|
311 | // irmp_data.address is the address/manufacturer code of ir sender
|
312 | // irmp_data.command is the command code
|
313 | // irmp_protocol_names[irmp_data.protocol] is the protocol name (if enabled, see irmpconfig.h)
|
314 | }
|
315 | }
|
316 | }
|
317 |
|
318 | /*---------------------------------------------------------------------------------------------------------------------------------------------------
|
319 | * PIC18F4520 with XC8 compiler:
|
320 | *---------------------------------------------------------------------------------------------------------------------------------------------------
|
321 | */
|
322 | #elif defined (__XC8)
|
323 |
|
324 | #define _XTAL_FREQ 32000000UL // 32MHz clock
|
325 | #define FOSC _XTAL_FREQ
|
326 | #define FCY FOSC / 4UL // --> 8MHz
|
327 |
|
328 | #define BAUDRATE 19200UL
|
329 | #define BRG (( FCY 16 BAUDRATE ) -1UL)
|
330 |
|
331 | #include <stdio.h>
|
332 | #include <stdlib.h>
|
333 |
|
334 | int
|
335 | main (void)
|
336 | {
|
337 | IRMP_DATA irmp_data;
|
338 |
|
339 | irmp_init(); // initialize irmp
|
340 |
|
341 | // infinite loop, interrupts will blink PORTD pins and handle UART communications.
|
342 | while (1)
|
343 | {
|
344 | LATBbits.LATB0 = ~LATBbits.LATB0;
|
345 |
|
346 | if (irmp_get_data (&irmp_data))
|
347 | {
|
348 | // ir signal decoded, do something here...
|
349 | // irmp_data.protocol is the protocol, see irmp.h
|
350 | // irmp_data.address is the address/manufacturer code of ir sender
|
351 | // irmp_data.command is the command code
|
352 | // irmp_protocol_names[irmp_data.protocol] is the protocol name (if enabled, see irmpconfig.h)
|
353 | printf("proto %d addr %d cmd %d\n", irmp_data.protocol, irmp_data.address, irmp_data.command );
|
354 | }
|
355 | }
|
356 | }
|
357 |
|
358 | void interrupt high_priority high_isr(void)
|
359 | {
|
360 | if (TMR2IF)
|
361 | {
|
362 | TMR2IF = 0; // clear Timer 0 interrupt flag
|
363 | irmp_ISR();
|
364 | }
|
365 | }
|
366 |
|
367 | /*---------------------------------------------------------------------------------------------------------------------------------------------------
|
368 | * STM32:
|
369 | *---------------------------------------------------------------------------------------------------------------------------------------------------
|
370 | */
|
371 | #elif defined(ARM_STM32)
|
372 |
|
373 | uint32_t
|
374 | SysCtlClockGet(void)
|
375 | {
|
376 | RCC_ClocksTypeDef RCC_ClocksStatus;
|
377 | RCC_GetClocksFreq(&RCC_ClocksStatus);
|
378 | return RCC_ClocksStatus.SYSCLK_Frequency;
|
379 | }
|
380 |
|
381 | void
|
382 | timer2_init (void)
|
383 | {
|
384 | TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
385 | NVIC_InitTypeDef NVIC_InitStructure;
|
386 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
|
387 |
|
388 | TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
389 | TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
390 | TIM_TimeBaseStructure.TIM_Period = 7;
|
391 | TIM_TimeBaseStructure.TIM_Prescaler = ((F_CPU / F_INTERRUPTS)/8) - 1;
|
392 | TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
|
393 |
|
394 | TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
|
395 |
|
396 | NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
|
397 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
398 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
|
399 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
|
400 | NVIC_Init(&NVIC_InitStructure);
|
401 |
|
402 | TIM_Cmd(TIM2, ENABLE);
|
403 | }
|
404 |
|
405 | void
|
406 | TIM2_IRQHandler(void) // Timer2 Interrupt Handler
|
407 | {
|
408 | TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
|
409 | (void) irmp_ISR(); // call irmp ISR
|
410 | // call other timer interrupt routines...
|
411 | }
|
412 |
|
413 | int
|
414 | main (void)
|
415 | {
|
416 | IRMP_DATA irmp_data;
|
417 |
|
418 | irmp_init(); // initialize irmp
|
419 | timer2_init(); // initialize timer2
|
420 |
|
421 | for (;;)
|
422 | {
|
423 | if (irmp_get_data (&irmp_data))
|
424 | {
|
425 | // ir signal decoded, do something here...
|
426 | // irmp_data.protocol is the protocol, see irmp.h
|
427 | // irmp_data.address is the address/manufacturer code of ir sender
|
428 | // irmp_data.command is the command code
|
429 | // irmp_protocol_names[irmp_data.protocol] is the protocol name (if enabled, see irmpconfig.h)
|
430 | }
|
431 | }
|
432 | }
|
433 | #endif
|