LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 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  */
31 
32 #ifndef __LPC_OHCI_H__
33 #define __LPC_OHCI_H__
34 
35 #ifndef __LPC_OHCI_C__ // TODO INCLUDE FROM OHCI.C
36  #error OHCI.h is private header and can only be included by OHCI.c, try to include HCD.h instead
37 #endif
38 
39 #ifdef __TEST__ // suppress static/inline for Testing purpose
40  #define static
41  #define inline
42 #endif
43 
44 #define MAX_ED HCD_MAX_ENDPOINT
45 #define MAX_GTD (MAX_ED + 3)
46 #define MAX_STATIC_ED 3 /* Serve as list head, fixed, not configurable */
47 
48 #if ISO_LIST_ENABLE
49  #define MAX_ITD 4
50 #else
51  #define MAX_ITD 0
52 #endif
53 
54 #define CONTROL_BULK_SERVICE_RATIO 3 /* Control Bulk transfer ratio 0 = 1:1 - 1 = 2:1 - 2 = 3:1 - 3 = 4:1 */
55 #define INTERRUPT_ROUTING 0 /* Host interrupt routing 0 = IRQ - 1 = SMI */
56 #define REMOTE_WAKEUP_CONNECTED NO /* Remote wakeup connected */
57 #define REMOTE_WAKEUP_ENABLE NO /* Remote wakeup enable */
58 
59 #define SCHEDULING_OVRERRUN_INTERRUPT NO
60 
61 #define SOF_INTERRUPT NO
62 #define RESUME_DETECT_INTERRUPT NO
63 #define UNRECOVERABLE_ERROR_INTERRUPT NO
64 #define FRAMENUMBER_OVERFLOW_INTERRUPT NO
65 
66 #define OWNERSHIP_CHANGE_INTERRUPT NO
67 
68 #define FRAME_INTERVAL 0x2EDF /* Reset default value */
69 #define HC_FMINTERVAL_DEFAULT ((((6 * (FRAME_INTERVAL - 210)) / 7) << 16) | FRAME_INTERVAL)
70 
71 #define PERIODIC_START 0x00002A27UL /* 10% off from FRAME_INTERVAL */
72 
73 #define PORT_POWER_SWITCHING NO
74 #define PER_PORT_POWER_SWITCHING NO
75 #define PER_PORT_OVER_CURRENT_REPORT NO
76 #define OVER_CURRENT_PROTECTION NO
77 
78 #define INTERRUPT_1ms_LIST_HEAD 0
79 #define INTERRUPT_2ms_LIST_HEAD 1
80 #define INTERRUPT_4ms_LIST_HEAD 3
81 #define INTERRUPT_8ms_LIST_HEAD 7
82 #define INTERRUPT_16ms_LIST_HEAD 15
83 #define INTERRUPT_32ms_LIST_HEAD 31
84 #define ISO_LIST_HEAD (MAX_STATIC_ED - 3)
85 #define CONTROL_LIST_HEAD (MAX_STATIC_ED - 2)
86 #define BULK_LIST_HEAD (MAX_STATIC_ED - 1)
87 #define TD_MAX_XFER_LENGTH 0x2000
88 
89 #define TD_NoInterruptOnComplete (7)
90 
91 #define HC_REVISION 0x000000FFUL
92 
93 #define HC_FM_REMAIN 0x00003FFFUL /* Frame remaining */
94 
95 #define HC_FM_NUMBER 0x0000FFFFUL /* Frame Number */
96 
97 #define HC_CONTROL_ControlBulkServiceRatio 0x00000003UL /* Control/Bulk ratio */
98 #define HC_CONTROL_PeriodListEnable 0x00000004UL /* Periodic List Enable */
99 #define HC_CONTROL_IsochronousEnable 0x00000008UL /* Isochronous Enable */
100 #define HC_CONTROL_ControlListEnable 0x00000010UL /* Control List Enable */
101 #define HC_CONTROL_BulkListEnable 0x00000020UL /* Bulk List Enable */
102 #define HC_CONTROL_HostControllerFunctionalState 0x000000C0UL /* Host Controller Functional State */
103 #define HC_CONTROL_InterruptRouting 0x00000100UL /* Interrupt Routing */
104 #define HC_CONTROL_RemoteWakeupConnected 0x00000200UL /* Remote Wakeup Connected */
105 #define HC_CONTROL_RemoteWakeupEnable 0x00000400UL /* Remote Wakeup Enable */
106 
107 #define HC_HOST_RESET 0x00000000UL /* Reset state */
108 #define HC_HOST_RESUME 0X00000001UL /* Resume state */
109 #define HC_HOST_OPERATIONAL 0x00000002UL /* Operational state */
110 #define HC_HOST_SUSPEND 0x00000003UL /* Suspend state */
111 
112 #define HC_COMMAND_STATUS_HostControllerReset 0x00000001UL /* Host Controller Reset */
113 #define HC_COMMAND_STATUS_ControlListFilled 0x00000002UL /* Control List Filled */
114 #define HC_COMMAND_STATUS_BulkListFilled 0x00000004UL /* Bulk List Filled */
115 
116 #define HC_INTERRUPT_SchedulingOverrun 0x00000001UL /* Scheduling Overrun */
117 #define HC_INTERRUPT_WritebackDoneHead 0x00000002UL /* Writeback DoneHead */
118 #define HC_INTERRUPT_StartofFrame 0x00000004UL /* Start of Frame */
119 #define HC_INTERRUPT_ResumeDetected 0x00000008UL /* Resume Detect */
120 #define HC_INTERRUPT_UnrecoverableError 0x00000010UL /* Unrecoverable error */
121 #define HC_INTERRUPT_FrameNumberOverflow 0x00000020UL /* Frame Number Overflow */
122 #define HC_INTERRUPT_RootHubStatusChange 0x00000040UL /* Root Hub Status Change */
123 #define HC_INTERRUPT_OwnershipChange 0x40000000UL /* Ownership Change */
124 #define HC_INTERRUPT_MasterInterruptEnable 0x80000000UL /* Master Interrupt Enable */
125 #define HC_INTERRUPT_ALL 0xC000007FUL /* All interrupts */
126 
127 #define HC_RH_DESCRIPTORA_NumberDownstreamPorts 0x000000FFUL /* Number of downstream ports */
128 #define HC_RH_DESCRIPTORA_PowerSwitchingMode 0x00000100UL /* Power Switching Mode */
129 #define HC_RH_DESCRIPTORA_NoPowerSwitching 0x00000200UL /* No Power Switching */
130 #define HC_RH_DESCRIPTORA_OverCurrentProtectionMode 0x00000800UL /* OverCurrent Protection Mode */
131 #define HC_RH_DESCRIPTORA_NoOverCurrentProtection 0x00001000UL /* No OverCurrent Protection */
132 #define HC_RH_DESCRIPTORA_PowerOnToPowerGoodTime 0xFF000000UL /* Power On To Power Good Time */
133 
134 #define HC_RH_DESCRIPTORB_PortPowerControlMask 0xFFFF0000UL /* Port Power Control Mask */
135 #define HC_RH_DESCRIPTORB_DeviceRemovable 0x0000FFFFUL /* Device Removable */
136 
137 #define HC_RH_STATUS_LocalPowerStatus 0x00000001UL /* R: Local Power Status - W: Clear Global Power */
138 #define HC_RH_STATUS_LocalPowerStatusChange 0x00010000UL /* R: Local Power Status Change - W: Set Global Power */
139 #define HC_RH_STATUS_DeviceRemoteWakeupEnable 0x00008000UL /* W: Set Remote Wakeup Enable */
140 
141 #define HC_RH_PORT_STATUS_CurrentConnectStatus 0x00000001UL /* R: Current Connect Status - W: Clear Port Enable */
142 #define HC_RH_PORT_STATUS_PowerEnableStatus 0x00000002UL /* R: Port Enable Status - W: Set Port Enable */
143 #define HC_RH_PORT_STATUS_PortSuspendStatus 0x00000004UL /* R: Port Suspend Status - W: Set Port Suspend */
144 #define HC_RH_PORT_STATUS_PortOverCurrentIndicator 0x00000008UL /* R: Port OverCurrent Indicator- W: Clear Suspend Status */
145 #define HC_RH_PORT_STATUS_PortResetStatus 0x00000010UL /* R: Port Reset Status - W: Set Port Reset */
146 #define HC_RH_PORT_STATUS_PortPowerStatus 0x00000100UL /* R: Port Power Status - W: Set Port Power */
147 #define HC_RH_PORT_STATUS_LowSpeedDeviceAttached 0x00000200UL /* R: Low Speed Device Attached - W: Clear Port Power */
148 
149 #define HC_RH_PORT_STATUS_ConnectStatusChange 0x00010000UL /* Connect Status Change */
150 #define HC_RH_PORT_STATUS_PortEnableStatusChange 0x00020000UL /* Port Enable Status Change */
151 #define HC_RH_PORT_STATUS_PortSuspendStatusChange 0x00040000UL /* Port Suspend Status Change */
152 #define HC_RH_PORT_STATUS_OverCurrentIndicatorChange 0x00080000UL /* OverCurrent Indicator Change */
153 #define HC_RH_PORT_STATUS_PortResetStatusChange 0x00100000UL /* Port Reset Status Change */
154 
155 typedef struct st_HC_HCCA {
157  __I uint16_t HccaFrameNumber;
158  __I uint16_t HccaPad1;
160  __I uint8_t HccaReserved[116];
161 } ATTR_ALIGNED (256) HC_HCCA;
163 typedef struct st_HC_ED { // 16 byte align
164  /*---------- Word 1 ----------*/
172  uint32_t : 0;/* Force next member on next storage unit */
173  /*---------- End Word 1 ----------*/
174 
175  /*---------- Word 2 ----------*/
176  uint32_t TailP; // only 28 bits - 16B align
177 
178  /*---------- Word 3 ----------*/
179  union {
181  __IO struct {
184  uint32_t : 30;
185  };
186 
187  } HeadP;/* TODO remove this name */
188 
189  /*---------- Word 4 ----------*/
190  uint32_t NextED;// only 28 bits - 16B align
191 } ATTR_ALIGNED (16) HC_ED, *PHC_ED;
192 
193 typedef struct st_HCD_EndpointDescriptor { // 32 byte align
194  HC_ED hcED;
196  /*---------- Word 1 ----------*/
198  uint32_t ListIndex : 7; // 0: Interrupt/ISO, 1: Control, 2: bulk
199  uint32_t Interval : 8; /* Used by ISO, High speed Bulk/Control maximum NAK */
200  uint32_t : 0; /* Force next member on next storage unit */
201  /*---------- End Word 1 ----------*/
202 
203  __IO uint32_t status; // TODO status is updated by ISR --> is non-caching
204  uint16_t *pActualTransferCount; /* total transferred bytes of a usb request */
205 
207 } HCD_EndpointDescriptor, *PHCD_EndpointDescriptor;
209 typedef struct st_HC_GTD { // 16 byte align
210  /*---------- Word 1 ----------*/
211  uint32_t : 18;
218  uint32_t : 0; /* Force next member on next storage unit */
219  /*---------- End Word 1 ----------*/
220 
221  /*---------- Word 2 ----------*/
222  __IO uint8_t *CurrentBufferPointer;
223 
224  /*---------- Word 3 ----------*/
225  __IO uint32_t NextTD; // only 28 bits - 16B align
226 
227  /*---------- Word 4 ----------*/
228  uint8_t *BufferEnd;
229 } ATTR_ALIGNED (16) HC_GTD, *PHC_GTD; /* TODO merge into HCD_GeneralTransferDescriptor */
230 
231 typedef struct st_HCD_GeneralTransferDescriptor { // 32 byte align
232  HC_GTD hcGTD;
234  /*---------- Word 1 ----------*/
236  uint32_t : 0; /* Force next member on next storage unit */
237  /*---------- End Word 1 ----------*/
238 
239  uint16_t EdIdx;
240  uint16_t TransferCount;
241 
244 } HCD_GeneralTransferDescriptor, *PHCD_GeneralTransferDescriptor;
246 typedef struct st_HCD_IsoTransferDescriptor { // 64 byte align
247  /*---------- Word 1 ----------*/
249  uint32_t : 5;
252  uint32_t : 1;
254  uint32_t : 0; /* Force next member on next storage unit */
255  /*---------- End Word 1 ----------*/
256 
257  /*---------- Word 2 ----------*/
258  uint32_t BufferPage0; // only 20 bits - 4KB align
259 
260  /*---------- Word 3 ----------*/
261  __IO uint32_t NextTD; // only 27 bits - 32B align
262 
263  /*---------- Word 4 ----------*/
265 
266  /*---------- Word 5-8 ----------*/
267  __IO uint16_t OffsetPSW[8];
268 
269  /*---------- HCD AREA ----------*/
270  /*---------- Word 9 ----------*/
272  uint32_t : 0; /* Force next member on next storage unit */
273  /*---------- End Word 9 ----------*/
274 
275  /*---------- Word 10 ----------*/
276  uint16_t EdIdx;
277  uint16_t reserved3;
278  /*---------- End Word 10 ----------*/
279 
281 } ATTR_ALIGNED (32) HCD_IsoTransferDescriptor, *PHCD_IsoTransferDescriptor;
282 
283 typedef struct st_OHCI_HOST {
284  HC_HCCA hcca;
285 #if ISO_LIST_ENABLE
286  HCD_IsoTransferDescriptor iTDs[MAX_ITD];
287 #endif
290  HC_ED staticEDs[MAX_STATIC_ED];
292 
293 #define OHCI_REG(x) LPC_USB
294 // #define OHCI_DATA(HostID) ((OHCI_HOST_DATA_Type*) HCD_RAM_ADDR_BASE)
295 extern OHCI_HOST_DATA_Type ohci_data[MAX_USB_CORE];
296 
297 static INLINE HCD_STATUS OHciHostInit(uint8_t HostID);
298 
299 static INLINE HCD_STATUS OHciHostReset(uint8_t HostID);
300 
301 static INLINE HCD_STATUS OHciHostSuspend(uint8_t HostID);
303 static INLINE HCD_STATUS OHciHostOperational(uint8_t HostID);
304 
305 static INLINE HCD_STATUS OHciRhPortPowerOn(uint8_t HostID, uint8_t uPortNumber);
307 static INLINE HCD_STATUS OHciRhPortPowerOff(uint8_t HostID, uint8_t uPortNumber);
308 
309 static INLINE HCD_STATUS OHciRhPortSuspend(uint8_t HostID, uint8_t uPortNumber);
310 
311 static INLINE HCD_STATUS OHciRhPortResume(uint8_t HostID, uint8_t uPortNumber);
313 static INLINE uint32_t Align16 (uint32_t Value);
314 
315 static INLINE PHCD_EndpointDescriptor HcdED(uint8_t idx);
316 
317 static INLINE PHCD_GeneralTransferDescriptor HcdGTD(uint8_t idx);
318 
319 static INLINE PHCD_IsoTransferDescriptor HcdITD(uint8_t idx);
320 
321 static INLINE Bool IsIsoEndpoint(uint8_t EdIdx);
322 
323 static INLINE Bool IsInterruptEndpoint (uint8_t EdIdx);
324 
325 static void PipehandleCreate(uint32_t *pPipeHandle, uint8_t HostID, uint8_t idx);
326 
327 static HCD_STATUS PipehandleParse(uint32_t Pipehandle, uint8_t *HostID, uint8_t *EdIdx);
328 
329 static INLINE void BuildPeriodicStaticEdTree(uint8_t HostID);
330 
331 static INLINE HCD_STATUS AllocEd(uint8_t DeviceAddr,
332  HCD_USB_SPEED DeviceSpeed,
333  uint8_t EndpointNumber,
334  HCD_TRANSFER_TYPE TransferType,
335  HCD_TRANSFER_DIR TransferDir,
336  uint16_t MaxPacketSize,
337  uint8_t Interval,
338  uint32_t *pEdIdx);
339 
340 static INLINE HCD_STATUS AllocGtdForEd(uint8_t EdIdx);
341 
342 static INLINE HCD_STATUS AllocItdForEd(uint8_t EdIdx);
343 
344 static INLINE HCD_STATUS FreeED(uint8_t EdIdx);
345 
346 static INLINE HCD_STATUS FreeGtd(PHCD_GeneralTransferDescriptor pGtd);
347 
349 
350 static INLINE HCD_STATUS InsertEndpoint(uint8_t HostID, uint32_t EdIdx, uint8_t ListIndex);
351 
352 static INLINE HCD_STATUS RemoveEndpoint(uint8_t HostID, uint32_t EdIdx);
353 
354 /*static INLINE uint8_t FindInterruptTransferListIndex(uint8_t HostID, uint8_t Interval);*/
356  uint8_t *const CurrentBufferPointer,
357  uint32_t xferLen,
358  uint8_t DirectionPID,
359  uint8_t DataToggle,
360  uint8_t IOC);
361 
362 static HCD_STATUS QueueGTDs (uint32_t EdIdx, uint8_t *dataBuff, uint32_t xferLen, uint8_t Direction);
363 
365 
366 #endif /*defined(__LPC_OHCI__)*/