]> git.sur5r.net Git - freertos/blob
8c906e2a9d35b651b118d5c06cb57d2c32ee3f37
[freertos] /
1 /*\r
2  * @brief Open Host Controller Interface\r
3  *\r
4  * @note\r
5  * Copyright(C) NXP Semiconductors, 2012\r
6  * All rights reserved.\r
7  *\r
8  * @par\r
9  * Software that is described herein is for illustrative purposes only\r
10  * which provides customers with programming information regarding the\r
11  * LPC products.  This software is supplied "AS IS" without any warranties of\r
12  * any kind, and NXP Semiconductors and its licensor disclaim any and\r
13  * all warranties, express or implied, including all implied warranties of\r
14  * merchantability, fitness for a particular purpose and non-infringement of\r
15  * intellectual property rights.  NXP Semiconductors assumes no responsibility\r
16  * or liability for the use of the software, conveys no license or rights under any\r
17  * patent, copyright, mask work right, or any other intellectual property rights in\r
18  * or to any products. NXP Semiconductors reserves the right to make changes\r
19  * in the software without notification. NXP Semiconductors also makes no\r
20  * representation or warranty that such application will be suitable for the\r
21  * specified use without further testing or modification.\r
22  *\r
23  * @par\r
24  * Permission to use, copy, modify, and distribute this software and its\r
25  * documentation is hereby granted, under NXP Semiconductors' and its\r
26  * licensor's relevant copyrights in the software, without fee, provided that it\r
27  * is used in conjunction with NXP Semiconductors microcontrollers.  This\r
28  * copyright, permission, and disclaimer notice must appear in all copies of\r
29  * this code.\r
30  */\r
31 /** @ingroup Group_HCD\r
32  *  @defgroup Host_OHCI Open Host Controller Interface Driver\r
33  *  @{\r
34  */\r
35  \r
36 #ifndef __LPC_OHCI_H__\r
37 #define __LPC_OHCI_H__\r
38 \r
39 #ifndef __LPC_OHCI_C__  // TODO INCLUDE FROM OHCI.C\r
40         #error OHCI.h is private header and can only be included by OHCI.c, try to include HCD.h instead\r
41 #endif\r
42 \r
43 #ifdef __TEST__ // suppress static/inline for Testing purpose\r
44         #define static\r
45         #define inline\r
46 #endif\r
47 \r
48 #define MAX_ED                              HCD_MAX_ENDPOINT\r
49 #define MAX_GTD                             (MAX_ED + 3)\r
50 #define MAX_STATIC_ED                       3   /* Serve as list head, fixed, not configurable */\r
51 \r
52 #if ISO_LIST_ENABLE\r
53         #define MAX_ITD                             4\r
54 #else\r
55         #define MAX_ITD                             0\r
56 #endif\r
57 \r
58 #define CONTROL_BULK_SERVICE_RATIO          3                   /* Control Bulk transfer ratio 0 = 1:1 - 1 = 2:1 - 2 = 3:1 - 3 = 4:1 */\r
59 #define INTERRUPT_ROUTING                   0                   /* Host interrupt routing 0 = IRQ - 1 = SMI */\r
60 #define REMOTE_WAKEUP_CONNECTED             NO          /* Remote wakeup connected */\r
61 #define REMOTE_WAKEUP_ENABLE                NO          /* Remote wakeup enable    */\r
62 \r
63 #define SCHEDULING_OVRERRUN_INTERRUPT       NO\r
64 \r
65 #define SOF_INTERRUPT                       NO\r
66 #define RESUME_DETECT_INTERRUPT             NO\r
67 #define UNRECOVERABLE_ERROR_INTERRUPT       NO\r
68 #define FRAMENUMBER_OVERFLOW_INTERRUPT      NO\r
69 \r
70 #define OWNERSHIP_CHANGE_INTERRUPT          NO\r
71 \r
72 #define FRAME_INTERVAL                      0x2EDF              /* Reset default value */\r
73 #define HC_FMINTERVAL_DEFAULT               ((((6 * (FRAME_INTERVAL - 210)) / 7) << 16) | FRAME_INTERVAL)\r
74 \r
75 #define PERIODIC_START                      0x00002A27UL                /* 10% off from FRAME_INTERVAL */\r
76 \r
77 #define PORT_POWER_SWITCHING                NO\r
78 #define PER_PORT_POWER_SWITCHING            NO\r
79 #define PER_PORT_OVER_CURRENT_REPORT        NO\r
80 #define OVER_CURRENT_PROTECTION             NO\r
81 \r
82 #define INTERRUPT_1ms_LIST_HEAD     0\r
83 #define INTERRUPT_2ms_LIST_HEAD     1\r
84 #define INTERRUPT_4ms_LIST_HEAD     3\r
85 #define INTERRUPT_8ms_LIST_HEAD     7\r
86 #define INTERRUPT_16ms_LIST_HEAD    15\r
87 #define INTERRUPT_32ms_LIST_HEAD    31\r
88 #define ISO_LIST_HEAD               (MAX_STATIC_ED - 3)\r
89 #define CONTROL_LIST_HEAD           (MAX_STATIC_ED - 2)\r
90 #define BULK_LIST_HEAD              (MAX_STATIC_ED - 1)\r
91 #define TD_MAX_XFER_LENGTH          0x2000\r
92 \r
93 #define TD_NoInterruptOnComplete    (7)\r
94 \r
95 #define HC_REVISION                                     0x000000FFUL\r
96 \r
97 #define HC_FM_REMAIN                                    0x00003FFFUL            /* Frame remaining                              */\r
98 \r
99 #define HC_FM_NUMBER                                    0x0000FFFFUL            /* Frame Number                                 */\r
100 \r
101 #define HC_CONTROL_ControlBulkServiceRatio              0x00000003UL            /* Control/Bulk ratio                   */\r
102 #define HC_CONTROL_PeriodListEnable                     0x00000004UL            /* Periodic List Enable                 */\r
103 #define HC_CONTROL_IsochronousEnable                    0x00000008UL            /* Isochronous Enable                   */\r
104 #define HC_CONTROL_ControlListEnable                    0x00000010UL            /* Control List Enable                  */\r
105 #define HC_CONTROL_BulkListEnable                       0x00000020UL            /* Bulk List Enable                             */\r
106 #define HC_CONTROL_HostControllerFunctionalState        0x000000C0UL            /* Host Controller Functional State */\r
107 #define HC_CONTROL_InterruptRouting                     0x00000100UL            /* Interrupt Routing                    */\r
108 #define HC_CONTROL_RemoteWakeupConnected                0x00000200UL            /* Remote Wakeup Connected              */\r
109 #define HC_CONTROL_RemoteWakeupEnable                   0x00000400UL            /* Remote Wakeup Enable                 */\r
110 \r
111 #define HC_HOST_RESET                                   0x00000000UL            /* Reset state                                  */\r
112 #define HC_HOST_RESUME                                  0X00000001UL            /* Resume state                                 */\r
113 #define HC_HOST_OPERATIONAL                             0x00000002UL            /* Operational state                    */\r
114 #define HC_HOST_SUSPEND                                 0x00000003UL            /* Suspend state                                */\r
115 \r
116 #define HC_COMMAND_STATUS_HostControllerReset           0x00000001UL            /* Host Controller Reset                */\r
117 #define HC_COMMAND_STATUS_ControlListFilled             0x00000002UL            /* Control List Filled                  */\r
118 #define HC_COMMAND_STATUS_BulkListFilled                0x00000004UL            /* Bulk List Filled                             */\r
119 \r
120 #define HC_INTERRUPT_SchedulingOverrun                  0x00000001UL            /* Scheduling Overrun                   */\r
121 #define HC_INTERRUPT_WritebackDoneHead                  0x00000002UL            /* Writeback DoneHead                   */\r
122 #define HC_INTERRUPT_StartofFrame                       0x00000004UL            /* Start of Frame                               */\r
123 #define HC_INTERRUPT_ResumeDetected                     0x00000008UL            /* Resume Detect                                */\r
124 #define HC_INTERRUPT_UnrecoverableError                 0x00000010UL            /* Unrecoverable error                  */\r
125 #define HC_INTERRUPT_FrameNumberOverflow                0x00000020UL            /* Frame Number Overflow                */\r
126 #define HC_INTERRUPT_RootHubStatusChange                0x00000040UL            /* Root Hub Status Change               */\r
127 #define HC_INTERRUPT_OwnershipChange                    0x40000000UL            /* Ownership Change                             */\r
128 #define HC_INTERRUPT_MasterInterruptEnable              0x80000000UL            /* Master Interrupt Enable              */\r
129 #define HC_INTERRUPT_ALL                                0xC000007FUL            /* All interrupts                               */\r
130 \r
131 #define HC_RH_DESCRIPTORA_NumberDownstreamPorts         0x000000FFUL            /* Number of downstream ports  */\r
132 #define HC_RH_DESCRIPTORA_PowerSwitchingMode            0x00000100UL            /* Power Switching Mode        */\r
133 #define HC_RH_DESCRIPTORA_NoPowerSwitching              0x00000200UL            /* No Power Switching          */\r
134 #define HC_RH_DESCRIPTORA_OverCurrentProtectionMode     0x00000800UL            /* OverCurrent Protection Mode */\r
135 #define HC_RH_DESCRIPTORA_NoOverCurrentProtection       0x00001000UL            /* No OverCurrent Protection   */\r
136 #define HC_RH_DESCRIPTORA_PowerOnToPowerGoodTime        0xFF000000UL            /* Power On To Power Good Time */\r
137 \r
138 #define HC_RH_DESCRIPTORB_PortPowerControlMask          0xFFFF0000UL            /* Port Power Control Mask     */\r
139 #define HC_RH_DESCRIPTORB_DeviceRemovable               0x0000FFFFUL            /* Device Removable            */\r
140 \r
141 #define HC_RH_STATUS_LocalPowerStatus                   0x00000001UL            /* R: Local Power Status                - W: Clear Global Power         */\r
142 #define HC_RH_STATUS_LocalPowerStatusChange             0x00010000UL            /* R: Local Power Status Change - W: Set Global Power           */\r
143 #define HC_RH_STATUS_DeviceRemoteWakeupEnable           0x00008000UL            /* W: Set Remote Wakeup Enable */\r
144 \r
145 #define HC_RH_PORT_STATUS_CurrentConnectStatus          0x00000001UL            /* R: Current Connect Status    - W: Clear Port Enable      */\r
146 #define HC_RH_PORT_STATUS_PowerEnableStatus             0x00000002UL            /* R: Port Enable Status                - W: Set Port Enable        */\r
147 #define HC_RH_PORT_STATUS_PortSuspendStatus             0x00000004UL            /* R: Port Suspend Status               - W: Set Port Suspend       */\r
148 #define HC_RH_PORT_STATUS_PortOverCurrentIndicator      0x00000008UL            /* R: Port OverCurrent Indicator- W: Clear Suspend Status       */\r
149 #define HC_RH_PORT_STATUS_PortResetStatus               0x00000010UL            /* R: Port Reset  Status                - W: Set Port Reset         */\r
150 #define HC_RH_PORT_STATUS_PortPowerStatus               0x00000100UL            /* R: Port Power Status                 - W: Set Port Power         */\r
151 #define HC_RH_PORT_STATUS_LowSpeedDeviceAttached        0x00000200UL            /* R: Low Speed Device Attached - W: Clear Port Power       */\r
152 \r
153 #define HC_RH_PORT_STATUS_ConnectStatusChange           0x00010000UL            /* Connect Status Change        */\r
154 #define HC_RH_PORT_STATUS_PortEnableStatusChange        0x00020000UL            /* Port Enable Status Change    */\r
155 #define HC_RH_PORT_STATUS_PortSuspendStatusChange       0x00040000UL            /* Port Suspend Status Change   */\r
156 #define HC_RH_PORT_STATUS_OverCurrentIndicatorChange    0x00080000UL            /* OverCurrent Indicator Change */\r
157 #define HC_RH_PORT_STATUS_PortResetStatusChange         0x00100000UL            /* Port Reset Status Change     */\r
158 #define HC_RH_PORT_STATUS_StatusChangeMask                                                      (HC_RH_PORT_STATUS_ConnectStatusChange | \\r
159                                                                                                                                                                                                                                         HC_RH_PORT_STATUS_PortEnableStatusChange | \\r
160                                                                                                                                                                                                                                         HC_RH_PORT_STATUS_PortSuspendStatusChange | \\r
161                                                                                                                                                                                                                                         HC_RH_PORT_STATUS_OverCurrentIndicatorChange | \\r
162                                                                                                                                                                                                                                         HC_RH_PORT_STATUS_PortResetStatusChange)\r
163 \r
164 typedef struct st_HC_HCCA {\r
165         __O  uint32_t HccaIntTable[32];\r
166         __I  uint16_t HccaFrameNumber;\r
167         __I  uint16_t HccaPad1;\r
168         __I  uint32_t HccaDoneHead;\r
169         __I  uint8_t  HccaReserved[116];\r
170 } ATTR_ALIGNED (256) HC_HCCA;\r
171 \r
172 typedef struct st_HC_ED {       // 16 byte align\r
173         /*---------- Word 1 ----------*/\r
174         uint32_t FunctionAddr   : 7;\r
175         uint32_t EndpointNumber : 4;\r
176         uint32_t Direction      : 2;\r
177         uint32_t Speed          : 1;\r
178         uint32_t Skip           : 1;\r
179         uint32_t Format         : 1;\r
180         uint32_t MaxPackageSize : 11;\r
181         uint32_t                : 0;/* Force next member on next storage unit */\r
182         /*---------- End Word 1 ----------*/\r
183 \r
184         /*---------- Word 2 ----------*/\r
185         uint32_t TailP; // only 28 bits - 16B align\r
186 \r
187         /*---------- Word 3 ----------*/\r
188         union {\r
189                  uint32_t HeadTD;\r
190                  struct {\r
191                         uint32_t Halted         : 1;\r
192                         uint32_t ToggleCarry    : 1;\r
193                         uint32_t                : 30;\r
194                 };\r
195 \r
196         } HeadP;/* TODO remove this name */\r
197 \r
198         /*---------- Word 4 ----------*/\r
199         uint32_t NextED;// only 28 bits - 16B align\r
200 } ATTR_ALIGNED (16) HC_ED, *PHC_ED;\r
201 \r
202 typedef struct st_HCD_EndpointDescriptor {      // 32 byte align\r
203         HC_ED hcED;\r
204 \r
205         /*---------- Word 1 ----------*/\r
206         uint32_t inUse          : 1;\r
207         uint32_t ListIndex      : 7;    // 0: Interrupt/ISO, 1: Control, 2: bulk\r
208         uint32_t Interval       : 8;    /* Used by ISO, High speed Bulk/Control maximum NAK */\r
209         uint32_t                : 0;    /* Force next member on next storage unit */\r
210         /*---------- End Word 1 ----------*/\r
211 \r
212         __IO uint32_t status;                   // TODO status is updated by ISR --> is non-caching\r
213         uint16_t *pActualTransferCount; /* total transferred bytes of a usb request */\r
214 \r
215         uint32_t reserved;\r
216 } HCD_EndpointDescriptor, *PHCD_EndpointDescriptor;\r
217 \r
218 typedef struct st_HC_GTD {      // 16 byte align\r
219         /*---------- Word 1 ----------*/\r
220         uint32_t               : 18;\r
221         uint32_t BufferRounding : 1;\r
222         uint32_t DirectionPID  : 2;\r
223         uint32_t DelayInterrupt : 3;\r
224         __IO uint32_t DataToggle    : 2;\r
225         __IO uint32_t ErrorCount    : 2;\r
226         __IO uint32_t ConditionCode : 4;\r
227         uint32_t               : 0;                     /* Force next member on next storage unit */\r
228         /*---------- End Word 1 ----------*/\r
229 \r
230         /*---------- Word 2 ----------*/\r
231         __IO uint8_t *CurrentBufferPointer;\r
232 \r
233         /*---------- Word 3 ----------*/\r
234         __IO uint32_t NextTD;   // only 28 bits - 16B align\r
235 \r
236         /*---------- Word 4 ----------*/\r
237         uint8_t *BufferEnd;\r
238 } ATTR_ALIGNED (16) HC_GTD, *PHC_GTD;   /* TODO merge into HCD_GeneralTransferDescriptor */\r
239 \r
240 typedef struct st_HCD_GeneralTransferDescriptor {       // 32 byte align\r
241         HC_GTD hcGTD;\r
242 \r
243         /*---------- Word 1 ----------*/\r
244         uint32_t inUse      : 1;\r
245         uint32_t            : 0;        /* Force next member on next storage unit */\r
246         /*---------- End Word 1 ----------*/\r
247 \r
248         uint16_t EdIdx;\r
249         uint16_t TransferCount;\r
250 \r
251         uint32_t reserved2;\r
252         uint32_t reserved3;\r
253 } HCD_GeneralTransferDescriptor, *PHCD_GeneralTransferDescriptor;\r
254 \r
255 typedef struct st_HCD_IsoTransferDescriptor {   // 64 byte align\r
256         /*---------- Word 1 ----------*/\r
257         uint32_t StartingFrame : 16;\r
258         uint32_t               : 5;\r
259         uint32_t DelayInterrupt : 3;\r
260         uint32_t FrameCount    : 3;\r
261         uint32_t               : 1;\r
262         __IO uint32_t ConditionCode : 4;\r
263         uint32_t               : 0;                     /* Force next member on next storage unit */\r
264         /*---------- End Word 1 ----------*/\r
265 \r
266         /*---------- Word 2 ----------*/\r
267         uint32_t BufferPage0;   // only 20 bits - 4KB align\r
268 \r
269         /*---------- Word 3 ----------*/\r
270         __IO uint32_t NextTD;   // only 27 bits - 32B align\r
271 \r
272         /*---------- Word 4 ----------*/\r
273         uint32_t BufferEnd;\r
274 \r
275         /*---------- Word 5-8 ----------*/\r
276         __IO uint16_t OffsetPSW[8];\r
277 \r
278         /*---------- HCD AREA ----------*/\r
279         /*---------- Word 9 ----------*/\r
280         uint32_t inUse      : 1;\r
281         uint32_t            : 0;        /* Force next member on next storage unit */\r
282         /*---------- End Word 9 ----------*/\r
283 \r
284         /*---------- Word 10 ----------*/\r
285         uint16_t EdIdx;\r
286         uint16_t reserved3;\r
287         /*---------- End Word 10 ----------*/\r
288 \r
289         uint32_t reserved2[6];\r
290 } ATTR_ALIGNED (32)  HCD_IsoTransferDescriptor, *PHCD_IsoTransferDescriptor;\r
291 \r
292 typedef struct st_OHCI_HOST {\r
293         HC_HCCA hcca;\r
294         uint32_t host_reserved1;\r
295 #if ISO_LIST_ENABLE\r
296         HCD_IsoTransferDescriptor       iTDs[MAX_ITD];\r
297 #endif\r
298         HCD_GeneralTransferDescriptor   gTDs[MAX_GTD];\r
299         HCD_EndpointDescriptor          EDs[MAX_ED];\r
300         HC_ED                           staticEDs[MAX_STATIC_ED];\r
301 } OHCI_HOST_DATA_T;\r
302 \r
303 // #define OHCI_DATA(HostID)    ((OHCI_HOST_DATA_T*) HCD_RAM_ADDR_BASE)\r
304 extern OHCI_HOST_DATA_T ohci_data[MAX_USB_CORE];\r
305 \r
306 static INLINE HCD_STATUS OHciHostInit(uint8_t HostID);\r
307 \r
308 static INLINE HCD_STATUS OHciHostReset(uint8_t HostID);\r
309 \r
310 static INLINE HCD_STATUS OHciHostOperational(uint8_t HostID);\r
311 \r
312 #if 0   // just to clear warning\r
313 static INLINE HCD_STATUS OHciHostSuspend(uint8_t HostID);\r
314 \r
315 static INLINE HCD_STATUS OHciRhPortPowerOn(uint8_t HostID, uint8_t uPortNumber);\r
316 \r
317 static INLINE HCD_STATUS OHciRhPortPowerOff(uint8_t HostID, uint8_t uPortNumber);\r
318 \r
319 static INLINE HCD_STATUS OHciRhPortSuspend(uint8_t HostID, uint8_t uPortNumber);\r
320 \r
321 static INLINE HCD_STATUS OHciRhPortResume(uint8_t HostID, uint8_t uPortNumber);\r
322 \r
323 static INLINE Bool IsInterruptEndpoint (uint8_t EdIdx);\r
324 \r
325 #endif\r
326 \r
327 static INLINE uint32_t Align16 (uint32_t Value);\r
328 \r
329 static INLINE PHCD_EndpointDescriptor HcdED(uint8_t idx);\r
330 \r
331 static INLINE PHCD_GeneralTransferDescriptor HcdGTD(uint8_t idx);\r
332 \r
333 static INLINE PHCD_IsoTransferDescriptor HcdITD(uint8_t idx);\r
334 \r
335 static INLINE Bool IsIsoEndpoint(uint8_t EdIdx);\r
336 \r
337 static void PipehandleCreate(uint32_t *pPipeHandle, uint8_t HostID, uint8_t idx);\r
338 \r
339 static HCD_STATUS PipehandleParse(uint32_t Pipehandle, uint8_t *HostID, uint8_t *EdIdx);\r
340 \r
341 static INLINE void BuildPeriodicStaticEdTree(uint8_t HostID);\r
342 \r
343 static INLINE HCD_STATUS AllocEd(uint8_t DeviceAddr,\r
344                                                                    HCD_USB_SPEED DeviceSpeed,\r
345                                                                    uint8_t EndpointNumber,\r
346                                                                    HCD_TRANSFER_TYPE TransferType,\r
347                                                                    HCD_TRANSFER_DIR TransferDir,\r
348                                                                    uint16_t MaxPacketSize,\r
349                                                                    uint8_t Interval,\r
350                                                                    uint32_t *pEdIdx);\r
351 \r
352 static INLINE HCD_STATUS AllocGtdForEd(uint8_t EdIdx);\r
353 \r
354 static INLINE HCD_STATUS AllocItdForEd(uint8_t EdIdx);\r
355 \r
356 static INLINE HCD_STATUS FreeED(uint8_t EdIdx);\r
357 \r
358 static INLINE HCD_STATUS FreeGtd(PHCD_GeneralTransferDescriptor pGtd);\r
359 \r
360 static INLINE HCD_STATUS FreeItd(PHCD_IsoTransferDescriptor pItd);\r
361 \r
362 static INLINE HCD_STATUS InsertEndpoint(uint8_t HostID, uint32_t EdIdx, uint8_t ListIndex);\r
363 \r
364 static INLINE HCD_STATUS RemoveEndpoint(uint8_t HostID, uint32_t EdIdx);\r
365 \r
366 /*static INLINE uint8_t FindInterruptTransferListIndex(uint8_t HostID, uint8_t Interval);*/\r
367 static HCD_STATUS QueueOneGTD (uint32_t EdIdx,\r
368                                                            uint8_t *const CurrentBufferPointer,\r
369                                                            uint32_t xferLen,\r
370                                                            uint8_t DirectionPID,\r
371                                                            uint8_t DataToggle,\r
372                                                            uint8_t IOC);\r
373 \r
374 static HCD_STATUS QueueGTDs (uint32_t EdIdx, uint8_t *dataBuff, uint32_t xferLen, uint8_t Direction);\r
375 \r
376 static HCD_STATUS WaitForTransferComplete(uint8_t EdIdx);\r
377 \r
378 #endif /*defined(__LPC_OHCI__)*/\r
379 \r
380 /** @} */\r