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.

202 lines
4.5 KiB

12 months ago
  1. #include "modbus_block_host.hpp"
  2. #include "modbus_basic.hpp"
  3. using namespace iflytop;
  4. #define PRV_DEBUG 0
  5. ModbusBlockHost::ModbusBlockHost() {}
  6. ModbusBlockHost::~ModbusBlockHost() {}
  7. extern "C" {
  8. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {}
  9. }
  10. void ModbusBlockHost::initialize(UART_HandleTypeDef *huart) {
  11. this->huart = huart;
  12. m_modbus_lock.init();
  13. }
  14. void ModbusBlockHost::cleanRxBuff() { //
  15. HAL_StatusTypeDef status;
  16. do {
  17. status = HAL_UART_Receive(huart, rxbuff, 1, 1);
  18. } while (status == HAL_OK);
  19. }
  20. void ModbusBlockHost::uarttx(uint8_t *buff, size_t len) {
  21. ZASSERT(len < sizeof(txbuff));
  22. #if PRV_DEBUG
  23. printf("uart_tx:\n");
  24. for (size_t i = 0; i < len; i++) {
  25. printf("%02x ", buff[i]);
  26. }
  27. printf("\n");
  28. #endif
  29. // HAL_UART_Transmit(huart, buff, len, 1000);
  30. HAL_UART_DMAStop(huart);
  31. HAL_StatusTypeDef ret = HAL_UART_Transmit_DMA(huart, buff, len);
  32. ZASSERT(ret == HAL_OK);
  33. // 等待DMA传输完成
  34. while (true) {
  35. if (HAL_UART_GetState(huart) == HAL_UART_STATE_READY) break;
  36. }
  37. return;
  38. }
  39. bool ModbusBlockHost::uartrx(uint8_t *buff, size_t len, int overtimems) {
  40. HAL_StatusTypeDef status;
  41. ZASSERT(len < sizeof(rxbuff));
  42. status = HAL_UART_Receive_DMA(huart, buff, len);
  43. if (status != HAL_OK) {
  44. return false;
  45. }
  46. for (size_t i = 0; i < overtimems; i++) {
  47. osDelay(3);
  48. if (HAL_UART_GetState(huart) == HAL_UART_STATE_READY) {
  49. #if PRV_DEBUG
  50. if (status == HAL_OK) {
  51. printf("uart_rx:");
  52. for (size_t i = 0; i < len; i++) {
  53. printf("%02x ", buff[i]);
  54. }
  55. printf("\n");
  56. }
  57. #endif
  58. return true;
  59. }
  60. }
  61. #if PRV_DEBUG
  62. printf("uart_rx timeout\n");
  63. #endif
  64. HAL_UART_Abort(huart);
  65. HAL_UART_DMAStop(huart);
  66. return false;
  67. }
  68. bool ModbusBlockHost::readReg03(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int overtimems) {
  69. zlock_guard lck(m_modbus_lock);
  70. txbuff[0] = slaveAddr;
  71. txbuff[1] = 0x03;
  72. txbuff[2] = regAddr >> 8;
  73. txbuff[3] = regAddr & 0xff;
  74. txbuff[4] = 0x00;
  75. txbuff[5] = 0x01;
  76. modbus_pack_crc_to_packet(txbuff, 6 + 2);
  77. cleanRxBuff();
  78. uarttx(txbuff, 6 + 2);
  79. bool status;
  80. status = uartrx(rxbuff, 5 + 2, overtimems);
  81. if (!status) {
  82. return false;
  83. }
  84. if (!modbus_checkcrc16(rxbuff, 7)) {
  85. ZLOGE("ModbusBlockHost", "crc error");
  86. return false;
  87. }
  88. *regVal = (((uint16_t)(rxbuff[3])) << 8) | rxbuff[4];
  89. return true;
  90. }
  91. // static const char *hex2str(uint8_t *buff, size_t len) {
  92. // static char str[100];
  93. // for (size_t i = 0; i < len; i++) {
  94. // sprintf(str + i * 2, "%02x", buff[i]);
  95. // }
  96. // return str;
  97. // }
  98. bool ModbusBlockHost::readReg03Muti(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int regNum, int overtimems) {
  99. zlock_guard lck(m_modbus_lock);
  100. txbuff[0] = slaveAddr;
  101. txbuff[1] = 0x03;
  102. txbuff[2] = regAddr >> 8;
  103. txbuff[3] = regAddr & 0xff;
  104. txbuff[4] = 0x00;
  105. txbuff[5] = regNum;
  106. modbus_pack_crc_to_packet(txbuff, 6 + 2);
  107. cleanRxBuff();
  108. uarttx(txbuff, 6 + 2);
  109. bool status;
  110. // 14*2 = 28
  111. status = uartrx(rxbuff, 5 + regNum * 2, overtimems);
  112. if (!status) {
  113. return false;
  114. }
  115. if (!modbus_checkcrc16(rxbuff, 5 + regNum * 2)) {
  116. ZLOGE("ModbusBlockHost", "crc error");
  117. return false;
  118. }
  119. for (int i = 0; i < regNum; i++) {
  120. regVal[i] = ((uint16_t)(rxbuff[3 + i * 2]) << 8) | rxbuff[4 + i * 2];
  121. // int16_t val = regVal[i] ;
  122. // ZLOGI("RX", "%d", val);
  123. }
  124. return true;
  125. }
  126. bool ModbusBlockHost::writeReg06(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems) {
  127. zlock_guard lck(m_modbus_lock);
  128. txbuff[0] = slaveAddr;
  129. txbuff[1] = 0x06;
  130. txbuff[2] = regAddr >> 8;
  131. txbuff[3] = regAddr & 0xff;
  132. txbuff[4] = regVal >> 8;
  133. txbuff[5] = regVal & 0xff;
  134. modbus_pack_crc_to_packet(txbuff, 6 + 2);
  135. cleanRxBuff();
  136. uarttx(txbuff, 6 + 2);
  137. bool status;
  138. status = uartrx(rxbuff, 8, overtimems);
  139. if (status && modbus_checkcrc16(rxbuff, 8)) {
  140. return true;
  141. }
  142. return false;
  143. }
  144. bool ModbusBlockHost::writeReg10(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems) {
  145. zlock_guard lck(m_modbus_lock);
  146. txbuff[0] = slaveAddr;
  147. txbuff[1] = 0x10;
  148. txbuff[2] = regAddr >> 8;
  149. txbuff[3] = regAddr & 0xff;
  150. txbuff[4] = 0x00;
  151. txbuff[5] = 0x01;
  152. txbuff[6] = 0x02; // 字节数
  153. txbuff[7] = regVal >> 8;
  154. txbuff[8] = regVal & 0xff;
  155. modbus_pack_crc_to_packet(txbuff, 9 + 2);
  156. cleanRxBuff();
  157. uarttx(txbuff, 9 + 2);
  158. bool status;
  159. status = uartrx(rxbuff, 8, overtimems);
  160. if (status && modbus_checkcrc16(rxbuff, 8)) {
  161. return true;
  162. }
  163. return false;
  164. }