2015-04-20 11:36 AM
I am currently have intermittent issue where I am getting stuck in ''void USB_HP_CAN_TX_IRQHandler(void)'', Everything works well from minutes to hours then I notice my CAN traffic stops, currently I TX one message every 20 mSec, I am the only module on the bus, so there should be no bus contention issues.
During my troubleshooting I am noticing if I stop my code I am alway in my interrupt routine(CAN data will also stop if I am not in debug mode). If I single step through my code while this issue is occuring I can get out of the interrupt routine. So it seem like a timing issue, but I have no idea of how to fix it.
/** @brief This function handles USB High Priority or CAN_TX interrupts. */
void USB_HP_CAN_TX_IRQHandler(void)
{
HAL_NVIC_ClearPendingIRQ(USB_HP_CAN_TX_IRQn);
HAL_CAN_IRQHandler(&hcan);
if(hcan.Instance->ESR > 0)
{
__HAL_CAN_CANCEL_TRANSMIT(&hcan,0);
}
}
/**
* @brief Initiates and transmits a CAN frame message.
* @param hcan: pointer to a CAN_HandleTypeDef structure that contains
* the configuration information for the specified CAN.
* @retval HAL status
*/
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((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
{
transmitmailbox = 0;
}
else if((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
{
transmitmailbox = 1;
}
else if((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2)
{
transmitmailbox = 2;
}
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 <<
21
) | \
hcan->pTxMsg->RTR);
}
else
{
assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId <<
3
) | \
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 */
hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3] <<
24
) |
((uint32_t)hcan->pTxMsg->Data[2] <<
16
) |
((uint32_t)hcan->pTxMsg->Data[1] <<
8
) |
((uint32_t)hcan->pTxMsg->Data[0]));
hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7] <<
24
) |
((uint32_t)hcan->pTxMsg->Data[6] <<
16
) |
((uint32_t)hcan->pTxMsg->Data[5] <<
8
) |
((uint32_t)hcan->pTxMsg->Data[4]));
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 Error warning Interrupt */
__HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG);
/* Enable Error passive Interrupt */
__HAL_CAN_ENABLE_IT(hcan, CAN_IT_EPV);
/* Enable Bus-off Interrupt */
__HAL_CAN_ENABLE_IT(hcan, CAN_IT_BOF);
/* Enable Last error code Interrupt */
__HAL_CAN_ENABLE_IT(hcan, CAN_IT_LEC);
/* Enable Error Interrupt */
__HAL_CAN_ENABLE_IT(hcan, CAN_IT_ERR);
/* Enable Transmit mailbox empty Interrupt */
__HAL_CAN_ENABLE_IT(hcan, CAN_IT_TME);
/* Request transmission */
hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
}
}
else
{
return HAL_BUSY;
}
return HAL_OK;
}
#stm32-can