void uart1_irq_handler(void)
{
    uint32_t ulReceived = 0;
    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
    const unsigned portBASE_TYPE uxUARTNumber = 1UL;
    Transfer_Control_t *pxTransferStruct;

    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
        pxTransferStruct = pxRxTransferControlStructs[uxUARTNumber];
        if (pxTransferStruct != NULL) {
            switch(diGET_TRANSFER_TYPE_FROM_CONTROL_STRUCT(pxTransferStruct)) {
            case ioctlUSE_CIRCULAR_BUFFER_RX:
            #if ioconfigUSE_UART_CIRCULAR_BUFFER_RX == 1
            {
                ioutilsRX_CHARS_INTO_CIRCULAR_BUFFER_FROM_ISR(
                        pxTransferStruct,   /* The structure that contains the reference to the circular buffer. */
                        (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET),    /* While loop condition. */
                        USART_ReceiveData(USART1),         /* Register holding the received character. */
                        ulReceived,
                        xHigherPriorityTaskWoken);
            }
            #endif /* ioconfigUSE_UART_CIRCULAR_BUFFER_RX */
                break;

            case ioctlUSE_CHARACTER_QUEUE_RX:
            #if ioconfigUSE_UART_RX_CHAR_QUEUE == 1
            {
                size_t i = 1;
                ioutilsRX_CHARS_INTO_QUEUE_FROM_ISR(
                        pxTransferStruct,
                        i--,
                        USART_ReceiveData(USART1),
                        ulReceived,
                        xHigherPriorityTaskWoken);
            }
            #endif /* ioconfigUSE_UART_RX_CHAR_QUEUE */
                break;

            default:
                break;
            }
        }
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    }

    if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET) {
        pxTransferStruct = pxTxTransferControlStructs[uxUARTNumber];
        if (pxTransferStruct != NULL) {
            switch (diGET_TRANSFER_TYPE_FROM_CONTROL_STRUCT(pxTransferStruct)) {
            case ioctlUSE_ZERO_COPY_TX:
            #if ioconfigUSE_UART_ZERO_COPY_TX == 1
            {
                iouitlsTX_SINGLE_CHAR_FROM_ZERO_COPY_BUFFER_FROM_ISR(
                        pxTransferStruct,
                        USART_SendData(USART1, ucChar),
                        xHigherPriorityTaskWoken);
            }
            #endif /* ioconfigUSE_UART_ZERO_COPY_TX */
                if (xHigherPriorityTaskWoken != pdTRUE)
                    USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
                break;

            case ioctlUSE_CHARACTER_QUEUE_TX:
            #if ioconfigUSE_UART_TX_CHAR_QUEUE == 1
            {
                size_t i = 1;
                ioutilsTX_CHARS_FROM_QUEUE_FROM_ISR(
                        pxTransferStruct,
                        i--,
                        USART_SendData(USART1, ucChar),
                        xHigherPriorityTaskWoken);
            }
            #endif /* ioconfigUSE_UART_TX_CHAR_QUEUE */
            if (xHigherPriorityTaskWoken != pdTRUE)
                USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
                break;

            default:
                /* This must be an error.  Force an assert. */
                configASSERT( xHigherPriorityTaskWoken );
                break;
            }
        }
        USART_ClearITPendingBit(USART1, USART_IT_TXE);
    }
    /* The ulReceived parameter is not used by the UART ISR. */
    (void) ulReceived;

    /* If xHigherPriorityTaskWoken is now equal to pdTRUE, then a context
    switch should be performed before the interrupt exists.  That ensures the
    unblocked (higher priority) task is returned to immediately. */
    portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
void UART3_IRQHandler( void )
{
uint32_t ulInterruptSource, ulReceived;
const uint32_t ulRxInterrupts = ( UART_IIR_INTID_RDA | UART_IIR_INTID_CTI );
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
const unsigned portBASE_TYPE uxUARTNumber = 3UL;
Transfer_Control_t *pxTransferStruct;

	/* Determine the interrupt source. */
	ulInterruptSource = UART_GetIntId( LPC_UART3 );

	if( ( ulInterruptSource & ulRxInterrupts ) != 0UL )
	{
		pxTransferStruct = pxRxTransferControlStructs[ uxUARTNumber ];
		if( pxTransferStruct != NULL )
		{
			switch( diGET_TRANSFER_TYPE_FROM_CONTROL_STRUCT( pxTransferStruct ) )
			{
				case ioctlUSE_CIRCULAR_BUFFER_RX :

					#if ioconfigUSE_UART_CIRCULAR_BUFFER_RX == 1
					{
						ioutilsRX_CHARS_INTO_CIRCULAR_BUFFER_FROM_ISR(
																	pxTransferStruct, 	/* The structure that contains the reference to the circular buffer. */
																	( ( LPC_UART3->LSR & UART_LSR_RDR ) != 0 ), 	/* While loop condition. */
																	LPC_UART3->RBR,			/* Register holding the received character. */
																	ulReceived,
																	xHigherPriorityTaskWoken
																);
					}
					#endif /* ioconfigUSE_UART_CIRCULAR_BUFFER_RX */
					break;


				case ioctlUSE_CHARACTER_QUEUE_RX :

					#if ioconfigUSE_UART_RX_CHAR_QUEUE == 1
					{
						ioutilsRX_CHARS_INTO_QUEUE_FROM_ISR( pxTransferStruct, ( ( LPC_UART3->LSR & UART_LSR_RDR ) != 0 ), LPC_UART3->RBR, ulReceived, xHigherPriorityTaskWoken );
					}
					#endif /* ioconfigUSE_UART_RX_CHAR_QUEUE */
					break;


				default :

					/* This must be an error.  Force an assert. */
					configASSERT( xHigherPriorityTaskWoken );
					break;
			}
		}
	}

	if( ( ulInterruptSource & UART_IIR_INTID_THRE ) != 0UL )
	{
		/* The transmit holding register is empty.  Is there any more data
		to send? */
		pxTransferStruct = pxTxTransferControlStructs[ uxUARTNumber ];
		if( pxTransferStruct != NULL )
		{
			switch( diGET_TRANSFER_TYPE_FROM_CONTROL_STRUCT( pxTransferStruct ) )
			{
				case ioctlUSE_ZERO_COPY_TX:

					#if ioconfigUSE_UART_ZERO_COPY_TX == 1
					{
						iouitlsTX_CHARS_FROM_ZERO_COPY_BUFFER_FROM_ISR( pxTransferStruct, ( ( LPC_UART3->FIFOLVL & uartTX_FIFO_LEVEL_MASK ) != uartTX_FIFO_LEVEL_MASK ), ( LPC_UART3->THR = ucChar ), xHigherPriorityTaskWoken );
					}
					#endif /* ioconfigUSE_UART_ZERO_COPY_TX */
					break;


				case ioctlUSE_CHARACTER_QUEUE_TX:

					#if ioconfigUSE_UART_TX_CHAR_QUEUE == 1
					{
						ioutilsTX_CHARS_FROM_QUEUE_FROM_ISR( pxTransferStruct, ( UART_FIFOLVL_TXFIFOLVL( LPC_UART3->FIFOLVL ) != ( UART_TX_FIFO_SIZE - 1 ) ), ( LPC_UART3->THR = ucChar ), xHigherPriorityTaskWoken );
					}
					#endif /* ioconfigUSE_UART_TX_CHAR_QUEUE */
					break;


				default :

					/* This must be an error.  Force an assert. */
					configASSERT( xHigherPriorityTaskWoken );
					break;
			}
		}
	}

	/* The ulReceived parameter is not used by the UART ISR. */
	( void ) ulReceived;

	/* If lHigherPriorityTaskWoken is now equal to pdTRUE, then a context
	switch should be performed before the interrupt exists.  That ensures the
	unblocked (higher priority) task is returned to immediately. */
	portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
Ejemplo n.º 3
0
void SSP1_IRQHandler( void )
{
uint32_t ulInterruptSource;
volatile uint32_t usJunk, ulReceived = 0UL;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
const unsigned portBASE_TYPE uxSSPNumber = 1UL;
Transfer_Control_t *pxTxTransferStruct, *pxRxTransferStruct;

	/* Determine the interrupt source. */
	ulInterruptSource = LPC_SSP1->MIS;

	/* Clear receive overruns, and optionally assert. */
	if( ( ulInterruptSource & SSP_INTSTAT_ROR ) != 0 )
	{
		configASSERT( ( ulInterruptSource & SSP_INTSTAT_ROR ) == 0 );
		LPC_SSP1->ICR = SSP_INTCLR_ROR;
	}

	/* Clear timeouts. */
	if( ( ulInterruptSource & SSP_INTSTAT_RT ) != 0 )
	{
		LPC_SSP1->ICR = SSP_INTCLR_RT;
	}

	/* Is this a receive FIFO half full or receive timeout? */
	if( ( ulInterruptSource & sspRX_DATA_AVAILABLE_INTERRUPTS ) != 0 )
	{
		pxTxTransferStruct = pxTxTransferControlStructs[ uxSSPNumber ];
		pxRxTransferStruct = pxRxTransferControlStructs[ uxSSPNumber ];
		configASSERT( pxRxTransferStruct );
		configASSERT( pxTxTransferStruct );

		if( pxRxTransferStruct != NULL )
		{
			if( ulReceiveActive[ uxSSPNumber ] == pdFALSE )
			{
				/* The data being received is just in response to data
				being sent,	not in response to data being read, just
				just junk it. */
				while( ( LPC_SSP1->SR & SSP_SR_RNE ) != 0 )
				{
					usJunk = LPC_SSP1->DR;
					ulReceived++;
				}
			}
			else
			{
				/* Data is being received because a read is being
				performed.  Store the data using whichever
				transfer mechanism is currently configured. */
				switch( diGET_TRANSFER_TYPE_FROM_CONTROL_STRUCT( pxRxTransferStruct ) )
				{
					case ioctlUSE_CIRCULAR_BUFFER_RX :

						#if ioconfigUSE_SSP_CIRCULAR_BUFFER_RX == 1
						{
							/* This call will empty the FIFO, and give the New
							Data semaphore so a task blocked on an SSP read
							will unblock.  Note that this does not mean that
							more data will not arrive after this interrupt,
							even if there is no more data to send. */
							ioutilsRX_CHARS_INTO_CIRCULAR_BUFFER_FROM_ISR(
																		pxRxTransferStruct, 	/* The structure that contains the reference to the circular buffer. */
																		( ( LPC_SSP1->SR & SSP_SR_RNE ) != 0 ), 		/* While loop condition. */
																		( LPC_SSP1->DR ),						/* The function that returns the chars. */
																		ulReceived,
																		xHigherPriorityTaskWoken
																	);
						}
						#endif /* ioconfigUSE_SSP_CIRCULAR_BUFFER_RX */
						break;


					case ioctlUSE_CHARACTER_QUEUE_RX :

						#if ioconfigUSE_SSP_RX_CHAR_QUEUE == 1
						{
							ioutilsRX_CHARS_INTO_QUEUE_FROM_ISR( pxRxTransferStruct, ( ( LPC_SSP1->SR & SSP_SR_RNE ) != 0 ), ( LPC_SSP1->DR ), ulReceived, xHigherPriorityTaskWoken );
						}
						#endif /* ioconfigUSE_SSP_RX_CHAR_QUEUE */
						break;


					default :

						/* This must be an error.  Force an assert. */
						configASSERT( xHigherPriorityTaskWoken );
						break;
				}
			}

			/* Space has been created in the Rx FIFO, see if there is any data
			to send to the Tx FIFO. */
			switch( diGET_TRANSFER_TYPE_FROM_CONTROL_STRUCT( pxTxTransferStruct ) )
			{
				case ioctlUSE_ZERO_COPY_TX:

					#if ioconfigUSE_SSP_ZERO_COPY_TX == 1
					{
						iouitlsTX_CHARS_FROM_ZERO_COPY_BUFFER_FROM_ISR( pxTxTransferStruct, ( ( ulReceived-- ) > 0 ), ( LPC_SSP1->DR = ucChar), xHigherPriorityTaskWoken );
					}
					#endif /* ioconfigUSE_SSP_ZERO_COPY_TX */
					break;


				case ioctlUSE_CHARACTER_QUEUE_TX:

					#if ioconfigUSE_SSP_TX_CHAR_QUEUE == 1
					{
						ioutilsTX_CHARS_FROM_QUEUE_FROM_ISR( pxTxTransferStruct, ( ( ulReceived-- ) > 0 ), ( LPC_SSP1->DR = SSP_DR_BITMASK( ( uint16_t ) ucChar ) ), xHigherPriorityTaskWoken );
					}
					#endif /* ioconfigUSE_SSP_TX_CHAR_QUEUE */
					break;


				default :

					/* Should not get here.  Set the saved transfer control
					structure to NULL so the Tx interrupt will get disabled
					before this ISR is exited. */
					pxTxTransferControlStructs[ uxSSPNumber ] = NULL;

					/* This must be an error.  Force an assert. */
					configASSERT( xHigherPriorityTaskWoken );
					break;
			}
		}
	}

	/* If lHigherPriorityTaskWoken is now equal to pdTRUE, then a context
	switch should be performed before the interrupt exists.  That ensures the
	unblocked (higher priority) task is returned to immediately. */
	portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}