#include "usart11_rs485.h" #include "ring_buffer.h" #include "sw_timer.h" #define USARTn_TX_INTERRUTP_ENABLE FALSE #define USARTn_PERIPHERAL USART11 #define USARTn_INTERRUPT_HANDLER USART11_IRQn #define USARTn_INTERRUPT_MASK MSK_USART11 #define USARTn_INTERRUPT_PRIORITY 3 #define USARTn_TX_PORT PD #define USARTn_TX_PIN_NUM 2 #define USARTn_RX_PORT PD #define USARTn_RX_PIN_NUM 3 #define USARTn_TX_BUFFER_SIZE 100 #define USARTn_RX_BUFFER_SIZE 100 #define USARTn_RS485_REDE_PORT (Pn_Type*)PD #define USARTn_RS485_REDE_NUM 4 #define USARTn_RS485_RECEIVE HAL_GPIO_ClearPin(USARTn_RS485_REDE_PORT, _BIT(USARTn_RS485_REDE_NUM)) #define USARTn_RS485_TRANSMIT HAL_GPIO_SetPin(USARTn_RS485_REDE_PORT, _BIT(USARTn_RS485_REDE_NUM)) static uint8_t Tx_Buffer[USARTn_TX_BUFFER_SIZE]; static uint8_t Rx_Buffer[USARTn_RX_BUFFER_SIZE]; static RING_BUFFER RingBuffer_Tx; static RING_BUFFER RingBuffer_Rx; #if (USARTn_TX_INTERRUTP_ENABLE == TRUE) static volatile uint8_t Usartn_TxIntEnable = FALSE; static void Usart11_Init_TransmitSet(void); #else static void Usart11_Transmit_Process(void); #endif static void Usart11_Receive_Handler(void); void Usart11_Initialization(uint32_t Baudrate, USART1n_DATA_BIT_Type Databit, USART1n_PARITY_BIT_Type Paritybit, USART1n_STOP_BIT_Type Stopbit) { USART1n_CFG_Type USART1n_Config; /* * Initialize USART10 pin connect */ HAL_GPIO_ConfigOutput( ( Pn_Type* )USARTn_RX_PORT, USARTn_RX_PIN_NUM, ALTERN_FUNC ); HAL_GPIO_ConfigFunction( ( Pn_Type* )USARTn_RX_PORT, USARTn_RX_PIN_NUM, AFSRx_AF1 ); HAL_GPIO_ConfigPullup( ( Pn_Type* )USARTn_RX_PORT, USARTn_RX_PIN_NUM, PUPDx_EnablePU ); HAL_GPIO_ConfigOutput( ( Pn_Type* )USARTn_TX_PORT, USARTn_TX_PIN_NUM, ALTERN_FUNC ); HAL_GPIO_ConfigFunction( ( Pn_Type* )USARTn_TX_PORT, USARTn_TX_PIN_NUM, AFSRx_AF1 ); // default: 38400-8-N-1 HAL_USART_UART_Mode_Config(&USART1n_Config); USART1n_Config.Baudrate = Baudrate; USART1n_Config.Databits = Databit; USART1n_Config.Parity = Paritybit; USART1n_Config.Stopbits = Stopbit; HAL_USART_Init( ( USART1n_Type* )USARTn_PERIPHERAL, &USART1n_Config ); HAL_GPIO_ConfigOutput(USARTn_RS485_REDE_PORT, USARTn_RS485_REDE_NUM, PUSH_PULL_OUTPUT); HAL_GPIO_ConfigPullup(USARTn_RS485_REDE_PORT, USARTn_RS485_REDE_NUM, PUPDx_EnablePU); USARTn_RS485_RECEIVE; /* Enable UART Rx interrupt */ HAL_USART_ConfigInterrupt((USART1n_Type*)USARTn_PERIPHERAL, USART1n_INTCFG_RXC, ENABLE ); #if (USARTn_TX_INTERRUTP_ENABLE == TRUE) HAL_USART_ConfigInterrupt((USART1n_Type*)USARTn_PERIPHERAL, USART1n_INTCFG_TXC, ENABLE ); Usartn_TxIntEnable = RESET; #else SW_Timer_Callback_Register(SW_TIMER_RUN_CONTINUE, 0, Usart11_Transmit_Process); #endif RingBuffer_Initialization(&RingBuffer_Rx, false, USARTn_RX_BUFFER_SIZE, &Rx_Buffer[0]); RingBuffer_Initialization(&RingBuffer_Tx, false, USARTn_TX_BUFFER_SIZE, &Tx_Buffer[0]); NVIC_SetPriority(USARTn_INTERRUPT_HANDLER, USARTn_INTERRUPT_PRIORITY); NVIC_EnableIRQ(USARTn_INTERRUPT_HANDLER); HAL_INT_EInt_MaskDisable(USARTn_INTERRUPT_MASK); HAL_USART_Enable((USART1n_Type*)USARTn_PERIPHERAL, ENABLE ); } void Usart11_Transmit(uint8_t TxData) { #if (USARTn_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_USART_ConfigInterrupt((USART1n_Type* )USARTn_PERIPHERAL, USART1n_INTCFG_TXC, 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(Usartn_TxIntEnable == RESET) { Usart11_Init_TransmitSet(); } /* * Otherwise, re-enables Tx Interrupt */ else { HAL_USART_ConfigInterrupt((USART1n_Type*)USARTn_PERIPHERAL, USART1n_INTCFG_TXC, ENABLE ); } #else RingBuffer_Enqueue(&RingBuffer_Tx, TxData); #endif } void Usart11_TransmitData(uint8_t* pTxData, uint32_t TxLen) { uint32_t i; #if (USARTn_TX_INTERRUTP_ENABLE == TRUE) HAL_USART_ConfigInterrupt((USART1n_Type* )USARTn_PERIPHERAL, USART1n_INTCFG_TXC, DISABLE ); for(i = 0 ; i < TxLen ; i++) RingBuffer_Enqueue(&RingBuffer_Tx, pTxData[i]); if(Usartn_TxIntEnable == RESET) { Usart11_Init_TransmitSet(); } else { HAL_USART_ConfigInterrupt((USART1n_Type*)USARTn_PERIPHERAL, USART1n_INTCFG_TXC, ENABLE ); } #else for(i = 0 ; i < TxLen ; i++) RingBuffer_Enqueue(&RingBuffer_Tx, pTxData[i]); #endif } #if (USARTn_TX_INTERRUTP_ENABLE == TRUE) static void Usart11_Init_TransmitSet(void) { // Disable THRE interrupt HAL_USART_ConfigInterrupt((USART1n_Type* )USARTn_PERIPHERAL, USART1n_INTCFG_TXC, DISABLE ); /* Wait until THR empty */ while( HAL_USART_CheckBusy((USART1n_Type*)USARTn_PERIPHERAL ) == SET ); while(RingBuffer_Get_DataSize(&RingBuffer_Tx) != 0) { uint8_t TxData; RingBuffer_GetData(&RingBuffer_Tx, &TxData); if(HAL_USART_Transmit((USART1n_Type*)USARTn_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_USART_ConfigInterrupt((USART1n_Type* )USARTn_PERIPHERAL, USART1n_INTCFG_TXC, DISABLE ); // Reset Tx Interrupt state Usartn_TxIntEnable = RESET; } else { // Set Tx Interrupt state Usartn_TxIntEnable = SET; HAL_USART_ConfigInterrupt((USART1n_Type*)USARTn_PERIPHERAL, USART1n_INTCFG_TXC, ENABLE ); } } #else static void Usart11_Transmit_Process(void) { uint32_t TxCount = RingBuffer_Get_DataSize(&RingBuffer_Tx); if(TxCount != 0) { uint8_t TxData; USARTn_RS485_TRANSMIT; RingBuffer_GetData(&RingBuffer_Tx, &TxData); if(TxCount <= 2) { if(HAL_USART_CheckBusy((UARTn_Type *)USARTn_PERIPHERAL) == RESET) { if(HAL_USART_Transmit((USART1n_Type*)USARTn_PERIPHERAL, &TxData, 1, BLOCKING)) { /* Update transmit ring FIFO tail pointer */ RingBuffer_PopData(&RingBuffer_Tx); } } } else { if(HAL_USART_Transmit((USART1n_Type*)USARTn_PERIPHERAL, &TxData, 1, NONE_BLOCKING)) { /* Update transmit ring FIFO tail pointer */ RingBuffer_PopData(&RingBuffer_Tx); } } } else { if(HAL_USART_CheckBusy((UARTn_Type *)USARTn_PERIPHERAL) == RESET) USARTn_RS485_RECEIVE; } } #endif static void Usart11_Receive_Handler(void) { uint8_t tmpc; uint32_t rLen; while(1) { rLen = HAL_USART_Receive((USART1n_Type*)USARTn_PERIPHERAL, &tmpc, 1, NONE_BLOCKING ); if (rLen) { RingBuffer_Enqueue(&RingBuffer_Rx, tmpc); } else { break; } } } /*-------------------------------------------------------------------------*//** * @brief USART10_IRQHandler_IT * @param None * @return None *//*-------------------------------------------------------------------------*/ void USART11_Handler( void ) { uint32_t intsrc, tmp; /* Determine the interrupt source */ intsrc = HAL_USART_GetStatus( ( USART1n_Type* )USARTn_PERIPHERAL ); tmp = intsrc & USART1n_SR_BITMASK; // Receive Data Available or Character time-out if( ( tmp & USART1n_SR_RXC ) == USART1n_SR_RXC ) { Usart11_Receive_Handler(); } #if (USARTn_TX_INTERRUTP_ENABLE == TRUE) // Transmit Holding Empty if( ( tmp & USART1n_SR_TXC ) == USART1n_SR_TXC ) { Usart11_Init_TransmitSet(); } #endif } uint32_t Usart11_Get_RecvDataCount(void) { return RingBuffer_Get_DataSize(&RingBuffer_Rx); } uint8_t Usart11_Get_RecvData(void) { uint8_t retData; RingBuffer_Dequeue(&RingBuffer_Rx, &retData); return retData; }