Пример #1
0
void vSerialISR( void )
{
    unsigned long ulStatus;
    signed char cChar;
    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

    /* What caused the interrupt? */
    ulStatus = BOARD_USART_BASE->US_CSR &= BOARD_USART_BASE->US_IMR;

    if( ulStatus & AT91C_US_TXRDY ) {
        /* The interrupt was caused by the THR becoming empty.  Are there any
        more characters to transmit? */
        if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE ) {
            /* A character was retrieved from the queue so can be sent to the
            THR now. */
            BOARD_USART_BASE->US_THR = cChar;
        } else {
            /* Queue empty, nothing to send so turn off the Tx interrupt. */
            vInterruptOff();
        }
    }

    if( ulStatus & AT91C_US_RXRDY ) {
        /* The interrupt was caused by a character being received.  Grab the
        character from the RHR and place it in the queue or received
        characters. */
        cChar = BOARD_USART_BASE->US_RHR;
        xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
    }

    /* If a task was woken by either a character being received or a character
    being transmitted then we may need to switch to another task. */
    portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
Пример #2
0
static portBASE_TYPE xComPortISR( xComPort * const pxPort )
{
unsigned short usStatusRegister;
char cChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE, xContinue = pdTRUE;

	/* NOTE:  THIS IS NOT AN EFFICIENT ISR AS IT IS DESIGNED SOLELY TO TEST
	THE SCHEDULER FUNCTIONALITY.  REAL APPLICATIONS SHOULD NOT USE THIS
	FUNCTION. */


	while( xContinue == pdTRUE )
	{
		xContinue = pdFALSE;
		usStatusRegister = portINPUT_WORD( pxPort->usStatusReg );

		if( usStatusRegister & serRX_READY )
		{
			cChar = ( char ) portINPUT_WORD( pxPort->usRxReg );
			xQueueSendFromISR( pxPort->xRxedChars, &cChar, &xHigherPriorityTaskWoken );

			/* Also release the semaphore - this does nothing interesting and is just a test. */
			xSemaphoreGiveFromISR( pxPort->xTestSem, &xHigherPriorityTaskWoken );

			/* We have performed an action this cycle - there may be other to perform. */
			xContinue = pdTRUE;
		}

		if( pxPort->sTxInterruptOn && ( usStatusRegister & serTX_EMPTY ) )
		{
			if( xQueueReceiveFromISR( pxPort->xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )
			{
				portOUTPUT_WORD( pxPort->usTxReg, ( unsigned short ) cChar );

				/* We have performed an action this cycle - there may be others to perform. */
				xContinue = pdTRUE;
			}
			else
			{
				/* Queue empty, nothing to send */
				vInterruptOff( pxPort, serTX_HOLD_EMPTY_INT );
			}
		}
	}

	serRESET_PIC( pxPort->usIRQVector );

	/* If posting to the queue woke a task that was blocked on the queue we may
	want to switch to the woken task - depending on its priority relative to
	the task interrupted by this ISR. */
	return xHigherPriorityTaskWoken;
}
Пример #3
0
__interrupt void SIG_UART_DATA( void )
{
signed char cChar, cTaskWoken = pdFALSE;

	if( xQueueReceiveFromISR( xCharsForTx, &cChar, &cTaskWoken ) == pdTRUE )
	{
		/* Send the next character queued for Tx. */
		outb( UDR, cChar );
	}
	else
	{
		/* Queue empty, nothing to send. */
		vInterruptOff();
	}
}
Пример #4
0
void vSerialClose( xComPortHandle xPort )
{
unsigned char ucByte;

	/* Turn off the interrupts.  We may also want to delete the queues and/or
	re-install the original ISR. */

	portENTER_CRITICAL();
	{
		vInterruptOff();
		ucByte = UCSRB;
		ucByte &= ~serRX_INT_ENABLE;
		outb( UCSRB, ucByte );
	}
	portEXIT_CRITICAL();
}
Пример #5
0
void vSerialClose( xComPortHandle xPort )
{
	uint8_t ucByte;

	/* The parameter is not used. */
	( void ) xPort;

	/* Turn off the interrupts.  We may also want to delete the queues and/or
	re-install the original ISR. */

	vPortFree (serialWorkBuffer);
	vQueueDelete(xRxedChars);
	vQueueDelete(xCharsForTx);

	portENTER_CRITICAL();
	{
		vInterruptOff();
		ucByte = UCSR0B;
		ucByte &= ~(_BV(RXCIE0));
		UCSR0B = ucByte;
	}
	portEXIT_CRITICAL();
}