void CAN1RxMsgProcess(void) { CANRxMessageBuffer *message; if(isCAN1MsgReceived == FALSE) { return; } isCAN1MsgReceived = FALSE; message = CANGetRxMessage(CAN1, CAN_CHANNEL1); lcdInstruction("0;0H"); unsigned int sid = message->msgSID.SID; unsigned int data = message->data[0] << 8; unsigned int data2 = message->data[1]; float temp = (data + data2) * 0.1; sprintf(buffer, "%u", sid); lcdString(buffer); sprintf(buffer, "%2.2fF", temp); lcdInstruction("1;0H"); lcdString("ET: "); lcdString(buffer); CANUpdateChannel(CAN1, CAN_CHANNEL1); CANEnableChannelEvent(CAN1, CAN_CHANNEL1, CAN_RX_CHANNEL_NOT_EMPTY, TRUE); }
MUST_CHECK s32 nu__Can__tx(const struct nu__Can *c, CAN_CHANNEL chn, enum nu__Can__id_type id_type, u16 sid, u32 eid, u32 rtr, const void *data, size_t n) { s32 err; CANTxMessageBuffer *message = CANGetTxMessageBuffer(c->module, chn); if (n > 8) return -EINVAL; if ((err = go_normal_mode(c)) < 0) return err; /* clear message data */ memset(message, 0, sizeof(CANTxMessageBuffer)); /* insert SID/EID information */ message->msgEID.IDE = (NU_CAN_EXTENDED_ID == id_type); message->msgSID.SID = BITFIELD_CAST(sid, 11); /* 11 bits */ message->msgEID.DLC = BITFIELD_CAST(n, 4); /* 4 bits */ message->msgEID.RTR = BITFIELD_CAST(rtr, 1); /* 1 bit; 1 = remote transmission request enabled */ if (NU_CAN_EXTENDED_ID == id_type) /* EID is indicated by IDTypeExtended = 1 */ message->msgEID.EID = BITFIELD_CAST(eid, 18); /* 18 bits */ if (n) memcpy(message->data, (const byte *)data, n); CANUpdateChannel(c->module, chn); CANFlushTxChannel(c->module, chn); return 0; }
void CAN1TxSendLEDMsg(BYTE data0) { /* This function will send a message to * CAN2 with SID 202. The data payload * size is 1 byte. The value of the LED5Status * will be toggled and then sent as * the payload. CAN1 Channel 0 is used * to send the message*/ CANTxMessageBuffer * message; /* Get a pointer to the next buffer in the channel * check if the returned value is null. */ message = CANGetTxMessageBuffer(CAN1,CAN_CHANNEL0); if(message != NULL) { /* Form a Standard ID CAN message. * Start by clearing the buffer. * Send message to CAN2. * IDE = 0 means Standard ID message. * Send one byte of data. * This is the payload. */ message->messageWord[0] = 0; message->messageWord[1] = 0; message->messageWord[2] = 0; message->messageWord[3] = 0; message->msgSID.SID = 0x202; message->msgEID.IDE = 0; message->msgEID.DLC = 1; message->data[0] = data0; /* This function lets the CAN module * know that the message processing is done * and message is ready to be processed. */ CANUpdateChannel(CAN1,CAN_CHANNEL0); /* Direct the CAN module to flush the * TX channel. This will send any pending * message in the TX channel. */ CANFlushTxChannel(CAN1,CAN_CHANNEL0); } }
CANRxMessageBuffer* CAN1RxMsgProcess(void) { /* This function will check if a CAN * message is available in CAN1 channel 1. * If so , the message is read. Byte 0 of * the received message will indicate if * LED6 should be switched ON or OFF. */ CANRxMessageBuffer * message; if(isCAN1MsgReceived == FALSE) { /* CAN1 did not receive any message so * exit the function. Note that the * isCAN1MsgReceived flag is updated * by the CAN1 ISR. */ return 0; } /* Message was received. Reset message received flag to catch * the next message and read the message. Note that * you could also check the CANGetRxMessage function * return value for null to check if a message has * been received. */ isCAN1MsgReceived = FALSE; message = CANGetRxMessage(CAN1,CAN_CHANNEL1); /* Call the CANUpdateChannel() function to let * CAN 1 module know that the message processing * is done. Enable the receive channale not empty event * so that the CAN module generates an interrupt when * the event occurs the next time.*/ CANUpdateChannel(CAN1, CAN_CHANNEL1); CANEnableChannelEvent(CAN1, CAN_CHANNEL1, CAN_RX_CHANNEL_NOT_EMPTY, TRUE); return message; }
MUST_CHECK s64 nu__Can__rx(const struct nu__Can *c, CAN_CHANNEL chn, u32 *id, void *dst) { CANRxMessageBuffer *buf; unsigned long len; buf = (CANRxMessageBuffer *)CANGetRxMessage(c->module, chn); if (NULL == buf) return -ENODATA; if (buf->msgEID.IDE == NU_CAN_STANDARD_ID) { *id = (int)(buf->msgSID.SID); } else { /* NU_CAN_EXTENDED_ID */ /* msgEID.EID is 18 bits; msgSID.SID is 11 bits */ *id = (unsigned int)(buf->msgEID.EID) | (unsigned int)(buf->msgSID.SID << 18); } len = (unsigned long) buf->msgEID.DLC; memcpy(dst, buf->data, len); CANUpdateChannel(c->module, chn); return (long) len; }
CANRxMessageBuffer* CAN2RxMsgProcess(void) { /* This function will check if CAN 2 received * a message from CAN1. If so it will then read * CAN2 Channel 1. * Byte 0 of the received message will indicate * if the LED5 should be switched ON or OFF. */ CANRxMessageBuffer * message; if(isCAN2MsgReceived == FALSE) { /* CAN2 did not receive any message * so exit the function. Note that the * isCAN2MsgReceived flag is updated * by the CAN2 ISR. */ return 0; } /* Message was received. Reset isCAN2MsgReceived flag * to catch the next message. */ isCAN2MsgReceived = FALSE; message = CANGetRxMessage(CAN2,CAN_CHANNEL1); /* Call the CANUpdateChannel() function to let * the CAN module know that the message processing * is done. Enable the event so that the CAN module * generates an interrupt when the event occurs.*/ CANUpdateChannel(CAN2, CAN_CHANNEL1); CANEnableChannelEvent(CAN2, CAN_CHANNEL1, CAN_RX_CHANNEL_NOT_EMPTY, TRUE); return message; }
//================================================ // Configure the CAN1 interrupt handler //================================================ void __ISR(_CAN_1_VECTOR, CAN1_INT_PRIORITY) Can1InterruptHandler(void) { // Check if the source of the interrupt is RX_EVENT. This is redundant since // only this event is enabled in this example but this shows one scheme for // handling events if ((CANGetModuleEvent(CAN1) & CAN_RX_EVENT) != 0) { LED_CAN_TOGGLE; CANRxMessageBuffer *message; /* * CHANNEL 1 = SWITCHES STATES */ if (CANGetPendingEventCode(CAN1) == CAN_CHANNEL1_EVENT) { CANEnableChannelEvent(CAN1, CAN_CHANNEL1, CAN_RX_CHANNEL_NOT_EMPTY, FALSE); message = CANGetRxMessage(CAN1, CAN_CHANNEL1); CanSwitches_t switches; switches.bytes.low = message->data[0]; switches.bytes.high = message->data[1]; if (buttons.buttons.bits.steerWheelSw1 != switches.bits.sw1 ) { buttons.buttons.bits.steerWheelSw1 = switches.bits.sw1; buttons.chng.bits.steerWheelSw1 = 1; } if (buttons.buttons.bits.steerWheelSw4 != switches.bits.sw4 ) { buttons.buttons.bits.steerWheelSw4 = switches.bits.sw4; buttons.chng.bits.steerWheelSw4 = 1; } if (buttons.buttons.bits.steerWheelSw10 != switches.bits.sw10) { buttons.buttons.bits.steerWheelSw10 = switches.bits.sw10; buttons.chng.bits.steerWheelSw10 = 1; } LED_CAN_TOGGLE; CANUpdateChannel(CAN1, CAN_CHANNEL1); CANEnableChannelEvent(CAN1, CAN_CHANNEL1, CAN_RX_CHANNEL_NOT_EMPTY, TRUE); } /* * CHANNEL 2 = WIND ANGLE */ if (CANGetPendingEventCode(CAN1) == CAN_CHANNEL2_EVENT) { CANEnableChannelEvent(CAN1, CAN_CHANNEL2, CAN_RX_CHANNEL_NOT_EMPTY, FALSE); message = CANGetRxMessage(CAN1, CAN_CHANNEL2); memcpy((void *) &rxWindAngle, &message->data[0], 4); oNewWindAngle = 1; CANUpdateChannel(CAN1, CAN_CHANNEL2); CANEnableChannelEvent(CAN1, CAN_CHANNEL2, CAN_RX_CHANNEL_NOT_EMPTY, TRUE); } } // The CAN1 Interrupt flag is cleared at the end of the interrupt routine. // This is because the event source that could have caused this interrupt to // occur (CAN_RX_CHANNEL_NOT_EMPTY) is disabled. Attempting to clear the // CAN1 interrupt flag when the the CAN_RX_CHANNEL_NOT_EMPTY interrupt is // enabled will not have any effect because the base event is still present. INTClearFlag(INT_CAN1); }
void __attribute__((vector(46), interrupt(ipl4), nomips16)) CAN1InterruptHandler(void) { /* This is the CAN1 Interrupt Handler. * Note that there are many source events in the * CAN1 module for this interrupt. These * events are enabled by the CANEnableModuleEvent() * function. In this example, only the RX_EVENT * is enabled. */ /* Check if the source of the interrupt is * RX_EVENT. This is redundant since only this * event is enabled in this example but * this shows one scheme for handling events. */ if((CANGetModuleEvent(CAN1) & CAN_RX_EVENT) != 0) { /* Within this, you can check which channel caused the * event by using the CANGetModuleEvent() function * which returns a code representing the highest priority * pending event. */ if(CANGetPendingEventCode(CAN1) == CAN_CHANNEL1_EVENT) { /* This means that channel 1 caused the event. * The CAN_RX_CHANNEL_NOT_EMPTY event is persistent. You * could either read the channel in the ISR * to clear the event condition or as done * here, disable the event source, and set * an application flag to indicate that a message * has been received. The event can be * enabled by the application when it has processed * one message. * * Note that leaving the event enabled would * cause the CPU to keep executing the ISR since * the CAN_RX_CHANNEL_NOT_EMPTY event is persistent (unless * the not empty condition is cleared.) * */ CANRxMessageBuffer * message; message = CANGetRxMessage(CAN1,CAN_CHANNEL1); // Copy the byte into the local FIFO, if it won't cause an overflow if(RXHeadPtr != RXTailPtr - 1) { if((RXHeadPtr != vCANRXFIFO + sizeof(vCANRXFIFO)) || (RXTailPtr != vCANRXFIFO)) { *RXHeadPtr++ = (message->msgSID.SID >> 8); *RXHeadPtr++ = message->msgSID.SID; *RXHeadPtr++ = message->data[0]; *RXHeadPtr++ = message->data[1]; *RXHeadPtr++ = message->data[2]; *RXHeadPtr++ = message->data[3]; *RXHeadPtr++ = message->data[4]; *RXHeadPtr++ = message->data[5]; *RXHeadPtr++ = message->data[6]; *RXHeadPtr++ = message->data[7]; if(RXHeadPtr >= vCANRXFIFO + sizeof(vCANRXFIFO)) RXHeadPtr = vCANRXFIFO; } } CANUpdateChannel(CAN1, CAN_CHANNEL1); }