123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- #include "port.h"
- #include "main.h"
- #include "cmsis_os2.h"
- /* ----------------------- Modbus includes ----------------------------------*/
- #include "mb.h"
- #include "mbport.h"
- /* ----------------------- Static variables ---------------------------------*/
- static volatile uint8_t rx_buff[256];
- static int rx_index;
- static int put_index;
- static osThreadId_t receiveDataHandle;
- static osEventFlagsId_t xSerialEventHandle;
- extern UART_HandleTypeDef huart3;
- /* ----------------------- Defines ------------------------------------------*/
- #define EVENT_MBSLAVE_HANDLE_RECEIVED_DATA 0x00000001UL
- #define huart huart3
- #define RS485_SLAVE_TX_MODE() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET)
- #define RS485_SLAVE_RX_MODE() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET)
- /* ----------------------- static functions ---------------------------------*/
- static void handleReceivedDataTask(void *argument);
- /* ----------------------- Start implementation -----------------------------*/
- BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
- eMBParity eParity)
- {
- /* set serial configure parameter */
- huart.Init.BaudRate = ulBaudRate;
- huart.Init.WordLength = ucDataBits == 8 ? UART_WORDLENGTH_8B : UART_WORDLENGTH_9B;
- huart.Init.StopBits = UART_STOPBITS_1;
- switch (eParity)
- {
- case MB_PAR_NONE:
- huart.Init.Parity = UART_PARITY_NONE;
- break;
- case MB_PAR_ODD:
- huart.Init.Parity = UART_PARITY_ODD;
- break;
- case MB_PAR_EVEN:
- huart.Init.Parity = UART_PARITY_EVEN;
- break;
- default:
- return FALSE;
- }
- huart.Init.Mode = UART_MODE_TX_RX;
- huart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
- huart.Init.OverSampling = UART_OVERSAMPLING_16;
- /* open serial device */
- if (HAL_UART_Init(&huart) != HAL_OK)
- {
- Error_Handler();
- return FALSE;
- }
- return TRUE;
- }
- void vMBPortSerialEnable(BOOL xRxEnable, BOOL xTxEnable)
- {
- if (xRxEnable)
- {
- /* switch 485 to receive mode */
- RS485_SLAVE_RX_MODE();
- __HAL_UART_ENABLE_IT(&huart,UART_IT_RXNE);
- }
- else
- {
- /* switch 485 to transmit mode */
- RS485_SLAVE_TX_MODE();
- __HAL_UART_DISABLE_IT(&huart,UART_IT_RXNE);
- }
- if (xTxEnable)
- {
- __HAL_UART_ENABLE_IT(&huart,UART_IT_TXE);
- }
- else
- {
- __HAL_UART_DISABLE_IT(&huart,UART_IT_TXE);
- }
- }
- void vMBPortClose(void)
- {
- HAL_UART_AbortReceive_IT(&huart);
- HAL_UART_AbortTransmit_IT(&huart);
- }
- BOOL xMBPortSerialPutByte(CHAR ucByte)
- {
- if(HAL_UART_Transmit (&huart ,(uint8_t *)&ucByte,1,0x01) != HAL_OK )
- return FALSE ;
- else
- return TRUE;
- }
- /*
- * A Function to send all bytes in one call.
- */
- BOOL xMBPortSerialPutBytes(volatile UCHAR *ucByte, USHORT usSize)
- {
- if(HAL_UART_Transmit (&huart ,(uint8_t *)&ucByte,usSize,1000) != HAL_OK )
- return FALSE ;
- else
- return TRUE;
- }
- BOOL xMBPortSerialGetByte(CHAR * pucByte)
- {
- // *pucByte = rx_buff[rx_index++];
- //
- // return TRUE;
- if(HAL_UART_Receive (&huart ,(uint8_t *)pucByte,1,0x01) != HAL_OK )
- return FALSE ;
- else
- return TRUE;
- }
- /*
- * Create an interrupt handler for the transmit buffer empty interrupt
- * (or an equivalent) for your target processor. This function should then
- * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that
- * a new character can be sent. The protocol stack will then call
- * xMBPortSerialPutByte( ) to send the character.
- */
- void prvvUARTTxReadyISR(void)
- {
- pxMBFrameCBTransmitterEmpty();
- }
- /*
- * Create an interrupt handler for the receive interrupt for your target
- * processor. This function should then call pxMBFrameCBByteReceived( ). The
- * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the
- * character.
- *
- * quanghona: This function is called when IDLE is detected. thus will then
- * trigger the received message handler.
- */
- void prvvUARTRxISR(void)
- {
- //osEventFlagsSet(xSerialEventHandle, EVENT_MBSLAVE_HANDLE_RECEIVED_DATA);
- pxMBFrameCBByteReceived( );
- }
- /*
- * Create an interrupt handler for the receive character for your target processor.
- * This function should store data to a buffer for received message thread to
- * handle later.
- */
- void prvvUARTRxReceiveCharISR(CHAR data)
- {
- rx_buff[put_index++] = data;
- }
- /*
- * A thread to handle the received message.
- * This thread is wait until a received message flag is set, then it will call
- * pxMBFrameCBByteReceived() until all characters in the receive buffer is handled.
- */
- static void handleReceivedDataTask(void *argument)
- {
- while (1)
- {
- osEventFlagsWait(xSerialEventHandle, EVENT_MBSLAVE_HANDLE_RECEIVED_DATA, osFlagsWaitAny, osWaitForever);
- while (put_index > 0) {
- pxMBFrameCBByteReceived();
- put_index--;
- }
- }
- }
|