Files
mr-library/bsp/wch/driver/drv_dac.c

158 lines
3.8 KiB
C

/*
* @copyright (c) 2023-2024, MR Development Team
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2023-11-14 MacRsh First version
*/
#include "drv_dac.h"
#ifdef MR_USING_DAC
#if !defined(MR_USING_DAC1)
#warning "Please enable at least one DAC driver"
#endif /* !defined(MR_USING_DAC1) */
static struct drv_dac_data dac_drv_data[] =
{
#ifdef MR_USING_DAC1
{RCC_APB1Periph_DAC}
#endif /* MR_USING_DAC1 */
};
static struct drv_dac_channel_data dac_channel_drv_data[] = DRV_DAC_CHANNEL_CONFIG;
static struct mr_dac dac_dev;
static struct drv_dac_channel_data *drv_dac_get_channel_data(int channel)
{
if ((channel >= MR_ARRAY_NUM(dac_channel_drv_data)) || (dac_channel_drv_data[channel].port == NULL))
{
return NULL;
}
return &dac_channel_drv_data[channel];
}
static int drv_dac_configure(struct mr_dac *dac, int state)
{
struct drv_dac_data *dac_data = (struct drv_dac_data *)dac->dev.drv->data;
/* Configure clock */
RCC_APB1PeriphClockCmd(dac_data->clock, state);
return MR_EOK;
}
static int drv_dac_channel_configure(struct mr_dac *dac, int channel, int state)
{
struct drv_dac_channel_data *dac_channel_data = drv_dac_get_channel_data(channel);
GPIO_InitTypeDef GPIO_InitStructure = {0};
DAC_InitTypeDef DAC_InitStructure = {0};
/* Check channel is valid */
if (dac_channel_data == NULL)
{
return MR_EINVAL;
}
/* Configure clock */
RCC_APB2PeriphClockCmd(dac_channel_data->gpio_clock, ENABLE);
switch (dac_channel_data->channel)
{
#ifdef DAC_Channel_1
case DAC_Channel_1:
{
DAC_SetChannel1Data(DAC_Align_12b_R, 0);
break;
}
#endif /* DAC_Channel_1 */
#ifdef DAC_Channel_2
case DAC_Channel_2:
{
DAC_SetChannel2Data(DAC_Align_12b_R, 0);
break;
}
#endif /* DAC_Channel_2 */
default:
{
return MR_EINVAL;
}
}
/* Configure pin */
if (dac_channel_data->port != MR_NULL)
{
if (state == MR_ENABLE)
{
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Pin = dac_channel_data->pin;
GPIO_Init(dac_channel_data->port, &GPIO_InitStructure);
}
}
/* Configure DAC */
DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
DAC_Init(dac_channel_data->channel, &DAC_InitStructure);
DAC_Cmd(dac_channel_data->channel, state);
return MR_EOK;
}
static void drv_dac_write(struct mr_dac *dac, int channel, uint32_t data)
{
struct drv_dac_channel_data *dac_channel_data = drv_dac_get_channel_data(channel);
/* Check channel is valid */
if (dac_channel_data == NULL)
{
return;
}
/* Write data */
switch (dac_channel_data->channel)
{
#ifdef DAC_Channel_1
case DAC_Channel_1:
{
DAC_SetChannel1Data(DAC_Align_12b_R, data);
break;
}
#endif /* DAC_Channel_1 */
#ifdef DAC_Channel_2
case DAC_Channel_2:
{
DAC_SetChannel2Data(DAC_Align_12b_R, data);
break;
}
#endif /* DAC_Channel_2 */
default:
{
return;
}
}
}
static struct mr_dac_ops dac_drv_ops =
{
drv_dac_configure,
drv_dac_channel_configure,
drv_dac_write,
};
static struct mr_drv dac_drv =
{
&dac_drv_ops,
&dac_drv_data,
};
static void drv_dac_init(void)
{
mr_dac_register(&dac_dev, "dac1", &dac_drv);
}
MR_INIT_DRV_EXPORT(drv_dac_init);
#endif /* MR_USING_DAC */