stmhal: Make USB CDC driver use SOF instead of TIM3 for outgoing data.
Previous to this patch the USB CDC driver used TIM3 to trigger the sending of outgoing data over USB serial. This patch changes the behaviour so that the USB SOF interrupt is used to trigger the processing of the sending. This reduces latency and increases bandwidth of outgoing data. Thanks to Martin Fischer, aka @hoihu, for the idea and initial prototype. See PR #1713.
This commit is contained in:
parent
7417ccfb0d
commit
d363133917
@ -480,8 +480,6 @@ void EXTI15_10_IRQHandler(void) {
|
|||||||
void PVD_IRQHandler(void) {
|
void PVD_IRQHandler(void) {
|
||||||
IRQ_ENTER(PVD_IRQn);
|
IRQ_ENTER(PVD_IRQn);
|
||||||
#if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
|
#if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
|
||||||
extern void USBD_CDC_HAL_TIM_PeriodElapsedCallback(void);
|
|
||||||
USBD_CDC_HAL_TIM_PeriodElapsedCallback();
|
|
||||||
#endif
|
#endif
|
||||||
Handle_EXTI_Irq(EXTI_PVD_OUTPUT);
|
Handle_EXTI_Irq(EXTI_PVD_OUTPUT);
|
||||||
IRQ_EXIT(PVD_IRQn);
|
IRQ_EXIT(PVD_IRQn);
|
||||||
|
@ -252,7 +252,6 @@ TIM_HandleTypeDef *timer_tim6_init(uint freq) {
|
|||||||
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
|
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
|
||||||
#if !defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
|
#if !defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
|
||||||
if (htim == &TIM3_Handle) {
|
if (htim == &TIM3_Handle) {
|
||||||
USBD_CDC_HAL_TIM_PeriodElapsedCallback();
|
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (htim == &TIM5_Handle) {
|
if (htim == &TIM5_Handle) {
|
||||||
|
@ -257,12 +257,10 @@ static int8_t CDC_Itf_Control(uint8_t cmd, uint8_t* pbuf, uint16_t length) {
|
|||||||
return USBD_OK;
|
return USBD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// This function is called to process outgoing data. We hook directly into the
|
||||||
* @brief TIM period elapsed callback
|
// SOF (start of frame) callback so that it is called exactly at the time it is
|
||||||
* @param htim: TIM handle
|
// needed (reducing latency), and often enough (increasing bandwidth).
|
||||||
* @retval None
|
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) {
|
||||||
*/
|
|
||||||
void USBD_CDC_HAL_TIM_PeriodElapsedCallback(void) {
|
|
||||||
if (!dev_is_connected) {
|
if (!dev_is_connected) {
|
||||||
// CDC device is not connected to a host, so we are unable to send any data
|
// CDC device is not connected to a host, so we are unable to send any data
|
||||||
return;
|
return;
|
||||||
@ -276,9 +274,8 @@ void USBD_CDC_HAL_TIM_PeriodElapsedCallback(void) {
|
|||||||
if (UserTxBufPtrOut != UserTxBufPtrOutShadow) {
|
if (UserTxBufPtrOut != UserTxBufPtrOutShadow) {
|
||||||
// We have sent data and are waiting for the low-level USB driver to
|
// We have sent data and are waiting for the low-level USB driver to
|
||||||
// finish sending it over the USB in-endpoint.
|
// finish sending it over the USB in-endpoint.
|
||||||
// We have a 15 * 10ms = 150ms timeout
|
// SOF occurs every 1ms, so we have a 150 * 1ms = 150ms timeout
|
||||||
if (UserTxBufPtrWaitCount < 15) {
|
if (UserTxBufPtrWaitCount < 150) {
|
||||||
PCD_HandleTypeDef *hpcd = hUSBDDevice.pData;
|
|
||||||
USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
|
USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
|
||||||
if (USBx_INEP(CDC_IN_EP & 0x7f)->DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ) {
|
if (USBx_INEP(CDC_IN_EP & 0x7f)->DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ) {
|
||||||
// USB in-endpoint is still reading the data
|
// USB in-endpoint is still reading the data
|
||||||
@ -457,7 +454,7 @@ void USBD_CDC_TxAlways(const uint8_t *buf, uint32_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Some unused code that makes sure the low-level USB buffer is drained.
|
// Some unused code that makes sure the low-level USB buffer is drained.
|
||||||
// Waiting for low-level is handled in USBD_CDC_HAL_TIM_PeriodElapsedCallback.
|
// Waiting for low-level is handled in HAL_PCD_SOFCallback.
|
||||||
/*
|
/*
|
||||||
start = HAL_GetTick();
|
start = HAL_GetTick();
|
||||||
PCD_HandleTypeDef *hpcd = hUSBDDevice.pData;
|
PCD_HandleTypeDef *hpcd = hUSBDDevice.pData;
|
||||||
|
@ -31,8 +31,6 @@
|
|||||||
|
|
||||||
extern const USBD_CDC_ItfTypeDef USBD_CDC_fops;
|
extern const USBD_CDC_ItfTypeDef USBD_CDC_fops;
|
||||||
|
|
||||||
void USBD_CDC_HAL_TIM_PeriodElapsedCallback(void);
|
|
||||||
|
|
||||||
int USBD_CDC_IsConnected(void);
|
int USBD_CDC_IsConnected(void);
|
||||||
void USBD_CDC_SetInterrupt(int chr, void *data);
|
void USBD_CDC_SetInterrupt(int chr, void *data);
|
||||||
|
|
||||||
|
@ -276,10 +276,13 @@ void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
|||||||
* @param hpcd: PCD handle
|
* @param hpcd: PCD handle
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
This is now handled by the USB CDC interface.
|
||||||
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
|
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
|
||||||
{
|
{
|
||||||
USBD_LL_SOF(hpcd->pData);
|
USBD_LL_SOF(hpcd->pData);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reset callback.
|
* @brief Reset callback.
|
||||||
@ -394,7 +397,7 @@ if (pdev->id == USB_PHY_FS_ID)
|
|||||||
pcd_fs_handle.Init.dma_enable = 0;
|
pcd_fs_handle.Init.dma_enable = 0;
|
||||||
pcd_fs_handle.Init.low_power_enable = 0;
|
pcd_fs_handle.Init.low_power_enable = 0;
|
||||||
pcd_fs_handle.Init.phy_itface = PCD_PHY_EMBEDDED;
|
pcd_fs_handle.Init.phy_itface = PCD_PHY_EMBEDDED;
|
||||||
pcd_fs_handle.Init.Sof_enable = 0;
|
pcd_fs_handle.Init.Sof_enable = 1;
|
||||||
pcd_fs_handle.Init.speed = PCD_SPEED_FULL;
|
pcd_fs_handle.Init.speed = PCD_SPEED_FULL;
|
||||||
#if !defined(MICROPY_HW_USB_VBUS_DETECT_PIN)
|
#if !defined(MICROPY_HW_USB_VBUS_DETECT_PIN)
|
||||||
pcd_fs_handle.Init.vbus_sensing_enable = 0; // No VBUS Sensing on USB0
|
pcd_fs_handle.Init.vbus_sensing_enable = 0; // No VBUS Sensing on USB0
|
||||||
|
Loading…
Reference in New Issue
Block a user