drv_otg.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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-09-17 CHChen First version
  10. *
  11. ******************************************************************************/
  12. #include <rtconfig.h>
  13. #if defined(BSP_USING_OTG)
  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 = (OTG->STATUS) & (OTG_STATUS_ASHOST_Msk | OTG_STATUS_ASPERI_Msk | OTG_STATUS_IDSTS_Msk);
  30. if (status == (OTG_STATUS_IDSTS_Msk | OTG_STATUS_ASPERI_Msk))
  31. rt_kprintf("usb frame acts as peripheral\n");
  32. else if (status == OTG_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 otg_init(void)
  40. {
  41. SYS_UnlockReg();
  42. /* Set OTG as ID dependent role */
  43. SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | SYS_USBPHY_OTGPHYEN_Msk | SYS_USBPHY_SBO_Msk | (0x2 << SYS_USBPHY_USBROLE_Pos);
  44. OTG_ENABLE();
  45. /* Enable OTG and ID detection function */
  46. OTG_ENABLE_PHY();
  47. /* Enable ID detection function */
  48. OTG_ENABLE_ID_DETECT();
  49. /* Enable OTG interrupt */
  50. NVIC_EnableIRQ(USBOTG_IRQn);
  51. _usb_init_delay();
  52. /* clear interrupt and enable relative interrupts */
  53. OTG_ENABLE_INT(OTG_INTEN_IDCHGIEN_Msk | OTG_INTEN_HOSTIEN_Msk | OTG_INTEN_PDEVIEN_Msk |
  54. OTG_INTEN_BVLDCHGIEN_Msk | OTG_INTEN_AVLDCHGIEN_Msk);
  55. SYS_LockReg();
  56. return (int)RT_EOK;
  57. }
  58. INIT_DEVICE_EXPORT(otg_init);
  59. /* OTG interrupt entry */
  60. void USBOTG_IRQHandler(void)
  61. {
  62. __IO uint32_t u32INTEN;
  63. u32INTEN = OTG->INTEN;
  64. /* usb id pin status change */
  65. if (u32INTEN & OTG_INTSTS_IDCHGIF_Msk)
  66. {
  67. if (OTG_GET_STATUS(OTG_STATUS_IDSTS_Msk))
  68. LOG_D("usb frame acts as peripheral\n");
  69. OTG_CLR_INT_FLAG(OTG_INTSTS_IDCHGIF_Msk);
  70. LOG_D("usb id change");
  71. }
  72. /* B-device session valid state change */
  73. if (u32INTEN & OTG_INTSTS_BVLDCHGIF_Msk)
  74. {
  75. if (OTG_GET_STATUS(OTG_STATUS_IDSTS_Msk) == 0)
  76. LOG_D("usb frame acts as host\n");
  77. OTG_CLR_INT_FLAG(OTG_INTSTS_BVLDCHGIF_Msk);
  78. LOG_D("usb b-device session valid state change");
  79. }
  80. /* Clear all interrupt flags */
  81. OTG->INTSTS = u32INTEN;
  82. }
  83. #endif /* defined(BSP_USING_OTG) */