kobuki_protocol.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-05-28 hw630 the first version
  9. */
  10. #include "kobuki_protocol.h"
  11. #define DBG_SECTION_NAME "kobuki_protocol"
  12. #define DBG_LEVEL DBG_LOG
  13. #include <rtdbg.h>
  14. int kobuki_protocol_send_payload(uint8_t* payload, uint8_t len)
  15. {
  16. uint8_t ret = 0;
  17. uint8_t cs = len;
  18. // Checksum
  19. for (int i = 0; i < len; i++)
  20. {
  21. cs ^= payload[i];
  22. }
  23. ret += kobuki_serial_write_char(KOBUKI_BYTE_STREAM_HEADER_0);
  24. ret += kobuki_serial_write_char(KOBUKI_BYTE_STREAM_HEADER_1);
  25. ret += kobuki_serial_write_char(len);
  26. ret += kobuki_serial_write(payload, len);
  27. ret += kobuki_serial_write_char(cs);
  28. return ret;
  29. }
  30. void kobuki_play_sound_sequence(uint8_t number)
  31. {
  32. kobuki_sound_sequence_payload_t payload;
  33. payload.header = KOBUKI_SOUND_SEQUENCE_HEADER;
  34. payload.length = KOBUKI_SOUND_SEQUENCE_LENGTH;
  35. payload.number = number;
  36. kobuki_protocol_send_payload( (uint8_t*) (&payload), sizeof(kobuki_sound_sequence_payload_t));
  37. }
  38. void kobuki_request_extra(uint16_t flag)
  39. {
  40. kobuki_request_extra_payload_t payload;
  41. payload.header = KOBUKI_REQUEST_EXTRA_HEADER;
  42. payload.length = KOBUKI_REQUEST_EXTRA_LENGTH;
  43. payload.flags = flag;
  44. kobuki_protocol_send_payload( (uint8_t*) (&payload), sizeof(kobuki_request_extra_payload_t));
  45. }
  46. void kobuki_set_gpio(uint16_t flag)
  47. {
  48. kobuki_general_output_payload_t payload;
  49. payload.header = KOBUKI_GENERAL_OUTPUT_HEADER;
  50. payload.length = KOBUKI_GENERAL_OUTPUT_LENGTH;
  51. payload.flags = flag;
  52. kobuki_protocol_send_payload( (uint8_t*) (&payload), sizeof(kobuki_general_output_payload_t));
  53. }
  54. void kobuki_set_controller_gain_(uint8_t type, uint32_t kp, uint32_t ki, uint32_t kd)
  55. {
  56. kobuki_set_controller_gain_payload_t payload;
  57. payload.header = KOBUKI_SET_CONTROLLER_GAIN_HEADER;
  58. payload.length = KOBUKI_SET_CONTROLLER_GAIN_LENGTH;
  59. payload.type = type;
  60. payload.p_gain = kp;
  61. payload.i_gain = ki;
  62. payload.d_gain = kd;
  63. kobuki_protocol_send_payload( (uint8_t*) (&payload), sizeof(kobuki_set_controller_gain_payload_t));
  64. }
  65. void kobuki_get_controller_gain_()
  66. {
  67. kobuki_get_controller_gain_payload_t payload;
  68. payload.header = KOBUKI_GET_CONTROLLER_GAIN_HEADER;
  69. payload.length = KOBUKI_GET_CONTROLLER_GAIN_LENGTH;
  70. kobuki_protocol_send_payload( (uint8_t*) (&payload), sizeof(kobuki_get_controller_gain_payload_t));
  71. }
  72. int8_t kobuki_protocol_loop(uint8_t* packet, uint8_t max_len)
  73. {
  74. char c;
  75. char cs = 0; // check sum
  76. char len = 0;
  77. uint8_t is_packet_ready = 0;
  78. int tick = kobuki_get_tick();
  79. while(!is_packet_ready)
  80. {
  81. kobuki_serial_read(&c);
  82. if (c == 0xAA)
  83. {
  84. kobuki_serial_read(&c);
  85. if(c == 0x55)
  86. {
  87. is_packet_ready = 1;
  88. }
  89. }
  90. if( (kobuki_get_tick() - tick) > KOBUKI_SERIAL_TIMEOUT)
  91. {
  92. return -2;
  93. }
  94. }
  95. kobuki_serial_read(&len);
  96. if(len > max_len)
  97. {
  98. LOG_E("Buffer Overflow");
  99. return -1;
  100. }
  101. cs ^= len;
  102. int i;
  103. for (i = 0; i < len; ++i) {
  104. if(kobuki_serial_read(&packet[i]) == 0)
  105. {
  106. // Timeout
  107. return -2;
  108. }
  109. else
  110. {
  111. cs ^= packet[i];
  112. }
  113. }
  114. char cs_;
  115. kobuki_serial_read(&cs_);
  116. if (cs ^= cs_)
  117. {
  118. LOG_E("Invalid Checksum");
  119. return 0;
  120. }
  121. return len;
  122. }