drv_dac.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. * Copyright (C) 2022-2024, Xiaohua Semiconductor Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-05-12 CDT first version
  9. */
  10. #include <board.h>
  11. #if defined(BSP_USING_DAC1) || defined(BSP_USING_DAC2) || defined(BSP_USING_DAC3) || defined(BSP_USING_DAC4)
  12. #include <drivers/dac.h>
  13. #include <drv_dac.h>
  14. #include <drv_config.h>
  15. #include "rtdevice.h"
  16. #include "hc32_ll.h"
  17. #include <drv_log.h>
  18. #include "board_config.h"
  19. /* DAC features */
  20. #define DAC_CHANNEL_ID_MAX (DAC_CH2 + 1U)
  21. #define DAC_RESOLUTION (12)
  22. #define DAC_LEFT_ALIGNED_DATA_MASK (0xFFF0U)
  23. #define DAC_RIGHT_ALIGNED_DATA_MASK (0xFFFU)
  24. typedef struct
  25. {
  26. struct rt_dac_device rt_dac;
  27. CM_DAC_TypeDef *instance;
  28. struct dac_dev_init_params init;
  29. } dac_device;
  30. static dac_device _g_dac_dev_array[] =
  31. {
  32. #ifdef BSP_USING_DAC1
  33. {
  34. {0},
  35. #if defined (HC32F4A0) || defined (HC32F472) || defined (HC32F4A8) || defined (HC32F334)
  36. CM_DAC1,
  37. #elif defined (HC32F448)
  38. CM_DAC,
  39. #endif
  40. DAC1_INIT_PARAMS,
  41. },
  42. #endif
  43. #ifdef BSP_USING_DAC2
  44. {
  45. {0},
  46. CM_DAC2,
  47. DAC2_INIT_PARAMS,
  48. },
  49. #endif
  50. #ifdef BSP_USING_DAC3
  51. {
  52. {0},
  53. CM_DAC3,
  54. DAC3_INIT_PARAMS,
  55. },
  56. #endif
  57. #ifdef BSP_USING_DAC4
  58. {
  59. {0},
  60. CM_DAC4,
  61. DAC4_INIT_PARAMS,
  62. },
  63. #endif
  64. };
  65. static rt_uint16_t _dac_get_channel(rt_uint32_t channel)
  66. {
  67. rt_uint16_t ll_channel = 0;
  68. switch (channel)
  69. {
  70. case 1:
  71. ll_channel = DAC_CH1;
  72. break;
  73. case 2:
  74. ll_channel = DAC_CH2;
  75. break;
  76. default:
  77. RT_ASSERT(0);
  78. break;
  79. }
  80. return ll_channel;
  81. }
  82. static rt_err_t _dac_enabled(struct rt_dac_device *device, rt_uint32_t channel)
  83. {
  84. RT_ASSERT(device != RT_NULL);
  85. RT_ASSERT(channel <= DAC_CHANNEL_ID_MAX);
  86. CM_DAC_TypeDef *p_ll_instance = device->parent.user_data;
  87. uint16_t ll_channel = _dac_get_channel(channel);
  88. int32_t result = DAC_Start(p_ll_instance, ll_channel);
  89. return (result == LL_OK) ? RT_EOK : -RT_ERROR;
  90. }
  91. static rt_err_t _dac_disabled(struct rt_dac_device *device, rt_uint32_t channel)
  92. {
  93. RT_ASSERT(device != RT_NULL);
  94. RT_ASSERT(channel <= DAC_CHANNEL_ID_MAX);
  95. CM_DAC_TypeDef *p_ll_instance = device->parent.user_data;
  96. uint16_t ll_channel = _dac_get_channel(channel);
  97. int32_t result = DAC_Stop(p_ll_instance, ll_channel);
  98. return (result == LL_OK) ? RT_EOK : -RT_ERROR;
  99. }
  100. static rt_uint8_t _dac_get_resolution(struct rt_dac_device *device)
  101. {
  102. return DAC_RESOLUTION;
  103. }
  104. static rt_err_t _dac_set_value(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value)
  105. {
  106. RT_ASSERT(device != RT_NULL);
  107. RT_ASSERT(channel <= DAC_CHANNEL_ID_MAX);
  108. CM_DAC_TypeDef *p_ll_instance = device->parent.user_data;
  109. if (READ_REG16_BIT(p_ll_instance->DACR, DAC_DACR_DPSEL) == DAC_DATA_ALIGN_LEFT)
  110. {
  111. RT_ASSERT(0U == (*value & ~DAC_LEFT_ALIGNED_DATA_MASK));
  112. }
  113. else
  114. {
  115. RT_ASSERT(0U == (*value & ~DAC_RIGHT_ALIGNED_DATA_MASK));
  116. }
  117. uint16_t ll_channel = _dac_get_channel(channel);
  118. DAC_SetChData(p_ll_instance, ll_channel, *value);
  119. return RT_EOK;
  120. }
  121. static const struct rt_dac_ops g_dac_ops =
  122. {
  123. .disabled = _dac_disabled,
  124. .enabled = _dac_enabled,
  125. .convert = _dac_set_value,
  126. .get_resolution = _dac_get_resolution,
  127. };
  128. static void _dac_clock_enable(void)
  129. {
  130. #if defined(BSP_USING_DAC1)
  131. #if defined (HC32F4A0) || defined (HC32F472) || defined (HC32F4A8) || defined (HC32F334)
  132. FCG_Fcg3PeriphClockCmd(FCG3_PERIPH_DAC1, ENABLE);
  133. #elif defined (HC32F448)
  134. FCG_Fcg3PeriphClockCmd(FCG3_PERIPH_DAC, ENABLE);
  135. #endif
  136. #endif
  137. #if defined(BSP_USING_DAC2)
  138. FCG_Fcg3PeriphClockCmd(FCG3_PERIPH_DAC2, ENABLE);
  139. #endif
  140. #if defined(BSP_USING_DAC3)
  141. FCG_Fcg3PeriphClockCmd(FCG3_PERIPH_DAC3, ENABLE);
  142. #endif
  143. #if defined(BSP_USING_DAC4)
  144. FCG_Fcg3PeriphClockCmd(FCG3_PERIPH_DAC4, ENABLE);
  145. #endif
  146. }
  147. extern rt_err_t rt_hw_board_dac_init(CM_DAC_TypeDef *DACx);
  148. int rt_hw_dac_init(void)
  149. {
  150. int result = RT_EOK;
  151. rt_err_t ret;
  152. int i = 0;
  153. stc_dac_init_t stcDacInit = {0};
  154. int32_t ll_ret = 0;
  155. _dac_clock_enable();
  156. uint32_t dev_cnt = sizeof(_g_dac_dev_array) / sizeof(_g_dac_dev_array[0]);
  157. for (; i < dev_cnt; i++)
  158. {
  159. DAC_DeInit(_g_dac_dev_array[i].instance);
  160. stcDacInit.enOutput = (en_functional_state_t)_g_dac_dev_array[i].init.ch1_output_enable;
  161. #if defined (HC32F4A0) || defined (HC32F448) || defined (HC32F4A8)
  162. stcDacInit.u16Src = _g_dac_dev_array[i].init.ch1_data_src;
  163. #endif
  164. ll_ret = DAC_Init((void *)_g_dac_dev_array[i].instance, DAC_CH1, &stcDacInit);
  165. #if defined (HC32F4A0) || defined (HC32F448) || defined (HC32F4A8) || defined (HC32F460)
  166. #if defined (HC32F4A0) || defined (HC32F448) || defined (HC32F4A8)
  167. stcDacInit.u16Src = _g_dac_dev_array[i].init.ch2_data_src;
  168. #endif
  169. stcDacInit.enOutput = _g_dac_dev_array[i].init.ch2_output_enable;
  170. ll_ret = DAC_Init((void *)_g_dac_dev_array[i].instance, DAC_CH2, &stcDacInit);
  171. #elif defined (HC32F334)
  172. if (CM_DAC1 == (void *)_g_dac_dev_array[i].instance)
  173. {
  174. stcDacInit.enOutput = (en_functional_state_t)_g_dac_dev_array[i].init.ch2_output_enable;
  175. ll_ret = DAC_Init((void *)_g_dac_dev_array[i].instance, DAC_CH2, &stcDacInit);
  176. }
  177. #endif
  178. DAC_DataRegAlignConfig(_g_dac_dev_array[i].instance, _g_dac_dev_array[i].init.data_align);
  179. if (ll_ret != LL_OK)
  180. {
  181. ret = -RT_ERROR;
  182. break;
  183. }
  184. DAC_ADCPrioConfig(_g_dac_dev_array[i].instance, _g_dac_dev_array[i].init.dac_adp_sel, ENABLE);
  185. DAC_ADCPrioCmd(_g_dac_dev_array[i].instance, (en_functional_state_t)_g_dac_dev_array[i].init.dac_adp_enable);
  186. #if defined (HC32F472)
  187. DAC_SetAmpGain(_g_dac_dev_array[i].instance, DAC_CH1, _g_dac_dev_array[i].init.ch1_amp_gain);
  188. DAC_SetAmpGain(_g_dac_dev_array[i].instance, DAC_CH2, _g_dac_dev_array[i].init.ch2_amp_gain);
  189. #endif
  190. DAC_AMPCmd(_g_dac_dev_array[i].instance, DAC_CH1, (en_functional_state_t)_g_dac_dev_array[i].init.ch1_amp_enable);
  191. #if defined (HC32F4A0) || defined (HC32F448) || defined (HC32F4A8) || defined (HC32F460)
  192. DAC_AMPCmd(_g_dac_dev_array[i].instance, DAC_CH2, _g_dac_dev_array[i].init.ch2_amp_enable);
  193. #elif defined (HC32F334)
  194. if (CM_DAC1 == (void *)_g_dac_dev_array[i].instance)
  195. {
  196. DAC_AMPCmd(_g_dac_dev_array[i].instance, DAC_CH2, (en_functional_state_t)_g_dac_dev_array[i].init.ch2_amp_enable);
  197. }
  198. #endif
  199. rt_hw_board_dac_init(_g_dac_dev_array[i].instance);
  200. ret = rt_hw_dac_register(&_g_dac_dev_array[i].rt_dac, \
  201. (const char *)_g_dac_dev_array[i].init.name, \
  202. &g_dac_ops, (void *)_g_dac_dev_array[i].instance);
  203. if (ret == RT_EOK)
  204. {
  205. LOG_D("%s init success", (const char *)_g_dac_dev_array[i].init.name);
  206. }
  207. else
  208. {
  209. LOG_E("%s register failed", (const char *)_g_dac_dev_array[i].init.name);
  210. result = -RT_ERROR;
  211. }
  212. }
  213. return result;
  214. }
  215. INIT_DEVICE_EXPORT(rt_hw_dac_init);
  216. #endif /* BSP_USING_DAC */