Running stm32f37x SDADC from GPT clock

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
dflogeras
Posts: 232
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 8 times
Been thanked: 22 times

Running stm32f37x SDADC from GPT clock

Post by dflogeras »

Hi, I decided to learn something new and try using the sigma delta ADC on my F372 device. In the past, I've used the regular ADC.

I am doing streaming processing on an audio signal, and I prefer to have a nice low-jitter sampling with very little software intervention. Previously I (with some help here) learned how to set up the ADC to trigger from TRG0 of the STM32's TIMx devices. That way I just get an interrupt when the ADC buffer is half-full and all the rest of the ADC operation is transparent to me after I start the device.

So my regular ADC config would be something like

Code: Select all

static const ADCConversionGroup adcgrpconf1 = {
  .circular = TRUE,
  .num_channels = ADC1_NUM_CHANNELS,
  .end_cb = newAdcBufferCb,
  .error_cb = NULL,
  .u = { .adc = {
    .cr1 = 0,
    .cr2 = ADC_CR2_EXTSEL_2 | ADC_CR2_EXTTRIG, // Use TIM3_TRGO as source
    .ltr = 0,
    .htr = 0,
    .smpr = { 0,
              ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5), },
    .sqr = { ADC_SQR1_NUM_CH(ADC1_NUM_CHANNELS),
             0,
             ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0), },
  },},
};


I would like to achieve something similar with the SDADC, but it seems that the TIMx TRG output isn't an option for a trigger source, only individual timer channels like TIM3 CH1. Is there a way to set up the GPT driver using the standard APIs to specifically set a TIMx CHy directly? I'm a bit confused about all the terminology and hoping someone has done something similar and can help.

So far my SDADC config is

Code: Select all

static const ADCConfig sdadc_config1 = {
  .cr1 = 0,
  .confxr = {
     SDADC_CONFR_GAIN_1X | SDADC_CONFR_SE_ZERO_VOLT | SDADC_CONFR_COMMON_VSSSD,
     0,
     0,
  },
};

static const ADCConversionGroup sdadcgrpcfg1 = {
  .circular = TRUE,
  .num_channels = ADC1_NUM_CHANNELS,
  .end_cb = newAdcBufferCb,
  .error_cb = 0x0,
  .u = { .sdadc = {
    .cr2 = SDADC_CR2_JEXTSEL_0 | SDADC_CR2_JEXTSEL_1 | SDADC_CR2_JEXTEN_1,
    .jchgr = SDADC_JCHGR_CH(0),
    .confchr = {
      SDADC_CONFCHR1_CH0(0),
      0,
    },
  },},
};


and my GPT config:

Code: Select all

static const GPTConfig gpt3cfg = {
  .frequency = 80000,
  .callback = 0x0,
  .cr2 = 0,
  .dier = 0
};


But when I start after I start the timer, the ADC callback is never called. Any help is greatly appreciated.
dflogeras
Posts: 232
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 8 times
Been thanked: 22 times

Re: Running stm32f37x SDADC from GPT clock

Post by dflogeras »

I noticed in the ST evaluation board demo that they seem to set up the PWM to generate pulses on a specific TIMx CHy (in wavereader.c which uses the SDADC). I tried that in ChibiOS (and confirmed the output with my scope by temporarily assigning it to an output pad), but the SDADC still isn't generating anything. The PWM configuration I used is:

Code: Select all

static PWMConfig pwmcfg = {
  .frequency = 64000,
  .period = 4,
  .callback = 0x0,
  .channels = {
   { .mode = PWM_OUTPUT_ACTIVE_HIGH, .callback = 0x0 },
   {PWM_OUTPUT_DISABLED, NULL},
   {PWM_OUTPUT_DISABLED, NULL},
   {PWM_OUTPUT_DISABLED, NULL}
  },
  .cr2 = 0,
  .dier = 0x2 // Enable CC1 interrupt
};
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: Running stm32f37x SDADC from GPT clock

Post by Giovanni »

Hi,

You may use the PWM driver for that, it uses channel comparators.

Giovanni
dflogeras
Posts: 232
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 8 times
Been thanked: 22 times

Re: Running stm32f37x SDADC from GPT clock

Post by dflogeras »

Hi Giovanni, any idea why the PWM config in my second post isn't doing the trick?

Thanks, and happy holidays!
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: Running stm32f37x SDADC from GPT clock

Post by Giovanni »

Hi,

I think you must not touch DIER, see the MMS field in the CR2 register.

Giovanni
dflogeras
Posts: 232
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 8 times
Been thanked: 22 times

Re: Running stm32f37x SDADC from GPT clock

Post by dflogeras »

Hmm it turned out it was working all along, but for some reason GCC inlines the callback function and when I was setting a breakpoint it would never hit it. I discovered this by paring my program down enough so that I could build with -O0 (both -O1 and -O2 inlined it). Initially my program was too big to build in -O0.

What's weirder is that GCC wasn't inlining it when I used the plain old ADC driver (vs SDADC). Does anyone know how to prevent this? I tried decorating my callback function with __attribute__((noinline)), and also putting a asm("") call in it (not sure what the latter supposed to do, but a thread I was reading suggested it).

I guess I could put the function in another translation unit, but then it becomes less straightforward to use the global semaphore I use to trigger new data.

I also tried turning off LTO with no effect.

Any suggestions?
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: Running stm32f37x SDADC from GPT clock

Post by Giovanni »

GCC has lots of options to disable specific optimizations, you need to find the right one.

Giovanni
Post Reply