LPCOpen Platform  v1.03
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  */
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 {
166  __I uint16_t HccaFrameNumber;
167  __I uint16_t HccaPad1;
169  __I uint8_t HccaReserved[116];
170 } ATTR_ALIGNED (256) HC_HCCA;
172 typedef struct st_HC_ED { // 16 byte align
173  /*---------- Word 1 ----------*/
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 {
190  struct {
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;
205  /*---------- Word 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 
216 } HCD_EndpointDescriptor, *PHCD_EndpointDescriptor;
218 typedef struct st_HC_GTD { // 16 byte align
219  /*---------- Word 1 ----------*/
220  uint32_t : 18;
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;
243  /*---------- Word 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 
253 } HCD_GeneralTransferDescriptor, *PHCD_GeneralTransferDescriptor;
255 typedef struct st_HCD_IsoTransferDescriptor { // 64 byte align
256  /*---------- Word 1 ----------*/
258  uint32_t : 5;
261  uint32_t : 1;
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 ----------*/
274 
275  /*---------- Word 5-8 ----------*/
276  __IO uint16_t OffsetPSW[8];
277 
278  /*---------- HCD AREA ----------*/
279  /*---------- Word 9 ----------*/
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 
290 } ATTR_ALIGNED (32) HCD_IsoTransferDescriptor, *PHCD_IsoTransferDescriptor;
291 
292 typedef struct st_OHCI_HOST {
293  HC_HCCA hcca;
295 #if ISO_LIST_ENABLE
296  HCD_IsoTransferDescriptor iTDs[MAX_ITD];
297 #endif
300  HC_ED staticEDs[MAX_STATIC_ED];
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);
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);
321 static INLINE HCD_STATUS OHciRhPortResume(uint8_t HostID, uint8_t uPortNumber);
322 
323 static INLINE Bool IsInterruptEndpoint (uint8_t EdIdx);
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 
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);*/
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 
377 
378 #endif /*defined(__LPC_OHCI__)*/
379