USBH1_LPC18xx.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /* -------------------------------------------------------------------------- /*
  2. * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * $Date: 02. March 2016
  19. * $Revision: V2.4
  20. *
  21. * Driver: Driver_USBH1_HCI
  22. * Configured: via RTE_Device.h configuration file
  23. * Project: USB Host 1 HCI Controller (EHCI) Driver for NXP LPC18xx
  24. * --------------------------------------------------------------------------
  25. * Use the following configuration settings in the middleware component
  26. * to connect to this driver.
  27. *
  28. * Configuration Setting Value
  29. * --------------------- -----
  30. * Connect to hardware via Driver_USBH# = 1
  31. * USB Host controller interface = EHCI
  32. * -------------------------------------------------------------------------- */
  33. /* History:
  34. * Version 2.4
  35. * Corrected PowerControl function for conditional Power full (driver must be initialized)
  36. * Version 2.3
  37. * PowerControl for Power OFF and Uninitialize functions made unconditional
  38. * Version 2.2
  39. * Updated in accordance with USB Device Driver
  40. * Version 2.1
  41. * Moved register initialization and uninitialization to PowerControl
  42. * function and removed from Initialize/Uninitialize functions
  43. * Pin configuration moved to USB_LPC18xx_USB0.c
  44. * Version 2.0
  45. * Initial release for USB Host EHCI Driver API v2.0
  46. * Version 1.0
  47. * Initial release
  48. */
  49. #include "Driver_USBH.h"
  50. #include "LPC18xx.h"
  51. #include "SCU_LPC18xx.h"
  52. #include "USB_LPC18xx.h"
  53. #include "RTE_Device.h"
  54. #include "RTE_Components.h"
  55. #if (RTE_USB_USB1 == 0)
  56. #error "USB1 is not enabled in the RTE_Device.h!"
  57. #endif
  58. #if (RTE_USB_USB1_FS_PHY_EN && RTE_USB_USB1_HS_PHY_EN)
  59. #error "Both full-speed and high-speed PHY can not be selected at the same time!"
  60. #endif
  61. extern uint8_t USB1_role;
  62. extern uint8_t USB1_state;
  63. extern void USB1_PinsConfigure (void);
  64. extern void USB1_PinsUnconfigure (void);
  65. // USBH EHCI Driver ************************************************************
  66. #define ARM_USBH_EHCI_DRIVER_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,4)
  67. // Driver Version
  68. static const ARM_DRIVER_VERSION usbh_ehci_driver_version = { ARM_USBH_API_VERSION, ARM_USBH_EHCI_DRIVER_VERSION };
  69. // Driver Capabilities
  70. static const ARM_USBH_HCI_CAPABILITIES usbh_ehci_driver_capabilities = {
  71. 0x0001U // Root HUB available Ports Mask
  72. };
  73. static ARM_USBH_HCI_Interrupt_t EHCI_IRQ;
  74. // USBH EHCI Driver functions
  75. /**
  76. \fn ARM_DRIVER_VERSION USBH_HCI_GetVersion (void)
  77. \brief Get USB Host HCI (OHCI/EHCI) driver version.
  78. \return \ref ARM_DRIVER_VERSION
  79. */
  80. static ARM_DRIVER_VERSION USBH_HCI_GetVersion (void) { return usbh_ehci_driver_version; }
  81. /**
  82. \fn ARM_USBH_HCI_CAPABILITIES USBH_HCI_GetCapabilities (void)
  83. \brief Get driver capabilities.
  84. \return \ref ARM_USBH_HCI_CAPABILITIES
  85. */
  86. static ARM_USBH_HCI_CAPABILITIES USBH_HCI_GetCapabilities (void) { return usbh_ehci_driver_capabilities; }
  87. /**
  88. \fn int32_t USBH_HCI_Initialize (ARM_USBH_HCI_Interrupt_t *cb_interrupt)
  89. \brief Initialize USB Host HCI (OHCI/EHCI) Interface.
  90. \param[in] cb_interrupt Pointer to Interrupt Handler Routine
  91. \return \ref execution_status
  92. */
  93. static int32_t USBH_HCI_Initialize (ARM_USBH_HCI_Interrupt_t cb_interrupt) {
  94. if ((USB1_state & USBH_DRIVER_INITIALIZED) != 0U) { return ARM_DRIVER_OK; }
  95. EHCI_IRQ = cb_interrupt;
  96. USB1_role = ARM_USB_ROLE_HOST;
  97. USB1_PinsConfigure ();
  98. USB1_state = USBH_DRIVER_INITIALIZED;
  99. return ARM_DRIVER_OK;
  100. }
  101. /**
  102. \fn int32_t USBH_HCI_Uninitialize (void)
  103. \brief De-initialize USB Host HCI (OHCI/EHCI) Interface.
  104. \return \ref execution_status
  105. */
  106. static int32_t USBH_HCI_Uninitialize (void) {
  107. USB1_PinsUnconfigure ();
  108. USB1_role = ARM_USB_ROLE_NONE;
  109. USB1_state &= ~USBH_DRIVER_INITIALIZED;
  110. return ARM_DRIVER_OK;
  111. }
  112. /**
  113. \fn int32_t USBH_HCI_PowerControl (ARM_POWER_STATE state)
  114. \brief Control USB Host HCI (OHCI/EHCI) Interface Power.
  115. \param[in] state Power state
  116. \return \ref execution_status
  117. */
  118. static int32_t USBH_HCI_PowerControl (ARM_POWER_STATE state) {
  119. switch (state) {
  120. case ARM_POWER_OFF:
  121. NVIC_DisableIRQ (USB1_IRQn); // Disable interrupt
  122. NVIC_ClearPendingIRQ (USB1_IRQn); // Clear pending interrupt
  123. USB1_state &= ~USBH_DRIVER_POWERED; // Clear powered flag
  124. #if (!RTE_USB_USB1_HS_PHY_EN)
  125. SCU_USB1_PinConfigure (SCU_USB1_PIN_CFG_ESEA); // Reset SCU Register
  126. #endif
  127. if ((LPC_CGU->BASE_USB1_CLK & 1U) == 0U) {
  128. LPC_CCU1->CLK_USB1_CFG &= ~1U; // Disable USB1 Base Clock
  129. while (LPC_CCU1->CLK_USB1_STAT & 1U);
  130. LPC_CCU1->CLK_M3_USB1_CFG &= ~1U; // Disable USB1 Register Interface Clock
  131. while (LPC_CCU1->CLK_M3_USB1_STAT & 1U);
  132. LPC_CGU->BASE_USB1_CLK = 1U; // Disable Base Clock
  133. }
  134. break;
  135. case ARM_POWER_FULL:
  136. if ((USB1_state & USBH_DRIVER_INITIALIZED) == 0U) { return ARM_DRIVER_ERROR; }
  137. if ((USB1_state & USBH_DRIVER_POWERED) != 0U) { return ARM_DRIVER_OK; }
  138. LPC_CGU->BASE_USB1_CLK = (0x01U << 11) | // Auto-block Enable
  139. (0x0CU << 24) ; // Clock source: IDIVA
  140. LPC_CCU1->CLK_M3_USB1_CFG |= 1U; // Enable USB1 Register Interface Clock
  141. while (!(LPC_CCU1->CLK_M3_USB1_STAT & 1U));
  142. LPC_CCU1->CLK_USB1_CFG |= 1U; // Enable USB1 Base Clock
  143. while (!(LPC_CCU1->CLK_USB1_STAT & 1U));
  144. // Clear Transceiver Selection
  145. LPC_USB1->PORTSC1_H &= ~(USB_PORTSC1_H_PTS_MSK | USB_PORTSC1_H_PFSC | USB_PORTSC1_H_PHCD);
  146. #if (RTE_USB_USB1_HS_PHY_EN)
  147. // ULPI Selected
  148. LPC_USB1->PORTSC1_H |= USB_PORTSC1_H_PTS(2U); // Activate ULPI
  149. #else
  150. // Serial/1.1 PHY selected and Full-speed forced
  151. LPC_USB1->PORTSC1_H |= USB_PORTSC1_H_PTS(3UL);
  152. SCU_USB1_PinConfigure (SCU_USB1_PIN_CFG_AIM |
  153. SCU_USB1_PIN_CFG_ESEA |
  154. SCU_USB1_PIN_CFG_EPD |
  155. SCU_USB1_PIN_CFG_EPWR);
  156. #endif
  157. USB1_state |= USBH_DRIVER_POWERED; // Set powered flag
  158. NVIC_EnableIRQ (USB1_IRQn); // Enable interrupt
  159. break;
  160. default:
  161. return ARM_DRIVER_ERROR_UNSUPPORTED;
  162. }
  163. return ARM_DRIVER_OK;
  164. }
  165. /**
  166. \fn int32_t USBH_HCI_PortVbusOnOff (uint8_t port, bool vbus)
  167. \brief USB Host HCI (OHCI/EHCI) Root HUB Port VBUS on/off.
  168. \param[in] port Root HUB Port Number
  169. \param[in] vbus
  170. - \b false VBUS off
  171. - \b true VBUS on
  172. \return \ref execution_status
  173. */
  174. static int32_t USBH_HCI_PortVbusOnOff (uint8_t port, bool power) {
  175. // No GPIO pins used for VBUS control it is controlled by EHCI Controller
  176. if (((1U << port) & usbh_ehci_driver_capabilities.port_mask) == 0U) { return ARM_DRIVER_ERROR; }
  177. return ARM_DRIVER_OK;
  178. }
  179. /**
  180. \fn void USBH1_IRQ (void)
  181. \brief USB1 Host Interrupt Routine (IRQ).
  182. */
  183. void USBH1_IRQ (void) {
  184. EHCI_IRQ();
  185. }
  186. ARM_DRIVER_USBH_HCI Driver_USBH1_HCI = {
  187. USBH_HCI_GetVersion,
  188. USBH_HCI_GetCapabilities,
  189. USBH_HCI_Initialize,
  190. USBH_HCI_Uninitialize,
  191. USBH_HCI_PowerControl,
  192. USBH_HCI_PortVbusOnOff
  193. };