drv_adc.c 4.0 KB

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