feat support DAC driver for aiit-arm32-board and stm32f407-st-discovery

This commit is contained in:
Liu_Weichao 2022-01-11 16:56:57 +08:00
parent d789b66ed2
commit bac136c51d
41 changed files with 2557 additions and 36 deletions

View File

@ -18,5 +18,16 @@ menu "test app"
default "/dev/adc1_dev"
endif
endif
menuconfig USER_TEST_DAC
bool "Config test dac"
default n
if USER_TEST_DAC
if ADD_XIUOS_FETURES
config DAC_DEV_DRIVER
string "Set DAC dev path"
default "/dev/dac_dev"
endif
endif
endif
endmenu

View File

@ -8,4 +8,8 @@ ifeq ($(CONFIG_USER_TEST_ADC),y)
SRC_FILES += test_adc.c
endif
ifeq ($(CONFIG_USER_TEST_DAC),y)
SRC_FILES += test_dac.c
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -52,7 +52,9 @@ void test_adc()
printf("adc sample %u value integer %u decimal %u\n", adc_sample, (uint16)adc_value, adc_value_decimal);
PrivClose(adc_fd);
return;
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
test_adc, test_adc, read 3.3 voltage data from adc);
// SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
// test_adc, test_adc, read 3.3 voltage data from adc);

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file: test_dac.c
* @brief: a application of dac function
* @version: 2.0
* @author: AIIT XUOS Lab
* @date: 2022/1/11
*/
#include <stdio.h>
#include <string.h>
#include <transform.h>
void test_dac()
{
int dac_fd;
uint16 dac_set_value = 800;
uint16 dac_sample, dac_value_decimal = 0;
float dac_value;
dac_fd = PrivOpen(DAC_DEV_DRIVER, O_RDWR);
if (dac_fd < 0) {
KPrintf("open dac fd error %d\n", dac_fd);
return;
}
struct PrivIoctlCfg ioctl_cfg;
ioctl_cfg.ioctl_driver_type = DAC_TYPE;
ioctl_cfg.args = &dac_set_value;
if (0 != PrivIoctl(dac_fd, OPE_CFG, &ioctl_cfg)) {
KPrintf("ioctl dac fd error %d\n", dac_fd);
PrivClose(dac_fd);
return;
}
PrivRead(dac_fd, &dac_sample, 2);
dac_value = (float)dac_sample * (3.3 / 4096);//Vref+ need to be 3.3V
dac_value_decimal = (dac_value - (uint16)dac_value) * 1000;
printf("dac sample %u value integer %u decimal %u\n", dac_sample, (uint16)dac_value, dac_value_decimal);
PrivClose(dac_fd);
return;
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
test_dac, test_dac, set digital data to dac);

View File

@ -155,6 +155,7 @@ int PrivIoctl(int fd, int cmd, void *args)
ret = ioctl(fd, cmd, ioctl_cfg->args);
break;
case ADC_TYPE:
case DAC_TYPE:
ret = ioctl(fd, cmd, ioctl_cfg->args);
break;
default:

View File

@ -139,6 +139,7 @@ enum IoctlDriverType
I2C_TYPE,
PIN_TYPE,
ADC_TYPE,
DAC_TYPE,
DEFAULT_TYPE,
};

View File

@ -49,6 +49,7 @@ extern int Stm32HwCanBusInit(void);
extern int HwSdioInit();
extern int HwSramInit(void);
extern int Stm32HwAdcInit(void);
extern int Stm32HwDacInit(void);
static void ClockConfiguration()
{
@ -150,6 +151,9 @@ struct InitSequenceDesc _board_init[] =
#endif
#ifdef BSP_USING_ADC
{"hw adc init", Stm32HwAdcInit},
#endif
#ifdef BSP_USING_DAC
{"hw dac init", Stm32HwDacInit},
#endif
{ " NONE ",NONE },
};

View File

@ -102,6 +102,14 @@ if BSP_USING_ADC
source "$BSP_DIR/third_party_driver/adc/Kconfig"
endif
menuconfig BSP_USING_DAC
bool "Using DAC device"
default n
select RESOURCES_DAC
if BSP_USING_DAC
source "$BSP_DIR/third_party_driver/dac/Kconfig"
endif
menuconfig BSP_USING_CAN
bool "Using CAN device"
default n

View File

@ -60,4 +60,8 @@ ifeq ($(CONFIG_BSP_USING_ADC),y)
SRC_DIR += adc
endif
ifeq ($(CONFIG_BSP_USING_DAC),y)
SRC_DIR += dac
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -240,6 +240,15 @@ static uint32 Stm32AdcOpen(void *dev)
return EOK;
}
static uint32 Stm32AdcClose(void *dev)
{
struct AdcHardwareDevice *adc_dev = (struct AdcHardwareDevice *)dev;
ADC_DeInit();
return EOK;
}
static uint32 Stm32AdcRead(void *dev, struct BusBlockReadParam *read_param)
{
struct AdcHardwareDevice *adc_dev = (struct AdcHardwareDevice *)dev;
@ -288,7 +297,7 @@ static uint32 Stm32AdcDrvConfigure(void *drv, struct BusConfigureInfo *configure
static const struct AdcDevDone dev_done =
{
Stm32AdcOpen,
NONE,
Stm32AdcClose,
NONE,
Stm32AdcRead,
};
@ -419,4 +428,6 @@ int Stm32HwAdcInit(void)
return ERROR;
}
#endif
return ret;
}

View File

@ -0,0 +1,17 @@
if BSP_USING_DAC
config DAC_BUS_NAME
string "dac bus name"
default "dac"
config DAC_DRIVER_NAME
string "dac driver name"
default "dac_drv"
config DAC_DEVICE_NAME
string "dac bus device name"
default "dac_dev"
config DAC_GPIO_NUM
int "dac gpio pin num(only support 4 or 5)"
default "4"
endif

View File

@ -0,0 +1,3 @@
SRC_FILES := connect_dac.c hardware_dac.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,168 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_dac.c
* @brief support to register DAC pointer and function
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-1-10
*/
#include <connect_dac.h>
#define _DAC_CONS(string1, string2) string1##string2
#define DAC_CONS(string1, string2) _DAC_CONS(string1, string2)
#ifdef BSP_USING_DAC
#define DAC_GPIO DAC_CONS(GPIO_Pin_, DAC_GPIO_NUM)
#endif
static void DacInit(struct DacHardwareDevice *dac_dev)
{
GPIO_InitTypeDef GPIO_InitStructure;
DAC_InitTypeDef DAC_InitType;
#ifdef BSP_USING_DAC
if (0 == strncmp(dac_dev->haldev.dev_name, DAC_DEVICE_NAME, NAME_NUM_MAX)) {
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//enable GPIOA clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//enable DAC clock
GPIO_InitStructure.GPIO_Pin = DAC_GPIO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
DAC_InitType.DAC_Trigger = DAC_Trigger_None;//disable trigger function TEN1=0
DAC_InitType.DAC_WaveGeneration = DAC_WaveGeneration_None;//disable wave generation function
DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;//mask and amplitude configure
DAC_InitType.DAC_OutputBuffer = DAC_OutputBuffer_Disable;//disable DAC1 output buffer BOFF1=1
DAC_Init(DAC_Channel_1, &DAC_InitType);
DAC_Cmd(DAC_Channel_1, ENABLE);//enable DAC channel 1
DAC_SetChannel1Data(DAC_Align_12b_R, 0);//12 bits、R-Align data format, default 0
}
#endif
}
static uint32 Stm32DacOpen(void *dev)
{
struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dev;
DacInit(dac_dev);
return EOK;
}
static uint32 Stm32DacClose(void *dev)
{
struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dev;
DAC_DeInit();
return EOK;
}
static uint32 Stm32DacRead(void *dev, struct BusBlockReadParam *read_param)
{
struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dev;
uint16 dac_set_value = 0;
dac_set_value = DAC_GetDataOutputValue(DAC_Channel_1);
*(uint16 *)read_param->buffer = dac_set_value;
read_param->read_length = 2;
return read_param->read_length;
}
static uint32 Stm32DacDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(drv);
NULL_PARAM_CHECK(configure_info);
x_err_t ret = EOK;
struct DacDriver *dac_drv = (struct DacDriver *)drv;
struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dac_drv->driver.owner_bus->owner_haldev;
struct Stm32HwDac *dac_cfg = (struct Stm32HwDac *)dac_dev->haldev.private_data;
switch (configure_info->configure_cmd)
{
case OPE_CFG:
dac_cfg->digital_data = *(uint16 *)configure_info->private_data;
DAC_SetChannel1Data(DAC_Align_12b_R, dac_cfg->digital_data);//12 bits、R-Align data format, digital data
break;
default:
break;
}
return ret;
}
static const struct DacDevDone dev_done =
{
Stm32DacOpen,
Stm32DacClose,
NONE,
Stm32DacRead,
};
int Stm32HwDacInit(void)
{
x_err_t ret = EOK;
#ifdef BSP_USING_DAC
static struct DacBus dac_bus;
static struct DacDriver dac_drv;
static struct DacHardwareDevice dac_dev;
static struct Stm32HwDac dac_cfg;
dac_drv.configure = Stm32DacDrvConfigure;
ret = DacBusInit(&dac_bus, DAC_BUS_NAME);
if (ret != EOK) {
KPrintf("DAC bus init error %d\n", ret);
return ERROR;
}
ret = DacDriverInit(&dac_drv, DAC_DRIVER_NAME);
if (ret != EOK) {
KPrintf("DAC driver init error %d\n", ret);
return ERROR;
}
ret = DacDriverAttachToBus(DAC_DRIVER_NAME, DAC_BUS_NAME);
if (ret != EOK) {
KPrintf("DAC driver attach error %d\n", ret);
return ERROR;
}
dac_dev.dac_dev_done = &dev_done;
dac_cfg.DACx = DAC;
dac_cfg.digital_data = 0;
ret = DacDeviceRegister(&dac_dev, (void *)&dac_cfg, DAC_DEVICE_NAME);
if (ret != EOK) {
KPrintf("DAC device register error %d\n", ret);
return ERROR;
}
ret = DacDeviceAttachToBus(DAC_DEVICE_NAME, DAC_BUS_NAME);
if (ret != EOK) {
KPrintf("DAC device register error %d\n", ret);
return ERROR;
}
#endif
return ret;
}

View File

@ -0,0 +1,733 @@
/**
******************************************************************************
* @file stm32f4xx_dac.c
* @author MCD Application Team
* @version V1.4.0
* @date 04-August-2014
* @brief This file provides firmware functions to manage the following
* functionalities of the Digital-to-Analog Converter (DAC) peripheral:
* + DAC channels configuration: trigger, output buffer, data format
* + DMA management
* + Interrupts and flags management
*
@verbatim
===============================================================================
##### DAC Peripheral features #####
===============================================================================
[..]
*** DAC Channels ***
====================
[..]
The device integrates two 12-bit Digital Analog Converters that can
be used independently or simultaneously (dual mode):
(#) DAC channel1 with DAC_OUT1 (PA4) as output
(#) DAC channel2 with DAC_OUT2 (PA5) as output
*** DAC Triggers ***
====================
[..]
Digital to Analog conversion can be non-triggered using DAC_Trigger_None
and DAC_OUT1/DAC_OUT2 is available once writing to DHRx register
using DAC_SetChannel1Data() / DAC_SetChannel2Data() functions.
[..]
Digital to Analog conversion can be triggered by:
(#) External event: EXTI Line 9 (any GPIOx_Pin9) using DAC_Trigger_Ext_IT9.
The used pin (GPIOx_Pin9) must be configured in input mode.
(#) Timers TRGO: TIM2, TIM4, TIM5, TIM6, TIM7 and TIM8
(DAC_Trigger_T2_TRGO, DAC_Trigger_T4_TRGO...)
The timer TRGO event should be selected using TIM_SelectOutputTrigger()
(#) Software using DAC_Trigger_Software
*** DAC Buffer mode feature ***
===============================
[..]
Each DAC channel integrates an output buffer that can be used to
reduce the output impedance, and to drive external loads directly
without having to add an external operational amplifier.
To enable, the output buffer use
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
[..]
(@) Refer to the device datasheet for more details about output
impedance value with and without output buffer.
*** DAC wave generation feature ***
===================================
[..]
Both DAC channels can be used to generate
(#) Noise wave using DAC_WaveGeneration_Noise
(#) Triangle wave using DAC_WaveGeneration_Triangle
-@- Wave generation can be disabled using DAC_WaveGeneration_None
*** DAC data format ***
=======================
[..]
The DAC data format can be:
(#) 8-bit right alignment using DAC_Align_8b_R
(#) 12-bit left alignment using DAC_Align_12b_L
(#) 12-bit right alignment using DAC_Align_12b_R
*** DAC data value to voltage correspondence ***
================================================
[..]
The analog output voltage on each DAC channel pin is determined
by the following equation:
DAC_OUTx = VREF+ * DOR / 4095
with DOR is the Data Output Register
VEF+ is the input voltage reference (refer to the device datasheet)
e.g. To set DAC_OUT1 to 0.7V, use
DAC_SetChannel1Data(DAC_Align_12b_R, 868);
Assuming that VREF+ = 3.3V, DAC_OUT1 = (3.3 * 868) / 4095 = 0.7V
*** DMA requests ***
=====================
[..]
A DMA1 request can be generated when an external trigger (but not
a software trigger) occurs if DMA1 requests are enabled using
DAC_DMACmd()
[..]
DMA1 requests are mapped as following:
(#) DAC channel1 : mapped on DMA1 Stream5 channel7 which must be
already configured
(#) DAC channel2 : mapped on DMA1 Stream6 channel7 which must be
already configured
##### How to use this driver #####
===============================================================================
[..]
(+) DAC APB clock must be enabled to get write access to DAC
registers using
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE)
(+) Configure DAC_OUTx (DAC_OUT1: PA4, DAC_OUT2: PA5) in analog mode.
(+) Configure the DAC channel using DAC_Init() function
(+) Enable the DAC channel using DAC_Cmd() function
@endverbatim
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/**
* @file: hardware_dac.c
* @brief: support hardware dac function
* @version: 2.0
* @author: AIIT XUOS Lab
* @date: 2022/1/11
*/
/*************************************************
File name: hardware_dac.c
Description: support hardware dac function
Others:
History:
1. Date: 2022-1-11
Author: AIIT XUOS Lab
Modification:
1. rename stm32f4xx_dac.c for XiUOS
*************************************************/
/* Includes ------------------------------------------------------------------*/
#include <hardware_dac.h>
#include <hardware_rcc.h>
#include <hardware_conf.h>
/** @addtogroup STM32F4xx_StdPeriph_Driver
* @{
*/
/** @defgroup DAC
* @brief DAC driver modules
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* CR register Mask */
#define CR_CLEAR_MASK ((uint32_t)0x00000FFE)
/* DAC Dual Channels SWTRIG masks */
#define DUAL_SWTRIG_SET ((uint32_t)0x00000003)
#define DUAL_SWTRIG_RESET ((uint32_t)0xFFFFFFFC)
/* DHR registers offsets */
#define DHR12R1_OFFSET ((uint32_t)0x00000008)
#define DHR12R2_OFFSET ((uint32_t)0x00000014)
#define DHR12RD_OFFSET ((uint32_t)0x00000020)
/* DOR register offset */
#define DOR_OFFSET ((uint32_t)0x0000002C)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup DAC_Private_Functions
* @{
*/
/** @defgroup DAC_Group1 DAC channels configuration
* @brief DAC channels configuration: trigger, output buffer, data format
*
@verbatim
===============================================================================
##### DAC channels configuration: trigger, output buffer, data format #####
===============================================================================
@endverbatim
* @{
*/
/**
* @brief Deinitializes the DAC peripheral registers to their default reset values.
* @param None
* @retval None
*/
void DAC_DeInit(void)
{
/* Enable DAC reset state */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, ENABLE);
/* Release DAC from reset state */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, DISABLE);
}
/**
* @brief Initializes the DAC peripheral according to the specified parameters
* in the DAC_InitStruct.
* @param DAC_Channel: the selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure that contains
* the configuration information for the specified DAC channel.
* @retval None
*/
void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct)
{
uint32_t tmpreg1 = 0, tmpreg2 = 0;
/* Check the DAC parameters */
assert_param(IS_DAC_TRIGGER(DAC_InitStruct->DAC_Trigger));
assert_param(IS_DAC_GENERATE_WAVE(DAC_InitStruct->DAC_WaveGeneration));
assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude));
assert_param(IS_DAC_OUTPUT_BUFFER_STATE(DAC_InitStruct->DAC_OutputBuffer));
/*---------------------------- DAC CR Configuration --------------------------*/
/* Get the DAC CR value */
tmpreg1 = DAC->CR;
/* Clear BOFFx, TENx, TSELx, WAVEx and MAMPx bits */
tmpreg1 &= ~(CR_CLEAR_MASK << DAC_Channel);
/* Configure for the selected DAC channel: buffer output, trigger,
wave generation, mask/amplitude for wave generation */
/* Set TSELx and TENx bits according to DAC_Trigger value */
/* Set WAVEx bits according to DAC_WaveGeneration value */
/* Set MAMPx bits according to DAC_LFSRUnmask_TriangleAmplitude value */
/* Set BOFFx bit according to DAC_OutputBuffer value */
tmpreg2 = (DAC_InitStruct->DAC_Trigger | DAC_InitStruct->DAC_WaveGeneration |
DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude | \
DAC_InitStruct->DAC_OutputBuffer);
/* Calculate CR register value depending on DAC_Channel */
tmpreg1 |= tmpreg2 << DAC_Channel;
/* Write to DAC CR */
DAC->CR = tmpreg1;
}
/**
* @brief Fills each DAC_InitStruct member with its default value.
* @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure which will
* be initialized.
* @retval None
*/
void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct)
{
/*--------------- Reset DAC init structure parameters values -----------------*/
/* Initialize the DAC_Trigger member */
DAC_InitStruct->DAC_Trigger = DAC_Trigger_None;
/* Initialize the DAC_WaveGeneration member */
DAC_InitStruct->DAC_WaveGeneration = DAC_WaveGeneration_None;
/* Initialize the DAC_LFSRUnmask_TriangleAmplitude member */
DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
/* Initialize the DAC_OutputBuffer member */
DAC_InitStruct->DAC_OutputBuffer = DAC_OutputBuffer_Enable;
}
/**
* @brief Enables or disables the specified DAC channel.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param NewState: new state of the DAC channel.
* This parameter can be: ENABLE or DISABLE.
* @note When the DAC channel is enabled the trigger source can no more be modified.
* @retval None
*/
void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected DAC channel */
DAC->CR |= (DAC_CR_EN1 << DAC_Channel);
}
else
{
/* Disable the selected DAC channel */
DAC->CR &= (~(DAC_CR_EN1 << DAC_Channel));
}
}
/**
* @brief Enables or disables the selected DAC channel software trigger.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param NewState: new state of the selected DAC channel software trigger.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable software trigger for the selected DAC channel */
DAC->SWTRIGR |= (uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4);
}
else
{
/* Disable software trigger for the selected DAC channel */
DAC->SWTRIGR &= ~((uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4));
}
}
/**
* @brief Enables or disables simultaneously the two DAC channels software triggers.
* @param NewState: new state of the DAC channels software triggers.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void DAC_DualSoftwareTriggerCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable software trigger for both DAC channels */
DAC->SWTRIGR |= DUAL_SWTRIG_SET;
}
else
{
/* Disable software trigger for both DAC channels */
DAC->SWTRIGR &= DUAL_SWTRIG_RESET;
}
}
/**
* @brief Enables or disables the selected DAC channel wave generation.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param DAC_Wave: specifies the wave type to enable or disable.
* This parameter can be one of the following values:
* @arg DAC_Wave_Noise: noise wave generation
* @arg DAC_Wave_Triangle: triangle wave generation
* @param NewState: new state of the selected DAC channel wave generation.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_DAC_WAVE(DAC_Wave));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected wave generation for the selected DAC channel */
DAC->CR |= DAC_Wave << DAC_Channel;
}
else
{
/* Disable the selected wave generation for the selected DAC channel */
DAC->CR &= ~(DAC_Wave << DAC_Channel);
}
}
/**
* @brief Set the specified data holding register value for DAC channel1.
* @param DAC_Align: Specifies the data alignment for DAC channel1.
* This parameter can be one of the following values:
* @arg DAC_Align_8b_R: 8bit right data alignment selected
* @arg DAC_Align_12b_L: 12bit left data alignment selected
* @arg DAC_Align_12b_R: 12bit right data alignment selected
* @param Data: Data to be loaded in the selected data holding register.
* @retval None
*/
void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data)
{
__IO uint32_t tmp = 0;
/* Check the parameters */
assert_param(IS_DAC_ALIGN(DAC_Align));
assert_param(IS_DAC_DATA(Data));
tmp = (uint32_t)DAC_BASE;
tmp += DHR12R1_OFFSET + DAC_Align;
/* Set the DAC channel1 selected data holding register */
*(__IO uint32_t *) tmp = Data;
}
/**
* @brief Set the specified data holding register value for DAC channel2.
* @param DAC_Align: Specifies the data alignment for DAC channel2.
* This parameter can be one of the following values:
* @arg DAC_Align_8b_R: 8bit right data alignment selected
* @arg DAC_Align_12b_L: 12bit left data alignment selected
* @arg DAC_Align_12b_R: 12bit right data alignment selected
* @param Data: Data to be loaded in the selected data holding register.
* @retval None
*/
void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data)
{
__IO uint32_t tmp = 0;
/* Check the parameters */
assert_param(IS_DAC_ALIGN(DAC_Align));
assert_param(IS_DAC_DATA(Data));
tmp = (uint32_t)DAC_BASE;
tmp += DHR12R2_OFFSET + DAC_Align;
/* Set the DAC channel2 selected data holding register */
*(__IO uint32_t *)tmp = Data;
}
/**
* @brief Set the specified data holding register value for dual channel DAC.
* @param DAC_Align: Specifies the data alignment for dual channel DAC.
* This parameter can be one of the following values:
* @arg DAC_Align_8b_R: 8bit right data alignment selected
* @arg DAC_Align_12b_L: 12bit left data alignment selected
* @arg DAC_Align_12b_R: 12bit right data alignment selected
* @param Data2: Data for DAC Channel2 to be loaded in the selected data holding register.
* @param Data1: Data for DAC Channel1 to be loaded in the selected data holding register.
* @note In dual mode, a unique register access is required to write in both
* DAC channels at the same time.
* @retval None
*/
void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1)
{
uint32_t data = 0, tmp = 0;
/* Check the parameters */
assert_param(IS_DAC_ALIGN(DAC_Align));
assert_param(IS_DAC_DATA(Data1));
assert_param(IS_DAC_DATA(Data2));
/* Calculate and set dual DAC data holding register value */
if (DAC_Align == DAC_Align_8b_R)
{
data = ((uint32_t)Data2 << 8) | Data1;
}
else
{
data = ((uint32_t)Data2 << 16) | Data1;
}
tmp = (uint32_t)DAC_BASE;
tmp += DHR12RD_OFFSET + DAC_Align;
/* Set the dual DAC selected data holding register */
*(__IO uint32_t *)tmp = data;
}
/**
* @brief Returns the last data output value of the selected DAC channel.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @retval The selected DAC channel data output value.
*/
uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel)
{
__IO uint32_t tmp = 0;
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
tmp = (uint32_t) DAC_BASE ;
tmp += DOR_OFFSET + ((uint32_t)DAC_Channel >> 2);
/* Returns the DAC channel data output register value */
return (uint16_t) (*(__IO uint32_t*) tmp);
}
/**
* @}
*/
/** @defgroup DAC_Group2 DMA management functions
* @brief DMA management functions
*
@verbatim
===============================================================================
##### DMA management functions #####
===============================================================================
@endverbatim
* @{
*/
/**
* @brief Enables or disables the specified DAC channel DMA request.
* @note When enabled DMA1 is generated when an external trigger (EXTI Line9,
* TIM2, TIM4, TIM5, TIM6, TIM7 or TIM8 but not a software trigger) occurs.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param NewState: new state of the selected DAC channel DMA request.
* This parameter can be: ENABLE or DISABLE.
* @note The DAC channel1 is mapped on DMA1 Stream 5 channel7 which must be
* already configured.
* @note The DAC channel2 is mapped on DMA1 Stream 6 channel7 which must be
* already configured.
* @retval None
*/
void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected DAC channel DMA request */
DAC->CR |= (DAC_CR_DMAEN1 << DAC_Channel);
}
else
{
/* Disable the selected DAC channel DMA request */
DAC->CR &= (~(DAC_CR_DMAEN1 << DAC_Channel));
}
}
/**
* @}
*/
/** @defgroup DAC_Group3 Interrupts and flags management functions
* @brief Interrupts and flags management functions
*
@verbatim
===============================================================================
##### Interrupts and flags management functions #####
===============================================================================
@endverbatim
* @{
*/
/**
* @brief Enables or disables the specified DAC interrupts.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param DAC_IT: specifies the DAC interrupt sources to be enabled or disabled.
* This parameter can be the following values:
* @arg DAC_IT_DMAUDR: DMA underrun interrupt mask
* @note The DMA underrun occurs when a second external trigger arrives before the
* acknowledgement for the first external trigger is received (first request).
* @param NewState: new state of the specified DAC interrupts.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_FUNCTIONAL_STATE(NewState));
assert_param(IS_DAC_IT(DAC_IT));
if (NewState != DISABLE)
{
/* Enable the selected DAC interrupts */
DAC->CR |= (DAC_IT << DAC_Channel);
}
else
{
/* Disable the selected DAC interrupts */
DAC->CR &= (~(uint32_t)(DAC_IT << DAC_Channel));
}
}
/**
* @brief Checks whether the specified DAC flag is set or not.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param DAC_FLAG: specifies the flag to check.
* This parameter can be only of the following value:
* @arg DAC_FLAG_DMAUDR: DMA underrun flag
* @note The DMA underrun occurs when a second external trigger arrives before the
* acknowledgement for the first external trigger is received (first request).
* @retval The new state of DAC_FLAG (SET or RESET).
*/
FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG)
{
FlagStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_DAC_FLAG(DAC_FLAG));
/* Check the status of the specified DAC flag */
if ((DAC->SR & (DAC_FLAG << DAC_Channel)) != (uint8_t)RESET)
{
/* DAC_FLAG is set */
bitstatus = SET;
}
else
{
/* DAC_FLAG is reset */
bitstatus = RESET;
}
/* Return the DAC_FLAG status */
return bitstatus;
}
/**
* @brief Clears the DAC channel's pending flags.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param DAC_FLAG: specifies the flag to clear.
* This parameter can be of the following value:
* @arg DAC_FLAG_DMAUDR: DMA underrun flag
* @note The DMA underrun occurs when a second external trigger arrives before the
* acknowledgement for the first external trigger is received (first request).
* @retval None
*/
void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG)
{
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_DAC_FLAG(DAC_FLAG));
/* Clear the selected DAC flags */
DAC->SR = (DAC_FLAG << DAC_Channel);
}
/**
* @brief Checks whether the specified DAC interrupt has occurred or not.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param DAC_IT: specifies the DAC interrupt source to check.
* This parameter can be the following values:
* @arg DAC_IT_DMAUDR: DMA underrun interrupt mask
* @note The DMA underrun occurs when a second external trigger arrives before the
* acknowledgement for the first external trigger is received (first request).
* @retval The new state of DAC_IT (SET or RESET).
*/
ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT)
{
ITStatus bitstatus = RESET;
uint32_t enablestatus = 0;
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_DAC_IT(DAC_IT));
/* Get the DAC_IT enable bit status */
enablestatus = (DAC->CR & (DAC_IT << DAC_Channel)) ;
/* Check the status of the specified DAC interrupt */
if (((DAC->SR & (DAC_IT << DAC_Channel)) != (uint32_t)RESET) && enablestatus)
{
/* DAC_IT is set */
bitstatus = SET;
}
else
{
/* DAC_IT is reset */
bitstatus = RESET;
}
/* Return the DAC_IT status */
return bitstatus;
}
/**
* @brief Clears the DAC channel's interrupt pending bits.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param DAC_IT: specifies the DAC interrupt pending bit to clear.
* This parameter can be the following values:
* @arg DAC_IT_DMAUDR: DMA underrun interrupt mask
* @note The DMA underrun occurs when a second external trigger arrives before the
* acknowledgement for the first external trigger is received (first request).
* @retval None
*/
void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT)
{
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_DAC_IT(DAC_IT));
/* Clear the selected DAC interrupt pending bits */
DAC->SR = (DAC_IT << DAC_Channel);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_dac.h
* @brief define stm32f407-st-discovery adc function and struct
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-1-10
*/
#ifndef CONNECT_DAC_H
#define CONNECT_DAC_H
#include <device.h>
#include <hardware_dac.h>
#include <hardware_rcc.h>
#include <hardware_gpio.h>
struct Stm32HwDac
{
DAC_TypeDef *DACx;
uint16 digital_data;
};
int Stm32HwDacInit(void);
#endif

View File

@ -80,7 +80,7 @@ Modification:
/* Uncomment the line below to expanse the "assert_param" macro in the
Standard Peripheral Library drivers code */
#define USE_FULL_ASSERT 1
//#define USE_FULL_ASSERT 1
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT

View File

@ -2,30 +2,36 @@
******************************************************************************
* @file stm32f4xx_dac.h
* @author MCD Application Team
* @version V1.0.0
* @date 30-September-2011
* @version V1.4.0
* @date 04-August-2014
* @brief This file contains all the functions prototypes for the DAC firmware
* library.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
* <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/**
* @file: hardware_dac.h
* @brief: define hardware dac function
* @version: 1.0
* @version: 2.0
* @author: AIIT XUOS Lab
* @date: 2021/4/25
* @date: 2022/1/10
*/
/*************************************************
@ -33,7 +39,7 @@ File name: hardware_dac.h
Description: define hardware dac function
Others:
History:
1. Date: 2021-04-25
1. Date: 2022-1-10
Author: AIIT XUOS Lab
Modification:
1. rename stm32f4xx_dac.h for XiUOS
@ -48,7 +54,7 @@ Modification:
#endif
/* Includes ------------------------------------------------------------------*/
#include <stm32f4xx.h>
#include "stm32f4xx.h"
/** @addtogroup STM32F4xx_StdPeriph_Driver
* @{
@ -314,4 +320,4 @@ void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT);
* @}
*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -49,6 +49,7 @@ extern int Stm32HwUsartInit();
extern int Stm32HwRtcInit();
extern int HwSdioInit();
extern int Stm32HwAdcInit(void);
extern int Stm32HwDacInit(void);
static void ClockConfiguration()
{
@ -137,6 +138,9 @@ struct InitSequenceDesc _board_init[] =
#endif
#ifdef BSP_USING_ADC
{"hw adc init", Stm32HwAdcInit},
#endif
#ifdef BSP_USING_DAC
{"hw dac init", Stm32HwDacInit},
#endif
{ " NONE ",NONE },
};

View File

@ -14,6 +14,14 @@ if BSP_USING_CAN
source "$BSP_DIR/third_party_driver/can/Kconfig"
endif
menuconfig BSP_USING_DAC
bool "Using DAC device"
default n
select RESOURCES_DAC
if BSP_USING_DAC
source "$BSP_DIR/third_party_driver/dac/Kconfig"
endif
menuconfig BSP_USING_DMA
bool "Using DMA device"
default y

View File

@ -9,6 +9,10 @@ ifeq ($(CONFIG_BSP_USING_CAN),y)
SRC_DIR += can
endif
ifeq ($(CONFIG_BSP_USING_DAC),y)
SRC_DIR += dac
endif
ifeq ($(CONFIG_BSP_USING_GPIO),y)
SRC_DIR += gpio
endif

View File

@ -240,6 +240,15 @@ static uint32 Stm32AdcOpen(void *dev)
return EOK;
}
static uint32 Stm32AdcClose(void *dev)
{
struct AdcHardwareDevice *adc_dev = (struct AdcHardwareDevice *)dev;
ADC_DeInit();
return EOK;
}
static uint32 Stm32AdcRead(void *dev, struct BusBlockReadParam *read_param)
{
struct AdcHardwareDevice *adc_dev = (struct AdcHardwareDevice *)dev;
@ -288,7 +297,7 @@ static uint32 Stm32AdcDrvConfigure(void *drv, struct BusConfigureInfo *configure
static const struct AdcDevDone dev_done =
{
Stm32AdcOpen,
NONE,
Stm32AdcClose,
NONE,
Stm32AdcRead,
};
@ -419,4 +428,6 @@ int Stm32HwAdcInit(void)
return ERROR;
}
#endif
return ret;
}

View File

@ -0,0 +1,17 @@
if BSP_USING_DAC
config DAC_BUS_NAME
string "dac bus name"
default "dac"
config DAC_DRIVER_NAME
string "dac driver name"
default "dac_drv"
config DAC_DEVICE_NAME
string "dac bus device name"
default "dac_dev"
config DAC_GPIO_NUM
int "dac gpio pin num(only support 4 or 5)"
default "4"
endif

View File

@ -0,0 +1,3 @@
SRC_FILES := connect_dac.c hardware_dac.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,168 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_dac.c
* @brief support to register DAC pointer and function
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-1-10
*/
#include <connect_dac.h>
#define _DAC_CONS(string1, string2) string1##string2
#define DAC_CONS(string1, string2) _DAC_CONS(string1, string2)
#ifdef BSP_USING_DAC
#define DAC_GPIO DAC_CONS(GPIO_Pin_, DAC_GPIO_NUM)
#endif
static void DacInit(struct DacHardwareDevice *dac_dev)
{
GPIO_InitTypeDef GPIO_InitStructure;
DAC_InitTypeDef DAC_InitType;
#ifdef BSP_USING_DAC
if (0 == strncmp(dac_dev->haldev.dev_name, DAC_DEVICE_NAME, NAME_NUM_MAX)) {
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//enable GPIOA clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//enable DAC clock
GPIO_InitStructure.GPIO_Pin = DAC_GPIO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
DAC_InitType.DAC_Trigger = DAC_Trigger_None;//disable trigger function TEN1=0
DAC_InitType.DAC_WaveGeneration = DAC_WaveGeneration_None;//disable wave generation function
DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;//mask and amplitude configure
DAC_InitType.DAC_OutputBuffer = DAC_OutputBuffer_Disable;//disable DAC1 output buffer BOFF1=1
DAC_Init(DAC_Channel_1, &DAC_InitType);
DAC_Cmd(DAC_Channel_1, ENABLE);//enable DAC channel 1
DAC_SetChannel1Data(DAC_Align_12b_R, 0);//12 bits、R-Align data format, default 0
}
#endif
}
static uint32 Stm32DacOpen(void *dev)
{
struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dev;
DacInit(dac_dev);
return EOK;
}
static uint32 Stm32DacClose(void *dev)
{
struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dev;
DAC_DeInit();
return EOK;
}
static uint32 Stm32DacRead(void *dev, struct BusBlockReadParam *read_param)
{
struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dev;
uint16 dac_set_value = 0;
dac_set_value = DAC_GetDataOutputValue(DAC_Channel_1);
*(uint16 *)read_param->buffer = dac_set_value;
read_param->read_length = 2;
return read_param->read_length;
}
static uint32 Stm32DacDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(drv);
NULL_PARAM_CHECK(configure_info);
x_err_t ret = EOK;
struct DacDriver *dac_drv = (struct DacDriver *)drv;
struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dac_drv->driver.owner_bus->owner_haldev;
struct Stm32HwDac *dac_cfg = (struct Stm32HwDac *)dac_dev->haldev.private_data;
switch (configure_info->configure_cmd)
{
case OPE_CFG:
dac_cfg->digital_data = *(uint16 *)configure_info->private_data;
DAC_SetChannel1Data(DAC_Align_12b_R, dac_cfg->digital_data);//12 bits、R-Align data format, digital data
break;
default:
break;
}
return ret;
}
static const struct DacDevDone dev_done =
{
Stm32DacOpen,
Stm32DacClose,
NONE,
Stm32DacRead,
};
int Stm32HwDacInit(void)
{
x_err_t ret = EOK;
#ifdef BSP_USING_DAC
static struct DacBus dac_bus;
static struct DacDriver dac_drv;
static struct DacHardwareDevice dac_dev;
static struct Stm32HwDac dac_cfg;
dac_drv.configure = Stm32DacDrvConfigure;
ret = DacBusInit(&dac_bus, DAC_BUS_NAME);
if (ret != EOK) {
KPrintf("DAC bus init error %d\n", ret);
return ERROR;
}
ret = DacDriverInit(&dac_drv, DAC_DRIVER_NAME);
if (ret != EOK) {
KPrintf("DAC driver init error %d\n", ret);
return ERROR;
}
ret = DacDriverAttachToBus(DAC_DRIVER_NAME, DAC_BUS_NAME);
if (ret != EOK) {
KPrintf("DAC driver attach error %d\n", ret);
return ERROR;
}
dac_dev.dac_dev_done = &dev_done;
dac_cfg.DACx = DAC;
dac_cfg.digital_data = 0;
ret = DacDeviceRegister(&dac_dev, (void *)&dac_cfg, DAC_DEVICE_NAME);
if (ret != EOK) {
KPrintf("DAC device register error %d\n", ret);
return ERROR;
}
ret = DacDeviceAttachToBus(DAC_DEVICE_NAME, DAC_BUS_NAME);
if (ret != EOK) {
KPrintf("DAC device register error %d\n", ret);
return ERROR;
}
#endif
return ret;
}

View File

@ -0,0 +1,733 @@
/**
******************************************************************************
* @file stm32f4xx_dac.c
* @author MCD Application Team
* @version V1.4.0
* @date 04-August-2014
* @brief This file provides firmware functions to manage the following
* functionalities of the Digital-to-Analog Converter (DAC) peripheral:
* + DAC channels configuration: trigger, output buffer, data format
* + DMA management
* + Interrupts and flags management
*
@verbatim
===============================================================================
##### DAC Peripheral features #####
===============================================================================
[..]
*** DAC Channels ***
====================
[..]
The device integrates two 12-bit Digital Analog Converters that can
be used independently or simultaneously (dual mode):
(#) DAC channel1 with DAC_OUT1 (PA4) as output
(#) DAC channel2 with DAC_OUT2 (PA5) as output
*** DAC Triggers ***
====================
[..]
Digital to Analog conversion can be non-triggered using DAC_Trigger_None
and DAC_OUT1/DAC_OUT2 is available once writing to DHRx register
using DAC_SetChannel1Data() / DAC_SetChannel2Data() functions.
[..]
Digital to Analog conversion can be triggered by:
(#) External event: EXTI Line 9 (any GPIOx_Pin9) using DAC_Trigger_Ext_IT9.
The used pin (GPIOx_Pin9) must be configured in input mode.
(#) Timers TRGO: TIM2, TIM4, TIM5, TIM6, TIM7 and TIM8
(DAC_Trigger_T2_TRGO, DAC_Trigger_T4_TRGO...)
The timer TRGO event should be selected using TIM_SelectOutputTrigger()
(#) Software using DAC_Trigger_Software
*** DAC Buffer mode feature ***
===============================
[..]
Each DAC channel integrates an output buffer that can be used to
reduce the output impedance, and to drive external loads directly
without having to add an external operational amplifier.
To enable, the output buffer use
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
[..]
(@) Refer to the device datasheet for more details about output
impedance value with and without output buffer.
*** DAC wave generation feature ***
===================================
[..]
Both DAC channels can be used to generate
(#) Noise wave using DAC_WaveGeneration_Noise
(#) Triangle wave using DAC_WaveGeneration_Triangle
-@- Wave generation can be disabled using DAC_WaveGeneration_None
*** DAC data format ***
=======================
[..]
The DAC data format can be:
(#) 8-bit right alignment using DAC_Align_8b_R
(#) 12-bit left alignment using DAC_Align_12b_L
(#) 12-bit right alignment using DAC_Align_12b_R
*** DAC data value to voltage correspondence ***
================================================
[..]
The analog output voltage on each DAC channel pin is determined
by the following equation:
DAC_OUTx = VREF+ * DOR / 4095
with DOR is the Data Output Register
VEF+ is the input voltage reference (refer to the device datasheet)
e.g. To set DAC_OUT1 to 0.7V, use
DAC_SetChannel1Data(DAC_Align_12b_R, 868);
Assuming that VREF+ = 3.3V, DAC_OUT1 = (3.3 * 868) / 4095 = 0.7V
*** DMA requests ***
=====================
[..]
A DMA1 request can be generated when an external trigger (but not
a software trigger) occurs if DMA1 requests are enabled using
DAC_DMACmd()
[..]
DMA1 requests are mapped as following:
(#) DAC channel1 : mapped on DMA1 Stream5 channel7 which must be
already configured
(#) DAC channel2 : mapped on DMA1 Stream6 channel7 which must be
already configured
##### How to use this driver #####
===============================================================================
[..]
(+) DAC APB clock must be enabled to get write access to DAC
registers using
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE)
(+) Configure DAC_OUTx (DAC_OUT1: PA4, DAC_OUT2: PA5) in analog mode.
(+) Configure the DAC channel using DAC_Init() function
(+) Enable the DAC channel using DAC_Cmd() function
@endverbatim
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/**
* @file: hardware_dac.c
* @brief: support hardware dac function
* @version: 2.0
* @author: AIIT XUOS Lab
* @date: 2022/1/11
*/
/*************************************************
File name: hardware_dac.c
Description: support hardware dac function
Others:
History:
1. Date: 2022-1-11
Author: AIIT XUOS Lab
Modification:
1. rename stm32f4xx_dac.c for XiUOS
*************************************************/
/* Includes ------------------------------------------------------------------*/
#include <hardware_dac.h>
#include <hardware_rcc.h>
#include <hardware_conf.h>
/** @addtogroup STM32F4xx_StdPeriph_Driver
* @{
*/
/** @defgroup DAC
* @brief DAC driver modules
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* CR register Mask */
#define CR_CLEAR_MASK ((uint32_t)0x00000FFE)
/* DAC Dual Channels SWTRIG masks */
#define DUAL_SWTRIG_SET ((uint32_t)0x00000003)
#define DUAL_SWTRIG_RESET ((uint32_t)0xFFFFFFFC)
/* DHR registers offsets */
#define DHR12R1_OFFSET ((uint32_t)0x00000008)
#define DHR12R2_OFFSET ((uint32_t)0x00000014)
#define DHR12RD_OFFSET ((uint32_t)0x00000020)
/* DOR register offset */
#define DOR_OFFSET ((uint32_t)0x0000002C)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup DAC_Private_Functions
* @{
*/
/** @defgroup DAC_Group1 DAC channels configuration
* @brief DAC channels configuration: trigger, output buffer, data format
*
@verbatim
===============================================================================
##### DAC channels configuration: trigger, output buffer, data format #####
===============================================================================
@endverbatim
* @{
*/
/**
* @brief Deinitializes the DAC peripheral registers to their default reset values.
* @param None
* @retval None
*/
void DAC_DeInit(void)
{
/* Enable DAC reset state */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, ENABLE);
/* Release DAC from reset state */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, DISABLE);
}
/**
* @brief Initializes the DAC peripheral according to the specified parameters
* in the DAC_InitStruct.
* @param DAC_Channel: the selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure that contains
* the configuration information for the specified DAC channel.
* @retval None
*/
void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct)
{
uint32_t tmpreg1 = 0, tmpreg2 = 0;
/* Check the DAC parameters */
assert_param(IS_DAC_TRIGGER(DAC_InitStruct->DAC_Trigger));
assert_param(IS_DAC_GENERATE_WAVE(DAC_InitStruct->DAC_WaveGeneration));
assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude));
assert_param(IS_DAC_OUTPUT_BUFFER_STATE(DAC_InitStruct->DAC_OutputBuffer));
/*---------------------------- DAC CR Configuration --------------------------*/
/* Get the DAC CR value */
tmpreg1 = DAC->CR;
/* Clear BOFFx, TENx, TSELx, WAVEx and MAMPx bits */
tmpreg1 &= ~(CR_CLEAR_MASK << DAC_Channel);
/* Configure for the selected DAC channel: buffer output, trigger,
wave generation, mask/amplitude for wave generation */
/* Set TSELx and TENx bits according to DAC_Trigger value */
/* Set WAVEx bits according to DAC_WaveGeneration value */
/* Set MAMPx bits according to DAC_LFSRUnmask_TriangleAmplitude value */
/* Set BOFFx bit according to DAC_OutputBuffer value */
tmpreg2 = (DAC_InitStruct->DAC_Trigger | DAC_InitStruct->DAC_WaveGeneration |
DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude | \
DAC_InitStruct->DAC_OutputBuffer);
/* Calculate CR register value depending on DAC_Channel */
tmpreg1 |= tmpreg2 << DAC_Channel;
/* Write to DAC CR */
DAC->CR = tmpreg1;
}
/**
* @brief Fills each DAC_InitStruct member with its default value.
* @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure which will
* be initialized.
* @retval None
*/
void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct)
{
/*--------------- Reset DAC init structure parameters values -----------------*/
/* Initialize the DAC_Trigger member */
DAC_InitStruct->DAC_Trigger = DAC_Trigger_None;
/* Initialize the DAC_WaveGeneration member */
DAC_InitStruct->DAC_WaveGeneration = DAC_WaveGeneration_None;
/* Initialize the DAC_LFSRUnmask_TriangleAmplitude member */
DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
/* Initialize the DAC_OutputBuffer member */
DAC_InitStruct->DAC_OutputBuffer = DAC_OutputBuffer_Enable;
}
/**
* @brief Enables or disables the specified DAC channel.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param NewState: new state of the DAC channel.
* This parameter can be: ENABLE or DISABLE.
* @note When the DAC channel is enabled the trigger source can no more be modified.
* @retval None
*/
void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected DAC channel */
DAC->CR |= (DAC_CR_EN1 << DAC_Channel);
}
else
{
/* Disable the selected DAC channel */
DAC->CR &= (~(DAC_CR_EN1 << DAC_Channel));
}
}
/**
* @brief Enables or disables the selected DAC channel software trigger.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param NewState: new state of the selected DAC channel software trigger.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable software trigger for the selected DAC channel */
DAC->SWTRIGR |= (uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4);
}
else
{
/* Disable software trigger for the selected DAC channel */
DAC->SWTRIGR &= ~((uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4));
}
}
/**
* @brief Enables or disables simultaneously the two DAC channels software triggers.
* @param NewState: new state of the DAC channels software triggers.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void DAC_DualSoftwareTriggerCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable software trigger for both DAC channels */
DAC->SWTRIGR |= DUAL_SWTRIG_SET;
}
else
{
/* Disable software trigger for both DAC channels */
DAC->SWTRIGR &= DUAL_SWTRIG_RESET;
}
}
/**
* @brief Enables or disables the selected DAC channel wave generation.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param DAC_Wave: specifies the wave type to enable or disable.
* This parameter can be one of the following values:
* @arg DAC_Wave_Noise: noise wave generation
* @arg DAC_Wave_Triangle: triangle wave generation
* @param NewState: new state of the selected DAC channel wave generation.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_DAC_WAVE(DAC_Wave));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected wave generation for the selected DAC channel */
DAC->CR |= DAC_Wave << DAC_Channel;
}
else
{
/* Disable the selected wave generation for the selected DAC channel */
DAC->CR &= ~(DAC_Wave << DAC_Channel);
}
}
/**
* @brief Set the specified data holding register value for DAC channel1.
* @param DAC_Align: Specifies the data alignment for DAC channel1.
* This parameter can be one of the following values:
* @arg DAC_Align_8b_R: 8bit right data alignment selected
* @arg DAC_Align_12b_L: 12bit left data alignment selected
* @arg DAC_Align_12b_R: 12bit right data alignment selected
* @param Data: Data to be loaded in the selected data holding register.
* @retval None
*/
void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data)
{
__IO uint32_t tmp = 0;
/* Check the parameters */
assert_param(IS_DAC_ALIGN(DAC_Align));
assert_param(IS_DAC_DATA(Data));
tmp = (uint32_t)DAC_BASE;
tmp += DHR12R1_OFFSET + DAC_Align;
/* Set the DAC channel1 selected data holding register */
*(__IO uint32_t *) tmp = Data;
}
/**
* @brief Set the specified data holding register value for DAC channel2.
* @param DAC_Align: Specifies the data alignment for DAC channel2.
* This parameter can be one of the following values:
* @arg DAC_Align_8b_R: 8bit right data alignment selected
* @arg DAC_Align_12b_L: 12bit left data alignment selected
* @arg DAC_Align_12b_R: 12bit right data alignment selected
* @param Data: Data to be loaded in the selected data holding register.
* @retval None
*/
void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data)
{
__IO uint32_t tmp = 0;
/* Check the parameters */
assert_param(IS_DAC_ALIGN(DAC_Align));
assert_param(IS_DAC_DATA(Data));
tmp = (uint32_t)DAC_BASE;
tmp += DHR12R2_OFFSET + DAC_Align;
/* Set the DAC channel2 selected data holding register */
*(__IO uint32_t *)tmp = Data;
}
/**
* @brief Set the specified data holding register value for dual channel DAC.
* @param DAC_Align: Specifies the data alignment for dual channel DAC.
* This parameter can be one of the following values:
* @arg DAC_Align_8b_R: 8bit right data alignment selected
* @arg DAC_Align_12b_L: 12bit left data alignment selected
* @arg DAC_Align_12b_R: 12bit right data alignment selected
* @param Data2: Data for DAC Channel2 to be loaded in the selected data holding register.
* @param Data1: Data for DAC Channel1 to be loaded in the selected data holding register.
* @note In dual mode, a unique register access is required to write in both
* DAC channels at the same time.
* @retval None
*/
void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1)
{
uint32_t data = 0, tmp = 0;
/* Check the parameters */
assert_param(IS_DAC_ALIGN(DAC_Align));
assert_param(IS_DAC_DATA(Data1));
assert_param(IS_DAC_DATA(Data2));
/* Calculate and set dual DAC data holding register value */
if (DAC_Align == DAC_Align_8b_R)
{
data = ((uint32_t)Data2 << 8) | Data1;
}
else
{
data = ((uint32_t)Data2 << 16) | Data1;
}
tmp = (uint32_t)DAC_BASE;
tmp += DHR12RD_OFFSET + DAC_Align;
/* Set the dual DAC selected data holding register */
*(__IO uint32_t *)tmp = data;
}
/**
* @brief Returns the last data output value of the selected DAC channel.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @retval The selected DAC channel data output value.
*/
uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel)
{
__IO uint32_t tmp = 0;
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
tmp = (uint32_t) DAC_BASE ;
tmp += DOR_OFFSET + ((uint32_t)DAC_Channel >> 2);
/* Returns the DAC channel data output register value */
return (uint16_t) (*(__IO uint32_t*) tmp);
}
/**
* @}
*/
/** @defgroup DAC_Group2 DMA management functions
* @brief DMA management functions
*
@verbatim
===============================================================================
##### DMA management functions #####
===============================================================================
@endverbatim
* @{
*/
/**
* @brief Enables or disables the specified DAC channel DMA request.
* @note When enabled DMA1 is generated when an external trigger (EXTI Line9,
* TIM2, TIM4, TIM5, TIM6, TIM7 or TIM8 but not a software trigger) occurs.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param NewState: new state of the selected DAC channel DMA request.
* This parameter can be: ENABLE or DISABLE.
* @note The DAC channel1 is mapped on DMA1 Stream 5 channel7 which must be
* already configured.
* @note The DAC channel2 is mapped on DMA1 Stream 6 channel7 which must be
* already configured.
* @retval None
*/
void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected DAC channel DMA request */
DAC->CR |= (DAC_CR_DMAEN1 << DAC_Channel);
}
else
{
/* Disable the selected DAC channel DMA request */
DAC->CR &= (~(DAC_CR_DMAEN1 << DAC_Channel));
}
}
/**
* @}
*/
/** @defgroup DAC_Group3 Interrupts and flags management functions
* @brief Interrupts and flags management functions
*
@verbatim
===============================================================================
##### Interrupts and flags management functions #####
===============================================================================
@endverbatim
* @{
*/
/**
* @brief Enables or disables the specified DAC interrupts.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param DAC_IT: specifies the DAC interrupt sources to be enabled or disabled.
* This parameter can be the following values:
* @arg DAC_IT_DMAUDR: DMA underrun interrupt mask
* @note The DMA underrun occurs when a second external trigger arrives before the
* acknowledgement for the first external trigger is received (first request).
* @param NewState: new state of the specified DAC interrupts.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_FUNCTIONAL_STATE(NewState));
assert_param(IS_DAC_IT(DAC_IT));
if (NewState != DISABLE)
{
/* Enable the selected DAC interrupts */
DAC->CR |= (DAC_IT << DAC_Channel);
}
else
{
/* Disable the selected DAC interrupts */
DAC->CR &= (~(uint32_t)(DAC_IT << DAC_Channel));
}
}
/**
* @brief Checks whether the specified DAC flag is set or not.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param DAC_FLAG: specifies the flag to check.
* This parameter can be only of the following value:
* @arg DAC_FLAG_DMAUDR: DMA underrun flag
* @note The DMA underrun occurs when a second external trigger arrives before the
* acknowledgement for the first external trigger is received (first request).
* @retval The new state of DAC_FLAG (SET or RESET).
*/
FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG)
{
FlagStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_DAC_FLAG(DAC_FLAG));
/* Check the status of the specified DAC flag */
if ((DAC->SR & (DAC_FLAG << DAC_Channel)) != (uint8_t)RESET)
{
/* DAC_FLAG is set */
bitstatus = SET;
}
else
{
/* DAC_FLAG is reset */
bitstatus = RESET;
}
/* Return the DAC_FLAG status */
return bitstatus;
}
/**
* @brief Clears the DAC channel's pending flags.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param DAC_FLAG: specifies the flag to clear.
* This parameter can be of the following value:
* @arg DAC_FLAG_DMAUDR: DMA underrun flag
* @note The DMA underrun occurs when a second external trigger arrives before the
* acknowledgement for the first external trigger is received (first request).
* @retval None
*/
void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG)
{
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_DAC_FLAG(DAC_FLAG));
/* Clear the selected DAC flags */
DAC->SR = (DAC_FLAG << DAC_Channel);
}
/**
* @brief Checks whether the specified DAC interrupt has occurred or not.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param DAC_IT: specifies the DAC interrupt source to check.
* This parameter can be the following values:
* @arg DAC_IT_DMAUDR: DMA underrun interrupt mask
* @note The DMA underrun occurs when a second external trigger arrives before the
* acknowledgement for the first external trigger is received (first request).
* @retval The new state of DAC_IT (SET or RESET).
*/
ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT)
{
ITStatus bitstatus = RESET;
uint32_t enablestatus = 0;
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_DAC_IT(DAC_IT));
/* Get the DAC_IT enable bit status */
enablestatus = (DAC->CR & (DAC_IT << DAC_Channel)) ;
/* Check the status of the specified DAC interrupt */
if (((DAC->SR & (DAC_IT << DAC_Channel)) != (uint32_t)RESET) && enablestatus)
{
/* DAC_IT is set */
bitstatus = SET;
}
else
{
/* DAC_IT is reset */
bitstatus = RESET;
}
/* Return the DAC_IT status */
return bitstatus;
}
/**
* @brief Clears the DAC channel's interrupt pending bits.
* @param DAC_Channel: The selected DAC channel.
* This parameter can be one of the following values:
* @arg DAC_Channel_1: DAC Channel1 selected
* @arg DAC_Channel_2: DAC Channel2 selected
* @param DAC_IT: specifies the DAC interrupt pending bit to clear.
* This parameter can be the following values:
* @arg DAC_IT_DMAUDR: DMA underrun interrupt mask
* @note The DMA underrun occurs when a second external trigger arrives before the
* acknowledgement for the first external trigger is received (first request).
* @retval None
*/
void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT)
{
/* Check the parameters */
assert_param(IS_DAC_CHANNEL(DAC_Channel));
assert_param(IS_DAC_IT(DAC_IT));
/* Clear the selected DAC interrupt pending bits */
DAC->SR = (DAC_IT << DAC_Channel);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_dac.h
* @brief define stm32f407-st-discovery adc function and struct
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-1-10
*/
#ifndef CONNECT_DAC_H
#define CONNECT_DAC_H
#include <device.h>
#include <hardware_dac.h>
#include <hardware_rcc.h>
#include <hardware_gpio.h>
struct Stm32HwDac
{
DAC_TypeDef *DACx;
uint16 digital_data;
};
int Stm32HwDacInit(void);
#endif

View File

@ -2,30 +2,36 @@
******************************************************************************
* @file stm32f4xx_dac.h
* @author MCD Application Team
* @version V1.0.0
* @date 30-September-2011
* @version V1.4.0
* @date 04-August-2014
* @brief This file contains all the functions prototypes for the DAC firmware
* library.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
* <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/**
* @file: hardware_dac.h
* @brief: define hardware dac function
* @version: 1.0
* @version: 2.0
* @author: AIIT XUOS Lab
* @date: 2021/4/25
* @date: 2022/1/10
*/
/*************************************************
@ -33,7 +39,7 @@ File name: hardware_dac.h
Description: define hardware dac function
Others:
History:
1. Date: 2021-04-25
1. Date: 2022-1-10
Author: AIIT XUOS Lab
Modification:
1. rename stm32f4xx_dac.h for XiUOS
@ -48,7 +54,7 @@ Modification:
#endif
/* Includes ------------------------------------------------------------------*/
#include <stm32f4xx.h>
#include "stm32f4xx.h"
/** @addtogroup STM32F4xx_StdPeriph_Driver
* @{
@ -314,4 +320,4 @@ void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT);
* @}
*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -157,3 +157,9 @@ if BSP_USING_ADC
bool "Using ADC bus drivers"
default n
endif
if BSP_USING_DAC
config RESOURCES_DAC
bool "Using DAC bus drivers"
default n
endif

View File

@ -61,4 +61,8 @@ ifeq ($(CONFIG_RESOURCES_ADC),y)
SRC_DIR += adc
endif
ifeq ($(CONFIG_RESOURCES_DAC),y)
SRC_DIR += dac
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You adc use this software according to the terms and conditions of the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You adc use this software according to the terms and conditions of the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,

View File

@ -0,0 +1,3 @@
SRC_FILES += dev_dac.c drv_dac.c bus_dac.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,122 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file bus_dac.c
* @brief register dac bus function using bus driver framework
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-1-11
*/
#include <bus_dac.h>
#include <dev_dac.h>
/*Register the DAC BUS*/
int DacBusInit(struct DacBus *dac_bus, const char *bus_name)
{
NULL_PARAM_CHECK(dac_bus);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
if (BUS_INSTALL != dac_bus->bus.bus_state) {
strncpy(dac_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
dac_bus->bus.bus_type = TYPE_DAC_BUS;
dac_bus->bus.bus_state = BUS_INSTALL;
dac_bus->bus.private_data = dac_bus->private_data;
ret = BusRegister(&dac_bus->bus);
if (EOK != ret) {
KPrintf("DacBusInit BusRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("DacBusInit BusRegister bus has been register state%u\n", dac_bus->bus.bus_state);
}
return ret;
}
/*Register the DAC Driver*/
int DacDriverInit(struct DacDriver *dac_driver, const char *driver_name)
{
NULL_PARAM_CHECK(dac_driver);
NULL_PARAM_CHECK(driver_name);
x_err_t ret = EOK;
if (DRV_INSTALL != dac_driver->driver.driver_state) {
dac_driver->driver.driver_type = TYPE_DAC_DRV;
dac_driver->driver.driver_state = DRV_INSTALL;
strncpy(dac_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
dac_driver->driver.configure = dac_driver->configure;
dac_driver->driver.private_data = dac_driver->private_data;
ret = DacDriverRegister(&dac_driver->driver);
if (EOK != ret) {
KPrintf("DacDriverInit DriverRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("DacDriverInit DriverRegister driver has been register state%u\n", dac_driver->driver.driver_state);
}
return ret;
}
/*Release the DAC device*/
int DacReleaseBus(struct DacBus *dac_bus)
{
NULL_PARAM_CHECK(dac_bus);
return BusRelease(&dac_bus->bus);
}
/*Register the DAC Driver to the DAC BUS*/
int DacDriverAttachToBus(const char *drv_name, const char *bus_name)
{
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct Driver *driver;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("DacDriverAttachToBus find dac bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_DAC_BUS == bus->bus_type) {
driver = DacDriverFind(drv_name, TYPE_DAC_DRV);
if (NONE == driver) {
KPrintf("DacDriverAttachToBus find dac driver error!name %s\n", drv_name);
return ERROR;
}
if (TYPE_DAC_DRV == driver->driver_type) {
ret = DriverRegisterToBus(bus, driver);
if (EOK != ret) {
KPrintf("DacDriverAttachToBus DriverRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return ret;
}

View File

@ -0,0 +1,119 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file dev_dac.c
* @brief register dac dev function using bus driver framework
* @version 1.1
* @author AIIT XUOS Lab
* @date 2021-12-28
*/
#include <bus_dac.h>
#include <dev_dac.h>
static DoubleLinklistType dacdev_linklist;
/*Create the DAC device linklist*/
static void DacDeviceLinkInit()
{
InitDoubleLinkList(&dacdev_linklist);
}
/*Find the register DAC device*/
HardwareDevType DacDeviceFind(const char *dev_name, enum DevType dev_type)
{
NULL_PARAM_CHECK(dev_name);
struct HardwareDev *device = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &dacdev_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link);
if ((!strcmp(device->dev_name, dev_name)) && (dev_type == device->dev_type)) {
return device;
}
}
KPrintf("DacDeviceFind dacnot find the %s device.return NULL\n", dev_name);
return NONE;
}
/*Register the DAC device*/
int DacDeviceRegister(struct DacHardwareDevice *dac_device, void *dac_param, const char *device_name)
{
NULL_PARAM_CHECK(dac_device);
NULL_PARAM_CHECK(device_name);
x_err_t ret = EOK;
static x_bool dev_link_flag = RET_FALSE;
if (!dev_link_flag) {
DacDeviceLinkInit();
dev_link_flag = RET_TRUE;
}
if (DEV_INSTALL != dac_device->haldev.dev_state) {
strncpy(dac_device->haldev.dev_name, device_name, NAME_NUM_MAX);
dac_device->haldev.dev_type = TYPE_DAC_DEV;
dac_device->haldev.dev_state = DEV_INSTALL;
dac_device->haldev.dev_done = (struct HalDevDone *)dac_device->dac_dev_done;
dac_device->haldev.private_data = dac_param;
DoubleLinkListInsertNodeAfter(&dacdev_linklist, &(dac_device->haldev.dev_link));
} else {
KPrintf("DacDeviceRegister device has been register state%u\n", dac_device->haldev.dev_state);
}
return ret;
}
/*Register the DAC Device to the DAC BUS*/
int DacDeviceAttachToBus(const char *dev_name, const char *bus_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct HardwareDev *device;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("DacDeviceAttachToBus find dac bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_DAC_BUS == bus->bus_type) {
device = DacDeviceFind(dev_name, TYPE_DAC_DEV);
if (NONE == device) {
KPrintf("DacDeviceAttachToBus find dac device error!name %s\n", dev_name);
return ERROR;
}
if (TYPE_DAC_DEV == device->dev_type) {
ret = DeviceRegisterToBus(bus, device);
if (EOK != ret) {
KPrintf("DacDeviceAttachToBus DeviceRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return EOK;
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file drv_dac.c
* @brief register dac drv function using bus driver framework
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-1-11
*/
#include <bus_dac.h>
#include <dev_dac.h>
static DoubleLinklistType dacdrv_linklist;
/*Create the driver linklist*/
static void DacDrvLinkInit()
{
InitDoubleLinkList(&dacdrv_linklist);
}
/*Find the regiter driver*/
DriverType DacDriverFind(const char *drv_name, enum DriverType_e drv_type)
{
NULL_PARAM_CHECK(drv_name);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &dacdrv_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link);
if ((!strcmp(driver->drv_name, drv_name)) && (drv_type == driver->driver_type)) {
return driver;
}
}
KPrintf("DacDriverFind cannot find the %s driver.return NULL\n", drv_name);
return NONE;
}
/*Register the Driver, manage with the double linklist*/
int DacDriverRegister(struct Driver *driver)
{
NULL_PARAM_CHECK(driver);
x_err_t ret = EOK;
static x_bool driver_link_flag = RET_FALSE;
if (!driver_link_flag) {
DacDrvLinkInit();
driver_link_flag = RET_TRUE;
}
DoubleLinkListInsertNodeAfter(&dacdrv_linklist, &(driver->driver_link));
return ret;
}

View File

@ -53,6 +53,7 @@ enum BusType_e
TYPE_RTC_BUS,
TYPE_SERIAL_BUS,
TYPE_ADC_BUS,
TYPE_DAC_BUS,
TYPE_BUS_END,
};
@ -78,6 +79,7 @@ enum DevType
TYPE_RTC_DEV,
TYPE_SERIAL_DEV,
TYPE_ADC_DEV,
TYPE_DAC_DEV,
TYPE_DEV_END,
};
@ -103,6 +105,7 @@ enum DriverType_e
TYPE_RTC_DRV,
TYPE_SERIAL_DRV,
TYPE_ADC_DRV,
TYPE_DAC_DRV,
TYPE_DRV_END,
};

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You adc use this software according to the terms and conditions of the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file bus_dac.h
* @brief define dac bus and drv function using bus driver framework
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-1-11
*/
#ifndef BUS_DAC_H
#define BUS_DAC_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct DacDriver
{
struct Driver driver;
uint32 (*configure) (void *drv, struct BusConfigureInfo *configure_info);
void *private_data;
};
struct DacBus
{
struct Bus bus;
void *private_data;
};
/*Register the DAC bus*/
int DacBusInit(struct DacBus *dac_bus, const char *bus_name);
/*Register the DAC driver*/
int DacDriverInit(struct DacDriver *dac_driver, const char *driver_name);
/*Release the DAC device*/
int DacReleaseBus(struct DacBus *dac_bus);
/*Register the DAC driver to the DAC bus*/
int DacDriverAttachToBus(const char *drv_name, const char *bus_name);
/*Register the driver, manage with the double linklist*/
int DacDriverRegister(struct Driver *driver);
/*Find the register driver*/
DriverType DacDriverFind(const char *drv_name, enum DriverType_e drv_type);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file dev_dac.h
* @brief define dac dev function using bus driver framework
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-1-11
*/
#ifndef DEV_DAC_H
#define DEV_DAC_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct DacHardwareDevice;
struct DacDevDone
{
uint32 (*open) (void *dev);
uint32 (*close) (void *dev);
uint32 (*write) (void *dev,struct BusBlockWriteParam *write_param);
uint32 (*read) (void *dev, struct BusBlockReadParam *read_param);
};
struct DacHardwareDevice
{
struct HardwareDev haldev;
const struct DacDevDone *dac_dev_done;
void *private_data;
};
/*Register the DAC device*/
int DacDeviceRegister(struct DacHardwareDevice *dac_device, void *dac_param, const char *device_name);
/*Register the DAC device to the DAC bus*/
int DacDeviceAttachToBus(const char *dev_name, const char *bus_name);
/*Find the register DAC device*/
HardwareDevType DacDeviceFind(const char *dev_name, enum DevType dev_type);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -99,4 +99,9 @@ HardwareDevType ObtainConsole(void);
#include <dev_adc.h>
#endif
#ifdef RESOURCES_DAC
#include <bus_dac.h>
#include <dev_dac.h>
#endif
#endif

View File

@ -383,6 +383,7 @@ static char *const bus_type_str[] =
"RTC_BUS",
"SERIAL_BUS",
"ADC_BUS",
"DAC_BUS",
"Unknown"
};