| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- /*
- * Copyright (C) 2022-2024, Xiaohua Semiconductor Co., Ltd.
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2023-05-12 CDT first version
- */
- #include <board.h>
- #if defined(BSP_USING_DAC1) || defined(BSP_USING_DAC2) || defined(BSP_USING_DAC3) || defined(BSP_USING_DAC4)
- #include <drivers/dac.h>
- #include <drv_dac.h>
- #include <drv_config.h>
- #include "rtdevice.h"
- #include "hc32_ll.h"
- #include <drv_log.h>
- #include "board_config.h"
- /* DAC features */
- #define DAC_CHANNEL_ID_MAX (DAC_CH2 + 1U)
- #define DAC_RESOLUTION (12)
- #define DAC_LEFT_ALIGNED_DATA_MASK (0xFFF0U)
- #define DAC_RIGHT_ALIGNED_DATA_MASK (0xFFFU)
- typedef struct
- {
- struct rt_dac_device rt_dac;
- CM_DAC_TypeDef *instance;
- struct dac_dev_init_params init;
- } dac_device;
- static dac_device _g_dac_dev_array[] =
- {
- #ifdef BSP_USING_DAC1
- {
- {0},
- #if defined (HC32F4A0) || defined (HC32F472) || defined (HC32F4A8) || defined (HC32F334)
- CM_DAC1,
- #elif defined (HC32F448)
- CM_DAC,
- #endif
- DAC1_INIT_PARAMS,
- },
- #endif
- #ifdef BSP_USING_DAC2
- {
- {0},
- CM_DAC2,
- DAC2_INIT_PARAMS,
- },
- #endif
- #ifdef BSP_USING_DAC3
- {
- {0},
- CM_DAC3,
- DAC3_INIT_PARAMS,
- },
- #endif
- #ifdef BSP_USING_DAC4
- {
- {0},
- CM_DAC4,
- DAC4_INIT_PARAMS,
- },
- #endif
- };
- static rt_uint16_t _dac_get_channel(rt_uint32_t channel)
- {
- rt_uint16_t ll_channel = 0;
- switch (channel)
- {
- case 1:
- ll_channel = DAC_CH1;
- break;
- case 2:
- ll_channel = DAC_CH2;
- break;
- default:
- RT_ASSERT(0);
- break;
- }
- return ll_channel;
- }
- static rt_err_t _dac_enabled(struct rt_dac_device *device, rt_uint32_t channel)
- {
- RT_ASSERT(device != RT_NULL);
- RT_ASSERT(channel <= DAC_CHANNEL_ID_MAX);
- CM_DAC_TypeDef *p_ll_instance = device->parent.user_data;
- uint16_t ll_channel = _dac_get_channel(channel);
- int32_t result = DAC_Start(p_ll_instance, ll_channel);
- return (result == LL_OK) ? RT_EOK : -RT_ERROR;
- }
- static rt_err_t _dac_disabled(struct rt_dac_device *device, rt_uint32_t channel)
- {
- RT_ASSERT(device != RT_NULL);
- RT_ASSERT(channel <= DAC_CHANNEL_ID_MAX);
- CM_DAC_TypeDef *p_ll_instance = device->parent.user_data;
- uint16_t ll_channel = _dac_get_channel(channel);
- int32_t result = DAC_Stop(p_ll_instance, ll_channel);
- return (result == LL_OK) ? RT_EOK : -RT_ERROR;
- }
- static rt_uint8_t _dac_get_resolution(struct rt_dac_device *device)
- {
- return DAC_RESOLUTION;
- }
- static rt_err_t _dac_set_value(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value)
- {
- RT_ASSERT(device != RT_NULL);
- RT_ASSERT(channel <= DAC_CHANNEL_ID_MAX);
- CM_DAC_TypeDef *p_ll_instance = device->parent.user_data;
- if (READ_REG16_BIT(p_ll_instance->DACR, DAC_DACR_DPSEL) == DAC_DATA_ALIGN_LEFT)
- {
- RT_ASSERT(0U == (*value & ~DAC_LEFT_ALIGNED_DATA_MASK));
- }
- else
- {
- RT_ASSERT(0U == (*value & ~DAC_RIGHT_ALIGNED_DATA_MASK));
- }
- uint16_t ll_channel = _dac_get_channel(channel);
- DAC_SetChData(p_ll_instance, ll_channel, *value);
- return RT_EOK;
- }
- static const struct rt_dac_ops g_dac_ops =
- {
- .disabled = _dac_disabled,
- .enabled = _dac_enabled,
- .convert = _dac_set_value,
- .get_resolution = _dac_get_resolution,
- };
- static void _dac_clock_enable(void)
- {
- #if defined(BSP_USING_DAC1)
- #if defined (HC32F4A0) || defined (HC32F472) || defined (HC32F4A8) || defined (HC32F334)
- FCG_Fcg3PeriphClockCmd(FCG3_PERIPH_DAC1, ENABLE);
- #elif defined (HC32F448)
- FCG_Fcg3PeriphClockCmd(FCG3_PERIPH_DAC, ENABLE);
- #endif
- #endif
- #if defined(BSP_USING_DAC2)
- FCG_Fcg3PeriphClockCmd(FCG3_PERIPH_DAC2, ENABLE);
- #endif
- #if defined(BSP_USING_DAC3)
- FCG_Fcg3PeriphClockCmd(FCG3_PERIPH_DAC3, ENABLE);
- #endif
- #if defined(BSP_USING_DAC4)
- FCG_Fcg3PeriphClockCmd(FCG3_PERIPH_DAC4, ENABLE);
- #endif
- }
- extern rt_err_t rt_hw_board_dac_init(CM_DAC_TypeDef *DACx);
- int rt_hw_dac_init(void)
- {
- int result = RT_EOK;
- rt_err_t ret;
- int i = 0;
- stc_dac_init_t stcDacInit = {0};
- int32_t ll_ret = 0;
- _dac_clock_enable();
- uint32_t dev_cnt = sizeof(_g_dac_dev_array) / sizeof(_g_dac_dev_array[0]);
- for (; i < dev_cnt; i++)
- {
- DAC_DeInit(_g_dac_dev_array[i].instance);
- stcDacInit.enOutput = (en_functional_state_t)_g_dac_dev_array[i].init.ch1_output_enable;
- #if defined (HC32F4A0) || defined (HC32F448) || defined (HC32F4A8)
- stcDacInit.u16Src = _g_dac_dev_array[i].init.ch1_data_src;
- #endif
- ll_ret = DAC_Init((void *)_g_dac_dev_array[i].instance, DAC_CH1, &stcDacInit);
- #if defined (HC32F4A0) || defined (HC32F448) || defined (HC32F4A8) || defined (HC32F460)
- #if defined (HC32F4A0) || defined (HC32F448) || defined (HC32F4A8)
- stcDacInit.u16Src = _g_dac_dev_array[i].init.ch2_data_src;
- #endif
- stcDacInit.enOutput = _g_dac_dev_array[i].init.ch2_output_enable;
- ll_ret = DAC_Init((void *)_g_dac_dev_array[i].instance, DAC_CH2, &stcDacInit);
- #elif defined (HC32F334)
- if (CM_DAC1 == (void *)_g_dac_dev_array[i].instance)
- {
- stcDacInit.enOutput = (en_functional_state_t)_g_dac_dev_array[i].init.ch2_output_enable;
- ll_ret = DAC_Init((void *)_g_dac_dev_array[i].instance, DAC_CH2, &stcDacInit);
- }
- #endif
- DAC_DataRegAlignConfig(_g_dac_dev_array[i].instance, _g_dac_dev_array[i].init.data_align);
- if (ll_ret != LL_OK)
- {
- ret = -RT_ERROR;
- break;
- }
- DAC_ADCPrioConfig(_g_dac_dev_array[i].instance, _g_dac_dev_array[i].init.dac_adp_sel, ENABLE);
- DAC_ADCPrioCmd(_g_dac_dev_array[i].instance, (en_functional_state_t)_g_dac_dev_array[i].init.dac_adp_enable);
- #if defined (HC32F472)
- DAC_SetAmpGain(_g_dac_dev_array[i].instance, DAC_CH1, _g_dac_dev_array[i].init.ch1_amp_gain);
- DAC_SetAmpGain(_g_dac_dev_array[i].instance, DAC_CH2, _g_dac_dev_array[i].init.ch2_amp_gain);
- #endif
- DAC_AMPCmd(_g_dac_dev_array[i].instance, DAC_CH1, (en_functional_state_t)_g_dac_dev_array[i].init.ch1_amp_enable);
- #if defined (HC32F4A0) || defined (HC32F448) || defined (HC32F4A8) || defined (HC32F460)
- DAC_AMPCmd(_g_dac_dev_array[i].instance, DAC_CH2, _g_dac_dev_array[i].init.ch2_amp_enable);
- #elif defined (HC32F334)
- if (CM_DAC1 == (void *)_g_dac_dev_array[i].instance)
- {
- DAC_AMPCmd(_g_dac_dev_array[i].instance, DAC_CH2, (en_functional_state_t)_g_dac_dev_array[i].init.ch2_amp_enable);
- }
- #endif
- rt_hw_board_dac_init(_g_dac_dev_array[i].instance);
- ret = rt_hw_dac_register(&_g_dac_dev_array[i].rt_dac, \
- (const char *)_g_dac_dev_array[i].init.name, \
- &g_dac_ops, (void *)_g_dac_dev_array[i].instance);
- if (ret == RT_EOK)
- {
- LOG_D("%s init success", (const char *)_g_dac_dev_array[i].init.name);
- }
- else
- {
- LOG_E("%s register failed", (const char *)_g_dac_dev_array[i].init.name);
- result = -RT_ERROR;
- }
- }
- return result;
- }
- INIT_DEVICE_EXPORT(rt_hw_dac_init);
- #endif /* BSP_USING_DAC */
|