This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

STM32, RTX and CAN Filter Message Index

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.

0