From: Daniele Basile Date: Fri, 13 Jan 2012 15:53:11 +0000 (+0100) Subject: Merge contributed patch to extend support of atxmega. X-Git-Url: https://codewiz.org/gitweb?a=commitdiff_plain;h=57fa5e371a8b40afc99b922731b77d17c55330a4;p=bertos.git Merge contributed patch to extend support of atxmega. Signed-off-by: Onno --- diff --git a/bertos/cfg/cfg_ser.h b/bertos/cfg/cfg_ser.h index e7d5cc43..ec113e52 100644 --- a/bertos/cfg/cfg_ser.h +++ b/bertos/cfg/cfg_ser.h @@ -44,6 +44,13 @@ * Edit these define for your project. */ +/** + * Enable port 0 + * $WIZ$ type = "boolean" + * $WIZ$ supports = "xmega" + */ +#define CONFIG_UART0_ENABLED 1 + /** * Size of the outbound FIFO buffer for port 0 [bytes]. * $WIZ$ type = "int" @@ -58,11 +65,18 @@ */ #define CONFIG_UART0_RXBUFSIZE 32 +/** + * Enable port 1 + * $WIZ$ type = "boolean" + * $WIZ$ supports = "xmega" + */ +#define CONFIG_UART1_ENABLED 1 + /** * Size of the outbound FIFO buffer for port 1 [bytes]. * $WIZ$ type = "int" * $WIZ$ min = 2 - * $WIZ$ supports = "lm3s or lpc2 or (at91 and not atmega8 and not atmega168 and not atmega32)" + * $WIZ$ supports = "lm3s or lpc2 or xmega or (at91 and not atmega8 and not atmega168 and not atmega32)" */ #define CONFIG_UART1_TXBUFSIZE 32 @@ -70,15 +84,22 @@ * Size of the inbound FIFO buffer for port 1 [bytes]. * $WIZ$ type = "int" * $WIZ$ min = 2 - * $WIZ$ supports = "lm3s or lpc2 or (at91 and not atmega8 and not atmega168 and not atmega32)" + * $WIZ$ supports = "lm3s or lpc2 or xmega or (at91 and not atmega8 and not atmega168 and not atmega32)" */ #define CONFIG_UART1_RXBUFSIZE 32 +/** + * Enable port 2 + * $WIZ$ type = "boolean" + * $WIZ$ supports = "xmega and (not xmegad4)" + */ +#define CONFIG_UART2_ENABLED 1 + /** * Size of the outbound FIFO buffer for port 2 [bytes]. * $WIZ$ type = "int" * $WIZ$ min = 2 - * $WIZ$ supports = "lm3s or lpc2" + * $WIZ$ supports = "lm3s or lpc2 or (xmega and not xmegad4)" */ #define CONFIG_UART2_TXBUFSIZE 32 @@ -86,15 +107,22 @@ * Size of the inbound FIFO buffer for port 2 [bytes]. * $WIZ$ type = "int" * $WIZ$ min = 2 - * $WIZ$ supports = "lm3s or lpc2" + * $WIZ$ supports = "lm3s or lpc2 or (xmega and not xmegad4)" */ #define CONFIG_UART2_RXBUFSIZE 32 +/** + * Enable port 3 + * $WIZ$ type = "boolean" + * $WIZ$ supports = "xmega and not xmegad4" + */ +#define CONFIG_UART3_ENABLED 1 + /** * Size of the outbound FIFO buffer for port 3 [bytes]. * $WIZ$ type = "int" * $WIZ$ min = 2 - * $WIZ$ supports = "lpc2" + * $WIZ$ supports = "lpc2 or xmega and not xmegad4" */ #define CONFIG_UART3_TXBUFSIZE 32 @@ -102,16 +130,107 @@ * Size of the inbound FIFO buffer for port 3 [bytes]. * $WIZ$ type = "int" * $WIZ$ min = 2 - * $WIZ$ supports = "lpc2" + * $WIZ$ supports = "lpc2 or xmega and not xmegad4" */ #define CONFIG_UART3_RXBUFSIZE 32 +/** + * Enable port 4 + * $WIZ$ type = "boolean" + * $WIZ$ supports = "xmega and not xmegad4" + */ +#define CONFIG_UART4_ENABLED 1 + +/** + * Size of the outbound FIFO buffer for port 4 [bytes]. + * $WIZ$ type = "int" + * $WIZ$ min = 2 + * $WIZ$ supports = "xmega and not xmegad4" + */ +#define CONFIG_UART4_TXBUFSIZE 32 + +/** + * Size of the inbound FIFO buffer for port 4 [bytes]. + * $WIZ$ type = "int" + * $WIZ$ min = 2 + * $WIZ$ supports = "xmega and not xmegad4" + */ +#define CONFIG_UART4_RXBUFSIZE 32 + +/** + * Enable port 5 + * $WIZ$ type = "boolean" + * $WIZ$ supports = "xmegaa1 or xmegaa3" + */ +#define CONFIG_UART5_ENABLED 1 + +/** + * Size of the outbound FIFO buffer for port 5 [bytes]. + * $WIZ$ type = "int" + * $WIZ$ min = 2 + * $WIZ$ supports = "xmegaa1 or xmegaa3" + */ +#define CONFIG_UART5_TXBUFSIZE 32 + +/** + * Size of the inbound FIFO buffer for port 5 [bytes]. + * $WIZ$ type = "int" + * $WIZ$ min = 2 + * $WIZ$ supports = "xmegaa1 or xmegaa3" + */ +#define CONFIG_UART5_RXBUFSIZE 32 + +/** + * Enable port 6 + * $WIZ$ type = "boolean" + * $WIZ$ supports = "xmegaa1 or xmegaa3" + */ +#define CONFIG_UART6_ENABLED 1 + +/** + * Size of the outbound FIFO buffer for port 6 [bytes]. + * $WIZ$ type = "int" + * $WIZ$ min = 2 + * $WIZ$ supports = "xmegaa1 or xmegaa3" + */ +#define CONFIG_UART6_TXBUFSIZE 32 + +/** + * Size of the inbound FIFO buffer for port 6 [bytes]. + * $WIZ$ type = "int" + * $WIZ$ min = 2 + * $WIZ$ supports = "xmegaa1 or xmegaa3" + */ +#define CONFIG_UART6_RXBUFSIZE 32 + +/** + * Enable port 7 + * $WIZ$ type = "boolean" + * $WIZ$ supports = "xmegaa1" + */ +#define CONFIG_UART7_ENABLED 1 + +/** + * Size of the outbound FIFO buffer for port 7 [bytes]. + * $WIZ$ type = "int" + * $WIZ$ min = 2 + * $WIZ$ supports = "xmegaa1" + */ +#define CONFIG_UART7_TXBUFSIZE 32 + +/** + * Size of the inbound FIFO buffer for port 7 [bytes]. + * $WIZ$ type = "int" + * $WIZ$ min = 2 + * $WIZ$ supports = "xmegaa1" + */ +#define CONFIG_UART7_RXBUFSIZE 32 /** * Size of the outbound FIFO buffer for SPI port [bytes]. * $WIZ$ type = "int" * $WIZ$ min = 2 - * $WIZ$ supports = "avr" + * $WIZ$ supports = "avr and not xmega" */ #define CONFIG_SPI_TXBUFSIZE 32 @@ -119,7 +238,7 @@ * Size of the inbound FIFO buffer for SPI port [bytes]. * $WIZ$ type = "int" * $WIZ$ min = 2 - * $WIZ$ supports = "avr" + * $WIZ$ supports = "avr and not xmega" */ #define CONFIG_SPI_RXBUFSIZE 32 @@ -160,14 +279,14 @@ * * $WIZ$ type = "enum" * $WIZ$ value_list = "ser_order_bit" - * $WIZ$ supports = "avr and not xmega32d" + * $WIZ$ supports = "avr and not xmega" */ #define CONFIG_SPI_DATA_ORDER SER_MSB_FIRST /** * SPI clock division factor. * $WIZ$ type = "int" - * $WIZ$ supports = "avr and not xmega32d" + * $WIZ$ supports = "avr and not xmega" */ #define CONFIG_SPI_CLOCK_DIV 16 @@ -175,7 +294,7 @@ * SPI clock polarity: normal low or normal high. * $WIZ$ type = "enum" * $WIZ$ value_list = "ser_spi_pol" - * $WIZ$ supports = "avr and not xmega32d" + * $WIZ$ supports = "avr and not xmega" */ #define CONFIG_SPI_CLOCK_POL SPI_NORMAL_LOW @@ -184,7 +303,7 @@ * sample on second clock edge. * $WIZ$ type = "enum" * $WIZ$ value_list = "ser_spi_phase" - * $WIZ$ supports = "avr and not xmega32d" + * $WIZ$ supports = "avr and not xmega" */ #define CONFIG_SPI_CLOCK_PHASE SPI_SAMPLE_ON_FIRST_EDGE diff --git a/bertos/cpu/attr.h b/bertos/cpu/attr.h index e0e97ef3..331f26df 100644 --- a/bertos/cpu/attr.h +++ b/bertos/cpu/attr.h @@ -258,7 +258,7 @@ #define CPU_RAM_START 0x100 #elif CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560 #define CPU_RAM_START 0x200 - #elif CPU_AVR_XMEGA_D + #elif CPU_AVR_XMEGA #define CPU_RAM_START 0x2000 #else #warning Fix CPU_RAM_START address for your AVR, default value set to 0x100 diff --git a/bertos/cpu/avr/drv/kdebug_xmega.c b/bertos/cpu/avr/drv/kdebug_xmega.c index aa40e4cb..34ed9ee1 100644 --- a/bertos/cpu/avr/drv/kdebug_xmega.c +++ b/bertos/cpu/avr/drv/kdebug_xmega.c @@ -55,7 +55,8 @@ /* Set KDBG_USART, KDBG_USART_PORT and KDBG_USART_TX_PIN_bm * according to the CONFIG_KDEBUG_PORT setting - * The Xmega A and D families support at least 2 UARTS + * All Xmega families support at least 2 UARTS + * Some Xmega families suport more (D3->3, A4->5, A3->7, A1->8) */ #if CONFIG_KDEBUG_PORT == 0 #define KDBG_USART USARTC0 @@ -66,31 +67,57 @@ #define KDBG_USART_PORT PORTD #define KDBG_USART_TX_PIN_bm PIN3_bm #endif -/* Allow the configuration of the extra 3 UARTS for the - * Xmega A family - */ -#ifdef CPU_AVR_XMEGA_A +#if CPU_AVR_XMEGA_D3 || CPU_AVR_XMEGA_A4 || CPU_AVR_XMEGA_A3 || CPU_AVR_XMEGA_A1 #if CONFIG_KDEBUG_PORT == 2 + #define KDBG_USART USARTE0 + #define KDBG_USART_PORT PORTE + #define KDBG_USART_TX_PIN_bm PIN3_bm + #endif +#endif +#if CPU_AVR_XMEGA_A4 || CPU_AVR_XMEGA_A3 || CPU_AVR_XMEGA_A1 + #if CONFIG_KDEBUG_PORT == 3 #define KDBG_USART USARTC1 #define KDBG_USART_PORT PORTC #define KDBG_USART_TX_PIN_bm PIN7_bm - #elif CONFIG_KDEBUG_PORT == 3 + #elif CONFIG_KDEBUG_PORT == 4 #define KDBG_USART USARTD1 #define KDBG_USART_PORT PORTD #define KDBG_USART_TX_PIN_bm PIN7_bm - #elif CONFIG_KDEBUG_PORT == 4 - #define KDBG_USART USARTE0 + #endif +#endif +#if CPU_AVR_XMEGA_A3 || CPU_AVR_XMEGA_A1 + #if CONFIG_KDEBUG_PORT == 5 + #define KDBG_USART USARTE1 #define KDBG_USART_PORT PORTE + #define KDBG_USART_TX_PIN_bm PIN7_bm + #elif CONFIG_KDEBUG_PORT == 6 + #define KDBG_USART USARTF0 + #define KDBG_USART_PORT PORTF #define KDBG_USART_TX_PIN_bm PIN3_bm #endif #endif +#if CPU_AVR_XMEGA_A1 + #if CONFIG_KDEBUG_PORT == 7 + #define KDBG_USART USARTF1 + #define KDBG_USART_PORT PORTF + #define KDBG_USART_TX_PIN_bm PIN7_bm + #endif +#endif + + /* Check if all required KDBG_ macros are defined */ #ifndef KDBG_USART - #if CPU_AVR_XMEGA_D + #if CPU_AVR_XMEGA_D4 #error CONFIG_KDEBUG_PORT should be either 0 or 1 - #elif CPU_AVR_XMEGA_A + #elif CPU_AVR_XMEGA_D3 + #error CONFIG_KDEBUG_PORT should be either 0, 1 or 2 + #elif CPU_AVR_XMEGA_A4 #error CONFIG_KDEBUG_PORT should be either 0, 1, 2, 3 or 4 + #elif CPU_AVR_XMEGA_A3 + #error CONFIG_KDEBUG_PORT should be either 0, 1, 2, 3, 4, 5 or 6 + #elif CPU_AVR_XMEGA_A1 + #error CONFIG_KDEBUG_PORT should be either 0, 1, 2, 3, 4, 5, 6 or 7 #endif #endif @@ -195,7 +222,8 @@ typedef struct kdbg_avr_xmega_irqsave kdbg_irqsave_t; INLINE void kdbg_hw_init(void) { //set transmit pin as output - KDBG_USART_PORT.OUT = KDBG_USART_PORT.OUT & ~KDBG_USART_TX_PIN_bm; + //KDBG_USART_PORT.OUTCLR = KDBG_USART_TX_PIN_bm; + KDBG_USART_PORT.OUTSET = KDBG_USART_TX_PIN_bm; KDBG_USART_PORT.DIRSET = KDBG_USART_TX_PIN_bm; //set 8 bits, no parity, 1 stop bit KDBG_SET_FORMAT(USART_CHSIZE_8BIT_gc, USART_PMODE_DISABLED_gc, false); diff --git a/bertos/cpu/avr/drv/ser_xmega.c b/bertos/cpu/avr/drv/ser_xmega.c index 9b1e2c17..14c3ab28 100644 --- a/bertos/cpu/avr/drv/ser_xmega.c +++ b/bertos/cpu/avr/drv/ser_xmega.c @@ -44,8 +44,6 @@ #include "hw/hw_ser.h" /* Required for bus macros overrides */ #include /* CPU_FREQ */ -#include "cfg/cfg_ser.h" /* Serialport configuration settings */ - #include /* DIV_ROUND */ #include /* debug configuration */ @@ -312,17 +310,37 @@ extern struct Serial *ser_handles[SER_CNT]; /* TX and RX buffers */ -static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE]; -static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE]; -static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE]; -static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE]; -#ifdef CPU_AVR_XMEGA_A -static unsigned char uart2_txbuffer[CONFIG_UART2_TXBUFSIZE]; -static unsigned char uart2_rxbuffer[CONFIG_UART2_RXBUFSIZE]; -static unsigned char uart3_txbuffer[CONFIG_UART3_TXBUFSIZE]; -static unsigned char uart3_rxbuffer[CONFIG_UART3_RXBUFSIZE]; -static unsigned char uart4_txbuffer[CONFIG_UART4_TXBUFSIZE]; -static unsigned char uart4_rxbuffer[CONFIG_UART4_RXBUFSIZE]; +#if IMPLEMENT_SER_UART0 + static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE]; + static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE]; +#endif +#if IMPLEMENT_SER_UART1 + static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE]; + static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE]; +#endif +#if IMPLEMENT_SER_UART2 + static unsigned char uart2_txbuffer[CONFIG_UART2_TXBUFSIZE]; + static unsigned char uart2_rxbuffer[CONFIG_UART2_RXBUFSIZE]; +#endif +#if IMPLEMENT_SER_UART3 + static unsigned char uart3_txbuffer[CONFIG_UART3_TXBUFSIZE]; + static unsigned char uart3_rxbuffer[CONFIG_UART3_RXBUFSIZE]; +#endif +#if IMPLEMENT_SER_UART4 + static unsigned char uart4_txbuffer[CONFIG_UART4_TXBUFSIZE]; + static unsigned char uart4_rxbuffer[CONFIG_UART4_RXBUFSIZE]; +#endif +#if IMPLEMENT_SER_UART5 + static unsigned char uart5_txbuffer[CONFIG_UART5_TXBUFSIZE]; + static unsigned char uart5_rxbuffer[CONFIG_UART5_RXBUFSIZE]; +#endif +#if IMPLEMENT_SER_UART6 + static unsigned char uart6_txbuffer[CONFIG_UART6_TXBUFSIZE]; + static unsigned char uart6_rxbuffer[CONFIG_UART6_RXBUFSIZE]; +#endif +#if IMPLEMENT_SER_UART7 + static unsigned char uart7_txbuffer[CONFIG_UART7_TXBUFSIZE]; + static unsigned char uart7_rxbuffer[CONFIG_UART7_RXBUFSIZE]; #endif /* @@ -519,8 +537,23 @@ static const struct SerialHardwareVT UART_VT = C99INIT(txSending, tx_sending) }; +/* + * Xmega UARTDesc data structure + * Contains all information required to manage a serial port. + * + * Serial ports are assigned (as far as present on the xmega family) as: + * SER_UART0 -> USARTC0 + * SER_UART1 -> USARTD0 + * SER_UART2 -> USARTE0 + * SER_UART3 -> USARTC1 + * SER_UART4 -> USARTD1 + * SER_UART5 -> USARTE1 + * SER_UART6 -> USARTF0 + * SER_UART7 -> USARTF1 + */ static struct AvrxmegaSerial UARTDescs[SER_CNT] = { +#if IMPLEMENT_SER_UART0 { C99INIT(hw, /**/) { C99INIT(table, &UART_VT), @@ -535,6 +568,8 @@ static struct AvrxmegaSerial UARTDescs[SER_CNT] = C99INIT(txpin, PIN3_bp), C99INIT(rxpin, PIN2_bp), }, +#endif +#if IMPLEMENT_SER_UART1 { C99INIT(hw, /**/) { C99INIT(table, &UART_VT), @@ -549,7 +584,8 @@ static struct AvrxmegaSerial UARTDescs[SER_CNT] = C99INIT(txpin, PIN3_bp), C99INIT(rxpin, PIN2_bp), }, -#ifdef CPU_AVR_XMEGA_A +#endif +#if IMPLEMENT_SER_UART2 { C99INIT(hw, /**/) { C99INIT(table, &UART_VT), @@ -559,11 +595,13 @@ static struct AvrxmegaSerial UARTDescs[SER_CNT] = C99INIT(rxbuffer_size, sizeof(uart2_rxbuffer)), }, C99INIT(sending, false), - C99INIT(usart, &USARTC1), - C99INIT(port, &PORTC), - C99INIT(txpin, PIN7_bp), - C99INIT(rxpin, PIN6_bp), + C99INIT(usart, &USARTE0), + C99INIT(port, &PORTE), + C99INIT(txpin, PIN3_bp), + C99INIT(rxpin, PIN2_bp), }, +#endif +#if IMPLEMENT_SER_UART3 { C99INIT(hw, /**/) { C99INIT(table, &UART_VT), @@ -573,11 +611,13 @@ static struct AvrxmegaSerial UARTDescs[SER_CNT] = C99INIT(rxbuffer_size, sizeof(uart3_rxbuffer)), }, C99INIT(sending, false), - C99INIT(usart, &USARTD1), - C99INIT(port, &PORTD), + C99INIT(usart, &USARTC1), + C99INIT(port, &PORTC), C99INIT(txpin, PIN7_bp), C99INIT(rxpin, PIN6_bp), }, +#endif +#if IMPLEMENT_SER_UART4 { C99INIT(hw, /**/) { C99INIT(table, &UART_VT), @@ -587,12 +627,60 @@ static struct AvrxmegaSerial UARTDescs[SER_CNT] = C99INIT(rxbuffer_size, sizeof(uart4_rxbuffer)), }, C99INIT(sending, false), - C99INIT(usart, &USARTE0), + C99INIT(usart, &USARTD1), + C99INIT(port, &PORTD), + C99INIT(txpin, PIN7_bp), + C99INIT(rxpin, PIN6_bp), + }, +#endif +#if IMPLEMENT_SER_UART5 + { + C99INIT(hw, /**/) { + C99INIT(table, &UART_VT), + C99INIT(txbuffer, uart5_txbuffer), + C99INIT(rxbuffer, uart5_rxbuffer), + C99INIT(txbuffer_size, sizeof(uart5_txbuffer)), + C99INIT(rxbuffer_size, sizeof(uart5_rxbuffer)), + }, + C99INIT(sending, false), + C99INIT(usart, &USARTE1), C99INIT(port, &PORTE), + C99INIT(txpin, PIN7_bp), + C99INIT(rxpin, PIN6_bp), + }, +#endif +#if IMPLEMENT_SER_UART6 + { + C99INIT(hw, /**/) { + C99INIT(table, &UART_VT), + C99INIT(txbuffer, uart6_txbuffer), + C99INIT(rxbuffer, uart6_rxbuffer), + C99INIT(txbuffer_size, sizeof(uart6_txbuffer)), + C99INIT(rxbuffer_size, sizeof(uart6_rxbuffer)), + }, + C99INIT(sending, false), + C99INIT(usart, &USARTF0), + C99INIT(port, &PORTF), C99INIT(txpin, PIN3_bp), C99INIT(rxpin, PIN2_bp), }, -#endif //CPU_AVR_XMEGA_A +#endif +#if IMPLEMENT_SER_UART7 + { + C99INIT(hw, /**/) { + C99INIT(table, &UART_VT), + C99INIT(txbuffer, uart7_txbuffer), + C99INIT(rxbuffer, uart7_rxbuffer), + C99INIT(txbuffer_size, sizeof(uart7_txbuffer)), + C99INIT(rxbuffer_size, sizeof(uart7_rxbuffer)), + }, + C99INIT(sending, false), + C99INIT(usart, &USARTF1), + C99INIT(port, &PORTF), + C99INIT(txpin, PIN7_bp), + C99INIT(rxpin, PIN6_bp), + } +#endif }; struct SerialHardware *ser_hw_getdesc(int unit) @@ -630,61 +718,6 @@ DECLARE_ISR(_vector) \ usart_handleDreInterrupt( _usart ); \ } -USART_DRE_INTERRUPT_VECTOR(USARTC0_DRE_vect, SER_UART0) -USART_DRE_INTERRUPT_VECTOR(USARTD0_DRE_vect, SER_UART1) -#ifdef CPU_AVR_XMEGA_A - USART_DRE_INTERRUPT_VECTOR(USARTC1_DRE_vect, SER_UART2) - USART_DRE_INTERRUPT_VECTOR(USARTD1_DRE_VECT, SER_UART3) - USART_DRE_INTERRUPT_VECTOR(USARTE0_DRE_vect, SER_UART4) -#endif - -#ifdef SER_UART_BUS_TXOFF - static inline void USART_handleTXCInterrupt(uint8_t usartNumber) - { - SER_STROBE_ON; - struct FIFOBuffer * const txfifo = &ser_handles[usartNumber]->txfifo; - if (fifo_isempty(txfifo)) - { - SER_UART_BUS_TXOFF(UARTDescs[usartNumber].usart); - UARTDescs[usartNumber].sending = false; - } - else - { - SER_UART_BUS_TXBEGIN(UARTDescs[usartNumber].usart); - } - SER_STROBE_OFF; - } - - /* - * Serial port 0 TX complete interrupt handler. - * - * This IRQ is usually disabled. The UDR-empty interrupt - * enables it when there's no more data to transmit. - * We need to wait until the last character has been - * transmitted before switching the 485 transceiver to - * receive mode. - * - * The txfifo might have been refilled by putchar() while - * we were waiting for the transmission complete interrupt. - * In this case, we must restart the UDR empty interrupt, - * otherwise we'd stop the serial port with some data - * still pending in the buffer. - */ - #define USART_TXC_INTERRUPT_VECTOR(_vector, _usart) \ - DECLARE_ISR(_vector) \ - { \ - USART_handleTXCInterrupt( _usart ); \ - } - - USART_TXC_INTERRUPT_VECTOR(USARTC0_TXC_vect, SER_UART0) - USART_TXC_INTERRUPT_VECTOR(USARTD0_TXC_vect, SER_UART1) - #ifdef CPU_AVR_XMEGA_A - USART_TXC_INTERRUPT_VECTOR(USARTC1_TXC_vect, SER_UART2) - USART_TXC_INTERRUPT_VECTOR(USARTD1_TXC_vect, SER_UART3) - USART_TXC_INTERRUPT_VECTOR(USARTE0_TXC_vect, SER_UART4) - #endif /* CPU_AVR_XMEGA_A */ -#endif /* SER_UART_BUS_TXOFF */ - /* * Serial RX complete interrupt handler. * @@ -727,10 +760,100 @@ DECLARE_ISR(_vector) \ { \ USART_handleRXCInterrupt( _usart ); \ } -USART_RXC_INTERRUPT_VECTOR(USARTC0_RXC_vect, SER_UART0) -USART_RXC_INTERRUPT_VECTOR(USARTD0_RXC_vect, SER_UART1) -#ifdef CPU_AVR_XMEGA_A - USART_RXC_INTERRUPT_VECTOR(USARTC1_RXC_vect, SER_UART2) - USART_RXC_INTERRUPT_VECTOR(USARTD1_RXC_vect, SER_UART3) - USART_RXC_INTERRUPT_VECTOR(USARTE0_RXC_vect, SER_UART4) + +#if IMPLEMENT_SER_UART0 + USART_DRE_INTERRUPT_VECTOR(USARTC0_DRE_vect, SER_UART0) + USART_RXC_INTERRUPT_VECTOR(USARTC0_RXC_vect, SER_UART0) +#endif +#if IMPLEMENT_SER_UART1 + USART_DRE_INTERRUPT_VECTOR(USARTD0_DRE_vect, SER_UART1) + USART_RXC_INTERRUPT_VECTOR(USARTD0_RXC_vect, SER_UART1) +#endif +#if IMPLEMENT_SER_UART2 + USART_DRE_INTERRUPT_VECTOR(USARTE0_DRE_vect, SER_UART2) + USART_RXC_INTERRUPT_VECTOR(USARTE0_RXC_vect, SER_UART2) +#endif +#if IMPLEMENT_SER_UART3 + USART_DRE_INTERRUPT_VECTOR(USARTC1_DRE_vect, SER_UART3) + USART_RXC_INTERRUPT_VECTOR(USARTC1_RXC_vect, SER_UART3) #endif +#if IMPLEMENT_SER_UART4 + USART_DRE_INTERRUPT_VECTOR(USARTD1_DRE_vect, SER_UART4) + USART_RXC_INTERRUPT_VECTOR(USARTD1_RXC_vect, SER_UART4) +#endif +#if IMPLEMENT_SER_UART5 + USART_DRE_INTERRUPT_VECTOR(USARTE1_DRE_vect, SER_UART5) + USART_RXC_INTERRUPT_VECTOR(USARTE1_RXC_vect, SER_UART5) +#endif +#if IMPLEMENT_SER_UART6 + USART_DRE_INTERRUPT_VECTOR(USARTF0_DRE_vect, SER_UART6) + USART_RXC_INTERRUPT_VECTOR(USARTF0_RXC_vect, SER_UART6) +#endif +#if IMPLEMENT_SER_UART7 + USART_DRE_INTERRUPT_VECTOR(USARTF1_DRE_vect, SER_UART7) + USART_RXC_INTERRUPT_VECTOR(USARTF1_RXC_vect, SER_UART7) +#endif + +#ifdef SER_UART_BUS_TXOFF + static inline void USART_handleTXCInterrupt(uint8_t usartNumber) + { + SER_STROBE_ON; + struct FIFOBuffer * const txfifo = &ser_handles[usartNumber]->txfifo; + if (fifo_isempty(txfifo)) + { + SER_UART_BUS_TXOFF(UARTDescs[usartNumber].usart); + UARTDescs[usartNumber].sending = false; + } + else + { + SER_UART_BUS_TXBEGIN(UARTDescs[usartNumber].usart); + } + SER_STROBE_OFF; + } + + /* + * Serial port 0 TX complete interrupt handler. + * + * This IRQ is usually disabled. The UDR-empty interrupt + * enables it when there's no more data to transmit. + * We need to wait until the last character has been + * transmitted before switching the 485 transceiver to + * receive mode. + * + * The txfifo might have been refilled by putchar() while + * we were waiting for the transmission complete interrupt. + * In this case, we must restart the UDR empty interrupt, + * otherwise we'd stop the serial port with some data + * still pending in the buffer. + */ + #define USART_TXC_INTERRUPT_VECTOR(_vector, _usart) \ + DECLARE_ISR(_vector) \ + { \ + USART_handleTXCInterrupt( _usart ); \ + } + + #if IMPLEMENT_SER_UART0 + USART_TXC_INTERRUPT_VECTOR(USARTC0_TXC_vect, SER_UART0) + #endif + #if IMPLEMENT_SER_UART1 + USART_TXC_INTERRUPT_VECTOR(USARTD0_TXC_vect, SER_UART1) + #endif + #if IMPLEMENT_SER_UART2 + USART_TXC_INTERRUPT_VECTOR(USARTE0_TXC_vect, SER_UART2) + #endif + #if IMPLEMENT_SER_UART3 + USART_TXC_INTERRUPT_VECTOR(USARTC1_TXC_vect, SER_UART3) + #endif + #if IMPLEMENT_SER_UART4 + USART_TXC_INTERRUPT_VECTOR(USARTD1_TXC_vect, SER_UART4) + #endif + #if IMPLEMENT_SER_UART5 + USART_TXC_INTERRUPT_VECTOR(USARTE1_TXC_vect, SER_UART5) + #endif + #if IMPLEMENT_SER_UART6 + USART_TXC_INTERRUPT_VECTOR(USARTF0_TXC_vect, SER_UART6) + #endif + #if IMPLEMENT_SER_UART7 + USART_TXC_INTERRUPT_VECTOR(USARTF1_TXC_vect, SER_UART7) + #endif +#endif /* SER_UART_BUS_TXOFF */ diff --git a/bertos/cpu/avr/drv/ser_xmega.h b/bertos/cpu/avr/drv/ser_xmega.h index cad8b1e9..3dc58fc8 100644 --- a/bertos/cpu/avr/drv/ser_xmega.h +++ b/bertos/cpu/avr/drv/ser_xmega.h @@ -46,6 +46,7 @@ #include /* BV() */ #include /* uint8_t */ +#include "cfg/cfg_ser.h" /* Serialport configuration settings */ typedef uint8_t serstatus_t; @@ -64,21 +65,100 @@ typedef uint8_t serstatus_t; #define SERRF_NOISEERROR 0 /**< Unsupported */ /* + * XMEGA_D4 has 2 serial ports + * XMEGA_D3 has 3 serial ports + * XMEGA_A4 has 5 serial ports + * XMEGA_A3 has 7 serial ports + * XMEGA_A1 has 8 serial ports + * + * These serial ports can be enabled or disabled in the cfg_ser.h file + * Generate definitions whether a serial port needs to be implementend by + * the driver, depending on the type of XMega and the settings in cfg_ser.h + */ +#if CONFIG_UART0_ENABLED + #define IMPLEMENT_SER_UART0 1 +#else + #define IMPLEMENT_SER_UART0 0 +#endif +#if CONFIG_UART1_ENABLED + #define IMPLEMENT_SER_UART1 1 +#else + #define IMPLEMENT_SER_UART1 0 +#endif +#if (CPU_AVR_XMEGA_D3 || CPU_AVR_XMEGA_A4 || CPU_AVR_XMEGA_A3 || CPU_AVR_XMEGA_A1) && CONFIG_UART2_ENABLED + #define IMPLEMENT_SER_UART2 1 +#else + #define IMPLEMENT_SER_UART2 0 +#endif +#if CPU_AVR_XMEGA_A4 || CPU_AVR_XMEGA_A3 || CPU_AVR_XMEGA_A1 + #if CONFIG_UART3_ENABLED + #define IMPLEMENT_SER_UART3 1 + #else + #define IMPLEMENT_SER_UART3 0 + #endif + #if CONFIG_UART4_ENABLED + #define IMPLEMENT_SER_UART4 1 + #else + #define IMPLEMENT_SER_UART4 0 + #endif +#else + #define IMPLEMENT_SER_UART3 0 + #define IMPLEMENT_SER_UART4 0 +#endif +#if CPU_AVR_XMEGA_A3 || CPU_AVR_XMEGA_A1 + #if CONFIG_UART5_ENABLED + #define IMPLEMENT_SER_UART5 1 + #else + #define IMPLEMENT_SER_UART5 0 + #endif + #if CONFIG_UART6_ENABLED + #define IMPLEMENT_SER_UART6 1 + #else + #define IMPLEMENT_SER_UART6 0 + #endif +#else + #define IMPLEMENT_SER_UART5 0 + #define IMPLEMENT_SER_UART6 0 +#endif +#if CPU_AVR_XMEGA_A1 && CONFIG_UART7_ENABLED + #define IMPLEMENT_SER_UART7 1 +#else + #define IMPLEMENT_SER_UART7 0 +#endif + +/* + * * \name Serial hw numbers * * \{ */ enum { +#if IMPLEMENT_SER_UART0 SER_UART0, +#endif +#if IMPLEMENT_SER_UART1 SER_UART1, -#ifdef CPU_AVR_XMEGA_A - //the XMEGA A Family have 5 USART ports +#endif +#if IMPLEMENT_SER_UART2 SER_UART2, +#endif +#if IMPLEMENT_SER_UART3 SER_UART3, +#endif +#if IMPLEMENT_SER_UART4 SER_UART4, #endif - SER_CNT /**< Number of serial ports */ +#if IMPLEMENT_SER_UART5 + SER_UART5, +#endif +#if IMPLEMENT_SER_UART6 + SER_UART6, +#endif +#if IMPLEMENT_SER_UART7 + SER_UART7, +#endif + SER_CNT /**< Number of serial ports implemented*/ }; /*\}*/ diff --git a/bertos/cpu/avr/drv/timer_xmega.h b/bertos/cpu/avr/drv/timer_xmega.h index 092cb4c4..a451b4af 100644 --- a/bertos/cpu/avr/drv/timer_xmega.h +++ b/bertos/cpu/avr/drv/timer_xmega.h @@ -54,19 +54,35 @@ #include #include -/* +/** * \name Values for CONFIG_TIMER. * * Select which hardware timer interrupt to use for system clock and softtimers. - * $WIZ$ timer_select = "TIMER_USE_TCC0", "TIMER_USE_TCC1", "TIMER_USE_TCD0", "TIMER_USE_TCE0", "TIMER_USE_TCD1", "TIMER_DEFAULT" + * $WIZ$ timer_select = "TIMER_USE_TCC0", "TIMER_USE_TCC1", "TIMER_USE_TCD0", "TIMER_USE_TCE0", "TIMER_USE_TCD1", "TIMER_USE_TCF0", "TIMER_USE_TCE1", "TIMER_USE_TCF1", "TIMER_DEFAULT" */ #define TIMER_USE_TCC0 1 #define TIMER_USE_TCC1 2 #define TIMER_USE_TCD0 3 #define TIMER_USE_TCE0 4 -// The XMEGA A Family has one extra timer -#ifdef CPU_AVR_XMEGA_A - #define TIMER_USE_TCD1 5 +#if CPU_AVR_XMEGA_A4 || CPU_AVR_XMEGA_A3 || CPU_AVR_XMEGA_A1 + #define TIMER_USE_TCD1 5 +#else + #define TIMER_USE_TCD1 0 +#endif +#if CPU_AVR_XMEGA_D3 || CPU_AVR_XMEGA_A3 || CPU_AVR_XMEGA_A1 + #define TIMER_USE_TCF0 6 +#else + #define TIMER_USE_TCF0 0 +#endif +#if CPU_AVR_XMEGA_A3 || CPU_AVR_XMEGA_A1 + #define TIMER_USE_TCE1 7 +#else + #define TIMER_USE_TCE1 0 +#endif +#if CPU_AVR_XMEGA_A1 + #define TIMER_USE_TCF1 8 +#else + #define TIMER_USE_TCF1 0 #endif #define TIMER_DEFAULT TIMER_USE_TCC1 ///< Default system timer @@ -83,12 +99,21 @@ #elif (CONFIG_TIMER == TIMER_USE_TCD0) #define TIMER_OVF_VECT TCD0_OVF_vect #define TIMERCOUNTER TCD0 -#elif (CONFIG_TIMER == TIMER_USE_TCE0) - #define TIMER_OVF_VECT TCE0_OVF_vect - #define TIMERCOUNTER TCE0 #elif (CONFIG_TIMER == TIMER_USE_TCD1) #define TIMER_OVF_VECT TCD1_OVF_vect #define TIMERCOUNTER TCD1 +#elif (CONFIG_TIMER == TIMER_USE_TCE0) + #define TIMER_OVF_VECT TCE0_OVF_vect + #define TIMERCOUNTER TCE0 +#elif (CONFIG_TIMER == TIMER_USE_TCE1) + #define TIMER_OVF_VECT TCE1_OVF_vect + #define TIMERCOUNTER TCE1 +#elif (CONFIG_TIMER == TIMER_USE_TCF0) + #define TIMER_OVF_VECT TCF0_OVF_vect + #define TIMERCOUNTER TCF0 +#elif (CONFIG_TIMER == TIMER_USE_TCF1) + #define TIMER_OVF_VECT TCF1_OVF_vect + #define TIMERCOUNTER TCF1 #else #error Unimplemented value for CONFIG_TIMER #endif /* CONFIG_TIMER */ diff --git a/bertos/cpu/avr/info/ATxmega32D4.cdef b/bertos/cpu/avr/info/ATxmega32D4.cdef index 82077cec..6d93446a 100644 --- a/bertos/cpu/avr/info/ATxmega32D4.cdef +++ b/bertos/cpu/avr/info/ATxmega32D4.cdef @@ -50,8 +50,7 @@ CPU_DESC += [ "32 Kbyte in-System Programmable Flash", # If we use the GCC compiler we should pass some flags. CORE_CPU = "atxmega32d4" - -# Special CPU related tags. -CPU_TAGS += ["xmega32d"] +# add a family tag for the wizard +CPU_TAGS += ["xmegad4"] include("avr_post.common") diff --git a/bertos/cpu/detect.h b/bertos/cpu/detect.h index 8dce9b8f..815e663d 100644 --- a/bertos/cpu/detect.h +++ b/bertos/cpu/detect.h @@ -498,9 +498,52 @@ #define CPU_AVR_ATMEGA2560 0 #endif + #if defined(__AVR_ATxmega128A1__) + #define CPU_AVR_XMEGA 1 + #define CPU_AVR_XMEGA_D4 0 + #define CPU_AVR_XMEGA_D3 0 + #define CPU_AVR_XMEGA_A4 0 + #define CPU_AVR_XMEGA_A3 0 + #define CPU_AVR_XMEGA_A1 1 + #define CPU_AVR_ATXMEGA128A1 1 + #define CPU_NAME "ATxmega128a1" + #else + #define CPU_AVR_ATXMEGA128A1 0 + #endif + + #if defined(__AVR_ATxmega64A3__) + #define CPU_AVR_XMEGA 1 + #define CPU_AVR_XMEGA_D4 0 + #define CPU_AVR_XMEGA_D3 0 + #define CPU_AVR_XMEGA_A4 0 + #define CPU_AVR_XMEGA_A3 1 + #define CPU_AVR_XMEGA_A1 0 + #define CPU_AVR_ATXMEGA64A3 1 + #define CPU_NAME "ATxmega64a3" + #else + #define CPU_AVR_ATXMEGA64A3 0 + #endif + + #if defined(__AVR_ATxmega32A4__) + #define CPU_AVR_XMEGA 1 + #define CPU_AVR_XMEGA_D4 0 + #define CPU_AVR_XMEGA_D3 0 + #define CPU_AVR_XMEGA_A4 1 + #define CPU_AVR_XMEGA_A3 0 + #define CPU_AVR_XMEGA_A1 0 + #define CPU_AVR_ATXMEGA32A4 1 + #define CPU_NAME "ATxmega32a4" + #else + #define CPU_AVR_ATXMEGA32A4 0 + #endif + #if defined(__AVR_ATxmega32D4__) #define CPU_AVR_XMEGA 1 - #define CPU_AVR_XMEGA_D 1 + #define CPU_AVR_XMEGA_D4 1 + #define CPU_AVR_XMEGA_D3 0 + #define CPU_AVR_XMEGA_A4 0 + #define CPU_AVR_XMEGA_A3 0 + #define CPU_AVR_XMEGA_A1 0 #define CPU_AVR_ATXMEGA32D4 1 #define CPU_NAME "ATxmega32d4" #else @@ -509,7 +552,8 @@ #if CPU_AVR_ATMEGA32 + CPU_AVR_ATMEGA64 + CPU_AVR_ATMEGA103 + CPU_AVR_ATMEGA128 \ + CPU_AVR_ATMEGA8 + CPU_AVR_ATMEGA168 + CPU_AVR_ATMEGA328P + CPU_AVR_ATMEGA1281 \ - + CPU_AVR_ATMEGA1280 + CPU_AVR_ATMEGA2560 + CPU_AVR_ATXMEGA32D4 != 1 + + CPU_AVR_ATMEGA1280 + CPU_AVR_ATMEGA2560 + CPU_AVR_ATXMEGA128A1 + CPU_AVR_ATXMEGA64A3 \ + + CPU_AVR_ATXMEGA32A4 + CPU_AVR_ATXMEGA32D4 != 1 #error AVR CPU configuration error #endif @@ -517,9 +561,17 @@ #error CPU cannot be MEGA and XMEGA #elif defined(CPU_AVR_MEGA) #define CPU_AVR_XMEGA 0 - #define CPU_AVR_XMEGA_D 0 + #define CPU_AVR_XMEGA_D4 0 + #define CPU_AVR_XMEGA_D3 0 + #define CPU_AVR_XMEGA_A4 0 + #define CPU_AVR_XMEGA_A3 0 + #define CPU_AVR_XMEGA_A1 0 #elif defined(CPU_AVR_XMEGA) #define CPU_AVR_MEGA 0 + #if CPU_AVR_XMEGA_D4 + CPU_AVR_XMEGA_D3 + CPU_AVR_XMEGA_A4 \ + + CPU_AVR_XMEGA_A3 + CPU_AVR_XMEGA_A1 != 1 + #error AVR XMEGA CPU Configuration error + #endif #endif #if CPU_AVR_MEGA + CPU_AVR_XMEGA != 1 @@ -540,7 +592,15 @@ #define CPU_AVR_ATMEGA1280 0 #define CPU_AVR_ATMEGA2560 0 #define CPU_AVR_XMEGA 0 - #define CPU_AVR_XMEGA_D 0 + #define CPU_AVR_XMEGA_D4 0 + #define CPU_AVR_XMEGA_D3 0 + #define CPU_AVR_XMEGA_A4 0 + #define CPU_AVR_XMEGA_A3 0 + #define CPU_AVR_XMEGA_A1 0 + #define CPU_AVR_ATXMEGA128A1 0 + #define CPU_AVR_ATXMEGA64A3 0 + #define CPU_AVR_XTMEGA32A4 0 + #define CPU_AVR_ATXMEGA32D4 0 #endif #if defined (__MSP430__)