Merged in raiden00/nuttx_l0f0/stm32m0_adc (pull request #867)

Initial ADC support and some improvemnets for the STM32 M0

arch/arm/src/stm32f0l0/Kconfig: improvements

configs/b-l072z-lrwan1: add ADC example

Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
raiden00pl
2019-05-09 13:02:53 +00:00
committed by Gregory Nutt
parent a0061325ef
commit ebad04c269
13 changed files with 3250 additions and 230 deletions
File diff suppressed because it is too large Load Diff
+6 -2
View File
@@ -63,7 +63,7 @@ CMN_CSRCS += up_dumpnvic.c
endif
CHIP_ASRCS =
CHIP_CSRCS = stm32_start.c stm32_gpio.c stm32_exti_gpio.c stm32_irq.c # stm32_dma_v1.c
CHIP_CSRCS = stm32_start.c stm32_gpio.c stm32_exti_gpio.c stm32_irq.c stm32_dma_v1.c
CHIP_CSRCS += stm32_lse.c stm32_lowputc.c stm32_serial.c stm32_rcc.c
ifeq ($(CONFIG_STM32F0L0_PWR),y)
@@ -106,6 +106,10 @@ ifeq ($(CONFIG_STM32F0L0_SPI),y)
CHIP_CSRCS += stm32_spi.c
endif
ifeq ($(CONFIG_PWM),y)
ifeq ($(CONFIG_STM32F0L0_PWM),y)
CHIP_CSRCS += stm32_pwm.c
endif
ifeq ($(CONFIG_STM32F0L0_ADC),y)
CHIP_CSRCS += stm32_adc.c
endif
+107 -31
View File
@@ -45,10 +45,64 @@
#include "chip.h"
/* STM32 M0 ADC driver:
* - no injected channels
* - no offset registers
* - the F0/L0 family support one sampling time configuration for all channels
* - the G0 family support two sampling time configurations
*/
/* Support for battery voltage */
#if 0
# define HAVE_ADC_VBAT
#else
# undef HAVE_ADC_VBAT
#endif
/* Support for ADC clock prescaler */
#if defined(CONFIG_STM32F0L0_STM32L0) || defined(CONFIG_STM32F0L0_STM32G0)
# define HAVE_ADC_PRE
#else
# undef HAVE_ADC_PRE
#endif
/* Support for LCD voltage */
#ifdef CONFIG_STM32F0L0_HAVE_LCD
# define HAVE_ADC_VLCD
#else
# undef HAVE_ADC_VLCD
#endif
/* Supprot for Low frequency mode */
#ifdef CONFIG_STM32F0L0_ENERGYLITE
# define HAVE_ADC_LFM
#else
# undef HAVE_ADC_LFM
#endif
#undef ADC_HAVE_INJECTED
/********************************************************************************
* Pre-processor Definitions
********************************************************************************/
#define STM32_ADC1_OFFSET 0x0000
#define STM32_ADC2_OFFSET 0x0100
#define STM32_ADC3_OFFSET 0x0000
#define STM32_ADC4_OFFSET 0x0100
#define STM32_ADCCMN_OFFSET 0x0300
#define STM32_ADC1_BASE (STM32_ADC1_OFFSET+STM32_ADC12_BASE) /* ADC1 Master ADC */
#define STM32_ADC2_BASE (STM32_ADC2_OFFSET+STM32_ADC12_BASE) /* ADC2 Slave ADC */
#define STM32_ADC3_BASE (STM32_ADC3_OFFSET+STM32_ADC34_BASE) /* ADC3 Master ADC */
#define STM32_ADC4_BASE (STM32_ADC4_OFFSET+STM32_ADC34_BASE) /* ADC4 Slave ADC */
#define STM32_ADC12CMN_BASE (STM32_ADCCMN_OFFSET+STM32_ADC12_BASE) /* ADC1, ADC2 common */
#define STM32_ADC34CMN_BASE (STM32_ADCCMN_OFFSET+STM32_ADC34_BASE) /* ADC3, ADC4 common */
/* Register Offsets *********************************************************************************/
#define STM32_ADC_ISR_OFFSET 0x0000 /* ADC interrupt and status register */
@@ -60,20 +114,23 @@
#define STM32_ADC_TR_OFFSET 0x0020 /* ADC watchdog threshold register */
#define STM32_ADC_CHSELR_OFFSET 0x0028 /* ADC channel selection register */
#define STM32_ADC_DR_OFFSET 0x0040 /* ADC regular data register */
#define STM32_ADC_CCR_OFFSET 0x0308 /* ADC common configuration register */
/* Master and Slave ADC Common Registers */
#define STM32_ADC_CCR_OFFSET 0x0008 /* Common control register */
/* Register Addresses *******************************************************************************/
#define STM32_ADC_ISR (STM32_ADC_BASE + STM32_ADC_ISR_OFFSET)
#define STM32_ADC_IER (STM32_ADC_BASE + STM32_ADC_IER_OFFSET)
#define STM32_ADC_CR (STM32_ADC_BASE + STM32_ADC_CR_OFFSET)
#define STM32_ADC_CFGR1 (STM32_ADC_BASE + STM32_ADC_CFGR1_OFFSET)
#define STM32_ADC_CFGR2 (STM32_ADC_BASE + STM32_ADC_CFGR2_OFFSET)
#define STM32_ADC_SMPR (STM32_ADC_BASE + STM32_ADC_SMPR_OFFSET)
#define STM32_ADC_TR (STM32_ADC_BASE + STM32_ADC_TR_OFFSET)
#define STM32_ADC_CHSELR (STM32_ADC_BASE + STM32_ADC_CHSELR_OFFSET)
#define STM32_ADC_DR (STM32_ADC_BASE + STM32_ADC_DR_OFFSET)
#define STM32_ADC_CCR (STM32_ADC_BASE + STM32_ADC_CCR_OFFSET)
#define STM32_ADC1_ISR (STM32_ADC1_BASE + STM32_ADC_ISR_OFFSET)
#define STM32_ADC1_IER (STM32_ADC1_BASE + STM32_ADC_IER_OFFSET)
#define STM32_ADC1_CR (STM32_ADC1_BASE + STM32_ADC_CR_OFFSET)
#define STM32_ADC1_CFGR1 (STM32_ADC1_BASE + STM32_ADC_CFGR1_OFFSET)
#define STM32_ADC1_CFGR2 (STM32_ADC1_BASE + STM32_ADC_CFGR2_OFFSET)
#define STM32_ADC1_SMPR (STM32_ADC1_BASE + STM32_ADC_SMPR_OFFSET)
#define STM32_ADC1_TR (STM32_ADC1_BASE + STM32_ADC_TR_OFFSET)
#define STM32_ADC1_CHSELR (STM32_ADC1_BASE + STM32_ADC_CHSELR_OFFSET)
#define STM32_ADC1_DR (STM32_ADC1_BASE + STM32_ADC_DR_OFFSET)
#define STM32_ADC1_CCR (STM32_ADC1_BASE + STM32_ADC_CCR_OFFSET)
/* Register Bitfield Definitions ************************************************/
@@ -92,6 +149,7 @@
#define ADC_CR_ADDIS (1 << 1) /* Bit 1: ADC disable command */
#define ADC_CR_ADSTART (1 << 2) /* Bit 2: ADC start of regular conversion */
#define ADC_CR_ADSTP (1 << 4) /* Bit 4: ADC stop of regular conversion command */
#define ADC_CR_ADVREGEN (1 << 28) /* Bit 28: ADC Voltage Regulator Enable */
#define ADC_CR_ADCAL (1 << 31) /* Bit 31: ADC calibration */
/* ADC configuration register 1 */
@@ -143,16 +201,21 @@
/* ADC sample time register */
#define ADC_SMPR_SMP_SHIFT (0) /* Bits 0-2: Sampling time selection */
#define ADC_SMPR_SMP_MASK (7 << ADC_SMPR_SMP_SHIFT)
#define ADC_SMPR_SMP_1p5 (0 << ADC_SMPR_SMP_SHIFT) /* 000: 1.5 cycles */
#define ADC_SMPR_SMP_7p5 (1 << ADC_SMPR_SMP_SHIFT) /* 001: 7.5 cycles */
#define ADC_SMPR_SMP_13p5 (2 << ADC_SMPR_SMP_SHIFT) /* 010: 13.5 cycles */
#define ADC_SMPR_SMP_28p5 (3 << ADC_SMPR_SMP_SHIFT) /* 011: 28.5 cycles */
#define ADC_SMPR_SMP_41p5 (4 << ADC_SMPR_SMP_SHIFT) /* 100: 41.5 cycles */
#define ADC_SMPR_SMP_55p5 (5 << ADC_SMPR_SMP_SHIFT) /* 101: 55.5 cycles */
#define ADC_SMPR_SMP_71p5 (6 << ADC_SMPR_SMP_SHIFT) /* 110: 71.5 cycles */
#define ADC_SMPR_SMP_239p5 (7 << ADC_SMPR_SMP_SHIFT) /* 111: 239.5 cycles */
#define ADC_SMPR_1p5 (0) /* 000: 1.5 cycles */
#define ADC_SMPR_7p5 (1) /* 001: 7.5 cycles */
#define ADC_SMPR_13p5 (2) /* 010: 13.5 cycles */
#define ADC_SMPR_28p5 (3) /* 011: 28.5 cycles */
#define ADC_SMPR_41p5 (4) /* 100: 41.5 cycles */
#define ADC_SMPR_55p5 (5) /* 101: 55.5 cycles */
#define ADC_SMPR_71p5 (6) /* 110: 71.5 cycles */
#define ADC_SMPR_239p5 (7) /* 111: 239.5 cycles */
#define ADC_SMPR_SMP1_SHIFT (0) /* Bits 0-2: Sampling time selection 1 */
#define ADC_SMPR_SMP1_MASK (7 << ADC_SMPR_SMP_SHIFT)
#define ADC_SMPR_SMP2_SHIFT (4) /* Bits 4-6: Sampling time selection 2 */
#define ADC_SMPR_SMP2_MASK (7 << ADC_SMPR_SMP_SHIFT)
#define ADC_SMPR_SMPSEL_SHIFT (8) /* Bits 8-26: channel-x sampling time selection */
#define ADC_SMPR_SMPSEL(ch, smp) (smp << ADC_SMPR_SMPSEL_SHIFT)
/* ADC watchdog threshold register */
@@ -173,23 +236,36 @@
#define ADC_CHSELR_CHSEL7 (1 << 7) /* Select channel 7 */
#define ADC_CHSELR_CHSEL8 (1 << 8) /* Select channel 8 */
#define ADC_CHSELR_CHSEL9 (1 << 9) /* Select channel 9 */
#define ADC_CHSELR_CHSEL10 (1 << 10) /* Select channel 10 */
#define ADC_CHSELR_CHSEL11 (1 << 11) /* Select channel 11 */
#define ADC_CHSELR_CHSEL12 (1 << 12) /* Select channel 12 */
#define ADC_CHSELR_CHSEL13 (1 << 13) /* Select channel 13 */
#define ADC_CHSELR_CHSEL14 (1 << 14) /* Select channel 14 */
#define ADC_CHSELR_CHSEL15 (1 << 15) /* Select channel 15 */
#define ADC_CHSELR_CHSEL16 (1 << 16) /* Select channel 16 */
#define ADC_CHSELR_CHSEL17 (1 << 17) /* Select channel 17 */
#define ADC_CHSELR_CHSEL18 (1 << 18) /* Select channel 18 */
#define ADC_CHSELR_CHSEL10 (1 << 10) /* Select channel 10 */
#define ADC_CHSELR_CHSEL11 (1 << 11) /* Select channel 11 */
#define ADC_CHSELR_CHSEL12 (1 << 12) /* Select channel 12 */
#define ADC_CHSELR_CHSEL13 (1 << 13) /* Select channel 13 */
#define ADC_CHSELR_CHSEL14 (1 << 14) /* Select channel 14 */
#define ADC_CHSELR_CHSEL15 (1 << 15) /* Select channel 15 */
#define ADC_CHSELR_CHSEL16 (1 << 16) /* Select channel 16 */
#define ADC_CHSELR_CHSEL17 (1 << 17) /* Select channel 17 */
#define ADC_CHSELR_CHSEL18 (1 << 18) /* Select channel 18 */
#define ADC_CHSELR_CHSEL(ch) (1 << ch)
#define ADC_DR_RDATA_SHIFT (0)
#define ADC_DR_RDATA_MASK (0xffff << ADC_DR_RDATA_SHIFT)
/* Common configuration register */
#ifdef HAVE_ADC_VLCD
# define ADC_CCR_PRESC_SHIFT (18) /* ADC Prescaler */
# define ADC_CCR_PRESC_MASK (0xf << ADC_CCR_PRESC_SHIFT)
#endif
#define ADC_CCR_VREFEN (1 << 22) /* Bit 22: VREFINT enable */
#define ADC_CCR_TSEN (1 << 23) /* Bit 23: Temperature sensor enable */
#define ADC_CCR_VBATEN (1 << 24) /* Bit 22: VBAT enable */
#ifdef HAVE_ADC_VBAT
# define ADC_CCR_VBATEN (1 << 24) /* Bit 24: VBAT enable */
#endif
#ifdef HAVE_ADC_VLCD
# define ADC_CCR_VLCDEN (1 << 24) /* Bit 24: VLCD enable */
#endif
#ifdef HAVE_ADC_LFM
# define ADC_CCR_LFMEN (1 << 25) /* Bit 25: Low Frequency Mode enable */
#endif
#endif /* __ARCH_ARM_SRC_STM32F0L0_CHIP_STM32_ADC_H */
@@ -119,7 +119,7 @@
#define STM32_USART6_BASE 0x40011400 /* 0x40011400-0x400117ff USART6 */
#define STM32_USART7_BASE 0x40011800 /* 0x40011800-0x40011bff USART7 */
#define STM32_USART8_BASE 0x40011c00 /* 0x40011c00-0x40011fff USART8 */
#define STM32_ADC1_BASE 0x40012400 /* 0x40012400-0x400127ff ADC 1 */
#define STM32_ADC12_BASE 0x40012400 /* 0x40012400-0x400127ff ADC 12 */
#define STM32_TIM1_BASE 0x40012c00 /* 0x40012c00-0x40012fff TIM1 */
#define STM32_SPI1_BASE 0x40013000 /* 0x40013000-0x400133ff SPI1 */
#define STM32_USART1_BASE 0x40013800 /* 0x40013800-0x40013bff USART1 */
@@ -103,7 +103,7 @@
#define STM32_TIM21_BASE 0x40010800 /* 0x40010800-0x40010bff TIM21 */
#define STM32_TIM22_BASE 0x40014000 /* 0x40014000-0x400117ff TIM22 */
#define STM32_FIREWALL_BASE 0x4001c000 /* 0x4001c000-0x400113ff Firewall */
#define STM32_ADC1_BASE 0x40012400 /* 0x40012400-0x400127ff ADC1 */
#define STM32_ADC12_BASE 0x40012400 /* 0x40012400-0x400127ff ADC12 */
#define STM32_SPI1_BASE 0x40013000 /* 0x40013000-0x400133ff SPI1 */
#define STM32_USART1_BASE 0x40013800 /* 0x40013800-0x40013bff USART1 */
#define STM32_DBGMCU_BASE 0x40015800 /* 0x40015800-0x40015bff DBGMCU */
+1
View File
@@ -62,5 +62,6 @@
#include "stm32_spi.h"
#include "stm32_uart.h"
#include "stm32_lowputc.h"
#include "stm32_adc.h"
#endif /* __ARCH_ARM_SRC_STM32F0L0_STM32_H */
File diff suppressed because it is too large Load Diff
+343
View File
@@ -0,0 +1,343 @@
/************************************************************************************
* arch/arm/src/stm32/stm32_adc.h
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Mateusz Szafoni <raiden00@railab.me>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
#ifndef __ARCH_ARM_SRC_STM32F0L0_STM32_ADC_H
#define __ARCH_ARM_SRC_STM32F0L0_STM32_ADC_H
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
#include "chip.h"
#include "hardware/stm32_adc.h"
#include <nuttx/analog/adc.h>
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/* Configuration ********************************************************************/
/* Timer ADC trigger not supported yet */
#undef ADC1_HAVE_TIMER
/* Up to 1 ADC interfaces are supported */
#if STM32_NADC < 1
# undef CONFIG_STM32F0L0_ADC1
#endif
#if defined(CONFIG_STM32F0L0_ADC1)
/* DMA support */
#undef ADC_HAVE_DMA
#if defined(CONFIG_STM32F0L0_ADC1_DMA)
# define ADC_HAVE_DMA 1
#endif
#ifdef CONFIG_STM32F0L0_ADC1_DMA
# define ADC1_HAVE_DMA 1
#else
# undef ADC1_HAVE_DMA
#endif
/* EXTSEL */
#if defined(CONFIG_STM32F0L0_STM32F0)
# define ADC1_EXTSEL_T1TRGO ADC12_CFGR1_EXTSEL_TRG0
# define ADC1_EXTSEL_T1CC4 ADC12_CFGR1_EXTSEL_TRG1
# define ADC1_EXTSEL_T2TRGO ADC12_CFGR1_EXTSEL_TRG2
# define ADC1_EXTSEL_T3TRGO ADC12_CFGR1_EXTSEL_TRG3
# define ADC1_EXTSEL_T15TRGO ADC12_CFGR1_EXTSEL_TRG4
/* TRG5 reserved */
/* TRG6 reserved */
/* TRG7 reserved */
#elif defined(CONFIG_STM32F0L0_STM32L0)
/* TRG0 reserved */
# define ADC1_EXTSEL_T21CC2 ADC12_CFGR1_EXTSEL_TRG1
# define ADC1_EXTSEL_T2TRGO ADC12_CFGR1_EXTSEL_TRG2
# define ADC1_EXTSEL_T2CC4 ADC12_CFGR1_EXTSEL_TRG3
# define ADC1_EXTSEL_T21TRGO ADC12_CFGR1_EXTSEL_TRG4
# define ADC1_EXTSEL_T2CC3 ADC12_CFGR1_EXTSEL_TRG5
/* TRG6 reserved */
# define ADC1_EXTSEL_EXTI11 ADC12_CFGR1_EXTSEL_TRG7
#elif defined(CONFIG_STM32F0L0_STM32G0)
# define ADC1_EXTSEL_T1TRGO2 ADC12_CFGR1_EXTSEL_TRG0
# define ADC1_EXTSEL_T1CC4 ADC12_CFGR1_EXTSEL_TRG1
# define ADC1_EXTSEL_T2TRGO ADC12_CFGR1_EXTSEL_TRG2
# define ADC1_EXTSEL_T3TRGO ADC12_CFGR1_EXTSEL_TRG3
# define ADC1_EXTSEL_T15TRGO ADC12_CFGR1_EXTSEL_TRG4
# define ADC1_EXTSEL_T6TRGO ADC12_CFGR1_EXTSEL_TRG5
/* TRG6 reserved */
# define ADC1_EXTSEL_EXTI11 ADC12_CFGR1_EXTSEL_TRG7
#else
# error
#endif
/* EXTSEL configuration *****************************************************/
/* TODO */
/* ADC interrupts ***********************************************************/
#define ADC_ISR_EOC ADC_INT_EOC
#define ADC_IER_EOC ADC_INT_EOC
#define ADC_ISR_AWD ADC_INT_AWD
#define ADC_IER_AWD ADC_INT_AWD
#define ADC_ISR_OVR ADC_INT_OVR
#define ADC_IER_OVR ADC_INT_OVR
#define ADC_ISR_ALLINTS (ADC_ISR_EOC | ADC_ISR_AWD | ADC_ISR_OVR)
#define ADC_IER_ALLINTS (ADC_IER_EOC | ADC_IER_AWD | ADC_IER_OVR)
/* ADC registers ***********************************************************/
#define STM32_ADC_DMAREG_OFFSET STM32_ADC_CFGR1_OFFSET
#define ADC_DMAREG_DMA ADC_CFGR1_DMAEN
#define STM32_ADC_EXTREG_OFFSET STM32_ADC_CFGR1_OFFSET
#define ADC_EXTREG_EXTSEL_MASK ADC_CFGR1_EXTSEL_MASK
#define ADC_EXTREG_EXTEN_MASK ADC_CFGR1_EXTEN_MASK
#define ADC_EXTREG_EXTEN_DEFAULT ADC_CFGR1_EXTEN_RISING
/* Low-level ops helpers ****************************************************/
#define ADC_INT_ACK(adc, source) \
(adc)->llops->int_ack(adc, source)
#define ADC_INT_GET(adc) \
(adc)->llops->int_get(adc)
#define ADC_INT_ENABLE(adc, source) \
(adc)->llops->int_en(adc, source)
#define ADC_INT_DISABLE(adc, source) \
(adc)->llops->int_dis(adc, source)
#define ADC_REGDATA_GET(adc) \
(adc)->llops->val_get(adc)
#define ADC_REGBUF_REGISTER(adc, buffer, len) \
(adc)->llops->regbuf_reg(adc, buffer, len)
#define ADC_REG_STARTCONV(adc, state) \
(adc)->llops->reg_startconv(adc, state)
#define ADC_SAMPLETIME_SET(adc, time_samples) \
(adc)->llops->stime_set(adc, time_samples)
#define ADC_SAMPLETIME_WRITE(adc) \
(adc)->llops->stime_write(adc)
#define ADC_DUMP_REGS(adc) \
(adc)->llops->dump_regs(adc)
/************************************************************************************
* Public Types
************************************************************************************/
/* On STM32F42xx and STM32F43xx devices,VBAT and temperature sensor are connected
* to the same ADC internal channel (ADC1_IN18). Only one conversion, either
* temperature sensor or VBAT, must be selected at a time. When both conversion are
* enabled simultaneously, only the VBAT conversion is performed.
*/
enum adc_io_cmds_e
{
#ifdef HAVE_ADC_VBAT
IO_ENABLE_DISABLE_VBAT_CH,
#endif
IO_ENABLE_DISABLE_AWDIE,
IO_ENABLE_DISABLE_EOCIE,
IO_ENABLE_DISABLE_JEOCIE,
IO_ENABLE_DISABLE_OVRIE,
IO_ENABLE_DISABLE_ALL_INTS,
IO_STOP_ADC,
IO_START_ADC,
IO_START_CONV,
IO_TRIGGER_REG,
#ifdef ADC_HAVE_INJECTED
IO_TRIGGER_INJ,
#endif
#ifdef HAVE_ADC_POWERDOWN
IO_ENABLE_DISABLE_PDI,
IO_ENABLE_DISABLE_PDD,
IO_ENABLE_DISABLE_PDD_PDI
#endif
};
/* ADC resolution can be reduced in order to perform faster conversion */
enum stm32_adc_resoluton_e
{
ADC_RESOLUTION_12BIT = 0, /* 12 bit */
ADC_RESOLUTION_10BIT = 1, /* 10 bit */
ADC_RESOLUTION_8BIT = 2, /* 8 bit */
ADC_RESOLUTION_6BIT = 3 /* 6 bit */
};
#ifdef CONFIG_STM32F0L0_ADC_LL_OPS
#ifdef CONFIG_STM32F0L0_ADC_CHANGE_SAMPLETIME
/* Channel and sample time pair */
typedef struct adc_channel_s
{
uint8_t channel:5;
/* Sampling time individually for each channel. It differs between families */
uint8_t sample_time:3;
} adc_channel_t;
/* This structure will be used while setting channels to specified by the
* "channel-sample time" pairs' values
*/
struct adc_sample_time_s
{
adc_channel_t *channel; /* Array of channels */
uint8_t channels_nbr:5; /* Number of channels in array */
bool all_same:1; /* All channels will get the
* same value of the sample time */
uint8_t all_ch_sample_time:3; /* Sample time for all channels */
};
#endif /* CONFIG_STM32F0L0_ADC_CHANGE_SAMPLETIME */
/* This structure provides the publicly visable representation of the
* "lower-half" ADC driver structure.
*/
struct stm32_adc_dev_s
{
/* Publicly visible portion of the "lower-half" ADC driver structure */
FAR const struct stm32_adc_ops_s *llops;
/* Require cast-compatibility with private "lower-half" ADC strucutre */
};
/* Low-level operations for ADC */
struct stm32_adc_ops_s
{
/* Acknowledge interrupts */
void (*int_ack)(FAR struct stm32_adc_dev_s *dev, uint32_t source);
/* Get pending interrupts */
uint32_t (*int_get)(FAR struct stm32_adc_dev_s *dev);
/* Enable interrupts */
void (*int_en)(FAR struct stm32_adc_dev_s *dev, uint32_t source);
/* Disable interrupts */
void (*int_dis)(FAR struct stm32_adc_dev_s *dev, uint32_t source);
/* Get current ADC data register */
uint32_t (*val_get)(FAR struct stm32_adc_dev_s *dev);
/* Register buffer for ADC DMA transfer */
int (*regbuf_reg)(FAR struct stm32_adc_dev_s *dev, uint16_t *buffer, uint8_t len);
/* Start/stop regular conversion */
void (*reg_startconv)(FAR struct stm32_adc_dev_s *dev, bool state);
#ifdef CONFIG_STM32F0L0_ADC_CHANGE_SAMPLETIME
/* Set ADC sample time */
void (*stime_set)(FAR struct stm32_adc_dev_s *dev,
FAR struct adc_sample_time_s *time_samples);
/* Write ADC sample time */
void (*stime_write)(FAR struct stm32_adc_dev_s *dev);
#endif
void (*dump_regs)(FAR struct stm32_adc_dev_s *dev);
};
#endif /* CONFIG_STM32F0L0_ADC_LL_OPS */
/************************************************************************************
* Public Function Prototypes
************************************************************************************/
#ifndef __ASSEMBLY__
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Name: stm32_adcinitialize
*
* Description:
* Initialize the ADC. See stm32_adc.c for more details.
*
* Input Parameters:
* intf - Could be {1,2,3,4} for ADC1, ADC2, ADC3 or ADC4
* chanlist - The list of channels (regular + injected)
* nchannels - Number of channels (regular + injected)
*
* Returned Value:
* Valid can device structure reference on succcess; a NULL on failure
*
****************************************************************************/
struct adc_dev_s;
struct adc_dev_s *stm32_adcinitialize(int intf, FAR const uint8_t *chanlist,
int channels);
/************************************************************************************
* Name: stm32_adc_llops_get
************************************************************************************/
#ifdef CONFIG_STM32F0L0_ADC_LL_OPS
FAR const struct stm32_adc_ops_s *stm32_adc_llops_get(FAR struct adc_dev_s *dev);
#endif
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_STM32F0L0_ADC1 */
#endif /* __ARCH_ARM_SRC_STM32F0L0_STM32_ADC_H */
+67
View File
@@ -0,0 +1,67 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_LIBC_LONG_LONG is not set
# CONFIG_NSH_ARGCAT is not set
CONFIG_ADC=y
CONFIG_ANALOG=y
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="b-l072z-lrwan1"
CONFIG_ARCH_BOARD_B_L072Z_LRWAN1=y
CONFIG_ARCH_CHIP_STM32L072CZ=y
CONFIG_ARCH_CHIP_STM32L072XX=y
CONFIG_ARCH_CHIP_STM32L0=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARD_LOOPSPERMSEC=2796
CONFIG_BUILTIN=y
CONFIG_DISABLE_ENVIRON=y
CONFIG_DISABLE_MOUNTPOINT=y
CONFIG_DISABLE_MQUEUE=y
CONFIG_DISABLE_POLL=y
CONFIG_DISABLE_POSIX_TIMERS=y
CONFIG_DISABLE_PSEUDOFS_OPERATIONS=y
CONFIG_EXAMPLES_ADC=y
CONFIG_EXAMPLES_ADC_SWTRIG=y
CONFIG_EXPERIMENTAL=y
CONFIG_INTELHEX_BINARY=y
CONFIG_MAX_TASKS=8
CONFIG_MAX_WDOGPARMS=2
CONFIG_NFILE_DESCRIPTORS=6
CONFIG_NFILE_STREAMS=6
CONFIG_NPTHREAD_KEYS=0
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=64
CONFIG_NSH_LINELEN=64
CONFIG_NSH_READLINE=y
CONFIG_NUNGET_CHARS=0
CONFIG_PREALLOC_TIMERS=0
CONFIG_PREALLOC_WDOGS=4
CONFIG_PTHREAD_MUTEX_UNSAFE=y
CONFIG_PTHREAD_STACK_DEFAULT=1536
CONFIG_RAM_SIZE=20480
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_SDCLONE_DISABLE=y
CONFIG_START_DAY=19
CONFIG_START_MONTH=5
CONFIG_START_YEAR=2013
CONFIG_STDIO_DISABLE_BUFFERING=y
CONFIG_STM32F0L0_ADC1=y
CONFIG_STM32F0L0_ADC1_DMA=y
CONFIG_STM32F0L0_DMA1=y
CONFIG_STM32F0L0_PWR=y
CONFIG_STM32F0L0_USART2=y
CONFIG_SYSTEM_NSH=y
CONFIG_TASK_NAME_SIZE=0
CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=1536
CONFIG_USART2_SERIAL_CONSOLE=y
CONFIG_USERMAIN_STACKSIZE=1536
CONFIG_USER_ENTRYPOINT="nsh_main"
CONFIG_WDOG_INTRESERVE=0
+1 -1
View File
@@ -248,6 +248,6 @@
/* DMA channels *************************************************************/
/* ADC */
#define ADC1_DMA_CHAN DMACHAN_ADC1 /* DMA1_CH1 */
#define ADC1_DMA_CHAN DMACHAN_ADC1_1 /* DMA1_CH1 */
#endif /* __CONFIG_NUCLEO_LO73RZ_INCLUDE_BOARD_H */
+4
View File
@@ -60,4 +60,8 @@ ifeq ($(CONFIG_LPWAN_SX127X),y)
CSRCS += stm32_sx127x.c
endif
ifeq ($(CONFIG_ADC),y)
CSRCS += stm32_adc.c
endif
include $(TOPDIR)/configs/Board.mk
@@ -161,4 +161,16 @@ void stm32_spidev_initialize(void);
int stm32_lpwaninitialize(void);
#endif
/************************************************************************************
* Name: stm32_adc_setup
*
* Description:
* Initialize ADC and register the ADC driver.
*
************************************************************************************/
#ifdef CONFIG_ADC
int stm32_adc_setup(void);
#endif
#endif /* __CONFIGS_B_L072Z_LRWAN1_SRC_B_L072Z_LRWAN1_H */
+145
View File
@@ -0,0 +1,145 @@
/****************************************************************************
* configs/b-l072z-lrwan1/src/stm32_adc.c
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Mateusz Szafoni <raiden00@railab.me>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/board.h>
#include <nuttx/analog/adc.h>
#include "stm32.h"
#if defined(CONFIG_ADC) && defined(CONFIG_STM32F0L0_ADC1)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* The number of ADC channels in the conversion list */
#define ADC1_NCHANNELS 2
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/* Identifying number of each ADC channel (even if NCHANNELS is less ) */
static const uint8_t g_chanlist1[2] =
{
0,
4,
};
/* Configurations of pins used by each ADC channel */
static const uint32_t g_pinlist1[2] =
{
GPIO_ADC1_IN0, /* PA0/A0 */
GPIO_ADC1_IN4 /* PA4/A2 */
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_adc_setup
*
* Description:
* Initialize ADC and register the ADC driver.
*
****************************************************************************/
int stm32_adc_setup(void)
{
static bool initialized = false;
FAR struct adc_dev_s *adc;
int ret;
int i;
/* Check if we have already initialized */
if (!initialized)
{
/* Configure the pins as analog inputs for the selected channels */
for (i = 0; i < ADC1_NCHANNELS; i++)
{
stm32_configgpio(g_pinlist1[i]);
}
/* Call stm32_adcinitialize() to get an instance of the ADC interface */
adc = stm32_adcinitialize(1, g_chanlist1, ADC1_NCHANNELS);
if (adc == NULL)
{
aerr("ERROR: Failed to get ADC interface 1\n");
return -ENODEV;
}
/* Register the ADC driver at "/dev/adc0" */
ret = adc_register("/dev/adc0", adc);
if (ret < 0)
{
aerr("ERROR: adc_register /dev/adc0 failed: %d\n", ret);
return ret;
}
initialized = true;
}
return OK;
}
#endif /* CONFIG_ADC && CONFIG_STM32F0L0_ADC1 */