diff --git a/bsp/mm32f327x/drivers/Kconfig b/bsp/mm32f327x/drivers/Kconfig index f9f37213eb..0d22a9c319 100644 --- a/bsp/mm32f327x/drivers/Kconfig +++ b/bsp/mm32f327x/drivers/Kconfig @@ -1,23 +1,38 @@ menu "Hardware Drivers Config" - menu "On-chip Peripheral Drivers" + menu "GPIO Drivers" config BSP_USING_GPIO bool "Enable GPIO" select RT_USING_PIN default n endmenu + menu "UART Drivers" config BSP_USING_UART1 bool "Enable UART1 PA9/10(T/R)" select RT_USING_SERIAL default n - config BSP_USING_UART2 bool "Enable UART2 PA2/3(T/R)" select RT_USING_SERIAL default y endmenu + + menuconfig BSP_USING_ADC + bool "Enable ADC" + default n + select RT_USING_ADC + if BSP_USING_ADC + config BSP_USING_ADC1 + bool "Enable ADC1" + default n + + config BSP_USING_ADC2 + bool "Enable ADC2" + default n + endif + menu "Flash Drivers" config BSP_USING_OCFLASH bool "Enable On Chip Flash" @@ -36,5 +51,4 @@ menu "Hardware Drivers Config" default n endmenu endmenu - endmenu diff --git a/bsp/mm32f327x/drivers/SConscript b/bsp/mm32f327x/drivers/SConscript index 27aeda3f91..be3a6f1ff2 100644 --- a/bsp/mm32f327x/drivers/SConscript +++ b/bsp/mm32f327x/drivers/SConscript @@ -17,7 +17,11 @@ if GetDepend('BSP_USING_UART1') or GetDepend('BSP_USING_UART2'): if GetDepend(['BSP_USING_GPIO']): src += ['drv_gpio.c'] -# add gpio driver code +# add adc driver code +if GetDepend(['BSP_USING_ADC']): + src += ['drv_adc.c'] + +# add flash driver code if GetDepend(['BSP_USING_OCFLASH']): src += ['drv_flash.c'] CPPPATH = [cwd] diff --git a/bsp/mm32f327x/drivers/drv_adc.c b/bsp/mm32f327x/drivers/drv_adc.c new file mode 100644 index 0000000000..e2cae02ec2 --- /dev/null +++ b/bsp/mm32f327x/drivers/drv_adc.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-03-17 letian first version + */ +#include +#include +#include "drv_adc.h" +#include +#include +#include +#include + +#if defined(BSP_USING_ADC) + +#define ADC_CONFIG_GPIORCC RCC_AHBENR_GPIOA +#define ADC_CONFIG_GPIOX GPIOA +#define ADC_CONFIG_IOX GPIO_Pin_5 | GPIO_Pin_4 + +struct mm32_adc +{ + struct rt_adc_device mm32_adc_device; + ADC_TypeDef *adc_x; + char *name; +}; + +#if defined(BSP_USING_ADC1) +struct mm32_adc mm32_adc1_config = { + .adc_x = ADC1, + .name = "adc1", +}; +#endif /* BSP_USING_ADC1 */ + +#if defined(BSP_USING_ADC2) +struct mm32_adc mm32_adc2_config = { + .adc_x = ADC2, + .name = "adc2", +}; +#endif /* BSP_USING_ADC2 */ + +static void ADCxChannelEnable(ADC_TypeDef* ADCn, ADCCHANNEL_TypeDef channel) +{ + ADCn->CHSR &= ~(1 << channel); + ADCn->CHSR |= (1 << channel); +} + +static rt_err_t mm32_adc_init(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled) +{ + ADC_InitTypeDef ADC_InitStruct; + ADC_TypeDef *adc_x; + RT_ASSERT(device != RT_NULL); + adc_x = device->parent.user_data; + + #if defined(BSP_USING_ADC1) + RCC_APB2PeriphClockCmd(RCC_APB2ENR_ADC1, ENABLE); //Enable ADC1 clock + #endif /* BSP_USING_ADC1 */ + + #if defined(BSP_USING_ADC2) + RCC_APB2PeriphClockCmd(RCC_APB2ENR_ADC2, ENABLE); //Enable ADC2 clock + #endif /* BSP_USING_ADC2 */ + + ADC_StructInit(&ADC_InitStruct); + ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b; + ADC_InitStruct.ADC_PRESCARE = ADC_PCLK2_PRESCARE_16; //ADC prescale factor + ADC_InitStruct.ADC_Mode = ADC_Mode_Continue; //Set ADC mode to continuous conversion mode + ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; //AD data right-justified + ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; + ADC_Init(adc_x, &ADC_InitStruct); + + ADC_RegularChannelConfig(adc_x, channel, 0, ADC_Samctl_239_5); + ADC_Cmd(adc_x, ENABLE); + ADCxChannelEnable(adc_x, channel); + + //config gpio + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_StructInit(&GPIO_InitStruct); + + RCC_AHBPeriphClockCmd(ADC_CONFIG_GPIORCC, ENABLE); + GPIO_InitStruct.GPIO_Pin = ADC_CONFIG_IOX; + GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; + GPIO_Init(ADC_CONFIG_GPIOX, &GPIO_InitStruct); + + return RT_EOK; +} + +static rt_err_t mm32_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value) +{ + ADC_TypeDef *adc_x; + RT_ASSERT(device != RT_NULL); + adc_x = device->parent.user_data; + + ADC_SoftwareStartConvCmd(adc_x, ENABLE); + while(ADC_GetFlagStatus(adc_x, ADC_IT_EOC) == 0); + ADC_ClearFlag(adc_x, ADC_IT_EOC); + *value = ADC_GetConversionValue(adc_x); + return RT_EOK; +} + +static rt_uint8_t mm32_adc_get_resolution(struct rt_adc_device *device) +{ + ADC_TypeDef *adc_x = device->parent.user_data; + + RT_ASSERT(device != RT_NULL); + + switch( ((adc_x->CFGR)&(0x00000380)) ) + { + case ADC_Resolution_12b: + return 12; + case ADC_Resolution_11b: + return 11; + case ADC_Resolution_10b: + return 10; + case ADC_Resolution_9b: + return 9; + case ADC_Resolution_8b: + return 8; + default: + return 0; + } +} + +static rt_int16_t mm32_adc_get_vref(struct rt_adc_device *device) +{ + if(device == RT_NULL) + return RT_ERROR; + + return 3300; +} + +static const struct rt_adc_ops mm32_adc_ops = +{ + .enabled = mm32_adc_init, + .convert = mm32_get_adc_value, + .get_resolution = mm32_adc_get_resolution, + .get_vref = mm32_adc_get_vref, +}; + +int rt_hw_adc_init(void) +{ + #if defined(BSP_USING_ADC1) + rt_hw_adc_register(&mm32_adc1_config.mm32_adc_device, mm32_adc1_config.name, &mm32_adc_ops, mm32_adc1_config.adc_x); + #endif /* BSP_USING_ADC1 */ + + #if defined(BSP_USING_ADC2) + rt_hw_adc_register(&mm32_adc2_config.mm32_adc_device, mm32_adc2_config.name, &mm32_adc_ops, mm32_adc2_config.adc_x); + #endif /* BSP_USING_ADC2 */ + + return RT_EOK; +} +INIT_BOARD_EXPORT(rt_hw_adc_init); + +#endif /* BSP_USING_ADC */ diff --git a/bsp/mm32f327x/drivers/drv_adc.h b/bsp/mm32f327x/drivers/drv_adc.h new file mode 100644 index 0000000000..9812cdf3cd --- /dev/null +++ b/bsp/mm32f327x/drivers/drv_adc.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-03-17 letian first version + */ + +#ifndef __DRV_ADC_H__ +#define __DRV_ADC_H__ + +int rt_hw_adc_init(void); + +#endif