KW36 FLEXCAN - GET ALL IDs (no filter)

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

KW36 FLEXCAN - GET ALL IDs (no filter)

750 Views
acarles
Contributor I

Hi,

I have some problems trying to configure the CAN to recieve all the possible identifiers. 

I know that I have to set a 0x0 mask to (no)filter the messages. This is my canInit function:

  FLEXCAN_Init(CAN0, &CAN0_config, CAN0_ENGINE_CLOCK_SOURCE);
  FLEXCAN_Enable(CAN0, true);
  flexcan_rx_mb_config_t mb_config = {
    .id = FLEXCAN_ID_STD(0x0),
    .format = kFLEXCAN_FrameFormatStandard,
    .type = kFLEXCAN_FrameTypeData
  };
  FLEXCAN_SetRxMbConfig(CAN0, rxBuffer, &mb_config, true);
  FLEXCAN_SetRxIndividualMask(CAN0, rxBuffer, FLEXCAN_RX_MB_STD_MASK(0x0,0,0)); //In config, individual mask is enabled
  FLEXCAN_SetTxMbConfig(CAN0, txBuffer, true);
  FLEXCAN_EnableMbInterrupts(CAN0, 1 << rxBuffer);

I can send messages (every 9ms for example) and recieve messages (all the possible IDs) but the main problem is that function CAN0_MB_IRQHandler is called all the time. Inside the interruption, I used FLEXCAN_GetMbStatusFlags(CAN0, 1 << rxBuffer) to check if there is any message in rxBuffer.

Because it is stopping each cycle in the interruption, the main while don't run. If I comments the lines that involve the Tx message there is no problem because CAN0_MB_IRQHandler is not called at every moment. 

Also, what I do not understand is why the CAN0_MB_IRQHandler handler is called every millisecond and not every 9ms (if Tx is the main problem).

uint8_t CAN0_SEND_8 (uint16_t ID,uint8_t DATA1, uint8_t DATA2, uint8_t DATA3, uint8_t DATA4, uint8_t DATA5, uint8_t DATA6, uint8_t DATA7, uint8_t DATA8, uint8_t LONG)
{
  flexcan_frame_t txFrame;
  if (!FLEXCAN_GetMbStatusFlags(CAN0, 1 << txBuffer)){    
    txFrame.format = kFLEXCAN_FrameFormatStandard;
    txFrame.type   = kFLEXCAN_FrameTypeData;
    txFrame.id     = FLEXCAN_ID_STD(ID);
    txFrame.length = LONG;
    txFrame.dataWord0 = CAN_WORD0_DATA_BYTE_0(DATA1) |
      CAN_WORD0_DATA_BYTE_1(DATA2) |
        CAN_WORD0_DATA_BYTE_2(DATA3) |
          CAN_WORD0_DATA_BYTE_3(DATA4);
    txFrame.dataWord1 = CAN_WORD1_DATA_BYTE_4(DATA5) |
      CAN_WORD1_DATA_BYTE_5(DATA6) |
        CAN_WORD1_DATA_BYTE_6(DATA7) |
          CAN_WORD1_DATA_BYTE_7(DATA8);
    FLEXCAN_WriteTxMb(CAN0, txBuffer, &txFrame);    
    return TRUE;
  }
  return FALSE; 
}

 

I also have configured a PIT callback (1ms).

void PIT_IRQHandler(){
  m_tick++;
  if(FLEXCAN_GetMbStatusFlags(CAN0, 1 << txBuffer)){
    FLEXCAN_ClearMbStatusFlags(CAN0, 1 << txBuffer);
  }
  CAN_Update(); //Here a switch call every 9 cycles CAN_SEND_8
   PIT_ClearStatusFlags(PIT_PERIPHERAL, PIT_CHANNEL_0, 1); 
  #if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
  #endif

}

If I use flexcan examples with blocking (while) flag cleaning, it happens the same. Is the 0x000 mask the main problem?

@santiago_lopez 

Labels (1)
0 Kudos
1 Reply

736 Views
acarles
Contributor I

I think I found a good solution. When implement a (no)filter CAN Rx (mask 0x000), the CAN0_MB_IRQHandler will be called on all Tx and Rx messages because if it is listen all the identifiers, it should also stop with the ones we sends.

The easiest way to fix this is to set the interrupt in this way:

void CAN0_MB_IRQHandler( void ){
if(FLEXCAN_GetMbStatusFlags(CAN0, 1 << rxBuffer) && (FLEXCAN_GetStatusFlags(CAN0) & kFLEXCAN_ReceivingFlag)){
FLEXCAN_ReadRxMb(CAN0, rxBuffer, &rxFrame);
CAN0_Rx(); //function to do something with rxFrame
FLEXCAN_ClearStatusFlags(CAN0, kFLEXCAN_ReceivingFlag);
}
FLEXCAN_ClearMbStatusFlags(CAN0, 1 << rxBuffer);
FLEXCAN_ClearMbStatusFlags(CAN0, 1 << txBuffer);
}

This solution has solved my main problem (the main loop stopped executing any line because the interrupt consumes all the time and the INTR FLAG was always 1).

 

0 Kudos