Line 53... |
Line 53... |
#include "queue.h"
|
#include "queue.h"
|
#include "task.h"
|
#include "task.h"
|
|
|
/* Demo application includes. */
|
/* Demo application includes. */
|
#include "serial.h"
|
#include "serial.h"
|
|
|
|
/* bsp includes. */
|
|
#include "support.h"
|
|
#include "spr_defs.h"
|
#include "uart.h"
|
#include "uart.h"
|
|
#include "interrupts.h"
|
|
|
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
|
|
/* Constants to setup and access the USART. */
|
/* Constants to setup and access the USART. */
|
#define serINVALID_COMPORT_HANDLER ( ( xComPortHandle ) 0 )
|
#define serINVALID_COMPORT_HANDLER ( ( xComPortHandle ) 0 )
|
Line 78... |
Line 83... |
static void vprvSerialCreateQueues( unsigned portBASE_TYPE uxQueueLength,
|
static void vprvSerialCreateQueues( unsigned portBASE_TYPE uxQueueLength,
|
xQueueHandle *pxRxedChars,
|
xQueueHandle *pxRxedChars,
|
xQueueHandle *pxCharsForTx );
|
xQueueHandle *pxCharsForTx );
|
|
|
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
// TODO : Porting
|
static void vUSART_ISR( void *arg )
|
static portBASE_TYPE prvUSART_ISR_NonNakedBehaviour( void )
|
|
{
|
{
|
/* Now we can declare the local variables. */
|
/* Now we can declare the local variables. */
|
|
arg = arg;
|
signed portCHAR cChar;
|
signed portCHAR cChar;
|
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
unsigned portLONG ulStatus;
|
unsigned portLONG ulStatus;
|
// FIXME
|
|
#define ADDR_UART_BASE (0x90000000)
|
|
volatile portBASE_TYPE *usart = ADDR_UART_BASE;
|
|
portBASE_TYPE retstatus;
|
portBASE_TYPE retstatus;
|
|
|
/* What caused the interrupt? */
|
/* What caused the interrupt? */
|
// FIXME
|
ulStatus = uart_get_iir(0);
|
// ulStatus = usart->csr & usart->imr;
|
|
|
|
// TODO : TX RADY INTERRUPT, FIXME
|
// TX RADY INTERRUPT
|
// if (ulStatus & AVR32_USART_CSR_TXRDY_MASK)
|
if (ulStatus & UART_IIR_THRI)
|
if (ulStatus & 0x1)
|
|
{
|
{
|
/* The interrupt was caused by the THR becoming empty. Are there any
|
/* The interrupt was caused by the THR becoming empty. Are there any
|
more characters to transmit?
|
more characters to transmit?
|
Because FreeRTOS is not supposed to run with nested interrupts, put all OS
|
Because FreeRTOS is not supposed to run with nested interrupts, put all OS
|
calls in a critical section . */
|
calls in a critical section . */
|
|
|
|
/* FIXME, entering, exiting ciritical section around
|
|
xQueueReceiveFromISR is not work */
|
|
#if 0
|
portENTER_CRITICAL();
|
portENTER_CRITICAL();
|
retstatus = xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken );
|
retstatus = xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken );
|
portEXIT_CRITICAL();
|
portEXIT_CRITICAL();
|
|
#else
|
|
retstatus = xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken );
|
|
#endif
|
|
|
if (retstatus == pdTRUE)
|
if (retstatus == pdTRUE)
|
{
|
{
|
/* A character was retrieved from the queue so can be sent to the
|
/* A character was retrieved from the queue so can be sent to the
|
THR now. */
|
THR now. */
|
// FIXME
|
uart_putc_noblock(0, cChar);
|
// usart->thr = cChar;
|
|
}
|
}
|
else
|
else
|
{
|
{
|
/* Queue empty, nothing to send so turn off the Tx interrupt. */
|
/* Queue empty, nothing to send so turn off the Tx interrupt. */
|
// FIXME
|
uart_txint_disable(0);
|
// usart->idr = AVR32_USART_IDR_TXRDY_MASK;
|
|
}
|
}
|
}
|
}
|
|
|
// TODO : RX RADY INTERRUPT, FIXME
|
// RX RADY INTERRUPT
|
// if (ulStatus & AVR32_USART_CSR_RXRDY_MASK)
|
if (ulStatus & UART_IIR_RDI)
|
if (ulStatus & 0x2)
|
|
{
|
{
|
/* The interrupt was caused by the receiver getting data. */
|
/* The interrupt was caused by the receiver getting data. */
|
// FIXME
|
cChar = uart_getc_noblock(0);
|
// cChar = usart->rhr;
|
|
|
|
/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
|
/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
|
calls in a critical section . */
|
calls in a critical section . */
|
portENTER_CRITICAL();
|
portENTER_CRITICAL();
|
xQueueSendFromISR(xRxedChars, &cChar, &xHigherPriorityTaskWoken);
|
xQueueSendFromISR(xRxedChars, &cChar, &xHigherPriorityTaskWoken);
|
portEXIT_CRITICAL();
|
portEXIT_CRITICAL();
|
}
|
}
|
|
|
/* The return value will be used by portEXIT_SWITCHING_ISR() to know if it
|
/* The return value will be used by portEXIT_SWITCHING_ISR() to know if it
|
should perform a vTaskSwitchContext(). */
|
should perform a vTaskSwitchContext(). */
|
return ( xHigherPriorityTaskWoken );
|
// return ( xHigherPriorityTaskWoken );
|
}
|
}
|
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
|
|
/*
|
|
* USART interrupt service routine.
|
|
*/
|
|
// FIXME it was __naked__ fuction
|
|
static void vUSART_ISR( void )
|
|
{
|
|
/* This ISR can cause a context switch, so the first statement must be a
|
|
call to the portENTER_SWITCHING_ISR() macro. This must be BEFORE any
|
|
variable declarations. */
|
|
portENTER_SWITCHING_ISR(); // TODO
|
|
|
|
prvUSART_ISR_NonNakedBehaviour();
|
|
|
|
/* Exit the ISR. If a task was woken by either a character being received
|
|
or transmitted then a context switch will occur. */
|
|
portEXIT_SWITCHING_ISR(); // TODO
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
// TODO : porting
|
|
/*
|
/*
|
* Init the serial port for the Minimal implementation.
|
* Init the serial port for the Minimal implementation.
|
*/
|
*/
|
xComPortHandle xSerialPortInitMinimal( unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
|
xComPortHandle xSerialPortInitMinimal( unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
|
{
|
{
|
xComPortHandle xReturn = serHANDLE;
|
xComPortHandle xReturn = serHANDLE;
|
// FIXME
|
|
#define ADDR_UART_BASE (0x90000000)
|
|
volatile portBASE_TYPE *usart = ADDR_UART_BASE;
|
|
int cd; /* USART Clock Divider. */
|
|
|
|
/* Create the rx and tx queues. */
|
/* Create the rx and tx queues. */
|
vprvSerialCreateQueues( uxQueueLength, &xRxedChars, &xCharsForTx );
|
vprvSerialCreateQueues( uxQueueLength, &xRxedChars, &xCharsForTx );
|
|
|
/* Configure USART. */
|
/* Configure USART. */
|
Line 184... |
Line 163... |
( xCharsForTx != serINVALID_QUEUE ) &&
|
( xCharsForTx != serINVALID_QUEUE ) &&
|
( ulWantedBaud != ( unsigned portLONG ) 0 ) )
|
( ulWantedBaud != ( unsigned portLONG ) 0 ) )
|
{
|
{
|
portENTER_CRITICAL();
|
portENTER_CRITICAL();
|
{
|
{
|
if( cd > 65535 )
|
// register interrupt handler
|
{
|
int_add(UART0_IRQ, vUSART_ISR, 0x0);
|
/* Baudrate is too low */
|
|
return serINVALID_COMPORT_HANDLER;
|
|
}
|
|
|
|
// FIXME
|
|
// INTC_register_interrupt((__int_handler)&vUSART_ISR, serialPORT_USART_IRQ, INT1); // interrupt register
|
|
}
|
}
|
portEXIT_CRITICAL();
|
portEXIT_CRITICAL();
|
}
|
}
|
else
|
else
|
{
|
{
|
Line 224... |
Line 197... |
}
|
}
|
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
|
|
void vSerialPutString( xComPortHandle pxPort, const signed portCHAR * const pcString, unsigned portSHORT usStringLength )
|
void vSerialPutString( xComPortHandle pxPort, const signed portCHAR * const pcString, unsigned portSHORT usStringLength )
|
{
|
{
|
|
usStringLength = usStringLength;
|
signed portCHAR *pxNext;
|
signed portCHAR *pxNext;
|
|
|
/* NOTE: This implementation does not handle the queue being full as no
|
/* NOTE: This implementation does not handle the queue being full as no
|
block time is used! */
|
block time is used! */
|
|
|
Line 244... |
Line 218... |
}
|
}
|
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
|
|
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed portCHAR cOutChar, portTickType xBlockTime )
|
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed portCHAR cOutChar, portTickType xBlockTime )
|
{
|
{
|
// FIXME
|
/* The port handle is not required as this driver only supports UART0. */
|
#define ADDR_UART_BASE (0x90000000)
|
( void ) pxPort;
|
volatile portBASE_TYPE *usart = ADDR_UART_BASE;
|
|
|
|
/* Place the character in the queue of characters to be transmitted. */
|
/* Place the character in the queue of characters to be transmitted. */
|
if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )
|
if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )
|
{
|
{
|
return pdFAIL;
|
return pdFAIL;
|
Line 258... |
Line 231... |
|
|
/* Turn on the Tx interrupt so the ISR will remove the character from the
|
/* Turn on the Tx interrupt so the ISR will remove the character from the
|
queue and send it. This does not need to be in a critical section as
|
queue and send it. This does not need to be in a critical section as
|
if the interrupt has already removed the character the next interrupt
|
if the interrupt has already removed the character the next interrupt
|
will simply turn off the Tx interrupt again. */
|
will simply turn off the Tx interrupt again. */
|
|
uart_txint_enable(0);
|
// FIXME
|
|
// usart->ier = (1 << AVR32_USART_IER_TXRDY_OFFSET);
|
|
// TODO : Turn on TX interrupt
|
|
|
|
return pdPASS;
|
return pdPASS;
|
}
|
}
|
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
|
|
void vSerialClose( xComPortHandle xPort )
|
void vSerialClose( xComPortHandle xPort )
|
{
|
{
|
/* Not supported as not required by the demo application. */
|
/* Not supported as not required by the demo application. */
|
|
xPort = xPort; // prevent compiler warning
|
}
|
}
|
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
|
|
/*###########################################################*/
|
/*###########################################################*/
|
|
|