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.

90 lines
3.1 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #include "modbus_client.hpp"
  2. #include <string.h>
  3. #include "modbus_basic.hpp"
  4. #include "sdk\os\delay.hpp"
  5. using namespace iflytop;
  6. static uint8_t modbus_rx_buf[255];
  7. static uint8_t modbus_tx_buf[255];
  8. static bool modbus_rx_is_ready = false;
  9. static int modbus_rx_size = 0;
  10. static void modbux_tx(uint8_t* rx, uint16_t len) { ModulebusClient::Inst()->sendpacket(rx, len); }
  11. static void modbux_process_rx(modbus_processer_context_t* context) { ModulebusClient::Inst()->process_rx_packet(context); }
  12. void ModulebusClient::init(ZIUartReceiver* receiver, ZIUartSender* sender, int deviceId, //
  13. on_reg_read_t regreadcb, //
  14. on_reg_write_t regwritecb) {
  15. static modbus_processer_t s_modbus_processer = {};
  16. s_modbus_processer.modbus_device_id = deviceId;
  17. s_modbus_processer.modbus_processer_rx_buf = modbus_rx_buf;
  18. s_modbus_processer.modbus_processer_rx_buf_size = sizeof(modbus_rx_buf);
  19. s_modbus_processer.modbus_processer_tx_buf = modbus_tx_buf;
  20. s_modbus_processer.modbus_processer_tx_buf_size = sizeof(modbus_tx_buf);
  21. s_modbus_processer.tx = modbux_tx;
  22. s_modbus_processer.process_rx = modbux_process_rx;
  23. m_receiver = receiver;
  24. m_sender = sender;
  25. m_deviceId = deviceId;
  26. m_regreadcb = regreadcb;
  27. m_regwritecb = regwritecb;
  28. modbus_processer_init(&s_modbus_processer);
  29. receiver->startRx([this](uint8_t* data, size_t len) { //
  30. if (modbus_rx_is_ready) return;
  31. if (len > 255) return;
  32. memcpy(modbus_rx_buf, data, len);
  33. modbus_rx_size = len;
  34. modbus_rx_is_ready = true;
  35. });
  36. }
  37. void ModulebusClient::loop() {
  38. if (modbus_rx_is_ready) {
  39. modbus_processer_process_data(modbus_rx_buf, modbus_rx_size);
  40. modbus_rx_is_ready = false;
  41. }
  42. }
  43. void ModulebusClient::sendpacket(uint8_t* data, uint16_t len) { m_sender->send(data, len); }
  44. void ModulebusClient::process_rx_packet(modbus_processer_context_t* context) {
  45. ModbusFunctionCode fcode = modbus_get_function_code(context);
  46. if (fcode == ModbusOrder10) {
  47. /**
  48. * @brief GPIOд
  49. */
  50. uint16_t startreg = context->rx->d.O10.startreg;
  51. uint16_t endreg = context->rx->d.O10.startreg + context->rx->d.O10.numreg;
  52. uint16_t regnum = context->rx->d.O10.numreg;
  53. for (int i = 0; i < regnum; i++) {
  54. int32_t regoff = i + startreg;
  55. if (m_regwritecb) {
  56. m_regwritecb(regoff, modbus_get_reg_10(context, regoff));
  57. }
  58. }
  59. } else if (fcode == ModbusOrder03) {
  60. uint16_t startreg = context->rx->d.O03.startreg;
  61. uint16_t endreg = context->rx->d.O03.startreg + context->rx->d.O03.numreg;
  62. uint16_t regnum = context->rx->d.O03.numreg;
  63. for (int i = 0; i < regnum; i++) {
  64. int32_t regoff = i + startreg;
  65. uint16_t regval = 0;
  66. if (m_regreadcb) {
  67. m_regreadcb(regoff, regval);
  68. }
  69. modbus_set_tx_reg_03(context, regoff, regval);
  70. }
  71. }
  72. if (fcode == ModbusOrder10) {
  73. modbus_send_10(context, Modbus_OK);
  74. } else if (fcode == ModbusOrder03) {
  75. modbus_send_03(context, Modbus_OK);
  76. }
  77. }