common: Implement Time::fmt_time().
[gps-watch.git] / src / common / usb_device_khci.h
1 /*
2  * The Clear BSD License
3  * Copyright (c) 2015, Freescale Semiconductor, Inc.
4  * Copyright 2016 NXP
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without modification,
8  * are permitted (subject to the limitations in the disclaimer below) provided
9  * that the following conditions are met:
10  *
11  * o Redistributions of source code must retain the above copyright notice, this list
12  *   of conditions and the following disclaimer.
13  *
14  * o Redistributions in binary form must reproduce the above copyright notice, this
15  *   list of conditions and the following disclaimer in the documentation and/or
16  *   other materials provided with the distribution.
17  *
18  * o Neither the name of the copyright holder nor the names of its
19  *   contributors may be used to endorse or promote products derived from this
20  *   software without specific prior written permission.
21  *
22  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
27  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 #ifndef __USB_DEVICE_KHCI_H__
36 #define __USB_DEVICE_KHCI_H__
37
38 /*!
39  * @addtogroup usb_device_controller_khci_driver
40  * @{
41  */
42
43 /*******************************************************************************
44  * Definitions
45  ******************************************************************************/
46
47 /*! @brief The maximum value of ISO maximum packet size for FS in USB specification 2.0 */
48 #define USB_DEVICE_MAX_FS_ISO_MAX_PACKET_SIZE (1023U)
49
50 /*! @brief The maximum value of non-ISO maximum packet size for FS in USB specification 2.0 */
51 #define USB_DEVICE_MAX_FS_NONE_ISO_MAX_PACKET_SIZE (64U)
52
53 /*! @brief Set BDT buffer address */
54 #define USB_KHCI_BDT_SET_ADDRESS(bdt_base, ep, direction, odd, address)                          \
55     *((volatile uint32_t *)((bdt_base & 0xfffffe00U) | (((uint32_t)ep & 0x0fU) << 5U) |          \
56                             (((uint32_t)direction & 1U) << 4U) | (((uint32_t)odd & 1U) << 3U)) + \
57       1U) = address
58
59 /*! @brief Set BDT control fields*/
60 #define USB_KHCI_BDT_SET_CONTROL(bdt_base, ep, direction, odd, control)                \
61     *(volatile uint32_t *)((bdt_base & 0xfffffe00U) | (((uint32_t)ep & 0x0fU) << 5U) | \
62                            (((uint32_t)direction & 1U) << 4U) | (((uint32_t)odd & 1U) << 3U)) = control
63
64 /*! @brief Get BDT buffer address*/
65 #define USB_KHCI_BDT_GET_ADDRESS(bdt_base, ep, direction, odd)                                    \
66     (*((volatile uint32_t *)((bdt_base & 0xfffffe00U) | (((uint32_t)ep & 0x0fU) << 5U) |          \
67                              (((uint32_t)direction & 1U) << 4U) | (((uint32_t)odd & 1U) << 3U)) + \
68        1U))
69
70 /*! @brief Get BDT control fields*/
71 #define USB_KHCI_BDT_GET_CONTROL(bdt_base, ep, direction, odd)                          \
72     (*(volatile uint32_t *)((bdt_base & 0xfffffe00U) | (((uint32_t)ep & 0x0fU) << 5U) | \
73                             (((uint32_t)direction & 1U) << 4U) | (((uint32_t)odd & 1U) << 3U)))
74
75 /*! @brief Endpoint state structure */
76 typedef struct _usb_device_khci_endpoint_state_struct
77 {
78     uint8_t *transferBuffer; /*!< Address of buffer containing the data to be transmitted */
79     uint32_t transferLength; /*!< Length of data to transmit. */
80     uint32_t transferDone;   /*!< The data length has been transferred*/
81     union
82     {
83         uint32_t state; /*!< The state of the endpoint */
84         struct
85         {
86             uint32_t maxPacketSize : 10U; /*!< The maximum packet size of the endpoint */
87             uint32_t stalled : 1U;        /*!< The endpoint is stalled or not */
88             uint32_t data0 : 1U;          /*!< The data toggle of the transaction */
89             uint32_t bdtOdd : 1U;         /*!< The BDT toggle of the endpoint */
90             uint32_t dmaAlign : 1U;       /*!< Whether the transferBuffer is DMA aligned or not */
91             uint32_t transferring : 1U;   /*!< The endpoint is transferring */
92             uint32_t zlt : 1U;            /*!< zlt flag */
93         } stateBitField;
94     } stateUnion;
95 } usb_device_khci_endpoint_state_struct_t;
96
97 /*! @brief KHCI state structure */
98 typedef struct _usb_device_khci_state_struct
99 {
100     usb_device_struct_t *deviceHandle; /*!< Device handle used to identify the device object belongs to */
101     uint8_t *bdt;                      /*!< BDT buffer address */
102     USB_Type *registerBase;            /*!< The base address of the register */
103     uint8_t setupPacketBuffer[USB_SETUP_PACKET_SIZE * 2]; /*!< The setup request buffer */
104     uint8_t *dmaAlignBuffer; /*!< This buffer is used to fix the transferBuffer or transferLength does
105                                not align to 4-bytes when the function USB_DeviceKhciRecv is called.
106                                The macro USB_DEVICE_CONFIG_KHCI_DMA_ALIGN is used to enable or disable this feature.
107                                If the feature is enabled, when the transferBuffer or transferLength does not align to
108                                4-bytes,
109                                the transferLength is not more than USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH, and
110                                the flag isDmaAlignBufferInusing is zero, the dmaAlignBuffer is used to receive data
111                                and the flag isDmaAlignBufferInusing is set to 1.
112                                When the transfer is done, the received data, kept in dmaAlignBuffer, is copied
113                                to the transferBuffer, and the flag isDmaAlignBufferInusing is cleared.
114                                 */
115     usb_device_khci_endpoint_state_struct_t
116         endpointState[USB_DEVICE_CONFIG_ENDPOINTS * 2]; /*!< Endpoint state structures */
117     uint8_t isDmaAlignBufferInusing;                    /*!< The dmaAlignBuffer is used or not */
118     uint8_t isResetting;                                /*!< Is doing device reset or not */
119     uint8_t controllerId;                               /*!< Controller ID */
120     uint8_t setupBufferIndex;                           /*!< A valid setup buffer flag */
121 #if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG))
122     uint8_t otgStatus;
123 #endif
124 } usb_device_khci_state_struct_t;
125
126 #if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \
127     (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U))
128 typedef struct _usb_device_dcd_state_struct
129 {
130     usb_device_struct_t *deviceHandle; /*!< Device handle used to identify the device object belongs to */
131     USBDCD_Type *dcdRegisterBase;      /*!< The base address of the dcd module */
132     uint8_t controllerId;              /*!< Controller ID */
133 } usb_device_dcd_state_struct_t;
134 #endif
135
136 #if defined(__cplusplus)
137 extern "C" {
138 #endif
139
140 /*!
141  * @name USB device KHCI functions
142  * @{
143  */
144
145 /*******************************************************************************
146  * API
147  ******************************************************************************/
148
149 /*!
150  * @brief Initializes the USB device KHCI instance.
151  *
152  * This function initializes the USB device KHCI module specified by the controllerId.
153  *
154  * @param[in] controllerId The controller ID of the USB IP. See the enumeration type usb_controller_index_t.
155  * @param[in] handle        Pointer of the device handle used to identify the device object belongs to.
156  * @param[out] khciHandle   An out parameter used to return the pointer of the device KHCI handle to the caller.
157  *
158  * @return A USB error code or kStatus_USB_Success.
159  */
160 usb_status_t USB_DeviceKhciInit(uint8_t controllerId,
161                                 usb_device_handle handle,
162                                 usb_device_controller_handle *khciHandle);
163
164 /*!
165  * @brief Deinitializes the USB device KHCI instance.
166  *
167  * This function deinitializes the USB device KHCI module.
168  *
169  * @param[in] khciHandle   Pointer of the device KHCI handle.
170  *
171  * @return A USB error code or kStatus_USB_Success.
172  */
173 usb_status_t USB_DeviceKhciDeinit(usb_device_controller_handle khciHandle);
174
175 /*!
176  * @brief Sends data through a specified endpoint.
177  *
178  * This function sends data through a specified endpoint.
179  *
180  * @param[in] khciHandle      Pointer of the device KHCI handle.
181  * @param[in] endpointAddress Endpoint index.
182  * @param[in] buffer           The memory address to hold the data need to be sent.
183  * @param[in] length           The data length need to be sent.
184  *
185  * @return A USB error code or kStatus_USB_Success.
186  *
187  * @note The return value indicates whether the sending request is successful or not. The transfer completion is
188  * notified by the
189  * corresponding callback function.
190  * Currently, only one transfer request can be supported for a specific endpoint.
191  * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application
192  * should implement a queue in the application level.
193  * The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the
194  * endpoint
195  * callback).
196  */
197 usb_status_t USB_DeviceKhciSend(usb_device_controller_handle khciHandle,
198                                 uint8_t endpointAddress,
199                                 uint8_t *buffer,
200                                 uint32_t length);
201
202 /*!
203  * @brief Receives data through a specified endpoint.
204  *
205  * This function receives data through a specified endpoint.
206  *
207  * @param[in] khciHandle      Pointer of the device KHCI handle.
208  * @param[in] endpointAddress Endpoint index.
209  * @param[in] buffer           The memory address to save the received data.
210  * @param[in] length           The data length to be received.
211  *
212  * @return A USB error code or kStatus_USB_Success.
213  *
214  * @note The return value indicates whether the receiving request is successful or not. The transfer completion is
215  * notified by the
216  * corresponding callback function.
217  * Currently, only one transfer request can be supported for a specific endpoint.
218  * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application
219  * should implement a queue in the application level.
220  * The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the
221  * endpoint
222  * callback).
223  */
224 usb_status_t USB_DeviceKhciRecv(usb_device_controller_handle khciHandle,
225                                 uint8_t endpointAddress,
226                                 uint8_t *buffer,
227                                 uint32_t length);
228
229 /*!
230  * @brief Cancels the pending transfer in a specified endpoint.
231  *
232  * The function is used to cancel the pending transfer in a specified endpoint.
233  *
234  * @param[in] khciHandle      Pointer of the device KHCI handle.
235  * @param[in] ep               Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
236  *
237  * @return A USB error code or kStatus_USB_Success.
238  */
239 usb_status_t USB_DeviceKhciCancel(usb_device_controller_handle khciHandle, uint8_t ep);
240
241 /*!
242  * @brief Controls the status of the selected item.
243  *
244  * The function is used to control the status of the selected item.
245  *
246  * @param[in] khciHandle      Pointer of the device KHCI handle.
247  * @param[in] type             The selected item. See enumeration type usb_device_control_type_t.
248  * @param[in,out] param            The parameter type is determined by the selected item.
249  *
250  * @return A USB error code or kStatus_USB_Success.
251  */
252 usb_status_t USB_DeviceKhciControl(usb_device_controller_handle khciHandle,
253                                    usb_device_control_type_t type,
254                                    void *param);
255
256 /*! @} */
257
258 #if defined(__cplusplus)
259 }
260 #endif
261
262 /*! @} */
263
264 #endif /* __USB_DEVICE_KHCI_H__ */