From ad4d3d4157a9781b6ff3f83ac72b42f8bc3db0b5 Mon Sep 17 00:00:00 2001 From: ukw Date: Thu, 23 Apr 2015 12:44:18 +0000 Subject: [PATCH] Version 2.8.0: port to AVR XMEGA git-svn-id: svn://mikrocontroller.net/irmp@154 aeb2e35e-bfc4-4214-b83c-9e8de998ed28 --- irmp.h | 24 +++++++++++---- irmpconfig.h | 17 ++++++----- irmpprotocols.h | 4 +-- irmpsystem.h | 20 +++++++++++-- irsnd.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++-- irsndconfig.h | 45 +++++++++++++++++++--------- main.c | 40 +++++++------------------ 7 files changed, 166 insertions(+), 64 deletions(-) diff --git a/irmp.h b/irmp.h index abeec77..f662fe1 100644 --- a/irmp.h +++ b/irmp.h @@ -3,7 +3,7 @@ * * Copyright (c) 2009-2015 Frank Meyer - frank(at)fli4l.de * - * $Id: irmp.h,v 1.92 2015/01/28 09:18:30 fm Exp $ + * $Id: irmp.h,v 1.93 2015/02/26 15:42:53 fm Exp $ * * 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 @@ -21,7 +21,19 @@ # include "irmpconfig.h" #endif -#if defined (ATMEL_AVR) +#if defined (__AVR_XMEGA__) +# define _CONCAT(a,b) a##b +# define CONCAT(a,b) _CONCAT(a,b) +# define IRMP_PORT_PRE CONCAT(PORT, IRMP_PORT_LETTER) +# define IRMP_DDR_PRE CONCAT(DDR, IRMP_PORT_LETTER) +# define IRMP_PIN_PRE CONCAT(PIN, IRMP_PORT_LETTER) +# define IRMP_PORT IRMP_PORT_PRE.OUT +# define IRMP_DDR IRMP_DDR_PRE.DIR +# define IRMP_PIN IRMP_PIN_PRE.IN +# define IRMP_BIT IRMP_BIT_NUMBER +# define input(x) ((x) & (1 << IRMP_BIT)) + +#elif defined (ATMEL_AVR) # define _CONCAT(a,b) a##b # define CONCAT(a,b) _CONCAT(a,b) # define IRMP_PORT CONCAT(PORT, IRMP_PORT_LETTER) @@ -29,10 +41,10 @@ # define IRMP_PIN CONCAT(PIN, IRMP_PORT_LETTER) # define IRMP_BIT IRMP_BIT_NUMBER # define input(x) ((x) & (1 << IRMP_BIT)) -#elif defined (PIC_C18) -# define input(x) (x) -#elif defined (PIC_CCS) + +#elif defined (PIC_C18) || defined (PIC_CCS) # define input(x) (x) + #elif defined (ARM_STM32) # define _CONCAT(a,b) a##b # define CONCAT(a,b) _CONCAT(a,b) @@ -50,6 +62,7 @@ # ifndef USE_STDPERIPH_DRIVER # warning The STM32 port of IRMP uses the ST standard peripheral drivers which are not enabled in your build configuration. # endif + #elif defined (STELLARIS_ARM_CORTEX_M4) # define _CONCAT(a,b) a##b # define CONCAT(a,b) _CONCAT(a,b) @@ -59,6 +72,7 @@ # define IRMP_PIN IRMP_PORT_PIN # define input(x) ((uint8_t)(ROM_GPIOPinRead(IRMP_PORT_BASE, IRMP_PORT_PIN))) # define sei() IntMasterEnable() + #endif #if IRMP_SUPPORT_DENON_PROTOCOL == 1 && IRMP_SUPPORT_RUWIDO_PROTOCOL == 1 diff --git a/irmpconfig.h b/irmpconfig.h index 6860a3e..acbaf3c 100644 --- a/irmpconfig.h +++ b/irmpconfig.h @@ -6,7 +6,7 @@ * Copyright (c) 2009-2015 Frank Meyer - frank(at)fli4l.de * Extensions for PIC 12F1820 W.Strobl 2014-07-20 * - * $Id: irmpconfig.h,v 1.124 2015/01/26 13:07:01 fm Exp $ + * $Id: irmpconfig.h,v 1.125 2015/02/26 15:42:53 fm Exp $ * * 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 @@ -94,10 +94,10 @@ #define IRMP_SUPPORT_RADIO1_PROTOCOL 0 // RADIO, e.g. TEVION >= 10000 ~250 bytes (experimental) /*--------------------------------------------------------------------------------------------------------------------------------------------------- - * Change hardware pin here for ATMEL AVR + * Change hardware pin here for ATMEL ATMega/ATTiny/XMega *--------------------------------------------------------------------------------------------------------------------------------------------------- */ -#if defined (ATMEL_AVR) // use PB6 as IR input on AVR +#if defined (ATMEL_AVR) || defined (__AVR_XMEGA__) // use PB6 as IR input on AVR # define IRMP_PORT_LETTER B # define IRMP_BIT_NUMBER 6 @@ -106,10 +106,11 @@ *--------------------------------------------------------------------------------------------------------------------------------------------------- */ #elif defined (PIC_C18) // use RB4 as IR input on PIC (C18 or XC8 compiler) -#if defined(__12F1840) -# define IRMP_PIN RA5 // on 12F1840 with XC8 compiler -#endif -# define IRMP_PIN PORTBbits.RB4 // PIC C18 +# if defined(__12F1840) +# define IRMP_PIN RA5 // on 12F1840 with XC8 compiler +# else +# define IRMP_PIN PORTBbits.RB4 // PIC C18 +# endif /*--------------------------------------------------------------------------------------------------------------------------------------------------- * Change hardware pin here for PIC CCS compiler @@ -175,4 +176,4 @@ # define IRMP_USE_CALLBACK 0 // 1: use callbacks. 0: do not. default is 0 #endif -#endif /* _WC_IRMPCONFIG_H_ */ +#endif // _IRMPCONFIG_H_ diff --git a/irmpprotocols.h b/irmpprotocols.h index 64309d1..134aa4a 100644 --- a/irmpprotocols.h +++ b/irmpprotocols.h @@ -5,7 +5,7 @@ * * Copyright (c) 2013-2015 Frank Meyer - frank(at)fli4l.de * - * $Id: irmpprotocols.h,v 1.30 2015/01/26 13:07:01 fm Exp $ + * $Id: irmpprotocols.h,v 1.31 2015/02/26 15:42:53 fm Exp $ * * 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 @@ -263,7 +263,7 @@ typedef uint8_t PAUSE_LEN; *--------------------------------------------------------------------------------------------------------------------------------------------------- */ #define RC5_BIT_TIME 889.0e-6 // 889 usec pulse/pause -#define RC5_FRAME_REPEAT_PAUSE_TIME 45.0e-3 // frame repeat after 45ms +#define RC5_FRAME_REPEAT_PAUSE_TIME 88.9e-3 // frame repeat after 88.9ms #define RC5_ADDRESS_OFFSET 1 // skip 1 bit (2nd start) #define RC5_ADDRESS_LEN 6 // read 1 toggle bit (for key repetition detection) + 5 address bits diff --git a/irmpsystem.h b/irmpsystem.h index a6a4a69..6e85149 100644 --- a/irmpsystem.h +++ b/irmpsystem.h @@ -3,7 +3,7 @@ * * Copyright (c) 2009-2015 Frank Meyer - frank(at)fli4l.de * - * $Id: irmpsystem.h,v 1.16 2015/01/26 13:07:01 fm Exp $ + * $Id: irmpsystem.h,v 1.17 2015/02/26 15:42:53 fm Exp $ * * 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 @@ -80,7 +80,16 @@ typedef unsigned short uint16_t; # define IRSND_OC0 3 // OC0 # define IRSND_OC0A 4 // OC0A # define IRSND_OC0B 5 // OC0B + +# define IRSND_XMEGA_OC0A 0 // OC0A +# define IRSND_XMEGA_OC0B 1 // OC0B +# define IRSND_XMEGA_OC0C 2 // OC0C +# define IRSND_XMEGA_OC0D 3 // OC0D +# define IRSND_XMEGA_OC1A 4 // OC1A +# define IRSND_XMEGA_OC1B 5 // OC1B + #elif defined(STELLARIS_ARM_CORTEX_M4) + # include "inc/hw_ints.h" # include "inc/hw_memmap.h" # include "inc/hw_types.h" @@ -93,19 +102,24 @@ typedef unsigned short uint16_t; # include "driverlib/systick.h" # include "driverlib/pin_map.h" # include "driverlib/timer.h" -# define PROGMEM volatile -# define memcpy_P memcpy +# define PROGMEM +# define memcpy_P memcpy # define APP_SYSTICKS_PER_SEC 32 + #elif defined(ARM_STM32F10X) + # include "stm32f10x_gpio.h" # include "stm32f10x_rcc.h" # include "stm32f10x_tim.h" # include "misc.h" # define PROGMEM # define memcpy_P memcpy + #else + # define PROGMEM # define memcpy_P memcpy + #endif #if defined(PIC_CCS) || defined(PIC_C18) || defined(ARM_STM32) || defined(STELLARIS_ARM_CORTEX_M4) diff --git a/irsnd.c b/irsnd.c index 80d262e..b414d85 100644 --- a/irsnd.c +++ b/irsnd.c @@ -13,7 +13,7 @@ * ATmega164, ATmega324, ATmega644, ATmega644P, ATmega1284, ATmega1284P * ATmega88, ATmega88P, ATmega168, ATmega168P, ATmega328P * - * $Id: irsnd.c,v 1.83 2015/01/26 13:09:28 fm Exp $ + * $Id: irsnd.c,v 1.84 2015/02/26 15:42:53 fm Exp $ * * 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 @@ -43,6 +43,7 @@ # else # error Wrong value for IRSND_OCx, choose IRSND_OC0A or IRSND_OC0B in irsndconfig.h # endif // IRSND_OCx + #elif defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__) // ATtiny45/85 uses OC0A = PB0 or OC0B = PB1 # if IRSND_OCx == IRSND_OC0A // OC0A # define IRSND_PORT_LETTER B @@ -53,6 +54,7 @@ # else # error Wrong value for IRSND_OCx, choose IRSND_OC0A or IRSND_OC0B in irsndconfig.h # endif // IRSND_OCx + #elif defined (__AVR_ATtiny87__) || defined (__AVR_ATtiny167__) // ATtiny87/167 uses OC0A = PA2 # if IRSND_OCx == IRSND_OC0A // OC0A # define IRSND_PORT_LETTER A @@ -60,6 +62,7 @@ # else # error Wrong value for IRSND_OCx, choose IRSND_OC0A in irsndconfig.h # endif // IRSND_OCx + #elif defined (__AVR_ATmega8__) // ATmega8 uses only OC2 = PB3 # if IRSND_OCx == IRSND_OC2 // OC0A # define IRSND_PORT_LETTER B @@ -74,6 +77,7 @@ # else # error Wrong value for IRSND_OCx, choose IRSND_OC2 in irsndconfig.h # endif // IRSND_OCx + #elif defined (__AVR_ATmega162__) // ATmega162 uses OC2 = PB1 or OC0 = PB0 # if IRSND_OCx == IRSND_OC2 // OC2 # define IRSND_PORT_LETTER B @@ -84,6 +88,7 @@ # else # error Wrong value for IRSND_OCx, choose IRSND_OC2 or IRSND_OC0 in irsndconfig.h # endif // IRSND_OCx + #elif defined (__AVR_ATmega164__) \ || defined (__AVR_ATmega324__) \ || defined (__AVR_ATmega644__) \ @@ -105,6 +110,7 @@ # else # error Wrong value for IRSND_OCx, choose IRSND_OC2A, IRSND_OC2B, IRSND_OC0A, or IRSND_OC0B in irsndconfig.h # endif // IRSND_OCx + #elif defined (__AVR_ATmega48__) \ || defined (__AVR_ATmega88__) \ || defined (__AVR_ATmega88P__) \ @@ -126,6 +132,7 @@ # else # error Wrong value for IRSND_OCx, choose IRSND_OC2A, IRSND_OC2B, IRSND_OC0A, or IRSND_OC0B in irsndconfig.h # endif // IRSND_OCx + #elif defined (__AVR_ATmega8515__) // ATmega8515 uses OC0 = PB0 or OC1A = PD5 or OC1B = PE2 # if IRSND_OCx == IRSND_OC0 # define IRSND_PORT_LETTER B @@ -136,9 +143,36 @@ # elif IRSND_OCx == IRSND_OC1B # define IRSND_PORT_LETTER E # define IRSND_BIT_NUMBER 2 +# endif // IRSND_OCx + +#elif defined (__AVR_ATxmega128A1U__) // ATxmega128A1U +# if (XMEGA_Timer_NR == 1) +# define IRSND_PORT_PRE PORTC +# elif (XMEGA_Timer_NR == 2) +# define IRSND_PORT_PRE PORTD +# elif (XMEGA_Timer_NR == 3) +# define IRSND_PORT_PRE PORTE +# elif (XMEGA_Timer_NR == 4) +# define IRSND_PORT_PRE PORTF +# else +# warning wrong XMEGA_Timer_NR, choose correct value in irsndconfig.h +# endif +# if IRSND_OCx == IRSND_XMEGA_OC0A +# define IRSND_BIT_NUMBER 0 +# elif IRSND_OCx == IRSND_XMEGA_OC0B +# define IRSND_BIT_NUMBER 1 +# elif IRSND_OCx == IRSND_XMEGA_OC0C +# define IRSND_BIT_NUMBER 2 +# elif IRSND_OCx == IRSND_XMEGA_OC0D +# define IRSND_BIT_NUMBER 3 +# elif IRSND_OCx == IRSND_XMEGA_OC1A +# define IRSND_BIT_NUMBER 4 +# elif IRSND_OCx == IRSND_XMEGA_OC1B +# define IRSND_BIT_NUMBER 5 # else # error Wrong value for IRSND_OCx, choose IRSND_OC0, IRSND_OC1A, or IRSND_OC1B in irsndconfig.h # endif // IRSND_OCx + #elif defined (PIC_C18) //Microchip C18 compiler //Nothing here to do here -> See irsndconfig.h #elif defined (ARM_STM32) //STM32 @@ -149,7 +183,15 @@ # endif // unix, WIN32 #endif // __AVR... -#if defined(ATMEL_AVR) +#if defined(__AVR_XMEGA__) +# define _CONCAT(a,b) a##b +# define CONCAT(a,b) _CONCAT(a,b) +# define IRSND_PORT IRSND_PORT_PRE.OUT +# define IRSND_DDR IRSND_DDR_PRE.DIR +# define IRSND_PIN IRSND_PIN_PRE.IN +# define IRSND_BIT IRSND_BIT_NUMBER + +#elif defined(ATMEL_AVR) # define _CONCAT(a,b) a##b # define CONCAT(a,b) _CONCAT(a,b) # define IRSND_PORT CONCAT(PORT, IRSND_PORT_LETTER) @@ -414,10 +456,25 @@ irsnd_on (void) # if defined(PIC_C18) // PIC C18 PWMon(); // IRSND_PIN = 0; // output mode -> enable PWM outout pin (0=PWM on, 1=PWM off) + # elif defined (ARM_STM32) // STM32 TIM_SelectOCxM(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_OCMode_PWM1); // enable PWM as OC-mode TIM_CCxCmd(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_CCx_Enable); // enable OC-output (is being disabled in TIM_SelectOCxM()) TIM_Cmd(IRSND_TIMER, ENABLE); // enable counter + +# elif defined (__AVR_XMEGA__) +# if ( (IRSND_OCx == IRSND_XMEGA_OC0A) | (IRSND_OCx == IRSND_XMEGA_OC1A) ) // use OC0A or OC1A + XMEGA_Timer.CTRLB |= (1< disbale PWM output pin (0=PWM on, 1=PWM off) + # elif defined (ARM_STM32) // STM32 TIM_Cmd(IRSND_TIMER, DISABLE); // disable counter TIM_SelectOCxM(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_ForcedAction_InActive); // force output inactive TIM_CCxCmd(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_CCx_Enable); // enable OC-output (is being disabled in TIM_SelectOCxM()) TIM_SetCounter(IRSND_TIMER, 0); // reset counter value + +# elif defined (__AVR_XMEGA__) +# if ( (IRSND_OCx == IRSND_XMEGA_OC0A) | (IRSND_OCx == IRSND_XMEGA_OC1A) ) // use OC0A or OC1A + XMEGA_Timer.CTRLB &= ~(1<= 10000 ~150 bytes. #define IRSND_SUPPORT_SAMSUNG48_PROTOCOL 0 // Samsung48 >= 10000 ~100 bytes + +/*--------------------------------------------------------------------------------------------------------------------------------------------------- + * AVR XMega section: + * + * Change hardware pin here: IRSND_XMEGA_OC0A = OC0A on ATxmegas supporting OC0A, e.g. ATxmega128A1U + * IRSND_XMEGA_OC0B = OC0B on ATxmegas supporting OC0B, e.g. ATxmega128A1U + * IRSND_XMEGA_OC0C = OC0C on ATxmegas supporting OC0C, e.g. ATxmega128A1U + * IRSND_XMEGA_OC0D = OC0D on ATxmegas supporting OC0D, e.g. ATxmega128A1U + * IRSND_XMEGA_OC1A = OC0A on ATxmegas supporting OC1A, e.g. ATxmega128A1U + * IRSND_XMEGA_OC1B = OC0B on ATxmegas supporting OC1B, e.g. ATxmega128A1U + *--------------------------------------------------------------------------------------------------------------------------------------------------- + */ +#if defined(__AVR_XMEGA__) // XMEGA +# define XMEGA_Timer_NR 2 // 1 == Timer PORTC //2 == Timer PORTD //3 == Timer PORTE //4 == Timer PORTF +# define XMEGA_Timer TCD0 +# define IRSND_OCx IRSND_XMEGA_OC0B // use OC0B + /*--------------------------------------------------------------------------------------------------------------------------------------------------- - * AVR section: + * AVR ATMega/ATTiny section: * * Change hardware pin here: IRSND_OC2 = OC2 on ATmegas supporting OC2, e.g. ATmega8 * IRSND_OC2A = OC2A on ATmegas supporting OC2A, e.g. ATmega88 @@ -92,7 +109,7 @@ * IRSND_OC0B = OC0B on ATmegas/ATtinys supporting OC0B, e.g. ATtiny84, ATtiny85 *--------------------------------------------------------------------------------------------------------------------------------------------------- */ -#if defined(ATMEL_AVR) +#elif defined(ATMEL_AVR) # define IRSND_OCx IRSND_OC2B // use OC2B /*--------------------------------------------------------------------------------------------------------------------------------------------------- @@ -103,18 +120,18 @@ *--------------------------------------------------------------------------------------------------------------------------------------------------- */ #elif defined(PIC_C18) // C18 or XC8 compiler -# if defined(__12F1840) // XC8 compiler -# define Pre_Scaler 1 // define prescaler for timer2 e.g. 1,4,16 -# define F_CPU 32000000UL // PIC frequency: set your freq here -# define PIC_Scaler 2 // PIC needs /2 extra in IRSND_FREQ_32_KHZ calculation for right value +# if defined(__12F1840) // XC8 compiler +# define Pre_Scaler 1 // define prescaler for timer2 e.g. 1,4,16 +# define F_CPU 32000000UL // PIC frequency: set your freq here +# define PIC_Scaler 2 // PIC needs /2 extra in IRSND_FREQ_32_KHZ calculation for right value -# else // C18 compiler -# define IRSND_OCx IRSND_PIC_CCP2 // Use PWMx for PIC +# else // C18 compiler +# define IRSND_OCx IRSND_PIC_CCP2 // Use PWMx for PIC // change other PIC C18 specific settings: -# define F_CPU 48000000UL // PIC frequency: set your freq here -# define Pre_Scaler 4 // define prescaler for timer2 e.g. 1,4,16 -# define PIC_Scaler 2 // PIC needs /2 extra in IRSND_FREQ_32_KHZ calculation for right value -# endif +# define F_CPU 48000000UL // PIC frequency: set your freq here +# define Pre_Scaler 4 // define prescaler for timer2 e.g. 1,4,16 +# define PIC_Scaler 2 // PIC needs /2 extra in IRSND_FREQ_32_KHZ calculation for right value +# endif /*--------------------------------------------------------------------------------------------------------------------------------------------------- * ARM STM32 section: @@ -127,7 +144,7 @@ # define IRSND_TIMER_CHANNEL_NUMBER 1 // only channel 1 can be used at the moment, others won't work /*--------------------------------------------------------------------------------------------------------------------------------------------------- - * Other target system + * Other target systems *--------------------------------------------------------------------------------------------------------------------------------------------------- */ #elif !defined (UNIX_OR_WINDOWS) diff --git a/main.c b/main.c index 38a9676..1c3050b 100644 --- a/main.c +++ b/main.c @@ -3,7 +3,7 @@ * * Copyright (c) 2009-2015 Frank Meyer - frank(at)fli4l.de * - * $Id: main.c,v 1.24 2015/01/26 13:09:28 fm Exp $ + * $Id: main.c,v 1.27 2015/02/27 10:19:20 fm Exp $ * * This demo module is runnable on AVRs and LM4F120 Launchpad (ARM Cortex M4) * @@ -122,30 +122,14 @@ uart_puts_P (PGM_P s) } } -static uint8_t -itox (uint8_t val) +static char * +itoh (char * buf, uint8_t digits, uint16_t number) { - uint8_t rtc; - - val &= 0x0F; - - if (val <= 9) + for (buf[digits] = 0; digits--; number >>= 4) { - rtc = val + '0'; + buf[digits] = "0123456789ABCDEF"[number & 0x0F]; } - else - { - rtc = val - 10 + 'A'; - } - return (rtc); -} - -static void -itoxx (char * xx, unsigned char i) -{ - *xx++ = itox (i >> 4); - *xx++ = itox (i & 0x0F); - *xx = '\0'; + return buf; } static void @@ -202,7 +186,7 @@ main (void) if (irmp_get_data (&irmp_data)) { uart_puts_P (PSTR("protocol: 0x")); - itoxx (buf, irmp_data.protocol); + itoh (buf, 2, irmp_data.protocol); uart_puts (buf); #if IRMP_PROTOCOL_NAMES == 1 @@ -211,19 +195,15 @@ main (void) #endif uart_puts_P (PSTR(" address: 0x")); - itoxx (buf, irmp_data.address >> 8); - uart_puts (buf); - itoxx (buf, irmp_data.address & 0xFF); + itoh (buf, 4, irmp_data.address); uart_puts (buf); uart_puts_P (PSTR(" command: 0x")); - itoxx (buf, irmp_data.command >> 8); - uart_puts (buf); - itoxx (buf, irmp_data.command & 0xFF); + itoh (buf, 4, irmp_data.command); uart_puts (buf); uart_puts_P (PSTR(" flags: 0x")); - itoxx (buf, irmp_data.flags); + itoh (buf, 2, irmp_data.flags); uart_puts (buf); uart_puts_P (PSTR("\r\n")); -- 2.39.2