This repository has been archived on 2024-01-25. You can view files and clone it, but cannot push or open issues or pull requests.
SummerSchool2-Controller/306-controller_interface.X/mcc_generated_files/ecan.c

768 lines
26 KiB
C
Raw Normal View History

2023-08-22 07:22:00 +00:00
/**
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 :
2023-08-24 15:28:07 +00:00
Product Revision : PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.81.8
Device : PIC18F25K83
2023-08-22 07:22:00 +00:00
Driver Version : 3.0.0
The generated drivers are tested against the following:
2023-08-24 15:28:07 +00:00
Compiler : XC8 2.36 and above
MPLAB : MPLAB X 6.00
2023-08-22 07:22:00 +00: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 <xc.h>
#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
........................................................
........................................................
*/
2023-08-25 07:06:54 +00:00
/*
* 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
*/
2023-08-22 07:22:00 +00:00
convertCANid2Reg(0x070, dSTANDARD_CAN_MSG_ID_2_0B, &RXM0EIDH, &RXM0EIDL, &RXM0SIDH, &RXM0SIDL);
2023-08-25 07:06:54 +00:00
convertCANid2Reg(0x070, dSTANDARD_CAN_MSG_ID_2_0B, &RXM1EIDH, &RXM1EIDL, &RXM1SIDH, &RXM1SIDL);
// filter 0 is broadcast message
2023-08-22 07:22:00 +00:00
convertCANid2Reg(0x000, dSTANDARD_CAN_MSG_ID_2_0B, &RXF0EIDH, &RXF0EIDL, &RXF0SIDH, &RXF0SIDL);
2023-08-25 07:06:54 +00:00
// filter 1 is message for controller
2023-08-22 07:22:00 +00:00
convertCANid2Reg(0x010, dSTANDARD_CAN_MSG_ID_2_0B, &RXF1EIDH, &RXF1EIDL, &RXF1SIDH, &RXF1SIDL);
2023-08-25 07:06:54 +00:00
// filter 2 is message for recipient n<>7, not yet defined
2023-08-22 07:22:00 +00:00
convertCANid2Reg(0x070, dSTANDARD_CAN_MSG_ID_2_0B, &RXF2EIDH, &RXF2EIDL, &RXF2SIDH, &RXF2SIDL);
2023-08-25 07:06:54 +00:00
/*
* ENABLE FILTERS
*
* Filter 0 set on mask 0
* Filter 1 set on mask 0
* Filter 2 set on mask 1
*/
RXFCON0 = 0x07;
2023-08-22 07:22:00 +00:00
/**
Assign Filters to Masks
*/
2023-08-25 07:06:54 +00:00
// Filter 0 & 1 assigned to mask 0 and filter 2 assigned to mask 1
MSEL0 = 0x10;
2023-08-22 07:22:00 +00:00
/**
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;
}