/** ****************************************************************************** * @file rs485_comm.c * @author MCD Application Team * @version V1.0.0 * @date 05/12/2011 * @brief A Console based on a Telnet connection * The application works as a server which wait for the client request ****************************************************************************** * @copy * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * *

© COPYRIGHT 2009 STMicroelectronics

*/ /* Includes ------------------------------------------------------------------*/ #include #include "rs485_comm.h" #include "uart3.h" #include "delay.h" #include "console.h" #include "asutil.h" #include "modbus.h" #include "malloc.h" #include "device_param.h" #include "io.h" /* Private typedef -----------------------------------------------------------*/ typedef struct { u8 dev_addr; u8 function; u16 start_addr; u16 qty_reg; u8 crch; u8 crcl; } TReqRtuPacket, *PReqRtuPacket; typedef struct { u8 *Buffer; u16 Tick; u16 Timeout; u16 Position; u8 Commfail; u8 Addr; u8 Mode; u8 TxFlag; u8 RxFlag; u8 BufferStart; u8 MsgPrint; u8 DataPrint; u8 BakMsgPrint; u8 BakDataPrint; } TRs485Config, *PRs485Config; /* Private define ------------------------------------------------------------*/ #define RS485_TASK_TIME 20 // 20ms TASK #define RS485_RX_TIMEOUT 100 // 100ms TimeOut #define RS485_RX_DELAY 5 #define RS485_MAX_TIMEOUT 20 #define RS485_MAX_BUFFER_SIZE 512 /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ TRs485Config Rs485Config; /* Private function prototypes -----------------------------------------------*/ void Rs485CommProcess(void); void Rs485SendData(u8 *data, u16 len); void Rs485PacketInit(void); u8 GetRs485Packet(void); void Rs485RxProcess(void); /* Private functions ---------------------------------------------------------*/ void Rs485CommInit(void) { memset(&Rs485Config, 0x00, sizeof(TRs485Config)); Rs485Config.Buffer = mymalloc(RS485_MAX_BUFFER_SIZE); Rs485Config.Addr = GetDevAddrIO(); uart3_init(9600); } /** * @brief Initialize the Ethernet Module communication application * @param None * @retval None */ void App_TaskRs485Comm(void) { Rs485CommInit(); while (DEF_TRUE) { Rs485CommProcess(); delay_os_ms(RS485_TASK_TIME); } } void Rs485CommProcess(void) { if (GetRs485Packet()) { Rs485RxProcess(); } Rs485PacketInit(); } void Rs485RxProcess(void) { u16 wlen; u8 *sdata; if ((Rs485Config.MsgPrint == true)&&(screenmode == DIAG_MODE)) UART_DATA_PRINT(5, Rs485Config.Buffer, Rs485Config.Position, RX_PRINT); if (ModBusPacketCheck(Rs485Config.Buffer, Rs485Config.Position, Rs485Config.Addr)) { switch (Rs485Config.Buffer[1]) { case READ_HOLDING_REG: if ((Rs485Config.MsgPrint == true)&&(screenmode == DIAG_MODE)) printf("[READ REGISTER]"); sdata = ModBusReadRegister(Rs485Config.Buffer, Rs485Config.Position, &wlen); if (sdata != NULL) { Rs485SendData(sdata, wlen); myfree(sdata); } break; case PRESET_MULTI_REG: if ((Rs485Config.MsgPrint == true)&&(screenmode == DIAG_MODE)) printf("[WRITE REGISTER]"); sdata = ModBusWriteRegister(Rs485Config.Buffer, Rs485Config.Position, &wlen); if (sdata != NULL) { Rs485SendData(sdata, wlen); myfree(sdata); } break; } } } void Rs485SendData(u8 *data, u16 len) { UART3_PutStr(data, len); if ((Rs485Config.MsgPrint == true)&&(screenmode == DIAG_MODE)) UART_DATA_PRINT(3, data, len, TX_PRINT); } void Rs485PacketInit(void) { Rs485Config.BufferStart = false; Rs485Config.Position = 0; } u8 GetRs485Packet(void) { u8 one; u16 count; count = 0; if (Rs485Config.Buffer == NULL) { printf("\r\n[MEM ERROR] : RS485 Comm"); return false; } while(1) { if (UART3_GetChar(&one) == SUCCESS) { count = 0; if ((Rs485Config.DataPrint == true)&&(screenmode == DIAG_MODE)) { if (Rs485Config.BufferStart == false) printf("\r\n[BMCU RECV] : "); printf("%02X ", one); } if (Rs485Config.Position >= RS485_MAX_BUFFER_SIZE) { Rs485PacketInit(); return false; } if (Rs485Config.BufferStart == false) { if ((one == Rs485Config.Addr)||(one == 0xFF)) { Rs485Config.Position = 0; Rs485Config.Buffer[Rs485Config.Position] = one; Rs485Config.Position++; Rs485Config.BufferStart = true; } } else { Rs485Config.Buffer[Rs485Config.Position++] = one; } } else { if ((Rs485Config.BufferStart == true)&&(count > 0)) return true; count++; if (count >= (RS485_RX_TIMEOUT / RS485_RX_DELAY)) return false; delay_os_ms(RS485_RX_DELAY); } } } #ifdef CONSOLE_DEBUG void DDisplay_Rs485Comm(u8 p) { if (p ||(Rs485Config.BakMsgPrint != Rs485Config.MsgPrint)) { if (Rs485Config.MsgPrint) GreenOutXY ( 27, 10, (u8 *)"ENABLE "); else NormalOutXY( 27, 10, (u8 *)"DISABLE"); Rs485Config.BakMsgPrint = Rs485Config.MsgPrint; } if (p ||(Rs485Config.BakDataPrint != Rs485Config.DataPrint)) { if (Rs485Config.DataPrint)GreenOutXY ( 71, 10, (u8 *)"ENABLE "); else NormalOutXY( 71, 10, (u8 *)"DISABLE"); Rs485Config.BakDataPrint = Rs485Config.DataPrint; } } u8 DRs485CommCommand(u8 cmd) { u8 result = 1; switch (cmd) { case '4': // RS485 COMM MSG MONITOR if (Rs485Config.MsgPrint == true) { Rs485Config.MsgPrint = false; UserMessage("[MESSAGE]: BMCU MSG PRINT DISABLE"); } else { Rs485Config.MsgPrint = true; UserMessage("[MESSAGE]: BMCU MSG PRINT ENABLE"); } break; case '5': // RS485 COMM DATA MONITOR if (Rs485Config.DataPrint == true) { Rs485Config.DataPrint = false; UserMessage("[MESSAGE]: BMCU DATA PRINT DISABLE"); } else { Rs485Config.DataPrint = true; UserMessage("[MESSAGE]: BMCU DATA PRINT ENABLE"); } break; default: result = 0; break; } return result; } #endif //#ifdef CONSOLE_DEBUG /******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/