]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/CORTEX_M4F_MSP432_LaunchPad_IAR_CCS_Keil/Full_Demo/serial.c
Final V8.2.1 release ready for tagging:
[freertos] / FreeRTOS / Demo / CORTEX_M4F_MSP432_LaunchPad_IAR_CCS_Keil / Full_Demo / serial.c
diff --git a/FreeRTOS/Demo/CORTEX_M4F_MSP432_LaunchPad_IAR_CCS_Keil/Full_Demo/serial.c b/FreeRTOS/Demo/CORTEX_M4F_MSP432_LaunchPad_IAR_CCS_Keil/Full_Demo/serial.c
new file mode 100644 (file)
index 0000000..9dd99f3
--- /dev/null
@@ -0,0 +1,307 @@
+/*\r
+    FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+    All rights reserved\r
+\r
+    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify it under\r
+    the terms of the GNU General Public License (version 2) as published by the\r
+    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+    ***************************************************************************\r
+    >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
+    >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
+    >>!   obliged to provide the source code for proprietary components     !<<\r
+    >>!   outside of the FreeRTOS kernel.                                   !<<\r
+    ***************************************************************************\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+    FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
+    link: http://www.freertos.org/a00114.html\r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS provides completely free yet professionally developed,    *\r
+     *    robust, strictly quality controlled, supported, and cross          *\r
+     *    platform software that is more than just the market leader, it     *\r
+     *    is the industry's de facto standard.                               *\r
+     *                                                                       *\r
+     *    Help yourself get started quickly while simultaneously helping     *\r
+     *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
+     *    tutorial book, reference manual, or both:                          *\r
+     *    http://www.FreeRTOS.org/Documentation                              *\r
+     *                                                                       *\r
+    ***************************************************************************\r
+\r
+    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
+    the FAQ page "My application does not run, what could be wrong?".  Have you\r
+    defined configASSERT()?\r
+\r
+    http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+    embedded software for free we request you assist our global community by\r
+    participating in the support forum.\r
+\r
+    http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+    be as productive as possible as early as possible.  Now you can receive\r
+    FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+    Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+    including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+    compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
+    licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+    engineered and independently SIL3 certified version for use in safety and\r
+    mission critical applications that require provable dependability.\r
+\r
+    1 tab == 4 spaces!\r
+*/\r
+\r
+/*\r
+       BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER.\r
+\r
+       Note1:  This driver is used specifically to provide an interface to the\r
+       FreeRTOS+CLI command interpreter.  It is *not* intended to be a generic\r
+       serial port driver.  Nor is it intended to be used as an example of an\r
+       efficient implementation.  In particular, a queue is used to buffer\r
+       received characters, which is fine in this case as key presses arrive\r
+       slowly, but a DMA and/or RAM buffer should be used in place of the queue in\r
+       applications that expect higher throughput.\r
+\r
+       Note2:  This driver does not attempt to handle UART errors.\r
+*/\r
+\r
+/* Scheduler includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+#include "semphr.h"\r
+\r
+/* Demo application includes. */\r
+#include "serial.h"\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * The UART interrupt handler.\r
+ */\r
+void vUART_Handler( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The queue into which received key presses are placed.  NOTE THE COMMENTS AT\r
+THE TOP OF THIS FILE REGARDING THE USE OF QUEUES FOR THIS PURPOSE. */\r
+static QueueHandle_t xRxQueue = NULL;\r
+\r
+/* Variables used in the Tx interrupt to send a string. */\r
+static volatile const signed char *pcStringStart = NULL, *pcStringEnd = NULL;\r
+static volatile TaskHandle_t xTransmittingTask = NULL;\r
+\r
+static EUSCI_A0_Type * const pxUARTA0 = ( EUSCI_A0_Type * ) EUSCI_A0_MODULE;\r
+\r
+/* UART Configuration for 19200 baud.  Value generated using the tool provided\r
+on the following page:\r
+http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html\r
+ */\r
+const eUSCI_UART_Config xUARTConfig =\r
+{\r
+       EUSCI_A_UART_CLOCKSOURCE_SMCLK, /* SMCLK Clock Source. */\r
+       156,                                                    /* BRDIV */\r
+       4,                                                              /* UCxBRF */\r
+       0,                                                              /* UCxBRS */\r
+       EUSCI_A_UART_NO_PARITY,                 /* No Parity. */\r
+       EUSCI_A_UART_LSB_FIRST,                 /* MSB First. */\r
+       EUSCI_A_UART_ONE_STOP_BIT,              /* One stop bit. */\r
+       EUSCI_A_UART_MODE,                              /* UART mode. */\r
+       EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION /* Low Frequency Mode. */\r
+};\r
+\r
+/*\r
+ * See the serial2.h header file.\r
+ */\r
+xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned long uxQueueLength )\r
+{\r
+       /* Create the queue used to hold received characters.  NOTE THE COMMENTS AT\r
+       THE TOP OF THIS FILE REGARDING THE USE OF QUEUES FOR THIS PURPSOE. */\r
+       xRxQueue = xQueueCreate( uxQueueLength, sizeof( char ) );\r
+       configASSERT( xRxQueue );\r
+\r
+       /* Use the library functions to initialise and enable the UART. */\r
+       MAP_UART_initModule( EUSCI_A0_MODULE, &xUARTConfig );\r
+       MAP_UART_enableModule( EUSCI_A0_MODULE );\r
+       MAP_UART_clearInterruptFlag( EUSCI_A0_MODULE, EUSCI_A_UART_RECEIVE_INTERRUPT | EUSCI_A_UART_TRANSMIT_INTERRUPT );\r
+       MAP_UART_enableInterrupt( EUSCI_A0_MODULE, EUSCI_A_UART_RECEIVE_INTERRUPT );\r
+\r
+       /* The interrupt handler uses the FreeRTOS API function so its priority must\r
+       be at or below the configured maximum system call interrupt priority.\r
+       configKERNEL_INTERRUPT_PRIORITY is the priority used by the RTOS tick and\r
+       (should) always be set to the minimum priority. */\r
+       MAP_Interrupt_setPriority( INT_EUSCIA0, configKERNEL_INTERRUPT_PRIORITY );\r
+       MAP_Interrupt_enableInterrupt( INT_EUSCIA0 );\r
+\r
+       /* Only one UART is supported so the handle is not used. */\r
+       return ( xComPortHandle ) 0;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+BaseType_t xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, TickType_t xBlockTime )\r
+{\r
+BaseType_t xReturn;\r
+\r
+       /* Only a single port is supported. */\r
+       ( void ) pxPort;\r
+\r
+       /* Obtain a received character from the queue - entering the Blocked state\r
+       (so not consuming any processing time) to wait for a character if one is not\r
+       already available. */\r
+       xReturn = xQueueReceive( xRxQueue, pcRxedChar, xBlockTime );\r
+       return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength )\r
+{\r
+const TickType_t xMaxWaitTime = pdMS_TO_TICKS( 20UL * ( uint32_t ) usStringLength );\r
+\r
+       /* Only a single port is supported. */\r
+       ( void ) pxPort;\r
+\r
+       /* Note there is no mutual exclusion at the driver level.  If more than one\r
+       task is using the serial port then mutual exclusion should be provided where\r
+       this function is called. */\r
+\r
+       /* Ensure notifications are not already waiting. */\r
+       ( void ) ulTaskNotifyTake( pdTRUE, 0 );\r
+\r
+       /* Remember which task is sending the byte. */\r
+       xTransmittingTask = xTaskGetCurrentTaskHandle();\r
+\r
+       /* Mark the start and end of the data being sent. */\r
+       pcStringStart = pcString;\r
+       pcStringEnd = pcStringStart + usStringLength;\r
+\r
+       /* Start to send the first byte. */\r
+       pxUARTA0->rTXBUF.r = ( uint_fast8_t ) *pcString;\r
+\r
+       /* Enable the interrupt then wait for the byte to be sent.  The interrupt\r
+       will be disabled again in the ISR. */\r
+       MAP_UART_enableInterrupt( EUSCI_A0_MODULE, EUSCI_A_UART_TRANSMIT_INTERRUPT );\r
+       ulTaskNotifyTake( pdTRUE, xMaxWaitTime );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime )\r
+{\r
+const TickType_t xMaxWaitTime = pdMS_TO_TICKS( 20UL );\r
+\r
+       /* Only a single port is supported. */\r
+       ( void ) pxPort;\r
+\r
+       /* Note there is no mutual exclusion at the driver level.  If more than one\r
+       task is using the serial port then mutual exclusion should be provided where\r
+       this function is called. */\r
+\r
+       /* Ensure notifications are not already waiting. */\r
+       ( void ) ulTaskNotifyTake( pdTRUE, 0 );\r
+\r
+       /* Remember which task is sending the byte. */\r
+       xTransmittingTask = xTaskGetCurrentTaskHandle();\r
+\r
+       /* Mark the start and end of the data being sent - in this case just a\r
+       single byte. */\r
+       pcStringStart = &cOutChar;\r
+       pcStringEnd = pcStringStart + sizeof( cOutChar );\r
+\r
+       /* Start to send the byte. */\r
+       pxUARTA0->rTXBUF.r = ( uint_fast8_t ) cOutChar;\r
+\r
+       /* Enable the interrupt then wait for the byte to be sent.  The interrupt\r
+       will be disabled again in the ISR. */\r
+       MAP_UART_enableInterrupt( EUSCI_A0_MODULE, EUSCI_A_UART_TRANSMIT_INTERRUPT );\r
+       ulTaskNotifyTake( pdTRUE, xMaxWaitTime );\r
+\r
+       return pdPASS;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vSerialClose(xComPortHandle xPort)\r
+{\r
+       /* Not supported as not required by the demo application. */\r
+       ( void ) xPort;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vUART_Handler( void )\r
+{\r
+uint8_t ucChar;\r
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;\r
+uint_fast8_t xInterruptStatus;\r
+\r
+       xInterruptStatus = MAP_UART_getEnabledInterruptStatus( EUSCI_A0_MODULE );\r
+\r
+       if( ( xInterruptStatus & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG ) != 0x00 )\r
+       {\r
+               /* Obtain the character. */\r
+               ucChar = MAP_UART_receiveData( EUSCI_A0_MODULE );\r
+\r
+               /* Send the character to the queue.  Note the comments at the top of this\r
+               file with regards to the inefficiency of this method for anything other than\r
+               very low bandwidth communications.\r
+\r
+               If writing to the queue unblocks a task, and the unblocked task has a\r
+               priority above the currently running task (the task that this interrupt\r
+               interrupted), then xHigherPriorityTaskWoken will be set to pdTRUE inside the\r
+               xQueueSendFromISR() function.  xHigherPriorityTaskWoken is then passed to\r
+               portYIELD_FROM_ISR() at the end of this interrupt handler to request a\r
+               context switch so the interrupt returns directly to the (higher priority)\r
+               unblocked task. */\r
+               xQueueSendFromISR( xRxQueue, &ucChar, &xHigherPriorityTaskWoken );\r
+       }\r
+\r
+       if( ( xInterruptStatus & EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG ) != 0x00 )\r
+       {\r
+               /* Are there more characters to transmit? */\r
+               pcStringStart++;\r
+               if( ( uint32_t ) pcStringStart < ( uint32_t ) pcStringEnd )\r
+               {\r
+                       /* This is probably quite a heavy wait function just for writing to\r
+                       the Tx register.  An optimised design would probably replace this\r
+                       with a simple register write. */\r
+                       pxUARTA0->rTXBUF.r = ( uint_fast8_t ) *pcStringStart;\r
+               }\r
+               else\r
+               {\r
+                       /* No more characters to send.  Disable the interrupt and notify the\r
+                       task, if the task is waiting. */\r
+                       MAP_UART_disableInterrupt( EUSCI_A0_MODULE, EUSCI_A_UART_TRANSMIT_INTERRUPT );\r
+                       if( xTransmittingTask != NULL )\r
+                       {\r
+                               vTaskNotifyGiveFromISR( xTransmittingTask, &xHigherPriorityTaskWoken );\r
+                               xTransmittingTask = NULL;\r
+                       }\r
+               }\r
+       }\r
+\r
+\r
+       /* portYIELD_FROM_ISR() will request a context switch if executing this\r
+       interrupt handler caused a task to leave the blocked state, and the task\r
+       that left the blocked state has a higher priority than the currently running\r
+       task (the task this interrupt interrupted).  See the comment above the calls\r
+       to xSemaphoreGiveFromISR() and xQueueSendFromISR() within this function. */\r
+       portYIELD_FROM_ISR( xHigherPriorityTaskWoken );\r
+}\r
+\r
+\r
+\r
+\r
+\r