Triode
Well-Known Member
I'm using a PIC18F46K80. I have some inherited code that I need to add two CAN frames to by the end of the week. I do intend to gain a solid understanding of the ECAN module, but I'm reading the datasheet and given the time limit I think it's too complex to figure out that quickly.
Currently it reads 2 frames, and since there are 2 buffers it has one receive filter on each buffer. On the datasheet under settings for the "RECEIVE FILTER BUFFER CONTROL REGISTER" it lists more buffers. But due to naming I am wary that they may not be what I hope they are, are B0 and B1 aditional full buffers, or something else?
These settings seem to imply there are more buffers - but some of the diagrams only list RXB0 and RXB1. I could be totally on the wrong track here, maybe I don't need more buffers to read more CAN messages.
Here is the code that sets up the buffers, the first block below is just for completeness, the second has the filter settings that I think need to be fixed.
Now here is where I'm thinking I need to add something (besides the spot noted above)
Elsewhere in the .h file for this c file that CAN_RecieveFrames array is set up with something like this for each CAN frame
STATUS_FRAME, 0, 0x102, 0x08, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
These are parts of an enum defined as this
name, refreshRate, arbitrationID, DLC (data length code), DATA[8] (the data payload)
I have added entries for my two new frames to that array with their arbitration IDs
So as you can see below, the code makes use of CAN_ReceiveFrames[0].arbitrationID, and the same for element [1], of course I need to add 2 and 3
Do I put them so they go into the B0 and B1 register? Do I need to change this filter? Like I said, I do plan to take the time to fully understand this, but I'm running out of time for now and it's pretty complicated.
Thank you for any ideas on how to make this work.
Currently it reads 2 frames, and since there are 2 buffers it has one receive filter on each buffer. On the datasheet under settings for the "RECEIVE FILTER BUFFER CONTROL REGISTER" it lists more buffers. But due to naming I am wary that they may not be what I hope they are, are B0 and B1 aditional full buffers, or something else?
Code:
0000 = Filter n is associated with
RXB0 0001 = Filter n is associated with
RXB1 0010 = Filter n is associated with
B0 0011 = Filter n is associated with B1
...
These settings seem to imply there are more buffers - but some of the diagrams only list RXB0 and RXB1. I could be totally on the wrong track here, maybe I don't need more buffers to read more CAN messages.
Here is the code that sets up the buffers, the first block below is just for completeness, the second has the filter settings that I think need to be fixed.
Code:
void CAN_Init()
{
// Enter CAN module into config mode
CANCON = 0x80;
while(!(CANCON & 0x80));
// Enter CAN module into Mode 1
ECANCON = 0x40;
// 500 Kbps @ 8MHz
BRGCON1 = 0x00; //0000 0000
BRGCON2 = 0x91; //1001 0001
BRGCON3 = 0x01; //0000 0001
// Setup Programmable buffers (all receive buffers, unused)
BSEL0 = 0x00;
// Initialize Receive Masks
// The first mask is used that accepts all SIDs and no EIDs
// The second mask is used to ignore all SIDs and EIDs
RXM0EIDH = 0x00; // 0's for EID and 1's for SID
RXM0EIDL = 0x00;
RXM0SIDH = 0xFF;
RXM0SIDL = 0xFF;
RXM1EIDH = 0x00; // 0's for EID and SID
RXM1EIDL = 0x00;
RXM1SIDH = 0x00;
RXM1SIDL = 0x00;
// Enable Filters
// Only using first two filters, so the rest can be disabled
RXFCON0 = 0x03; //Enable Filters 0,1,2 (do I need to change this?)
RXFCON1 = 0x00; //Disable all others
// Assign Filters to Masks
// Only one mask is used for three filters //CAN MASK SELECT REGISTER
MSEL0 = 0xC0; //Assign Filters 0-2 to Mask 0 and 3 to Mask 1
MSEL1 = 0xFF; //Assign Filters 4-7 to Mask 1
MSEL2 = 0xFF; //Assign Filters 8-11 to Mask 1
MSEL3 = 0xFF; //Assign Filters 12-15 to Mask 1
// Assign Filters to Buffers
// Have the first buffer only accept the first filter, the second buffer accept
// the second filter.
RXFBCON0 = 0x10; //Assign Filter 0 to RXB0, and Filter 1 to RXB1
RXFBCON1 = 0xFF; //Assign the rest of the buffers with no filter
RXFBCON2 = 0xFF;
RXFBCON3 = 0xFF;
RXFBCON4 = 0xFF;
RXFBCON5 = 0xFF;
RXFBCON6 = 0xFF;
RXFBCON7 = 0xFF;
Now here is where I'm thinking I need to add something (besides the spot noted above)
Elsewhere in the .h file for this c file that CAN_RecieveFrames array is set up with something like this for each CAN frame
STATUS_FRAME, 0, 0x102, 0x08, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
These are parts of an enum defined as this
name, refreshRate, arbitrationID, DLC (data length code), DATA[8] (the data payload)
I have added entries for my two new frames to that array with their arbitration IDs
So as you can see below, the code makes use of CAN_ReceiveFrames[0].arbitrationID, and the same for element [1], of course I need to add 2 and 3
Do I put them so they go into the B0 and B1 register? Do I need to change this filter? Like I said, I do plan to take the time to fully understand this, but I'm running out of time for now and it's pretty complicated.
Code:
// Initialize Receive Filters
RXF0EIDH = 0x00;
RXF0EIDL = 0x00;
RXF0SIDH = (unsigned char)((CAN_ReceiveFrames[0].arbitrationID >> 3) & 0x00FFU);//SIDH takes the 8 MSB's of the 11-bit arbitration ID
RXF0SIDL = (unsigned char)((CAN_ReceiveFrames[0].arbitrationID << 5) & 0x00FFU);//SIDL takes the 3 LSB's, padded ON THE RIGHT with 0's
RXF1EIDH = 0x00;
RXF1EIDL = 0x00;
RXF1SIDH = (unsigned char)((CAN_ReceiveFrames[1].arbitrationID >> 3) & 0x00FFU);//SIDH takes the 8 MSB's of the 11-bit arbitration ID
RXF1SIDL = (unsigned char)((CAN_ReceiveFrames[1].arbitrationID << 5) & 0x00FFU);//SIDL takes the 3 LSB's, padded ON THE RIGHT with 0's
// Enter CAN module into normal mode
CANCON = 0x00;
while(CANCON & 0xE0);
// Set Receive Mode for buffers
RXB0CON = 0x00;
RXB1CON = 0x00;
}
Thank you for any ideas on how to make this work.
Last edited: