add adc and dac drivers for hc32f4a0 in XiZi Kernel

This commit is contained in:
zhaoyun1215 2023-02-09 00:41:24 -08:00
parent ff78fcc100
commit 3950a6ec28
12 changed files with 681 additions and 0 deletions

View File

@ -38,6 +38,14 @@ Modification:
#include <connect_gpio.h>
#endif
#ifdef BSP_USING_ADC
#include <connect_adc.h>
#endif
#ifdef BSP_USING_DAC
#include <connect_dac.h>
#endif
#ifdef BSP_USING_SDIO
#include <connect_sdio.h>
#endif
@ -165,6 +173,12 @@ struct InitSequenceDesc _board_init[] =
#ifdef BSP_USING_I2C
{ "i2c", HwI2cInit },
#endif
#ifdef BSP_USING_ADC
{"hw adc init", HwAdcInit},
#endif
#ifdef BSP_USING_DAC
{"hw adc init", HwDacInit},
#endif
#ifdef BSP_USING_USB
{ "usb", HwUsbHostInit },
#endif

View File

@ -6,6 +6,23 @@ menuconfig BSP_USING_UART
source "$BSP_DIR/third_party_driver/usart/Kconfig"
endif
menuconfig BSP_USING_ADC
bool "Using ADC device"
default n
select RESOURCES_ADC
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_GPIO
bool "Using GPIO device "
default y

View File

@ -4,6 +4,14 @@ ifeq ($(CONFIG_BSP_USING_UART),y)
SRC_DIR += usart
endif
ifeq ($(CONFIG_BSP_USING_ADC),y)
SRC_DIR += adc
endif
ifeq ($(CONFIG_BSP_USING_DAC),y)
SRC_DIR += dac
endif
ifeq ($(CONFIG_BSP_USING_GPIO),y)
SRC_DIR += gpio
endif

View File

@ -0,0 +1,74 @@
menuconfig BSP_USING_ADC1
bool "Enable ADC1"
default y
if BSP_USING_ADC1
config ADC1_BUS_NAME
string "adc 1 bus name"
default "adc1"
config ADC1_DRIVER_NAME
string "adc 1 driver name"
default "adc1_drv"
config ADC1_DEVICE_NAME
string "adc 1 bus device name"
default "adc1_dev"
config ADC1_GPIO_NUM
int "adc 1 gpio pin num"
default "0"
config ADC1_GPIO_DEF
string "adc 1 gpio define type"
default "A"
endif
menuconfig BSP_USING_ADC2
bool "Enable ADC2"
default y
if BSP_USING_ADC2
config ADC2_BUS_NAME
string "adc 2 bus name"
default "adc2"
config ADC2_DRIVER_NAME
string "adc 2 driver name"
default "adc2_drv"
config ADC2_DEVICE_NAME
string "adc 2 bus device name"
default "adc2_dev"
config ADC2_GPIO_NUM
int "adc 2 gpio pin num"
default "6"
config ADC2_GPIO_DEF
string "adc 2 gpio define type"
default "A"
endif
menuconfig BSP_USING_ADC3
bool "Enable ADC3"
default y
if BSP_USING_ADC3
config ADC3_BUS_NAME
string "adc 3 bus name"
default "adc3"
config ADC3_DRIVER_NAME
string "adc 3 driver name"
default "adc3_drv"
config ADC3_DEVICE_NAME
string "adc 3 bus device name"
default "adc3_dev"
config ADC3_GPIO_NUM
int "adc 3 gpio pin num"
default "0"
config ADC3_GPIO_DEF
string "adc 3 gpio define type"
default "A"
endif

View File

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

View File

@ -0,0 +1,289 @@
/*
* 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_adc.c
* @brief support to register ADC pointer and function
* @version 1.1
* @author AIIT XUOS Lab
* @date 2023-2-6
*/
#include <connect_adc.h>
#define _ADC_CONS(string1, string2) string1##string2
#define ADC_CONS(string1, string2) _ADC_CONS(string1, string2)
#ifdef BSP_USING_ADC1
#define ADC1_GPIO ADC_CONS(GPIO_Pin_, ADC1_GPIO_NUM)
#endif
#ifdef BSP_USING_ADC2
#define ADC2_GPIO ADC_CONS(GPIO_Pin_, ADC2_GPIO_NUM)
#endif
#ifdef BSP_USING_ADC3
#define ADC3_GPIO ADC_CONS(GPIO_Pin_, ADC3_GPIO_NUM)
#endif
static int AdcUdelay(uint32 us)
{
uint32 ticks;
uint32 told, tnow, tcnt = 0;
uint32 reload = SysTick->LOAD;
ticks = us * reload / (1000000 / TICK_PER_SECOND);
told = SysTick->VAL;
while (1) {
tnow = SysTick->VAL;
if (tnow != told) {
if (tnow < told) {
tcnt += told - tnow;
} else {
tcnt += reload - tnow + told;
}
told = tnow;
if (tcnt >= ticks) {
return 0;
break;
}
}
}
}
static uint16 GetAdcAverageValue(CM_ADC_TypeDef *ADCx, uint8 channel, uint8 times)
{
uint32 temp_val = 0;
int i;
for(i = 0;i < times;i ++) {
temp_val += ADC_GetValue(ADCx, channel) & 0x0FFF;
KPrintf("GetAdcAverageValue val %u\n", ADC_GetValue(ADCx, channel));
AdcUdelay(5000);
}
return temp_val / times;
}
static uint32 AdcOpen(void *dev)
{
x_err_t ret = EOK;
stc_adc_init_t stcAdcInit;
ADC_StructInit(&stcAdcInit);
struct AdcHardwareDevice* adc_dev = (struct AdcHardwareDevice*)dev;
CM_ADC_TypeDef *ADCx= (CM_ADC_TypeDef *)adc_dev->private_data;
ADC_Init((ADCx),&stcAdcInit);
return ret;
}
static uint32 AdcClose(void *dev)
{
// CM_ADC_TypeDef *adc_dev = (CM_ADC_TypeDef*)dev;
struct AdcHardwareDevice* adc_dev = (struct AdcHardwareDevice*)dev;
CM_ADC_TypeDef *ADCx= (CM_ADC_TypeDef *)adc_dev->private_data;
ADC_DeInit(ADCx);
return EOK;
}
static uint32 AdcRead(void *dev, struct BusBlockReadParam *read_param)
{
struct AdcHardwareDevice *adc_dev = (struct AdcHardwareDevice *)dev;
struct HwAdc *adc_cfg = (struct HwAdc *)adc_dev->haldev.private_data;
uint16 adc_average_value = 0;
uint8 times = 20;
adc_average_value = GetAdcAverageValue(adc_cfg->ADCx, adc_cfg->adc_channel, times);
*(uint16 *)read_param->buffer = adc_average_value;
read_param->read_length = 2;
return read_param->read_length;
}
static uint32 AdcDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(drv);
NULL_PARAM_CHECK(configure_info);
x_err_t ret = EOK;
uint8 adc_channel;
struct AdcDriver *adc_drv = (struct AdcDriver *)drv;
struct AdcHardwareDevice *adc_dev = (struct AdcHardwareDevice *)adc_drv->driver.owner_bus->owner_haldev;
struct HwAdc *adc_cfg = (struct HwAdc *)adc_dev->haldev.private_data;
switch (configure_info->configure_cmd)
{
case OPE_CFG:
adc_cfg->adc_channel = *(uint8 *)configure_info->private_data;
if (adc_cfg->adc_channel > 18) {
KPrintf("AdcDrvConfigure set adc channel(0-18) %u error!", adc_cfg->adc_channel);
adc_cfg->adc_channel = 0;
ret = ERROR;
}
break;
default:
break;
}
return ret;
}
static const struct AdcDevDone dev_done =
{
AdcOpen,
AdcClose,
NONE,
AdcRead,
};
int HwAdcInit(void)
{
x_err_t ret = EOK;
#ifdef BSP_USING_ADC1
static struct AdcBus adc1_bus;
static struct AdcDriver adc1_drv;
static struct AdcHardwareDevice adc1_dev;
static struct HwAdc adc1_cfg;
adc1_drv.configure = AdcDrvConfigure;
ret = AdcBusInit(&adc1_bus, ADC1_BUS_NAME);
if (ret != EOK) {
KPrintf("ADC1 bus init error %d\n", ret);
return ERROR;
}
ret = AdcDriverInit(&adc1_drv, ADC1_DRIVER_NAME);
if (ret != EOK) {
KPrintf("ADC1 driver init error %d\n", ret);
return ERROR;
}
ret = AdcDriverAttachToBus(ADC1_DRIVER_NAME, ADC1_BUS_NAME);
if (ret != EOK) {
KPrintf("ADC1 driver attach error %d\n", ret);
return ERROR;
}
adc1_dev.adc_dev_done = &dev_done;
adc1_cfg.ADCx = CM_ADC1;
adc1_cfg.adc_channel = 0;
ret = AdcDeviceRegister(&adc1_dev, (void *)&adc1_cfg, ADC1_DEVICE_NAME);
if (ret != EOK) {
KPrintf("ADC1 device register error %d\n", ret);
return ERROR;
}
ret = AdcDeviceAttachToBus(ADC1_DEVICE_NAME, ADC1_BUS_NAME);
if (ret != EOK) {
KPrintf("ADC1 device register error %d\n", ret);
return ERROR;
}
#endif
#ifdef BSP_USING_ADC2
static struct AdcBus adc2_bus;
static struct AdcDriver adc2_drv;
static struct AdcHardwareDevice adc2_dev;
static struct HwAdc adc2_cfg;
adc2_drv.configure = AdcDrvConfigure;
ret = AdcBusInit(&adc2_bus, ADC2_BUS_NAME);
if (ret != EOK) {
KPrintf("ADC2 bus init error %d\n", ret);
return ERROR;
}
ret = AdcDriverInit(&adc2_drv, ADC2_DRIVER_NAME);
if (ret != EOK) {
KPrintf("ADC2 driver init error %d\n", ret);
return ERROR;
}
ret = AdcDriverAttachToBus(ADC2_DRIVER_NAME, ADC2_BUS_NAME);
if (ret != EOK) {
KPrintf("ADC2 driver attach error %d\n", ret);
return ERROR;
}
adc2_dev.adc_dev_done = &dev_done;
adc2_cfg.ADCx = CM_ADC2;
adc2_cfg.adc_channel = 0;
ret = AdcDeviceRegister(&adc2_dev, (void *)&adc2_cfg, ADC2_DEVICE_NAME);
if (ret != EOK) {
KPrintf("ADC2 device register error %d\n", ret);
return ERROR;
}
ret = AdcDeviceAttachToBus(ADC2_DEVICE_NAME, ADC2_BUS_NAME);
if (ret != EOK) {
KPrintf("ADC2 device register error %d\n", ret);
return ERROR;
}
#endif
#ifdef BSP_USING_ADC3
static struct AdcBus adc3_bus;
static struct AdcDriver adc3_drv;
static struct AdcHardwareDevice adc3_dev;
static struct HwAdc adc3_cfg;
adc3_drv.configure = AdcDrvConfigure;
ret = AdcBusInit(&adc3_bus, ADC3_BUS_NAME);
if (ret != EOK) {
KPrintf("ADC3 bus init error %d\n", ret);
return ERROR;
}
ret = AdcDriverInit(&adc3_drv, ADC3_DRIVER_NAME);
if (ret != EOK) {
KPrintf("ADC3 driver init error %d\n", ret);
return ERROR;
}
ret = AdcDriverAttachToBus(ADC3_DRIVER_NAME, ADC3_BUS_NAME);
if (ret != EOK) {
KPrintf("ADC3 driver attach error %d\n", ret);
return ERROR;
}
adc3_dev.adc_dev_done = &dev_done;
adc3_cfg.ADCx = CM_ADC3;
adc3_cfg.adc_channel = 0;
ret = AdcDeviceRegister(&adc3_dev, (void *)&adc3_cfg, ADC3_DEVICE_NAME);
if (ret != EOK) {
KPrintf("ADC3 device register error %d\n", ret);
return ERROR;
}
ret = AdcDeviceAttachToBus(ADC3_DEVICE_NAME, ADC3_BUS_NAME);
if (ret != EOK) {
KPrintf("ADC3 device register error %d\n", ret);
return ERROR;
}
#endif
return ret;
}

View File

@ -4,6 +4,14 @@ ifeq ($(CONFIG_BSP_USING_UART),y)
SRC_FILES += hc32_ll_usart.c
endif
ifeq ($(CONFIG_BSP_USING_ADC),y)
SRC_FILES += hc32_ll_adc.c
endif
ifeq ($(CONFIG_BSP_USING_DAC),y)
SRC_FILES += hc32_ll_dac.c
endif
ifeq ($(CONFIG_BSP_USING_SDIO),y)
SRC_FILES += hc32_ll_sdioc.c
endif

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
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,156 @@
/*
* 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 2023-2-09
*/
#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 uint32 DacOpen(void *dev)
{
struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dev;
CM_DAC_TypeDef *DACx = (CM_DAC_TypeDef *)dac_dev->private_data;
stc_dac_init_t pstcDacInit;
DAC_StructInit(&pstcDacInit);
DAC_Init(DACx,DAC_CH1,&pstcDacInit);
return EOK;
}
static uint32 DacClose(void *dev)
{
struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dev;
CM_DAC_TypeDef *DACx = (CM_DAC_TypeDef *)dac_dev->private_data;
DAC_DeInit(DACx);
return EOK;
}
static uint32 DacRead(void *dev, struct BusBlockReadParam *read_param)
{
struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dev;
CM_DAC_TypeDef *DACx = (CM_DAC_TypeDef *)dac_dev->private_data;
uint16 dac_set_value = 0;
// dac_set_value = DAC_GetDataOutputValue(DAC_CH1);
dac_set_value = DAC_GetChConvertState(DACx,DAC_CH1);
*(uint16 *)read_param->buffer = dac_set_value;
read_param->read_length = 2;
return read_param->read_length;
return EOK;
}
static uint32 DacDrvConfigure(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 HwDac *dac_cfg = (struct HwDac *)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
DAC_SetChData(dac_cfg->DACx,DAC_CH1,dac_cfg->digital_data);
break;
default:
break;
}
return ret;
}
static const struct DacDevDone dev_done =
{
DacOpen,
DacClose,
NONE,
DacRead,
};
int HwDacInit(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 HwDac dac_cfg;
dac_drv.configure = DacDrvConfigure;
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 = CM_DAC1;
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,42 @@
/*
* 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_uart.h
* @brief define hc32f4a0-board usart function and struct
* @version 2.0
* @author AIIT XUOS Lab
* @date 2023-02-09
*/
#include <device.h>
#include <hardware_irq.h>
#include <hc32_ll_adc.h>
#ifdef __cplusplus
extern "C" {
#endif
struct HwAdc
{
CM_ADC_TypeDef *ADCx;
uint8 adc_channel;
};
int HwAdcInit(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,50 @@
/*
* 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_uart.h
* @brief define hc32f4a0-board usart function and struct
* @version 2.0
* @author AIIT XUOS Lab
* @date
*/
#include <device.h>
#include <hardware_irq.h>
#include <hc32_ll_fcg.h>
#include <hc32_ll_dac.h>
#include <hc32_ll_gpio.h>
#ifdef __cplusplus
extern "C" {
#endif
struct HwDac
{
CM_DAC_TypeDef *DACx;
uint16 digital_data;
};
typedef struct {
CM_DAC_TypeDef *pUnit;
// en_dac_cvt_t enCvtType;
uint16_t u16Ch;
} stc_dac_handle_t;
int HwDacInit(void);
#ifdef __cplusplus
}
#endif