drv_hsotg.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /**************************************************************************//**
  2. *
  3. * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2020-05-22 klcheng First version
  10. *
  11. ******************************************************************************/
  12. #include <rtconfig.h>
  13. #if defined(BSP_USING_HSOTG)
  14. #include <rtdevice.h>
  15. #include <rtdbg.h>
  16. #include "NuMicro.h"
  17. /* This delay must be at least 10 us */
  18. static void _usb_init_delay(void)
  19. {
  20. volatile uint32_t i = 0x1000;
  21. while (i--)
  22. __NOP();
  23. return;
  24. }
  25. /* Check current usb role */
  26. static void usb_role(void)
  27. {
  28. uint32_t status;
  29. status = (HSOTG->STATUS) & (HSOTG_STATUS_ASHOST_Msk | HSOTG_STATUS_ASPERI_Msk | HSOTG_STATUS_IDSTS_Msk);
  30. if (status == (HSOTG_STATUS_IDSTS_Msk | HSOTG_STATUS_ASPERI_Msk))
  31. rt_kprintf("usb frame acts as peripheral\n");
  32. else if (status == HSOTG_STATUS_ASHOST_Msk)
  33. rt_kprintf("usb frame acts as host\n");
  34. else
  35. rt_kprintf("usb frame is unknown state: 0x%x\n", status);
  36. return;
  37. }
  38. MSH_CMD_EXPORT_ALIAS(usb_role, usb_role, check usb role);
  39. static int hsotg_init(void)
  40. {
  41. SYS_UnlockReg();
  42. /* Set HSOTG as ID dependent role */
  43. SYS->USBPHY = SYS_USBPHY_HSUSBEN_Msk | (0x2 << SYS_USBPHY_HSUSBROLE_Pos);
  44. /* user should keep HSUSB PHY at reset mode at lease 10 us before changing to active mode */
  45. _usb_init_delay();
  46. SYS->USBPHY |= SYS_USBPHY_HSUSBACT_Msk;
  47. /* Enable OTG and ID detection function */
  48. HSOTG_ENABLE_PHY();
  49. HSOTG_ENABLE_ID_DETECT();
  50. NVIC_EnableIRQ(USBOTG20_IRQn);
  51. /* clear interrupt and enable relative interrupts */
  52. HSOTG_ENABLE_INT(HSOTG_INTEN_IDCHGIEN_Msk | HSOTG_INTEN_HOSTIEN_Msk | HSOTG_INTEN_PDEVIEN_Msk |
  53. HSOTG_INTEN_BVLDCHGIEN_Msk | HSOTG_INTEN_AVLDCHGIEN_Msk);
  54. SYS_LockReg();
  55. return (int)RT_EOK;
  56. }
  57. INIT_DEVICE_EXPORT(hsotg_init);
  58. /* HSOTG interrupt entry */
  59. void USBOTG20_IRQHandler(void)
  60. {
  61. __IO uint32_t reg;
  62. reg = HSOTG->INTSTS;
  63. /* usb id pin status change */
  64. if (reg & HSOTG_INTSTS_IDCHGIF_Msk)
  65. {
  66. HSOTG_CLR_INT_FLAG(HSOTG_INTSTS_IDCHGIF_Msk);
  67. LOG_D("usb id change");
  68. }
  69. /* usb acts as host */
  70. if (reg & HSOTG_INTSTS_HOSTIF_Msk)
  71. {
  72. HSOTG_CLR_INT_FLAG(HSOTG_INTSTS_HOSTIF_Msk);
  73. LOG_D("usb acts as host");
  74. }
  75. /* usb acts as peripheral */
  76. if (reg & HSOTG_INTSTS_PDEVIF_Msk)
  77. {
  78. HSOTG_CLR_INT_FLAG(HSOTG_INTSTS_PDEVIF_Msk);
  79. LOG_D("usb acts as peripheral");
  80. }
  81. /* A-device session valid state change */
  82. if (reg & HSOTG_INTSTS_AVLDCHGIF_Msk)
  83. {
  84. HSOTG_CLR_INT_FLAG(HSOTG_INTSTS_AVLDCHGIF_Msk);
  85. LOG_D("usb a-device session valid state change");
  86. }
  87. /* B-device session valid state change */
  88. if (reg & HSOTG_INTSTS_BVLDCHGIF_Msk)
  89. {
  90. HSOTG_CLR_INT_FLAG(HSOTG_INTSTS_BVLDCHGIF_Msk);
  91. LOG_D("usb b-device session valid state change");
  92. }
  93. }
  94. #endif /* defined(BSP_USING_HSOTG) */