rx_callback function in the example AN4975

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

rx_callback function in the example AN4975

736 Views
frankkong
Contributor III

Hello, 

 I am using the example of MSCAN(AN4975). What's the function of callback funcation? How it works?

void (*rx_callback)(unsigned int, unsigned char[8], unsigned char);

if(rx_callback!=NULL){
rx_callback(id, data, length);
}

CAN_set_rx_callback(&processCANMessage);

0 Kudos
3 Replies

587 Views
dianabatrlova
NXP TechSupport
NXP TechSupport

Hello, 

I would like to direct you to the AN4975 https://www.nxp.com/docs/en/application-note/AN4975.pdf 

There is a chapter "6 Receiving a CAN message" point 4:

4) Execute a user callback function to process the data. This user function may take action on the received ID and Data

Before the CAN RX interrupt service routine can execute the callback function, the user must provide a pointer to this function. To do this the “CAN_set_rx_callback” is called. The only parameter of this function is a pointer to the user callback. 

I hope it helps.

Best Regards,

Diana

0 Kudos

587 Views
frankkong
Contributor III

Thanks,

      I had read AN4975。I find that the RX_CALLBACK function is empty. As shown below,

void processCANMessage(unsigned int id, unsigned char data[8], unsigned char length){  }

Does it mean that there is nothing to do in the callback function?

0 Kudos

587 Views
lama
NXP TechSupport
NXP TechSupport

Hello,

Diana has left for vacation so I'll answer.

the callback function in this case is used only to process received data. If you do not want to use it the you can ignore it and do not define pointer to this function. However, if you want to process received and already adjusted ID and correctly read data then you just initialize pointer to this function and inside it you can process data because they are send to this function as a parameter. You can see the ID, data and length are already prepared in the interrupt and they are stored in a local variables which are destroyed when you leave interrupt.

Of course, there is basic info stored only for callback function call. You can also sent RTR, IDE there if you also to use them ...but this is another story. You can see different message ID (standard/extended) processing in the attached example for different ID size. (you can ignore next text.....)

//CAN_Tx

  if( msg->IDE == 0 )
    {
      can->TXIDR0 = ( UBYTE ) ( msg->id >> 3 );         // insert ID MSB
      can->TXIDR1 = ( UBYTE ) ( msg->id << 5 ); // insert last 3 bits of ID to the msb
      can->TXIDR1 &= 0B11110111;                 // clear IDE
      if( msg->RTR ) can->TXIDR1 |= 0x10;          // set/clear RTR
    }
  else
    {
      can->TXIDR0 = ( UBYTE ) ( msg->id >> 21 );      // insert ID MSB

      can->TXIDR1 = ( ( ( UBYTE ) ( msg->id >> 13 ) ) & 0xE0 )
          + ( ( ( UBYTE ) ( msg->id >> 15 ) ) & 0x07 );

      can->TXIDR2 = ( UBYTE ) ( msg->id >> 7 );
      can->TXIDR3 = ( ( UBYTE ) ( msg->id << 1 ) ) & 0xFE;

      can->TXIDR1 |= 0x10;                       // SRR=1
      can->TXIDR1 |= 0B00001000;                 // set IDE
      if( msg->RTR ) can->TXIDR3 |= 0x01;          // set/clear RTR
    }

//Can Rx

  if( ( can->RXIDR1 & 0x08 ) == 0 )  // standard or extended?
    {
      msg->id = ( ( can->RXIDR0 << 3 ) & 0x0700 )  | ( UBYTE ) ( can->RXIDR0 << 3 ) | ( UBYTE ) ( can->RXIDR1 >> 5 );

      if( can->RXIDR1 & 0x10 ) msg->RTR = 1;
      else msg->RTR = 0;

      if( can->RXIDR1 & 0x08 ) msg->IDE = 1;
      else msg->IDE = 0;
    }
  else
    {
      t = *( ( ULONG * ) ( &( can->RXIDR0 ) ) );
      msg->id = ( t >> 3 ) & 0x1FFC0000;
      msg->id |= ( t >> 1 ) & 0x0003FFFF;

      if( can->RXIDR3 & 0x01 ) msg->RTR = 1;
      else msg->RTR = 0;

      if( can->RXIDR1 & 0x08 ) msg->IDE = 1;
      else msg->IDE = 0;
    }

"Only to confuse you" I have attached the example (I hope I have not done some changes in it...) where I used CAN in polling mode for standard and extended ID.

Best regards,

Ladislav

0 Kudos