2 * @brief Open Host Controller Interface
\r
5 * Copyright(C) NXP Semiconductors, 2012
\r
6 * All rights reserved.
\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
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
31 /** @ingroup Group_HCD
\r
32 * @defgroup Host_OHCI Open Host Controller Interface Driver
\r
36 #ifndef __LPC_OHCI_H__
\r
37 #define __LPC_OHCI_H__
\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
43 #ifdef __TEST__ // suppress static/inline for Testing purpose
\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
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
63 #define SCHEDULING_OVRERRUN_INTERRUPT NO
\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
70 #define OWNERSHIP_CHANGE_INTERRUPT NO
\r
72 #define FRAME_INTERVAL 0x2EDF /* Reset default value */
\r
73 #define HC_FMINTERVAL_DEFAULT ((((6 * (FRAME_INTERVAL - 210)) / 7) << 16) | FRAME_INTERVAL)
\r
75 #define PERIODIC_START 0x00002A27UL /* 10% off from FRAME_INTERVAL */
\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
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
93 #define TD_NoInterruptOnComplete (7)
\r
95 #define HC_REVISION 0x000000FFUL
\r
97 #define HC_FM_REMAIN 0x00003FFFUL /* Frame remaining */
\r
99 #define HC_FM_NUMBER 0x0000FFFFUL /* Frame Number */
\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
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
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
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
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
138 #define HC_RH_DESCRIPTORB_PortPowerControlMask 0xFFFF0000UL /* Port Power Control Mask */
\r
139 #define HC_RH_DESCRIPTORB_DeviceRemovable 0x0000FFFFUL /* Device Removable */
\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
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
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
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
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
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
184 /*---------- Word 2 ----------*/
\r
185 uint32_t TailP; // only 28 bits - 16B align
\r
187 /*---------- Word 3 ----------*/
\r
191 uint32_t Halted : 1;
\r
192 uint32_t ToggleCarry : 1;
\r
196 } HeadP;/* TODO remove this name */
\r
198 /*---------- Word 4 ----------*/
\r
199 uint32_t NextED;// only 28 bits - 16B align
\r
200 } ATTR_ALIGNED (16) HC_ED, *PHC_ED;
\r
202 typedef struct st_HCD_EndpointDescriptor { // 32 byte align
\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
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
216 } HCD_EndpointDescriptor, *PHCD_EndpointDescriptor;
\r
218 typedef struct st_HC_GTD { // 16 byte align
\r
219 /*---------- Word 1 ----------*/
\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
230 /*---------- Word 2 ----------*/
\r
231 __IO uint8_t *CurrentBufferPointer;
\r
233 /*---------- Word 3 ----------*/
\r
234 __IO uint32_t NextTD; // only 28 bits - 16B align
\r
236 /*---------- Word 4 ----------*/
\r
237 uint8_t *BufferEnd;
\r
238 } ATTR_ALIGNED (16) HC_GTD, *PHC_GTD; /* TODO merge into HCD_GeneralTransferDescriptor */
\r
240 typedef struct st_HCD_GeneralTransferDescriptor { // 32 byte align
\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
249 uint16_t TransferCount;
\r
251 uint32_t reserved2;
\r
252 uint32_t reserved3;
\r
253 } HCD_GeneralTransferDescriptor, *PHCD_GeneralTransferDescriptor;
\r
255 typedef struct st_HCD_IsoTransferDescriptor { // 64 byte align
\r
256 /*---------- Word 1 ----------*/
\r
257 uint32_t StartingFrame : 16;
\r
259 uint32_t DelayInterrupt : 3;
\r
260 uint32_t FrameCount : 3;
\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
266 /*---------- Word 2 ----------*/
\r
267 uint32_t BufferPage0; // only 20 bits - 4KB align
\r
269 /*---------- Word 3 ----------*/
\r
270 __IO uint32_t NextTD; // only 27 bits - 32B align
\r
272 /*---------- Word 4 ----------*/
\r
273 uint32_t BufferEnd;
\r
275 /*---------- Word 5-8 ----------*/
\r
276 __IO uint16_t OffsetPSW[8];
\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
284 /*---------- Word 10 ----------*/
\r
286 uint16_t reserved3;
\r
287 /*---------- End Word 10 ----------*/
\r
289 uint32_t reserved2[6];
\r
290 } ATTR_ALIGNED (32) HCD_IsoTransferDescriptor, *PHCD_IsoTransferDescriptor;
\r
292 typedef struct st_OHCI_HOST {
\r
294 uint32_t host_reserved1;
\r
295 #if ISO_LIST_ENABLE
\r
296 HCD_IsoTransferDescriptor iTDs[MAX_ITD];
\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
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
306 static INLINE HCD_STATUS OHciHostInit(uint8_t HostID);
\r
308 static INLINE HCD_STATUS OHciHostReset(uint8_t HostID);
\r
310 static INLINE HCD_STATUS OHciHostOperational(uint8_t HostID);
\r
312 #if 0 // just to clear warning
\r
313 static INLINE HCD_STATUS OHciHostSuspend(uint8_t HostID);
\r
315 static INLINE HCD_STATUS OHciRhPortPowerOn(uint8_t HostID, uint8_t uPortNumber);
\r
317 static INLINE HCD_STATUS OHciRhPortPowerOff(uint8_t HostID, uint8_t uPortNumber);
\r
319 static INLINE HCD_STATUS OHciRhPortSuspend(uint8_t HostID, uint8_t uPortNumber);
\r
321 static INLINE HCD_STATUS OHciRhPortResume(uint8_t HostID, uint8_t uPortNumber);
\r
323 static INLINE Bool IsInterruptEndpoint (uint8_t EdIdx);
\r
327 static INLINE uint32_t Align16 (uint32_t Value);
\r
329 static INLINE PHCD_EndpointDescriptor HcdED(uint8_t idx);
\r
331 static INLINE PHCD_GeneralTransferDescriptor HcdGTD(uint8_t idx);
\r
333 static INLINE PHCD_IsoTransferDescriptor HcdITD(uint8_t idx);
\r
335 static INLINE Bool IsIsoEndpoint(uint8_t EdIdx);
\r
337 static void PipehandleCreate(uint32_t *pPipeHandle, uint8_t HostID, uint8_t idx);
\r
339 static HCD_STATUS PipehandleParse(uint32_t Pipehandle, uint8_t *HostID, uint8_t *EdIdx);
\r
341 static INLINE void BuildPeriodicStaticEdTree(uint8_t HostID);
\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
352 static INLINE HCD_STATUS AllocGtdForEd(uint8_t EdIdx);
\r
354 static INLINE HCD_STATUS AllocItdForEd(uint8_t EdIdx);
\r
356 static INLINE HCD_STATUS FreeED(uint8_t EdIdx);
\r
358 static INLINE HCD_STATUS FreeGtd(PHCD_GeneralTransferDescriptor pGtd);
\r
360 static INLINE HCD_STATUS FreeItd(PHCD_IsoTransferDescriptor pItd);
\r
362 static INLINE HCD_STATUS InsertEndpoint(uint8_t HostID, uint32_t EdIdx, uint8_t ListIndex);
\r
364 static INLINE HCD_STATUS RemoveEndpoint(uint8_t HostID, uint32_t EdIdx);
\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
370 uint8_t DirectionPID,
\r
371 uint8_t DataToggle,
\r
374 static HCD_STATUS QueueGTDs (uint32_t EdIdx, uint8_t *dataBuff, uint32_t xferLen, uint8_t Direction);
\r
376 static HCD_STATUS WaitForTransferComplete(uint8_t EdIdx);
\r
378 #endif /*defined(__LPC_OHCI__)*/
\r