How to receive a CAN message with MM9Z1J638

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

How to receive a CAN message with MM9Z1J638

Jump to solution
761 Views
kadiruzun
Contributor III

Hello all,

 

I am dealing with DEMO code of MM9Z1J638 intelligent battery sensor for a while. I am pretty new with embedded coding, C and all of these topics. As I learn more, I have much more questions.

 

I get how to transmit a CAN message. I made some changes in DEMO code so that I can send whatever the message I want to be sended. Now,, I am trying to understand how receive routine works. In can.c file I found the following piece of C code:

 

interrupt VectorNumber_Vcan0rx void isrCANRx(void)  {

  TYPE_RETURN_CODE can_errorflag;

  u8 length, index, hitid;

 

  hitid = CAN0IDAC & 0x7;

  length = (CAN0RXDLR & 0x0F);

 

  can_errorflag = NO_ERR;

  switch(hitid) {

 

  case 0: // Acceptance code 0 hit

  for (index=0; index<length; index++) {

  rx0_buf[index] = *(&CAN0RXDSR0 + index); /* Get received data */

  }

  rx0_flag = 1;

  break;

  case 1:

  for (index=0; index<length; index++) {

  rx1_buf[index] = *(&CAN0RXDSR0 + index); /* Get received data */

  }

  rx1_flag = 1;

  break;

  case 2:

  for (index=0; index<length; index++) {

  rx2_buf[index] = *(&CAN0RXDSR0 + index); /* Get received data */

  }

  rx2_flag = 1;

  break;

  case 3:

  for (index=0; index<length; index++) {

  rx3_buf[index] = *(&CAN0RXDSR0 + index); /* Get received data */

  }

  rx3_flag = 1;

  break;

  default:

  can_errorflag = ERR_NO_ACC_HIT;

  break;

  }

  CAN0RFLG = 0x01;   /* Clear RXF */

}

 

I did not really understand how this code works, how it gets the message from transmitter. Where is the message kept? There is a switch-case statement for different can message IDs, but What happens if the id is not 0,1,2, or 3 but something like 143? These are some of the questions I can not answer.

 

I will be glad if you have any idea or recommendations.

Labels (1)
Tags (1)
1 Solution
538 Views
RadekS
NXP Employee
NXP Employee

Hi Kadir,

It is simple code.

However, you have to know a little bit more about acceptance filter.

On the typical CAN bus is more than two nodes and there are necessary several types of CAN messages per every node. Therefore msCAN module contains flexible acceptance filter. You can simply configure which types of CAN messages (CAN IDs) will be accepted, the rest of CAN traffic will be ignored.

The standard CAN frame use 11bit IDs, the extended CAN frame use 29bit IDs.

The acceptance filter on msCAN module might be configured to use two 32-bit acceptance filters / four 16-bit acceptance filters / eight 8-bit acceptance filters / Filter closed.

So, if you know that you will accept only CAN frames in the standard format, you may define four independent filters and accept only CAN messages defined by these filters.

Every filter is defined by Acceptance registers and by Mask registers. So, you will write how to acceptable frame IDs should look and additionally you may define on which bits matters. Finally, you may define for example group of sixteen IDs which will be accepted by one filter. However, I suppose that the demo code do not use that feature and every 16-bit acceptance filter refers to just one specific ID.

After filtering, you have just one RX interrupt. For detection of message ID you may read IDR0~IDR3 registers (IDR0~IDR1 in the case of standard IDs) and compare it with expected value or you may use Acceptance filter flags for short identifying of received CAN frame (as in Demo code).

Advantage of the second approach:

The testing 3bits in CAN0IDAC register is much faster than comparing 16 (32) bit IDs.

Disadvantage of the second approach:

The second option works fine mainly in a case when every filter is configured to specific CAN message ID.

So, demo code just read flags from acceptance filters and copy CAN message data to appropriate array according to CAN frame ID.

Of course, we have to clear RX flag at the end of this ISR routine.

I hope it helps you.

Have a great day,
Radek

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

2 Replies
539 Views
RadekS
NXP Employee
NXP Employee

Hi Kadir,

It is simple code.

However, you have to know a little bit more about acceptance filter.

On the typical CAN bus is more than two nodes and there are necessary several types of CAN messages per every node. Therefore msCAN module contains flexible acceptance filter. You can simply configure which types of CAN messages (CAN IDs) will be accepted, the rest of CAN traffic will be ignored.

The standard CAN frame use 11bit IDs, the extended CAN frame use 29bit IDs.

The acceptance filter on msCAN module might be configured to use two 32-bit acceptance filters / four 16-bit acceptance filters / eight 8-bit acceptance filters / Filter closed.

So, if you know that you will accept only CAN frames in the standard format, you may define four independent filters and accept only CAN messages defined by these filters.

Every filter is defined by Acceptance registers and by Mask registers. So, you will write how to acceptable frame IDs should look and additionally you may define on which bits matters. Finally, you may define for example group of sixteen IDs which will be accepted by one filter. However, I suppose that the demo code do not use that feature and every 16-bit acceptance filter refers to just one specific ID.

After filtering, you have just one RX interrupt. For detection of message ID you may read IDR0~IDR3 registers (IDR0~IDR1 in the case of standard IDs) and compare it with expected value or you may use Acceptance filter flags for short identifying of received CAN frame (as in Demo code).

Advantage of the second approach:

The testing 3bits in CAN0IDAC register is much faster than comparing 16 (32) bit IDs.

Disadvantage of the second approach:

The second option works fine mainly in a case when every filter is configured to specific CAN message ID.

So, demo code just read flags from acceptance filters and copy CAN message data to appropriate array according to CAN frame ID.

Of course, we have to clear RX flag at the end of this ISR routine.

I hope it helps you.

Have a great day,
Radek

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

538 Views
kadiruzun
Contributor III

Hi Radek,

Thank you very much for your response.

By changing ACC_CODE_ID0 (1, 2 or 3),  I am able to receive a can message with the ID I set. Your detailed explanation is very helpful for me to understand this protocol.

Best,

Kadir

0 Kudos