diff --git a/bsp/bouffalo_lab/libraries/rt_drivers/Kconfig b/bsp/bouffalo_lab/libraries/rt_drivers/Kconfig index 3c93d42630..707d98d201 100755 --- a/bsp/bouffalo_lab/libraries/rt_drivers/Kconfig +++ b/bsp/bouffalo_lab/libraries/rt_drivers/Kconfig @@ -665,6 +665,99 @@ menu "General Drivers Configuration" bool "Enable ADC" select RT_USING_ADC default n + if BSP_USING_ADC + config BSP_ADC_DMA_CHANNEL + string "ADC DMA Channel Name" + default "dma0_ch2" + config BSP_USING_ADC_CH0 + bool "USING ADC CH0" + default n + if BSP_USING_ADC_CH0 + config BSP_ADC_CH0_PIN + int "ADC CH0 Pin Num (GPIO_X)" + default 17 + endif + config BSP_USING_ADC_CH1 + bool "USING ADC CH1" + default n + if BSP_USING_ADC_CH1 + config BSP_ADC_CH1_PIN + int "ADC CH1 Pin Num (GPIO_X)" + default 5 + endif + config BSP_USING_ADC_CH2 + bool "USING ADC CH2" + default n + if BSP_USING_ADC_CH2 + config BSP_ADC_CH2_PIN + int "ADC CH2 Pin Num (GPIO_X)" + default 4 + endif + config BSP_USING_ADC_CH3 + bool "USING ADC CH3" + default n + if BSP_USING_ADC_CH3 + config BSP_ADC_CH3_PIN + int "ADC CH3 Pin Num (GPIO_X)" + default 11 + endif + config BSP_USING_ADC_CH4 + bool "USING ADC CH4" + default n + if BSP_USING_ADC_CH4 + config BSP_ADC_CH4_PIN + int "ADC CH4 Pin Num (GPIO_X)" + default 6 + endif + config BSP_USING_ADC_CH5 + bool "USING ADC CH5" + default n + if BSP_USING_ADC_CH5 + config BSP_ADC_CH5_PIN + int "ADC CH5 Pin Num (GPIO_X)" + default 40 + endif + config BSP_USING_ADC_CH6 + bool "USING ADC CH6" + default n + if BSP_USING_ADC_CH6 + config BSP_ADC_CH6_PIN + int "ADC CH6 Pin Num (GPIO_X)" + default 12 + endif + config BSP_USING_ADC_CH7 + bool "USING ADC CH7" + default n + if BSP_USING_ADC_CH7 + config BSP_ADC_CH7_PIN + int "ADC CH7 Pin Num (GPIO_X)" + default 13 + endif + config BSP_USING_ADC_CH8 + bool "USING ADC CH8" + default n + if BSP_USING_ADC_CH8 + config BSP_ADC_CH8_PIN + int "ADC CH8 Pin Num (GPIO_X)" + default 16 + endif + config BSP_USING_ADC_CH9 + bool "USING ADC CH9" + default n + if BSP_USING_ADC_CH9 + config BSP_ADC_CH9_PIN + int "ADC CH9 Pin Num (GPIO_X)" + default 18 + endif + config BSP_USING_ADC_CH10 + bool "USING ADC CH10" + default n + if BSP_USING_ADC_CH10 + config BSP_ADC_CH10_PIN + int "ADC CH10 Pin Num (GPIO_X)" + default 19 + endif + endif config BSP_USING_RTC bool "Enable RTC" diff --git a/bsp/bouffalo_lab/libraries/rt_drivers/drv_adc.c b/bsp/bouffalo_lab/libraries/rt_drivers/drv_adc.c index 8dc28cd8b8..7cbe6dddfc 100644 --- a/bsp/bouffalo_lab/libraries/rt_drivers/drv_adc.c +++ b/bsp/bouffalo_lab/libraries/rt_drivers/drv_adc.c @@ -22,61 +22,148 @@ #define ADC_GPIP_BASE ((uint32_t)0x20002000) #endif +static struct bflb_dma_channel_lli_pool_s lli[1]; +static volatile uint32_t raw_data[16 + 10]; +static struct bflb_adc_result_s adc_value[10]; + static struct bflb_adc_config_s adc_config = { - ADC_CLK_DIV_32, - false, - false, - false, - ADC_RESOLUTION_16B, - ADC_VREF_2P0V + .clk_div = ADC_CLK_DIV_32, + .scan_conv_mode = false, + .continuous_conv_mode = true, + .differential_mode = false, + .resolution = ADC_RESOLUTION_16B, + .vref = ADC_VREF_3P2V, }; struct bl_adc { struct rt_adc_device bl_adc_device; - struct bflb_device_s *bflb_device; + struct bflb_device_s *adc; + struct bflb_device_s *dma; + rt_sem_t sem; }; static struct bl_adc bl_adc_obj; -static rt_err_t bl_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled) +struct _adc_channel_cfg { - struct bflb_device_s *bl_adc_handler; - RT_ASSERT(device != RT_NULL); - bl_adc_handler = device->parent.user_data; struct bflb_adc_channel_s chan; + uint16_t chan_gpio; +}; +static struct _adc_channel_cfg chan[] = { +#ifdef BSP_USING_ADC_CH0 + { .chan.pos_chan = ADC_CHANNEL_0, + .chan.neg_chan = ADC_CHANNEL_GND, + .chan_gpio = BSP_ADC_CH0_PIN,}, +#endif +#ifdef BSP_USING_ADC_CH1 + { .chan.pos_chan = ADC_CHANNEL_1, + .chan.neg_chan = ADC_CHANNEL_GND, + .chan_gpio = BSP_ADC_CH1_PIN,}, +#endif +#ifdef BSP_USING_ADC_CH2 + { .chan.pos_chan = ADC_CHANNEL_2, + .chan.neg_chan = ADC_CHANNEL_GND, + .chan_gpio = BSP_ADC_CH2_PIN,}, +#endif +#ifdef BSP_USING_ADC_CH3 + { .chan.pos_chan = ADC_CHANNEL_3, + .chan.neg_chan = ADC_CHANNEL_GND, + .chan_gpio = BSP_ADC_CH3_PIN,}, +#endif +#ifdef BSP_USING_ADC_CH4 + { .chan.pos_chan = ADC_CHANNEL_4, + .chan.neg_chan = ADC_CHANNEL_GND, + .chan_gpio = BSP_ADC_CH4_PIN,}, +#endif +#ifdef BSP_USING_ADC_CH5 + { .chan.pos_chan = ADC_CHANNEL_5, + .chan.neg_chan = ADC_CHANNEL_GND, + .chan_gpio = BSP_ADC_CH5_PIN,}, +#endif +#ifdef BSP_USING_ADC_CH6 + { .chan.pos_chan = ADC_CHANNEL_6, + .chan.neg_chan = ADC_CHANNEL_GND, + .chan_gpio = BSP_ADC_CH6_PIN,}, +#endif +#ifdef BSP_USING_ADC_CH7 + { .chan.pos_chan = ADC_CHANNEL_7, + .chan.neg_chan = ADC_CHANNEL_GND, + .chan_gpio = BSP_ADC_CH7_PIN,}, +#endif +#ifdef BSP_USING_ADC_CH8 + { .chan.pos_chan = ADC_CHANNEL_8, + .chan.neg_chan = ADC_CHANNEL_GND, + .chan_gpio = BSP_ADC_CH8_PIN,}, +#endif +#ifdef BSP_USING_ADC_CH9 + { .chan.pos_chan = ADC_CHANNEL_9, + .chan.neg_chan = ADC_CHANNEL_GND, + .chan_gpio = BSP_ADC_CH9_PIN,}, +#endif +#ifdef BSP_USING_ADC_CH10 + { .chan.pos_chan = ADC_CHANNEL_10, + .chan.neg_chan = ADC_CHANNEL_GND, + .chan_gpio = BSP_ADC_CH10_PIN,}, +#endif +}; + +static void bl_adc_pin_init(void) +{ + struct bflb_device_s *gpio; + + gpio = bflb_device_get_by_name("gpio"); + for (uint8_t i = 0; i < sizeof(chan) / sizeof(chan[0]); i++) + { + bflb_gpio_init(gpio, chan[i].chan_gpio, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0); + } +} + +static rt_err_t bl_adc_enabled(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled) +{ + RT_ASSERT(device != RT_NULL); + struct bl_adc *_adc; + struct bflb_dma_channel_lli_transfer_s transfers[1]; + _adc = (struct bl_adc *)device->parent.user_data; + struct bflb_adc_channel_s chan; chan.pos_chan = channel; chan.neg_chan = ADC_CHANNEL_GND; - bflb_adc_channel_config(bl_adc_handler, &chan, channel); + bflb_adc_channel_config(_adc->adc, &chan, channel); - bflb_adc_link_rxdma(bl_adc_handler, enabled); + transfers[0].src_addr = (uint32_t)DMA_ADDR_ADC_RDR; + transfers[0].dst_addr = (uint32_t)raw_data; + transfers[0].nbytes = sizeof(raw_data); + + bflb_dma_channel_lli_reload(_adc->dma, lli, 1, transfers, 1); + bflb_dma_channel_start(_adc->dma); if (enabled) { - bflb_adc_start_conversion(bl_adc_handler); + bflb_adc_start_conversion(_adc->adc); } else { - bflb_adc_stop_conversion(bl_adc_handler); + bflb_adc_stop_conversion(_adc->adc); } return RT_EOK; } -static rt_err_t bl_adc_get_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value) +static rt_err_t bl_adc_get_value(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value) { - struct bflb_device_s *bl_adc_handler; + struct bl_adc *_adc; RT_ASSERT(device != RT_NULL); RT_ASSERT(value != RT_NULL); - bl_adc_handler = device->parent.user_data; + _adc = device->parent.user_data; + rt_sem_take(_adc->sem, RT_WAITING_FOREVER); /* get ADC value */ - *value = (rt_uint32_t)bflb_adc_read_raw(bl_adc_handler); + *value = (rt_uint32_t)raw_data[10 + channel]; return RT_EOK; } @@ -87,16 +174,55 @@ static const struct rt_adc_ops bl_adc_ops = .convert = bl_adc_get_value, }; +static void bl_adc_dma_isr(void *arg) +{ + struct bl_adc *_adc = (struct bl_adc *)arg; + LOG_D("adc dma done "); + + // bflb_adc_parse_result(_adc->adc, raw_data, adc_value, 10); + + rt_sem_release(_adc->sem); +} + int rt_hw_adc_init(void) { int result = RT_EOK; - /* ADC init */ - bl_adc_obj.bflb_device = bflb_device_get_by_name("adc"); - bflb_adc_init(bl_adc_obj.bflb_device, &adc_config); + bl_adc_pin_init(); + bl_adc_obj.adc = bflb_device_get_by_name("adc"); + bl_adc_obj.dma = bflb_device_get_by_name(BSP_ADC_DMA_CHANNEL); + + if(bl_adc_obj.adc == RT_NULL || bl_adc_obj.dma == RT_NULL) + { + LOG_E("adc dma device not found"); + return -RT_ERROR; + } + + bl_adc_obj.sem = rt_sem_create("adc_sem", 0, RT_IPC_FLAG_PRIO); + if(bl_adc_obj.sem == RT_NULL) + { + LOG_E("rt_sem_create adc_dma_sem error"); + return -RT_ENOMEM; + } + + bflb_adc_init(bl_adc_obj.adc, &adc_config); + bflb_adc_link_rxdma(bl_adc_obj.adc, true); + + struct bflb_dma_channel_config_s config; + config.direction = DMA_PERIPH_TO_MEMORY; + config.src_req = DMA_REQUEST_ADC; + config.dst_req = DMA_REQUEST_NONE; + config.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE; + config.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE; + config.src_burst_count = DMA_BURST_INCR1; + config.dst_burst_count = DMA_BURST_INCR1; + config.src_width = DMA_DATA_WIDTH_32BIT; + config.dst_width = DMA_DATA_WIDTH_32BIT; + bflb_dma_channel_init(bl_adc_obj.dma, &config); + bflb_dma_channel_irq_attach(bl_adc_obj.dma, bl_adc_dma_isr, (void *)&bl_adc_obj); /* register ADC device */ - if (rt_hw_adc_register(&bl_adc_obj.bl_adc_device, "adc", &bl_adc_ops, &bl_adc_obj.bflb_device) == RT_EOK) + if (rt_hw_adc_register(&bl_adc_obj.bl_adc_device, "adc", &bl_adc_ops, &bl_adc_obj) == RT_EOK) { LOG_D("adc init success"); } diff --git a/bsp/bouffalo_lab/libraries/rt_drivers/drv_adc.h b/bsp/bouffalo_lab/libraries/rt_drivers/drv_adc.h index c6b9812653..bfe70719cf 100644 --- a/bsp/bouffalo_lab/libraries/rt_drivers/drv_adc.h +++ b/bsp/bouffalo_lab/libraries/rt_drivers/drv_adc.h @@ -6,6 +6,7 @@ #include #include "bflb_adc.h" #include "bflb_core.h" +#include "bflb_dma.h" int rt_hw_adc_init(void);