drv_adc.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-09-16 linshire the first version which add from wch
  9. */
  10. #include <board.h>
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include "drv_adc.h"
  14. #if defined(BSP_USING_ADC1) || defined(BSP_USING_ADC2)
  15. //#define DRV_DEBUG
  16. #define LOG_TAG "drv.adc"
  17. #include <drv_log.h>
  18. static ADC_HandleTypeDef adc_config[] =
  19. {
  20. #ifdef BSP_USING_ADC1
  21. { \
  22. .Instance = ADC1, \
  23. .Init.ADC_Mode = ADC_Mode_Independent, \
  24. .Init.ADC_ScanConvMode = DISABLE, \
  25. .Init.ADC_ContinuousConvMode = DISABLE, \
  26. .Init.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None, \
  27. .Init.ADC_DataAlign = ADC_DataAlign_Right, \
  28. .Init.ADC_NbrOfChannel = 1, \
  29. },
  30. #endif
  31. #ifdef BSP_USING_ADC2
  32. { \
  33. .Instance = ADC2, \
  34. .Init.ADC_Mode = ADC_Mode_Independent, \
  35. .Init.ADC_ScanConvMode = DISABLE, \
  36. .Init.ADC_ContinuousConvMode = DISABLE, \
  37. .Init.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None, \
  38. .Init.ADC_DataAlign = ADC_DataAlign_Right, \
  39. .Init.ADC_NbrOfChannel = 1, \
  40. }
  41. #endif
  42. };
  43. struct ch32_adc
  44. {
  45. ADC_HandleTypeDef ADC_Handler;
  46. struct rt_adc_device ch32_adc_device;
  47. };
  48. static struct ch32_adc ch32_adc_obj[sizeof(adc_config) / sizeof(adc_config[0])];
  49. static rt_uint8_t ch32_adc_get_resolution(struct rt_adc_device *device)
  50. {
  51. //the resolution which can not be changed is just 12bit;
  52. return 12;
  53. }
  54. static rt_int16_t ch32_adc_get_vref (struct rt_adc_device *device)
  55. {
  56. RT_ASSERT(device);
  57. return 3300;
  58. }
  59. static rt_err_t ch32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
  60. {
  61. ADC_HandleTypeDef *ch32_adc_handler;
  62. RT_ASSERT(device != RT_NULL);
  63. ch32_adc_handler = device->parent.user_data;
  64. if (enabled)
  65. {
  66. ADC_Cmd(ch32_adc_handler->Instance, ENABLE);
  67. }
  68. else
  69. {
  70. ADC_Cmd(ch32_adc_handler->Instance, DISABLE);
  71. }
  72. return RT_EOK;
  73. }
  74. static rt_uint32_t ch32_adc_get_channel(rt_uint32_t channel)
  75. {
  76. rt_uint32_t ch32_channel = 0;
  77. switch (channel)
  78. {
  79. case 0:
  80. ch32_channel = ADC_Channel_0;
  81. break;
  82. case 1:
  83. ch32_channel = ADC_Channel_1;
  84. break;
  85. case 2:
  86. ch32_channel = ADC_Channel_2;
  87. break;
  88. case 3:
  89. ch32_channel = ADC_Channel_3;
  90. break;
  91. case 4:
  92. ch32_channel = ADC_Channel_4;
  93. break;
  94. case 5:
  95. ch32_channel = ADC_Channel_5;
  96. break;
  97. case 6:
  98. ch32_channel = ADC_Channel_6;
  99. break;
  100. case 7:
  101. ch32_channel = ADC_Channel_7;
  102. break;
  103. case 8:
  104. ch32_channel = ADC_Channel_8;
  105. break;
  106. case 9:
  107. ch32_channel = ADC_Channel_9;
  108. break;
  109. case 10:
  110. ch32_channel = ADC_Channel_10;
  111. break;
  112. case 11:
  113. ch32_channel = ADC_Channel_11;
  114. break;
  115. case 12:
  116. ch32_channel = ADC_Channel_12;
  117. break;
  118. case 13:
  119. ch32_channel = ADC_Channel_13;
  120. break;
  121. case 14:
  122. ch32_channel = ADC_Channel_14;
  123. break;
  124. case 15:
  125. ch32_channel = ADC_Channel_15;
  126. break;
  127. #ifdef ADC_CHANNEL_16
  128. case 16:
  129. ch32_channel = ADC_Channel_16;
  130. break;
  131. #endif /* ADC_CHANNEL_16 */
  132. #ifdef ADC_CHANNEL_17
  133. case 17:
  134. ch32_channel = ADC_Channel_17;
  135. break;
  136. #endif /* ADC_CHANNEL_17 */
  137. #ifdef ADC_CHANNEL_18
  138. case 18:
  139. ch32_channel = ADC_Channel_18;
  140. break;
  141. #endif /* ADC_CHANNEL_18 */
  142. #ifdef ADC_CHANNEL_19
  143. case 19:
  144. ch32_channel = ADC_Channel_19;
  145. break;
  146. #endif /* ADC_CHANNEL_19 */
  147. }
  148. return ch32_channel;
  149. }
  150. static rt_err_t ch32_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
  151. {
  152. ADC_ChannelConfTypeDef ADC_ChanConf;
  153. ADC_HandleTypeDef *ch32_adc_handler;
  154. RT_ASSERT(device != RT_NULL);
  155. RT_ASSERT(value != RT_NULL);
  156. ch32_adc_handler = device->parent.user_data;
  157. rt_memset(&ADC_ChanConf, 0, sizeof(ADC_ChanConf));
  158. #ifndef ADC_CHANNEL_16
  159. if (channel == 16)
  160. {
  161. LOG_E("ADC channel must not be 16.");
  162. return -RT_ERROR;
  163. }
  164. #endif
  165. /* ADC channel number is up to 17 */
  166. #if !defined(ADC_CHANNEL_18)
  167. if (channel <= 17)
  168. /* ADC channel number is up to 19 */
  169. #elif defined(ADC_CHANNEL_19)
  170. if (channel <= 19)
  171. /* ADC channel number is up to 18 */
  172. #else
  173. if (channel <= 18)
  174. #endif
  175. {
  176. /* set ch32 ADC channel */
  177. ADC_ChanConf.Channel = ch32_adc_get_channel(channel);
  178. }
  179. else
  180. {
  181. #if !defined(ADC_CHANNEL_18)
  182. LOG_E("ADC channel must be between 0 and 17.");
  183. #elif defined(ADC_CHANNEL_19)
  184. LOG_E("ADC channel must be between 0 and 19.");
  185. #else
  186. LOG_E("ADC channel must be between 0 and 18.");
  187. #endif
  188. return -RT_ERROR;
  189. }
  190. ADC_ChanConf.Rank = 1;
  191. ADC_ChanConf.SamplingTime = ADC_SampleTime_239Cycles5;
  192. ADC_RegularChannelConfig(ch32_adc_handler->Instance,ADC_ChanConf.Channel , ADC_ChanConf.Rank, ADC_ChanConf.SamplingTime );
  193. /* start ADC */
  194. ADC_SoftwareStartConvCmd(ch32_adc_handler->Instance, ENABLE);
  195. /* Wait for the ADC to convert */
  196. while(!ADC_GetFlagStatus(ch32_adc_handler->Instance, ADC_FLAG_EOC ));
  197. /* get ADC value */
  198. *value = (rt_uint32_t)ADC_GetConversionValue(ch32_adc_handler->Instance);
  199. ADC_ClearFlag( ch32_adc_handler->Instance, ADC_FLAG_EOC);
  200. return RT_EOK;
  201. }
  202. static const struct rt_adc_ops ch32_adc_ops =
  203. {
  204. .enabled = ch32_adc_enabled,
  205. .convert = ch32_get_adc_value,
  206. .get_resolution = ch32_adc_get_resolution,
  207. .get_vref = ch32_adc_get_vref
  208. };
  209. static int ch32_adc_init(void)
  210. {
  211. int result = RT_EOK;
  212. /* save adc name */
  213. char name_buf[5] = {'a', 'd', 'c', '0', 0};
  214. int i = 0;
  215. for (i = 0; i < sizeof(adc_config) / sizeof(adc_config[0]); i++)
  216. {
  217. /* ADC init */
  218. name_buf[3] = '0';
  219. ch32_adc_obj[i].ADC_Handler = adc_config[i];
  220. #if defined(ADC1)
  221. if (ch32_adc_obj[i].ADC_Handler.Instance == ADC1)
  222. {
  223. name_buf[3] = '1';
  224. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE );
  225. }
  226. #endif
  227. #if defined(ADC2)
  228. if (ch32_adc_obj[i].ADC_Handler.Instance == ADC2)
  229. {
  230. name_buf[3] = '2';
  231. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE );
  232. }
  233. #endif
  234. {
  235. ADC_Init(ch32_adc_obj[i].ADC_Handler.Instance,&ch32_adc_obj[i].ADC_Handler.Init );
  236. /* register ADC device */
  237. if (rt_hw_adc_register(&ch32_adc_obj[i].ch32_adc_device, name_buf, &ch32_adc_ops, &ch32_adc_obj[i].ADC_Handler) == RT_EOK)
  238. {
  239. LOG_D("%s init success", name_buf);
  240. }
  241. else
  242. {
  243. LOG_E("%s register failed", name_buf);
  244. result = -RT_ERROR;
  245. }
  246. }
  247. }
  248. return result;
  249. }
  250. INIT_DEVICE_EXPORT(ch32_adc_init);
  251. #endif /* BSP_USING_ADC */