Hi Sirs,
I am using Flexcan Tx with MPC5744P platform and encounter interrupt problem.
When I use MB[9] transmmit data with no other slave situation and that means Flexcan Tx always gets ACK=1 .
After Can_ECR[TxERRCNT] counts to 96 the interrupt occurs successfully and entered ESR1 ISR handler Can_ESR1[TWRNINT]=1.
During ESR1 ISR handler, I have abort FlexCan CAN_MCR[AEN]=1 and MB[9] as the following setting.
CAN_0.MCR.B.AEN = 1;
CAN_0.MB[9].CS.B.CODE = 9;
CAN_0.ECR.R &= ~(0xFF) ; //clear TXERRCNT
Then set CAN_MCR[AEN]=0 and MB[9] Code filed =0xC to leave abort mode and restart tranmit as the following setting.
The flexCan could transmit, but it can't enter Can_ESR1[TWRNINT] anymore.
CAN_0.MCR.B.AEN = 0;
while(0 == CAN_0.MCR.B.FRZACK) ;
CAN_0.MB[9].CS.B.CODE = 0xC; // MB9 trigger
I just want to abort Flexcan in ESR1 ISR handler and clear TXERRCNT
then restart FlexCan transmit the Can_ESR1[TWRNINT] will not occur interrupt anymore.
Could somebody help me?
Please help me with the suggestion.
Thank you very much.
Please neglect previous e-mail about flexcan Remote request issue.
I found the MPC5744p mother and daughter board regulator is not stable when powered on by the power supply.
So that I need to plug out and plug in cable handly then the regulator stable.
Under this situation, the FlexCan signal was normally and could transmit remote request.
Thanks for your recent support.
Hi Jeff,
Please read chapter 45.3.29 “RX FIFO structure” carefully. Here I am placing just a picture from the RM.
The RXFIFO is 6-message deep. To read the RX FIFO you always use the 0x80-0x8C region, similarly as the MB0 is read.
Before using the FIFO you have to set full ID table as per the length set in CTRL2[RFFN]. Out of reset, the ID filter table flexible memory area defaults to 0xE0 and extends only to 0xFC, which corresponds to MBs 6 to 7 for RFFN = 0. So just 8 ID filters must be written.
Flags are set in following way when FIFO is enabled. The 8 least significant interrupt flags (BUF7I–BUF0I) is changed to support the FIFO operation. BUF7I, BUF6I and BUF5I indicate operating conditions of the FIFO, while BUF4I to BUF0I are not used. In details
- BUF5I - Frames available in FIFO. Once set you should read the MB0
- BUF6I - FIFO Warning. 5 frames have accumulated in the FIFO.
- BUF7I - FIFO Overflow. The FIFO is full and subsequent frames are not accepted until the CPU creates space in the FIFO by reading one or more frames (using MB0 still !!!). While the FIFO is full, the frames are only received if they are matched with another MBs.
BR, Petr
Well I forgot to highlight one thing, but it is actually stated within the RM.
Each time you read the RXFIFO you need to clear the BUF5I flag so the FIFO output is updated with the next message. So your code could be following to read all 5 messages from FIFO upon BUF6I is set.
/* upon receiving the interrupt flag */
if(CAN_1.IFLAG1.B.BUF6I) // test BUF6I flag if set
{
for(i=0;i<5;i++)
{
gMB_buffer[i][0] = CAN_1.MB[0].CS.R;
gMB_buffer[i][1] = CAN_1.MB[0].ID.R;
gMB_buffer[i][2] = CAN_1.MB[0].DATA.W[0];
gMB_buffer[i][3] = CAN_1.MB[0].DATA.W[1];
CAN_1.IFLAG1.R = 0x00000020; // clear BUF05I to update the RXFIFO output
}
/* clear the BUF06I bit - bit 6 */
CAN_1.IFLAG1.R = 0x00000040;
}
BR, Petr
Hi Petr,
Please neglect previous e-mail.
I have understood how to use individual mask register.
When ID match the Rx SMB receives data, moves into MB and occurs MB interrupt flag.
When ID mismatch Rx SMB doesn't receive data and move into MB and doesn't MB interrupt flag.
But I can't understand when Rx side occurs ID mismatch the acknowledge always 0 during ack slot.
That means the data receives successfully by Rx side I think its not make sense.
what does something missing when ack slot always 0?
Best regards,
Jeff
Hi Jeff,
The receive/matching process is little bit different. I can suggest you to read chapters “Receive process”, “Matching process” and “Move-in” within the RM to get detailed info.
Very briefly, the message is always received into SMB, if no error is detected during reception the module acknowledge the message. Depending the message type, the Matching process is started at certain time during message reception. If there is matching winner detected the message is transferred from SMB into RXFIFO or RXMB during Intermission field. If there is no matching, the message stays in SMB and will be overwritten by next received message.
BR, Petr
Hi Jeff,
Error counters do not “count” based on any clock. The rules for increasing and decreasing these counters are described in the CAN protocol. Basically, when an error is detected the counter increments by 8, decrement by 1 when message is transmitted/received without error. See more in http://cache.freescale.com/files/microcontrollers/doc/data_sheet/BCANPSV2.pdf.
In your first picture, you tried to sent message, but as node is disconnected from the bus you got and ACK error and the message is resending again. Assuming there is no other error the TX error counter is incremented by 8 after each ACK error. So after message is repeated 16 times the error counter equals 128 and is no longer incremented (as per standard)
For your second case, have no idea what it is done. You are receiving a message from other node? The MB9 is used for receiving? If yes, why do you use ABORT code for it. Or do you also transmit something?
If you only receive message and get RX errors, then probably the CAN bit timing is incorrect.
BR, Petr
Hi,
If the WRNEN bit in MCR is asserted, the TWRNINT bit is set when the TXWRN flag transitions from 0 to 1, meaning that the Tx error counter reached 96. So to get a TWRNINT set again you need to decrement TX error counter below 96 and let it increase again when errors appears. This error counter decrements automatically as per standard if message is transmitted correctly or can be written by SW if module is in Freeze mode.
You have tried to clear it within ISR, but it makes no effect if you are not in Freeze mode, thus leaving interrupt the TWRNINT is not set anymore.
Also MCR[AEN] bit can be set in Freeze mode only.
You can have this ISR routine, I think.
BR, Petr
That’s what I suggested. The TXERRCNT can be only written in Freeze mode. So I wrote you need to put the module into Freeze mode and wait until it is really in Freeze mode.
The FRZ bit allows module to enter Freeze mode when either HALT bit is set or debug mode is entered.
Module then leaves the Freeze mode when HALT bit is cleared or debug mode is left.
So the FRZ can be set still and HALT then set or clear upon needs.
BR, Petr