| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

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