1
0

drv_eadc.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /**************************************************************************//**
  2. * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-9-23 Wayne First version
  9. *
  10. ******************************************************************************/
  11. #include <rtconfig.h>
  12. #if defined(BSP_USING_EADC)
  13. #include <rtdevice.h>
  14. #include "NuMicro.h"
  15. /* Private define ---------------------------------------------------------------*/
  16. #define DEF_EADC_MAX_CHANNEL_NUM 8
  17. enum
  18. {
  19. EADC_START = -1,
  20. #if defined(BSP_USING_EADC0)
  21. EADC0_IDX,
  22. #endif
  23. EADC_CNT
  24. };
  25. /* Private Typedef --------------------------------------------------------------*/
  26. struct nu_eadc
  27. {
  28. struct rt_adc_device parent;
  29. char *name;
  30. EADC_T *base;
  31. uint32_t rstidx;
  32. uint32_t modid;
  33. uint32_t chnmask;
  34. };
  35. typedef struct nu_eadc *nu_eadc_t;
  36. /* Private functions ------------------------------------------------------------*/
  37. static rt_err_t nu_eadc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled);
  38. static rt_err_t nu_get_eadc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value);
  39. static rt_err_t nu_get_eadc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value);
  40. /* Public functions ------------------------------------------------------------*/
  41. int rt_hw_eadc_init(void);
  42. /* Private variables ------------------------------------------------------------*/
  43. static struct nu_eadc nu_eadc_arr [] =
  44. {
  45. #if defined(BSP_USING_EADC0)
  46. { .name = "eadc0", .base = EADC0, .rstidx = EADC0_RST, .modid = EADC0_MODULE, .chnmask = 0 },
  47. #endif
  48. };
  49. static const struct rt_adc_ops nu_adc_ops =
  50. {
  51. nu_eadc_enabled,
  52. nu_get_eadc_value,
  53. };
  54. typedef struct rt_adc_ops *rt_adc_ops_t;
  55. /* nu_adc_enabled - Enable ADC clock and wait for ready */
  56. static rt_err_t nu_eadc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
  57. {
  58. nu_eadc_t psNuEadc = (nu_eadc_t)device;
  59. RT_ASSERT(device != RT_NULL);
  60. if (channel >= DEF_EADC_MAX_CHANNEL_NUM)
  61. return -(RT_EINVAL);
  62. if (enabled)
  63. {
  64. if (psNuEadc->chnmask == 0)
  65. {
  66. /* Invoke Open function at first call. */
  67. EADC_Open(psNuEadc->base, EADC_CTL_DIFFEN_SINGLE_END);
  68. }
  69. psNuEadc->chnmask |= (1 << channel);
  70. }
  71. else
  72. {
  73. psNuEadc->chnmask &= ~(1 << channel);
  74. if (psNuEadc->chnmask == 0)
  75. {
  76. /* Invoke Open function at last call. */
  77. EADC_Close(psNuEadc->base);
  78. }
  79. }
  80. return RT_EOK;
  81. }
  82. static rt_err_t nu_get_eadc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
  83. {
  84. nu_eadc_t psNuEadc = (nu_eadc_t)device;
  85. RT_ASSERT(device != RT_NULL);
  86. RT_ASSERT(value != RT_NULL);
  87. if (channel >= DEF_EADC_MAX_CHANNEL_NUM)
  88. {
  89. *value = 0xFFFFFFFF;
  90. return -(RT_EINVAL);
  91. }
  92. if ((psNuEadc->chnmask & (1 << channel)) == 0)
  93. {
  94. *value = 0xFFFFFFFF;
  95. return -(RT_EBUSY);
  96. }
  97. EADC_ConfigSampleModule(psNuEadc->base, 0, EADC_SOFTWARE_TRIGGER, channel);
  98. EADC_CLR_INT_FLAG(psNuEadc->base, EADC_STATUS2_ADIF0_Msk);
  99. EADC_ENABLE_INT(psNuEadc->base, BIT0);
  100. EADC_ENABLE_SAMPLE_MODULE_INT(psNuEadc->base, 0, BIT0);
  101. EADC_START_CONV(psNuEadc->base, BIT0);
  102. while (EADC_GET_INT_FLAG(psNuEadc->base, BIT0) == 0);
  103. *value = EADC_GET_CONV_DATA(psNuEadc->base, 0);
  104. return RT_EOK;
  105. }
  106. int rt_hw_eadc_init(void)
  107. {
  108. int i;
  109. rt_err_t ret = RT_EOK;
  110. for (i = (EADC_START + 1); i < EADC_CNT; i++)
  111. {
  112. CLK_EnableModuleClock(nu_eadc_arr[i].modid);
  113. SYS_ResetModule(nu_eadc_arr[i].rstidx);
  114. ret = rt_hw_adc_register(&nu_eadc_arr[i].parent, nu_eadc_arr[i].name, &nu_adc_ops, &nu_eadc_arr[i]);
  115. RT_ASSERT(ret == RT_EOK);
  116. }
  117. return (int)ret;
  118. }
  119. INIT_BOARD_EXPORT(rt_hw_eadc_init);
  120. #endif //#if defined(BSP_USING_EADC)