You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

203 lines
4.7 KiB

#include "modbus_block_host.hpp"
#include "modbus_basic.hpp"
using namespace iflytop;
#define PRV_DEBUG 0
ModbusBlockHost::ModbusBlockHost() {}
ModbusBlockHost::~ModbusBlockHost() {}
void ModbusBlockHost::initialize(UART_HandleTypeDef *huart, Pin_t rePin) {
this->huart = huart;
this->rePin = rePin;
txEnGpio.initAsOutput(rePin, kxs_gpio_pulldown, false, false);
m_modbus_lock.init();
}
void ModbusBlockHost::enableDump(bool enable) { m_dump = enable; }
void ModbusBlockHost::cleanRxBuff() { //
HAL_StatusTypeDef status;
do {
status = HAL_UART_Receive(huart, rxbuff, 1, 1);
} while (status == HAL_OK);
}
void ModbusBlockHost::uarttx(uint8_t *buff, size_t len) {
ZASSERT(len < sizeof(txbuff));
if (m_dump) {
printf("uart_tx:\n");
for (size_t i = 0; i < len; i++) {
printf("%02x ", buff[i]);
}
printf("\n");
}
// HAL_UART_Transmit(huart, buff, len, 1000);
HAL_UART_DMAStop(huart);
if (rePin != PinNull) txEnGpio.setState(true);
HAL_StatusTypeDef ret = HAL_UART_Transmit_DMA(huart, buff, len);
ZASSERT(ret == HAL_OK);
while (true) {
if (HAL_UART_GetState(huart) == HAL_UART_STATE_READY) break;
}
if (rePin != PinNull) txEnGpio.setState(false);
return;
}
bool ModbusBlockHost::uartrx(uint8_t *buff, size_t len, int overtimems) {
HAL_StatusTypeDef status;
ZASSERT(len < sizeof(rxbuff));
status = HAL_UART_Receive_DMA(huart, buff, len);
if (status != HAL_OK) {
return false;
}
for (size_t i = 0; i < overtimems; i++) {
osDelay(3);
if (HAL_UART_GetState(huart) == HAL_UART_STATE_READY) {
if (m_dump) {
if (status == HAL_OK) {
printf("uart_rx:");
for (size_t i = 0; i < len; i++) {
printf("%02x ", buff[i]);
}
printf("\n");
}
}
return true;
}
}
#if PRV_DEBUG
printf("uart_rx timeout\n");
#endif
HAL_UART_Abort(huart);
HAL_UART_DMAStop(huart);
return false;
}
bool ModbusBlockHost::readReg03(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int overtimems) {
zlock_guard lck(m_modbus_lock);
txbuff[0] = slaveAddr;
txbuff[1] = 0x03;
txbuff[2] = regAddr >> 8;
txbuff[3] = regAddr & 0xff;
txbuff[4] = 0x00;
txbuff[5] = 0x01;
modbus_pack_crc_to_packet(txbuff, 6 + 2);
cleanRxBuff();
uarttx(txbuff, 6 + 2);
bool status;
status = uartrx(rxbuff, 5 + 2, overtimems);
if (!status) {
return false;
}
if (!modbus_checkcrc16(rxbuff, 7)) {
ZLOGE("ModbusBlockHost", "crc error");
return false;
}
*regVal = (((uint16_t)(rxbuff[3])) << 8) | rxbuff[4];
return true;
}
// static const char *hex2str(uint8_t *buff, size_t len) {
// static char str[100];
// for (size_t i = 0; i < len; i++) {
// sprintf(str + i * 2, "%02x", buff[i]);
// }
// return str;
// }
bool ModbusBlockHost::readReg03Muti(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int regNum, int overtimems) {
zlock_guard lck(m_modbus_lock);
txbuff[0] = slaveAddr;
txbuff[1] = 0x03;
txbuff[2] = regAddr >> 8;
txbuff[3] = regAddr & 0xff;
txbuff[4] = 0x00;
txbuff[5] = regNum;
modbus_pack_crc_to_packet(txbuff, 6 + 2);
cleanRxBuff();
uarttx(txbuff, 6 + 2);
bool status;
// 14*2 = 28
status = uartrx(rxbuff, 5 + regNum * 2, overtimems);
if (!status) {
return false;
}
if (!modbus_checkcrc16(rxbuff, 5 + regNum * 2)) {
ZLOGE("ModbusBlockHost", "crc error");
return false;
}
for (int i = 0; i < regNum; i++) {
regVal[i] = ((uint16_t)(rxbuff[3 + i * 2]) << 8) | rxbuff[4 + i * 2];
// int16_t val = regVal[i] ;
// ZLOGI("RX", "%d", val);
}
return true;
}
bool ModbusBlockHost::writeReg06(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems) {
zlock_guard lck(m_modbus_lock);
txbuff[0] = slaveAddr;
txbuff[1] = 0x06;
txbuff[2] = regAddr >> 8;
txbuff[3] = regAddr & 0xff;
txbuff[4] = regVal >> 8;
txbuff[5] = regVal & 0xff;
modbus_pack_crc_to_packet(txbuff, 6 + 2);
cleanRxBuff();
uarttx(txbuff, 6 + 2);
bool status;
status = uartrx(rxbuff, 8, overtimems);
if (status && modbus_checkcrc16(rxbuff, 8)) {
return true;
}
return false;
}
bool ModbusBlockHost::writeReg10(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems) {
zlock_guard lck(m_modbus_lock);
txbuff[0] = slaveAddr;
txbuff[1] = 0x10;
txbuff[2] = regAddr >> 8;
txbuff[3] = regAddr & 0xff;
txbuff[4] = 0x00;
txbuff[5] = 0x01;
txbuff[6] = 0x02; //
txbuff[7] = regVal >> 8;
txbuff[8] = regVal & 0xff;
modbus_pack_crc_to_packet(txbuff, 9 + 2);
cleanRxBuff();
uarttx(txbuff, 9 + 2);
bool status;
status = uartrx(rxbuff, 8, overtimems);
if (status && modbus_checkcrc16(rxbuff, 8)) {
return true;
}
return false;
}