diff --git a/include/libopencm3/stm32/adc.h b/include/libopencm3/stm32/adc.h index fed4a3b7..3f2de8a7 100644 --- a/include/libopencm3/stm32/adc.h +++ b/include/libopencm3/stm32/adc.h @@ -38,6 +38,8 @@ # include #elif defined(STM32G0) # include +#elif defined(STM32G4) +# include #else # error "stm32 family not defined." #endif diff --git a/include/libopencm3/stm32/g4/adc.h b/include/libopencm3/stm32/g4/adc.h new file mode 100644 index 00000000..b9a0cd25 --- /dev/null +++ b/include/libopencm3/stm32/g4/adc.h @@ -0,0 +1,613 @@ +/** @defgroup adc_defines ADC Defines + * + * @brief Defined Constants and Types for the STM32G4xx Analog to Digital + * converter + * + * @ingroup STM32G4xx_defines + * + * @version 1.0.0 + * + * @date 10 Jul 2020 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_ADC_H +#define LIBOPENCM3_ADC_H + +#include +#include + +/**@{*/ + +/** @defgroup adc_reg_base ADC register base addresses +@ingroup STM32xx_adc_defines +@{*/ +#define ADC1 ADC1_BASE +#define ADC2 ADC2_BASE +#define ADC3 ADC3_BASE +#define ADC4 ADC4_BASE +#define ADC5 ADC5_BASE +/**@}*/ + + +/*----------- ADC registers -------------------------------------- */ +/** ADC_GCOMP Gain compensation Register */ +#define ADC_GCOMP(adc) MMIO32((adc) + 0xC0) + +/*------- ADC_CR values ---------*/ + +/* DEEPPWD: Deep power down */ +#define ADC_CR_DEEPPWD (1 << 29) + +/** ADVREGEN: ADC voltage regulator enable bit */ +#define ADC_CR_ADVREGEN (1 << 28) + +/*------- ADC_CFGR1 values ---------*/ + +/** ALIGN: Data alignment */ +#define ADC_CFGR1_ALIGN (1 << 15) + +/** EXTSEL[4:0]: External trigger selection for regular group */ +#define ADC_CFGR1_EXTSEL_SHIFT 5 +#define ADC_CFGR1_EXTSEL_MASK (0x1f << ADC_CFGR1_EXTSEL_SHIFT) +#define ADC_CFGR1_EXTSEL_VAL(x) ((x) << ADC_CFGR1_EXTSEL_SHIFT) + +/** CFGR1: ADC configuration register */ +#define ADC12_CFGR1_EXTSEL_TIM1_CC1 ADC_CFGR1_EXTSEL_VAL(0) +#define ADC12_CFGR1_EXTSEL_TIM1_CC2 ADC_CFGR1_EXTSEL_VAL(1) +#define ADC12_CFGR1_EXTSEL_TIM1_CC3 ADC_CFGR1_EXTSEL_VAL(2) +#define ADC12_CFGR1_EXTSEL_TIM2_CC2 ADC_CFGR1_EXTSEL_VAL(3) +#define ADC12_CFGR1_EXTSEL_TIM3_TRGO ADC_CFGR1_EXTSEL_VAL(4) +#define ADC12_CFGR1_EXTSEL_TIM4_CC4 ADC_CFGR1_EXTSEL_VAL(5) +#define ADC12_CFGR1_EXTSEL_EXTI11 ADC_CFGR1_EXTSEL_VAL(6) +#define ADC12_CFGR1_EXTSEL_TIM8_TRGO ADC_CFGR1_EXTSEL_VAL(7) +#define ADC12_CFGR1_EXTSEL_TIM8_TRGO2 ADC_CFGR1_EXTSEL_VAL(8) +#define ADC12_CFGR1_EXTSEL_TIM1_TRGO ADC_CFGR1_EXTSEL_VAL(9) +#define ADC12_CFGR1_EXTSEL_TIM1_TRGO2 ADC_CFGR1_EXTSEL_VAL(10) +#define ADC12_CFGR1_EXTSEL_TIM2_TRGO ADC_CFGR1_EXTSEL_VAL(11) +#define ADC12_CFGR1_EXTSEL_TIM4_TRGO ADC_CFGR1_EXTSEL_VAL(12) +#define ADC12_CFGR1_EXTSEL_TIM6_TRGO ADC_CFGR1_EXTSEL_VAL(13) +#define ADC12_CFGR1_EXTSEL_TIM15_TRGO ADC_CFGR1_EXTSEL_VAL(14) +#define ADC12_CFGR1_EXTSEL_TIM3_CC4 ADC_CFGR1_EXTSEL_VAL(15) +#define ADC12_CFGR1_EXTSEL_TIM20_TRGO ADC_CFGR1_EXTSEL_VAL(16) +#define ADC12_CFGR1_EXTSEL_TIM20_TRGO2 ADC_CFGR1_EXTSEL_VAL(17) +#define ADC12_CFGR1_EXTSEL_TIM20_CC1 ADC_CFGR1_EXTSEL_VAL(18) +#define ADC12_CFGR1_EXTSEL_TIM20_CC2 ADC_CFGR1_EXTSEL_VAL(19) +#define ADC12_CFGR1_EXTSEL_TIM20_CC3 ADC_CFGR1_EXTSEL_VAL(20) +#define ADC12_CFGR1_EXTSEL_HRTIM_ADC_TRG1 ADC_CFGR1_EXTSEL_VAL(21) +#define ADC12_CFGR1_EXTSEL_HRTIM_ADC_TRG3 ADC_CFGR1_EXTSEL_VAL(22) +#define ADC12_CFGR1_EXTSEL_HRTIM_ADC_TRG5 ADC_CFGR1_EXTSEL_VAL(23) +#define ADC12_CFGR1_EXTSEL_HRTIM_ADC_TRG6 ADC_CFGR1_EXTSEL_VAL(24) +#define ADC12_CFGR1_EXTSEL_HRTIM_ADC_TRG7 ADC_CFGR1_EXTSEL_VAL(25) +#define ADC12_CFGR1_EXTSEL_HRTIM_ADC_TRG8 ADC_CFGR1_EXTSEL_VAL(26) +#define ADC12_CFGR1_EXTSEL_HRTIM_ADC_TRG9 ADC_CFGR1_EXTSEL_VAL(27) +#define ADC12_CFGR1_EXTSEL_HRTIM_ADC_TRG10 ADC_CFGR1_EXTSEL_VAL(28) +#define ADC12_CFGR1_EXTSEL_LPTIMOUT ADC_CFGR1_EXTSEL_VAL(29) +#define ADC12_CFGR1_EXTSEL_TIM7_TRGO ADC_CFGR1_EXTSEL_VAL(30) + +#define ADC345_CFGR1_EXTSEL_TIM3_CC1 ADC_CFGR1_EXTSEL_VAL(0) +#define ADC345_CFGR1_EXTSEL_TIM2_CC3 ADC_CFGR1_EXTSEL_VAL(1) +#define ADC345_CFGR1_EXTSEL_TIM1_CC3 ADC_CFGR1_EXTSEL_VAL(2) +#define ADC345_CFGR1_EXTSEL_TIM8_CC1 ADC_CFGR1_EXTSEL_VAL(3) +#define ADC345_CFGR1_EXTSEL_TIM3_TRGO ADC_CFGR1_EXTSEL_VAL(4) +#define ADC345_CFGR1_EXTSEL_EXTI2 ADC_CFGR1_EXTSEL_VAL(5) +#define ADC345_CFGR1_EXTSEL_TIM4_CC1 ADC_CFGR1_EXTSEL_VAL(6) +#define ADC345_CFGR1_EXTSEL_TIM8_TRGO ADC_CFGR1_EXTSEL_VAL(7) +#define ADC345_CFGR1_EXTSEL_TIM8_TRGO2 ADC_CFGR1_EXTSEL_VAL(8) +#define ADC345_CFGR1_EXTSEL_TIM1_TRGO ADC_CFGR1_EXTSEL_VAL(9) +#define ADC345_CFGR1_EXTSEL_TIM1_TRGO2 ADC_CFGR1_EXTSEL_VAL(10) +#define ADC345_CFGR1_EXTSEL_TIM2_TRGO ADC_CFGR1_EXTSEL_VAL(11) +#define ADC345_CFGR1_EXTSEL_TIM4_TRGO ADC_CFGR1_EXTSEL_VAL(12) +#define ADC345_CFGR1_EXTSEL_TIM6_TRGO ADC_CFGR1_EXTSEL_VAL(13) +#define ADC345_CFGR1_EXTSEL_TIM15_TRGO ADC_CFGR1_EXTSEL_VAL(14) +#define ADC345_CFGR1_EXTSEL_TIM2_CC1 ADC_CFGR1_EXTSEL_VAL(15) +#define ADC345_CFGR1_EXTSEL_TIM20_TRGO ADC_CFGR1_EXTSEL_VAL(16) +#define ADC345_CFGR1_EXTSEL_TIM20_TRGO2 ADC_CFGR1_EXTSEL_VAL(17) +#define ADC345_CFGR1_EXTSEL_TIM20_CC1 ADC_CFGR1_EXTSEL_VAL(18) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG2 ADC_CFGR1_EXTSEL_VAL(19) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG4 ADC_CFGR1_EXTSEL_VAL(20) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG1 ADC_CFGR1_EXTSEL_VAL(21) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG3 ADC_CFGR1_EXTSEL_VAL(22) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG5 ADC_CFGR1_EXTSEL_VAL(23) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG6 ADC_CFGR1_EXTSEL_VAL(24) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG7 ADC_CFGR1_EXTSEL_VAL(25) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG8 ADC_CFGR1_EXTSEL_VAL(26) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG9 ADC_CFGR1_EXTSEL_VAL(27) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG10 ADC_CFGR1_EXTSEL_VAL(28) +#define ADC345_CFGR1_EXTSEL_LPTIMOUT ADC_CFGR1_EXTSEL_VAL(29) +#define ADC345_CFGR1_EXTSEL_TIM7_TRGO ADC_CFGR1_EXTSEL_VAL(30) + +/*------- ADC_CFGR2 values ---------*/ + +/** ROVSE: Regular Oversampling Enable */ +#define ADC_CFGR2_ROVSE (1 << 0) + +/** JOVSE: Injected Oversampling Enable */ +#define ADC_CFGR2_JOVSE (1 << 1) + +/** OVSR[2:0]: Oversampling ratio */ +#define ADC_CFGR2_OVSR_SHIFT 2 +#define ADC_CFGR2_OVSR_MASK (0x7 << ADC_CFGR2_OVSR_SHIFT) +#define ADC_CFGR2_OVSR_VAL(x) ((x) << ADC_CFGR2_OVSR_SHIFT) + +#define ADC_CFGR2_OVSR_2x ADC_CFGR2_OVSR_VAL(0) +#define ADC_CFGR2_OVSR_4x ADC_CFGR2_OVSR_VAL(1) +#define ADC_CFGR2_OVSR_8x ADC_CFGR2_OVSR_VAL(2) +#define ADC_CFGR2_OVSR_16x ADC_CFGR2_OVSR_VAL(3) +#define ADC_CFGR2_OVSR_32x ADC_CFGR2_OVSR_VAL(4) +#define ADC_CFGR2_OVSR_64x ADC_CFGR2_OVSR_VAL(5) +#define ADC_CFGR2_OVSR_128x ADC_CFGR2_OVSR_VAL(6) +#define ADC_CFGR2_OVSR_256x ADC_CFGR2_OVSR_VAL(7) + +/** OVSS[3:0]: Oversampling shift */ +#define ADC_CFGR2_OVSS_SHIFT 5 +#define ADC_CFGR2_OVSS_MASK (0xf << ADC_CFGR2_OVSS_SHIFT) +#define ADC_CFGR2_OVSS_VAL(x) ((x) << ADC_CFGR2_OVSS_SHIFT) + +/** TROVS: Triggered Regular Oversampling */ +#define ADC_CFGR2_TROVS (1 << 9) + +/** ROVSM: Regular Oversampling mode */ +#define ADC_CFGR2_ROVSM (1 << 10) + +/** GCOMP: Gain compensation mode */ +#define ADC_CFGR2_GCOMP (1 << 16) + +/** SWTRIG: Software trigger bit for sampling time control trigger mode */ +#define ADC_CFGR2_SWTRIG (1 << 25) + +/** BULB: Bulb sampling mode */ +#define ADC_CFGR2_BULB (1 << 26) + +/** SMPTRIG: Sampling time control trigger mode */ +#define ADC_CFGR2_SMPTRIG (1 << 27) + +/****************************************************************************/ +/* ADC_SMPRx ADC Sample Time Selection for Channels */ +/** @defgroup adc_sample ADC Sample Time Selection values +@ingroup adc_defines + +@{*/ +#define ADC_SMPR_SMP_2DOT5CYC 0x0 +#define ADC_SMPR_SMP_6DOT5CYC 0x1 +#define ADC_SMPR_SMP_12DOT5CYC 0x2 +#define ADC_SMPR_SMP_24DOT5CYC 0x3 +#define ADC_SMPR_SMP_47DOT5CYC 0x4 +#define ADC_SMPR_SMP_92DOT5CYC 0x5 +#define ADC_SMPR_SMP_247DOT5CYC 0x6 +#define ADC_SMPR_SMP_640DOT5CYC 0x7 + +#define ADC_SMPR1_SMP_PLUSONE (1 << 31) + +/**@}*/ + +/* SMPx[2:0]: Channel x sampling time selection */ + +/*------- ADC_T2 values ---------*/ + +/* Bits 23:16 HT2[7:0]: Analog watchdog 2 higher threshold */ + +/* Bit 7:0 LT2[7:0]: Analog watchdog 2 lower threshold */ + + +/*------- ADC_T3 values ---------*/ + +/* Bits 23:16 HT3[7:0]: Analog watchdog 3 higher threshold */ + +/* Bit 7:0 LT3[7:0]: Analog watchdog 3 lower threshold */ + + +/*------- ADC_DR values ---------*/ + +/* Bits 15:0 RDATA[15:0]: Regular Data converted */ + + +/*------- ADC_JSQR values ---------*/ + +#define ADC_JSQR_JL_LSB 0 +#define ADC_JSQR_JL_SHIFT 0 +#define ADC_JSQR_JSQ4_LSB 27 +#define ADC_JSQR_JSQ3_LSB 21 +#define ADC_JSQR_JSQ2_LSB 15 +#define ADC_JSQR_JSQ1_LSB 9 + +#define ADC_JSQR_JSQ_VAL(n, val) ((val) << (((n) - 1) * 6 + 8)) +#define ADC_JSQR_JL_VAL(val) (((val) - 1) << ADC_JSQR_JL_SHIFT) + +/* Bits 31:27 JSQ4[4:0]: 4th conversion in the injected sequence */ + +/* Bits 25:21 JSQ3[4:0]: 3rd conversion in the injected sequence */ + +/* Bits 19:15 JSQ2[4:0]: 2nd conversion in the injected sequence */ + +/* Bits 13:9 JSQ1[4:0]: 1st conversion in the injected sequence */ + +/* + * JEXTEN[1:0]: External Trigger Enable and Polarity Selection for injected + * channels + */ +#define ADC_JSQR_JEXTEN_DISABLED (0x0 << 7) +#define ADC_JSQR_JEXTEN_RISING_EDGE (0x1 << 7) +#define ADC_JSQR_JEXTEN_FALLING_EDGE (0x2 << 7) +#define ADC_JSQR_JEXTEN_BOTH_EDGES (0x3 << 7) + +#define ADC_JSQR_JEXTEN_MASK (0x3 << 7) + +/* JEXTSEL[3:0]: External Trigger Selection for injected group */ +#define ADC_JSQR_JEXTSEL_SHIFT 2 + +#define ADC12_JSQR_JEXTSEL_TIM1_TRGO (0 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM1_CC4 (1 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM2_TRGO (2 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM2_CC1 (3 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM3_CC4 (4 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM4_TRGO (5 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_EXTI15 (6 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM8_CC4 (7 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM1_TRGO2 (8 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM8_TRGO (9 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM8_TRGO2 (10 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM3_CC3 (11 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM3_TRGO (12 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM3_CC1 (13 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM6_TRGO (14 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM15_TRGO (15 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM20_TRGO (16 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM20_TRGO2 (17 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM20_CC4 (18 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_HRTIM_ADC_TRG2 (19 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_HRTIM_ADC_TRG4 (20 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_HRTIM_ADC_TRG5 (21 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_HRTIM_ADC_TRG6 (22 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_HRTIM_ADC_TRG7 (23 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_HRTIM_ADC_TRG8 (24 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_HRTIM_ADC_TRG9 (25 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_HRTIM_ADC_TRG10 (26 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM16_CC1 (27 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_LPTIMOUT (29 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM7_TRGO (30 << ADC_JSQR_JEXTSEL_SHIFT) + +#define ADC345_JSQR_JEXTSEL_TIM1_TRGO (0 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM1_CC4 (1 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM2_TRGO (2 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM8_CC2 (3 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM4_CC3 (4 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM4_TRGO (5 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM4_CC4 (6 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM8_CC4 (7 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM1_TRGO2 (8 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM8_TRGO (9 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM8_TRGO2 (10 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM1_CC3 (11 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM3_TRGO (12 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_EXTI3 (13 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM6_TRGO (14 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM15_TRGO (15 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM20_TRGO (16 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM20_TRGO2 (17 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM20_CC2 (18 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG2 (19 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG4 (20 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG5 (21 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG6 (22 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG7 (23 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG8 (24 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG9 (25 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG10 (26 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG1 (27 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG3 (28 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_LPTIMOUT (29 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM7_TRGO (30 << ADC_JSQR_JEXTSEL_SHIFT) + +#define ADC_JSQR_JEXTSEL_MASK (0x1F << ADC_JSQR_JEXTSEL_SHIFT) + +/* JL[1:0]: Injected channel sequence length */ +#define ADC_JSQR_JL_1_CONVERSION (0x0 << 0) +#define ADC_JSQR_JL_2_CONVERSIONS (0x1 << 0) +#define ADC_JSQR_JL_3_CONVERSIONS (0x2 << 0) +#define ADC_JSQR_JL_4_CONVERSIONS (0x3 << 0) + +/*------- ADC_OFR1 values ---------*/ + +/* OFFSET1_EN: Offset 1 Enable */ +#define ADC_OFR1_OFFSET1_EN (1 << 31) + +/* Bits 30:26 OFFSET1_CH[4:0]: Channel selection for the Data offset 1 */ + +/* + * Bits 11:0 OFFSET1[11:0]: Data offset y for the channel programmed into bits + * OFFSET1_CH[4:0] + */ + + +/*------- ADC_OFR2 values ---------*/ + +/* OFFSET2_EN: Offset 2 Enable */ +#define ADC_OFR2_OFFSET2_EN (1 << 31) + +/* Bits 30:26 OFFSET2_CH[4:0]: Channel selection for the Data offset 2 */ + +/* + * Bits 11:0 OFFSET2[11:0]: Data offset y for the channel programmed into bits + * OFFSET2_CH[4:0] + */ + + +/*------- ADC_OFR3 values ---------*/ + +/* OFFSET3_EN: Offset 3 Enable */ +#define ADC_OFR3_OFFSET3_EN (1 << 31) + +/* Bits 30:26 OFFSET3_CH[4:0]: Channel selection for the Data offset 3 */ + +/* + * Bits 11:0 OFFSET3[11:0]: Data offset y for the channel programmed into bits + * OFFSET3_CH[4:0] + */ + + +/*------- ADC_OFR4 values ---------*/ + +/* OFFSET4_EN: Offset 4 Enable */ +#define ADC_OFR4_OFFSET4_EN (1 << 31) + +/* Bits 30:26 OFFSET4_CH[4:0]: Channel selection for the Data offset 4 */ + +/* + * Bits 11:0 OFFSET4[11:0]: Data offset y for the channel programmed into bits + * OFFSET4_CH[4:0] + */ + + +/*------- ADC_JDRy, y= 1..4 values -------*/ + +/* Bits 15:0 JDATA[15:0]: Injected data */ + + +/*------- ADC_AWD2CR values ---------*/ + +/* Bits 18:1 AWD2CH[18:1]: Analog watchdog 2 channel selection */ + + +/*------- ADC_AWD3CR values ---------*/ + +/* Bits 18:1 AWD3CH[18:1]: Analog watchdog 3 channel selection */ + +/*--------------- ADC_CSR values ------------------------*/ + +/* Bit 26 JQOVF_SLV: Injected Context Queue Overflow flag of the slave ADC */ +#define ADC_CSR_JQOVF_SLV (1 << 26) + +/* Bit 25 AWD3_SLV: Analog watchdog 3 flag of the slave ADC */ +#define ADC_CSR_AWD3_SLV (1 << 25) + +/* Bit 24 AWD2_SLV: Analog watchdog 2 flag of the slave ADC */ +#define ADC_CSR_AWD2_SLV (1 << 24) + +/* Bit 23 AWD1_SLV: Analog watchdog 1 flag of the slave ADC */ +#define ADC_CSR_AWD1_SLV (1 << 23) + +/* Bit 22 JEOS_SLV: End of injected sequence flag of the slave ADC */ +#define ADC_CSR_JEOS_SLV (1 << 22) + +/* Bit 21 JEOC_SLV: End of injected conversion flag of the slave ADC */ +#define ADC_CSR_JEOC_SLV (1 << 21) + +/* Bit 20 OVR_SLV: Overrun flag of the slave ADC */ +#define ADC_CSR_OVR_SLV (1 << 20) + +/* Bit 19 EOS_SLV: End of regular sequence flag of the slave ADC */ +#define ADC_CSR_EOS_SLV (1 << 19) + +/* Bit 18 EOC_SLV: End of regular conversion of the slave ADC */ +#define ADC_CSR_EOC_SLV (1 << 18) + +/* Bit 17 EOSMP_SLV: End of Sampling phase flag of the slave ADC */ +#define ADC_CSR_EOSMP_SLV (1 << 17) + +/* Bit 16 ADRDY_SLV: Slave ADC ready */ +#define ADC_CSR_ADRDY_SLV (1 << 16) + +/* Bit 10 JQOVF_MST: Injected Context Queue Overflow flag of the master ADC */ +#define ADC_CSR_JQOVF_MST (1 << 10) + +/* Bit 9 AWD3_MST: Analog watchdog 3 flag of the master ADC */ +#define ADC_CSR_AWD3_MST (1 << 9) + +/* Bit 8 AWD2_MST: Analog watchdog 2 flag of the master ADC */ +#define ADC_CSR_AWD2_MST (1 << 8) + +/* Bit 7 AWD1_MST: Analog watchdog 1 flag of the master ADC */ +#define ADC_CSR_AWD1_MST (1 << 7) + +/* Bit 6 JEOS_MST: End of injected sequence flag of the master ADC */ +#define ADC_CSR_JEOS_MST (1 << 6) + +/* Bit 5 JEOC_MST: End of injected conversion flag of the master ADC */ +#define ADC_CSR_JEOC_MST (1 << 5) + +/* Bit 4 OVR_MST: Overrun flag of the master ADC */ +#define ADC_CSR_OVR_MST (1 << 4) + +/* Bit 3 EOS_MST: End of regular sequence flag of the master ADC */ +#define ADC_CSR_EOS_MST (1 << 3) + +/* Bit 2 EOC_MST: End of regular conversion of the master ADC */ +#define ADC_CSR_EOC_MST (1 << 2) + +/* Bit 1 EOSMP_MST: End of Sampling phase flag of the master ADC */ +#define ADC_CSR_EOSMP_MST (1 << 1) + +/* Bit 0 ADRDY_MST: Master ADC ready */ +#define ADC_CSR_ADRDY_MST (1 << 0) + + +/*-------- ADC_CCR values ------------*/ + +/* Bits 21:18 PRESC[21:18]: ADC Prescaler */ +#define ADC_CCR_PRESC_MASK (0xf) +#define ADC_CCR_PRESC_SHIFT (18) +/** @defgroup adc_ccr_presc ADC clock prescaler + *@{*/ +#define ADC_CCR_PRESC_NODIV (0x0 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV1 (0x1 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV2 (0x2 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV6 (0x3 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV8 (0x4 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV10 (0x5 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV12 (0x6 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV16 (0x7 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV32 (0x8 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV64 (0x9 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV128 (0x10 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV256 (0x11 << ADC_CCR_PRESC_SHIFT) +/**@}*/ + +/* CKMODE[1:0]: ADC clock mode */ +#define ADC_CCR_CKMODE_CKX (0x0 << 16) +#define ADC_CCR_CKMODE_DIV1 (0x1 << 16) +#define ADC_CCR_CKMODE_DIV2 (0x2 << 16) +#define ADC_CCR_CKMODE_DIV4 (0x3 << 16) + +#define ADC_CCR_CKMODE_MASK (0x3 << 16) + +/* MDMA[1:0]: Direct memory access mode for dual ADC mode */ +#define ADC_CCR_MDMA_DISABLE (0x0 << 14) +/*#define ADC_CCR_MDMA_RESERVED (0x1 << 14)*/ +#define ADC_CCR_MDMA_12_10_BIT (0x2 << 14) +#define ADC_CCR_MDMA_8_6_BIT (0x3 << 14) + +/* DMACFG: DMA configuration (for dual ADC mode) */ +#define ADC_CCR_DMACFG (1 << 13) + +/* DELAY: Delay between 2 sampling phases */ +#define ADC_CCR_DELAY_SHIFT 8 + +/* DUAL[4:0]: Dual ADC mode selection */ +/****************************************************************************/ +/** @defgroup adc_multi_mode ADC Multi mode selection +@ingroup adc_defines + +@{*/ + +/** All ADCs independent */ +#define ADC_CCR_DUAL_INDEPENDENT 0x0 + +/* Dual modes: (ADC1 master + ADC2 slave or ADC3 master + ADC4 slave) */ +/** + * Dual modes combined regular simultaneous + + * injected simultaneous mode. + */ +#define ADC_CCR_DUAL_REG_SIMUL_AND_INJECTED_SIMUL 0x1 +/** + * Dual mode Combined regular simultaneous + + * alternate trigger mode. + */ +#define ADC_CCR_DUAL_REG_SIMUL_AND_ALTERNATE_TRIG 0x2 +/** + * Dual mode Combined interleaved mode + + * injected simultaneous mode. + */ +#define ADC_CCR_DUAL_REG_INTERLEAVED_AND_INJECTED_SIMUL 0x3 + +/** Dual mode Injected simultaneous mode only. */ +#define ADC_CCR_DUAL_INJECTED_SIMUL 0x5 +/** Dual mode Regular simultaneous mode only. */ +#define ADC_CCR_DUAL_REGULAR_SIMUL 0x6 +/** Dual mode Interleaved mode only. */ +#define ADC_CCR_DUAL_INTERLEAVED 0x7 +/** Dual mode Alternate trigger mode only. */ +#define ADC_CCR_DUAL_ALTERNATE_TRIG 0x9 +/**@}*/ + +#define ADC_CCR_DUAL_MASK (0x1f) +#define ADC_CCR_DUAL_SHIFT 0 + + +/*---------------- ADC_CDR values -----------------*/ + +/* Bits 31:16 RDATA_SLV[15:0]: Regular data of the slave ADC */ + +/* Bits 15:0 RDATA_MST[15:0]: Regular data of the master ADC. */ + +/** @defgroup adc_channel ADC Channel Numbers + * @ingroup adc_defines + * + *@{*/ +#define ADC_CHANNEL_TEMP 16 +#define ADC_CHANNEL_VBAT 17 +#define ADC_CHANNEL_VREF 18 +/**@}*/ + +#define ADC_CHANNEL_COUNT 19 +#define ADC_CHANNEL_IS_FAST(x) ((x) <= 5) + + +BEGIN_DECLS + +void adc_enable_analog_watchdog_regular(uint32_t adc); +void adc_disable_analog_watchdog_regular(uint32_t adc); +void adc_enable_analog_watchdog_injected(uint32_t adc); +void adc_disable_analog_watchdog_injected(uint32_t adc); +void adc_enable_discontinuous_mode_regular(uint32_t adc, uint8_t length); +void adc_disable_discontinuous_mode_regular(uint32_t adc); +void adc_enable_discontinuous_mode_injected(uint32_t adc); +void adc_disable_discontinuous_mode_injected(uint32_t adc); +void adc_enable_automatic_injected_group_conversion(uint32_t adc); +void adc_disable_automatic_injected_group_conversion(uint32_t adc); +void adc_enable_analog_watchdog_on_all_channels(uint32_t adc); +void adc_enable_analog_watchdog_on_selected_channel(uint32_t adc, + uint8_t channel); +void adc_enable_eoc_interrupt_injected(uint32_t adc); +void adc_disable_eoc_interrupt_injected(uint32_t adc); +void adc_enable_eos_interrupt_injected(uint32_t adc); +void adc_disable_eos_interrupt_injected(uint32_t adc); +void adc_enable_all_awd_interrupt(uint32_t adc); +void adc_disable_all_awd_interrupt(uint32_t adc); +void adc_enable_eos_interrupt(uint32_t adc); +void adc_disable_eos_interrupt(uint32_t adc); +void adc_start_conversion_injected(uint32_t adc); +void adc_disable_external_trigger_regular(uint32_t adc); +void adc_disable_external_trigger_injected(uint32_t adc); +void adc_set_watchdog_high_threshold(uint32_t adc, uint16_t threshold); +void adc_set_watchdog_low_threshold(uint32_t adc, uint16_t threshold); +void adc_set_injected_sequence(uint32_t adc, uint8_t length, uint8_t channel[]); +bool adc_eoc_injected(uint32_t adc); +bool adc_eos_injected(uint32_t adc); +uint32_t adc_read_injected(uint32_t adc, uint8_t reg); +void adc_set_injected_offset(uint32_t adc, uint8_t reg, uint32_t offset); +void adc_set_clk_source(uint32_t adc, uint32_t source); +void adc_set_clk_prescale(uint32_t adc, uint32_t prescaler); +void adc_set_multi_mode(uint32_t adc, uint32_t mode); +void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger, + uint32_t polarity); +void adc_enable_external_trigger_injected(uint32_t adc, uint32_t trigger, + uint32_t polarity); +bool adc_awd(uint32_t adc); +void adc_enable_deeppwd(uint32_t adc); +void adc_disable_deeppwd(uint32_t adc); + +END_DECLS + +/**@}*/ + + +#endif + diff --git a/include/libopencm3/stm32/g4/memorymap.h b/include/libopencm3/stm32/g4/memorymap.h index 06a958c4..56a16617 100644 --- a/include/libopencm3/stm32/g4/memorymap.h +++ b/include/libopencm3/stm32/g4/memorymap.h @@ -105,10 +105,10 @@ /* AHB2 */ #define ADC1_BASE (PERIPH_BASE_AHB2 + 0x0000) -#define ADC2_BASE ADC1_BASE +#define ADC2_BASE (ADC1_BASE + 0x0100) #define ADC3_BASE (PERIPH_BASE_AHB2 + 0x0400) -#define ADC4_BASE ADC3_BASE -#define ADC5_BASE ADC3_BASE +#define ADC4_BASE (ADC3_BASE + 0x0100) +#define ADC5_BASE (ADC3_BASE + 0x0200) #define DAC1_BASE (PERIPH_BASE_AHB2 + 0x0800) #define DAC2_BASE (PERIPH_BASE_AHB2 + 0x0c00) #define DAC3_BASE (PERIPH_BASE_AHB2 + 0x1000) diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index d4771707..5c1bfdca 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -35,6 +35,7 @@ TGT_CFLAGS += $(DEBUG_FLAGS) TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs +OBJS += adc.o adc_common_v2.o adc_common_v2_multi.o OBJS += dma_common_l1f013.o OBJS += dmamux.o OBJS += flash.o flash_common_all.o flash_common_f.o flash_common_idcache.o diff --git a/lib/stm32/g4/adc.c b/lib/stm32/g4/adc.c new file mode 100644 index 00000000..4ce7ad72 --- /dev/null +++ b/lib/stm32/g4/adc.c @@ -0,0 +1,720 @@ +/** @defgroup adc_file ADC + * + * @ingroup STM32G4xx + * + * @brief libopencm3 STM32G4xx ADC + * + * @version 1.0.0 + * + * @date 10 Jul 2020 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/**@{*/ + +#include + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for Regular Conversions + * + * The analog watchdog allows the monitoring of an analog signal between two + * threshold levels. The thresholds must be preset. Comparison is done before + * data alignment takes place, so the thresholds are left-aligned. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_analog_watchdog_regular(uint32_t adc) +{ + ADC_CFGR1(adc) |= ADC_CFGR1_AWD1EN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for Regular Conversions + * + * The analog watchdog allows the monitoring of an analog signal between two + * threshold levels. The thresholds must be preset. Comparison is done before + * data alignment takes place, so the thresholds are left-aligned. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ +void adc_disable_analog_watchdog_regular(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_AWD1EN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for Injected Conversions + * + * The analog watchdog allows the monitoring of an analog signal between two + * threshold levels. The thresholds must be preset. Comparison is done before + * data alignment takes place, so the thresholds are left-aligned. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_analog_watchdog_injected(uint32_t adc) +{ + ADC_CFGR1(adc) |= ADC_CFGR1_JAWD1EN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Analog Watchdog for Injected Conversions + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_analog_watchdog_injected(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_JAWD1EN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Discontinuous Mode for Regular Conversions + * + * In this mode the ADC converts, on each trigger, a subgroup of up to 8 of the + * defined regular channel group. The subgroup is defined by the number of + * consecutive channels to be converted. After a subgroup has been converted + * the next trigger will start conversion of the immediately following subgroup + * of the same length or until the whole group has all been converted. When the + * whole group has been converted, the next trigger will restart conversion of + * the subgroup at the beginning of the whole group. + * + * @param[in] adc ADC block register address base @ref adc_reg_base + * @param[in] length Number of channels in the group @ref adc_cr1_discnum + */ +void adc_enable_discontinuous_mode_regular(uint32_t adc, uint8_t length) +{ + if ((length-1) > 7) { + return; + } + ADC_CFGR1(adc) |= ADC_CFGR1_DISCEN; + ADC_CFGR1(adc) |= ((length-1) << ADC_CFGR1_DISCNUM_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Discontinuous Mode for Regular Conversions + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_discontinuous_mode_regular(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_DISCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Discontinuous Mode for Injected Conversions + * + * In this mode the ADC converts sequentially one channel of the defined group + * of injected channels, cycling back to the first channel in the group once + * the entire group has been converted. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_discontinuous_mode_injected(uint32_t adc) +{ + ADC_CFGR1(adc) |= ADC_CFGR1_JDISCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Discontinuous Mode for Injected Conversions + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_discontinuous_mode_injected(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_JDISCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Automatic Injected Conversions + * + * The ADC converts a defined injected group of channels immediately after the + * regular channels have been converted. The external trigger on the injected + * channels is disabled as required. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_automatic_injected_group_conversion(uint32_t adc) +{ + adc_disable_external_trigger_injected(adc); + ADC_CFGR1(adc) |= ADC_CFGR1_JAUTO; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Automatic Injected Conversions + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_automatic_injected_group_conversion(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_JAUTO; +} +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for All Regular and/or Injected Channels + * + * The analog watchdog allows the monitoring of an analog signal between two + * threshold levels. The thresholds must be preset. Comparison is done before + * data alignment takes place, so the thresholds are left-aligned. + * + * @note The analog watchdog must be enabled for either or both of the regular + * or injected channels. If neither are enabled, the analog watchdog feature + * will be disabled. + * + * @ref adc_enable_analog_watchdog_injected, @ref + * adc_enable_analog_watchdog_regular. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_analog_watchdog_on_all_channels(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_AWD1SGL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for a Selected Channel + * + * The analog watchdog allows the monitoring of an analog signal between two + * threshold levels. The thresholds must be preset. Comparison is done before + * data alignment takes place, so the thresholds are left-aligned. + * + * @note The analog watchdog must be enabled for either or both of the regular + * or injected channels. If neither are enabled, the analog watchdog feature + * will be disabled. If both are enabled, the same channel number is monitored + * @ref adc_enable_analog_watchdog_injected, @ref + * adc_enable_analog_watchdog_regular. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + * @param[in] channel Unsigned int8. ADC channel numbe + * @ref adc_watchdog_channel + */ + +void adc_enable_analog_watchdog_on_selected_channel(uint32_t adc, + uint8_t channel) +{ + ADC_CFGR1(adc) = (ADC_CFGR1(adc) & ~ADC_CFGR1_AWD1CH) | + ADC_CFGR1_AWD1CH_VAL(channel); + + ADC_CFGR1(adc) |= ADC_CFGR1_AWD1EN | ADC_CFGR1_AWD1SGL; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Injected End-Of-Conversion Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_eoc_interrupt_injected(uint32_t adc) +{ + ADC_IER(adc) |= ADC_IER_JEOCIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Injected End-Of-Conversion Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_eoc_interrupt_injected(uint32_t adc) +{ + ADC_IER(adc) &= ~ADC_IER_JEOCIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Injected End-Of-Sequence Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_eos_interrupt_injected(uint32_t adc) +{ + ADC_IER(adc) |= ADC_IER_JEOSIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Injected End-Of-Sequence Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_eos_interrupt_injected(uint32_t adc) +{ + ADC_IER(adc) &= ~ADC_IER_JEOSIE; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_all_awd_interrupt(uint32_t adc) +{ + ADC_IER(adc) |= ADC_IER_AWD1IE; + ADC_IER(adc) |= ADC_IER_AWD2IE; + ADC_IER(adc) |= ADC_IER_AWD3IE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Analog Watchdog Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_all_awd_interrupt(uint32_t adc) +{ + ADC_IER(adc) &= ~ADC_IER_AWD1IE; + ADC_IER(adc) &= ~ADC_IER_AWD2IE; + ADC_IER(adc) &= ~ADC_IER_AWD3IE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Regular End-Of-Sequence Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_eos_interrupt(uint32_t adc) +{ + ADC_IER(adc) |= ADC_IER_EOSIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Regular End-Of-Sequence Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_eos_interrupt(uint32_t adc) +{ + ADC_IER(adc) &= ~ADC_IER_EOSIE; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Software Triggered Conversion on Injected Channels + * + * This starts conversion on a set of defined injected channels. + * Depending on the configuration bits JEXTEN, a conversion will start + * immediately (software trigger configuration) or once an injected hardware + * trigger event occurs (hardware trigger configuration). + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_start_conversion_injected(uint32_t adc) +{ + /* Start conversion on injected channels. */ + ADC_CR(adc) |= ADC_CR_JADSTART; +} + + +/** ADC Set Analog Watchdog Upper Threshold. + * @param[in] adc ADC block register address base + * @ref adc_reg_base + * @param[in] threshold Upper threshold value + */ +void adc_set_watchdog_high_threshold(uint32_t adc, uint16_t threshold) +{ + uint32_t reg32 = 0; + uint32_t mask = 0xf000ffff; + + reg32 |= (threshold << 16); + reg32 &= ~mask; /* clear masked bits. */ + + ADC_TR1(adc) = (ADC_TR1(adc) & mask) | reg32; + ADC_TR2(adc) = (ADC_TR2(adc) & mask) | reg32; + ADC_TR3(adc) = (ADC_TR3(adc) & mask) | reg32; +} + +/** ADC Set Analog Watchdog Lower Threshold. + * @param[in] adc ADC block register address base + * @ref adc_reg_base + * @param[in] threshold Lower threshold value + */ +void adc_set_watchdog_low_threshold(uint32_t adc, uint16_t threshold) +{ + uint32_t reg32 = 0; + uint32_t mask = 0xfffff000; + reg32 = (uint32_t)threshold; + reg32 &= ~mask; /* clear masked bits. */ + + ADC_TR1(adc) = (ADC_TR1(adc) & mask) | reg32; + ADC_TR2(adc) = (ADC_TR2(adc) & mask) | reg32; + ADC_TR3(adc) = (ADC_TR3(adc) & mask) | reg32; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set an Injected Channel Conversion Sequence + * + * Defines a sequence of channels to be converted as an injected group with a + * length from 1 to 4 channels. If this is called during conversion, the current + * conversion is reset and conversion begins again with the newly defined group. + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @param[in] length Unsigned int8. Number of channels in the group. + * @param[in] channel Unsigned int8[]. Set of channels in sequence, integers + * 0..18 + */ + +void adc_set_injected_sequence(uint32_t adc, uint8_t length, uint8_t channel[]) +{ + uint32_t reg32 = 0; + uint8_t i = 0; + + /* Maximum sequence length is 4 channels. Minimum sequence is 1.*/ + if ((length - 1) > 3) { + return; + } + + for (i = 0; i < length; i++) { + reg32 |= ADC_JSQR_JSQ_VAL(4 - i, channel[length - i - 1]); + } + + reg32 |= ADC_JSQR_JL_VAL(length); + + ADC_JSQR(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read the End-of-Conversion Flag for Injected Conversion + * + * This flag is set by hardware at the end of each injected conversion of a + * channel when a new data is available in the corresponding ADCx_JDRy register. + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @returns bool. End of conversion flag. + */ + +bool adc_eoc_injected(uint32_t adc) +{ + return ADC_ISR(adc) & ADC_ISR_JEOC; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read the End-of-Sequence Flag for Injected Conversions + * + * This flag is set after all channels of an injected group have been + * converted. + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @returns bool. End of conversion flag. + */ +bool adc_eos_injected(uint32_t adc) +{ + return ADC_ISR(adc) & ADC_ISR_JEOS; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read from an Injected Conversion Result Register + * + * The result read back from the selected injected result register (one of four) + * is 12 bits, right or left aligned within the first 16 bits. The result can + * have a negative value if the injected channel offset has been set @see + * adc_set_injected_offset. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + * @param[in] reg Unsigned int8. Register number (1 ... 4). + * @returns Unsigned int32 conversion result. + */ + +uint32_t adc_read_injected(uint32_t adc, uint8_t reg) +{ + switch (reg) { + case 1: + return ADC_JDR1(adc); + case 2: + return ADC_JDR2(adc); + case 3: + return ADC_JDR3(adc); + case 4: + return ADC_JDR4(adc); + } + return 0; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set the Injected Channel Data Offset + * + * This value is subtracted from the injected channel results after conversion + * is complete, and can result in negative results. A separate value can be + * specified for each injected data register. + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @param[in] reg Unsigned int8. Register number (1 ... 4). + * @param[in] offset Unsigned int32. +*/ + +void adc_set_injected_offset(uint32_t adc, uint8_t reg, uint32_t offset) +{ + switch (reg) { + case 1: + ADC_OFR1(adc) |= ADC_OFR1_OFFSET1_EN; + ADC_OFR1(adc) |= offset; + break; + case 2: + ADC_OFR2(adc) |= ADC_OFR2_OFFSET2_EN; + ADC_OFR2(adc) |= offset; + break; + case 3: + ADC_OFR3(adc) |= ADC_OFR3_OFFSET3_EN; + ADC_OFR3(adc) |= offset; + break; + case 4: + ADC_OFR4(adc) |= ADC_OFR4_OFFSET4_EN; + ADC_OFR4(adc) |= offset; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Clock Source + * + * The ADC clock taken from the APB2 clock can be scaled down by 2, 4, 6 or 8. + * + * @param adc peripheral of choice @ref adc_reg_base + * @param[in] source Unsigned int32. Source value for ADC Clock @ref + * adc_ccr_adcpre + */ +void adc_set_clk_source(uint32_t adc, uint32_t source) +{ + uint32_t reg32 = ((ADC_CCR(adc) & ~ADC_CCR_CKMODE_MASK) | source); + ADC_CCR(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Clock Prescale + * + * The ADC clock taken from the APB2 clock can be scaled down by 2, 4, 6 or 8. + * + * @param adc peripheral of choice @ref adc_reg_base + * @param[in] prescale Unsigned int32. Prescale value for ADC Clock @ref + * adc_ccr_adcpre + */ +void adc_set_clk_prescale(uint32_t adc, uint32_t ckmode) +{ + uint32_t reg32 = ((ADC_CCR(adc) & ~ADC_CCR_CKMODE_MASK) | ckmode); + ADC_CCR(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC set multi mode + * + * The multiple mode can uses these arrangement: + * - ADC1 as master and ADC2 as slave + * - ADC3 as master and ADC4 as slave + * + * This setting is applied to ADC master only (ADC1 or ADC3). + * + * The various modes possible are described in the reference manual. + * + * @param adc peripheral of choice @ref adc_reg_base + * @param[in] mode Multiple mode selection from @ref adc_multi_mode + */ +void adc_set_multi_mode(uint32_t adc, uint32_t mode) +{ + ADC_CCR(adc) &= ~(ADC_CCR_DUAL_MASK << ADC_CCR_DUAL_SHIFT); + ADC_CCR(adc) |= (mode << ADC_CCR_DUAL_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Regular Channels + * + * This enables an external trigger for set of defined regular channels, and + * sets the polarity of the trigger event: rising or falling edge or both. Note + * that if the trigger polarity is zero, triggering is disabled. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + * @param[in] trigger Unsigned int32. Trigger identifier + * @ref adc_trigger_regular + * @param[in] polarity Unsigned int32. Trigger polarity @ref + * adc_trigger_polarity_regular + */ + +void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger, + uint32_t polarity) +{ + uint32_t reg32 = ADC_CFGR1(adc); + + reg32 &= ~(ADC_CFGR1_EXTSEL_MASK | ADC_CFGR1_EXTEN_MASK); + reg32 |= (trigger | polarity); + ADC_CFGR1(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Regular Channels + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + */ + +void adc_disable_external_trigger_regular(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_EXTEN_MASK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Injected Channels + * + * This enables an external trigger for set of defined injected channels, and + * sets the polarity of the trigger event: rising or falling edge or both. + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @param[in] trigger Unsigned int8. Trigger identifier + * @ref adc_trigger_injected + * @param[in] polarity Unsigned int32. Trigger polarity + * @ref adc_trigger_polarity_injected +*/ + +void adc_enable_external_trigger_injected(uint32_t adc, uint32_t trigger, + uint32_t polarity) +{ + uint32_t reg32 = ADC_JSQR(adc); + + reg32 &= ~(ADC_JSQR_JEXTSEL_MASK | ADC_JSQR_JEXTEN_MASK); + reg32 |= (trigger | polarity); + ADC_JSQR(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Injected Channels + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_external_trigger_injected(uint32_t adc) +{ + ADC_JSQR(adc) &= ~ADC_JSQR_JEXTEN_MASK; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read the Analog Watchdog Flag + * + * This flag is set when the converted voltage crosses the high or low + * thresholds. + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @returns bool. AWD flag. + */ + +bool adc_awd(uint32_t adc) +{ + return (ADC_ISR(adc) & ADC_ISR_AWD1) && + (ADC_ISR(adc) & ADC_ISR_AWD2) && + (ADC_ISR(adc) & ADC_ISR_AWD3); +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Deep-Power-Down Mdoe + * + * Deep-power-down mode allows additional power saving by internally switching + * off to reduce leakage currents. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ +void adc_enable_deeppwd(uint32_t adc) +{ + ADC_CR(adc) |= ADC_CR_DEEPPWD; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Deep-Power-Down Mdoe + * + * Deep-power-down mode allows additional power saving by internally switching + * off to reduce leakage currents. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ +void adc_disable_deeppwd(uint32_t adc) +{ + ADC_CR(adc) &= ~ADC_CR_DEEPPWD; +} + + +/** + * Enable the ADC Voltage regulator + * Before any use of the ADC, the ADC Voltage regulator must be enabled. + * You must wait up to 10uSecs afterwards before trying anything else. + * @param[in] adc ADC block register address base + * @sa adc_disable_regulator + */ +void adc_enable_regulator(uint32_t adc) +{ + ADC_CR(adc) |= ADC_CR_ADVREGEN; +} + +/** + * Disable the ADC Voltage regulator + * You can disable the adc vreg when not in use to save power + * @param[in] adc ADC block register address base + * @sa adc_enable_regulator + */ +void adc_disable_regulator(uint32_t adc) +{ + ADC_CR(adc) &= ~ADC_CR_ADVREGEN; +} + +/**@}*/ + +