/** * @author Rémi Heredero * @version 1.0.0 * @date August 2023 * @file can_interface.c */ #include "can_interface.h" #include "../mcc_generated_files/ecan.h" typedef union { struct { uint8_t sender; uint8_t recipient; uint8_t message; uint32_t data; } full; struct { uint8_t sender; uint8_t recipient; uint8_t message; uint8_t data0; uint8_t data1; uint8_t data2; uint8_t data3; } separate; } CAN_MESSAGE; typedef union { struct { uint8_t byte0; uint8_t byte1; uint8_t byte2; uint8_t byte3; } separate; struct { uint32_t bytes; } full; } CAN_4_BYTES; void CAN_init(){ CAN_myself.receiveCan = NULL; CAN_myself.sender = 0; } void CAN_startBehaviour(){ POST(&CAN_myself, &CAN_processEvent, evCAinit, 0, 0); } bool CAN_processEvent(Event* ev) { bool processed = false; CAN* me = (CAN*)Event_getTarget(ev); CAN_STATES oldState = me->state; evIDT evid = Event_getId(ev); uint64_t data = Event_getData(ev); switch (me->state) { // onState case STCA_INIT: if (ev->id == evCAinit) { me->state = STCA_PROCESS; } break; case STCA_PROCESS: // New message arrive if (ev->id == evCAnewMsg) { if (me->receiveCan != NULL) { uint32_t canData = (uint32_t) data; data = data>>32; CAN_4_BYTES tmpData; tmpData.full.bytes = data; uint8_t idMsg = tmpData.separate.byte0; idMsg = idMsg >> 4; idMsg = idMsg & 0xF; uint8_t idRecipient = tmpData.separate.byte1; idRecipient = idRecipient & 0xF; uint8_t idSender = tmpData.separate.byte1; idSender = idSender >> 4; me->receiveCan(idSender, idMsg, canData); } } // Send a message if (ev->id == evCAsend) { uCAN_MSG canMsg; canMsg.frame.idType = dSTANDARD_CAN_MSG_ID_2_0B; // standard canMsg.frame.dlc = 4; // 4 bytes to send canMsg.frame.rtr = 0; // no remote frame canMsg.frame.data0 = (uint8_t) data; data = data >> 8; canMsg.frame.data1 = (uint8_t) data; data = data >> 8; canMsg.frame.data2 = (uint8_t) data; data = data >> 8; canMsg.frame.data3 = (uint8_t) data; data = data >> 8; canMsg.frame.id = (uint32_t) data; CAN_transmit(&canMsg); } break; } if(oldState != me->state){ switch (oldState) { // onExit case STCA_INIT: break; case STCA_PROCESS: break; } switch (me->state) { // onEntry case STCA_INIT: break; case STCA_PROCESS: break; } processed = true; } return processed; } /************* * Callbacks * *************/ void CAN_onReceiveCan(CAN_CALLBACK f) { CAN_myself.receiveCan = f; } /************ * EMITTERS * ************/ void CAN_newMsg() { uint64_t data; uCAN_MSG canMsg; CAN_receive(&canMsg); data = canMsg.frame.id; data = data<<12; data = data | canMsg.frame.data3; data = data<<8; data = data | canMsg.frame.data2; data = data<<8; data = data | canMsg.frame.data1; data = data<<8; data = data | canMsg.frame.data0; POST(&CAN_myself, &CAN_processEvent, evCAnewMsg, 0, data); } void CAN_Send(uint8_t idRecipient, uint8_t idMsg, uint32_t data) { uint64_t tmpData = CAN_myself.sender; tmpData = (tmpData<<4) | idRecipient; tmpData = (tmpData<<4) | idMsg; tmpData = (tmpData<<32) | data; POST(&CAN_myself, &CAN_processEvent, evCAsend, 0, tmpData); } /*********** * SETTERS * ***********/ void CAN_setSender(uint8_t idSender) { CAN_myself.sender = idSender; }