1 /* 2 * Copyright (c) 2021 HPMicro 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 8 #ifndef HPM_USB_DEVICE_H 9 #define HPM_USB_DEVICE_H 10 11 /*--------------------------------------------------------------------- 12 * Includes 13 *--------------------------------------------------------------------- 14 */ 15 #include "hpm_usb_drv.h" 16 #include "hpm_soc_feature.h" 17 /*--------------------------------------------------------------------- 18 * Macro Constant Declarations 19 *--------------------------------------------------------------------- 20 */ 21 22 /*--------------------------------------------------------------------- 23 * Macro Typedef Declaration 24 *--------------------------------------------------------------------- 25 */ 26 27 /* Queue Transfer Descriptor */ 28 typedef struct { 29 /* Word 0: Next QTD Pointer */ 30 volatile uint32_t next; /* Next link pointer This field contains the physical memory address of the next dTD to be processed */ 31 32 /* Word 1: qTQ Token */ 33 volatile uint32_t : 3; 34 volatile uint32_t xact_err : 1; 35 volatile uint32_t : 1; 36 volatile uint32_t buffer_err : 1; 37 volatile uint32_t halted : 1; 38 volatile uint32_t active : 1; 39 volatile uint32_t : 2; 40 volatile uint32_t iso_mult_override : 2 ; /* This field can be used for transmit ISOs to override the MULT field in the dQH. This field must be zero for all packet types that are not transmit-ISO. */ 41 volatile uint32_t : 3; 42 volatile uint32_t int_on_complete : 1; 43 volatile uint32_t total_bytes : 15; 44 volatile uint32_t : 0; 45 46 /* Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page */ 47 volatile uint32_t buffer[USB_SOC_DCD_QHD_BUFFER_COUNT]; 48 49 /*------------- DCD Area -------------*/ 50 volatile uint16_t expected_bytes; 51 volatile uint8_t reserved[2]; 52 } dcd_qtd_t; 53 54 /* Queue Head */ 55 typedef struct { 56 /* Word 0: Capabilities and Characteristics */ 57 58 volatile uint32_t : 15 ; /* Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated by the USB variable length protocol where N is computed using Max_packet_length and the Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 - Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark: Isochronous endpoints must set MULT = 01, 10, or 11 as needed. */ 59 volatile uint32_t int_on_setup : 1 ; /* Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is set in response to a setup being received. */ 60 volatile uint32_t max_packet_size : 11 ; /* This directly corresponds to the maximum packet size of the associated endpoint (wMaxPacketSize) */ 61 volatile uint32_t : 2; 62 volatile uint32_t zero_length_termination : 1 ; /* This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to terminate transfers in case the total transfer length is “multiple”. 0 - Enable zero-length packet to terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on transfers that are equal in length to a multiple Max_packet_length. */ 63 volatile uint32_t iso_mult : 2; 64 volatile uint32_t : 0; 65 66 /* Word 1: Current qTD Pointer */ 67 volatile uint32_t qtd_addr; 68 69 /* Word 2-9: Transfer Overlay */ 70 volatile dcd_qtd_t qtd_overlay; 71 72 /* Word 10-11: Setup request (control OUT only) */ 73 volatile usb_control_request_t setup_request; 74 75 /*-------------------------------------------------------------------- 76 * Due to the fact QHD is 64 bytes aligned but occupies only 48 bytes 77 * thus there are 16 bytes padding free that we can make use of. 78 *-------------------------------------------------------------------- 79 */ 80 volatile uint8_t reserved[16]; 81 } dcd_qhd_t; 82 83 typedef struct { 84 dcd_qhd_t qhd[USB_SOS_DCD_MAX_QHD_COUNT]; 85 dcd_qtd_t qtd[USB_SOC_DCD_MAX_QTD_COUNT]; 86 } dcd_data_t; 87 88 typedef struct { 89 USB_Type *regs; 90 dcd_data_t *dcd_data; 91 } usb_device_handle_t; 92 93 #if defined(__cplusplus) 94 extern "C" { 95 #endif /* __cplusplus */ 96 97 /*--------------------------------------------------------------------- 98 * Exported Function Declarations 99 *--------------------------------------------------------------------- 100 */ 101 /* Get a qhd of the specifed endpoint */ 102 dcd_qhd_t *usb_device_qhd_get(usb_device_handle_t *handle, uint8_t ep_idx); 103 104 /* Get a qtd of the specifed endpoint */ 105 dcd_qtd_t *usb_device_qtd_get(usb_device_handle_t *handle, uint8_t ep_idx); 106 107 /* USB bus reset */ 108 void usb_device_bus_reset(usb_device_handle_t *handle, uint16_t ep0_max_packet_size); 109 110 /* Initialize controller to device mode */ 111 bool usb_device_init(usb_device_handle_t *handle, uint32_t int_mask); 112 113 /* De-initialize controller */ 114 void usb_device_deinit(usb_device_handle_t *handle); 115 116 /* Set Address request */ 117 void usb_device_set_address(usb_device_handle_t *handle, uint8_t dev_addr); 118 119 /* Get device address */ 120 uint8_t usb_device_get_address(usb_device_handle_t *handle); 121 122 /* Wake up host */ 123 void usb_device_remote_wakeup(usb_device_handle_t *handle); 124 125 /* Connect by enabling internal pull-up resistor on D+/D- */ 126 void usb_device_connect(usb_device_handle_t *handle); 127 128 /* Disconnect by disabling internal pull-up resistor on D+/D- */ 129 void usb_device_disconnect(usb_device_handle_t *handle); 130 131 /* Configure an endpoint */ 132 bool usb_device_edpt_open(usb_device_handle_t *handle, usb_endpoint_config_t *config); 133 134 /* Submit a transfe */ 135 bool usb_device_edpt_xfer(usb_device_handle_t *handle, uint8_t ep_addr, uint8_t *buffer, uint32_t total_bytes); 136 137 /* Stall endpoint */ 138 void usb_device_edpt_stall(usb_device_handle_t *handle, uint8_t ep_addr); 139 140 /* clear stall */ 141 void usb_device_edpt_clear_stall(usb_device_handle_t *handle, uint8_t ep_addr); 142 143 /* check stall */ 144 bool usb_device_edpt_check_stall(usb_device_handle_t *handle, uint8_t ep_addr); 145 146 /* close a specified endpoint */ 147 void usb_device_edpt_close(usb_device_handle_t *handle, uint8_t ep_addr); 148 149 void usb_device_edpt_close_all(usb_device_handle_t *handle); 150 151 uint32_t usb_device_status_flags(usb_device_handle_t *handle); 152 153 void usb_device_clear_status_flags(usb_device_handle_t *handle, uint32_t mask); 154 155 uint32_t usb_device_interrupts(usb_device_handle_t *handle); 156 157 uint8_t usb_device_get_port_speed(usb_device_handle_t *handle); 158 159 uint8_t usb_device_get_suspend_status(usb_device_handle_t *handle); 160 161 bool usb_device_get_port_ccs(usb_device_handle_t *handle); 162 163 bool usb_device_get_port_reset_status(usb_device_handle_t *handle); 164 165 uint32_t usb_device_get_edpt_complete_status(usb_device_handle_t *handle); 166 167 void usb_device_clear_edpt_complete_status(usb_device_handle_t *handle, uint32_t mask); 168 169 uint32_t usb_device_get_setup_status(usb_device_handle_t *handle); 170 171 void usb_device_clear_setup_status(usb_device_handle_t *handle, uint32_t mask); 172 173 #if defined(__cplusplus) 174 } 175 #endif /* __cplusplus */ 176 #endif /* HPM_USB_DEVICE_H */ 177