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
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?
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