int can_recv(can_msg_t *msg) { tCANMsgObject MsgObjectRx; int i; unsigned long MsgObjNr,temp; MsgObjNr = CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT); if(MsgObjNr == 0) return 1; //find which msg object receives the can frame for (i = 0; i < 31; i++) { temp = 1 << i; if (MsgObjNr & temp) break; } MsgObjectRx.pucMsgData = (unsigned char *)msg->data; CANMessageGet(CAN0_BASE, i + 1, &MsgObjectRx, 1); msg->dlc = MsgObjectRx.ulMsgLen; if (MsgObjectRx.ulFlags & MSG_OBJ_EXTENDED_ID) { msg->flag = 1; msg->id = (MsgObjectRx.ulMsgID & 0x1FFFFFFF); } else { msg->flag = 0; msg->id = (MsgObjectRx.ulMsgID & 0x000007FF); } return 0; }
//******************************************************************************* // CAN ISR //******************************************************************************* void CANIntHandler() { // Read the CAN interrupt status to find the cause of the interrupt CAN_status = CANIntStatus(CAN0_BASE,CAN_INT_STS_CAUSE); if(CAN_status == CAN_INT_INTID_STATUS) // controller status interrupt { CAN_status = CANStatusGet(CAN0_BASE,CAN_STS_CONTROL); // read back error bits it will // clear also the status interrupt if(CAN_status & (CAN_STATUS_BUS_OFF | CAN_STATUS_EWARN | CAN_STATUS_EPASS | CAN_STATUS_LEC_MASK)) { err_flag = 1; // set the error flag //UARTprintf("Device connected on the CAN bus?\n\r"); // hint for connection trouble } CANIntDisable(CAN0_BASE,CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); //disable all CAN0 interrupts } else if(CAN_status == 1) // message object 1 interrupt { err_flag = 0; // clear any error flags CANIntClear(CAN0_BASE,1); // clear interrupt } else // should never happen { err_flag = 2 ; CANIntDisable(CAN0_BASE,CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); //disable all CAN0 interrupts } }
void CANIntHandler(void) { unsigned long status_flags; status_flags = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); if (status_flags == CAN_INT_INTID_STATUS) { status_flags = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); // TODO: process the error? } else if (status_flags == 1) { // Wheel A sCANMessage.pui8MsgData = (uint8_t *)&wheel_a_data; CANMessageGet(CAN0_BASE, 1, &sCANMessage, 1); } else if (status_flags == 2) { // Wheel B sCANMessage.pui8MsgData = (uint8_t *)&wheel_b_data; CANMessageGet(CAN0_BASE, 2, &sCANMessage, 1); } else if (status_flags == 3) { // Engine sCANMessage.pui8MsgData = (uint8_t *)&engine_data; CANMessageGet(CAN0_BASE, 3, &sCANMessage, 1); } else if (status_flags == 4) { // Fuel sCANMessage.pui8MsgData = (uint8_t *)&fuel_data; CANMessageGet(CAN0_BASE, 4, &sCANMessage, 1); } else { // // Spurious interrupt handling can go here. // } }
//***************************************************************************** // // The CAN controller interrupt handler. // //***************************************************************************** void CAN0_Handler(void){ uint8_t data[8]; uint32_t ulIntStatus, ulIDStatus; int i; tCANMsgObject xTempMsgObject; xTempMsgObject.pucMsgData = data; ulIntStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); // cause? if(ulIntStatus & CAN_INT_INTID_STATUS){ // receive? ulIDStatus = CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT); for(i = 0; i < 64; i++){ //test every bit of the mask if( (0x1 << i) & ulIDStatus){ // if active, get data CANMessageGet(CAN0_BASE, (i+1), &xTempMsgObject, true); if(xTempMsgObject.ulMsgID == RCV_ID){ if(CAN0_Fifo_Put(data[0])==0||CAN0_Fifo_Put(data[1])==0|| CAN0_Fifo_Put(data[2])==0||CAN0_Fifo_Put(data[3])==0|| CAN0_Fifo_Put(data[4])==0||CAN0_Fifo_Put(data[5])==0|| CAN0_Fifo_Put(data[6])==0||CAN0_Fifo_Put(data[7])==0){ PacketLost++;//increment the packet lost } MailFlag = true; // new mail } } } } CANIntClear(CAN0_BASE, ulIntStatus); // acknowledge }
int getFormMachine(char* id) { int value = -999; // error code int rc = 0; g_MsgObjectRx.ulMsgID = (0x400); g_MsgObjectRx.ulMsgIDMask = 0x7f8; g_MsgObjectRx.ulFlags = MSG_OBJ_USE_ID_FILTER; g_MsgObjectRx.ulMsgLen = snprintf(ucBufferIn, BUFFER_LEN, "%s", id, value); g_MsgObjectRx.pucMsgData = ucBufferIn; CANMessageSet(CAN0_BASE, 1, &g_MsgObjectRx, MSG_OBJ_TYPE_RX); printf("getFormMachine Message: %s\n", g_MsgObjectRx.pucMsgData); while((CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT)) & 1 == 0) { } CANMessageGet(CAN0_BASE, 1, &g_MsgObjectRx, true); value = atoi(strstr(g_MsgObjectRx.pucMsgData) + 1); printf("getFromMachine GetMessage: %s\n", g_MsgObjectRx.pucMsgData); return rc; return value; }
void CANIntHandler(void) { u32 status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); if(status == CAN_INT_INTID_STATUS) { status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); can_err_flag = 1; can_tx_flag = 0; } else if( status == 1 ) // Message receive { CANIntClear(CAN0_BASE, 1); can_rx_flag = 1; can_err_flag = 0; } else if( status == 2 ) // Message send { CANIntClear(CAN0_BASE, 2); can_tx_flag = 0; can_err_flag = 0; } else CANIntClear(CAN0_BASE, status); }
//***************************************************************************** // // The CAN controller interrupt handler. // //***************************************************************************** void CANIntHandler(void) { unsigned long ulStatus; // // Find the cause of the interrupt, if it is a status interrupt then just // acknowledge the interrupt by reading the status register. // ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); // // The first eight message objects make up the Transmit message FIFO. // if(ulStatus <= 8) { // // Increment the number of bytes transmitted. // g_sCAN.ulBytesTransmitted += 8; } // // The second eight message objects make up the Receive message FIFO. // else if((ulStatus > 8) && (ulStatus <= 16)) { // // Read the data out and acknowledge that it was read. // CANMessageGet(CAN0_BASE, ulStatus, &g_sCAN.MsgObjectRx, 1); // // Advance the read pointer. // g_sCAN.MsgObjectRx.pucMsgData += 8; // // Decrement the expected bytes remaining. // g_sCAN.ulBytesRemaining -= 8; } else { // // This was a status interrupt so read the current status to // clear the interrupt and return. // CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); } // // Acknowledge the CAN controller interrupt has been handled. // CANIntClear(CAN0_BASE, ulStatus); }
void setup(){ Serial.begin(9600); Serial.println("DEBUG1"); SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0); SysCtlPeripheralEnable(GPIO_PORTE_BASE); GPIOPinTypeCAN(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5); GPIOPinConfigure(GPIO_PE4_CAN0RX); GPIOPinConfigure(GPIO_PE5_CAN0TX); tCANMsgObject sCANMessage; uint8_t ucMsgData[8]; Serial.println("DEBUG2"); uint8_t pui8BufferIn[8]; uint8_t pui8BufferOut[8]; Serial.println("DEBUG3"); CANInit(CAN0_BASE); CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000); CANEnable(CAN0_BASE); sCANMessage.ui32MsgID = 0; // CAN msg ID - 0 for any sCANMessage.ui32MsgIDMask = 0; // mask is 0 for any ID sCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER; sCANMessage.ui32MsgLen = 8; // allow up to 8 bytes // // Now load the message object into the CAN peripheral. Once loaded the // CAN will receive any message on the bus, and an interrupt will occur. // Use message object 1 for receiving messages (this is not the same as // the CAN ID which can be any value in this example). // CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_RX); Serial.println("DEBUG5"); while((CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT) & 1) == 0) { // // Read the message out of the message object. // CANMessageGet(CAN0_BASE, 1, &sCANMessage, true); Serial.println(sCANMessage.ui32MsgLen); } Serial.println(sCANMessage.ui32MsgLen); Serial.println(sCANMessage.ui32MsgID); }
void CAN_ISR(void) { unsigned long ulStatus; ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); switch(ulStatus) { case MSG_NUM_RX: // message received CANMessageGet(CAN0_BASE, MSG_NUM_RX, &g_MsgRx, /*clear int*/ 1); NetworkRxCallback(g_ulRxData); // call user function upon receiving a message break; default: // status or other interrupt: clear it without further action CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); CANIntClear(CAN0_BASE, ulStatus); } }
int sendToMachine(char* id, int value) { int rc = 0; g_MsgObjectRx.ulMsgID = (0x400); g_MsgObjectRx.ulMsgIDMask = 0x7f8; g_MsgObjectRx.ulFlags = MSG_OBJ_USE_ID_FILTER; g_MsgObjectRx.ulMsgLen = snprintf(ucBufferIn, BUFFER_LEN, "%s:%d", id, value); g_MsgObjectRx.pucMsgData = ucBufferIn; CANMessageSet(CAN0_BASE, 1, &g_MsgObjectRx, MSG_OBJ_TYPE_RX); printf("setToMachine SetMessage: %s\n", g_MsgObjectRx.pucMsgData); while((CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT)) & 1 == 0) {} CANMessageGet(CAN0_BASE, 1, &g_MsgObjectRx, true); printf("setToMachine Message: %s\n", g_MsgObjectRx.pucMsgData); return rc; }
//***************************************************************************** // // The CAN controller interrupt handler. // //***************************************************************************** void CAN0_Handler(void){ uint8_t data[4]; uint32_t ulIntStatus, ulIDStatus; unsigned long temp; int i; tCANMsgObject xTempMsgObject; xTempMsgObject.pucMsgData = data; ulIntStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); // cause? if(ulIntStatus & CAN_INT_INTID_STATUS){ // receive? ulIDStatus = CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT); for(i = 0; i < 32; i++){ //test every bit of the mask if( (0x1 << i) & ulIDStatus){ // if active, get data CANMessageGet(CAN0_BASE, (i+1), &xTempMsgObject, true); if(xTempMsgObject.ulMsgID == Ping1_ID){ //temp = (data[0]<<24)&0xFF000000 + (data[1]<<16)&0x00FF0000 + (data[2]<<8)&0x0000FF00 + data[3]&0x000000FF; temp = (data[0]<<24) + (data[1]<<16) + (data[2]<<8) + data[3]; Mailbox = temp; }else if(xTempMsgObject.ulMsgID == Ping2_ID){ temp = (data[0]<<24) + (data[1]<<16) + (data[2]<<8) + data[3]; Mailbox2 = temp; }else if(xTempMsgObject.ulMsgID == Ping3_ID){ temp = (data[0]<<24) + (data[1]<<16) + (data[2]<<8) + data[3]; Mailbox3 = temp; }else if(xTempMsgObject.ulMsgID == Ping4_ID){ temp = (data[0]<<24) + (data[1]<<16) + (data[2]<<8) + data[3]; Mailbox4 = temp; }else if(xTempMsgObject.ulMsgID == Button1_ID){ button1Pressed = 1; //add thread that compensates for wall hit }else if(xTempMsgObject.ulMsgID == Button2_ID){ button2Pressed = 1; //add thread that compensates for wall hit }else if(xTempMsgObject.ulMsgID == IR_ID){ temp = (data[0]<<24) + (data[1]<<16) + (data[2]<<8) + data[3]; Mailbox5 = temp; } } } } CANIntClear(CAN0_BASE, ulIntStatus); // acknowledge }
void CAN0_Handler(void) { unsigned char data[8]; unsigned long ulIntStatus, ulIDStatus; CANmsgType rxMsg; int i; tCANMsgObject xTempMsgObject; xTempMsgObject.pucMsgData = data; // rxMsg.timestamp = OS_getTime(); //timestamp the CAN message ulIntStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); if(ulIntStatus & CAN_INT_INTID_STATUS) { // receive? ulIDStatus = CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT); for(i = 0; i < 32; i++) { //test every bit of the mask if( (0x1 << i) & ulIDStatus) { // if active, get data CANMessageGet(CAN0_BASE, (i+1), &xTempMsgObject, true); rxMsg.byte0 = data[0]; rxMsg.byte1 = data[1]; rxMsg.byte2 = data[2]; rxMsg.byte3 = data[3]; rxMsg.byte4 = data[4]; rxMsg.byte5 = data[5]; rxMsg.byte6 = data[6]; rxMsg.byte7 = data[7]; rxMsg.length = xTempMsgObject.ulMsgLen; rxMsg.ID = xTempMsgObject.ulMsgID; if(CAN_RX_FIFOFifo_Put(rxMsg) == CANFIFOFAIL); CAN_Data_lost++; OS_Signal(&CANmessagesReceived); break; } } } CANIntClear(CAN0_BASE, ulIntStatus); // acknowledge }
//***************************************************************************** // // The CAN controller interrupt handler. // //***************************************************************************** void CAN0_Handler(void){ unsigned char data[4]; unsigned long ulIntStatus, ulIDStatus; int i; tCANMsgObject xTempMsgObject; xTempMsgObject.pucMsgData = data; ulIntStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); // cause? if(ulIntStatus & CAN_INT_INTID_STATUS){ // receive? ulIDStatus = CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT); for(i = 0; i < 32; i++){ //test every bit of the mask if( (0x1 << i) & ulIDStatus){ // if active, get data CANMessageGet(CAN0_BASE, (i+1), &xTempMsgObject, true); if(xTempMsgObject.ulMsgID == RCV_ID){ RCVData[0] = data[0]; RCVData[1] = data[1]; RCVData[2] = data[2]; RCVData[3] = data[3]; MailFlag = true; // new mail } } } } CANIntClear(CAN0_BASE, ulIntStatus); // acknowledge }
/* nonblocked send, success return 0, else return -1 */ int can_send(const can_msg_t *msg) { unsigned long status; tCANMsgObject MsgObjectTx; status = CANStatusGet(CAN0_BASE, CAN_STS_TXREQUEST); if(status & (unsigned long)(1 << (LM3S_TxMsgObjNr - 1))) return 1; MsgObjectTx.ulMsgID = msg->id; MsgObjectTx.ulMsgLen = msg->dlc; MsgObjectTx.pucMsgData = (unsigned char *)msg->data; if (msg->flag) { MsgObjectTx.ulFlags = MSG_OBJ_EXTENDED_ID; } else { MsgObjectTx.ulFlags = MSG_OBJ_NO_FLAGS; } CANRetrySet(CAN0_BASE, LM3S_TxMsgObjNr); //set retry send CANMessageSet(CAN0_BASE, LM3S_TxMsgObjNr, &MsgObjectTx, MSG_OBJ_TYPE_TX); return 0; }
// The CAN controller interrupt handler. void CANHandler(void) { unsigned long ulStatus; // // Find the cause of the interrupt, if it is a status interrupt then just // acknowledge the interrupt by reading the status register. // ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); switch(ulStatus) { // This was a status interrupt so read the current status to clear the interrupt and return. default: { CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); return; } } // Acknowledge the CAN controller interrupt has been handled. CANIntClear(CAN0_BASE, ulStatus); }
//***************************************************************************** // // This function is the interrupt handler for the CAN peripheral. It checks // for the cause of the interrupt, and maintains a count of all messages that // have been transmitted. // //***************************************************************************** void CANIntHandler(void) { uint32_t ui32Status; // // Read the CAN interrupt status to find the cause of the interrupt // ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); // // If the cause is a controller status interrupt, then get the status // if(ui32Status == CAN_INT_INTID_STATUS) { // // Read the controller status. This will return a field of status // error bits that can indicate various errors. Error processing // is not done in this example for simplicity. Refer to the // API documentation for details about the error status bits. // The act of reading this status will clear the interrupt. If the // CAN peripheral is not connected to a CAN bus with other CAN devices // present, then errors will occur and will be indicated in the // controller status. // ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); // // Set a flag to indicate some errors may have occurred. // g_bErrFlag = 1; } // // Check if the cause is message object 1, which is used for sending // message 1. // else if(ui32Status == 1) { // // Getting to this point means that the TX interrupt occurred on // message object 1, and the message TX is complete. Clear the // message object interrupt. // CANIntClear(CAN0_BASE, 1); // // Increment a counter to keep track of how many messages have been // sent. In a real application this could be used to set flags to // indicate when a message is sent. // g_ui32Msg1Count++; // // Since the message was sent, clear any error flags. // g_bErrFlag = 0; } // // Check if the cause is message object 2, which is used for sending // message 2. // else if(ui32Status == 2) { // // Getting to this point means that the TX interrupt occurred on // message object 2, and the message TX is complete. Clear the // message object interrupt. // CANIntClear(CAN0_BASE, 2); // // Increment a counter to keep track of how many messages have been // sent. In a real application this could be used to set flags to // indicate when a message is sent. // g_ui32Msg2Count++; // // Since the message was sent, clear any error flags. // g_bErrFlag = 0; } // // Check if the cause is message object 3, which is used for sending // messages 3 and 4. // else if(ui32Status == 3) { // // Getting to this point means that the TX interrupt occurred on // message object 3, and a message TX is complete. Clear the // message object interrupt. // CANIntClear(CAN0_BASE, 3); // // Increment a counter to keep track of how many messages have been // sent. In a real application this could be used to set flags to // indicate when a message is sent. // g_ui32Msg3Count++; // // Set the flag indicating that a message was sent using message // object 3. The program main loop uses this to know when to send // another message using message object 3. // g_bMsgObj3Sent = 1; // // Since the message was sent, clear any error flags. // g_bErrFlag = 0; } // // Otherwise, something unexpected caused the interrupt. This should // never happen. // else { // // Spurious interrupt handling can go here. // } }
//***************************************************************************** // // The CAN controller Interrupt handler. // //***************************************************************************** void CANHandler(void) { unsigned long ulStatus; // // Find the cause of the interrupt, if it is a status interrupt then just // acknowledge the interrupt by reading the status register. // ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); switch(ulStatus) { // // Let the forground loop handle sending this, just set a flag to // indicate that the data should be sent. // case MSGOBJ_NUM_BUTTON: { // // Read the Button Message. // CANMessageGet(CAN0_BASE, MSGOBJ_NUM_BUTTON, &g_MsgObjectButton, 1); // // Only respond to buttons being release. // if(g_MsgObjectButton.pucMsgData[0] == EVENT_BUTTON_RELEASED) { // // Check if the up button was released. // if(g_MsgObjectButton.pucMsgData[1] == TARGET_BUTTON_UP) { // // Adjust the volume up by 10. // AudioVolumeUp(10); } // // Check if the down button was released. // if(g_MsgObjectButton.pucMsgData[1] == TARGET_BUTTON_DN) { // // Adjust the volume down by 10. // AudioVolumeDown(10); } } break; } // // When the LED message object interrupts, just clear the flag so that // more LED messages are allowed to transfer. // case MSGOBJ_NUM_LED: { g_ulFlags &= (~FLAG_LED_TX_PEND); break; } // // When the transmit data message object interrupts, clear the // flag so that more data can be trasferred. // case MSGOBJ_NUM_DATA_TX: { g_ulFlags &= (~FLAG_DATA_TX_PEND); break; } // // When a receive data message object interrupts, set the flag to // indicate that new data is ready. // case MSGOBJ_NUM_DATA_RX: { g_ulFlags |= FLAG_DATA_RECV; break; } // // This was a status interrupt so read the current status to // clear the interrupt and return. // default: { // // Read the controller status to acknowledge this interrupt. // CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); // // If there was a LED transmission pending, then stop it and // clear the flag. // if(g_ulFlags & FLAG_LED_TX_PEND) { // // Disable this message object until we retry it later. // CANMessageClear(CAN0_BASE, MSGOBJ_NUM_LED); // // Clear the transmit pending flag. // g_ulFlags &= (~FLAG_LED_TX_PEND); } // // If there was a Data transmission pending, then stop it and // clear the flag. // if(g_ulFlags & FLAG_DATA_TX_PEND) { // // Disable this message object until we retry it later. // CANMessageClear(CAN0_BASE, MSGOBJ_NUM_DATA_TX); // // Clear the transmit pending flag. // g_ulFlags &= (~FLAG_DATA_TX_PEND); } return; } } // // Acknowledge the CAN controller interrupt has been handled. // CANIntClear(CAN0_BASE, ulStatus); }
//***************************************************************************** // // The CAN controller interrupt handler. // // /return None. // //***************************************************************************** void CANHandler(void) { unsigned long ulStatus; // // Find the cause of the interrupt, if it is a status interrupt then just // acknowledge the interrupt by reading the status register. // ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); switch(ulStatus) { // // Let the forground loop handle sending this, just set a flag to // indicate that the data should be sent. // case MSGOBJ_NUM_BUTTON: { // // Indicate a pending button transmission is complete. // g_ulFlags &= (~FLAG_BUTTON_PEND); break; } case MSGOBJ_NUM_LED: { // // Read the new LED level and let the foreground handle it. // CANMessageGet(CAN0_BASE, MSGOBJ_NUM_LED, &g_MsgObjectLED, 1); // // Limit the LED Level to MAX_LED_BRIGHTNESS. // if((g_ucLEDLevel & LED_FLASH_VALUE_MASK) > MAX_LED_BRIGHTNESS) { g_ucLEDLevel = MAX_LED_BRIGHTNESS | (g_ucLEDLevel & LED_FLASH_ONCE); } // // Indicate that the LED needs to be updated. // g_ulFlags |= FLAG_UPDATE_LED; break; } // // The data transmit message object has been sent successfully. // case MSGOBJ_NUM_DATA_TX: { // // Clear the data transmit pending flag. // g_ulFlags &= (~FLAG_DATA_TX_PEND); break; } // // The data receive message object has received some data. // case MSGOBJ_NUM_DATA_RX: { // // Indicate that the data message object has new data. // g_ulFlags |= FLAG_DATA_RECV; break; } // // This was a status interrupt so read the current status to // clear the interrupt and return. // default: { CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); return; } } // // Acknowledge the CAN controller interrupt has been handled. // CANIntClear(CAN0_BASE, ulStatus); }
//***************************************************************************** // // CAN 0 Interrupt Handler. It checks for the cause of the interrupt, and // maintains a count of all messages that have been transmitted / received // //***************************************************************************** void CAN0IntHandler(void) { uint32_t ui32Status; // // Read the CAN interrupt status to find the cause of the interrupt // // CAN_INT_STS_CAUSE register values // 0x0000 = No Interrupt Pending // 0x0001-0x0020 = Number of message object that caused the interrupt // 0x8000 = Status interrupt // all other numbers are reserved and have no meaning in this system // ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); // // If this was a status interrupt acknowledge it by reading the CAN // controller status register. // if(ui32Status == CAN_INT_INTID_STATUS) { // // Read the controller status. This will return a field of status // error bits that can indicate various errors. Refer to the // API documentation for details about the error status bits. // The act of reading this status will clear the interrupt. // ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); // // Add ERROR flags to list of current errors. To be handled // later, because it would take too much time here in the // interrupt. // g_ui32ErrFlag |= ui32Status; } // // Check if the cause is message object RXOBJECT, which we are using // for receiving messages. // else if(ui32Status == RXOBJECT) { // // Getting to this point means that the RX interrupt occurred on // message object RXOBJECT, and the message reception is complete. // Clear the message object interrupt. // CANIntClear(CAN0_BASE, RXOBJECT); // // Increment a counter to keep track of how many messages have been // received. In a real application this could be used to set flags to // indicate when a message is received. // g_ui32RXMsgCount++; // // Set flag to indicate received message is pending. // g_bRXFlag = true; // // Since a message was received, clear any error flags. // This is done because before the message is received it triggers // a Status Interrupt for RX complete. by clearing the flag here we // prevent unnecessary error handling from happeneing // g_ui32ErrFlag = 0; } // // Check if the cause is message object TXOBJECT, which we are using // for transmitting messages. // else if(ui32Status == TXOBJECT) { // // Getting to this point means that the TX interrupt occurred on // message object TXOBJECT, and the message reception is complete. // Clear the message object interrupt. // CANIntClear(CAN0_BASE, TXOBJECT); // // Increment a counter to keep track of how many messages have been // transmitted. In a real application this could be used to set // flags to indicate when a message is transmitted. // g_ui32TXMsgCount++; // // Since a message was transmitted, clear any error flags. // This is done because before the message is transmitted it triggers // a Status Interrupt for TX complete. by clearing the flag here we // prevent unnecessary error handling from happeneing // g_ui32ErrFlag = 0; } // // Otherwise, something unexpected caused the interrupt. This should // never happen. // else { // // Spurious interrupt handling can go here. // } }
//***************************************************************************** // // This function is the interrupt handler for the CAN peripheral. It checks // for the cause of the interrupt, and maintains a count of all messages that // have been received. // //***************************************************************************** void CAN0_IRQHandler(void) { uint32_t ui32Status; // // Read the CAN interrupt status to find the cause of the interrupt // ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); // // If the cause is a controller status interrupt, then get the status // if(ui32Status == CAN_INT_INTID_STATUS) { // // Read the controller status. This will return a field of status // error bits that can indicate various errors. Error processing // is not done in this example for simplicity. Refer to the // API documentation for details about the error status bits. // The act of reading this status will clear the interrupt. // ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); // // Set a flag to indicate some errors may have occurred. // g_bErrFlag = 1; } // // Check if the cause is message object 1. // else if(ui32Status == 1) { // // Getting to this point means that the RX interrupt occurred on // message object 1, and the message reception is complete. Clear the // message object interrupt. // CANIntClear(CAN0_BASE, 1); // // Increment a counter to keep track of how many messages have been // received. In a real application this could be used to set flags to // indicate when a message is received. // g_ui32MsgCount++; // // Set flag to indicate received message is pending for this message // object. // g_bRXFlag1 = 1; // // Since a message was received, clear any error flags. // g_bErrFlag = 0; } // // Check if the cause is message object 2. // else if(ui32Status == 2) { CANIntClear(CAN0_BASE, 2); g_ui32MsgCount++; g_bRXFlag2 = 1; g_bErrFlag = 0; } // // Check if the cause is message object 3. // else if(ui32Status == 3) { CANIntClear(CAN0_BASE, 3); g_ui32MsgCount++; g_bRXFlag3 = 1; g_bErrFlag = 0; } // // Otherwise, something unexpected caused the interrupt. This should // never happen. // else { // // Spurious interrupt handling can go here. // } }
//***************************************************************************** // // This function is the interrupt handler for the CAN peripheral. It checks // for the cause of the interrupt, and maintains a count of all messages that // have been transmitted. // //***************************************************************************** extern "C" void CAN0IntHandler(void) { unsigned long ulStatus; // Read the CAN interrupt status to find the cause of the interrupt ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); // // If the cause is a controller status interrupt, then get the status // if (ulStatus == CAN_INT_INTID_STATUS) { // // Read the controller status. This will return a field of status // error bits that can indicate various errors. Error processing // is not done in this example for simplicity. Refer to the // API documentation for details about the error status bits. // The act of reading this status will clear the interrupt. If the // CAN peripheral is not connected to a CAN bus with other CAN devices // present, then errors will occur and will be indicated in the // controller status. // ulStatus = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); if (ulStatus == CAN_STATUS_TXOK) { } else if (ulStatus == CAN_STATUS_RXOK) { } else /* CAN_STS_CONTROL - the main controller status CAN_STS_TXREQUEST - bit mask of objects pending transmissio CAN_STS_NEWDAT - bit mask of objects with new data CAN_STS_MSGVAL - bit mask of objects with valid configuration CAN_STATUS_BUS_OFF - controller is in bus-off condition CAN_STATUS_EWARN - an error counter has reached a limit of at least 96 CAN_STATUS_EPASS - CAN controller is in the error passive state CAN_STATUS_RXOK - a message was received successfully (independent of any mes-sage filtering). CAN_STATUS_TXOK - a message was successfully transmitted CAN_STATUS_LEC_MSK - mask of last error code bits (3 bits) CAN_STATUS_LEC_NONE - no error CAN_STATUS_LEC_STUFF - stuffing error detected CAN_STATUS_LEC_FORM - a format error occurred in the fixed format part of amessage CAN_STATUS_LEC_ACK - a transmitted message was not acknowledged CAN_STATUS_LEC_BIT1 - dominant level detected when trying to send in recessive mode CAN_STATUS_LEC_BIT0 - recessive level detected when trying to send in dominant mode CAN_STATUS_LEC_CRC - CRC error in received message */ can0._countErr++; } // // Check if the cause is message object 1, which what we are using for // sending messages. // else if (ulStatus < can0._tableIdx + 1 && ulStatus > 0) { uint32_t idx = ulStatus - 1; if (can0._table[idx].mode == CAN::RECV) { tCANMsgObject* msgObj = (can0._table[idx].msgObject); CANIntClear(CAN0_BASE, idx + 1); CANMessageGet(CAN0_BASE, idx + 1, msgObj, true); can0._countRxd++; CANListener* listener = can0._table[idx].listener; listener->recv(msgObj->ulMsgID, msgObj->ulMsgLen, msgObj->pucMsgData); CANMessageSet(CAN0_BASE, ulStatus, msgObj, MSG_OBJ_TYPE_RX); // CANMessageSet(CAN0_BASE, ulStatus, msgObj, MSG_OBJ_TYPE_TX); // reload } else if (can0._table[idx].mode == CAN::SEND) { CANListener* listener = can0._table[idx].listener; tCANMsgObject* msgObj = (can0._table[idx].msgObject); CANIntClear(CAN0_BASE, idx + 1); can0._countTxd++; listener->sendDone(msgObj->ulMsgID, E_OK); } } else { // // Spurious interrupt handling can go here. // CANIntClear(CAN0_BASE, ulStatus); } }