/**
* @file MODBUS_LOW_ATY.c
*
* @param Project DEVICE_GENERAL_ATY_LIB
*
* @author ATY
*
* @copyright
* - Copyright 2017 - 2026 MZ-ATY
* - This code follows:
* - MZ-ATY Various Contents Joint Statement -
*
* https://mengze.top/MZ-ATY_VCJS
* - CC 4.0 BY-NC-SA -
*
* https://creativecommons.org/licenses/by-nc-sa/4.0/
* - Your use will be deemed to have accepted the terms of this statement.
*
* @brief functions of modbus for all device
*
* @note 4 byte per reg, save float or uint32
*
* @version
* - 1_01_221029 > ATY
* -# Preliminary version, first Release
********************************************************************************
*/
#ifndef __MODBUS_LOW_ATY_C
#define __MODBUS_LOW_ATY_C
#include "MODBUS_LOW_ATY.h"
/******************************* For user *************************************/
/******************************************************************************/
#if defined (MODBUS_FLOAT_MODE)
float mbRegHoding[MODBUS_REG_HOLDING_SIZE] = {0};
/**
* @brief modbus process with float
* @note only make 03/06/10 function code, others will return err 01
*/
void Modbus_Process(uint8_t* buf, uint8_t len)
{
uint8_t sendBuf[(MODBUS_REG_HOLDING_SIZE * 4) + 4] = {0x00};
uint16_t snedBufSize = 4;
if(len < 4) return; // check buf min size
if(buf[0] != MODBUS_ADDR) return; // check addr
if(CheckCrc16Modbus(buf, len)) return; // check crc
sendBuf[0] = buf[0];
sendBuf[1] = buf[1];
switch(buf[1]) // check function code
{
// case MODBUS_FUNC_READ_COILS:{break; }
// case MODBUS_FUNC_READ_DISCRETE_INPUTS:{break; }
case MODBUS_FUNC_READ_HOLDING_REGISTERS:{
uint16_t i = 0, startAddr = 0, regCount = 0;
startAddr = ((buf[2] << 8) + buf[3]);
regCount = ((buf[4] << 8) + buf[5]);
if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){
sendBuf[1] = buf[1] + 0x80;
sendBuf[2] = 0x02;
snedBufSize = 6;
break;
}
sendBuf[2] = regCount * 4;
snedBufSize += 1;
for(i = 0; i < regCount; i++){
sendBuf[2 + (i * 4) + 1] = (uint32_t)(MUL_FLOAT * mbRegHoding[startAddr + i]) >> 24;
sendBuf[2 + (i * 4) + 2] = (uint32_t)(MUL_FLOAT * mbRegHoding[startAddr + i]) >> 16;
sendBuf[2 + (i * 4) + 3] = (uint32_t)(MUL_FLOAT * mbRegHoding[startAddr + i]) >> 8;
sendBuf[2 + (i * 4) + 4] = (uint32_t)(MUL_FLOAT * mbRegHoding[startAddr + i]);
snedBufSize += 4;
}
break; }
// case MODBUS_FUNC_READ_INPUT_REGISTERS:{break; }
// case MODBUS_FUNC_WRITE_SINGLE_COIL:{break; }
case MODBUS_FUNC_WRITE_SINGLE_HOLDING_REGISTERS:{
uint16_t startAddr = 0;
float regValue = 0.0;
startAddr = (((uint16_t)buf[2] << 8) + (uint16_t)buf[3]);
if(startAddr >= MODBUS_REG_HOLDING_SIZE){
sendBuf[1] = buf[1] + 0x80;
sendBuf[2] = 0x02;
snedBufSize = 6;
break;
}
regValue = (((uint32_t)buf[4] << 24) + ((uint32_t)buf[5] << 16) + ((uint32_t)buf[6] << 8) + (uint32_t)buf[7]);
mbRegHoding[startAddr] = regValue / MUL_FLOAT;
// sendBuf[2] = buf[2];
// sendBuf[3] = buf[3];
// sendBuf[4] = buf[4];
// sendBuf[5] = buf[5];
// sendBuf[6] = buf[6];
// sendBuf[7] = buf[7];
sendBuf[2] = startAddr >> 8;
sendBuf[3] = startAddr;
sendBuf[4] = ((uint32_t)regValue >> 24);
sendBuf[5] = ((uint32_t)regValue >> 16);
sendBuf[6] = ((uint32_t)regValue >> 8);
sendBuf[7] = (uint32_t)regValue;
snedBufSize += 6;
break; }
// case MODBUS_FUNC_WRITE_MULTY_HOLDING_REGISTERS:{
// uint16_t i = 0, startAddr = 0, regCount = 0;
// startAddr = ((buf[2] << 8) + buf[3]);
// regCount = ((buf[4] << 8) + buf[5]);
// if(startAddr + regCount - 1 >= MODBUS_REG_HOLDING_SIZE){
// sendBuf[1] = buf[1] + 0x80;
// sendBuf[2] = 0x02;
// snedBufSize = 6;
// break;
// }
// for(i = 0; i < regCount; i++)
// mbRegHoding[startAddr + i] =
// ((buf[7 + (i * 2)] << 8) + buf[8 + (i * 2)]) / MUL_FLOAT;
// sendBuf[2] = startAddr >> 8;
// sendBuf[3] = startAddr;
// sendBuf[4] = regCount >> 8;
// sendBuf[5] = regCount;
// snedBufSize += 4;
// break; }
default:{
sendBuf[1] = buf[1] + 0x80;
sendBuf[2] = 0x01;
snedBufSize = 6;
break; }
}
sendBuf[snedBufSize - 2] = GenCrc16ModbusHL(sendBuf, snedBufSize - 2, 1);
sendBuf[snedBufSize - 1] = GenCrc16ModbusHL(sendBuf, snedBufSize - 2, 0);
UartSendBytes(sendBuf, snedBufSize);
}
#elif defined(MODBUS_FLOAT_CODE_MODE)
__XDATA float mbRegHoding[MODBUS_REG_HOLDING_SIZE] = {0};
union{ float f_t; uint8_t u8_t[4]; }mbFloatChange_u;
/**
* @brief modbus process with float
* @note only make 03/06/10 function code, others will return err 01
*/
void Modbus_Process(uint8_t* buf, uint8_t len)
{
uint8_t sendBuf[(MODBUS_REG_HOLDING_SIZE * 4) + 4] = {0x00};
uint16_t sendBufSize = 4;
if(len < 4) return; // check buf min size
if(buf[0] != MODBUS_ADDR) return; // check addr
if(CheckCrc16Modbus(buf, len)) return; // check crc
sendBuf[0] = buf[0];
sendBuf[1] = buf[1];
switch(buf[1]) // check function code
{
// case MODBUS_FUNC_READ_COILS:{break; }
// case MODBUS_FUNC_READ_DISCRETE_INPUTS:{break; }
case MODBUS_FUNC_READ_HOLDING_REGISTERS:{
uint16_t i = 0, startAddr = 0, regCount = 0;
startAddr = ((buf[2] << 8) + buf[3]);
regCount = ((buf[4] << 8) + buf[5]);
if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){
sendBuf[1] = buf[1] + 0x80;
sendBuf[2] = 0x02;
sendBufSize = 6;
break;
}
sendBuf[2] = regCount * 4;
sendBufSize += 1;
for(i = 0; i < regCount; i++){
mbFloatChange_u.f_t = mbRegHoding[startAddr + i];
#ifdef BIG_ENDIAN
sendBuf[2 + (i * 4) + 1] = mbFloatChange_u.u8_t[0];
sendBuf[2 + (i * 4) + 2] = mbFloatChange_u.u8_t[1];
sendBuf[2 + (i * 4) + 3] = mbFloatChange_u.u8_t[2];
sendBuf[2 + (i * 4) + 4] = mbFloatChange_u.u8_t[3];
#else
sendBuf[2 + (i * 4) + 1] = mbFloatChange_u.u8_t[3];
sendBuf[2 + (i * 4) + 2] = mbFloatChange_u.u8_t[2];
sendBuf[2 + (i * 4) + 3] = mbFloatChange_u.u8_t[1];
sendBuf[2 + (i * 4) + 4] = mbFloatChange_u.u8_t[0];
#endif
sendBufSize += 4;
// sendBufSize += 4; // aty240117
}
break; }
// case MODBUS_FUNC_READ_INPUT_REGISTERS:{break; }
// case MODBUS_FUNC_WRITE_SINGLE_COIL:{break; }
case MODBUS_FUNC_WRITE_SINGLE_HOLDING_REGISTERS:{
uint16_t startAddr = 0;
float regValue = 0.0;
startAddr = (((uint16_t)buf[2] << 8) + (uint16_t)buf[3]);
if(startAddr >= MODBUS_REG_HOLDING_SIZE){
sendBuf[1] = buf[1] + 0x80;
sendBuf[2] = 0x02;
sendBufSize = 6;
break;
}
#ifdef BIG_ENDIAN
mbFloatChange_u.u8_t[0] = buf[4];
mbFloatChange_u.u8_t[1] = buf[5];
mbFloatChange_u.u8_t[2] = buf[6];
mbFloatChange_u.u8_t[3] = buf[7];
#else
mbFloatChange_u.u8_t[3] = buf[4];
mbFloatChange_u.u8_t[2] = buf[5];
mbFloatChange_u.u8_t[1] = buf[6];
mbFloatChange_u.u8_t[0] = buf[7];
#endif
regValue = mbFloatChange_u.f_t;
mbRegHoding[startAddr] = regValue;
sendBuf[2] = startAddr >> 8;
sendBuf[3] = startAddr;
#ifdef BIG_ENDIAN
sendBuf[4] = mbFloatChange_u.u8_t[0];
sendBuf[5] = mbFloatChange_u.u8_t[1];
sendBuf[6] = mbFloatChange_u.u8_t[2];
sendBuf[7] = mbFloatChange_u.u8_t[3];
#else
sendBuf[4] = mbFloatChange_u.u8_t[3];
sendBuf[5] = mbFloatChange_u.u8_t[2];
sendBuf[6] = mbFloatChange_u.u8_t[1];
sendBuf[7] = mbFloatChange_u.u8_t[0];
#endif
sendBufSize += 6;
break; }
case MODBUS_FUNC_WRITE_MULTY_HOLDING_REGISTERS:{
uint16_t i = 0, startAddr = 0, regCount = 0;
startAddr = ((buf[2] << 8) + buf[3]);
regCount = ((buf[4] << 8) + buf[5]);
if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){
sendBuf[1] = buf[1] + 0x80;
sendBuf[2] = 0x02;
sendBufSize = 6;
break;
}
for(i = 0; i < regCount; i++)
{
float regValue = 0.0;
#ifdef BIG_ENDIAN
mbFloatChange_u.u8_t[0] = buf[6 + (i * 4) + 1];
mbFloatChange_u.u8_t[1] = buf[6 + (i * 4) + 2];
mbFloatChange_u.u8_t[2] = buf[6 + (i * 4) + 3];
mbFloatChange_u.u8_t[3] = buf[6 + (i * 4) + 4];
#else
mbFloatChange_u.u8_t[3] = buf[6 + (i * 4) + 1];
mbFloatChange_u.u8_t[2] = buf[6 + (i * 4) + 2];
mbFloatChange_u.u8_t[1] = buf[6 + (i * 4) + 3];
mbFloatChange_u.u8_t[0] = buf[6 + (i * 4) + 4];
#endif
regValue = mbFloatChange_u.f_t;
mbRegHoding[startAddr + i] = regValue;
}
sendBuf[2] = startAddr >> 8;
sendBuf[3] = startAddr;
sendBuf[4] = regCount >> 8;
sendBuf[5] = regCount;
sendBufSize += 4;
break; }
default:{
sendBuf[1] = buf[1] + 0x80;
sendBuf[2] = 0x01;
sendBufSize = 6;
break; }
}
sendBuf[sendBufSize - 2] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 1);
sendBuf[sendBufSize - 1] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 0);
UartSendBytes(sendBuf, sendBufSize);
}
#else
uint16_t mbRegHoding[MODBUS_REG_HOLDING_SIZE] = {0x0000};
/**
* @brief modbus process
* @note only make 03/06/10 function code, others will return err 01
*/
void Modbus_Process(uint8_t* buf, uint8_t len)
{
uint8_t sendBuf[(MODBUS_REG_HOLDING_SIZE * 2) + 4] = {0x00};
uint16_t sendBufSize = 4;
if(len < 4) return; // check buf min size
if(buf[0] != MODBUS_ADDR) return; // check addr
if(CheckCrc16Modbus(buf, len)) return; // check crc
sendBuf[0] = buf[0];
sendBuf[1] = buf[1];
switch(buf[1]) // check function code
{
// case MODBUS_FUNC_READ_COILS:{break; }
// case MODBUS_FUNC_READ_DISCRETE_INPUTS:{break; }
case MODBUS_FUNC_READ_HOLDING_REGISTERS:{
uint16_t i = 0, startAddr = 0, regCount = 0;
startAddr = (buf[2] << 8 + buf[3]);
regCount = (buf[4] << 8 + buf[5]);
if(startAddr + regCount - 1 >= MODBUS_REG_HOLDING_SIZE){
sendBuf[1] = buf[1] + 0x80;
sendBuf[2] = 0x02;
sendBufSize = 6;
break;
}
sendBuf[2] = regCount * 2;
sendBufSize += 1;
for(i = 0; i < regCount; i++){
sendBuf[3 + (i * 2)] = mbRegHoding[startAddr + i] >> 8;
sendBuf[3 + (i * 2) + 1] = mbRegHoding[startAddr + i];
sendBufSize += 2;
}
break; }
// case MODBUS_FUNC_READ_INPUT_REGISTERS:{break; }
// case MODBUS_FUNC_WRITE_SINGLE_COIL:{break; }
case MODBUS_FUNC_WRITE_SINGLE_HOLDING_REGISTERS:{
uint16_t startAddr = 0, regValue = 0;
startAddr = (buf[2] << 8 + buf[3]);
regValue = (buf[4] << 8 + buf[5]);
if(startAddr >= MODBUS_REG_HOLDING_SIZE){
sendBuf[1] = buf[1] + 0x80;
sendBuf[2] = 0x02;
sendBufSize = 6;
break;
}
mbRegHoding[startAddr] = regValue;
sendBuf[2] = startAddr >> 8;
sendBuf[3] = startAddr;
sendBuf[4] = regValue >> 8;
sendBuf[5] = regValue;
sendBufSize += 4;
break; }
case MODBUS_FUNC_WRITE_MULTY_HOLDING_REGISTERS:{
uint16_t i = 0, startAddr = 0, regCount = 0;
startAddr = (buf[2] << 8 + buf[3]);
regCount = (buf[4] << 8 + buf[5]);
if(startAddr + regCount - 1 >= MODBUS_REG_HOLDING_SIZE){
sendBuf[1] = buf[1] + 0x80;
sendBuf[2] = 0x02;
sendBufSize = 6;
break;
}
for(i = 0; i < regCount; i++)
mbRegHoding[startAddr + i] =
(buf[7 + (i * 2)] << 8 + buf[8 + (i * 2)]);
sendBuf[2] = startAddr >> 8;
sendBuf[3] = startAddr;
sendBuf[4] = regCount >> 8;
sendBuf[5] = regCount;
sendBufSize += 4;
break; }
default:{
sendBuf[1] = buf[1] + 0x80;
sendBuf[2] = 0x01;
sendBufSize = 6;
break;
}
}
sendBuf[sendBufSize - 2] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 0);
sendBuf[sendBufSize - 1] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 1);
UartSendBytes(sendBuf, sendBufSize);
}
#endif /* MODBUS_FLOAT_MODE */
#endif /* __MODBUS_LOW_ATY_C */
/******************************** End Of File *********************************/