cancel
Showing results for 
Search instead for 
Did you mean: 

Stuck in CAN TX Interrupt

ebommer
Associate II
Posted on April 20, 2015 at 20:36

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
0 REPLIES 0