This commit is contained in:
hathach 2021-05-31 16:05:55 +07:00
parent 4b2f32b778
commit 04797bc5a5
No known key found for this signature in database
GPG Key ID: 2FA891220FBFD581
3 changed files with 84 additions and 96 deletions

View File

@ -108,7 +108,7 @@ bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t resu
_ctrl_xfer.stage = STAGE_DATA;
if (request->wLength)
{
// Note: initial data toggle is always 1
// DATA stage: initial data toggle is always 1
hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength);
return true;
}
@ -123,7 +123,7 @@ bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t resu
TU_LOG2_MEM(_ctrl_xfer.buffer, request->wLength, 2);
}
// data toggle is always 1
// ACK stage: toggle is always 1
hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0);
break;

View File

@ -44,6 +44,28 @@
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
typedef struct
{
ehci_link_t period_framelist[EHCI_FRAMELIST_SIZE];
// for NXP ECHI, only implement 1 ms & 2 ms & 4 ms, 8 ms (framelist)
// [0] : 1ms, [1] : 2ms, [2] : 4ms, [3] : 8 ms
ehci_qhd_t period_head_arr[4];
// Note control qhd of dev0 is used as head of async list
struct {
ehci_qhd_t qhd;
ehci_qtd_t qtd;
}control[CFG_TUSB_HOST_DEVICE_MAX+1];
ehci_qhd_t qhd_pool[HCD_MAX_ENDPOINT];
ehci_qtd_t qtd_pool[HCD_MAX_XFER] TU_ATTR_ALIGNED(32);
ehci_registers_t* regs;
volatile uint32_t uframe_number;
}ehci_data_t;
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
@ -67,7 +89,8 @@ static inline ehci_qhd_t* qhd_control(uint8_t dev_addr)
static inline ehci_qhd_t* qhd_async_head(uint8_t rhport)
{
(void) rhport;
return qhd_control(0); // control qhd of dev0 is used as async head
// control qhd of dev0 is used as async head
return qhd_control(0);
}
static inline ehci_qtd_t* qtd_control(uint8_t dev_addr)
@ -296,6 +319,59 @@ static void ehci_stop(uint8_t rhport)
// Endpoint API
//--------------------------------------------------------------------+
bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc)
{
(void) rhport;
// TODO not support ISO yet
TU_ASSERT (ep_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS);
//------------- Prepare Queue Head -------------//
ehci_qhd_t * p_qhd;
if ( ep_desc->bEndpointAddress == 0 )
{
p_qhd = qhd_control(dev_addr);
}else
{
p_qhd = qhd_find_free();
}
TU_ASSERT(p_qhd);
qhd_init(p_qhd, dev_addr, ep_desc);
// control of dev0 is always present as async head
if ( dev_addr == 0 ) return true;
// Insert to list
ehci_link_t * list_head = NULL;
switch (ep_desc->bmAttributes.xfer)
{
case TUSB_XFER_CONTROL:
case TUSB_XFER_BULK:
list_head = (ehci_link_t*) qhd_async_head(rhport);
break;
case TUSB_XFER_INTERRUPT:
list_head = get_period_head(rhport, p_qhd->interval_ms);
break;
case TUSB_XFER_ISOCHRONOUS:
// TODO iso is not supported
break;
default: break;
}
TU_ASSERT(list_head);
// TODO might need to disable async/period list
list_insert(list_head, (ehci_link_t*) p_qhd, EHCI_QTYPE_QHD);
return true;
}
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
{
(void) rhport;
@ -365,59 +441,6 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
return true;
}
bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc)
{
(void) rhport;
// TODO not support ISO yet
TU_ASSERT (ep_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS);
//------------- Prepare Queue Head -------------//
ehci_qhd_t * p_qhd;
if ( ep_desc->bEndpointAddress == 0 )
{
p_qhd = qhd_control(dev_addr);
}else
{
p_qhd = qhd_find_free();
}
TU_ASSERT(p_qhd);
qhd_init(p_qhd, dev_addr, ep_desc);
// control of dev0 is always present as async head
if ( dev_addr == 0 ) return true;
// Insert to list
ehci_link_t * list_head = NULL;
switch (ep_desc->bmAttributes.xfer)
{
case TUSB_XFER_CONTROL:
case TUSB_XFER_BULK:
list_head = (ehci_link_t*) qhd_async_head(rhport);
break;
case TUSB_XFER_INTERRUPT:
list_head = get_period_head(rhport, p_qhd->interval_ms);
break;
case TUSB_XFER_ISOCHRONOUS:
// TODO iso is not supported
break;
default: break;
}
TU_ASSERT(list_head);
// TODO might need to disable async/period list
list_insert(list_head, (ehci_link_t*) p_qhd, EHCI_QTYPE_QHD);
return true;
}
bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr)
{
ehci_qhd_t *p_qhd = qhd_get_from_addr(dev_addr, ep_addr);

View File

@ -24,12 +24,6 @@
* This file is part of the TinyUSB stack.
*/
/** \ingroup Group_HCD
* @{
* \defgroup EHCI
* \brief EHCI driver. All documents sources mentioned here (eg section 3.5) is referring to EHCI Specs unless state otherwise
* @{ */
#ifndef _TUSB_EHCI_H_
#define _TUSB_EHCI_H_
@ -309,12 +303,11 @@ enum ehci_usbcmd_pos_ {
enum ehci_portsc_change_mask_{
EHCI_PORTSC_MASK_CURRENT_CONNECT_STATUS = TU_BIT(0),
EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE = TU_BIT(1),
EHCI_PORTSC_MASK_PORT_EANBLED = TU_BIT(2),
EHCI_PORTSC_MASK_PORT_ENABLE_CHAGNE = TU_BIT(3),
EHCI_PORTSC_MASK_OVER_CURRENT_CHANGE = TU_BIT(5),
EHCI_PORTSC_MASK_PORT_RESET = TU_BIT(8),
EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE = TU_BIT(1),
EHCI_PORTSC_MASK_PORT_EANBLED = TU_BIT(2),
EHCI_PORTSC_MASK_PORT_ENABLE_CHAGNE = TU_BIT(3),
EHCI_PORTSC_MASK_OVER_CURRENT_CHANGE = TU_BIT(5),
EHCI_PORTSC_MASK_PORT_RESET = TU_BIT(8),
EHCI_PORTSC_MASK_ALL =
EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE |
@ -425,36 +418,8 @@ typedef volatile struct
};
}ehci_registers_t;
//--------------------------------------------------------------------+
// EHCI Data Organization
//--------------------------------------------------------------------+
typedef struct
{
ehci_link_t period_framelist[EHCI_FRAMELIST_SIZE];
// for NXP ECHI, only implement 1 ms & 2 ms & 4 ms, 8 ms (framelist)
// [0] : 1ms, [1] : 2ms, [2] : 4ms, [3] : 8 ms
ehci_qhd_t period_head_arr[4];
// Note control qhd of dev0 is used as head of async list
struct {
ehci_qhd_t qhd;
ehci_qtd_t qtd;
}control[CFG_TUSB_HOST_DEVICE_MAX+1];
ehci_qhd_t qhd_pool[HCD_MAX_ENDPOINT];
ehci_qtd_t qtd_pool[HCD_MAX_XFER] TU_ATTR_ALIGNED(32);
ehci_registers_t* regs;
volatile uint32_t uframe_number;
}ehci_data_t;
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_EHCI_H_ */
/** @} */
/** @} */