int can_send(can_id_t id, uint8_t data[], uint8_t dlc, CSP_BASE_TYPE * task_woken) { int i, m = -1; /* Disable CAN interrupt while looping MOBs */ CAN_CLEAR_INTERRUPT(); /* Disable interrupts while looping mailboxes */ if (task_woken == NULL) { portENTER_CRITICAL(); } /* Search free MOB from 0 -> CAN_TX_MOBs */ for(i = 0; i < CAN_TX_MOBS; i++) { if (mbox[i] == MBOX_FREE && !(CANEN2 & (1 << i))) { mbox[i] = MBOX_USED; m = i; break; } } /* Enable interrupts */ if (task_woken == NULL) { portEXIT_CRITICAL(); } /* Enable CAN interrupt */ CAN_SET_INTERRUPT(); /* Return if no available MOB was found */ if (m < 0) { csp_log_warn("TX overflow, no available MOB\r\n"); return -1; } /* Select and clear mob */ CAN_SET_MOB(m); CAN_MOB_ABORT(); CAN_CLEAR_STATUS_MOB(); /* Set identifier */ CAN_SET_EXT_ID(id); /* Set data - CANMSG is auto incrementing */ for (i = 0; i < dlc; i++) CANMSG = data[i]; /* Set DLC */ CAN_CLEAR_DLC(); CAN_SET_DLC(dlc); /* Start TX */ CAN_CONFIG_TX(); return 0; }
static void int_handler(uint16_t source) { uint8_t mob_handle; can_cmd_t * cmd; mob_handle = 0; while(source != 0) { if(source & 1) { cmd = can_mob[mob_handle]; if(cmd != NULL) { CAN_SET_MOB(mob_handle); cmd->status = CAN_GET_STATUS_MOB() ; // RX operation finished if(cmd->status & MOB_RX_COMPLETED_DLCW) { cmd->frame->data.len = CAN_GET_DLC(); can_get_data(cmd->frame->data.itself); cmd->frame->inf.rtr = CAN_GET_RTR(); if (CAN_GET_IDE()) { cmd->frame->inf.ide = 1; CAN_GET_EXT_ID(cmd->frame->inf.id); } else { cmd->frame->inf.ide = 0; CAN_GET_STD_ID(cmd->frame->inf.id); } } } // reset MOb status CAN_CLEAR_STATUS_MOB(); } ++mob_handle; source >>= 1; } process_poll(&can_drv_process); }