#include "uart1.h" #include "sw_timer.h" #include "ring_buffer.h" #define UARTn_TX_INTERRUTP_ENABLE FALSE #define UARTn_PERIPHERAL UART1 #define UARTn_INTERRUPT_HANDLER UART1_IRQn #define UARTn_INTERRUPT_MASK MSK_UART1 #define UARTn_INTERRUPT_PRIORITY 3 #define UARTn_TX_PORT PB #define UARTn_TX_PIN_NUM 6 #define UARTn_RX_PORT PB #define UARTn_RX_PIN_NUM 7 #define UARTn_TX_BUFFER_SIZE 200 #define UARTn_RX_BUFFER_SIZE 100 static uint8_t Tx_Buffer[UARTn_TX_BUFFER_SIZE]; static uint8_t Rx_Buffer[UARTn_RX_BUFFER_SIZE]; static RING_BUFFER RingBuffer_Tx; static RING_BUFFER RingBuffer_Rx; #if (UARTn_TX_INTERRUTP_ENABLE == TRUE) static volatile uint8_t Uartn_TxIntEnable = FALSE; static void Uart1_Init_TransmitSet(void); #else static void Uart1_Transmit_Process(void); #endif static void Uart1_Receive_Handler(void); void Uart1_Initialization(uint32_t Baudrate, UARTn_DATA_BIT_Type Databit, UARTn_PARITY_BIT_Type Paritybit, UARTn_STOP_BIT_Type Stopbit) { UARTn_CFG_Type UARTn_Config; /* * Initialize UART0 pin connect */ HAL_GPIO_ConfigOutput((Pn_Type*)UARTn_RX_PORT, UARTn_RX_PIN_NUM, ALTERN_FUNC ); HAL_GPIO_ConfigFunction((Pn_Type*)UARTn_RX_PORT, UARTn_RX_PIN_NUM, AFSRx_AF1 ); HAL_GPIO_ConfigPullup((Pn_Type*)UARTn_RX_PORT, UARTn_RX_PIN_NUM, PUPDx_EnablePU ); HAL_GPIO_ConfigOutput((Pn_Type*)UARTn_TX_PORT, UARTn_TX_PIN_NUM, ALTERN_FUNC ); HAL_GPIO_ConfigFunction((Pn_Type*)UARTn_TX_PORT, UARTn_TX_PIN_NUM, AFSRx_AF1 ); // default: 38400-8-N-1 HAL_UART_ConfigStructInit(&UARTn_Config); UARTn_Config.Baudrate = Baudrate; UARTn_Config.Databits = Databit; UARTn_Config.Parity = Paritybit; UARTn_Config.Stopbits = Stopbit; HAL_UART_Init((UARTn_Type*)UARTn_PERIPHERAL, &UARTn_Config); /* Enable UART Rx interrupt */ HAL_UART_ConfigInterrupt((UARTn_Type*)UARTn_PERIPHERAL, UARTn_INTCFG_RBR, ENABLE ); #if (UARTn_TX_INTERRUTP_ENABLE == TRUE) // Reset Tx Interrupt state Uartn_TxIntEnable = RESET; #else SW_Timer_Callback_Register(SW_TIMER_RUN_CONTINUE, 0, Uart1_Transmit_Process); #endif RingBuffer_Initialization(&RingBuffer_Rx, false, UARTn_RX_BUFFER_SIZE, &Rx_Buffer[0]); RingBuffer_Initialization(&RingBuffer_Tx, false, UARTn_TX_BUFFER_SIZE, &Tx_Buffer[0]); NVIC_SetPriority(UARTn_INTERRUPT_HANDLER, UARTn_INTERRUPT_PRIORITY); NVIC_EnableIRQ(UARTn_INTERRUPT_HANDLER ); HAL_INT_EInt_MaskDisable(UARTn_INTERRUPT_MASK); } void Uart1_Transmit(uint8_t TxData) { #if (UARTn_TX_INTERRUTP_ENABLE == TRUE) /* Temporarily lock out UART transmit interrupts during this read so the UART transmit interrupt won't cause problems with the index values */ HAL_UART_ConfigInterrupt((UARTn_Type*)UARTn_PERIPHERAL, UARTn_INTCFG_THRE, DISABLE ); RingBuffer_Enqueue(&RingBuffer_Tx, TxData); /* * Check if current Tx interrupt enable is reset, * that means the Tx interrupt must be re-enabled * due to call IntTransmit() function to trigger * this interrupt type */ if(Uartn_TxIntEnable == RESET) { Uart1_Init_TransmitSet(); } /* * Otherwise, re-enables Tx Interrupt */ else { HAL_UART_ConfigInterrupt((UARTn_Type*)UARTn_PERIPHERAL, UARTn_INTCFG_THRE, ENABLE ); } #else RingBuffer_Enqueue(&RingBuffer_Tx, TxData); #endif } void Uart1_TransmitData(uint8_t* pTxData, uint32_t TxLen) { uint32_t i; #if (UARTn_TX_INTERRUTP_ENABLE == TRUE) HAL_UART_ConfigInterrupt( ( UARTn_Type* )UARTn_PERIPHERAL, UARTn_INTCFG_THRE, DISABLE ); for(i = 0 ; i < TxLen ; i++) RingBuffer_Enqueue(&RingBuffer_Tx, pTxData[i]); if(Uartn_TxIntEnable == RESET) { Uart1_Init_TransmitSet(); } else { HAL_UART_ConfigInterrupt( ( UARTn_Type* )UARTn_PERIPHERAL, UARTn_INTCFG_THRE, ENABLE ); } #else for(i = 0 ; i < TxLen ; i++) RingBuffer_Enqueue(&RingBuffer_Tx, pTxData[i]); #endif } #if (UARTn_TX_INTERRUTP_ENABLE == TRUE) static void Uart1_Init_TransmitSet(void) { // Disable THRE interrupt HAL_UART_ConfigInterrupt( ( UARTn_Type* )UARTn_PERIPHERAL, UARTn_INTCFG_THRE, DISABLE ); /* Wait until THR empty */ while( HAL_UART_CheckBusy( ( UARTn_Type* )UARTn_PERIPHERAL ) == SET ); while(RingBuffer_Get_DataSize(&RingBuffer_Tx) != 0) { uint8_t TxData; RingBuffer_GetData(&RingBuffer_Tx, &TxData); if(HAL_UART_Transmit( ( UARTn_Type* )UARTn_PERIPHERAL, &TxData, 1, NONE_BLOCKING ) ) { /* Update transmit ring FIFO tail pointer */ RingBuffer_PopData(&RingBuffer_Tx); break; } else { break; } } /* If there is no more data to send, disable the transmit interrupt - else enable it or keep it enabled */ if(RingBuffer_Get_DataSize(&RingBuffer_Tx) == 0) { HAL_UART_ConfigInterrupt((UARTn_Type*)UARTn_PERIPHERAL, UARTn_INTCFG_THRE, DISABLE ); // Reset Tx Interrupt state Uartn_TxIntEnable = RESET; } else { // Set Tx Interrupt state Uartn_TxIntEnable = SET; HAL_UART_ConfigInterrupt((UARTn_Type*)UARTn_PERIPHERAL, UARTn_INTCFG_THRE, ENABLE ); } } #else static void Uart1_Transmit_Process(void) { if(RingBuffer_Get_DataSize(&RingBuffer_Tx) != 0) { uint8_t TxData; RingBuffer_GetData(&RingBuffer_Tx, &TxData); if(HAL_UART_Transmit((UARTn_Type*)UARTn_PERIPHERAL, &TxData, 1, NONE_BLOCKING)) { /* Update transmit ring FIFO tail pointer */ RingBuffer_PopData(&RingBuffer_Tx); } } } #endif static void Uart1_Receive_Handler(void) { uint8_t tmpc; uint32_t rLen; while(1) { rLen = HAL_UART_Receive((UARTn_Type*)UARTn_PERIPHERAL, &tmpc, 1, NONE_BLOCKING ); if (rLen) { RingBuffer_Enqueue(&RingBuffer_Rx, tmpc); } else { break; } } } /*********************************************************************//** * @brief UART1 interrupt handler sub-routine * @param[in] None * @return None **********************************************************************/ void UART1_Handler(void) { uint32_t intsrc, tmp; /* Determine the interrupt source */ intsrc = UARTn_PERIPHERAL->IIR; tmp = intsrc & UARTn_IIR_INTID_MASK; // Receiver Line Status if(tmp == UARTn_IIR_INTID_RLS) // error(Overrun, Parity, Framing or Break Error) { } else if(tmp == UARTn_IIR_INTID_RDA) // Receiver Data Available { Uart1_Receive_Handler(); } else if(tmp == UARTn_IIR_INTID_THRE) // Transmitter Holding Register Empty { #if (UARTn_TX_INTERRUTP_ENABLE == TRUE) Uart1_Init_TransmitSet(); #endif } else if(tmp == UARTn_IIR_INTID_TXE) // Transmitter Register Empty { } } uint32_t Uart1_Get_RecvDataCount(void) { return RingBuffer_Get_DataSize(&RingBuffer_Rx); } uint8_t Uart1_Get_RecvData(void) { uint8_t retData; RingBuffer_Dequeue(&RingBuffer_Rx, &retData); return retData; }