can_message.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #include "bsp/bsp.h"
  2. #include "libs/os.h"
  3. #include "libs/logger.h"
  4. #include "libs/task.h"
  5. #include "can_message.h"
  6. #define MAX_CAN_MESSAGE 4
  7. static can_message_t messages[MAX_CAN_MESSAGE];
  8. static msg_list_t msg_list[10];
  9. static node_list_t _pending_list = LIST_HEAD_INIT(_pending_list);
  10. static node_list_t _idle_list = LIST_HEAD_INIT(_idle_list);
  11. static void can_process_message(can_message_t *message);
  12. static void free_can_message(can_message_t *message);
  13. static u32 _can_poll_task(void);
  14. static void handle_can_frame(void);
  15. void can_message_init(void){
  16. for(int i = 0; i < ARRAY_SIZE(msg_list); i++) {
  17. init_list_node(&msg_list[i].list);
  18. list_add_tail(&_idle_list, &msg_list[i].list);
  19. }
  20. shark_can0_init();
  21. task_start(_can_poll_task, 0);
  22. }
  23. void put_raw_message(can_id_t id, uint8_t *data, int len) {
  24. if (list_empty(&_idle_list)){
  25. return;
  26. }
  27. msg_list_t *raw = (msg_list_t *)_idle_list.next;
  28. list_del(&raw->list);
  29. raw->msg.id = id;
  30. raw->msg.len = len;
  31. memcpy(raw->msg.data, data, len);
  32. list_add_tail(&_pending_list, &raw->list);
  33. }
  34. static msg_list_t *_get_raw_message(void) {
  35. if (list_empty(&_pending_list)){
  36. return NULL;
  37. }
  38. msg_list_t *raw = (msg_list_t *)_pending_list.next;
  39. list_del(&raw->list);
  40. return raw;
  41. }
  42. static void free_raw_message(msg_list_t *raw) {
  43. list_add_tail(&_idle_list, &raw->list);
  44. }
  45. static u32 _can_poll_task(void) {
  46. handle_can_frame();
  47. return 0;
  48. }
  49. static can_message_t *get_message_by_id(can_id_t id){
  50. can_message_t *idle_msg = NULL;
  51. can_message_t *src_msg = NULL;
  52. for (int i = 0; i < MAX_CAN_MESSAGE; i++){
  53. /*first found the same src&dest */
  54. if ((messages[i].src == id.src) && (messages[i].dest == id.dest)){
  55. return (messages + i);
  56. }
  57. if (messages[i].src == id.src){
  58. src_msg = messages + i;
  59. }else if (messages[i].data == NULL){
  60. idle_msg = messages + i;
  61. }
  62. }
  63. return ((src_msg!=NULL)?src_msg:idle_msg);
  64. }
  65. s32 can_send_message(uint32_t can_id, u8 *data, int len){
  66. return shark_can0_send_message(can_id, data, len);
  67. }
  68. static void handle_can_frame(void){
  69. msg_list_t *raw = _get_raw_message();
  70. if (raw == NULL) {
  71. return;
  72. }
  73. can_id_t id = raw->msg.id;
  74. uint8_t *data = raw->msg.data;
  75. int len = raw->msg.len;
  76. can_message_t *message = get_message_by_id(id);
  77. if (message == NULL) {
  78. return ;
  79. }
  80. uint16_t key = 0;
  81. int total = id.total?id.total:32;
  82. int idx = id.idx?id.idx:32;
  83. if((total <= CAN_MESSAGE_MAX_FRAMES) && (idx <= CAN_MESSAGE_MAX_FRAMES)
  84. && (idx <= total)){
  85. if ((idx == 1) && (len >= 2)) { //first frame for message
  86. key = decoder_can_key(data);
  87. message->key = key;
  88. message->dest = id.dest;
  89. message->src = id.src;
  90. message->len = 0;
  91. message->idx = idx;
  92. message->type= id.type;
  93. message->total_frame = total;
  94. len = len - 2; //skip key
  95. data = data + 2;
  96. }
  97. if (message->data){
  98. if ((message->idx == idx) && (message->total_frame == total)){
  99. memcpy(message->data + message->len, data, len);
  100. message->len += len;
  101. if (idx == total) { //last frame
  102. can_process_message(message);
  103. }
  104. message->idx = (idx + 1);
  105. }else {
  106. free_can_message(message);
  107. }
  108. }
  109. }
  110. free_raw_message(raw);
  111. }
  112. static void can_process_message(can_message_t *message){
  113. free_can_message(message);
  114. }
  115. static void free_can_message(can_message_t *message){
  116. message->src = 0;
  117. message->len = 0;
  118. message->idx = 0xFF;
  119. message->total_frame = 0xFF;
  120. }
  121. void can_send_response(uint8_t can_add, uint8_t *data, int len){
  122. can_send_message(get_reponse_can_id(can_add), data, len);
  123. }
  124. void can_send_message_ack(can_message_t *msg, uint8_t success){
  125. u8 response[3];
  126. encoder_can_key(response, msg->key);
  127. response[2] = success;
  128. can_send_message(get_reponse_can_id(msg->src), response, 3);
  129. }
  130. void can_send_indicator(uint8_t can_add, uint8_t *data, int len){
  131. can_send_message(get_indicator_can_id(can_add), data, len);
  132. }
  133. void can_send_request(uint8_t can_add, uint8_t *data, int len){
  134. can_send_message(get_request_can_id(can_add,3), data, len);
  135. }