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.

166 lines
5.1 KiB

1 year ago
  1. #include "waveshare_can.hpp"
  2. #include "libzqt\zexception.hpp"
  3. #include "logger.hpp"
  4. using namespace iflytop;
  5. using namespace std;
  6. #define CANUSB_TTY_BAUD_RATE_DEFAULT 2000000
  7. #define TAG "WaveshareCan"
  8. static int generate_checksum(const unsigned char* data, int data_len) {
  9. int i, checksum;
  10. checksum = 0;
  11. for (i = 0; i < data_len; i++) {
  12. checksum += data[i];
  13. }
  14. return checksum & 0xff;
  15. }
  16. static bool isHeader(uint8_t* data) {
  17. if (data[0] == 0xAA && data[1] == 0x55) {
  18. return true;
  19. }
  20. return false;
  21. }
  22. bool WaveshareCan::init(IDataChannel* ch, frame_callback_t framecb) {
  23. m_frame_callback = framecb;
  24. m_ch = ch;
  25. m_ch->regRxListener([this](uint8_t* data, size_t len) {
  26. {
  27. lock_guard<mutex> lock(lock_);
  28. if (len + m_rxlen > sizeof(m_rxcache)) {
  29. m_rxlen = 0;
  30. }
  31. memcpy(m_rxcache + m_rxlen, data, len);
  32. m_rxlen += len;
  33. }
  34. });
  35. m_thread.reset(new thread([this]() {
  36. while (true) {
  37. this_thread::sleep_for(chrono::milliseconds(1));
  38. {
  39. lock_guard<mutex> lock(lock_);
  40. // 1.找头部
  41. int32_t headerpos = -1;
  42. for (int32_t i = 0; i < m_rxlen - 1; i++) {
  43. if (isHeader(m_rxcache + i)) {
  44. headerpos = i;
  45. break;
  46. }
  47. }
  48. if (headerpos == -1) {
  49. continue;
  50. }
  51. // 将包头移动到缓存头部
  52. if (headerpos != 0) {
  53. memmove(m_rxcache, m_rxcache + headerpos, m_rxlen - headerpos);
  54. m_rxlen = m_rxlen - headerpos;
  55. continue;
  56. }
  57. if (m_rxlen < 20) continue;
  58. onReceivePacket(m_rxcache, 20);
  59. memmove(m_rxcache, m_rxcache + 20, m_rxlen - 20);
  60. m_rxlen = m_rxlen - 20;
  61. }
  62. }
  63. }));
  64. }
  65. void WaveshareCan::setCanpPrameter(CANUSB_SPEED speed, CANUSB_MODE mode, CANUSB_FRAME frame) {
  66. int cmd_frame_len;
  67. unsigned char cmd_frame[20];
  68. cmd_frame_len = 0;
  69. cmd_frame[0] = 0xaa;
  70. cmd_frame[1] = 0x55;
  71. cmd_frame[2] = 0x02; // 0x02:用固定20字节协议收发数据 0x12-设置用可变协议收发数据
  72. cmd_frame[3] = speed; // speed
  73. cmd_frame[4] = frame; // 帧类型
  74. cmd_frame[5] = 0; /* Filter ID not handled. */
  75. cmd_frame[6] = 0; /* Filter ID not handled. */
  76. cmd_frame[7] = 0; /* Filter ID not handled. */
  77. cmd_frame[8] = 0; /* Filter ID not handled. */
  78. cmd_frame[9] = 0; /* Mask ID not handled. */
  79. cmd_frame[10] = 0; /* Mask ID not handled. */
  80. cmd_frame[11] = 0; /* Mask ID not handled. */
  81. cmd_frame[12] = 0; /* Mask ID not handled. */
  82. cmd_frame[13] = mode; // 模式
  83. cmd_frame[14] = 0x01; // 是否自动重发
  84. cmd_frame[15] = 0; // 占位,备用
  85. cmd_frame[16] = 0; // 占位,备用
  86. cmd_frame[17] = 0; // 占位,备用
  87. cmd_frame[18] = 0; // 占位,备用
  88. cmd_frame[19] = generate_checksum(&cmd_frame[2], 17);
  89. if (!m_ch || !m_ch->isOpen()) {
  90. throw zexception(ke_channel_is_close, "channel is not open");
  91. }
  92. m_ch->send(cmd_frame, 20);
  93. }
  94. bool WaveshareCan::sendframe(CANUSB_FRAME frametype, uint32_t id, unsigned char data[], int data_length_code) {
  95. int data_frame_len = 0;
  96. unsigned char data_frame[20] = {0x00};
  97. waveshare_can_packet_t* packet = (waveshare_can_packet_t*)data_frame;
  98. packet->packet_header0 = 0xaa;
  99. packet->packet_header1 = 0x55;
  100. packet->type = 0x01; // 数据
  101. packet->frame_type = frametype;
  102. packet->frame_format = 0x01; // 数据帧
  103. packet->frame_id_data_1 = id & 0xff;
  104. packet->frame_id_data_2 = (id >> 8) & 0xff;
  105. packet->frame_id_data_3 = (id >> 16) & 0xff;
  106. packet->frame_id_data_4 = (id >> 24) & 0xff;
  107. packet->frame_data_length = data_length_code;
  108. packet->frame_data_1 = data[0];
  109. packet->frame_data_2 = data[1];
  110. packet->frame_data_3 = data[2];
  111. packet->frame_data_4 = data[3];
  112. packet->frame_data_5 = data[4];
  113. packet->frame_data_6 = data[5];
  114. packet->frame_data_7 = data[6];
  115. packet->frame_data_8 = data[7];
  116. packet->reserve = 0;
  117. packet->check_code = generate_checksum(&data_frame[2], 17);
  118. if (!m_ch || !m_ch->isOpen()) {
  119. throw zexception(ke_channel_is_close, "channel is not open");
  120. }
  121. ZLOGI(TAG, "tx 0x%08x, %s", id, zhex2str(data, data_length_code).c_str());
  122. m_ch->send(data_frame, 20);
  123. return true;
  124. }
  125. int WaveshareCan::onReceivePacket(uint8_t* data, size_t len) {
  126. waveshare_can_packet_t* rxpacket = (waveshare_can_packet_t*)data;
  127. can_rx_frame_t canframe;
  128. canframe.dlc = rxpacket->frame_data_length;
  129. canframe.id = rxpacket->frame_id_data_1 | ((uint32_t)rxpacket->frame_id_data_2 << 8) | ((uint32_t)rxpacket->frame_id_data_3 << 16) | ((uint32_t)rxpacket->frame_id_data_4 << 24);
  130. canframe.data[0] = rxpacket->frame_data_1;
  131. canframe.data[1] = rxpacket->frame_data_2;
  132. canframe.data[2] = rxpacket->frame_data_3;
  133. canframe.data[3] = rxpacket->frame_data_4;
  134. canframe.data[4] = rxpacket->frame_data_5;
  135. canframe.data[5] = rxpacket->frame_data_6;
  136. canframe.data[6] = rxpacket->frame_data_6;
  137. canframe.data[7] = rxpacket->frame_data_6;
  138. if (m_frame_callback) {
  139. m_frame_callback(&canframe);
  140. }
  141. }