+++ /dev/null
-/*\r
- FreeRTOS V9.0.0rc2 - Copyright (C) 2016 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
-/* Xilinx includes. */\r
-#include "xuartps.h"\r
-#include "xscugic.h"\r
-#include "xil_exception.h"\r
-\r
-/* The UART interrupts of interest when receiving. */\r
-#define serRECEIVE_INTERRUPT_MASK ( XUARTPS_IXR_RXOVR | XUARTPS_IXR_RXFULL | XUARTPS_IXR_TOUT )\r
-\r
-/* The UART interrupts of interest when transmitting. */\r
-#define serTRANSMIT_IINTERRUPT_MASK ( XUARTPS_IXR_TXEMPTY )\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/* The UART being used. */\r
-static XUartPs xUARTInstance;\r
-\r
-/* The interrupt controller, which is configred by the hardware setup routines\r
-defined in main(). */\r
-extern XScuGic xInterruptController;\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
-/* The semaphore used to indicate the end of a transmission. */\r
-static SemaphoreHandle_t xTxCompleteSemaphore = NULL;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * The UART interrupt handler is defined in this file to provide more control,\r
- * but still uses parts of the Xilinx provided driver.\r
- */\r
-void prvUART_Handler( void *pvNotUsed );\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * See the serial2.h header file.\r
- */\r
-xComPortHandle xSerialPortInitMinimal( uint32_t ulWantedBaud, UBaseType_t uxQueueLength )\r
-{\r
-BaseType_t xStatus;\r
-XUartPs_Config *pxConfig;\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
- /* Create the semaphore used to signal the end of a transmission, then take\r
- the semaphore so it is in the correct state the first time\r
- xSerialSendString() is called. A block time of zero is used when taking\r
- the semaphore as it is guaranteed to be available (it was just created). */\r
- xTxCompleteSemaphore = xSemaphoreCreateBinary();\r
- configASSERT( xTxCompleteSemaphore );\r
- xSemaphoreTake( xTxCompleteSemaphore, 0 );\r
-\r
- /* Look up the UART configuration then initialise the dirver. */\r
- pxConfig = XUartPs_LookupConfig( XPAR_XUARTPS_0_DEVICE_ID );\r
-\r
- /* Initialise the driver. */\r
- xStatus = XUartPs_CfgInitialize( &xUARTInstance, pxConfig, XPAR_PS7_UART_1_BASEADDR );\r
- configASSERT( xStatus == XST_SUCCESS );\r
- ( void ) xStatus; /* Remove compiler warning if configASSERT() is not defined. */\r
-\r
- /* Misc. parameter configuration. */\r
- XUartPs_SetBaudRate( &xUARTInstance, ulWantedBaud );\r
- XUartPs_SetOperMode( &xUARTInstance, XUARTPS_OPER_MODE_NORMAL );\r
-\r
- /* Install the interrupt service routine that is defined within this\r
- file. */\r
- xStatus = XScuGic_Connect( &xInterruptController, XPAR_XUARTPS_1_INTR, (Xil_ExceptionHandler) prvUART_Handler, (void *) &xUARTInstance );\r
- configASSERT( xStatus == XST_SUCCESS );\r
- ( void ) xStatus; /* Remove compiler warning if configASSERT() is not defined. */\r
-\r
- /* Ensure interrupts start clear. */\r
- XUartPs_WriteReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_ISR_OFFSET, XUARTPS_IXR_MASK );\r
-\r
- /* Enable the UART interrupt within the GIC. */\r
- XScuGic_Enable( &xInterruptController, XPAR_XUARTPS_1_INTR );\r
-\r
- /* Enable the interrupts of interest in the UART. */\r
- XUartPs_SetInterruptMask( &xUARTInstance, XUARTPS_IXR_RXFULL | XUARTPS_IXR_RXOVR | XUARTPS_IXR_TOUT | XUARTPS_IXR_TXEMPTY );\r
-\r
- /* Set the receive timeout. */\r
- XUartPs_SetRecvTimeout( &xUARTInstance, 8 );\r
-\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 xMaxWait = 200UL / portTICK_PERIOD_MS;\r
-\r
- /* Only a single port is supported. */\r
- ( void ) pxPort;\r
-\r
- /* Start the transmission. The interrupt service routine will complete the\r
- transmission if necessary. */\r
- XUartPs_Send( &xUARTInstance, ( void * ) pcString, usStringLength );\r
-\r
- /* Wait until the string has been transmitted before exiting this function,\r
- otherwise there is a risk the calling function will overwrite the string\r
- pointed to by the pcString parameter while it is still being transmitted.\r
- The calling task will wait in the Blocked state (so not consuming any\r
- processing time) until the semaphore is available. */\r
- xSemaphoreTake( xTxCompleteSemaphore, xMaxWait );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime )\r
-{\r
- /* Only a single port is supported. */\r
- ( void ) pxPort;\r
-\r
- /* Send the character. */\r
- XUartPs_Send( &xUARTInstance, ( void * ) &cOutChar, sizeof( cOutChar ) );\r
-\r
- /* Wait for the transmission to be complete so the semaphore is left in the\r
- correct state for the next time vSerialPutString() is called. */\r
- xSemaphoreTake( xTxCompleteSemaphore, xBlockTime );\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 prvUART_Handler( void *pvNotUsed )\r
-{\r
-extern unsigned int XUartPs_SendBuffer( XUartPs *InstancePtr );\r
-uint32_t ulActiveInterrupts, ulChannelStatusRegister;\r
-BaseType_t xHigherPriorityTaskWoken = pdFALSE;\r
-char cChar;\r
-\r
- configASSERT( pvNotUsed == &xUARTInstance );\r
-\r
- /* Remove compile warnings if configASSERT() is not defined. */\r
- ( void ) pvNotUsed;\r
-\r
- /* Read the interrupt ID register to see which interrupt is active. */\r
- ulActiveInterrupts = XUartPs_ReadReg(XPAR_PS7_UART_1_BASEADDR, XUARTPS_IMR_OFFSET);\r
- ulActiveInterrupts &= XUartPs_ReadReg(XPAR_PS7_UART_1_BASEADDR, XUARTPS_ISR_OFFSET);\r
-\r
- /* Are any receive events of interest active? */\r
- if( ( ulActiveInterrupts & serRECEIVE_INTERRUPT_MASK ) != 0 )\r
- {\r
- /* Read the Channel Status Register to determine if there is any data in\r
- the RX FIFO. */\r
- ulChannelStatusRegister = XUartPs_ReadReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_SR_OFFSET );\r
-\r
- /* Move data from the Rx FIFO to the Rx queue. NOTE THE COMMENTS AT THE\r
- TOP OF THIS FILE ABOUT USING QUEUES FOR THIS PURPSOE. */\r
- while( ( ulChannelStatusRegister & XUARTPS_SR_RXEMPTY ) == 0 )\r
- {\r
- cChar = XUartPs_ReadReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_FIFO_OFFSET );\r
-\r
- /* If writing to the queue unblocks a task, and the unblocked task\r
- has a priority above the currently running task (the task that this\r
- interrupt interrupted), then xHigherPriorityTaskWoken will be set\r
- to pdTRUE inside the xQueueSendFromISR() function.\r
- xHigherPriorityTaskWoken is then passed to portYIELD_FROM_ISR() at\r
- the end of this interrupt handler to request a context switch so the\r
- interrupt returns directly to the (higher priority) unblocked\r
- task. */\r
- xQueueSendFromISR( xRxQueue, &cChar, &xHigherPriorityTaskWoken );\r
- ulChannelStatusRegister = XUartPs_ReadReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_SR_OFFSET );\r
- }\r
- }\r
-\r
- /* Are any transmit events of interest active? */\r
- if( ( ulActiveInterrupts & serTRANSMIT_IINTERRUPT_MASK ) != 0 )\r
- {\r
- if( xUARTInstance.SendBuffer.RemainingBytes == 0 )\r
- {\r
- /* Give back the semaphore to indicate that the tranmission is\r
- complete. If giving the semaphore unblocks a task, and the\r
- unblocked task has a priority above the currently running task (the\r
- task that this interrupt interrupted), then xHigherPriorityTaskWoken\r
- will be set to pdTRUE inside the xSemaphoreGiveFromISR() function.\r
- xHigherPriorityTaskWoken is then passed to portYIELD_FROM_ISR() at\r
- the end of this interrupt handler to request a context switch so the\r
- interrupt returns directly to the (higher priority) unblocked\r
- task. */\r
- xSemaphoreGiveFromISR( xTxCompleteSemaphore, &xHigherPriorityTaskWoken );\r
-\r
- /* No more data to transmit. */\r
- XUartPs_WriteReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_IDR_OFFSET, XUARTPS_IXR_TXEMPTY );\r
- }\r
- else\r
- {\r
- /* More data to send. */\r
- XUartPs_SendBuffer( &xUARTInstance );\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
- /* Clear the interrupt status. */\r
- XUartPs_WriteReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_ISR_OFFSET, ulActiveInterrupts );\r
-}\r
-\r
-\r
-\r
-\r
-\r