#include "port.h" #include "main.h" #include "cmsis_os2.h" /* ----------------------- Modbus includes ----------------------------------*/ #include "mb.h" #include "mbport.h" #include /* ----------------------- Defines ------------------------------------------*/ #define EVENT_MBSLAVE_HANDLE_RECEIVED_DATA 0x00000001UL /* ----------------------- Start implementation -----------------------------*/ BOOL xMBPortSerialInit(eMBRTUSlaveObj *pObj) { /* set serial configure parameter */ pObj->pUartHandle.Init.BaudRate = pObj->ulBaudRate; pObj->pUartHandle.Init.WordLength = UART_WORDLENGTH_8B ; pObj->pUartHandle.Init.StopBits = UART_STOPBITS_1; switch (pObj->eParity) { case MB_PAR_NONE: pObj->pUartHandle.Init.Parity = UART_PARITY_NONE; break; case MB_PAR_ODD: pObj->pUartHandle.Init.Parity = UART_PARITY_ODD; break; case MB_PAR_EVEN: pObj->pUartHandle.Init.Parity = UART_PARITY_EVEN; break; default: return FALSE; } pObj->pUartHandle.Init.Mode = UART_MODE_TX_RX; pObj->pUartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; pObj->pUartHandle.Init.OverSampling = UART_OVERSAMPLING_16; /* open serial device */ if (HAL_UART_Init(&pObj->pUartHandle) != HAL_OK) { Error_Handler(); return FALSE; } return TRUE; } void rs485_slave_rx_mode(eMBRTUSlaveObj * obj) { HAL_GPIO_WritePin(obj->enPort, obj->enPin, GPIO_PIN_RESET); } void rs485_slave_tx_mode(eMBRTUSlaveObj * obj) { HAL_GPIO_WritePin(obj->enPort, obj->enPin, GPIO_PIN_SET); } void vMBPortSerialEnable(eMBRTUSlaveObj * pObj, BOOL xRxEnable, BOOL xTxEnable) { if (xRxEnable) { /* switch 485 to receive mode */ rs485_slave_rx_mode(pObj); __HAL_UART_ENABLE_IT(&pObj->pUartHandle, UART_IT_RXNE); } else { /* switch 485 to transmit mode */ rs485_slave_tx_mode(pObj); __HAL_UART_DISABLE_IT(&pObj->pUartHandle, UART_IT_RXNE); } if (xTxEnable) { __HAL_UART_ENABLE_IT(&pObj->pUartHandle, UART_IT_TXE); } else { __HAL_UART_DISABLE_IT(&pObj->pUartHandle, UART_IT_TXE); } } void vMBPortClose(eMBRTUSlaveObj *pObj) { HAL_UART_AbortReceive_IT(&pObj->pUartHandle); HAL_UART_AbortTransmit_IT(&pObj->pUartHandle); } BOOL xMBPortSerialPutByte(eMBRTUSlaveObj *pObj, CHAR ucByte) { if (HAL_UART_Transmit(&pObj->pUartHandle, (uint8_t *) &ucByte, 1, 0x01) != HAL_OK) return FALSE; else return TRUE; } /* * A Function to send all bytes in one call. */ BOOL xMBPortSerialPutBytes(eMBRTUSlaveObj *pObj, volatile UCHAR *ucByte, USHORT usSize) { if (HAL_UART_Transmit(&pObj->pUartHandle, (uint8_t *) ucByte, usSize, 300) != HAL_OK) return FALSE; else return TRUE; } BOOL xMBPortSerialGetByte(eMBRTUSlaveObj *pObj, CHAR *pucByte) { if (HAL_UART_Receive(&pObj->pUartHandle, (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(eMBRTUSlaveObj *pObj) { pxMBFrameCBTransmitterEmpty(pObj); } /* * 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(eMBRTUSlaveObj *pObj) { pxMBFrameCBByteReceived(pObj); }