This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CAN RX Interrupt Woes

Within my ISR, CANIntStatus() only returns CAN_INT_INTID_STATUS, and reading the status register yields CAN_STATUS_RXOK.

Any ideas why my message object ID isn't being returned by CANIntStatus()?

Tx in advance,

Brad

bool CAN_ChannelInit( uint8_t uiChannel )
{
  if ( uiChannel >= CAN_CHANNEL_COUNT )
    return false;

  // CANInit must be called first
    ROM_CANInit( tCANDev[uiChannel].uiCANBase );

  // Configure the bit rate for the CAN device, the clock rate to the CAN
  // controller is the system clock and the bit rate is set to 1Mbps.
  CAN_ConfigApplyBusSpeed( uiChannel );

  // Enable the controller
  ROM_CANEnable( tCANDev[uiChannel].uiCANBase );

  // Set up the message object that will receive all messages on the CAN bus.
  CAN_ConfigureFIFORX( uiChannel );

  tCANDev[uiChannel].bInitialised = true;

  // Enable interrupts from the CAN controller
  ROM_CANIntEnable( tCANDev[uiChannel].uiCANBase, CAN_INT_MASTER | CAN_INT_STATUS | CAN_INT_ERROR );
  ROM_IntEnable( tCANDev[uiChannel].uiIRQNum );

  // Apply the current configuration
  CAN_ConfigApply( uiChannel );

  // Clear the status message interrupt request
  tCANDev[uiChannel].uiBusStatus = ROM_CANStatusGet( tCANDev[uiChannel].uiCANBase, CAN_STS_CONTROL );

  // Clear any prior message interrupts requests
  CAN_Flush( uiChannel );

  return false;
}

bool CAN_ConfigureFIFORX( uint8_t uiChannel )
{
  uint8_t uiMsgId;

  if ( uiChannel >= CAN_CHANNEL_COUNT )
    return false;

  // Set up the receive FIFO
  for ( uiMsgId = 0; uiMsgId < CAN_RX_FIFO_DEPTH; uiMsgId++ )
  {
    tCANDev[uiChannel].tRXCANMsgObjArray[uiMsgId].ui32MsgID     = 0x00000000;
    tCANDev[uiChannel].tRXCANMsgObjArray[uiMsgId].ui32MsgIDMask = 0x00000000;

    // This enables interrupts for received messages
    if ( uiMsgId == ( CAN_RX_FIFO_DEPTH - 1 ))
      tCANDev[uiChannel].tRXCANMsgObjArray[uiMsgId].ui32Flags = MSG_OBJ_RX_INT_ENABLE;
    else
      tCANDev[uiChannel].tRXCANMsgObjArray[uiMsgId].ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_FIFO;

    // The length of the message, which should be eight bytes
    tCANDev[uiChannel].tRXCANMsgObjArray[uiMsgId].ui32MsgLen = 8;

    // Set the message object
    ROM_CANMessageSet( tCANDev[uiChannel].uiCANBase, uiMsgId + 1, &(tCANDev[uiChannel].tRXCANMsgObjArray[uiMsgId]), MSG_OBJ_TYPE_RX );
  }

  return true;
}

bool CAN_ISR( uint8_t uiChannel )
{
  uint32_t uiIntStatus;

  if ( uiChannel >= CAN_CHANNEL_COUNT )
    return false;

  // Find the cause of the interrupt, if it is a status interrupt then just
  // acknowledge the interrupt by reading the status register.
  uiIntStatus = ROM_CANIntStatus( tCANDev[uiChannel].uiCANBase, CAN_INT_STS_CAUSE );
  if ( uiIntStatus == CAN_INT_INTID_STATUS )
  {
    // Clear the interrupt implicitly using CANStatusGet()
    tCANDev[uiChannel].uiBusStatus = ROM_CANStatusGet( tCANDev[uiChannel].uiCANBase, CAN_STS_CONTROL );
  }
  else if (( uiIntStatus >= 1 ) && ( uiIntStatus <= CAN_RX_FIFO_DEPTH ))
  {
    // CAN Message received
    tCANDev[uiChannel].bIntRX = true;

    // Interrupt is cleared by CANMessageGet()
  }
  else if ( uiIntStatus & CAN_TX_MSG_ID )
  {
    // CAN Message transmitted
    tCANDev[uiChannel].bIntTX = true;

    // Clear the interrupt
    ROM_CANIntClear( tCANDev[uiChannel].uiCANBase, uiIntStatus);
  }

  return true;
}

  • Even though I thought I wasn't using the filter, it's necessary to use the MSG_OBJ_USE_ID_FILTER flag to generate the message object interrupt.

      // This enables interrupts for received messages
      if ( uiMsgId == ( CAN_RX_FIFO_DEPTH - 1 ))
        pMsgObj->ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER;
      else
        pMsgObj->ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER | MSG_OBJ_FIFO;