Hi,
I'm designing an application receiving different configurable CAN frames. So I use the CAN_rx_object function to define them into the CAN filters.
CAN_rx_object (U32 ctrl, U32 ch, U32 id, U32 object_para)
I believed that every time I receive a CAN frame, the channel parameter would be in the CAN_msg structure (ch parameter). Unfortunately I was wrong.
CAN_receive (U32 ctrl, CAN_msg *msg, U16 timeout)
I looked in the documentation of the STM32F207 I'm using, and the micro stores the filter index each time it receives the message in the CAN_RTDxR register.
So I modified the CAN_hw_rd function in STM32F20x.c to store this filter index into the CAN_msg structure, using the ignored ch parameter.
/*--------------------------- CAN_hw_rd ------------------------------------- * * Read CAN_msg from the hardware registers of the requested controller * * Parameter: ctrl: Index of the hardware CAN controller (1 .. x) * ch: Ignored * msg: Pointer where CAN message will be read * * Return: none *---------------------------------------------------------------------------*/ static void CAN_hw_rd (U32 ctrl, U32 ch, CAN_msg *msg) { CAN_TypeDef *CANx = CAN_CTRL[ctrl-1]; /* Read identifier information */ if ((CANx->sFIFOMailBox[0].RIR & (1 << 2)) == 0) { /* Standard ID */ msg->format = STANDARD_FORMAT; msg->id = 0x000007FFUL & (CANx->sFIFOMailBox[0].RIR >> 21); } else { /* Extended ID */ msg->format = EXTENDED_FORMAT; msg->id = 0x1FFFFFFFUL & (CANx->sFIFOMailBox[0].RIR >> 3); } /* Read type information */ if ((CANx->sFIFOMailBox[0].RIR & (1 << 1)) == 0) { msg->type = DATA_FRAME; /* DATA FRAME */ } else { msg->type = REMOTE_FRAME; /* REMOTE FRAME */ } /* Read length (number of received bytes) */ msg->len = (U32)0x0000000F & CANx->sFIFOMailBox[0].RDTR; /* Read Filter Index */ msg->ch = CANx->sFIFOMailBox[0].RDTR >> 8; /* Read data bytes */ msg->data[0] = (U32)0x000000FF & (CANx->sFIFOMailBox[0].RDLR); msg->data[1] = (U32)0x000000FF & (CANx->sFIFOMailBox[0].RDLR >> 8); msg->data[2] = (U32)0x000000FF & (CANx->sFIFOMailBox[0].RDLR >> 16); msg->data[3] = (U32)0x000000FF & (CANx->sFIFOMailBox[0].RDLR >> 24); msg->data[4] = (U32)0x000000FF & (CANx->sFIFOMailBox[0].RDHR); msg->data[5] = (U32)0x000000FF & (CANx->sFIFOMailBox[0].RDHR >> 8); msg->data[6] = (U32)0x000000FF & (CANx->sFIFOMailBox[0].RDHR >> 16); msg->data[7] = (U32)0x000000FF & (CANx->sFIFOMailBox[0].RDHR >> 24); }
I'm aware that this Index is depending on how the CAN message are added (on the 2 controllers), but it will always return the same index for each frame received.
But why do you even need to know that? What difference does it make, to the application handling the messages, which CAN message object it arrived in?
You may know that each CAN frame (and there could be a lot) contains different information, so it can be useful to know which CAN frame has arrived, in order to store this information at the right place, without testing the frame ID against all the possible IDs.
For other processor, I use the filter index as a direct table lookup since it represents a continuous sequence - the CAN identifiers can be far apart.
Hi, did you find any solution? I'm experiencing the same problem, with FMI always indicating the same filter index (actually it is always 0).
Thanks!