drv_adc.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * Copyright (c) 2006-2024, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-05-17 QT-one first version
  9. */
  10. #include <rtdbg.h>
  11. #include "drv_adc.h"
  12. #ifdef RT_USING_ADC
  13. #if !defined(BSP_USING_ADC0) && !defined(BSP_USING_ADC1)
  14. #error "Please define at least one BSP_USING_ADCx"
  15. /* this driver can be disabled at menuconfig RT-Thread Components Device Drivers */
  16. #endif
  17. struct ht32_adc
  18. {
  19. struct rt_adc_device ht32_adc_device;
  20. HT_ADC_TypeDef *adc_x;
  21. char *name;
  22. };
  23. /* ADC Peripheral List */
  24. static struct ht32_adc ht32_adc_obj[] =
  25. {
  26. #ifdef BSP_USING_ADC0
  27. {
  28. .adc_x = HT_ADC0,
  29. .name = BSP_USING_ADC0_NAME,
  30. },
  31. #endif
  32. #ifdef BSP_USING_ADC1
  33. {
  34. .adc_x = HT_ADC1,
  35. .name = BSP_USING_ADC1_NAME,
  36. },
  37. #endif
  38. };
  39. static rt_err_t ht32_adc_enabled(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled)
  40. {
  41. HT_ADC_TypeDef *adc_x;
  42. RT_ASSERT(device != RT_NULL);
  43. adc_x = (HT_ADC_TypeDef*)device->parent.user_data;
  44. if(enabled)
  45. {
  46. ht32_adc_gpio_init(adc_x,channel);
  47. /* Configure the CK_ADCn prescaler */
  48. #ifdef BSP_USING_ADC0
  49. if(HT_ADC0 == adc_x)
  50. {
  51. CKCU_SetADCnPrescaler(CKCU_ADCPRE_ADC0,CKCU_ADCPRE_DIV64);
  52. }
  53. #endif
  54. #ifdef BSP_USING_ADC1
  55. if(HT_ADC1 == adc_x)
  56. {
  57. CKCU_SetADCnPrescaler(CKCU_ADCPRE_ADC1,CKCU_ADCPRE_DIV64);
  58. }
  59. #endif
  60. /* Configure conversion mode and sequence length (number of conversion channels) */
  61. ADC_RegularGroupConfig(adc_x,ONE_SHOT_MODE,1,0);
  62. #ifdef SOC_SERIES_HT32F5
  63. /* Configuring the Sampling Time */
  64. ADC_SamplingTimeConfig(adc_x,0);
  65. /* Configuring Channel Priority */
  66. ADC_RegularChannelConfig(adc_x,channel,0);
  67. #endif
  68. #ifdef SOC_SERIES_HT32F1
  69. /* Configuring Channel Priority */
  70. ADC_RegularChannelConfig(adc_x,channel,0,0);
  71. #endif
  72. /* Configuring the Trigger Source */
  73. ADC_RegularTrigConfig(adc_x,ADC_TRIG_SOFTWARE);
  74. /* Enable ADC */
  75. ADC_Cmd(adc_x,ENABLE);
  76. }
  77. else
  78. {
  79. /* Disable ADC */
  80. ADC_Cmd(adc_x,DISABLE);
  81. }
  82. return RT_EOK;
  83. }
  84. static rt_err_t ht32_adc_convert(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value)
  85. {
  86. HT_ADC_TypeDef *adc_x;
  87. rt_uint32_t timeout = 0;
  88. FlagStatus adc_writ_flag = RESET;
  89. RT_ASSERT(device != RT_NULL);
  90. adc_x = (HT_ADC_TypeDef*)device->parent.user_data;
  91. /* Toggle the acquisition channel */
  92. #ifdef SOC_SERIES_HT32F5
  93. ADC_RegularChannelConfig(adc_x,channel,0);
  94. #endif
  95. #ifdef SOC_SERIES_HT32F1
  96. ADC_RegularChannelConfig(adc_x,channel,0,0);
  97. #endif
  98. /* enable Software triggered */
  99. ADC_SoftwareStartConvCmd(adc_x,ENABLE);
  100. while((!adc_writ_flag) && (timeout < 0xFFFF))
  101. {
  102. /* Wait for the conversion to complete */
  103. adc_writ_flag = ADC_GetFlagStatus(adc_x,ADC_FLAG_SINGLE_EOC);
  104. timeout++;
  105. }
  106. if(timeout >= 0xFFFF)
  107. {
  108. LOG_D("channel%d converts timeout, please confirm adc_x enabled or not", channel);
  109. /* disable Software triggered */
  110. ADC_SoftwareStartConvCmd(adc_x,DISABLE);
  111. return -RT_ERROR;
  112. }
  113. /* clear ADC_FLAG_SINGLE_EOC flag */
  114. ADC_ClearIntPendingBit(adc_x,ADC_FLAG_SINGLE_EOC);
  115. /* get adc value */
  116. *value = ADC_GetConversionData(adc_x,ADC_REGULAR_DATA0);
  117. /* disable Software triggered */
  118. ADC_SoftwareStartConvCmd(adc_x,DISABLE);
  119. return RT_EOK;
  120. }
  121. static rt_uint8_t ht32_adc_get_resolution(struct rt_adc_device *device)
  122. {
  123. return 0;
  124. }
  125. static rt_int16_t ht32_adc_get_vref(struct rt_adc_device *device)
  126. {
  127. return 0;
  128. }
  129. /* ADC Device Operation Function Interface */
  130. static const struct rt_adc_ops ht32_adc_ops =
  131. {
  132. .enabled = ht32_adc_enabled,
  133. .convert = ht32_adc_convert,
  134. .get_resolution = ht32_adc_get_resolution,
  135. .get_vref = ht32_adc_get_vref,
  136. };
  137. static int rt_hw_adc_init(void)
  138. {
  139. int result = RT_EOK;
  140. int i = 0;
  141. for (i = 0; i < sizeof(ht32_adc_obj) / sizeof(ht32_adc_obj[0]); i++)
  142. {
  143. /* register ADC device */
  144. if (rt_hw_adc_register(&ht32_adc_obj[i].ht32_adc_device, ht32_adc_obj[i].name, &ht32_adc_ops, ht32_adc_obj[i].adc_x) == RT_EOK)
  145. {
  146. LOG_D("%s register success", ht32_adc_obj[i].name);
  147. }
  148. else
  149. {
  150. LOG_E("%s register failed", ht32_adc_obj[i].name);
  151. result = -RT_ERROR;
  152. }
  153. }
  154. return result;
  155. }
  156. INIT_BOARD_EXPORT(rt_hw_adc_init);
  157. #endif /* RT_USING_ADC */