Specific sample rate on ADC
Specific sample rate on ADC
Hi All,
is it possible with the current driver to get one sample every x µs ?
- With SWSTART that I can use to convert once but continuous mode is also enabled, which doesn't help in my case.
- Or in a SW independant way, is there a way to link a timer to the ADC driver to achieve this sample rate ?
What is your preferred way to trig the ADC with a specific sampling rate ?
Thanks for your support
Sebastien
is it possible with the current driver to get one sample every x µs ?
- With SWSTART that I can use to convert once but continuous mode is also enabled, which doesn't help in my case.
- Or in a SW independant way, is there a way to link a timer to the ADC driver to achieve this sample rate ?
What is your preferred way to trig the ADC with a specific sampling rate ?
Thanks for your support
Sebastien
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: Specific sample rate on ADC
Hi,
You can set the sample time for each channel so you have some freedom without having to do hardware triggering, there are fields dedicated to this in the ADCConversionGroup structure (read the RM in doing this).
If you need a slow conversion rate you can do one-shots from a timer callback (both a GPT or a virtual timer).
If you need precision and per-channel cycles settings are not sufficient then HW triggering is the best way.
Note that you can also play with ADC clock and slow it down.
Giovanni
You can set the sample time for each channel so you have some freedom without having to do hardware triggering, there are fields dedicated to this in the ADCConversionGroup structure (read the RM in doing this).
If you need a slow conversion rate you can do one-shots from a timer callback (both a GPT or a virtual timer).
If you need precision and per-channel cycles settings are not sufficient then HW triggering is the best way.
Note that you can also play with ADC clock and slow it down.
Giovanni
Re: Specific sample rate on ADC
I need a 8 kHz sampling frequency, so I'll probably go for the GPT method or Virtual Timer.
Thanks
Thanks
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: Specific sample rate on ADC
For 8kHz the GPT should be the best choice. If you need low jitter then you should do HW triggering.
Giovanni
Giovanni
Re: Specific sample rate on ADC
I'd prefer having a HW triggering.
I found a macro to configure CR2 but do you have a way using a driver to configure a timer or do I need to attack the timer registers directly ?
I found a macro to configure CR2 but do you have a way using a driver to configure a timer or do I need to attack the timer registers directly ?
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: Specific sample rate on ADC
In most drivers the configuration structures allow to setup all the relevant registers. Some bits of the control/configuration registers are enforced because required by the driver others are up to the user, hardware triggering bits and fields are up to you.
In your case you need to specify the correct bits for the CFGR register.
Helper macros are provided:
Giovanni
In your case you need to specify the correct bits for the CFGR register.
Code: Select all
/* End of the mandatory fields.*/
/**
* @brief ADC CFGR register initialization data.
* @note The bits DMAEN, DMACFG, OVRMOD, CONT are enforced internally
* to the driver, keep them to zero.
*/
uint32_t cfgr;
Helper macros are provided:
Code: Select all
/**
* @name CFGR register configuration helpers
* @{
*/
#define ADC_CFGR_DMACFG_MASK (1 << 1)
#define ADC_CFGR_DMACFG_ONESHOT (0 << 1)
#define ADC_CFGR_DMACFG_CIRCULAR (1 << 1)
#define ADC_CFGR_RES_MASK (3 << 3)
#define ADC_CFGR_RES_12BITS (0 << 3)
#define ADC_CFGR_RES_10BITS (1 << 3)
#define ADC_CFGR_RES_8BITS (2 << 3)
#define ADC_CFGR_RES_6BITS (3 << 3)
#define ADC_CFGR_ALIGN_MASK (1 << 5)
#define ADC_CFGR_ALIGN_RIGHT (0 << 5)
#define ADC_CFGR_ALIGN_LEFT (1 << 5)
#define ADC_CFGR_EXTSEL_MASK (15 << 6)
#define ADC_CFGR_EXTSEL_SRC(n) ((n) << 6)
#define ADC_CFGR_EXTEN_MASK (3 << 10)
#define ADC_CFGR_EXTEN_DISABLED (0 << 10)
#define ADC_CFGR_EXTEN_RISING (1 << 10)
#define ADC_CFGR_EXTEN_FALLING (2 << 10)
#define ADC_CFGR_EXTEN_BOTH (3 << 10)
#define ADC_CFGR_DISCEN_MASK (1 << 16)
#define ADC_CFGR_DISCEN_DISABLED (0 << 16)
#define ADC_CFGR_DISCEN_ENABLED (1 << 16)
#define ADC_CFGR_DISCNUM_MASK (7 << 17)
#define ADC_CFGR_DISCNUM_VAL(n) ((n) << 17)
#define ADC_CFGR_AWD1_DISABLED 0
#define ADC_CFGR_AWD1_ALL (1 << 23)
#define ADC_CFGR_AWD1_SINGLE(n) (((n) << 26) | (1 << 23) | (1 << 22))
/** @} */
Giovanni
Re: Specific sample rate on ADC
Sorry to bother you again. It doensn't seem to match the STM32F407 micro but I found the registers to modify.
I rechecked all the values for the ADC and TIM3 configuration registers and they seem right.
The Start of Conversion control for the ADC is in CR2. I don't want to have interrupts for the timer overflow, so I disable them after starting the timer.
I just want it to generate TRGO events.
The callback newAdcBufferCb never gets called.
Has someone an idea of what I may have missed ?
Thanks a lot for the support.
I rechecked all the values for the ADC and TIM3 configuration registers and they seem right.
The Start of Conversion control for the ADC is in CR2. I don't want to have interrupts for the timer overflow, so I disable them after starting the timer.
I just want it to generate TRGO events.
Code: Select all
#include "ch.h"
#include "hal.h"
#include "adc_in.h"
#define ADC1_NUM_CHANNELS 1
#define ADC1_BUF_DEPTH 1024
adcsample_t adc_buffer[ADC1_NUM_CHANNELS * ADC1_BUF_DEPTH];
static void newAdcBufferCb (ADCDriver *adcp, adcsample_t *buffer, size_t n) {
palSetPad(GPIOD, GPIOD_LED6);
}
static const ADCConversionGroup adcgrpconf1 = {
TRUE,
ADC1_NUM_CHANNELS,
newAdcBufferCb,
NULL,
0,
ADC_CR2_EXTSEL_SRC(8) | ADC_CR2_EXTEN_0, // Use TIM3_TRGO as source
0,
ADC_SMPR2_SMP_AN0(ADC_SAMPLE_15),
ADC_SQR1_NUM_CH(ADC1_NUM_CHANNELS),
0,
ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0)
};
static void sampleRateCb (GPTDriver *gptp) {}
static const GPTConfig sampleRateCfg = {
8000, /* 8kHz timer clock.*/
sampleRateCb/* Timer callback.*/
};
void startAdcAcquire(void) {
adcStart (&ADCD1, NULL);
gptStart (&GPTD3, &sampleRateCfg);
}
void beginAdcAcquire(void) {
adcStartConversion(&ADCD1, &adcgrpconf1, adc_buffer, ADC1_BUF_DEPTH);
gptStartContinuous (&GPTD3, 2); // Start ADC/DAC Timer
GPTD3.tim->SR = 0;
GPTD3.tim->DIER = 0;
}
void endAdcAcquire(void) {
adcStopConversion (&ADCD1);
gptStopTimer (&GPTD3); // Stop ADC/DAC Timer on closing
}
The callback newAdcBufferCb never gets called.
Has someone an idea of what I may have missed ?
Thanks a lot for the support.
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: Specific sample rate on ADC
I used F3 code, you have not mentioned the F4.
You are definitely in untested territory, I have never tried that combination.
Are you sure TRGO is the right way to do this and that it is actually generated?
Giovanni
You are definitely in untested territory, I have never tried that combination.
Are you sure TRGO is the right way to do this and that it is actually generated?
Giovanni
Re: Specific sample rate on ADC
You are right, TRGO was not generating any output.
In the CR2 register of the TIM3, you have to set the MMS field to UPDATE mode (2).
In the CR2 register of the TIM3, you have to set the MMS field to UPDATE mode (2).
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: Specific sample rate on ADC
Thanks, good to know. Probably that should be added to the GPT driver directly.
Giovanni
Giovanni