1 /* 2 * Copyright (c) 2016, Freescale Semiconductor, Inc. 3 * Copyright 2016 NXP 4 * All rights reserved. 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 */ 8 9 #ifndef __USB_DEVICE_LPC3511IP_H__ 10 #define __USB_DEVICE_LPC3511IP_H__ 11 12 #include "fsl_device_registers.h" 13 14 /*! 15 * @addtogroup usb_device_controller_lpcip3511_driver 16 * @{ 17 */ 18 19 /******************************************************************************* 20 * Definitions 21 ******************************************************************************/ 22 23 /* For bulk out endpoint in high speed mode, use long length data transfer to decrease the Ping packet count to increase 24 * bulk bandwidth */ 25 /* The bigger this macro's value is, the higher bandwidth bulk out endpoint has. However, you need to set a reasonable 26 * value for this macro based on RAM size of Soc. If this macro's value is too big, link may be failed. */ 27 /* Note that please set this value as integral multiple of 512U. When using USB RAM, you also can decrease the 28 * USB_DEVICE_IP3511_USB_RAM_IN_USE_SIZE within a reasonable range to use more USB RAM */ 29 #if (((defined(USB_DEVICE_CONFIG_MSC)) && (USB_DEVICE_CONFIG_MSC > 0U)) && \ 30 ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) 31 #define USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX (0U) 32 #endif 33 34 /* During enumeration for high speed, IP3511HS responds NYET to the host(HUAWEI smartphone P20, Kirin 970 platform) for 35 OUT transaction in the status stage of control transfer. \ The host can not handle NYET respond in this case. Then 36 this leads to enumeration failure. This workaround is used to fix this issue, which force the prime length is 65 37 bytes. This workaround is disabled by default */ 38 #if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) 39 #define USB_DEVICE_IP3511HS_CONTROL_OUT_NYET_WORKAROUND (0U) 40 #endif 41 42 /*! @brief Prime all the double endpoint buffer at the same time, if the transfer length is larger than max packet size. 43 */ 44 #define USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE (1U) 45 #if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) 46 #define USB_LPC3511IP_Type USBHSD_Type 47 #define USB_DEVICE_IP3511_ENDPOINTS_NUM FSL_FEATURE_USBHSD_EP_NUM 48 #define USB_DEVICE_IP3511_USB_RAM_SIZE FSL_FEATURE_USBHSD_USB_RAM 49 #else 50 #define USB_LPC3511IP_Type USB_Type 51 #define USB_DEVICE_IP3511_ENDPOINTS_NUM FSL_FEATURE_USB_EP_NUM 52 #if ((defined(FSL_FEATURE_USB_USB_RAM)) && (FSL_FEATURE_USB_USB_RAM > 0U)) 53 #define USB_DEVICE_IP3511_USB_RAM_SIZE FSL_FEATURE_USB_USB_RAM 54 #endif 55 #endif 56 57 /*! @brief Use the macro to represent the USB RAM that has been used. The remaining USB RAM will be used by the 58 controller driver. If application needs to allocate variables into the USB RAM, please increase the macro or link 59 may fail. Likewise, if requiring to assign more USB RAM to the controller driver, please decrease the macro. 60 When USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX is used, USB_DEVICE_IP3511_USB_RAM_IN_USE_SIZE can be 61 decreased within a reasonable range to use more USB RAM. */ 62 #define USB_DEVICE_IP3511_USB_RAM_IN_USE_SIZE (3U * 1024U) 63 /*! @brief The reserved buffer size, the buffer is for the memory copy if the application transfer buffer is 64 ((not 64 bytes alignment) || (not in the USB RAM) || (HS && OUT && not multiple of the maximum packet size)) */ 65 #if ((defined(USB_DEVICE_IP3511_USB_RAM_SIZE)) && (USB_DEVICE_IP3511_USB_RAM_SIZE > 0U)) 66 #define USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE \ 67 ((uint32_t)USB_DEVICE_IP3511_USB_RAM_SIZE - USB_DEVICE_IP3511_USB_RAM_IN_USE_SIZE) 68 #else 69 #if ((defined(USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX)) && \ 70 (USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX > 0U)) 71 /* if use USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX (>0U), need to increase the reserved buffer size */ 72 #define USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE \ 73 ((5U * 1024U) + (USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX / 512U) * 512U) 74 #else 75 #define USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE (5U * 1024U) 76 #endif 77 #endif 78 79 /*! @brief Use one bit to represent one reserved 64 bytes to allocate the buffer by uint of 64 bytes. */ 80 #define USB_DEVICE_IP3511_BITS_FOR_RESERVED_BUFFER ((USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE + 63U) / 64U) 81 /*! @brief How many IPs support the reserved buffer */ 82 #define USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY (USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS) 83 84 /* for out endpoint,only use buffer toggle, disable prime double buffer at the same time*/ 85 /*host send data less than maxpacket size and in endpoint prime length more more than maxpacketsize, there will be state 86 * mismtach*/ 87 #if USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE 88 #define USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER (1U) 89 #else 90 #define USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER (0U) 91 #endif 92 93 #define USB_DEVICE_IP3511HS_LPM_ADPPROBE_ATTACH_DEBOUNCE_COUNT (3) 94 95 /* if FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE is true: 96 * Enable this macro to exit HS mode automatically if the user case is: 97 * host and device keep cable connected, and host turn off vbus to simulate detachment. 98 * If user disconnects the cable, there is no issue and don't need enable this macro. 99 * There is one delay in the isr if enable this macro. 100 */ 101 #define USB_DEVICE_IP3511HS_FORCE_EXIT_HS_MODE_ENABLE (0u) 102 103 /*! @brief Endpoint state structure */ 104 typedef struct _usb_device_lpc3511ip_endpoint_state_struct 105 { 106 uint8_t *transferBuffer; /*!< Address of buffer containing the data to be transmitted */ 107 uint32_t transferLength; /*!< Length of data to transmit. */ 108 uint32_t transferDone; /*!< The data length has been transferred*/ 109 uint32_t transferPrimedLength; /*!< it may larger than transferLength, because the primed length may larger than the 110 transaction length. */ 111 uint8_t *epPacketBuffer; /*!< The max packet buffer for copying*/ 112 union 113 { 114 uint32_t state; /*!< The state of the endpoint */ 115 struct 116 { 117 uint32_t maxPacketSize : 12U; /*!< The maximum packet size of the endpoint */ 118 uint32_t stalled : 1U; /*!< The endpoint is stalled or not */ 119 uint32_t transferring : 1U; /*!< The endpoint is transferring */ 120 uint32_t zlt : 1U; /*!< zlt flag */ 121 uint32_t stallPrimed : 1U; 122 uint32_t epPacketCopyed : 1U; /*!< whether use the copy buffer */ 123 uint32_t epControlDefault : 5u; /*!< The EP command/status 26~30 bits */ 124 uint32_t doubleBufferBusy : 2U; /*!< How many buffers are primed, for control endpoint it is not used */ 125 uint32_t producerOdd : 1U; /*!< When priming one transaction, prime to this endpoint buffer */ 126 uint32_t consumerOdd : 1U; /*!< When transaction is done, read result from this endpoint buffer */ 127 uint32_t endpointType : 2U; 128 #if (defined(USB_DEVICE_CONFIG_ROOT2_TEST) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U)) 129 uint32_t isOpened : 1U; /*!< whether the endpoint is initialized */ 130 uint32_t reserved1 : 3U; 131 #else 132 uint32_t reserved1 : 4U; 133 #endif 134 } stateBitField; 135 } stateUnion; 136 union 137 { 138 uint16_t epBufferStatus; 139 /* If double buff is disable, only epBufferStatusUnion[0] is used; 140 For control endpoint, only epBufferStatusUnion[0] is used. */ 141 struct 142 { 143 uint16_t transactionLength : 15U; 144 uint16_t epPacketCopyed : 1U; 145 } epBufferStatusField; 146 } epBufferStatusUnion[2]; 147 } usb_device_lpc3511ip_endpoint_state_struct_t; 148 149 /*! @brief LPC USB controller (IP3511) state structure */ 150 typedef struct _usb_device_lpc3511ip_state_struct 151 { 152 /*!< control data buffer, must align with 64 */ 153 uint8_t *controlData; 154 /*!< 8 bytes' setup data, must align with 64 */ 155 uint8_t *setupData; 156 /*!< 4 bytes for zero length transaction, must align with 64 */ 157 uint8_t *zeroTransactionData; 158 /* Endpoint state structures */ 159 usb_device_lpc3511ip_endpoint_state_struct_t endpointState[(USB_DEVICE_IP3511_ENDPOINTS_NUM * 2)]; 160 usb_device_handle deviceHandle; /*!< (4 bytes) Device handle used to identify the device object belongs to */ 161 USB_LPC3511IP_Type *registerBase; /*!< (4 bytes) ip base address */ 162 volatile uint32_t *epCommandStatusList; /* endpoint list */ 163 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \ 164 (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) 165 void *dcdHandle; /*!< Dcd handle used to identify the device object belongs to */ 166 #endif 167 uint8_t controllerId; /*!< Controller ID */ 168 uint8_t isResetting; /*!< Is doing device reset or not */ 169 uint8_t deviceSpeed; /*!< some controller support the HS */ 170 #if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) 171 uint8_t controllerSpeed; 172 #endif 173 #if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE)) 174 uint8_t deviceState; /*!< Is device attached,1 attached,0 detached */ 175 #endif 176 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) 177 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) 178 uint8_t lpmRemoteWakeUp; 179 #endif 180 #endif 181 #if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) 182 #if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ 183 (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK)) 184 uint8_t hsInterruptIssue; 185 #endif 186 #endif 187 } usb_device_lpc3511ip_state_struct_t; 188 189 /*! 190 * @name USB device controller (IP3511) functions 191 * @{ 192 */ 193 194 /******************************************************************************* 195 * API 196 ******************************************************************************/ 197 198 #if defined(__cplusplus) 199 extern "C" { 200 #endif 201 202 /*! 203 * @brief Initializes the USB device controller instance. 204 * 205 * This function initializes the USB device controller module specified by the controllerId. 206 * 207 * @param[in] controllerId The controller ID of the USB IP. See the enumeration type usb_controller_index_t. 208 * @param[in] handle Pointer of the device handle used to identify the device object belongs to. 209 * @param[out] controllerHandle An out parameter used to return the pointer of the device controller handle to the 210 * caller. 211 * 212 * @return A USB error code or kStatus_USB_Success. 213 */ 214 usb_status_t USB_DeviceLpc3511IpInit(uint8_t controllerId, 215 usb_device_handle handle, 216 usb_device_controller_handle *controllerHandle); 217 218 /*! 219 * @brief Deinitializes the USB device controller instance. 220 * 221 * This function deinitializes the USB device controller module. 222 * 223 * @param[in] controllerHandle Pointer of the device controller handle. 224 * 225 * @return A USB error code or kStatus_USB_Success. 226 */ 227 usb_status_t USB_DeviceLpc3511IpDeinit(usb_device_controller_handle controllerHandle); 228 229 /*! 230 * @brief Sends data through a specified endpoint. 231 * 232 * This function sends data through a specified endpoint. 233 * 234 * @param[in] controllerHandle Pointer of the device controller handle. 235 * @param[in] endpointAddress Endpoint index. 236 * @param[in] buffer The memory address to hold the data need to be sent. 237 * @param[in] length The data length need to be sent. 238 * 239 * @return A USB error code or kStatus_USB_Success. 240 * 241 * @note The return value indicates whether the sending request is successful or not. The transfer completion is 242 * notified by the 243 * corresponding callback function. 244 * Currently, only one transfer request can be supported for a specific endpoint. 245 * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application 246 * should implement a queue in the application level. 247 * The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the 248 * endpoint 249 * callback). 250 */ 251 usb_status_t USB_DeviceLpc3511IpSend(usb_device_controller_handle controllerHandle, 252 uint8_t endpointAddress, 253 uint8_t *buffer, 254 uint32_t length); 255 256 /*! 257 * @brief Receives data through a specified endpoint. 258 * 259 * This function receives data through a specified endpoint. 260 * 261 * @param[in] controllerHandle Pointer of the device controller handle. 262 * @param[in] endpointAddress Endpoint index. 263 * @param[in] buffer The memory address to save the received data. 264 * @param[in] length The data length to be received. 265 * 266 * @return A USB error code or kStatus_USB_Success. 267 * 268 * @note The return value indicates whether the receiving request is successful or not. The transfer completion is 269 * notified by the 270 * corresponding callback function. 271 * Currently, only one transfer request can be supported for a specific endpoint. 272 * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application 273 * should implement a queue in the application level. 274 * The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the 275 * endpoint 276 * callback). 277 */ 278 usb_status_t USB_DeviceLpc3511IpRecv(usb_device_controller_handle controllerHandle, 279 uint8_t endpointAddress, 280 uint8_t *buffer, 281 uint32_t length); 282 283 /*! 284 * @brief Cancels the pending transfer in a specified endpoint. 285 * 286 * The function is used to cancel the pending transfer in a specified endpoint. 287 * 288 * @param[in] controllerHandle ointer of the device controller handle. 289 * @param[in] ep Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. 290 * 291 * @return A USB error code or kStatus_USB_Success. 292 */ 293 usb_status_t USB_DeviceLpc3511IpCancel(usb_device_controller_handle controllerHandle, uint8_t ep); 294 295 /*! 296 * @brief Controls the status of the selected item. 297 * 298 * The function is used to control the status of the selected item. 299 * 300 * @param[in] controllerHandle Pointer of the device controller handle. 301 * @param[in] type The selected item. Please refer to enumeration type usb_device_control_type_t. 302 * @param[in,out] param The parameter type is determined by the selected item. 303 * 304 * @return A USB error code or kStatus_USB_Success. 305 */ 306 usb_status_t USB_DeviceLpc3511IpControl(usb_device_controller_handle controllerHandle, 307 usb_device_control_type_t type, 308 void *param); 309 310 /*! @} */ 311 312 #if defined(__cplusplus) 313 } 314 #endif 315 316 /*! @} */ 317 318 #endif /* __USB_DEVICE_LPC3511IP_H__ */ 319