[已解决]请代码维护者看看 USB HOST 寄存器操作是否有误?

abcrazy2020
Posts: 16
Joined: Thu May 06, 2021 6:01 am

[已解决]请代码维护者看看 USB HOST 寄存器操作是否有误?

Postby abcrazy2020 » Fri Jun 04, 2021 6:58 am

IDF版本:4.4-master

文件路径:https://github.com/espressif/esp-idf/bl ... /usbh_ll.h

疑问代码:
  1. volatile usb_hprt_reg_t hprt_reg;                   //0x0440
  2. typedef union {
  3.     struct {
  4.         uint32_t prtconnsts: 1;
  5.         uint32_t prtconndet: 1;
  6.         uint32_t prtena: 1;
  7.         uint32_t prtenchng: 1;
  8.         uint32_t prtovrcurract: 1;
  9.         uint32_t prtovrcurrchng: 1;
  10.         uint32_t prtres: 1;
  11.         uint32_t prtsusp: 1;
  12.         uint32_t prtrst: 1;
  13.         uint32_t reserved1: 1;
  14.         uint32_t prtlnsts: 2;
  15.         uint32_t prtpwr: 1;
  16.         uint32_t prttstctl: 4;
  17.         uint32_t prtspd: 2;
  18.         uint32_t reserved13: 13;
  19.     };
  20.     uint32_t val;
  21. } usb_hprt_reg_t;
  22.  
  23. #define USBH_LL_HPRT_W1C_MSK                (0x2E)
  24. #define USBH_LL_HPRT_ENA_MSK                (0x04)
  25. static inline void usbh_ll_hprt_port_dis(usbh_dev_t *hw)
  26. {
  27.     usb_hprt_reg_t hprt;
  28.     hprt.val = hw->hprt_reg.val;
  29.     hprt.prtena = 1;        //W1C to disable
  30.     //we want to W1C ENA but not W1C the interrupt bits
  31.     hw->hprt_reg.val = hprt.val & ((~USBH_LL_HPRT_W1C_MSK) | USBH_LL_HPRT_ENA_MSK);
  32. }


疑问语句第29行:hprt.prtena = 1; //W1C to disable

疑问:
1.hprt.prtena 寄存器位由硬件模块置位,使能端口;软件置 0 才清除位,禁用端口。
2.如果第一点正确,那么同文件的下面函数都会把 hprt.prtena 寄存器位置 0,禁用端口:
static inline void usbh_ll_hprt_set_test_ctl(usbh_dev_t *hw, uint32_t test_mode);
static inline void usbh_ll_hprt_en_pwr(usbh_dev_t *hw);
static inline void usbh_ll_hprt_dis_pwr(usbh_dev_t *hw);
static inline void usbh_ll_hprt_set_port_reset(usbh_dev_t *hw, bool reset);
static inline void usbh_ll_hprt_set_port_suspend(usbh_dev_t *hw);
static inline void usbh_ll_hprt_set_port_resume(usbh_dev_t *hw);
static inline void usbh_ll_hprt_clr_port_resume(usbh_dev_t *hw);
static inline uint32_t usbh_ll_hprt_intr_read_and_clear(usbh_dev_t *hw);
static inline void usbh_ll_hprt_intr_clear(usbh_dev_t *hw, uint32_t intr_mask);
Last edited by abcrazy2020 on Mon Jun 14, 2021 1:39 am, edited 1 time in total.

ESP_Gargamel
Posts: 786
Joined: Wed Nov 14, 2018 8:45 am

Re: 请代码维护者看看 USB HOST 寄存器操作是否有误?

Postby ESP_Gargamel » Fri Jun 04, 2021 10:07 am

W1C,是写 1 禁用。

abcrazy2020
Posts: 16
Joined: Thu May 06, 2021 6:01 am

Re: 请代码维护者看看 USB HOST 寄存器操作是否有误?

Postby abcrazy2020 » Fri Jun 04, 2021 10:44 am

ESP_Gargamel wrote:
Fri Jun 04, 2021 10:07 am
W1C,是写 1 禁用。

https://github.com/espressif/esp-idf/bl ... /usb_reg.h
第 480 行

Code: Select all

/** USB_HPRT_REG register
 *  Host Port Control and Status Register
 */
#define USB_HPRT_REG (SOC_DPORT_USB_BASE + 0x440)

/** USB_PRTENA : R/W; bitpos: [2]; default: 0;
 *  Port Enable
 *  1'b0: Port disabled
 *  1'b1: Port enabled
 */
#define USB_PRTENA    (BIT(2))
#define USB_PRTENA_M  (USB_PRTENA_V << USB_PRTENA_S)
#define USB_PRTENA_V  0x00000001
#define USB_PRTENA_S  2
请认真考察,这个寄存器位不是中断反馈位,而是使能位,不具有写 1 清 0 属性。

abcrazy2020
Posts: 16
Joined: Thu May 06, 2021 6:01 am

Re: 请代码维护者看看 USB HOST 寄存器操作是否有误?

Postby abcrazy2020 » Fri Jun 04, 2021 10:49 am

文件:
https://github.com/espressif/esp-idf/bl ... /usb/hcd.c

函数:
esp_err_t hcd_pipe_alloc(hcd_port_handle_t port_hdl, const hcd_pipe_config_t *pipe_config, hcd_pipe_handle_t *pipe_hdl)

代码:

Code: Select all

switch (type) {
        case USB_XFER_TYPE_CTRL:
            hal_type = USB_PRIV_XFER_TYPE_CTRL;
            break;
        case USB_XFER_TYPE_ISOCHRONOUS:
            hal_type = USB_PRIV_XFER_TYPE_ISOCHRONOUS;
            break;
        case USB_XFER_TYPE_BULK:
            hal_type = USB_PRIV_XFER_TYPE_ISOCHRONOUS;
            break;
        default:    //USB_XFER_TYPE_INTR
            hal_type = USB_PRIV_XFER_TYPE_INTR;
            break;
    }
错误:
case USB_XFER_TYPE_BULK:
hal_type = USB_PRIV_XFER_TYPE_ISOCHRONOUS;

更正:
case USB_XFER_TYPE_BULK:
hal_type = USB_PRIV_XFER_TYPE_BULK;

ESP_Gargamel
Posts: 786
Joined: Wed Nov 14, 2018 8:45 am

Re: 请代码维护者看看 USB HOST 寄存器操作是否有误?

Postby ESP_Gargamel » Fri Jun 04, 2021 12:01 pm

非常感谢反馈,S2 TRM 里 USB 部分的寄存器说明暂时还未提供,从其他 vendor 的 TRM 中看 prtena 是 rc_w0,具体让负责 USB 的同事再确认下。

第二个问题,内部已经有修正,暂时未同步出去。

ESP_Dazz
Posts: 308
Joined: Fri Jun 02, 2017 6:50 am

Re: 请代码维护者看看 USB HOST 寄存器操作是否有误?

Postby ESP_Dazz » Mon Jun 07, 2021 7:41 am

在 HPRT (Host Port) 寄存器里有一些比特位是写1来清零(W1C, Write 1 to Clear)。这些比特位包括 PrtEnChng (Port Enable/Disable Change), PrtEna (Port Enable), PrtConnDet (Port Connection Detected),PrtOvrCurrChng (Port Over Current Change)。因为写1会清0,这些W1C比特位的 0->1 变化都是有 USB 外设的内部事件引发的。例如:
  • PrtEn 0->1 是成功发送 RESET 信号后引发的。软件写1会导致软件引发的 Port Disable
  • PrtEnChng 0->1 是任何 PrtEn 变化后引发的。软件写1会将 PrtEnChng 的中断清0
  • PrtConnDet 0->1 是 Device 链接[后引发的。软件写1会将 PrtConnDet 的中断清0
  1. static inline void usbh_ll_hprt_port_dis(usbh_dev_t *hw);
  2. static inline void usbh_ll_hprt_set_test_ctl(usbh_dev_t *hw, uint32_t test_mode);
  3. static inline void usbh_ll_hprt_en_pwr(usbh_dev_t *hw);
  4. static inline void usbh_ll_hprt_dis_pwr(usbh_dev_t *hw);
  5. static inline void usbh_ll_hprt_set_port_reset(usbh_dev_t *hw, bool reset);
  6. static inline void usbh_ll_hprt_set_port_suspend(usbh_dev_t *hw);
  7. static inline void usbh_ll_hprt_set_port_resume(usbh_dev_t *hw);
  8. static inline void usbh_ll_hprt_clr_port_resume(usbh_dev_t *hw);
  9. static inline uint32_t usbh_ll_hprt_intr_read_and_clear(usbh_dev_t *hw);
  10. static inline void usbh_ll_hprt_intr_clear(usbh_dev_t *hw, uint32_t intr_mask);
所以在这些函数里,必须用 USBH_LL_HPRT_W1C_MSK 来保证软件回写的时候不会写 1 到一些 W1C 比特位。

Who is online

Users browsing this forum: No registered users and 127 guests