/**
******************************************************************************
* @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****/