AnsweredAssumed Answered

CAN Bus Tx packets missing [STM32F303x]

Question asked by bigden.gary on Feb 8, 2016
Latest reply on Apr 5, 2016 by FTITI.Walid
Problem with the CAN Tx dropping packets.
I am testing by sending 8192 packets to a CAN Bus analyzer. each test packet is less than 8 data bytes. After about 60 packets have been sent at 250kBaud about half of the remaining are dropped. No indication of errors.
Anything obvious I am doing wrong here?

void setupCAN( void )
{
  float baudrate = (float)Calibrate.CAN_Baudrate, quanta, prescalar;
  uint8_t initStatus = CAN_InitStatus_Failed;
  
  CAN_DeInit( CAN1 );
  
    //CAN cell init 
  CANInit.CAN_TTCM = DISABLE;
  CANInit.CAN_ABOM = DISABLE;
  CANInit.CAN_AWUM = DISABLE;
  CANInit.CAN_NART = DISABLE;
//  CANInit.CAN_NART = ENABLE;
  CANInit.CAN_RFLM = ENABLE;            //Discard incoming messages on FIFO overrun
  CANInit.CAN_TXFP = ENABLE;            //Use as a FIFO where the priority order is given by the transmit request order
  CANInit.CAN_Mode = CAN_Mode_Normal;
  
  CANInit.CAN_SJW = CAN_SJW_1tq;
  CANInit.CAN_BS1 = CAN_BS1_9tq;
  CANInit.CAN_BS2 = CAN_BS2_1tq;
  quanta = 11;
  prescalar = 32768000 / (baudrate * quanta);
  CANInit.CAN_Prescaler = (uint16_t)( prescalar + 0.5 );        //Make sure we round to nearest whole number


  initStatus = CAN_Init(CAN1, &CANInit);
  if (initStatus == CAN_InitStatus_Failed) {Error.canRxError = true; Error.canTxError = true;}


    //CAN filter init "FIFO0" - we are only going to use this one in practice                                   
  CANFilter.CAN_FilterNumber = 0;
  CANFilter.CAN_FilterMode =  CAN_FilterMode_IdMask;
  CANFilter.CAN_FilterScale = CAN_FilterScale_32bit;
  CANFilter.CAN_FilterIdHigh = Calibrate.CAN_FilterIdHigh; 
  CANFilter.CAN_FilterIdLow = Calibrate.CAN_FilterIdLow; 
  CANFilter.CAN_FilterMaskIdHigh = Calibrate.CAN_FilterMaskIdHigh;
  CANFilter.CAN_FilterMaskIdLow = Calibrate.CAN_FilterMaskIdLow;
  CANFilter.CAN_FilterFIFOAssignment = 0;
  CANFilter.CAN_FilterActivation = ENABLE;
  CAN_FilterInit(&CANFilter);


    //Filling out the defaults in the Tx struct for CAN bus
  CANTxMessage.DLC = 8;                         //Default number of data bytes to send
  CANTxMessage.ExtId = 0;                       //No extended ID
  CANTxMessage.IDE = CAN_ID_STD;                //Base Frame identifier
  CANTxMessage.RTR = CAN_RTR_DATA;              //Remote transmission request for data frame
  CANTxMessage.StdId = Calibrate.CAN_stdID;     //Our frame ID for data transmitted from the SoS board 
}




  /////////////////////////////////////////////////////////////////////////////
  /// @brief The CAN bus transmit string function
  /// @note We just break the string into 8 byte chunks and transmit them
  /// If we cannot exactly divide by 8 then we pad the last few bytes with 0
  /// Remember we are sending ASCII and 0 is a clear "non data" byte
  /// @param[in] pStr Pointer to the string
  /// @param[in] numBytes Number of bytes to send
  /// @return Boolean pass or fail - false==fail, true==pass
  /////////////////////////////////////////////////////////////////////////////


bool stringToCAN( char* pStr, int numBytes )
{
  int i;
  char data;
  uint8_t mailBoxNumber=CAN_TxStatus_NoMailBox, dlc=8, canTxStatus=CAN_TxStatus_Failed;
  bool status=PASS;
  
  while (numBytes > 0)
  {
    watchdog();                         // Kick the dog on long data dumps
    if (numBytes < 8) 
    {
      dlc = numBytes;                   //Number of bytes, less than 8, that remain to be sent
      CANTxMessage.DLC = dlc; 
    }
    else
    {
      CANTxMessage.DLC = 8; 
    }


    for (i=0; i<dlc; i++)
    {
      data = *(pStr++);
      CANTxMessage.Data[i] = data;
      numBytes--;
    }
    
    while( mailBoxNumber == CAN_TxStatus_NoMailBox )             //Only transmit when mailbox is available
    {  
      mailBoxNumber = CAN_Transmit( CAN1, &CANTxMessage ); 
    }


    canTxStatus = CAN_TxStatus_Pending;
    while( canTxStatus == CAN_TxStatus_Pending )
    {
      canTxStatus = CAN_TransmitStatus(CAN1, mailBoxNumber); 
    }


    if (canTxStatus == CAN_TxStatus_Failed) 
    {
      Error.canTxError = true;
    }
    
  }
  return( status );
}

Outcomes