2019-01-25 05:28 AM
There bug in STM HAL Lib generated by cube mx.
Problem:
I am using usb communication on STM32L433. I have high speed traffic both direction on the same endpoint. USB is stopped in one of the direction, and doesn't transmit/receive data any more.
Why:
Interrupt flag of another interrupt cleared when read->modify->write process.
For examle. We had out endpoint interrupt and call macros PCD_CLEAR_RX_EP_CTR. But after status value is read, register was modifyed by hardware (another interrupt flag was set). When software will write new value it will clear this flag and it handler will be not called.
Solution:
stm32l4xx_hal_pcd.h, replace macros to:
#define PCD_CLEAR_RX_EP_CTR(USBx, bEpNum) do { \
register uint16_t _wRegVal; \
\
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (0x7FFFU & USB_EPREG_MASK); \
_wRegVal |= USB_EP_CTR_TX; \
\
PCD_SET_ENDPOINT((USBx), (bEpNum), _wRegVal); \
} while(0) /* PCD_CLEAR_RX_EP_CTR */
#define PCD_CLEAR_TX_EP_CTR(USBx, bEpNum) do { \
register uint16_t _wRegVal; \
\
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (0xFF7FU & USB_EPREG_MASK); \
_wRegVal |= USB_EP_CTR_RX; \
\
PCD_SET_ENDPOINT((USBx), (bEpNum), _wRegVal); \
} while(0) /* PCD_CLEAR_TX_EP_CTR */
2019-01-25 07:02 AM
Hi @Evgeny Sobolev ,
Thanks for sharing this proposal.
I will report it to our USB experts who will assess it, and will deploy your proposal if needed.
Btw, in PCD_CLEAR_TX_EP_CTR, you should be using USB_EP_CTR_TX, right?
#define PCD_CLEAR_TX_EP_CTR(USBx, bEpNum) do { \
register uint16_t _wRegVal; \
\
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (0xFF7FU & USB_EPREG_MASK); \
_wRegVal |= USB_EP_CTR_TX; \
\
PCD_SET_ENDPOINT((USBx), (bEpNum), _wRegVal); \
} while(0) /* PCD_CLEAR_TX_EP_CTR */
-Amel
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2019-01-25 07:17 AM
PCD_CLEAR_TX_EP_CTR should clear USB_EP_CTR_TX flag only by writing zero there, but sometimes it clears USB_EP_CTR_RX flag. That is why I append "_wRegVal |= USB_EP_CTR_RX" into the macro. According to datasheet USB_EP_CTR_RX can be cleared by writing zero, and write one means nothing. That is soltion in the first message.
2019-01-25 07:39 AM
OK, thanks for explanation.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.