7 changed files with 375 additions and 168 deletions
-
211components/eq_20_asb_motor/eq20_servomotor.cpp
-
46components/eq_20_asb_motor/eq20_servomotor.hpp
-
61components/hardware/uart/zuart_helper.cpp
-
23components/hardware/uart/zuart_helper.hpp
-
178components/modbus/modbus_block_host.cpp
-
22components/modbus/modbus_block_host.hpp
-
2components/zprotocols/errorcode
@ -0,0 +1,61 @@ |
|||||
|
#include "zuart_helper.hpp"
|
||||
|
using namespace iflytop; |
||||
|
#define DEBUG 0
|
||||
|
#if DEBUG
|
||||
|
static void dumphex(char* tag, uint8_t* data, uint8_t len) { |
||||
|
printf("%s:", tag); |
||||
|
for (int i = 0; i < len; i++) { |
||||
|
printf("%02x ", data[i]); |
||||
|
} |
||||
|
printf("\n"); |
||||
|
} |
||||
|
#endif
|
||||
|
|
||||
|
ZUARTHelper::ZUARTHelper(const char* tag, UART_HandleTypeDef* uart, DMA_HandleTypeDef* hdma_tx, DMA_HandleTypeDef* hdma_rx) { |
||||
|
m_uart = uart; |
||||
|
m_hdma_tx = hdma_tx; |
||||
|
m_hdma_rx = hdma_rx; |
||||
|
m_tag = tag; |
||||
|
} |
||||
|
|
||||
|
void ZUARTHelper::cleanRxBuff() { |
||||
|
HAL_StatusTypeDef status; |
||||
|
uint8_t datacache; |
||||
|
do { |
||||
|
status = HAL_UART_Receive(m_uart, &datacache, 1, 1); |
||||
|
} while (status == HAL_OK); |
||||
|
} |
||||
|
int32_t ZUARTHelper::tx_and_rx(uint8_t* tx, uint8_t txdatalen, uint8_t* rx, uint8_t expectrxsize, uint16_t overtimems) { |
||||
|
uint32_t enter_ticket = HAL_GetTick(); |
||||
|
#if DEBUG
|
||||
|
dumphex("tx:", tx, txdatalen); |
||||
|
#endif
|
||||
|
|
||||
|
HAL_UART_Transmit(m_uart, tx, txdatalen, 1000); |
||||
|
HAL_UART_Receive_DMA(m_uart, (uint8_t*)rx, expectrxsize); |
||||
|
|
||||
|
bool overtime_flag = false; |
||||
|
while (HAL_UART_GetState(m_uart) == HAL_UART_STATE_BUSY_RX || //
|
||||
|
HAL_UART_GetState(m_uart) == HAL_UART_STATE_BUSY_TX_RX) { |
||||
|
osDelay(1); |
||||
|
int rxsize = expectrxsize - __HAL_DMA_GET_COUNTER(m_hdma_rx); |
||||
|
if (rxsize == expectrxsize) { |
||||
|
#if DEBUG
|
||||
|
dumphex("rx:", rx, expectrxsize); |
||||
|
#endif
|
||||
|
break; |
||||
|
} |
||||
|
if (zos_haspassedms(enter_ticket) > overtimems) { |
||||
|
if (expectrxsize != 0 && rxsize != 0) { |
||||
|
ZLOGW(m_tag, "txandrx overtime rxsize:%d != expect_size:%d", rxsize, expectrxsize); |
||||
|
} |
||||
|
overtime_flag = true; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
HAL_UART_DMAStop(m_uart); |
||||
|
if (overtime_flag) { |
||||
|
return false; |
||||
|
} |
||||
|
return true; |
||||
|
} |
@ -0,0 +1,23 @@ |
|||||
|
#pragma once
|
||||
|
#include <functional>
|
||||
|
|
||||
|
#include "sdk\os\zos.hpp"
|
||||
|
namespace iflytop { |
||||
|
using namespace std; |
||||
|
class ZUARTHelper { |
||||
|
private: |
||||
|
const char* m_tag = ""; |
||||
|
UART_HandleTypeDef* m_uart = NULL; |
||||
|
DMA_HandleTypeDef* m_hdma_tx = NULL; |
||||
|
DMA_HandleTypeDef* m_hdma_rx = NULL; |
||||
|
|
||||
|
public: |
||||
|
ZUARTHelper(const char* tag, UART_HandleTypeDef* uart, DMA_HandleTypeDef* hdma_tx, DMA_HandleTypeDef* hdma_rx); |
||||
|
ZUARTHelper(){}; |
||||
|
|
||||
|
UART_HandleTypeDef* get_uart() { return m_uart; } |
||||
|
|
||||
|
int32_t tx_and_rx(uint8_t* tx, uint8_t txdatalen, uint8_t* rx, uint8_t expectrxsize, uint16_t overtimems); |
||||
|
void cleanRxBuff(); |
||||
|
}; |
||||
|
} // namespace iflytop
|
@ -1,138 +1,102 @@ |
|||||
#include "modbus_block_host.hpp"
|
#include "modbus_block_host.hpp"
|
||||
|
|
||||
#include "modbus_basic.hpp"
|
#include "modbus_basic.hpp"
|
||||
|
#include "sdk\components\zprotocols\errorcode\errorcode.hpp"
|
||||
using namespace iflytop; |
using namespace iflytop; |
||||
#define DEBUG 1
|
|
||||
ModbusBlockHost::ModbusBlockHost() {} |
|
||||
ModbusBlockHost::~ModbusBlockHost() {} |
|
||||
|
|
||||
void ModbusBlockHost::initialize(UART_HandleTypeDef *huart) { this->huart = huart; } |
|
||||
void ModbusBlockHost::cleanRxBuff() { //
|
|
||||
HAL_StatusTypeDef status; |
|
||||
do { |
|
||||
status = HAL_UART_Receive(huart, rxbuff, 1, 1); |
|
||||
} while (status == HAL_OK); |
|
||||
} |
|
||||
|
#define TAG "ModbusBlockHost"
|
||||
|
|
||||
void ModbusBlockHost::uarttx(uint8_t *buff, size_t len) { |
|
||||
ZASSERT(len < sizeof(txbuff)); |
|
||||
#if DEBUG
|
|
||||
printf("uarttx:\n"); |
|
||||
for (size_t i = 0; i < len; i++) { |
|
||||
printf("%02x ", buff[i]); |
|
||||
} |
|
||||
printf("\n"); |
|
||||
#endif
|
|
||||
HAL_UART_Transmit(huart, buff, len, 1000); |
|
||||
} |
|
||||
bool ModbusBlockHost::uartrx(uint8_t *buff, size_t len, int overtimems) { |
|
||||
HAL_StatusTypeDef status; |
|
||||
ZASSERT(len < sizeof(rxbuff)); |
|
||||
|
|
||||
status = HAL_UART_Receive(huart, buff, len, overtimems); |
|
||||
#if DEBUG
|
|
||||
if (status == HAL_OK) { |
|
||||
printf("uartrx:"); |
|
||||
for (size_t i = 0; i < len; i++) { |
|
||||
printf("%02x ", buff[i]); |
|
||||
} |
|
||||
printf("\n"); |
|
||||
|
#define DO(exptr) \
|
||||
|
{ \ |
||||
|
int32_t __ret = exptr; \ |
||||
|
if (__ret != 0) { \ |
||||
|
ZLOGE(TAG, "do %s %d", #exptr, __ret); \ |
||||
|
return __ret; \ |
||||
|
} \ |
||||
} |
} |
||||
#endif
|
|
||||
return status == HAL_OK; |
|
||||
} |
|
||||
|
|
||||
bool ModbusBlockHost::readReg03(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int overtimems) { |
|
||||
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); |
|
||||
|
#define DEBUG 0
|
||||
|
ModbusBlockHost::ModbusBlockHost() {} |
||||
|
ModbusBlockHost::~ModbusBlockHost() {} |
||||
|
|
||||
cleanRxBuff(); |
|
||||
|
void ModbusBlockHost::initialize(UART_HandleTypeDef *m_huart, DMA_HandleTypeDef *hdma_tx, DMA_HandleTypeDef *hdma_rx) { |
||||
|
// m_huart = m_huart;
|
||||
|
// m_hdma_tx = hdma_tx;
|
||||
|
// m_hdma_rx = hdma_rx;
|
||||
|
|
||||
uarttx(txbuff, 6 + 2); |
|
||||
|
m_zuartHelper = ZUARTHelper(TAG, m_huart, hdma_tx, hdma_rx); |
||||
|
|
||||
bool status; |
|
||||
status = uartrx(rxbuff, 5 + 2, overtimems); |
|
||||
|
m_mutex.init(); |
||||
|
} |
||||
|
void ModbusBlockHost::cleanRxBuff() { //
|
||||
|
m_zuartHelper.cleanRxBuff(); |
||||
|
} |
||||
|
|
||||
if (status && modbus_checkcrc16(rxbuff, 7)) { |
|
||||
*regVal = rxbuff[3] << 8 | rxbuff[4]; |
|
||||
return true; |
|
||||
} |
|
||||
return false; |
|
||||
|
int32_t ModbusBlockHost::readReg03(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int overtimems) { //
|
||||
|
int32_t status = readReg03Muti(slaveAddr, regAddr, regVal, 1, overtimems); |
||||
|
return status; |
||||
} |
} |
||||
|
|
||||
bool ModbusBlockHost::readReg03Muti(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int regNum, int overtimems) { |
|
||||
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); |
|
||||
|
int32_t ModbusBlockHost::readReg03Muti(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int regNum, int overtimems) { |
||||
|
m_txbuff[0] = slaveAddr; |
||||
|
m_txbuff[1] = 0x03; |
||||
|
m_txbuff[2] = regAddr >> 8; |
||||
|
m_txbuff[3] = regAddr & 0xff; |
||||
|
m_txbuff[4] = 0x00; |
||||
|
m_txbuff[5] = regNum; |
||||
|
modbus_pack_crc_to_packet(m_txbuff, 6 + 2); |
||||
|
|
||||
cleanRxBuff(); |
cleanRxBuff(); |
||||
|
|
||||
uarttx(txbuff, 6 + 2); |
|
||||
|
|
||||
bool status; |
|
||||
// 14*2 = 28
|
|
||||
status = uartrx(rxbuff, 5 + regNum * 2, overtimems); |
|
||||
|
|
||||
if (status && modbus_checkcrc16(rxbuff, 7 + regNum * 2)) { |
|
||||
for (int i = 0; i < regNum; i++) { |
|
||||
regVal[i] = rxbuff[3 + i * 2] << 8 | rxbuff[4 + i * 2]; |
|
||||
} |
|
||||
return true; |
|
||||
|
DO(m_zuartHelper.tx_and_rx(m_txbuff, 6 + 2, m_rxbuff, 5 + regNum * 2, overtimems)); |
||||
|
if (!modbus_checkcrc16(m_rxbuff, 7 + regNum * 2)) { |
||||
|
return err::kce_modbusCRC16checkfail; |
||||
|
} |
||||
|
for (int i = 0; i < regNum; i++) { |
||||
|
regVal[i] = m_rxbuff[3 + i * 2] << 8 | m_rxbuff[4 + i * 2]; |
||||
} |
} |
||||
return false; |
|
||||
|
return 0; |
||||
} |
} |
||||
|
|
||||
bool ModbusBlockHost::writeReg06(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems) { |
|
||||
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); |
|
||||
|
int32_t ModbusBlockHost::writeReg06(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems) { |
||||
|
m_txbuff[0] = slaveAddr; |
||||
|
m_txbuff[1] = 0x06; |
||||
|
m_txbuff[2] = regAddr >> 8; |
||||
|
m_txbuff[3] = regAddr & 0xff; |
||||
|
m_txbuff[4] = regVal >> 8; |
||||
|
m_txbuff[5] = regVal & 0xff; |
||||
|
modbus_pack_crc_to_packet(m_txbuff, 6 + 2); |
||||
|
|
||||
cleanRxBuff(); |
cleanRxBuff(); |
||||
|
|
||||
uarttx(txbuff, 6 + 2); |
|
||||
|
|
||||
bool status; |
|
||||
status = uartrx(rxbuff, 8, overtimems); |
|
||||
|
DO(m_zuartHelper.tx_and_rx(m_txbuff, 6 + 2, m_rxbuff, 8, overtimems)); |
||||
|
|
||||
if (status && modbus_checkcrc16(rxbuff, 8)) { |
|
||||
return true; |
|
||||
|
if (!modbus_checkcrc16(m_rxbuff, 8)) { |
||||
|
return err::kce_modbusCRC16checkfail; |
||||
} |
} |
||||
return false; |
|
||||
|
return 0; |
||||
} |
} |
||||
bool ModbusBlockHost::writeReg10(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems) { |
|
||||
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); |
|
||||
|
int32_t ModbusBlockHost::writeReg10(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems) { return writeReg10Muti(slaveAddr, regAddr, ®Val, 1, overtimems); } |
||||
|
|
||||
|
int32_t ModbusBlockHost::writeReg10Muti(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, uint16_t nreg, int overtimems) { |
||||
|
m_txbuff[0] = slaveAddr; |
||||
|
m_txbuff[1] = 0x10; |
||||
|
m_txbuff[2] = regAddr >> 8; |
||||
|
m_txbuff[3] = regAddr & 0xff; |
||||
|
m_txbuff[4] = 0x00; |
||||
|
m_txbuff[5] = nreg; |
||||
|
m_txbuff[6] = nreg * 2; // ×Ö½ÚÊý
|
||||
|
for (int i = 0; i < nreg; i++) { |
||||
|
m_txbuff[7 + i * 2] = regVal[i] >> 8; |
||||
|
m_txbuff[8 + i * 2] = regVal[i] & 0xff; |
||||
|
} |
||||
|
modbus_pack_crc_to_packet(m_txbuff, 7 + nreg * 2 + 2); |
||||
|
|
||||
cleanRxBuff(); |
cleanRxBuff(); |
||||
|
|
||||
uarttx(txbuff, 9 + 2); |
|
||||
|
|
||||
bool status; |
|
||||
status = uartrx(rxbuff, 8, overtimems); |
|
||||
|
DO(m_zuartHelper.tx_and_rx(m_txbuff, 7 + nreg * 2 + 2, m_rxbuff, 8, overtimems)); |
||||
|
|
||||
if (status && modbus_checkcrc16(rxbuff, 8)) { |
|
||||
return true; |
|
||||
|
if (!modbus_checkcrc16(m_rxbuff, 8)) { |
||||
|
return err::kce_modbusCRC16checkfail; |
||||
} |
} |
||||
return false; |
|
||||
|
return 0; |
||||
} |
} |
@ -1,29 +1,31 @@ |
|||||
#pragma once
|
#pragma once
|
||||
#include "sdk/os/zos.hpp"
|
#include "sdk/os/zos.hpp"
|
||||
|
#include "sdk\components\hardware\uart\zuart_helper.hpp"
|
||||
|
#include "sdk\os\mutex.hpp"
|
||||
|
|
||||
namespace iflytop { |
namespace iflytop { |
||||
class ModbusBlockHost { |
class ModbusBlockHost { |
||||
public: |
public: |
||||
UART_HandleTypeDef *huart; |
|
||||
|
ZUARTHelper m_zuartHelper; |
||||
|
zmutex m_mutex; |
||||
|
|
||||
uint8_t txbuff[100]; |
|
||||
uint8_t rxbuff[100]; |
|
||||
|
uint8_t m_txbuff[200]; // 大概支持同时读20个寄存器
|
||||
|
uint8_t m_rxbuff[200]; // 大概支持同时读20个寄存器
|
||||
|
|
||||
public: |
public: |
||||
ModbusBlockHost(); |
ModbusBlockHost(); |
||||
~ModbusBlockHost(); |
~ModbusBlockHost(); |
||||
|
|
||||
void initialize(UART_HandleTypeDef *huart); |
|
||||
|
void initialize(UART_HandleTypeDef *huart, DMA_HandleTypeDef *hdma_tx, DMA_HandleTypeDef *hdma_rx); |
||||
|
|
||||
bool readReg03(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int overtimems); |
|
||||
bool readReg03Muti(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int regNum, int overtimems); |
|
||||
bool writeReg06(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems); |
|
||||
bool writeReg10(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems); |
|
||||
|
int32_t readReg03(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int overtimems); |
||||
|
int32_t readReg03Muti(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int regNum, int overtimems); |
||||
|
int32_t writeReg06(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems); |
||||
|
int32_t writeReg10(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems); |
||||
|
int32_t writeReg10Muti(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, uint16_t nreg, int overtimems); |
||||
|
|
||||
void cleanRxBuff(); |
void cleanRxBuff(); |
||||
|
|
||||
private: |
private: |
||||
void uarttx(uint8_t *buff, size_t len); |
|
||||
bool uartrx(uint8_t *buff, size_t len, int overtimems); |
|
||||
}; |
}; |
||||
} // namespace iflytop
|
} // namespace iflytop
|
@ -1 +1 @@ |
|||||
Subproject commit 0d0b37363452b7ae7ca442bf924bf8ba021b5a62 |
|
||||
|
Subproject commit a3197d626bc551983a5598d3c3a35e8e4de63e35 |
Write
Preview
Loading…
Cancel
Save
Reference in new issue