MPC5744P FlexCan Tx interrupt problem

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MPC5744P FlexCan Tx interrupt problem

3,207 Views
jefferson_ll
Contributor III

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.

Labels (1)
Tags (2)
14 Replies

1,757 Views
jefferson_ll
Contributor III


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.

0 Kudos

1,757 Views
jefferson_ll
Contributor III
Hi Petr,
Thank you for your kind assistance.
According to your steps, the Rx FIFO could read 5 data message from FIFO successfully when IFLAG1.B.BUF6I asserted .
I'm using remote request now and can receive a remote request from another device and transmit data successfully.
When sending remote request by flexcan to another device the ESR1 always shows FLTCONF at bus off state.
The setting as normal Tx and the MB request setting as following:
CAN_0.MB[8].CS.B.RTR = 1;
CAN_0.MB[8].CS.B.SRR = 1;
CAN_0.MB[8].CS.B.DLC = 0;
CAN_0.MB[8].CS.B.IDE = 1;
CAN_0.MB[8].ID.R = 0X12770000;
CAN_0.MB[8].CS.B.CODE = 0x0C;
Could you please provide remote request setting for me?
0 Kudos

1,757 Views
jefferson_ll
Contributor III
Hi Petr,
Thanks for your response.
I'm using RX FIFO and ID table filtered correct ID and store into FIFO ( MB0 ).
According to the FlexCan datasheet, the MB0 ~ MB5 act as FIFO when FIFO enabled.
When IFLAG1[BUF6I] asserted means the FIFO almost overflow but read MB[0]~MB[5] always get the same data.
I'm so curious about how to read FIFO data sequentially when IFLAG1[BUF6I] asserted.
0 Kudos

1,757 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi Jeff,

Please read chapter 45.3.29 “RX FIFO structure” carefully. Here I am placing just a picture from the RM.

 pastedImage_1.png

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

0 Kudos

1,757 Views
jefferson_ll
Contributor III
Hi Petr,
According to your suggestion, I have read MB0 sequentially under BUF6I asserted.
Unfortunately, I can't read FIFO data sequentially and always get the same data.
The following code is BUF6I Rx FIFO read procedure:
if ( CAN_1.IFLAG1.B.BUF6I !=0 ){
gMB_buffer[0][0] = RX_FIFO( CAN1_BASE_ADDRESS , MB_START_OFFSET, 0); //MB[0].CS
gMB_buffer[0][1] = RX_FIFO( CAN1_BASE_ADDRESS , MB_START_OFFSET, 1); //MB[0].ID
gMB_buffer[0][2] = RX_FIFO( CAN1_BASE_ADDRESS , MB_START_OFFSET, 2); //MB[0].DATA[0]
gMB_buffer[0][3] = RX_FIFO( CAN1_BASE_ADDRESS , MB_START_OFFSET, 3); //MB[0].DATA[1]
g_timer_unlock = CAN_1.MB[0].CS.B.TIMESTAMP ;
gMB_buffer[1][0] = RX_FIFO( CAN1_BASE_ADDRESS , MB_START_OFFSET, 0); //MB[0].CS
gMB_buffer[1][1] = RX_FIFO( CAN1_BASE_ADDRESS , MB_START_OFFSET, 1); //MB[0].ID
gMB_buffer[1][2] = RX_FIFO( CAN1_BASE_ADDRESS , MB_START_OFFSET, 2); //MB[0].DATA[0]
gMB_buffer[1][3] = RX_FIFO( CAN1_BASE_ADDRESS , MB_START_OFFSET, 3); //MB[0].DATA[1]
g_timer_unlock = CAN_1.MB[0].CS.B.TIMESTAMP ;
........................
CAN_1.IFLAG1.R = BIT6_LIT ;
}
I  want to read FIFO sequentially under BUF6I asserted.
Could you provide a sample code for me?
Sorry about the inconvenience. 
0 Kudos

1,757 Views
PetrS
NXP TechSupport
NXP TechSupport

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

1,757 Views
jefferson_ll
Contributor III

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?

ID mismatch ACK 0.bmp

Best regards,

Jeff

0 Kudos

1,757 Views
PetrS
NXP TechSupport
NXP TechSupport

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

0 Kudos

1,757 Views
jefferson_ll
Contributor III
Hi Petr,
Thanks a lot for your help.
For question 2, I just want to make some mechanism when Can1 MB9 RXERRCNT bigger than 96.
So I have used the same procedure as TXERRCNT abort flow.
But that is not my main question.
There is a question about Can_RXIMR register.
Q3: Please give me an idea about Can_RXIMR in the match process.
setting as following pseudo code :
//---- During freeze mode  ----
CAN_1.MCR[RFEN] = 0; //RX FIFO not enable
CAN_1.MCR[IRMQ] = 1; //Individual Rx masking and queue feature are enabled.
CAN_1.MB[0~63].CS.R = 0;
CAN_1.RXIMR[0~63].R = 0x1FFFFFFF;
//--- Leave freeze mode ---
CAN_1.MB[9].ID.R = 0x12340000; /* Ext.ID = 0x12340000 */
CAN_1.MB[9].CS.R = 0x04200000; /* Rx active and empty + IDE */
When Tx send ID (0x12880000) the CAN1 generates ACK (0) on the can bus and Can1 MB[9] gets data.
The Tx_ID (0x12880000) does not match CAN1_ID (0x12340000), according to the matching mechanism MB[9] shouldn't get this data and needs send NACK on the bus.
Does this something wrong? 
May I use Can_RXIMR to accomplish ID filter procedure?
0 Kudos

1,757 Views
jefferson_ll
Contributor III
Hi petr,
Thanks for your explain, I have understood how to operate HALT and FRZ bit under FlexCan Tx case.
Sorry, I have another two question:
Q1: How to find TXERRCNT clock? 
I have measured TXERRCNT reached 96 about 2.07ms, the FlexCan using 500kHz and Can clock src is 40MHz.
I have estimated the TXERRCNT clock src about 47kHz (96/2.07ms=47kHz). the following figure shows
Does this be reasonable?
How can I find this clock source?

 
Q2:May I use above cleaning TXERRCNT flow in the RXERRCNT?
   I use the same flow when RXERRCNT reaches 96 after leaving ESR1 handler the RXERRCNT reaches 96 very quickly about 353us periodically.
   I don't know what happened. 
   The following shows figure and setting

   {
CAN_1.MB[9].CS.B.CODE = 9; //0: only one time interrupt ; 9:interrupt timing very stranger! // write abort
while(  CAN_1.MB[9].CS.B.CODE != 9 );
CAN_1.MB[9].CS.B.CODE = 9;
/* Disable MB9 Int. mask */
CAN_1.IMASK1.R &= (~BIT9_LIT);
while( (CAN_1.IFLAG1.R & BIT9_LIT) ==0);
CAN_1.IFLAG1.R = BIT9_LIT;
CAN_1.IMASK1.R |= (BIT9_LIT) ;
CAN_1.MCR.B.FRZ = 1;
CAN_1.MCR.B.HALT = 1;
while( 0 == CAN_1.MCR.B.FRZACK );
CAN_1.ECR.R &= ~(0xFF00) ;     //Clear RXERRCNT
CAN_1.MCR.B.HALT = 0;
CAN_1.MCR.B.FRZ = 0;
while( 1 == CAN_1.MCR.B.FRZACK );
CAN_1.MB[9].CS.B.CODE = 0x4; // Rx active and empty, write trigger
}
Thank you for your close cooperation with me in this matter.
Br,
Jeff 
0 Kudos

1,757 Views
PetrS
NXP TechSupport
NXP TechSupport

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

1,757 Views
PetrS
NXP TechSupport
NXP TechSupport

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.

 

  1. abort message writing code field 0x9
  2. wait till MB8 flag is set, indicating message is aborted
  3. clear MB8 flag
  4. put CAN to freeze mode and wait for its acknowledge
  5. clear TX error couter
  6. clear TWRNINIT flag
  7. leave a freeze mode and wait for its acknowledge

BR, Petr

1,757 Views
jefferson_ll
Contributor III
Hi Petr,
Thanks for your reply.
According to your suggestion, the TXERRCNT can't be cleared or modified.
But I use MCR[HALT] the TXERRCNT can be cleared.
These setting as  following:
void Flexcan0_ESR1_IRQ(void)
{
if(  (CAN_0.ESR1.R & BIT14_BIG) != 0)
{
CAN_0.ESR1.R = BIT14_BIG; //clear interrupt flag
CAN_0.MB[9].CS.B.CODE = 9; // write abort
/* Disable MB9 Int. mask */
CAN_0.IMASK1.R &= (~BIT9_LIT) ; //Jeff add
while( (CAN_0.IFLAG1.R & BIT9_LIT) ==0);
CAN_0.IFLAG1.R = BIT9_LIT;
CAN_0.IMASK1.R |= (BIT9_LIT) ;
CAN_0.MCR.B.FRZ = 1;
CAN_0.MCR.B.HALT = 1; //-----Halt could clear TXERRCNT-----
while( 0 == CAN_0.MCR.B.FRZACK );
CAN_0.ECR.R &= ~(0xFF) ;     //Clear TXERRCNT
CAN_0.MCR.B.HALT = 0; //-----Halt could clear TXERRCNT-----
CAN_0.MCR.B.FRZ = 0;
while( 1 == CAN_0.MCR.B.FRZACK );
CAN_0.MB[9].CS.B.CODE = 0xC; // write trigger
}
}
I am so curious in MCR[HALT] and MCR[FRZ], does these two registers can be set in the situation?
Does there setting exist some implicit problems?

Best regards,
Jeff
0 Kudos

1,757 Views
PetrS
NXP TechSupport
NXP TechSupport

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

0 Kudos