/** ECAN Generated Driver File @Company Microchip Technology Inc. @File Name ecan.c @Summary This is the generated driver implementation for the CAN driver using PIC10 / PIC12 / PIC16 / PIC18 MCUs @Description This source file provides APIs for CAN. Generation Information : Product Revision : PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.81.8 Device : PIC18F25K83 Driver Version : 3.0.0 The generated drivers are tested against the following: Compiler : XC8 2.36 and above MPLAB : MPLAB X 6.00 */ /* (c) 2018 Microchip Technology Inc. and its subsidiaries. Subject to your compliance with these terms, you may use Microchip software and any derivatives exclusively with Microchip products. It is your responsibility to comply with third party license terms applicable to your use of third party software (including open source software) that may accompany Microchip software. THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. */ /** Section: Included Files */ #include #include "ecan.h" static void (*RXBnInterruptHandler)(void); static void (*RXBnOverflowHandler)(void); static void (*BusOffHandler)(void); static void (*TXPassiveHandler)(void); static void (*RXPassiveHandler)(void); static void (*TXWarningHandler)(void); static void (*RXWarningHandler)(void); /** Local Functions */ static uint32_t convertReg2ExtendedCANid(uint8_t tempRXBn_EIDH, uint8_t tempRXBn_EIDL, uint8_t tempRXBn_SIDH, uint8_t tempRXBn_SIDL); static uint32_t convertReg2StandardCANid(uint8_t tempRXBn_SIDH, uint8_t tempRXBn_SIDL); static void convertCANid2Reg(uint32_t tempPassedInID, uint8_t canIdType, uint8_t *passedInEIDH, uint8_t *passedInEIDL, uint8_t *passedInSIDH, uint8_t *passedInSIDL); static void RXBnDefaultInterruptHandler(void) {} static void RXBnOverflowDefaultHandler(void) {} static void BusOffDefaultHandler(void) {} static void TXPassiveDefaultHandler(void) {} static void RXPassiveDefaultHandler(void) {} static void TXWarningDefaultHandler(void) {} static void RXWarningDefaultHandler(void) {} void ECAN_Initialize(void) { CANCON = 0x80; while (0x80 != (CANSTAT & 0xE0)); // wait until ECAN is in config mode /** Mode 2 */ ECANCON = 0x90; /** Initialize CAN I/O */ CIOCON = 0x00; /** Mask and Filter definitions ........................................................ CAN ID ID Type Mask Filter Buffer ........................................................ 0x123 SID Acceptance Mask 0 Filter 0 FIFO ........................................................ */ /** Configure Generic Buffers to be Transmit or Receive */ BSEL0 = 0x00; /** Mask and Filter definitions ........................................................ CAN ID ID Type Mask Filter Buffer ........................................................ ........................................................ */ /* * Mask 0 is 11 bits for filters 0 and 1 only * filter set for 3 recipient bits * Mask 1 is copy of mask 0 but for other filters */ convertCANid2Reg(0x070, dSTANDARD_CAN_MSG_ID_2_0B, &RXM0EIDH, &RXM0EIDL, &RXM0SIDH, &RXM0SIDL); convertCANid2Reg(0x070, dSTANDARD_CAN_MSG_ID_2_0B, &RXM1EIDH, &RXM1EIDL, &RXM1SIDH, &RXM1SIDL); // filter 0 is broadcast message convertCANid2Reg(0x000, dSTANDARD_CAN_MSG_ID_2_0B, &RXF0EIDH, &RXF0EIDL, &RXF0SIDH, &RXF0SIDL); // filter 1 is message for controller convertCANid2Reg(0x010, dSTANDARD_CAN_MSG_ID_2_0B, &RXF1EIDH, &RXF1EIDL, &RXF1SIDH, &RXF1SIDL); // filter 2 is message for recipient n°7, not yet defined convertCANid2Reg(0x070, dSTANDARD_CAN_MSG_ID_2_0B, &RXF2EIDH, &RXF2EIDL, &RXF2SIDH, &RXF2SIDL); /* * ENABLE FILTERS * * RXF7EN RXF6EN RXF5EN RXF4EN RXF3EN RXF2EN RXF1EN RXF0EN * 0b 00000111 */ RXFCON0 = 0x07; /* * Assign Filters to Masks * * Filter 0 set on mask 0 * Filter 1 set on mask 0 * Filter 2 set on mask 1 * 0b F3 F2 F1 F0 * 0b 00 01 00 00 */ MSEL0 = 0x10; /** Initialize CAN Timings */ /** Baud rate: 250kbps System frequency: 64000000 ECAN clock frequency: 64000000 Time quanta: 8 Sample point: 1-1-4-2 Sample point: 75% */ BRGCON1 = 0x0F; BRGCON2 = 0x98; BRGCON3 = 0x81; ECAN_SetRXBnInterruptHandler(RXBnDefaultInterruptHandler); PIR5bits.RXBnIF = 0; PIE5bits.RXBnIE = 1; ECAN_SetRXBnOverflowHandler(RXBnOverflowDefaultHandler); ECAN_SetBusOffHandler(BusOffDefaultHandler); ECAN_SetTXPassiveHandler(TXPassiveDefaultHandler); ECAN_SetRXPassiveHandler(RXPassiveDefaultHandler); ECAN_SetTXWarningHandler(TXWarningDefaultHandler); ECAN_SetRXWarningHandler(RXWarningDefaultHandler); PIR5bits.ERRIF = 0; PIE5bits.ERRIE = 1; CANCON = 0x00; while (0x00 != (CANSTAT & 0xE0)); // wait until ECAN is in Normal mode } /** Section: ECAN APIs */ void CAN_sleep(void) { CANCON = 0x20; // request disable mode while ((CANSTAT & 0xE0) != 0x20); // wait until ECAN is in disable mode //Wake up from sleep should set the CAN module straight into Normal mode } uint8_t CAN_transmit(uCAN_MSG *tempCanMsg) { uint8_t tempEIDH = 0; uint8_t tempEIDL = 0; uint8_t tempSIDH = 0; uint8_t tempSIDL = 0; uint8_t returnValue = 0; if (TXB0CONbits.TXREQ != 1) { convertCANid2Reg(tempCanMsg->frame.id, tempCanMsg->frame.idType, &tempEIDH, &tempEIDL, &tempSIDH, &tempSIDL); TXB0EIDH = tempEIDH; TXB0EIDL = tempEIDL; TXB0SIDH = tempSIDH; TXB0SIDL = tempSIDL; TXB0DLC = tempCanMsg->frame.dlc | ((tempCanMsg->frame.rtr)<<6); TXB0D0 = tempCanMsg->frame.data0; TXB0D1 = tempCanMsg->frame.data1; TXB0D2 = tempCanMsg->frame.data2; TXB0D3 = tempCanMsg->frame.data3; TXB0D4 = tempCanMsg->frame.data4; TXB0D5 = tempCanMsg->frame.data5; TXB0D6 = tempCanMsg->frame.data6; TXB0D7 = tempCanMsg->frame.data7; TXB0CONbits.TXREQ = 1; //Set the buffer to transmit returnValue = 1; } else if (TXB1CONbits.TXREQ != 1) { convertCANid2Reg(tempCanMsg->frame.id, tempCanMsg->frame.idType, &tempEIDH, &tempEIDL, &tempSIDH, &tempSIDL); TXB1EIDH = tempEIDH; TXB1EIDL = tempEIDL; TXB1SIDH = tempSIDH; TXB1SIDL = tempSIDL; TXB1DLC = tempCanMsg->frame.dlc | ((tempCanMsg->frame.rtr)<<6); TXB1D0 = tempCanMsg->frame.data0; TXB1D1 = tempCanMsg->frame.data1; TXB1D2 = tempCanMsg->frame.data2; TXB1D3 = tempCanMsg->frame.data3; TXB1D4 = tempCanMsg->frame.data4; TXB1D5 = tempCanMsg->frame.data5; TXB1D6 = tempCanMsg->frame.data6; TXB1D7 = tempCanMsg->frame.data7; TXB1CONbits.TXREQ = 1; //Set the buffer to transmit returnValue = 1; } else if (TXB2CONbits.TXREQ != 1) { convertCANid2Reg(tempCanMsg->frame.id, tempCanMsg->frame.idType, &tempEIDH, &tempEIDL, &tempSIDH, &tempSIDL); TXB2EIDH = tempEIDH; TXB2EIDL = tempEIDL; TXB2SIDH = tempSIDH; TXB2SIDL = tempSIDL; TXB2DLC = tempCanMsg->frame.dlc | ((tempCanMsg->frame.rtr)<<6); TXB2D0 = tempCanMsg->frame.data0; TXB2D1 = tempCanMsg->frame.data1; TXB2D2 = tempCanMsg->frame.data2; TXB2D3 = tempCanMsg->frame.data3; TXB2D4 = tempCanMsg->frame.data4; TXB2D5 = tempCanMsg->frame.data5; TXB2D6 = tempCanMsg->frame.data6; TXB2D7 = tempCanMsg->frame.data7; TXB2CONbits.TXREQ = 1; //Set the buffer to transmit returnValue = 1; } return (returnValue); } /** Version A2 has a silicon errata This code works for all revisions */ //Fix for Errata #define dRXB0CON_FIFO_POINTER_VALUE 0 #define dRXB1CON_FIFO_POINTER_VALUE 1 #define dB0CON_FIFO_POINTER_VALUE 2 #define dB1CON_FIFO_POINTER_VALUE 3 #define dB2CON_FIFO_POINTER_VALUE 4 #define dB3CON_FIFO_POINTER_VALUE 5 #define dB4CON_FIFO_POINTER_VALUE 6 #define dB5CON_FIFO_POINTER_VALUE 7 uint8_t CAN_receive(uCAN_MSG *tempCanMsg) { uint8_t returnValue = 0; uint8_t tempECANCON; uint8_t tempReg; tempReg = (CANCON & 0x0F); //get the next RX buffer to read tempECANCON = ECANCON; //Backup ECANCON |= (tempReg + 0x10); //Per Errata need to use this method to read out BxCON register switch (tempReg) { case dRXB0CON_FIFO_POINTER_VALUE: if (RXB0CONbits.RXFUL != 0) // Check RXB0 { if ((RXB0SIDL & 0x08) == 0x08) //If Extended Message { //message is extended tempCanMsg->frame.idType = (uint8_t) dEXTENDED_CAN_MSG_ID_2_0B; tempCanMsg->frame.id = convertReg2ExtendedCANid(RXB0EIDH, RXB0EIDL, RXB0SIDH, RXB0SIDL); } else { //message is standard tempCanMsg->frame.idType = (uint8_t) dSTANDARD_CAN_MSG_ID_2_0B; tempCanMsg->frame.id = convertReg2StandardCANid(RXB0SIDH, RXB0SIDL); } tempCanMsg->frame.dlc = RXB0DLC & 0x0F; tempCanMsg->frame.rtr = RXB0DLC >> 6; tempCanMsg->frame.data0 = RXB0D0; tempCanMsg->frame.data1 = RXB0D1; tempCanMsg->frame.data2 = RXB0D2; tempCanMsg->frame.data3 = RXB0D3; tempCanMsg->frame.data4 = RXB0D4; tempCanMsg->frame.data5 = RXB0D5; tempCanMsg->frame.data6 = RXB0D6; tempCanMsg->frame.data7 = RXB0D7; RXB0CONbits.RXFUL = 0; returnValue = 1; } break; case dRXB1CON_FIFO_POINTER_VALUE: if (RXB1CONbits.RXFUL != 0) // Check RXB1 { if ((RXB0SIDL & 0x08) == 0x08) //If Extended Message { //message is extended tempCanMsg->frame.idType = (uint8_t) dEXTENDED_CAN_MSG_ID_2_0B; tempCanMsg->frame.id = convertReg2ExtendedCANid(RXB0EIDH, RXB0EIDL, RXB0SIDH, RXB0SIDL); } else { //message is standard tempCanMsg->frame.idType = (uint8_t) dSTANDARD_CAN_MSG_ID_2_0B; tempCanMsg->frame.id = convertReg2StandardCANid(RXB0SIDH, RXB0SIDL); } tempCanMsg->frame.dlc = RXB0DLC & 0x0F; tempCanMsg->frame.rtr = RXB0DLC >> 6; tempCanMsg->frame.data0 = RXB0D0; tempCanMsg->frame.data1 = RXB0D1; tempCanMsg->frame.data2 = RXB0D2; tempCanMsg->frame.data3 = RXB0D3; tempCanMsg->frame.data4 = RXB0D4; tempCanMsg->frame.data5 = RXB0D5; tempCanMsg->frame.data6 = RXB0D6; tempCanMsg->frame.data7 = RXB0D7; RXB1CONbits.RXFUL = 0; returnValue = 1; } break; case dB0CON_FIFO_POINTER_VALUE: if (B0CONbits.RXFUL != 0) //Check B0 { if ((RXB0SIDL & 0x08) == 0x08) //If Extended Message { //message is extended tempCanMsg->frame.idType = (uint8_t) dEXTENDED_CAN_MSG_ID_2_0B; tempCanMsg->frame.id = convertReg2ExtendedCANid(RXB0EIDH, RXB0EIDL, RXB0SIDH, RXB0SIDL); } else { //message is standard tempCanMsg->frame.idType = (uint8_t) dSTANDARD_CAN_MSG_ID_2_0B; tempCanMsg->frame.id = convertReg2StandardCANid(RXB0SIDH, RXB0SIDL); } tempCanMsg->frame.dlc = RXB0DLC & 0x0F; tempCanMsg->frame.rtr = RXB0DLC >> 6; tempCanMsg->frame.data0 = RXB0D0; tempCanMsg->frame.data1 = RXB0D1; tempCanMsg->frame.data2 = RXB0D2; tempCanMsg->frame.data3 = RXB0D3; tempCanMsg->frame.data4 = RXB0D4; tempCanMsg->frame.data5 = RXB0D5; tempCanMsg->frame.data6 = RXB0D6; tempCanMsg->frame.data7 = RXB0D7; B0CONbits.RXFUL = 0; returnValue = 1; } break; case dB1CON_FIFO_POINTER_VALUE: if (B1CONbits.RXFUL != 0) //CheckB1 { if ((RXB0SIDL & 0x08) == 0x08) //If Extended Message { //message is extended tempCanMsg->frame.idType = (uint8_t) dEXTENDED_CAN_MSG_ID_2_0B; tempCanMsg->frame.id = convertReg2ExtendedCANid(RXB0EIDH, RXB0EIDL, RXB0SIDH, RXB0SIDL); } else { //message is standard tempCanMsg->frame.idType = (uint8_t) dSTANDARD_CAN_MSG_ID_2_0B; tempCanMsg->frame.id = convertReg2StandardCANid(RXB0SIDH, RXB0SIDL); } tempCanMsg->frame.dlc = RXB0DLC & 0x0F; tempCanMsg->frame.rtr = RXB0DLC >> 6; tempCanMsg->frame.data0 = RXB0D0; tempCanMsg->frame.data1 = RXB0D1; tempCanMsg->frame.data2 = RXB0D2; tempCanMsg->frame.data3 = RXB0D3; tempCanMsg->frame.data4 = RXB0D4; tempCanMsg->frame.data5 = RXB0D5; tempCanMsg->frame.data6 = RXB0D6; tempCanMsg->frame.data7 = RXB0D7; B1CONbits.RXFUL = 0; returnValue = 1; } break; case dB2CON_FIFO_POINTER_VALUE: if (B2CONbits.RXFUL != 0) //CheckB2 { if ((RXB0SIDL & 0x08) == 0x08) //If Extended Message { //message is extended tempCanMsg->frame.idType = (uint8_t) dEXTENDED_CAN_MSG_ID_2_0B; tempCanMsg->frame.id = convertReg2ExtendedCANid(RXB0EIDH, RXB0EIDL, RXB0SIDH, RXB0SIDL); } else { //message is standard tempCanMsg->frame.idType = (uint8_t) dSTANDARD_CAN_MSG_ID_2_0B; tempCanMsg->frame.id = convertReg2StandardCANid(RXB0SIDH, RXB0SIDL); } tempCanMsg->frame.dlc = RXB0DLC & 0x0F; tempCanMsg->frame.rtr = RXB0DLC >> 6; tempCanMsg->frame.data0 = RXB0D0; tempCanMsg->frame.data1 = RXB0D1; tempCanMsg->frame.data2 = RXB0D2; tempCanMsg->frame.data3 = RXB0D3; tempCanMsg->frame.data4 = RXB0D4; tempCanMsg->frame.data5 = RXB0D5; tempCanMsg->frame.data6 = RXB0D6; tempCanMsg->frame.data7 = RXB0D7; B2CONbits.RXFUL = 0; returnValue = 1; } break; case dB3CON_FIFO_POINTER_VALUE: if (B3CONbits.RXFUL != 0) //CheckB3 { if ((RXB0SIDL & 0x08) == 0x08) //If Extended Message { //message is extended tempCanMsg->frame.idType = (uint8_t) dEXTENDED_CAN_MSG_ID_2_0B; tempCanMsg->frame.id = convertReg2ExtendedCANid(RXB0EIDH, RXB0EIDL, RXB0SIDH, RXB0SIDL); } else { //message is standard tempCanMsg->frame.idType = (uint8_t) dSTANDARD_CAN_MSG_ID_2_0B; tempCanMsg->frame.id = convertReg2StandardCANid(RXB0SIDH, RXB0SIDL); } tempCanMsg->frame.dlc = RXB0DLC & 0x0F; tempCanMsg->frame.rtr = RXB0DLC >> 6; tempCanMsg->frame.data0 = RXB0D0; tempCanMsg->frame.data1 = RXB0D1; tempCanMsg->frame.data2 = RXB0D2; tempCanMsg->frame.data3 = RXB0D3; tempCanMsg->frame.data4 = RXB0D4; tempCanMsg->frame.data5 = RXB0D5; tempCanMsg->frame.data6 = RXB0D6; tempCanMsg->frame.data7 = RXB0D7; B3CONbits.RXFUL = 0; returnValue = 1; } break; case dB4CON_FIFO_POINTER_VALUE: if (B4CONbits.RXFUL != 0) //CheckB4 { if ((RXB0SIDL & 0x08) == 0x08) //If Extended Message { //message is extended tempCanMsg->frame.idType = (uint8_t) dEXTENDED_CAN_MSG_ID_2_0B; tempCanMsg->frame.id = convertReg2ExtendedCANid(RXB0EIDH, RXB0EIDL, RXB0SIDH, RXB0SIDL); } else { //message is standard tempCanMsg->frame.idType = (uint8_t) dSTANDARD_CAN_MSG_ID_2_0B; tempCanMsg->frame.id = convertReg2StandardCANid(RXB0SIDH, RXB0SIDL); } tempCanMsg->frame.dlc = RXB0DLC & 0x0F; tempCanMsg->frame.rtr = RXB0DLC >> 6; tempCanMsg->frame.data0 = RXB0D0; tempCanMsg->frame.data1 = RXB0D1; tempCanMsg->frame.data2 = RXB0D2; tempCanMsg->frame.data3 = RXB0D3; tempCanMsg->frame.data4 = RXB0D4; tempCanMsg->frame.data5 = RXB0D5; tempCanMsg->frame.data6 = RXB0D6; tempCanMsg->frame.data7 = RXB0D7; B4CONbits.RXFUL = 0; returnValue = 1; } break; case dB5CON_FIFO_POINTER_VALUE: if (B5CONbits.RXFUL != 0) //CheckB5 { if ((RXB0SIDL & 0x08) == 0x08) //If Extended Message { //message is extended tempCanMsg->frame.idType = (uint8_t) dEXTENDED_CAN_MSG_ID_2_0B; tempCanMsg->frame.id = convertReg2ExtendedCANid(RXB0EIDH, RXB0EIDL, RXB0SIDH, RXB0SIDL); } else { //message is standard tempCanMsg->frame.idType = (uint8_t) dSTANDARD_CAN_MSG_ID_2_0B; tempCanMsg->frame.id = convertReg2StandardCANid(RXB0SIDH, RXB0SIDL); } tempCanMsg->frame.dlc = RXB0DLC & 0x0F; tempCanMsg->frame.rtr = RXB0DLC >> 6; tempCanMsg->frame.data0 = RXB0D0; tempCanMsg->frame.data1 = RXB0D1; tempCanMsg->frame.data2 = RXB0D2; tempCanMsg->frame.data3 = RXB0D3; tempCanMsg->frame.data4 = RXB0D4; tempCanMsg->frame.data5 = RXB0D5; tempCanMsg->frame.data6 = RXB0D6; tempCanMsg->frame.data7 = RXB0D7; B5CONbits.RXFUL = 0; returnValue = 1; } break; } ECANCON = tempECANCON; return (returnValue); } uint8_t CAN_messagesInBuffer(void) { uint8_t messageCount = 0; if (RXB0CONbits.RXFUL != 0) //CheckRXB0 { messageCount++; } if (RXB1CONbits.RXFUL != 0) //CheckRXB1 { messageCount++; } if (B0CONbits.RXFUL_TXBIF != 0) //CheckB0 { messageCount++; } if (B1CONbits.RXFUL_TXBIF != 0) //CheckB1 { messageCount++; } if (B2CONbits.RXFUL_TXBIF != 0) //CheckB2 { messageCount++; } if (B3CONbits.RXFUL_TXBIF != 0) //CheckB3 { messageCount++; } if (B4CONbits.RXFUL_TXBIF != 0) //CheckB4 { messageCount++; } if (B5CONbits.RXFUL_TXBIF != 0) //CheckB5 { messageCount++; } return (messageCount); } uint8_t CAN_isBusOff(void) { uint8_t returnValue = 0; //COMSTAT bit 5 TXBO: Transmitter Bus-Off bit //1 = Transmit error counter > 255 //0 = Transmit error counter less then or equal to 255 if (COMSTATbits.TXBO == 1) { returnValue = 1; } return (returnValue); } uint8_t CAN_isRXErrorPassive(void) { uint8_t returnValue = 0; //COMSTAT bit 3 RXBP: Receiver Bus Passive bit //1 = Receive error counter > 127 //0 = Receive error counter less then or equal to 127 if (COMSTATbits.RXBP == 1) { returnValue = 1; } return (returnValue); } uint8_t CAN_isTXErrorPassive(void) { uint8_t returnValue = 0; //COMSTAT bit 4 TXBP: Transmitter Bus Passive bit //1 = Transmit error counter > 127 //0 = Transmit error counter less then or equal to 127 if (COMSTATbits.TXBP == 1) { returnValue = 1; } return (returnValue); } /** Internal functions */ static uint32_t convertReg2ExtendedCANid(uint8_t tempRXBn_EIDH, uint8_t tempRXBn_EIDL, uint8_t tempRXBn_SIDH, uint8_t tempRXBn_SIDL) { uint32_t returnValue = 0; uint32_t ConvertedID = 0; uint8_t CAN_standardLo_ID_lo2bits; uint8_t CAN_standardLo_ID_hi3bits; CAN_standardLo_ID_lo2bits = (uint8_t)(tempRXBn_SIDL & 0x03); CAN_standardLo_ID_hi3bits = (uint8_t)(tempRXBn_SIDL >> 5); ConvertedID = (uint32_t)(tempRXBn_SIDH << 3); ConvertedID = ConvertedID + CAN_standardLo_ID_hi3bits; ConvertedID = (ConvertedID << 2); ConvertedID = ConvertedID + CAN_standardLo_ID_lo2bits; ConvertedID = (ConvertedID << 8); ConvertedID = ConvertedID + tempRXBn_EIDH; ConvertedID = (ConvertedID << 8); ConvertedID = ConvertedID + tempRXBn_EIDL; returnValue = ConvertedID; return (returnValue); } static uint32_t convertReg2StandardCANid(uint8_t tempRXBn_SIDH, uint8_t tempRXBn_SIDL) { uint32_t returnValue = 0; uint32_t ConvertedID; //if standard message (11 bits) //EIDH = 0 + EIDL = 0 + SIDH + upper three bits SIDL (3rd bit needs to be clear) //1111 1111 111 ConvertedID = (uint32_t)(tempRXBn_SIDH << 3); ConvertedID = ConvertedID + (uint32_t)(tempRXBn_SIDL >> 5); returnValue = ConvertedID; return (returnValue); } static void convertCANid2Reg(uint32_t tempPassedInID, uint8_t canIdType, uint8_t *passedInEIDH, uint8_t *passedInEIDL, uint8_t *passedInSIDH, uint8_t *passedInSIDL) { uint8_t wipSIDL = 0; if (canIdType == dEXTENDED_CAN_MSG_ID_2_0B) { //EIDL *passedInEIDL = 0xFF & tempPassedInID; //CAN_extendedLo_ID_TX1 = &HFF And CAN_UserEnter_ID_TX1 tempPassedInID = tempPassedInID >> 8; //CAN_UserEnter_ID_TX1 = CAN_UserEnter_ID_TX1 >> 8 //EIDH *passedInEIDH = 0xFF & tempPassedInID; //CAN_extendedHi_ID_TX1 = &HFF And CAN_UserEnter_ID_TX1 tempPassedInID = tempPassedInID >> 8; //CAN_UserEnter_ID_TX1 = CAN_UserEnter_ID_TX1 >> 8 //SIDL //push back 5 and or it wipSIDL = 0x03 & tempPassedInID; tempPassedInID = tempPassedInID << 3; //CAN_UserEnter_ID_TX1 = CAN_UserEnter_ID_TX1 << 3 wipSIDL = (0xE0 & tempPassedInID) + wipSIDL; wipSIDL = (uint8_t)(wipSIDL + 0x08); // TEMP_CAN_standardLo_ID_TX1 = TEMP_CAN_standardLo_ID_TX1 + &H8 *passedInSIDL = (uint8_t)(0xEB & wipSIDL); //CAN_standardLo_ID_TX1 = &HEB And TEMP_CAN_standardLo_ID_TX1 //SIDH tempPassedInID = tempPassedInID >> 8; *passedInSIDH = 0xFF & tempPassedInID; } else //(canIdType == dSTANDARD_CAN_MSG_ID_2_0B) { *passedInEIDH = 0; *passedInEIDL = 0; tempPassedInID = tempPassedInID << 5; *passedInSIDL = 0xFF & tempPassedInID; tempPassedInID = tempPassedInID >> 8; *passedInSIDH = 0xFF & tempPassedInID; } } void ECAN_SetRXBnInterruptHandler(void (*handler)(void)) { RXBnInterruptHandler = handler; } void ECAN_RXBnI_ISR(void) { RXBnInterruptHandler(); PIR5bits.RXBnIF = 0; // The ECAN hardware overrides the setting of this bit (to '1') when any receive buffer is not empty. } void ECAN_SetRXBnOverflowHandler(void (*handler)(void)) { RXBnOverflowHandler = handler; } void ECAN_SetBusOffHandler(void (*handler)(void)) { BusOffHandler = handler; } void ECAN_SetTXPassiveHandler(void (*handler)(void)) { TXPassiveHandler = handler; } void ECAN_SetRXPassiveHandler(void (*handler)(void)) { RXPassiveHandler = handler; } void ECAN_SetTXWarningHandler(void (*handler)(void)) { TXWarningHandler = handler; } void ECAN_SetRXWarningHandler(void (*handler)(void)) { RXWarningHandler = handler; } void ECAN_ERRI_ISR(void) { if (COMSTATbits.RXB1OVFL) { RXBnOverflowHandler(); COMSTATbits.RXB1OVFL = 0; // In mode 2, this clears RXBnOVFL } if (COMSTATbits.TXBO) { BusOffHandler(); } if (COMSTATbits.TXBP) { TXPassiveHandler(); } if (COMSTATbits.RXBP) { RXPassiveHandler(); } if (COMSTATbits.TXWARN) { TXWarningHandler(); } if (COMSTATbits.RXWARN) { RXWarningHandler(); } PIR5bits.ERRIF = 0; }