AnsweredAssumed Answered

Bug on HAL_CAN_Transmit_IT on STM32F105 ?

Question asked by marco on Feb 16, 2016
Latest reply on Jan 26, 2017 by wu.xiaobin
Hi, 

i use this function to transmit data on CAN (generated from STM32CubeMX last version)....

But i see a little problem, if haven't MAILBOX available, what happend ?

You can see on exit return "HAL_OK" , state is "HAL_CAN_STATE_READY" and Lock is "HAL_LOCKED"

What actions should I take before exit from this funcion, if no mailboxes are available ?

Sorry for my english 



HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
{
  uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;


  /* Check the parameters */
  assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
  assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
  assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
  
  if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_RX))
  {
    /* Process Locked */
    __HAL_LOCK(hcan);
    
    /* Select one empty transmit mailbox */
    if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
    {
      transmitmailbox = 0;
    }
    else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
    {
      transmitmailbox = 1;
    }
    else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2))
    {
      transmitmailbox = 2;
    }
    else
    {
      transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
    }


    if(transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
    {
      /* Set up the Id */
      hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
      if (hcan->pTxMsg->IDE == CAN_ID_STD)
      {
        assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));  
        hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_BIT_POSITION) |
                                                             hcan->pTxMsg->RTR);
      }
      else
      {
        assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
        hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) |
                                                             hcan->pTxMsg->IDE |
                                                             hcan->pTxMsg->RTR);
      }
    
      /* Set up the DLC */
      hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
      hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
      hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
      
      /* Set up the data field */
      WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) | 
                                                                  ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) |
                                                                  ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) | 
                                                                  ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION)  );
      WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) | 
                                                                  ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) |
                                                                  ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) |
                                                                  ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION)  );
    
      if(hcan->State == HAL_CAN_STATE_BUSY_RX) 
      {
        /* Change CAN state */
        hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
      }
      else
      {
        /* Change CAN state */
        hcan->State = HAL_CAN_STATE_BUSY_TX;
      }
      
      /* Set CAN error code to none */
      hcan->ErrorCode = HAL_CAN_ERROR_NONE;
      
      /* Process Unlocked */
      __HAL_UNLOCK(hcan);
      
      /* Enable interrupts: */
      /*  - Enable Error warning Interrupt */
      /*  - Enable Error passive Interrupt */
      /*  - Enable Bus-off Interrupt */
      /*  - Enable Last error code Interrupt */
      /*  - Enable Error Interrupt */
      /*  - Enable Transmit mailbox empty Interrupt */
      __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
                                CAN_IT_EPV |
                                CAN_IT_BOF |
                                CAN_IT_LEC |
                                CAN_IT_ERR |
                                CAN_IT_TME  );
      
      /* Request transmission */
      hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
    }
    else
    {     
     // What actions should I take before exit from this funcion, if no mailboxes are available ?       
        // >> what should I do ???
    }
  }
  else
  {
    return HAL_BUSY;
  }
  
  return HAL_OK;
}

Outcomes