analog_digital_converter.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020, Richard Henrichsen
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * * Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
33 
35 {
36  this->current_channels = 0;
37  this->adc_def_ = adc_def;
38 
39  ADC_TypeDef *adc = adc_def_->adc;
40 
41  for (size_t index = 0; index < CHANNEL_COUNT; index++) this->buffer[index] = AnalogDigitalConverter::NO_READING;
42 
43  ADC_CommonInitTypeDef adc_common_init_struct;
44  adc_common_init_struct.ADC_Mode = ADC_Mode_Independent;
45  adc_common_init_struct.ADC_Prescaler = ADC_Prescaler_Div2;
46  adc_common_init_struct.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
47  adc_common_init_struct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
48  ADC_CommonInit(&adc_common_init_struct);
49 
50  ADC_InitTypeDef adc_init_struct;
51  ADC_StructInit(&adc_init_struct);
52  adc_init_struct.ADC_Resolution = ADC_Resolution_12b;
53  adc_init_struct.ADC_ScanConvMode = ENABLE;
54  adc_init_struct.ADC_ContinuousConvMode = ENABLE;
55  adc_init_struct.ADC_DataAlign = ADC_DataAlign_Right;
56  adc_init_struct.ADC_NbrOfConversion = 1; // This can't be less than 1
57  ADC_Init(adc, &adc_init_struct);
58 
59  this->init_dma();
61 
62  this->is_initialized_ = true;
63 }
64 
66 {
69  DMA_InitTypeDef dma_init_struct;
70  DMA_StructInit(&dma_init_struct);
71 
72  dma_init_struct.DMA_Channel = this->adc_def_->DMA_channel;
73  dma_init_struct.DMA_PeripheralBaseAddr = reinterpret_cast<uint32_t>(&(this->adc_def_->adc->DR));
74  dma_init_struct.DMA_Memory0BaseAddr = reinterpret_cast<uint32_t>((this->buffer));
75  dma_init_struct.DMA_DIR = DMA_DIR_PeripheralToMemory;
76  dma_init_struct.DMA_BufferSize = this->get_current_channel_count();
78  dma_init_struct.DMA_MemoryInc = DMA_MemoryInc_Enable;
79  // The ADC data register is 32 bits wide, even though the data is only 12 bits wide
82  dma_init_struct.DMA_Mode = DMA_Mode_Circular;
83  dma_init_struct.DMA_Priority = DMA_Priority_Medium;
84  dma_init_struct.DMA_FIFOMode = DMA_FIFOMode_Disable;
85  dma_init_struct.DMA_FIFOMode = DMA_FIFOStatus_1QuarterFull;
86  dma_init_struct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
88 
89  DMA_Init(this->adc_def_->DMA_Stream, &dma_init_struct);
90 
91  ADC_DMACmd(this->adc_def_->adc, ENABLE);
93 }
94 
95 uint8_t AnalogDigitalConverter::add_channel(uint8_t channel)
96 {
97  uint8_t index = this->get_current_channel_count() + 1;
98  this->current_channels++;
100 
101  // Increment the number of channels
103  this->adc_def_->adc->SQR1 |= (((index - 1) << SQR1_CHANNEL_COUNT_OFFSET) & SQR1_CHANNEL_COUNT_MASK);
104 
105  this->init_dma(); // reconfigure the DMA with the new memory size
106  this->start_dma();
107  ADC_Cmd(this->adc_def_->adc, ENABLE);
109  return index;
110 }
112 {
114 }
116 {
117  return this->is_initialized_;
118 }
119 uint16_t AnalogDigitalConverter::read(uint8_t index) const
120 {
121  return (this->buffer[index - 1] & 0xFFFF);
122 }
123 
125 {
126  return this->current_channels;
127 }
#define DMA_MemoryInc_Enable
uint32_t DMA_MemoryInc
Definition: stm32f4xx_dma.h:76
#define ADC_SampleTime_480Cycles
uint32_t DMA_Channel
Definition: stm32f4xx_dma.h:56
void ADC_ContinuousModeCmd(ADC_TypeDef *ADCx, FunctionalState NewState)
Enables or disables the ADC continuous conversion mode.
static constexpr uint16_t NO_READING
static constexpr uint8_t SQR1_CHANNEL_COUNT_OFFSET
#define DMA_Priority_Medium
#define DMA_FIFOStatus_1QuarterFull
DMA Init structure definition.
Definition: stm32f4xx_dma.h:54
ADC Init structure definition.
Definition: stm32f4xx_adc.h:53
#define ADC_TwoSamplingDelay_5Cycles
Analog to Digital Converter.
Definition: stm32f4xx.h:725
#define ADC_Mode_Independent
void ADC_Cmd(ADC_TypeDef *ADCx, FunctionalState NewState)
Enables or disables the specified ADC peripheral.
uint32_t DMA_MemoryBurst
FunctionalState ADC_ContinuousConvMode
Definition: stm32f4xx_adc.h:61
void DMA_DeInit(DMA_Stream_TypeDef *DMAy_Streamx)
Deinitialize the DMAy Streamx registers to their default reset values.
#define DMA_PeripheralInc_Disable
uint16_t read(uint8_t index) const
Reads a single channel.
void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef *ADCx, FunctionalState NewState)
Enables or disables the ADC DMA request after last transfer (Single-ADC mode)
void ADC_StructInit(ADC_InitTypeDef *ADC_InitStruct)
Fills each ADC_InitStruct member with its default value.
ADC_TypeDef * adc
Definition: system.h:127
uint32_t DMA_MemoryDataSize
Definition: stm32f4xx_dma.h:82
void ADC_DMACmd(ADC_TypeDef *ADCx, FunctionalState NewState)
Enables or disables the specified ADC DMA request.
static constexpr uint8_t CHANNEL_COUNT
void DMA_Init(DMA_Stream_TypeDef *DMAy_Streamx, DMA_InitTypeDef *DMA_InitStruct)
Initializes the DMAy Streamx according to the specified parameters in the DMA_InitStruct structure...
uint8_t get_current_channel_count() const
Checks the number of used channels. If this exceeds CHANNEL_COUNT, stuff will break.
uint32_t DMA_DIR
Definition: stm32f4xx_dma.h:65
uint32_t DMA_PeripheralInc
Definition: stm32f4xx_dma.h:73
#define ADC_Prescaler_Div2
#define DMA_MemoryDataSize_Word
uint32_t DMA_PeripheralDataSize
Definition: stm32f4xx_dma.h:79
ADC Common Init structure definition.
Definition: stm32f4xx_adc.h:84
uint32_t ADC_DataAlign
Definition: stm32f4xx_adc.h:72
void DMA_StructInit(DMA_InitTypeDef *DMA_InitStruct)
Fills each DMA_InitStruct member with its default value.
uint32_t DMA_PeripheralBurst
void DMA_Cmd(DMA_Stream_TypeDef *DMAy_Streamx, FunctionalState NewState)
Enables or disables the specified DMAy Streamx.
uint32_t DMA_PeripheralBaseAddr
Definition: stm32f4xx_dma.h:59
uint32_t DMA_Memory0BaseAddr
Definition: stm32f4xx_dma.h:61
uint8_t ADC_NbrOfConversion
Definition: stm32f4xx_adc.h:75
const ADCHardwareStruct * adc_def_
#define DMA_MemoryBurst_Single
uint32_t ADC_TwoSamplingDelay
Definition: stm32f4xx_adc.h:96
__IO uint32_t DR
Definition: stm32f4xx.h:746
DMA_Stream_TypeDef * DMA_Stream
Definition: system.h:128
void init(const ADCHardwareStruct *adc_def)
Initializes the ADC according to the definition struct provided.
__IO uint32_t SQR1
Definition: stm32f4xx.h:738
bool is_initialized() const
Checks if the adc has been initialized, i.e. init has been called.
#define ADC_DMAAccessMode_1
#define DMA_FIFOMode_Disable
uint32_t DMA_channel
Definition: system.h:129
uint8_t add_channel(uint8_t channel)
Adds a channel to the list that is scanned.
#define ADC_Resolution_12b
uint32_t DMA_FIFOMode
Definition: stm32f4xx_dma.h:93
void ADC_SoftwareStartConv(ADC_TypeDef *ADCx)
Enables the selected ADC software start conversion of the regular channels.
FunctionalState ADC_ScanConvMode
Definition: stm32f4xx_adc.h:57
uint32_t ADC_Resolution
Definition: stm32f4xx_adc.h:55
uint32_t DMA_Mode
Definition: stm32f4xx_dma.h:85
void ADC_CommonInit(ADC_CommonInitTypeDef *ADC_CommonInitStruct)
Initializes the ADCs peripherals according to the specified parameters in the ADC_CommonInitStruct.
volatile uint32_t buffer[CHANNEL_COUNT]
#define DMA_DIR_PeripheralToMemory
uint32_t DMA_BufferSize
Definition: stm32f4xx_dma.h:69
uint32_t DMA_Priority
Definition: stm32f4xx_dma.h:90
void ADC_RegularChannelConfig(ADC_TypeDef *ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)
Configures for the selected ADC regular channel its corresponding rank in the sequencer and its sampl...
#define DMA_Mode_Circular
#define ADC_DataAlign_Right
static constexpr uint32_t SQR1_CHANNEL_COUNT_MASK
#define DMA_PeripheralDataSize_Word
void ADC_Init(ADC_TypeDef *ADCx, ADC_InitTypeDef *ADC_InitStruct)
Initializes the ADCx peripheral according to the specified parameters in the ADC_InitStruct.
#define DMA_PeripheralBurst_Single


rosflight_firmware
Author(s): Daniel Koch , James Jackson
autogenerated on Thu Apr 15 2021 05:07:46