]> git.sur5r.net Git - freertos/blob
022742d85be5b709bc9cbfef391e2de0fced8669
[freertos] /
1 /*\r
2  * @brief HAL USB functions for the LPC18xx microcontrollers\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 \r
32 #if defined(__LPC18XX__) || defined(__LPC43XX__)\r
33 \r
34 #include "../HAL.h"\r
35 #include "../../USBTask.h"\r
36 \r
37 #if defined(USB_CAN_BE_DEVICE)\r
38 #include "../../Device.h"\r
39 \r
40 void HAL_USBConnect(uint8_t corenum, uint32_t con)\r
41 {\r
42 #if defined(USB_DEVICE_ROM_DRIVER)\r
43         if (con) {\r
44                 USBD_API->hw->Connect(UsbHandle, 1);\r
45         }\r
46         else {\r
47                 USBD_API->hw->Connect(UsbHandle, 0);\r
48         }\r
49 #else\r
50         if (con) {\r
51                 USB_REG(corenum)->USBCMD_D |= (1 << 0);\r
52         }\r
53         else {\r
54                 USB_REG(corenum)->USBCMD_D &= ~(1 << 0);\r
55         }\r
56 #endif\r
57 }\r
58 \r
59 #endif\r
60 \r
61 IP_USBHS_001_T * const USB_REG_BASE_ADDR[LPC18_43_MAX_USB_CORE] = {LPC_USB0, LPC_USB1};\r
62 \r
63 /* Support for USB0 and USB1, 2 cores */\r
64 static bool coreEnabled[2];\r
65 \r
66 void HAL_USBInit(uint8_t corenum)\r
67 {\r
68         /* Just exit if already enabled */\r
69         if (!coreEnabled[corenum]) {\r
70                 /* if other code is not enabled, the enable USB PLL */\r
71                 if (!coreEnabled[1 - corenum]) {\r
72                         /* Neither core is enabled, so enable USB PLL first */\r
73                         Chip_Clock_EnablePLL(CGU_USB_PLL);\r
74 \r
75                         /* Wait for PLL lock */\r
76                         while (!(Chip_Clock_GetPLLStatus(CGU_USB_PLL) & CGU_PLL_LOCKED));\r
77                 }\r
78 \r
79                 if (corenum == 0) {\r
80                         /* For core 0, enable USB0 base clock */\r
81                         Chip_Clock_EnableBaseClock(CLK_BASE_USB0);\r
82                         Chip_Clock_EnableOpts(CLK_MX_USB0, true, true, 1);\r
83 \r
84                         /* Turn on the phy */\r
85                         Chip_CREG_EnableUSB0Phy(true);\r
86                 }\r
87                 else {\r
88                         /* For core 1, enable USB1 base clock */\r
89                         Chip_Clock_EnableBaseClock(CLK_BASE_USB1);\r
90                         Chip_Clock_EnableOpts(CLK_MX_USB1, true, true, 1);\r
91 \r
92                         /* Turn on the phy */\r
93                         Chip_CREG_EnableUSB0Phy(true);\r
94 #if defined(USB_CAN_BE_HOST)\r
95                         /* enable USB1_DP and USB1_DN on chip FS phy */\r
96                         if (corenum && USB_CurrentMode[corenum] == USB_MODE_Host)LPC_SCU->SFSUSB = 0x16;\r
97 #endif\r
98 #if defined(USB_CAN_BE_DEVICE)\r
99                         /* enable USB1_DP and USB1_DN on chip FS phy */\r
100                         if (corenum && USB_CurrentMode[corenum] == USB_MODE_Device)LPC_SCU->SFSUSB = 0x12;\r
101 #endif\r
102                         LPC_USB1->PORTSC1_D |= (1 << 24);\r
103                 }\r
104 \r
105                 coreEnabled[corenum] = true;\r
106         }\r
107 \r
108 #if defined(USB_CAN_BE_DEVICE) && (!defined(USB_DEVICE_ROM_DRIVER))\r
109         /* reset the controller */\r
110         USB_REG(corenum)->USBCMD_D = USBCMD_D_Reset;\r
111         /* wait for reset to complete */\r
112         while (USB_REG(corenum)->USBCMD_D & USBCMD_D_Reset) ;\r
113 \r
114         /* Program the controller to be the USB device controller */\r
115         USB_REG(corenum)->USBMODE_D =   (0x2 << 0) /*| (1<<4)*//*| (1<<3)*/;\r
116         if (corenum == 0) {\r
117                 /* set OTG transcever in proper state, device is present\r
118                    on the port(CCS=1), port enable/disable status change(PES=1). */\r
119                 LPC_USB0->OTGSC = (1 << 3) | (1 << 0) /*| (1<<16)| (1<<24)| (1<<25)| (1<<26)| (1<<27)| (1<<28)| (1<<29)| (1<<30)*/;\r
120                 #if (USB_FORCED_FULLSPEED)\r
121                 LPC_USB0->PORTSC1_D |= (1 << 24);\r
122                 #endif\r
123         }\r
124         HAL_Reset(corenum);\r
125 #endif\r
126 }\r
127 \r
128 void HAL_USBDeInit(uint8_t corenum, uint8_t mode)\r
129 {\r
130         HAL_DisableUSBInterrupt(corenum);\r
131         if (mode == USB_MODE_Device) {\r
132                 #if defined(USB_CAN_BE_HOST)\r
133                 USB_REG(corenum)->USBSTS_H = 0xFFFFFFFF;                                /* clear all current interrupts */\r
134                 USB_REG(corenum)->PORTSC1_H &= ~(1 << 12);                                      /* clear port power */\r
135                 USB_REG(corenum)->USBMODE_H =   (1 << 0);                               /* set USB mode reserve */\r
136                 #endif\r
137         }\r
138         else if (mode == USB_MODE_Host) {\r
139                 #if defined(USB_CAN_BE_DEVICE)\r
140                 /* Clear all pending interrupts */\r
141                 USB_REG(corenum)->USBSTS_D   = 0xFFFFFFFF;\r
142                 USB_REG(corenum)->ENDPTNAK   = 0xFFFFFFFF;\r
143                 USB_REG(corenum)->ENDPTNAKEN = 0;\r
144                 USB_REG(corenum)->ENDPTSETUPSTAT = USB_REG(corenum)->ENDPTSETUPSTAT;\r
145                 USB_REG(corenum)->ENDPTCOMPLETE  = USB_REG(corenum)->ENDPTCOMPLETE;\r
146                 while (USB_REG(corenum)->ENDPTPRIME) ;                                          /* Wait until all bits are 0 */\r
147                 USB_REG(corenum)->ENDPTFLUSH = 0xFFFFFFFF;\r
148                 while (USB_REG(corenum)->ENDPTFLUSH) ;          /* Wait until all bits are 0 */\r
149                 #endif\r
150         }\r
151 \r
152         /* Disable USB PHY if both USB cores are disabled */\r
153         if (coreEnabled[1 - corenum]) {\r
154                 /* Turn off the phy (prior to PLL disabled) */\r
155                 Chip_CREG_EnableUSB0Phy(false);\r
156         }\r
157 \r
158         /* Power down USB clocking */\r
159         if (corenum == 0) {\r
160                 Chip_Clock_Disable(CLK_MX_USB0);\r
161                 Chip_Clock_DisableBaseClock(CLK_BASE_USB0);\r
162         }\r
163         else {\r
164                 Chip_Clock_Disable(CLK_MX_USB1);\r
165                 Chip_Clock_DisableBaseClock(CLK_BASE_USB1);\r
166         }\r
167 \r
168         /* Disable USB PLL if both USB cores are disabled */\r
169         if (coreEnabled[1 - corenum]) {\r
170                 /* Disable USB PLL */\r
171                 Chip_Clock_DisablePLL(CGU_USB_PLL);\r
172         }\r
173 \r
174         coreEnabled[corenum] = false;\r
175 }\r
176 \r
177 void HAL_EnableUSBInterrupt(uint8_t corenum)\r
178 {\r
179         NVIC_EnableIRQ((corenum) ? USB1_IRQn : USB0_IRQn);      //  enable USB interrupts\r
180 }\r
181 \r
182 void HAL_DisableUSBInterrupt(uint8_t corenum)\r
183 {\r
184         NVIC_DisableIRQ((corenum) ? USB1_IRQn : USB0_IRQn);     //  disable USB interrupts\r
185 }\r
186 \r
187 void USB0_IRQHandler(void)\r
188 {\r
189         if (USB_CurrentMode[0] == USB_MODE_Host) {\r
190                 #ifdef USB_CAN_BE_HOST\r
191                 HcdIrqHandler(0);\r
192                 #endif\r
193         }\r
194         if (USB_CurrentMode[0] == USB_MODE_Device) {\r
195                 #ifdef USB_CAN_BE_DEVICE\r
196                         #ifdef USB_DEVICE_ROM_DRIVER\r
197                 UsbdRom_IrqHandler();\r
198                         #else\r
199                 DcdIrqHandler(0);\r
200                         #endif\r
201                 #endif\r
202         }\r
203 }\r
204 \r
205 void USB1_IRQHandler(void)\r
206 {\r
207         if (USB_CurrentMode[1] == USB_MODE_Host) {\r
208                 #ifdef USB_CAN_BE_HOST\r
209                 HcdIrqHandler(1);\r
210                 #endif\r
211         }\r
212         if (USB_CurrentMode[1] == USB_MODE_Device) {\r
213                 #ifdef USB_CAN_BE_DEVICE\r
214                         #ifdef USB_DEVICE_ROM_DRIVER\r
215                 UsbdRom_IrqHandler();\r
216                         #else\r
217                 DcdIrqHandler(1);\r
218                         #endif\r
219                 #endif\r
220         }\r
221 }\r
222 \r
223 #endif /*__LPC18XX__*/\r