Esempio n. 1
0
void
prvvMBSerialIRQHandler( void )
{
    portENTER_SWITCHING_ISR(  );

    static BOOL     xTaskWokenReceive = FALSE;
    static BOOL     xTaskWokenTransmit = FALSE;
    static USHORT   usStatus;

    usStatus = UART_FlagStatus( MB_UART_DEV );

    if( prvMBPortTXIsEnabled(  ) && ( usStatus & UART_TxHalfEmpty ) )
    {
        xTaskWokenReceive = pxMBFrameCBTransmitterEmpty(  );
    }
    if( prvMBPortRXIsEnabled(  ) && ( usStatus & UART_RxBufFull ) )
    {
        xTaskWokenReceive = pxMBFrameCBByteReceived(  );
    }

    /* End the interrupt in the EIC. */
    EIC->IPR |= 1 << EIC_CurrentIRQChannelValue(  );

    portEXIT_SWITCHING_ISR( ( xTaskWokenReceive
                              || xTaskWokenTransmit ) ? pdTRUE : pdFALSE );
}
Esempio n. 2
0
/* Serial port ISR.  This can cause a context switch so is not defined as a
standard ISR using the __irq keyword.  Instead a wrapper function is defined
within serialISR.s79 which in turn calls this function.  See the port
documentation on the FreeRTOS.org website for more information. */
__arm void vSerialISR( void )
{
unsigned short usStatus;
signed char cChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

	/* What caused the interrupt? */
	usStatus = UART_FlagStatus( UART0 );

	if( usStatus & UART_TxHalfEmpty )
	{
		/* 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. */
			UART0->TxBUFR = cChar;
		}
		else
		{
			/* Queue empty, nothing to send so turn off the Tx interrupt. */
			serINTERRUPT_OFF();
		}		
	}

	if( usStatus & 	UART_RxBufFull )
	{
		/* The interrupt was caused by a character being received.  Grab the
		character from the RHR and place it in the queue of received
		characters. */
		cChar = UART0->RxBUFR;
		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 );

	/* End the interrupt in the EIC. */
	portCLEAR_EIC();
}
Esempio n. 3
0
void
sio_serial_isr( UART_TypeDef * UARTx, u8_t * need_ctx_switch )
{
    int             i;
    u16             status;
    volatile serdev_t *dev = SIO_FD_NULL;

    portBASE_TYPE   rx_woken = pdFALSE;
    portBASE_TYPE   tx_woken = pdFALSE;

    for( i = 0; i < UART_DEVICES_MAX; i++ )
    {
        if( devices[i].ready && ( devices[i].UARTx == UARTx ) )
        {
            dev = &devices[i];
            break;
        }
    }
    if( dev != SIO_FD_NULL )
    {
        status = UART_FlagStatus( dev->UARTx );

        /* If there are characters in the UART fifo place them into the 
         * ring buffer. In case the buffer is filled half or the requested
         * number of bytes has been read wakeup the receiver.
         */
        if( status & UART_RxBufFull )
        {
            do
            {
                /* Store the character in the ring buffer and advance write
                 * position. */
                dev->rx_buf[dev->rx_buf_wrpos] = dev->UARTx->RxBUFR;
                dev->rx_buf_wrpos = ( dev->rx_buf_wrpos + 1 ) % DEFAULT_RX_BUFSIZE;

                /* Increment the receiver buffer counter. Check for a buffer
                 * overrun. In that case we have overwritten a old character.
                 * Therefore we have to advance the read position. Note that
                 * in this error case we must not increment the read counter
                 * because an old character was lost.
                 */
                if( dev->rx_buf_cnt >= DEFAULT_RX_BUFSIZE )
                {
                    /* LWIP_ASSERT( "sio_serial_isr: receiver buffer overflow", 0 ); */
                    dev->rx_buf_rdpos = ( dev->rx_buf_rdpos + 1 ) % DEFAULT_RX_BUFSIZE;
                }
                else
                {
                    dev->rx_buf_cnt++;
                }

                /* Get the new status from the UART. */
                status = UART_FlagStatus( dev->UARTx );
            }
            while( status & UART_RxBufFull );

            /* Wakeup receiver if buffer is starting to fill. */
            if( dev->rx_buf_cnt > ( DEFAULT_RX_BUFSIZE / 2 ) )
            {
                rx_woken = xSemaphoreGiveFromISR( dev->rx_sem, rx_woken );
            }
        }

        /* Check if we must send characters. */
        if( ( dev->tx_buf_cnt > 0 ) && ( status & UART_TxHalfEmpty ) )
        {
            do
            {
                /* Fetch character from the ring buffer and place them into
                 * the FIFO. */
                dev->UARTx->TxBUFR = dev->tx_buf[dev->tx_buf_rdpos];
                dev->tx_buf_rdpos = ( dev->tx_buf_rdpos + 1 ) % DEFAULT_TX_BUFSIZE;
                dev->tx_buf_cnt--;

                /* Get the new status from the UART. */
                status = UART_FlagStatus( dev->UARTx );
            }
            while( ( dev->tx_buf_cnt > 0 ) && ( status & UART_TxHalfEmpty ) );

            if( dev->tx_buf_cnt == 0 )
            {
                tx_woken = xSemaphoreGiveFromISR( dev->tx_sem, tx_woken );
                UART_ItConfig( dev->UARTx, UART_TxHalfEmpty, DISABLE );
            }
        }

        if( tx_woken || rx_woken )
        {
            *need_ctx_switch = 1;
        }
    }
}