main.c


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