drv_adc.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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. * 2022-05-16 shelton first version
  9. * 2023-01-31 shelton add support f421/f425
  10. * 2023-04-08 shelton add support f423
  11. * 2023-10-18 shelton add support f402/f405
  12. * 2024-04-12 shelton add support a403a and a423
  13. * 2024-08-30 shelton add support m412 and m416
  14. * 2024-12-18 shelton add support f455/f456 and f457
  15. */
  16. #include "drv_common.h"
  17. #include "drv_adc.h"
  18. #if defined(BSP_USING_ADC1) || defined(BSP_USING_ADC2) || \
  19. defined(BSP_USING_ADC3)
  20. //#define DRV_DEBUG
  21. #define LOG_TAG "drv.adc"
  22. #include <drv_log.h>
  23. struct at32_adc
  24. {
  25. struct rt_adc_device at32_adc_device;
  26. adc_type *adc_x;
  27. char *name;
  28. };
  29. static struct at32_adc at32_adc_obj[] =
  30. {
  31. #ifdef BSP_USING_ADC1
  32. ADC1_CONFIG,
  33. #endif
  34. #ifdef BSP_USING_ADC2
  35. ADC2_CONFIG,
  36. #endif
  37. #ifdef BSP_USING_ADC3
  38. ADC3_CONFIG,
  39. #endif
  40. };
  41. static rt_err_t at32_adc_enabled(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled)
  42. {
  43. adc_type *adc_x;
  44. adc_base_config_type adc_config_struct;
  45. #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
  46. defined (SOC_SERIES_AT32F423) || defined (SOC_SERIES_AT32A423) || \
  47. defined (SOC_SERIES_AT32M412) || defined (SOC_SERIES_AT32M416) || \
  48. defined (SOC_SERIES_AT32F455) || defined (SOC_SERIES_AT32F456) || \
  49. defined (SOC_SERIES_AT32F457)
  50. adc_common_config_type adc_common_struct;
  51. adc_common_default_para_init(&adc_common_struct);
  52. #endif
  53. RT_ASSERT(device != RT_NULL);
  54. adc_x = device->parent.user_data;
  55. at32_msp_adc_init(adc_x);
  56. #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
  57. defined (SOC_SERIES_AT32M412) || defined (SOC_SERIES_AT32M416) || \
  58. defined (SOC_SERIES_AT32F455) || defined (SOC_SERIES_AT32F456) || \
  59. defined (SOC_SERIES_AT32F457)
  60. /* config combine mode */
  61. adc_common_struct.combine_mode = ADC_INDEPENDENT_MODE;
  62. /* config division, adcclk is division by hclk */
  63. adc_common_struct.div = ADC_HCLK_DIV_4;
  64. /* config common dma mode,it's not useful in independent mode */
  65. adc_common_struct.common_dma_mode = ADC_COMMON_DMAMODE_DISABLE;
  66. /* config common dma request repeat */
  67. adc_common_struct.common_dma_request_repeat_state = FALSE;
  68. /* config adjacent adc sampling interval,it's useful for ordinary shifting mode */
  69. adc_common_struct.sampling_interval = ADC_SAMPLING_INTERVAL_5CYCLES;
  70. /* config inner temperature sensor and vintrv */
  71. adc_common_struct.tempervintrv_state = FALSE;
  72. /* config voltage battery */
  73. #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
  74. defined (SOC_SERIES_AT32F455) || defined (SOC_SERIES_AT32F456) || \
  75. defined (SOC_SERIES_AT32F457)
  76. adc_common_struct.vbat_state = FALSE;
  77. #endif
  78. adc_common_config(&adc_common_struct);
  79. #elif defined (SOC_SERIES_AT32F423) || defined (SOC_SERIES_AT32A423)
  80. /* config division, adcclk is division by hclk */
  81. adc_common_struct.div = ADC_HCLK_DIV_4;
  82. /* config inner temperature sensor and vintrv */
  83. adc_common_struct.tempervintrv_state = FALSE;
  84. adc_common_config(&adc_common_struct);
  85. #else
  86. #if !defined (SOC_SERIES_AT32F415) && !defined (SOC_SERIES_AT32F421) && \
  87. !defined (SOC_SERIES_AT32F425) && !defined (SOC_SERIES_AT32F402) && \
  88. !defined (SOC_SERIES_AT32F405)
  89. adc_combine_mode_select(ADC_INDEPENDENT_MODE);
  90. #endif
  91. adc_ordinary_conversion_trigger_set(adc_x, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);
  92. #endif
  93. /* adc_x configuration */
  94. adc_base_default_para_init(&adc_config_struct);
  95. adc_config_struct.data_align = ADC_RIGHT_ALIGNMENT;
  96. adc_config_struct.ordinary_channel_length = 1;
  97. adc_config_struct.repeat_mode = FALSE;
  98. adc_config_struct.sequence_mode = FALSE;
  99. adc_base_config(adc_x, &adc_config_struct);
  100. if (!enabled)
  101. {
  102. /* disable adc_x */
  103. adc_enable(adc_x, FALSE);
  104. }
  105. else
  106. {
  107. /* enable adc_x */
  108. adc_enable(adc_x, TRUE);
  109. /* enable adc_x calibration */
  110. adc_calibration_init(adc_x);
  111. /* check the end of adc_x reset calibration register */
  112. while(adc_calibration_init_status_get(adc_x) == SET)
  113. {
  114. }
  115. /* start adc_x calibration */
  116. adc_calibration_start(adc_x);
  117. /* check the end of adc_x calibration */
  118. while(adc_calibration_status_get(adc_x) == SET)
  119. {
  120. }
  121. }
  122. return RT_EOK;
  123. }
  124. static rt_err_t at32_get_adc_value(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value)
  125. {
  126. adc_type *adc_x;
  127. rt_uint32_t timeout = 0;
  128. RT_ASSERT(device != RT_NULL);
  129. adc_x = device->parent.user_data;
  130. /* adc_x regular channels configuration */
  131. #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
  132. defined (SOC_SERIES_AT32F423) || defined (SOC_SERIES_AT32A423) || \
  133. defined (SOC_SERIES_AT32F455) || defined (SOC_SERIES_AT32F456) || \
  134. defined (SOC_SERIES_AT32F457)
  135. adc_flag_clear(adc_x, ADC_OCCE_FLAG);
  136. adc_ordinary_channel_set(adc_x, (adc_channel_select_type)channel, 1, ADC_SAMPLETIME_247_5);
  137. #else
  138. #if defined (SOC_SERIES_AT32M412) || defined (SOC_SERIES_AT32M416)
  139. adc_flag_clear(adc_x, ADC_OCCE_FLAG);
  140. #else
  141. adc_flag_clear(adc_x, ADC_CCE_FLAG);
  142. #endif
  143. adc_ordinary_channel_set(adc_x, (adc_channel_select_type)channel, 1, ADC_SAMPLETIME_239_5);
  144. #endif
  145. /* start adc_x software conversion */
  146. adc_ordinary_software_trigger_enable(adc_x, TRUE);
  147. /* wait for the adc to convert */
  148. #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
  149. defined (SOC_SERIES_AT32F423) || defined (SOC_SERIES_AT32A423) || \
  150. defined (SOC_SERIES_AT32M412) || defined (SOC_SERIES_AT32M416) || \
  151. defined (SOC_SERIES_AT32F455) || defined (SOC_SERIES_AT32F456) || \
  152. defined (SOC_SERIES_AT32F457)
  153. while((adc_flag_get(adc_x, ADC_OCCE_FLAG) == RESET) && timeout < 0xFFFF)
  154. #else
  155. while((adc_flag_get(adc_x, ADC_CCE_FLAG) == RESET) && timeout < 0xFFFF)
  156. #endif
  157. {
  158. timeout ++;
  159. }
  160. if(timeout >= 0xFFFF)
  161. {
  162. LOG_D("channel%d converts timeout, please confirm adc_x enabled or not", channel);
  163. }
  164. /* get adc value */
  165. *value = adc_ordinary_conversion_data_get(adc_x);
  166. return RT_EOK;
  167. }
  168. static const struct rt_adc_ops at_adc_ops =
  169. {
  170. .enabled = at32_adc_enabled,
  171. .convert = at32_get_adc_value,
  172. };
  173. static int rt_hw_adc_init(void)
  174. {
  175. int result = RT_EOK;
  176. int i = 0;
  177. for (i = 0; i < sizeof(at32_adc_obj) / sizeof(at32_adc_obj[0]); i++)
  178. {
  179. /* register ADC device */
  180. if (rt_hw_adc_register(&at32_adc_obj[i].at32_adc_device, at32_adc_obj[i].name, &at_adc_ops, at32_adc_obj[i].adc_x) == RT_EOK)
  181. {
  182. LOG_D("%s register success", at32_adc_obj[i].name);
  183. }
  184. else
  185. {
  186. LOG_E("%s register failed", at32_adc_obj[i].name);
  187. result = -RT_ERROR;
  188. }
  189. }
  190. return result;
  191. }
  192. INIT_BOARD_EXPORT(rt_hw_adc_init);
  193. #endif /* BSP_USING_ADC */