Question
HAL_CAN_Transmit_IT & HAL_CAN_Receive_IT can't be used simultaneously
Posted on November 10, 2015 at 11:08
Synopsis: HAL_CAN_Transmit_IT & HAL_CAN_Receive_IT can't be used simultaneously effective without data loss risks.
Details:When you build receive/transmit cycle like below (simplified)main() { HAL_CAN_Receive_IT(); HAL_CAN_Transmit_IT();}HAL_CAN_RxCpltCallback() { HAL_CAN_Receive_IT(); // rearm receive}HAL_CAN_TxCpltCallback() { HAL_CAN_Transmit_IT(); // rearm transmit}In some situations HAL_CAN_Receive_IT/HAL_CAN_Transmit_IT drops with busy state.This occurs because both of Transmit & Receive uses lock via __HAL_LOCK(hcan) When you call HAL_CAN_Transmit_IT and interrupt HAL_CAN_RxCpltCallback occurs, state is locked by HAL_CAN_Transmit_IT and rearm rx failed.What solution to solve?I can't find easy way now. In my opinion general mistake is unified ''HAL_CAN_StateTypeDef State'' used for three indenpended flags - General can state, rx state & tx state.I think solution is split State for {State, rxState & txState} and never lock same thing in both of Receive/Transmit.For example current structuretypedef enum{ HAL_CAN_STATE_RESET = 0x00, /*!< CAN not yet initialized or disabled */ HAL_CAN_STATE_READY = 0x01, /*!< CAN initialized and ready for use */ HAL_CAN_STATE_BUSY = 0x02, /*!< CAN process is ongoing */ HAL_CAN_STATE_BUSY_TX = 0x12, /*!< CAN process is ongoing */ HAL_CAN_STATE_BUSY_RX = 0x22, /*!< CAN process is ongoing */ HAL_CAN_STATE_BUSY_TX_RX = 0x32, /*!< CAN process is ongoing */ HAL_CAN_STATE_TIMEOUT = 0x03, /*!< CAN in Timeout state */ HAL_CAN_STATE_ERROR = 0x04 /*!< CAN error state */ }HAL_CAN_StateTypeDef;typedef struct{ ... __IO HAL_CAN_StateTypeDef State; /*!< CAN communication state */ ...}CAN_HandleTypeDef;split totypedef enum{ HAL_CAN_STATE_RESET = 0x00, /*!< CAN not yet initialized or disabled */ HAL_CAN_STATE_READY = 0x01, /*!< CAN initialized and ready for use */ HAL_CAN_STATE_BUSY = 0x02, /*!< CAN process is ongoing */ }HAL_CAN_StateTypeDef;typedef enum{ HAL_CAN_TXRX_STATE_READY = 0x01, HAL_CAN_TXRX_STATE_BUSY = 0x02, HAL_CAN_TXRX_STATE_TIMEOUT = 0x03, HAL_CAN_TXRX_STATE_ERROR = 0x04 }HAL_CAN_TxRxStateTypeDef;typedef struct{ ... __IO HAL_CAN_StateTypeDef State; /*!< CAN communication state */ __IO HAL_CAN_TxRxStateTypeDef RxState; /*!< CAN RX communication state */ __IO HAL_CAN_TxRxStateTypeDef TxState; /*!< CAN TX communication state */ ...}CAN_HandleTypeDef;But that is awesome library modification. Maybe you know any better solution?Same problem affects USART library, i think