drv_adc.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-01-03 iysheng first version
  9. */
  10. #include <board.h>
  11. #include <drivers/adc.h>
  12. #include <rtdbg.h>
  13. #ifdef RT_USING_ADC
  14. //#define DRV_DEBUG
  15. #define LOG_TAG "drv.adc"
  16. #ifndef ARRAY_SIZE
  17. #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
  18. #endif
  19. #define MAX_EXTERN_ADC_CHANNEL 16
  20. typedef struct {
  21. struct rt_adc_device adc_dev;
  22. char name[8];
  23. rt_base_t adc_pins[16];
  24. void *private_data;
  25. } gd32_adc_device;
  26. static gd32_adc_device g_gd32_devs[] = {
  27. #ifdef BSP_USING_ADC0
  28. {
  29. {},
  30. "adc0",
  31. {
  32. GET_PIN(A, 0), GET_PIN(A, 1), GET_PIN(A, 2), GET_PIN(A, 3),
  33. GET_PIN(A, 4), GET_PIN(A, 5), GET_PIN(A, 6), GET_PIN(A, 7),
  34. GET_PIN(B, 0), GET_PIN(B, 1), GET_PIN(C, 0), GET_PIN(C, 1),
  35. GET_PIN(C, 2), GET_PIN(C, 3), GET_PIN(C, 4), GET_PIN(C, 5),
  36. },
  37. ADC0,
  38. },
  39. #endif
  40. #ifdef BSP_USING_ADC1
  41. {
  42. {},
  43. "adc1",
  44. {
  45. GET_PIN(A, 0), GET_PIN(A, 1), GET_PIN(A, 2), GET_PIN(A, 3),
  46. GET_PIN(A, 4), GET_PIN(A, 5), GET_PIN(A, 6), GET_PIN(A, 7),
  47. GET_PIN(B, 0), GET_PIN(B, 1), GET_PIN(C, 0), GET_PIN(C, 1),
  48. GET_PIN(C, 2), GET_PIN(C, 3), GET_PIN(C, 4), GET_PIN(C, 5),
  49. },
  50. ADC1,
  51. },
  52. #endif
  53. };
  54. /*
  55. * static void init_pin4adc
  56. *
  57. * 初始化指定的管腳爲 analog 模式
  58. * @ rt_uint32_t pin: pin information
  59. * return: N/A
  60. */
  61. static void init_pin4adc(rt_base_t pin)
  62. {
  63. GPIO_InitPara GPIO_InitStruct = {0};
  64. GPIO_InitStruct.GPIO_Pin = PIN_GDPIN(pin);
  65. GPIO_InitStruct.GPIO_Speed = GPIO_SPEED_50MHZ;
  66. GPIO_InitStruct.GPIO_Mode = GPIO_MODE_AIN;
  67. GPIO_Init(PIN_GDPORT(pin), &GPIO_InitStruct);
  68. }
  69. static rt_err_t gd32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
  70. {
  71. ADC_TypeDef *ADCx;
  72. ADC_InitPara ADC_InitParaStruct = {0};
  73. gd32_adc_device * gd32_adc = (gd32_adc_device *)device;
  74. if (channel >= MAX_EXTERN_ADC_CHANNEL)
  75. {
  76. LOG_E("invalid channel");
  77. return -E2BIG;
  78. }
  79. ADCx = (ADC_TypeDef *)(device->parent.user_data);
  80. if (enabled == ENABLE)
  81. {
  82. init_pin4adc(gd32_adc->adc_pins[channel]);
  83. ADC_InitParaStruct.ADC_Trig_External = ADC_EXTERNAL_TRIGGER_MODE_NONE;
  84. /* Fix the channel number to fit the firmware library */
  85. ADC_InitParaStruct.ADC_Channel_Number = 1 + channel;
  86. ADC_InitParaStruct.ADC_Data_Align = ADC_DATAALIGN_RIGHT;
  87. ADC_InitParaStruct.ADC_Mode_Scan = DISABLE;
  88. ADC_InitParaStruct.ADC_Mode = ADC_MODE_INDEPENDENT;
  89. ADC_InitParaStruct.ADC_Mode_Continuous = ENABLE;
  90. ADC_Init(ADCx, &ADC_InitParaStruct);
  91. ADC_RegularChannel_Config(ADCx, channel, 1, ADC_SAMPLETIME_13POINT5);
  92. ADC_Enable(ADCx, ENABLE);
  93. ADC_SoftwareStartConv_Enable(ADCx, ENABLE);
  94. }
  95. else
  96. {
  97. ADC_Enable(ADCx, DISABLE);
  98. }
  99. return 0;
  100. }
  101. static rt_err_t gd32_adc_convert(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
  102. {
  103. ADC_TypeDef *ADCx;
  104. if (!value)
  105. {
  106. LOG_E("invalid param");
  107. return -EINVAL;
  108. }
  109. ADCx = (ADC_TypeDef *)(device->parent.user_data);
  110. *value = ADC_GetConversionValue(ADCx);
  111. return 0;
  112. }
  113. static struct rt_adc_ops g_gd32_adc_ops = {
  114. gd32_adc_enabled,
  115. gd32_adc_convert,
  116. };
  117. static int rt_hw_adc_init(void)
  118. {
  119. int ret, i = 0;
  120. #ifdef BSP_USING_ADC0
  121. rcu_periph_clock_enable(RCU_ADC0);
  122. #endif
  123. #ifdef BSP_USING_ADC1
  124. rcu_periph_clock_enable(RCU_ADC1);
  125. #endif
  126. for (; i < ARRAY_SIZE(g_gd32_devs); i++)
  127. {
  128. ret = rt_hw_adc_register(&g_gd32_devs[i].adc_dev, \
  129. (const char *)g_gd32_devs[i].name, \
  130. &g_gd32_adc_ops, g_gd32_devs[i].private_data);
  131. if (ret != RT_EOK)
  132. {
  133. /* TODO err handler */
  134. LOG_E("failed register %s, err=%d", g_gd32_devs[i].name, ret);
  135. }
  136. }
  137. return ret;
  138. }
  139. INIT_BOARD_EXPORT(rt_hw_adc_init);
  140. #endif