basically finish code for control transfer & test code
This commit is contained in:
		@@ -246,6 +246,7 @@ tusb_error_t hcd_controller_reset(uint8_t hostid)
 | 
			
		||||
// PIPE API
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
static void queue_head_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, uint16_t max_packet_size, uint8_t endpoint_addr, uint8_t xfer_type);
 | 
			
		||||
 | 
			
		||||
static inline ehci_qhd_t* const get_control_qhd(uint8_t dev_addr) ATTR_ALWAYS_INLINE ATTR_PURE ATTR_WARN_UNUSED_RESULT;
 | 
			
		||||
static inline ehci_qtd_t* get_control_qtds(uint8_t dev_addr) ATTR_ALWAYS_INLINE ATTR_PURE ATTR_WARN_UNUSED_RESULT;
 | 
			
		||||
static inline tusb_std_request_t* const get_control_request_ptr(uint8_t dev_addr) ATTR_ALWAYS_INLINE ATTR_PURE ATTR_WARN_UNUSED_RESULT;
 | 
			
		||||
@@ -301,6 +302,20 @@ pipe_handle_t hcd_pipe_open(uint8_t dev_addr, tusb_descriptor_endpoint_t const *
 | 
			
		||||
  return null_handle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void queue_td_init(ehci_qtd_t* p_qtd, uint32_t data_ptr, uint16_t total_bytes)
 | 
			
		||||
{
 | 
			
		||||
  memclr_(p_qtd, sizeof(ehci_qtd_t));
 | 
			
		||||
 | 
			
		||||
  p_qtd->alternate.terminate = 1; // not used, always set to terminated
 | 
			
		||||
  p_qtd->active = 1;
 | 
			
		||||
  p_qtd->cerr = 3; // TODO 3 consecutive errors tolerance
 | 
			
		||||
  p_qtd->data_toggle = 0;
 | 
			
		||||
  p_qtd->total_bytes = total_bytes;
 | 
			
		||||
 | 
			
		||||
  p_qtd->buffer[0] = data_ptr;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tusb_error_t  hcd_pipe_control_xfer(uint8_t dev_addr, tusb_std_request_t const * p_request, uint8_t data[])
 | 
			
		||||
{
 | 
			
		||||
  ehci_qhd_t * const p_qhd = get_control_qhd(dev_addr);
 | 
			
		||||
@@ -309,21 +324,19 @@ tusb_error_t  hcd_pipe_control_xfer(uint8_t dev_addr, tusb_std_request_t const *
 | 
			
		||||
  ehci_qtd_t *p_data   = p_setup + 1;
 | 
			
		||||
  ehci_qtd_t *p_status = p_setup + 2;
 | 
			
		||||
 | 
			
		||||
  memclr_(p_setup, sizeof(ehci_qtd_t));
 | 
			
		||||
  p_setup->next.address = (uint32_t) p_data;
 | 
			
		||||
  p_setup->active = 1;
 | 
			
		||||
  p_setup->cerr = 3; // TODO 3 consecutive errors tolerance
 | 
			
		||||
  p_setup->data_toggle = 0;
 | 
			
		||||
  p_setup->total_bytes = 8; // sizeof (tusb_std_request_t)
 | 
			
		||||
 | 
			
		||||
  p_setup->buffer[0] = (uint32_t) get_control_request_ptr(dev_addr);
 | 
			
		||||
  *(get_control_request_ptr(dev_addr)) = *p_request;
 | 
			
		||||
  //------------- SETUP Phase -------------//
 | 
			
		||||
  *(get_control_request_ptr(dev_addr)) = *p_request; // copy request
 | 
			
		||||
 | 
			
		||||
  queue_td_init(p_setup, (uint32_t) get_control_request_ptr(dev_addr), 8);
 | 
			
		||||
  p_setup->pid = EHCI_PID_SETUP;
 | 
			
		||||
  p_setup->next.address = (uint32_t) p_data;
 | 
			
		||||
 | 
			
		||||
  //------------- DATA Phase -------------//
 | 
			
		||||
  if (p_request->wLength > 0)
 | 
			
		||||
  {
 | 
			
		||||
 | 
			
		||||
    queue_td_init(p_data, (uint32_t) data, p_request->wLength);
 | 
			
		||||
    p_data->data_toggle = 1;
 | 
			
		||||
    p_data->pid         = p_request->bmRequestType.direction ? EHCI_PID_IN : EHCI_PID_OUT;
 | 
			
		||||
  }else
 | 
			
		||||
  {
 | 
			
		||||
    p_data = p_setup;
 | 
			
		||||
@@ -331,15 +344,15 @@ tusb_error_t  hcd_pipe_control_xfer(uint8_t dev_addr, tusb_std_request_t const *
 | 
			
		||||
 | 
			
		||||
  p_data->next.address = (uint32_t) p_status;
 | 
			
		||||
 | 
			
		||||
  p_status->next.terminate = 1;
 | 
			
		||||
 | 
			
		||||
  //------------- alternate link is not used -------------//
 | 
			
		||||
  p_data->alternate.terminate = 1;
 | 
			
		||||
  p_setup->alternate.terminate = 1;
 | 
			
		||||
  p_data->alternate.terminate = 1;
 | 
			
		||||
  //------------- STATUS Phase -------------//
 | 
			
		||||
  queue_td_init(p_status, 0, 0); // zero-length data
 | 
			
		||||
  p_status->int_on_complete = 1;
 | 
			
		||||
  p_status->data_toggle     = 1;
 | 
			
		||||
  p_status->pid             = p_request->bmRequestType.direction ? EHCI_PID_OUT : EHCI_PID_IN; // reverse direction of data phase
 | 
			
		||||
  p_status->next.terminate  = 1;
 | 
			
		||||
 | 
			
		||||
  //------------- hook TD List to Queue Head -------------//
 | 
			
		||||
  p_qhd->p_qtd_list = p_setup;
 | 
			
		||||
  p_qhd->p_qtd_list               = p_setup;
 | 
			
		||||
  p_qhd->qtd_overlay.next.address = (uint32_t) p_setup;
 | 
			
		||||
 | 
			
		||||
  return TUSB_ERROR_NONE;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user