mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-04 20:40:00 +00:00
fix(usb/host): Fix reaction on High-Speed NYET packet
In Scatter-Gather DMA mode, the USB-DWC will automatically enable PING protocol if an OUT packet is NACKed by the High-Speed device. The PING bit must be manually reset.
This commit is contained in:
@@ -791,50 +791,33 @@ static inline void usb_dwc_ll_hctsiz_set_qtd_list_len(volatile usb_dwc_host_chan
|
||||
chan->hctsiz_reg.val = hctsiz.val;
|
||||
}
|
||||
|
||||
static inline void usb_dwc_ll_hctsiz_init(volatile usb_dwc_host_chan_regs_t *chan)
|
||||
/**
|
||||
* @brief Perform PING protocol
|
||||
*
|
||||
* @note This function is here only for compatibility reasons. PING is not relevant on FS only targets
|
||||
* @param[in] chan Channel registers
|
||||
* @param[in] enable true: Enable PING, false: Disable PING
|
||||
*/
|
||||
static inline void usb_dwc_ll_hctsiz_set_dopng(volatile usb_dwc_host_chan_regs_t *chan, bool enable)
|
||||
{
|
||||
usb_dwc_hctsiz_reg_t hctsiz;
|
||||
hctsiz.val = chan->hctsiz_reg.val;
|
||||
hctsiz.dopng = 0; //Don't do ping
|
||||
/*
|
||||
Set SCHED_INFO which occupies xfersize[7:0]
|
||||
It is always set to 0xFF for full speed and not used in Bulk/Ctrl channels
|
||||
*/
|
||||
hctsiz.xfersize |= 0xFF;
|
||||
chan->hctsiz_reg.val = hctsiz.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set scheduling info for Periodic channel
|
||||
*
|
||||
* @note ESP32-S3 is Full-Speed only, so SCHED_INFO is always set to 0xFF
|
||||
* @attention This function must be called for each periodic channel!
|
||||
* @see USB-OTG databook: Table 5-47
|
||||
*
|
||||
* @param[in] chan Channel registers
|
||||
* @param[in] tokens_per_frame Ignored
|
||||
* @param[in] offset Ignored
|
||||
*/
|
||||
static inline void usb_dwc_ll_hctsiz_set_sched_info(volatile usb_dwc_host_chan_regs_t *chan, int tokens_per_frame, int offset)
|
||||
{
|
||||
// @see USB-OTG databook: Table 5-47
|
||||
// This function is relevant only for HS
|
||||
usb_dwc_hctsiz_reg_t hctsiz;
|
||||
hctsiz.val = chan->hctsiz_reg.val;
|
||||
uint8_t sched_info_val;
|
||||
switch (tokens_per_frame) {
|
||||
case 1:
|
||||
offset %= 8; // If the required offset > 8, we must wrap around to SCHED_INFO size = 8
|
||||
sched_info_val = 0b00000001;
|
||||
break;
|
||||
case 2:
|
||||
offset %= 4;
|
||||
sched_info_val = 0b00010001;
|
||||
break;
|
||||
case 4:
|
||||
offset %= 2;
|
||||
sched_info_val = 0b01010101;
|
||||
break;
|
||||
case 8:
|
||||
offset = 0;
|
||||
sched_info_val = 0b11111111;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
sched_info_val <<= offset;
|
||||
hctsiz.xfersize &= ~(0xFF);
|
||||
hctsiz.xfersize |= sched_info_val;
|
||||
hctsiz.xfersize |= 0xFF;
|
||||
chan->hctsiz_reg.val = hctsiz.val;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user