]> git.sur5r.net Git - freertos/blobdiff - Demo/AVR32_UC3/serial/serial.c
Start to re-arrange files to include FreeRTOS+ in main download.
[freertos] / Demo / AVR32_UC3 / serial / serial.c
index 7a7ea02ba4740ec7c15a1c2c0714f4f4eee5504b..83eb4023f408d26418b383f6daf434953bab5c62 100644 (file)
@@ -1,5 +1,3 @@
-/* This source file is part of the ATMEL FREERTOS-0.9.0 Release */\r
-\r
 /*This file has been prepared for Doxygen automatic documentation generation.*/\r
 /*! \file *********************************************************************\r
  *\r
@@ -10,7 +8,7 @@
  * - AppNote:\r
  *\r
  * \author               Atmel Corporation: http://www.atmel.com \n\r
- *                       Support email: avr32@atmel.com\r
+ *                       Support and FAQ: http://support.atmel.no/\r
  *\r
  *****************************************************************************/\r
 \r
@@ -43,7 +41,7 @@
 \r
 \r
 /*\r
-  BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR USART0.\r
+  BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR USART.\r
 */\r
 \r
 /* Scheduler includes. */\r
 \r
 /* Demo application includes. */\r
 #include "serial.h"\r
-\r
-#if __GNUC__\r
-       #include <avr32/io.h>\r
-#elif __ICCAVR32__\r
-       #include <avr32/iouc3a0512.h>\r
-#else\r
-       #error Unknown compiler\r
-#endif\r
-\r
+#include <avr32/io.h>\r
 #include "board.h"\r
 #include "gpio.h"\r
 \r
@@ -95,17 +85,17 @@ static void vprvSerialCreateQueues( unsigned portBASE_TYPE uxQueueLength,
        #pragma optimize = no_inline\r
 #endif\r
 \r
-static portBASE_TYPE prvUSART0_ISR_NonNakedBehaviour( void )\r
+static portBASE_TYPE prvUSART_ISR_NonNakedBehaviour( void )\r
 {\r
        /* Now we can declare the local variables. */\r
        signed portCHAR     cChar;\r
-       portBASE_TYPE     xTaskWokenByTx = pdFALSE, xTaskWokenByRx = pdFALSE;\r
+       portBASE_TYPE     xHigherPriorityTaskWoken = pdFALSE;\r
        unsigned portLONG     ulStatus;\r
-       volatile avr32_usart_t  *usart0 = &AVR32_USART0;\r
+       volatile avr32_usart_t  *usart = serialPORT_USART;\r
        portBASE_TYPE retstatus;\r
 \r
        /* What caused the interrupt? */\r
-       ulStatus = usart0->csr & usart0->imr;\r
+       ulStatus = usart->csr & usart->imr;\r
 \r
        if (ulStatus & AVR32_USART_CSR_TXRDY_MASK)\r
        {\r
@@ -114,47 +104,42 @@ static portBASE_TYPE prvUSART0_ISR_NonNakedBehaviour( void )
                Because FreeRTOS is not supposed to run with nested interrupts, put all OS\r
                calls in a critical section . */\r
                portENTER_CRITICAL();\r
-                       retstatus = xQueueReceiveFromISR( xCharsForTx, &cChar, &xTaskWokenByTx );\r
+                       retstatus = xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken );\r
                portEXIT_CRITICAL();\r
 \r
                if (retstatus == pdTRUE)\r
                {\r
                        /* A character was retrieved from the queue so can be sent to the\r
                         THR now. */\r
-                       usart0->thr = cChar;\r
+                       usart->thr = cChar;\r
                }\r
                else\r
                {\r
                        /* Queue empty, nothing to send so turn off the Tx interrupt. */\r
-                       usart0->idr = AVR32_USART_IDR_TXRDY_MASK;\r
+                       usart->idr = AVR32_USART_IDR_TXRDY_MASK;\r
                }\r
        }\r
 \r
        if (ulStatus & AVR32_USART_CSR_RXRDY_MASK)\r
        {\r
                /* The interrupt was caused by the receiver getting data. */\r
-               cChar = usart0->rhr; //TODO\r
+               cChar = usart->rhr; //TODO\r
 \r
                /* Because FreeRTOS is not supposed to run with nested interrupts, put all OS\r
                calls in a critical section . */\r
                portENTER_CRITICAL();\r
-                       retstatus = xQueueSendFromISR(xRxedChars, &cChar, pdFALSE);\r
+                       xQueueSendFromISR(xRxedChars, &cChar, &xHigherPriorityTaskWoken);\r
                portEXIT_CRITICAL();\r
-\r
-               if( retstatus )\r
-               {\r
-                       xTaskWokenByRx = pdTRUE;\r
-               }\r
        }\r
 \r
        /* The return value will be used by portEXIT_SWITCHING_ISR() to know if it\r
        should perform a vTaskSwitchContext(). */\r
-       return ( xTaskWokenByTx || xTaskWokenByRx );\r
+       return ( xHigherPriorityTaskWoken );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
- * USART0 interrupt service routine.\r
+ * USART interrupt service routine.\r
  */\r
 #if __GNUC__\r
        __attribute__((__naked__))\r
@@ -162,15 +147,15 @@ static portBASE_TYPE prvUSART0_ISR_NonNakedBehaviour( void )
        #pragma shadow_registers = full   // Naked.\r
 #endif\r
 \r
-static void vUSART0_ISR( void )\r
+static void vUSART_ISR( void )\r
 {\r
        /* This ISR can cause a context switch, so the first statement must be a\r
        call to the portENTER_SWITCHING_ISR() macro.  This must be BEFORE any\r
        variable declarations. */\r
        portENTER_SWITCHING_ISR();\r
-       \r
-       prvUSART0_ISR_NonNakedBehaviour();\r
-       \r
+\r
+       prvUSART_ISR_NonNakedBehaviour();\r
+\r
        /* Exit the ISR.  If a task was woken by either a character being received\r
        or transmitted then a context switch will occur. */\r
        portEXIT_SWITCHING_ISR();\r
@@ -183,14 +168,20 @@ static void vUSART0_ISR( void )
  */\r
 xComPortHandle xSerialPortInitMinimal( unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )\r
 {\r
+static const gpio_map_t USART_GPIO_MAP =\r
+{\r
+       { serialPORT_USART_RX_PIN, serialPORT_USART_RX_FUNCTION },\r
+       { serialPORT_USART_TX_PIN, serialPORT_USART_TX_FUNCTION }\r
+};\r
+\r
 xComPortHandle    xReturn = serHANDLE;\r
-volatile avr32_usart_t  *usart0 = &AVR32_USART0;\r
-int cd; /* USART0 Clock Divider. */\r
+volatile avr32_usart_t  *usart = serialPORT_USART;\r
+int cd; /* USART Clock Divider. */\r
 \r
        /* Create the rx and tx queues. */\r
        vprvSerialCreateQueues( uxQueueLength, &xRxedChars, &xCharsForTx );\r
 \r
-       /* Configure USART0. */\r
+       /* Configure USART. */\r
        if( ( xRxedChars != serINVALID_QUEUE ) &&\r
          ( xCharsForTx != serINVALID_QUEUE ) &&\r
          ( ulWantedBaud != ( unsigned portLONG ) 0 ) )\r
@@ -198,20 +189,20 @@ int cd; /* USART0 Clock Divider. */
                portENTER_CRITICAL();\r
                {\r
                        /**\r
-                       ** Reset USART0.\r
+                       ** Reset USART.\r
                        **/\r
-                       /* Disable all USART0 interrupt sources to begin... */\r
-                       usart0->idr = 0xFFFFFFFF;\r
+                       /* Disable all USART interrupt sources to begin... */\r
+                       usart->idr = 0xFFFFFFFF;\r
 \r
                        /* Reset mode and other registers that could cause unpredictable\r
                         behaviour after reset */\r
-                       usart0->mr = 0; /* Reset Mode register. */\r
-                       usart0->rtor = 0; /* Reset Receiver Time-out register. */\r
-                       usart0->ttgr = 0; /* Reset Transmitter Timeguard register. */\r
+                       usart->mr = 0; /* Reset Mode register. */\r
+                       usart->rtor = 0; /* Reset Receiver Time-out register. */\r
+                       usart->ttgr = 0; /* Reset Transmitter Timeguard register. */\r
 \r
                        /* Shutdown RX and TX, reset status bits, reset iterations in CSR, reset NACK\r
                         and turn off DTR and RTS */\r
-                       usart0->cr = AVR32_USART_CR_RSTRX_MASK   |\r
+                       usart->cr = AVR32_USART_CR_RSTRX_MASK   |\r
                                           AVR32_USART_CR_RSTTX_MASK   |\r
                                           AVR32_USART_CR_RXDIS_MASK   |\r
                                           AVR32_USART_CR_TXDIS_MASK   |\r
@@ -222,13 +213,12 @@ int cd; /* USART0 Clock Divider. */
                                           AVR32_USART_CR_RTSDIS_MASK;\r
 \r
                        /**\r
-                       ** Configure USART0.\r
+                       ** Configure USART.\r
                        **/\r
-                       /* Enable USART0 RXD & TXD pins. */\r
-                       gpio_enable_module_pin(AVR32_USART0_RXD_0_PIN, AVR32_USART0_RXD_0_FUNCTION);\r
-                       gpio_enable_module_pin(AVR32_USART0_TXD_0_PIN, AVR32_USART0_TXD_0_FUNCTION);\r
+                       /* Enable USART RXD & TXD pins. */\r
+                       gpio_enable_module( USART_GPIO_MAP, sizeof( USART_GPIO_MAP ) / sizeof( USART_GPIO_MAP[0] ) );\r
 \r
-                       /* Set the USART0 baudrate to be as close as possible to the wanted baudrate. */\r
+                       /* Set the USART baudrate to be as close as possible to the wanted baudrate. */\r
                        /*\r
                        *             ** BAUDRATE CALCULATION **\r
                        *\r
@@ -242,52 +232,52 @@ int cd; /* USART0 Clock Divider. */
                        if( ulWantedBaud < ( configCPU_CLOCK_HZ / 16 ) )\r
                        {\r
                                /* Use 8x oversampling */\r
-                               usart0->mr |= (1<<AVR32_USART_MR_OVER_OFFSET);\r
+                               usart->mr |= (1<<AVR32_USART_MR_OVER_OFFSET);\r
                                cd = configCPU_CLOCK_HZ / (8*ulWantedBaud);\r
 \r
-                               if( cd < 2 ) \r
+                               if( cd < 2 )\r
                                {\r
                                        return serINVALID_COMPORT_HANDLER;\r
                                }\r
 \r
-                               usart0->brgr = (cd << AVR32_USART_BRGR_CD_OFFSET);\r
-                       } \r
-                       else \r
+                               usart->brgr = (cd << AVR32_USART_BRGR_CD_OFFSET);\r
+                       }\r
+                       else\r
                        {\r
                                /* Use 16x oversampling */\r
-                               usart0->mr &= ~(1<<AVR32_USART_MR_OVER_OFFSET);\r
+                               usart->mr &= ~(1<<AVR32_USART_MR_OVER_OFFSET);\r
                                cd = configCPU_CLOCK_HZ / (16*ulWantedBaud);\r
 \r
-                               if( cd > 65535 ) \r
+                               if( cd > 65535 )\r
                                {\r
                                        /* Baudrate is too low */\r
                                        return serINVALID_COMPORT_HANDLER;\r
                                }\r
                        }\r
 \r
-                       usart0->brgr = (cd << AVR32_USART_BRGR_CD_OFFSET);\r
+                       usart->brgr = (cd << AVR32_USART_BRGR_CD_OFFSET);\r
 \r
-                       /* Set the USART0 Mode register: Mode=Normal(0), Clk selection=MCK(0),\r
+                       /* Set the USART Mode register: Mode=Normal(0), Clk selection=MCK(0),\r
                        CHRL=8,  SYNC=0(asynchronous), PAR=None, NBSTOP=1, CHMODE=0, MSBF=0,\r
                        MODE9=0, CKLO=0, OVER(previously done when setting the baudrate),\r
                        other fields not used in this mode. */\r
-                       usart0->mr |= ((8-5) << AVR32_USART_MR_CHRL_OFFSET  ) |\r
+                       usart->mr |= ((8-5) << AVR32_USART_MR_CHRL_OFFSET  ) |\r
                                        (   4  << AVR32_USART_MR_PAR_OFFSET   ) |\r
                                        (   1  << AVR32_USART_MR_NBSTOP_OFFSET);\r
 \r
                        /* Write the Transmit Timeguard Register */\r
-                       usart0->ttgr = 0;\r
+                       usart->ttgr = 0;\r
+\r
 \r
-                       \r
-                       /* Register the USART0 interrupt handler to the interrupt controller and\r
-                        enable the USART0 interrupt. */\r
-                       INTC_register_interrupt((__int_handler)&vUSART0_ISR, AVR32_USART0_IRQ, INT1);\r
+                       /* Register the USART interrupt handler to the interrupt controller and\r
+                        enable the USART interrupt. */\r
+                       INTC_register_interrupt((__int_handler)&vUSART_ISR, serialPORT_USART_IRQ, INT1);\r
 \r
-                       /* Enable USART0 interrupt sources (but not Tx for now)... */\r
-                       usart0->ier = AVR32_USART_IER_RXRDY_MASK;\r
+                       /* Enable USART interrupt sources (but not Tx for now)... */\r
+                       usart->ier = AVR32_USART_IER_RXRDY_MASK;\r
 \r
                        /* Enable receiver and transmitter... */\r
-                       usart0->cr |= AVR32_USART_CR_TXEN_MASK | AVR32_USART_CR_RXEN_MASK;\r
+                       usart->cr |= AVR32_USART_CR_TXEN_MASK | AVR32_USART_CR_RXEN_MASK;\r
                }\r
                portEXIT_CRITICAL();\r
        }\r
@@ -340,7 +330,7 @@ signed portCHAR *pxNext;
 \r
 signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed portCHAR cOutChar, portTickType xBlockTime )\r
 {\r
-volatile avr32_usart_t  *usart0 = &AVR32_USART0;\r
+volatile avr32_usart_t  *usart = serialPORT_USART;\r
 \r
        /* Place the character in the queue of characters to be transmitted. */\r
        if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )\r
@@ -352,7 +342,7 @@ volatile avr32_usart_t  *usart0 = &AVR32_USART0;
        queue and send it.   This does not need to be in a critical section as\r
        if the interrupt has already removed the character the next interrupt\r
        will simply turn off the Tx interrupt again. */\r
-       usart0->ier = (1 << AVR32_USART_IER_TXRDY_OFFSET);\r
+       usart->ier = (1 << AVR32_USART_IER_TXRDY_OFFSET);\r
 \r
        return pdPASS;\r
 }\r