From fdcee2da209fa587260d6b92bb37bb721bc6e5d5 Mon Sep 17 00:00:00 2001 From: linshire <89723088+linshire@users.noreply.github.com> Date: Sat, 17 Sep 2022 10:50:57 +0800 Subject: [PATCH] [BSP] CH32V307 add drv_adc (#6431) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加了ch32v307的adc驱动,已在ch32v307评估班上对adc1ch5进行了验证,并修改了kconfig以及scons脚本,可以成功编译以及使用 --- .../risc-v/Libraries/ch32_drivers/SConscript | 7 +- .../risc-v/Libraries/ch32_drivers/drv_adc.c | 278 ++++++++++++++++++ .../risc-v/Libraries/ch32_drivers/drv_adc.h | 27 ++ bsp/wch/risc-v/ch32v307v-r1/board/Kconfig | 96 ++++-- 4 files changed, 374 insertions(+), 34 deletions(-) create mode 100644 bsp/wch/risc-v/Libraries/ch32_drivers/drv_adc.c create mode 100644 bsp/wch/risc-v/Libraries/ch32_drivers/drv_adc.h diff --git a/bsp/wch/risc-v/Libraries/ch32_drivers/SConscript b/bsp/wch/risc-v/Libraries/ch32_drivers/SConscript index bc3867cd06..ef3ff5fc77 100644 --- a/bsp/wch/risc-v/Libraries/ch32_drivers/SConscript +++ b/bsp/wch/risc-v/Libraries/ch32_drivers/SConscript @@ -8,7 +8,6 @@ cwd = GetCurrentDir() src = Split(""" """) - if GetDepend('SOC_RISCV_FAMILY_CH32'): if GetDepend('RT_USING_PIN'): @@ -17,13 +16,11 @@ if GetDepend('SOC_RISCV_FAMILY_CH32'): if GetDepend(['RT_USING_SERIAL', 'BSP_USING_UART']): src += ['drv_usart.c'] - - - + if GetDepend('RT_USING_ADC'): + src += ['drv_adc.c'] path = [cwd] - group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path) Return('group') diff --git a/bsp/wch/risc-v/Libraries/ch32_drivers/drv_adc.c b/bsp/wch/risc-v/Libraries/ch32_drivers/drv_adc.c new file mode 100644 index 0000000000..6ada83c8cf --- /dev/null +++ b/bsp/wch/risc-v/Libraries/ch32_drivers/drv_adc.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-09-16 linshire the first version which add from wch + */ + +#include +#include +#include +#include "drv_adc.h" + +#if defined(BSP_USING_ADC1) || defined(BSP_USING_ADC2) + +//#define DRV_DEBUG +#define LOG_TAG "drv.adc" +#include + +static ADC_HandleTypeDef adc_config[] = +{ +#ifdef BSP_USING_ADC1 + { \ + .Instance = ADC1, \ + .Init.ADC_Mode = ADC_Mode_Independent, \ + .Init.ADC_ScanConvMode = DISABLE, \ + .Init.ADC_ContinuousConvMode = DISABLE, \ + .Init.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None, \ + .Init.ADC_DataAlign = ADC_DataAlign_Right, \ + .Init.ADC_NbrOfChannel = 1, \ + }, +#endif + +#ifdef BSP_USING_ADC2 + { \ + .Instance = ADC2, \ + .Init.ADC_Mode = ADC_Mode_Independent, \ + .Init.ADC_ScanConvMode = DISABLE, \ + .Init.ADC_ContinuousConvMode = DISABLE, \ + .Init.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None, \ + .Init.ADC_DataAlign = ADC_DataAlign_Right, \ + .Init.ADC_NbrOfChannel = 1, \ + } +#endif +}; + +struct ch32_adc +{ + ADC_HandleTypeDef ADC_Handler; + struct rt_adc_device ch32_adc_device; +}; + +static struct ch32_adc ch32_adc_obj[sizeof(adc_config) / sizeof(adc_config[0])]; + +static rt_uint8_t ch32_adc_get_resolution(struct rt_adc_device *device) +{ + //the resolution which can not be changed is just 12bit; + return 12; +} + +static rt_int16_t ch32_adc_get_vref (struct rt_adc_device *device) +{ + RT_ASSERT(device); + return 3300; +} + +static rt_err_t ch32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled) +{ + ADC_HandleTypeDef *ch32_adc_handler; + RT_ASSERT(device != RT_NULL); + ch32_adc_handler = device->parent.user_data; + + if (enabled) + { + ADC_Cmd(ch32_adc_handler->Instance, ENABLE); + } + else + { + ADC_Cmd(ch32_adc_handler->Instance, DISABLE); + } + + return RT_EOK; +} + +static rt_uint32_t ch32_adc_get_channel(rt_uint32_t channel) +{ + rt_uint32_t ch32_channel = 0; + + switch (channel) + { + case 0: + ch32_channel = ADC_Channel_0; + break; + case 1: + ch32_channel = ADC_Channel_1; + break; + case 2: + ch32_channel = ADC_Channel_2; + break; + case 3: + ch32_channel = ADC_Channel_3; + break; + case 4: + ch32_channel = ADC_Channel_4; + break; + case 5: + ch32_channel = ADC_Channel_5; + break; + case 6: + ch32_channel = ADC_Channel_6; + break; + case 7: + ch32_channel = ADC_Channel_7; + break; + case 8: + ch32_channel = ADC_Channel_8; + break; + case 9: + ch32_channel = ADC_Channel_9; + break; + case 10: + ch32_channel = ADC_Channel_10; + break; + case 11: + ch32_channel = ADC_Channel_11; + break; + case 12: + ch32_channel = ADC_Channel_12; + break; + case 13: + ch32_channel = ADC_Channel_13; + break; + case 14: + ch32_channel = ADC_Channel_14; + break; + case 15: + ch32_channel = ADC_Channel_15; + break; +#ifdef ADC_CHANNEL_16 + case 16: + ch32_channel = ADC_Channel_16; + break; +#endif /* ADC_CHANNEL_16 */ +#ifdef ADC_CHANNEL_17 + case 17: + ch32_channel = ADC_Channel_17; + break; +#endif /* ADC_CHANNEL_17 */ + case 18: + ch32_channel = ADC_Channel_18; + break; +#ifdef ADC_CHANNEL_19 + case 19: + ch32_channel = ADC_Channel_19; + break; +#endif /* ADC_CHANNEL_19 */ + } + + return ch32_channel; +} + +static rt_err_t ch32_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value) +{ + ADC_ChannelConfTypeDef ADC_ChanConf; + ADC_HandleTypeDef *ch32_adc_handler; + + RT_ASSERT(device != RT_NULL); + RT_ASSERT(value != RT_NULL); + + ch32_adc_handler = device->parent.user_data; + + rt_memset(&ADC_ChanConf, 0, sizeof(ADC_ChanConf)); + +#ifndef ADC_CHANNEL_16 + if (channel == 16) + { + LOG_E("ADC channel must not be 16."); + return -RT_ERROR; + } +#endif + +/* ADC channel number is up to 17 */ +#if !defined(ADC_CHANNEL_18) + if (channel <= 17) +/* ADC channel number is up to 19 */ +#elif defined(ADC_CHANNEL_19) + if (channel <= 19) +/* ADC channel number is up to 18 */ +#else + if (channel <= 18) +#endif + { + /* set ch32 ADC channel */ + ADC_ChanConf.Channel = ch32_adc_get_channel(channel); + } + else + { +#if !defined(ADC_CHANNEL_18) + LOG_E("ADC channel must be between 0 and 17."); +#elif defined(ADC_CHANNEL_19) + LOG_E("ADC channel must be between 0 and 19."); +#else + LOG_E("ADC channel must be between 0 and 18."); +#endif + return -RT_ERROR; + } + + ADC_ChanConf.Rank = 1; + ADC_ChanConf.SamplingTime = ADC_SampleTime_239Cycles5; + ADC_RegularChannelConfig(ch32_adc_handler->Instance,ADC_ChanConf.Channel , ADC_ChanConf.Rank, ADC_ChanConf.SamplingTime ); + + /* start ADC */ + ADC_SoftwareStartConvCmd(ch32_adc_handler->Instance, ENABLE); + /* Wait for the ADC to convert */ + while(!ADC_GetFlagStatus(ch32_adc_handler->Instance, ADC_FLAG_EOC )); + /* get ADC value */ + *value = (rt_uint32_t)ADC_GetConversionValue(ch32_adc_handler->Instance); + ADC_ClearFlag( ch32_adc_handler->Instance, ADC_FLAG_EOC); + + return RT_EOK; +} + +static const struct rt_adc_ops ch32_adc_ops = +{ + .enabled = ch32_adc_enabled, + .convert = ch32_get_adc_value, + .get_resolution = ch32_adc_get_resolution, + .get_vref = ch32_adc_get_vref +}; + +static int ch32_adc_init(void) +{ + int result = RT_EOK; + /* save adc name */ + char name_buf[5] = {'a', 'd', 'c', '0', 0}; + int i = 0; + + for (i = 0; i < sizeof(adc_config) / sizeof(adc_config[0]); i++) + { + /* ADC init */ + name_buf[3] = '0'; + ch32_adc_obj[i].ADC_Handler = adc_config[i]; +#if defined(ADC1) + if (ch32_adc_obj[i].ADC_Handler.Instance == ADC1) + { + name_buf[3] = '1'; + RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE ); + } +#endif +#if defined(ADC2) + if (ch32_adc_obj[i].ADC_Handler.Instance == ADC2) + { + name_buf[3] = '2'; + RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE ); + } +#endif + { + ADC_Init(ch32_adc_obj[i].ADC_Handler.Instance,&ch32_adc_obj[i].ADC_Handler.Init ); + /* register ADC device */ + if (rt_hw_adc_register(&ch32_adc_obj[i].ch32_adc_device, name_buf, &ch32_adc_ops, &ch32_adc_obj[i].ADC_Handler) == RT_EOK) + { + LOG_D("%s init success", name_buf); + } + else + { + LOG_E("%s register failed", name_buf); + result = -RT_ERROR; + } + } + } + + return result; +} +INIT_DEVICE_EXPORT(ch32_adc_init); + +#endif /* BSP_USING_ADC */ diff --git a/bsp/wch/risc-v/Libraries/ch32_drivers/drv_adc.h b/bsp/wch/risc-v/Libraries/ch32_drivers/drv_adc.h new file mode 100644 index 0000000000..1d700569e0 --- /dev/null +++ b/bsp/wch/risc-v/Libraries/ch32_drivers/drv_adc.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-09-16 linshire add some operation function + * 2021-09-09 WCH the first version + */ +#ifndef DRV_ADC_H__ +#define DRV_ADC_H__ +typedef struct +{ + ADC_TypeDef *Instance; + ADC_InitTypeDef Init; +}ADC_HandleTypeDef; + +typedef struct +{ + uint32_t Channel; + uint32_t Rank; + uint32_t SamplingTime; + uint32_t Offset; +}ADC_ChannelConfTypeDef; + +#endif diff --git a/bsp/wch/risc-v/ch32v307v-r1/board/Kconfig b/bsp/wch/risc-v/ch32v307v-r1/board/Kconfig index 2c2a3854d3..06a7d3bce9 100644 --- a/bsp/wch/risc-v/ch32v307v-r1/board/Kconfig +++ b/bsp/wch/risc-v/ch32v307v-r1/board/Kconfig @@ -14,38 +14,76 @@ menu "On-chip Peripheral Drivers" select RT_USING_SERIAL default n - if BSP_USING_UART - config BSP_USING_UART1 - bool "Enable UART1" + if BSP_USING_UART + config BSP_USING_UART1 + bool "Enable UART1" + default n + + config BSP_USING_UART2 + bool "Enable UART2" + default n + + config BSP_USING_UART3 + bool "Enable UART3" + default n + + config BSP_USING_UART4 + bool "Enable UART4" + default n + + config BSP_USING_UART5 + bool "Enable UART5" + default n + + config BSP_USING_UART6 + bool "Enable UART6" + default n + + config BSP_USING_UART7 + bool "Enable UART7" + default n + + config BSP_USING_UART8 + bool "Enable UART8" + default n + endif + + config BSP_USING_ADC + bool "Enable ADC" + select RT_USING_ADC + default n + + if BSP_USING_ADC + config BSP_USING_ADC1 + bool "Enable ADC1" + default n + + config BSP_USING_ADC2 + bool "Enable ADC2" + default n + + config ADC_CHANNEL_16 + bool "Enable ADC CHANNEL 16 (inside temperature)" + default n + + config ADC_CHANNEL_17 + bool "Enable ADC CHANNEL 17 (inside Verf)" + default n + endif + + config BSP_USING_DAC + bool "Enable DAC" + select RT_USING_DAC default n - config BSP_USING_UART2 - bool "Enable UART2" - default n + if BSP_USING_DAC + config BSP_USING_DAC_CHANNEL1 + bool "Enable DAC CHANNEL1" + default n - config BSP_USING_UART3 - bool "Enable UART3" - default n - - config BSP_USING_UART4 - bool "Enable UART4" - default n - - config BSP_USING_UART5 - bool "Enable UART5" - default n - - config BSP_USING_UART6 - bool "Enable UART6" - default n - - config BSP_USING_UART7 - bool "Enable UART7" - default n - - config BSP_USING_UART8 - bool "Enable UART8" - default n + config BSP_USING_DAC_CHANNEL2 + bool "Enable DAC CHANNEL2" + default n endif endmenu