| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- #include "bsp/bsp.h"
- #include "libs/os.h"
- #include "libs/logger.h"
- #include "libs/task.h"
- #include "can_message.h"
- #define MAX_CAN_MESSAGE 4
- static can_message_t messages[MAX_CAN_MESSAGE];
- static msg_list_t msg_list[10];
- static node_list_t _pending_list = LIST_HEAD_INIT(_pending_list);
- static node_list_t _idle_list = LIST_HEAD_INIT(_idle_list);
- static void can_process_message(can_message_t *message);
- static void free_can_message(can_message_t *message);
- static u32 _can_poll_task(void);
- static void handle_can_frame(void);
- void can_message_init(void){
- for(int i = 0; i < ARRAY_SIZE(msg_list); i++) {
- init_list_node(&msg_list[i].list);
- list_add_tail(&_idle_list, &msg_list[i].list);
- }
- shark_can0_init();
- task_start(_can_poll_task, 0);
- }
- void put_raw_message(can_id_t id, uint8_t *data, int len) {
- if (list_empty(&_idle_list)){
- return;
- }
- msg_list_t *raw = (msg_list_t *)_idle_list.next;
- list_del(&raw->list);
- raw->msg.id = id;
- raw->msg.len = len;
- memcpy(raw->msg.data, data, len);
- list_add_tail(&_pending_list, &raw->list);
- }
- static msg_list_t *_get_raw_message(void) {
- if (list_empty(&_pending_list)){
- return NULL;
- }
- msg_list_t *raw = (msg_list_t *)_pending_list.next;
- list_del(&raw->list);
- return raw;
- }
- static void free_raw_message(msg_list_t *raw) {
- list_add_tail(&_idle_list, &raw->list);
- }
- static u32 _can_poll_task(void) {
- handle_can_frame();
- return 0;
- }
- static can_message_t *get_message_by_id(can_id_t id){
- can_message_t *idle_msg = NULL;
- can_message_t *src_msg = NULL;
- for (int i = 0; i < MAX_CAN_MESSAGE; i++){
- /*first found the same src&dest */
- if ((messages[i].src == id.src) && (messages[i].dest == id.dest)){
- return (messages + i);
- }
- if (messages[i].src == id.src){
- src_msg = messages + i;
- }else if (messages[i].data == NULL){
- idle_msg = messages + i;
- }
- }
- return ((src_msg!=NULL)?src_msg:idle_msg);
- }
- s32 can_send_message(uint32_t can_id, u8 *data, int len){
- return shark_can0_send_message(can_id, data, len);
- }
- static void handle_can_frame(void){
- msg_list_t *raw = _get_raw_message();
- if (raw == NULL) {
- return;
- }
- can_id_t id = raw->msg.id;
- uint8_t *data = raw->msg.data;
- int len = raw->msg.len;
-
- can_message_t *message = get_message_by_id(id);
- if (message == NULL) {
- return ;
- }
- uint16_t key = 0;
- int total = id.total?id.total:32;
- int idx = id.idx?id.idx:32;
- if((total <= CAN_MESSAGE_MAX_FRAMES) && (idx <= CAN_MESSAGE_MAX_FRAMES)
- && (idx <= total)){
- if ((idx == 1) && (len >= 2)) { //first frame for message
- key = decoder_can_key(data);
- message->key = key;
- message->dest = id.dest;
- message->src = id.src;
- message->len = 0;
- message->idx = idx;
- message->type= id.type;
- message->total_frame = total;
- len = len - 2; //skip key
- data = data + 2;
- }
- if (message->data){
- if ((message->idx == idx) && (message->total_frame == total)){
- memcpy(message->data + message->len, data, len);
- message->len += len;
- if (idx == total) { //last frame
- can_process_message(message);
- }
- message->idx = (idx + 1);
- }else {
- free_can_message(message);
- }
- }
- }
- free_raw_message(raw);
- }
- static void can_process_message(can_message_t *message){
- free_can_message(message);
- }
- static void free_can_message(can_message_t *message){
- message->src = 0;
- message->len = 0;
- message->idx = 0xFF;
- message->total_frame = 0xFF;
- }
- void can_send_response(uint8_t can_add, uint8_t *data, int len){
- can_send_message(get_reponse_can_id(can_add), data, len);
- }
- void can_send_message_ack(can_message_t *msg, uint8_t success){
- u8 response[3];
- encoder_can_key(response, msg->key);
- response[2] = success;
- can_send_message(get_reponse_can_id(msg->src), response, 3);
- }
- void can_send_indicator(uint8_t can_add, uint8_t *data, int len){
- can_send_message(get_indicator_can_id(can_add), data, len);
- }
- void can_send_request(uint8_t can_add, uint8_t *data, int len){
- can_send_message(get_request_can_id(can_add,3), data, len);
- }
|