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 ); }
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 ); }