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); }
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); }