X-Git-Url: http://cloudbase.mooo.com/gitweb/irmp.git/blobdiff_plain/4225a882583e3f3f35b5a9ee652d204338059b61..3d2da98a7a2b423edbdf4e685b588fbc5789dd7f:/main.c?ds=sidebyside diff --git a/main.c b/main.c index 2e05660..1c3050b 100644 --- a/main.c +++ b/main.c @@ -1,11 +1,14 @@ /*--------------------------------------------------------------------------------------------------------------------------------------------------- * main.c - demo main module to test irmp decoder * - * Copyright (c) 2009-2010 Frank Meyer - frank(at)fli4l.de + * Copyright (c) 2009-2015 Frank Meyer - frank(at)fli4l.de * - * ATMEGA88 @ 8 MHz + * $Id: main.c,v 1.27 2015/02/27 10:19:20 fm Exp $ * - * Fuses: lfuse: 0xE2 hfuse: 0xDC efuse: 0xF9 + * This demo module is runnable on AVRs and LM4F120 Launchpad (ARM Cortex M4) + * + * ATMEGA88 @ 8 MHz internal RC Osc with BODLEVEL 4.3V: lfuse: 0xE2 hfuse: 0xDC efuse: 0xF9 + * ATMEGA88 @ 8 MHz external Crystal Osc with BODLEVEL 4.3V: lfuse: 0xFF hfuse: 0xDC efuse: 0xF9 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,166 +17,365 @@ *--------------------------------------------------------------------------------------------------------------------------------------------------- */ +#include "irmp.h" + +#ifndef F_CPU +#error F_CPU unknown +#endif + /*--------------------------------------------------------------------------------------------------------------------------------------------------- - * uncomment this for codevision compiler: + * ATMEL AVR part: *--------------------------------------------------------------------------------------------------------------------------------------------------- */ -// #define CODEVISION // to use Codevision Compiler instead of gcc - -#ifdef CODEVISION -#include -#include -#define uint8_t unsigned char -#define uint16_t unsigned int -#define F_CPU 8000000 // change for Codevision here, if you use WinAVR, use Project -> Configuration Options instead - -// register values from datasheet for ATMega88 -#define OCIE1A 1 -#define WGM12 3 -#define CS10 0 -#define UDRE0 5 -#define TXEN0 3 +#if defined (ATMEL_AVR) #include "irmp.h" -#include "irmp.c" +#define BAUD 9600L +#include -#else // gcc compiler +#ifdef UBRR0H -#include -#include -#include -#include -#include -#include "irmp.h" +#define UART0_UBRRH UBRR0H +#define UART0_UBRRL UBRR0L +#define UART0_UCSRA UCSR0A +#define UART0_UCSRB UCSR0B +#define UART0_UCSRC UCSR0C +#define UART0_UDRE_BIT_VALUE (1<> 8) & 0xFF; // compare value: 1/10000 of CPU frequency (upper byte) - OCR1AL = ((F_CPU / F_INTERRUPTS) - 1) & 0xFF; // compare value: 1/10000 of CPU frequency (lower byte) -#else // gcc - OCR1A = (F_CPU / F_INTERRUPTS) - 1; // compare value: 1/10000 of CPU frequency -#endif // CODEVISION - TCCR1B = (1 << WGM12) | (1 << CS10); // switch CTC Mode on, set prescaler to 1 - -#if defined (__AVR_ATmega8__) || defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega64__) || defined (__AVR_ATmega162__) - TIMSK = 1 << OCIE1A; // OCIE1A: Interrupt by timer compare + UART0_UCSRC = UART0_UCSZ1_BIT_VALUE | UART0_UCSZ0_BIT_VALUE | UART0_URSEL_BIT_VALUE; + UART0_UCSRB |= UART0_TXEN_BIT_VALUE; // enable UART TX +} + +static void +uart_putc (unsigned char ch) +{ + while (!(UART0_UCSRA & UART0_UDRE_BIT_VALUE)) + { + ; + } + + UART0_UDR = ch; +} + +static void +uart_puts (char * s) +{ + while (*s) + { + uart_putc (*s); + s++; + } +} + +static void +uart_puts_P (PGM_P s) +{ + uint8_t ch; + + while ((ch = pgm_read_byte(s)) != '\0') + { + uart_putc (ch); + s++; + } +} + +static char * +itoh (char * buf, uint8_t digits, uint16_t number) +{ + for (buf[digits] = 0; digits--; number >>= 4) + { + buf[digits] = "0123456789ABCDEF"[number & 0x0F]; + } + return buf; +} + +static void +timer1_init (void) +{ +#if defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__) // ATtiny45 / ATtiny85: + +#if F_CPU >= 16000000L + OCR1C = (F_CPU / F_INTERRUPTS / 8) - 1; // compare value: 1/15000 of CPU frequency, presc = 8 + TCCR1 = (1 << CTC1) | (1 << CS12); // switch CTC Mode on, set prescaler to 8 +#else + OCR1C = (F_CPU / F_INTERRUPTS / 4) - 1; // compare value: 1/15000 of CPU frequency, presc = 4 + TCCR1 = (1 << CTC1) | (1 << CS11) | (1 << CS10); // switch CTC Mode on, set prescaler to 4 +#endif + +#else // ATmegaXX: + OCR1A = (F_CPU / F_INTERRUPTS) - 1; // compare value: 1/15000 of CPU frequency + TCCR1B = (1 << WGM12) | (1 << CS10); // switch CTC Mode on, set prescaler to 1 +#endif + +#ifdef TIMSK1 + TIMSK1 = 1 << OCIE1A; // OCIE1A: Interrupt by timer compare #else - TIMSK1 = 1 << OCIE1A; // OCIE1A: Interrupt by timer compare -#endif // __AVR... + TIMSK = 1 << OCIE1A; // OCIE1A: Interrupt by timer compare +#endif } -/*--------------------------------------------------------------------------------------------------------------------------------------------------- - * timer 1 compare handler, called every 1/10000 sec - *--------------------------------------------------------------------------------------------------------------------------------------------------- - */ -// Timer 1 output compare A interrupt service routine -#ifdef CODEVISION -interrupt [TIM1_COMPA] void timer1_compa_isr(void) -#else // CODEVISION -ISR(TIMER1_COMPA_vect) -#endif // CODEVISION -{ - irmp_ISR(); // call irmp ISR +#ifdef TIM1_COMPA_vect // ATtiny84 +#define COMPA_VECT TIM1_COMPA_vect +#else +#define COMPA_VECT TIMER1_COMPA_vect // ATmega +#endif + +ISR(COMPA_VECT) // Timer1 output compare A interrupt service routine, called every 1/15000 sec +{ + (void) irmp_ISR(); // call irmp ISR // call other timer interrupt routines... } +int +main (void) +{ + IRMP_DATA irmp_data; + char buf[3]; + + irmp_init(); // initialize irmp + timer1_init(); // initialize timer1 + uart_init(); // initialize uart + + sei (); // enable interrupts + + for (;;) + { + if (irmp_get_data (&irmp_data)) + { + uart_puts_P (PSTR("protocol: 0x")); + itoh (buf, 2, irmp_data.protocol); + uart_puts (buf); + +#if IRMP_PROTOCOL_NAMES == 1 + uart_puts_P (PSTR(" ")); + uart_puts_P (pgm_read_word (&(irmp_protocol_names[irmp_data.protocol]))); +#endif + + uart_puts_P (PSTR(" address: 0x")); + itoh (buf, 4, irmp_data.address); + uart_puts (buf); + + uart_puts_P (PSTR(" command: 0x")); + itoh (buf, 4, irmp_data.command); + uart_puts (buf); + + uart_puts_P (PSTR(" flags: 0x")); + itoh (buf, 2, irmp_data.flags); + uart_puts (buf); + + uart_puts_P (PSTR("\r\n")); + } + } +} + /*--------------------------------------------------------------------------------------------------------------------------------------------------- - * MAIN: main routine + * LM4F120 Launchpad (ARM Cortex M4): *--------------------------------------------------------------------------------------------------------------------------------------------------- */ -#ifdef CODEVISION -// This is the main routine if you use Codevision C Compiler +#elif defined(STELLARIS_ARM_CORTEX_M4) + +void +timer1_init (void) +{ + SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1); + TimerConfigure(TIMER1_BASE, TIMER_CFG_32_BIT_PER); + + TimerLoadSet(TIMER1_BASE, TIMER_A, (F_CPU / F_INTERRUPTS) -1); + IntEnable(INT_TIMER1A); + TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT); + TimerEnable(TIMER1_BASE, TIMER_A); + // Important: Timer1IntHandler has to be configured in startup_ccs.c ! +} + void +Timer1IntHandler(void) // Timer1 Interrupt Handler +{ + (void) irmp_ISR(); // call irmp ISR + // call other timer interrupt routines... +} + +int main (void) { - IRMP_DATA irmp_data; - - #pragma optsize- - // crystal oscillator division factor: 1 - CLKPR=0x80; - CLKPR=0x00; - #ifdef _OPTIMIZE_SIZE_ - #pragma optsize+ - #endif - static uint8_t *Proto[]={"SIRCS","NEC","SAMSUNG","MATSUSH","KASEIKYO","RECS80","RC5(x)","DENON","RC6","SAMSG32","APPLE"}; - #define IRMP_APPLE_ADDRESS 0x77E1 - - - #if IRMP_LOGGING == 0 - // USART initialization has to be done here if Logging is off - // Communication Parameters: 8 Data, 1 Stop, No Parity - // USART Receiver: Off - // USART Transmitter: On - // USART0 Mode: Asynchronous - // USART Baud Rate: 9600 - #define BAUDRATE 9600L - UCSR0A=0x00; - UCSR0B=0x08; - UCSR0C=0x06; - UBRR0H = ((F_CPU+BAUDRATE*8)/(BAUDRATE*16)-1) >> 8; // store baudrate (upper byte) - UBRR0L = ((F_CPU+BAUDRATE*8)/(BAUDRATE*16)-1) & 0xFF; - #endif - - irmp_init(); // initialize rc5 - - printf("IRMP V1.0\n"); - #if IRMP_LOGGING == 1 - printf("Logging Mode\n"); - #endif - - timer_init(); // initialize timer - #asm("sei"); // enable interrupts - - for (;;) - { - if (irmp_get_data (&irmp_data)) + IRMP_DATA irmp_data; + + ROM_FPUEnable(); + ROM_FPUStackingEnable(); + ROM_SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); + + irmp_init(); // initialize irmp + timer1_init(); // initialize timer1 + sei (); // enable interrupts + + for (;;) { - // ir signal decoded, do something here... - // irmp_data.protocol is the protocol, see irmp.h - // irmp_data.address is the address/manufacturer code of ir sender - // irmp_data.command is the command code - #if IRMP_LOGGING != 1 - if((irmp_data.protocol == IRMP_NEC_PROTOCOL) && (irmp_data.address == IRMP_APPLE_ADDRESS)) - printf("Code: Apple\n"); - else printf("Code: %s\n",Proto[irmp_data.protocol-1]); - printf("Address: 0x%.2X\n",irmp_data.address); - printf("Command: 0x%.2X\n\n",irmp_data.command); - #endif + if (irmp_get_data (&irmp_data)) + { + // ir signal decoded, do something here... + // irmp_data.protocol is the protocol, see irmp.h + // irmp_data.address is the address/manufacturer code of ir sender + // irmp_data.command is the command code + // irmp_protocol_names[irmp_data.protocol] is the protocol name (if enabled, see irmpconfig.h) + } } - } } -#else // gcc +/*--------------------------------------------------------------------------------------------------------------------------------------------------- + * PIC18F4520 with XC8 compiler: + *--------------------------------------------------------------------------------------------------------------------------------------------------- + */ +#elif defined (__XC8) + +#define _XTAL_FREQ 32000000UL // 32MHz clock +#define FOSC _XTAL_FREQ +#define FCY FOSC / 4UL // --> 8MHz + +#define BAUDRATE 19200UL +#define BRG (( FCY 16 BAUDRATE ) -1UL) + +#include +#include -// This is the main routine if you use GCC Compiler int main (void) { - IRMP_DATA irmp_data; + IRMP_DATA irmp_data; - irmp_init(); // initialize rc5 - timer_init(); // initialize timer - sei (); // enable interrupts + irmp_init(); // initialize irmp - for (;;) - { - if (irmp_get_data (&irmp_data)) + // infinite loop, interrupts will blink PORTD pins and handle UART communications. + while (1) { - // ir signal decoded, do something here... - // irmp_data.protocol is the protocol, see irmp.h - // irmp_data.address is the address/manufacturer code of ir sender - // irmp_data.command is the command code + LATBbits.LATB0 = ~LATBbits.LATB0; + + if (irmp_get_data (&irmp_data)) + { + // ir signal decoded, do something here... + // irmp_data.protocol is the protocol, see irmp.h + // irmp_data.address is the address/manufacturer code of ir sender + // irmp_data.command is the command code + // irmp_protocol_names[irmp_data.protocol] is the protocol name (if enabled, see irmpconfig.h) + printf("proto %d addr %d cmd %d\n", irmp_data.protocol, irmp_data.address, irmp_data.command ); + } } - } } -#endif // CODEVISION / gcc +void interrupt high_priority high_isr(void) +{ + if (TMR2IF) + { + TMR2IF = 0; // clear Timer 0 interrupt flag + irmp_ISR(); + } +} + +/*--------------------------------------------------------------------------------------------------------------------------------------------------- + * STM32: + *--------------------------------------------------------------------------------------------------------------------------------------------------- + */ +#elif defined(ARM_STM32) + +uint32_t +SysCtlClockGet(void) +{ + RCC_ClocksTypeDef RCC_ClocksStatus; + RCC_GetClocksFreq(&RCC_ClocksStatus); + return RCC_ClocksStatus.SYSCLK_Frequency; +} + +void +timer2_init (void) +{ + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + NVIC_InitTypeDef NVIC_InitStructure; + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); + + TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseStructure.TIM_Period = 7; + TIM_TimeBaseStructure.TIM_Prescaler = ((F_CPU / F_INTERRUPTS)/8) - 1; + TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); + + TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); + + NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; + NVIC_Init(&NVIC_InitStructure); + + TIM_Cmd(TIM2, ENABLE); +} + +void +TIM2_IRQHandler(void) // Timer2 Interrupt Handler +{ + TIM_ClearITPendingBit(TIM2, TIM_IT_Update); + (void) irmp_ISR(); // call irmp ISR + // call other timer interrupt routines... +} + +int +main (void) +{ + IRMP_DATA irmp_data; + + irmp_init(); // initialize irmp + timer2_init(); // initialize timer2 + + for (;;) + { + if (irmp_get_data (&irmp_data)) + { + // ir signal decoded, do something here... + // irmp_data.protocol is the protocol, see irmp.h + // irmp_data.address is the address/manufacturer code of ir sender + // irmp_data.command is the command code + // irmp_protocol_names[irmp_data.protocol] is the protocol name (if enabled, see irmpconfig.h) + } + } +} +#endif