AnsweredAssumed Answered

24 ksps on SDADC on STM32F37x

Question asked by kvistgaard.morten on Jan 4, 2013
Latest reply on Jan 8, 2013 by lowpowermcu
We have a STM32F37x eval board for testing and I'd like to set up some code that will sample 24kHz 16-bit with the SDADC. According to documentation it should be able to sample 50 ksps if you don't use multiplexing. (Nice)

However, I can only make it output ~12 ksps. (That's not enough.)

Has anyone succeeded with more?

I have some sample code that I can show: (It's just code from the ST examples through.)

int sdadc_initialize(void)
{
  SDADC_AINStructTypeDef SDADC_AINStructure;
  GPIO_InitTypeDef   GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  uint32_t SDADCTimeout = 0;
   
  /* MPX2102_SDADC APB2 interface clock enable */
  RCC_APB2PeriphClockCmd(MPX2102_SDADC_CLK, ENABLE);
 
  /* PWR APB1 interface clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  /* Enable MPX2102_SDADC analog interface */
  PWR_SDADCAnalogCmd(MPX2102_SDADC_PWR, ENABLE);
 
  /* Set the SDADC divider: The SDADC should run @6MHz */
  /* If Sysclk is 72MHz, SDADC divider should be 12 */
  RCC_SDADCCLKConfig(RCC_SDADCCLK_SYSCLK_Div12);
 
  /* GPIOE Peripheral clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE);
 
  /* MPX2102_SDADC channel 8P (PE8)  and channel 8N (PE9) */
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Pin   = MPX2102_GPIO_PIN_P | MPX2102_GPIO_PIN_N;
  GPIO_Init(MPX2102_SDADC_GPIO_PORT, &GPIO_InitStructure);
 
  /* Select External reference: The reference voltage selection is available
     only in SDADC1 and therefore to select the VREF for SDADC2/SDADC3, SDADC1
     clock must be already enabled */
  SDADC_VREFSelect(MPX2102_SDADC_VREF);
  /* Insert delay equal to ~5 ms */
  msleep(5);
   
  /* Enable MPX2102_SDADC */
  SDADC_Cmd(MPX2102_SDADC, ENABLE);
 
  /* Enter initialization mode */
  SDADC_InitModeCmd(MPX2102_SDADC, ENABLE);
  SDADCTimeout = SDADC_INIT_TIMEOUT;
  /* wait for INITRDY flag to be set */
  while((SDADC_GetFlagStatus(MPX2102_SDADC, SDADC_FLAG_INITRDY) == RESET) && (--SDADCTimeout != 0));
 
  if(SDADCTimeout == 0)
  {
    /* INITRDY flag is not set */
    return 1;
  }
 
  /* Analog Input configuration conf0: use differential mode and gain = 4 */
  SDADC_AINStructure.SDADC_InputMode = SDADC_InputMode_Diff;
  SDADC_AINStructure.SDADC_Gain = MPX2102_SDADC_GAIN;
  SDADC_AINStructure.SDADC_CommonMode = SDADC_CommonMode_VSSA;
  SDADC_AINStructure.SDADC_Offset = 0;
  SDADC_AINInit(MPX2102_SDADC, SDADC_Conf_0, &SDADC_AINStructure);
 
  /* select MPX2102_SDADC channel 8 to use conf0 */
  SDADC_ChannelConfig(MPX2102_SDADC, MPX2102_SDADC_CHANNEL, SDADC_Conf_0);
 
  /* select channel 8 */
  SDADC_InjectedChannelSelect(MPX2102_SDADC, MPX2102_SDADC_CHANNEL);
  /* Select an external trigger */
  SDADC_ExternalTrigInjectedConvConfig(MPX2102_SDADC, SDADC_ExternalTrigInjecConv_T19_CC2);
  /* Select rising edge */
  SDADC_ExternalTrigInjectedConvEdgeConfig(MPX2102_SDADC, SDADC_ExternalTrigInjecConvEdge_Rising);
 
  /* Exit initialization mode */
  SDADC_InitModeCmd(MPX2102_SDADC, DISABLE);
 
  /* NVIC Configuration */
    NVIC_InitStructure.NVIC_IRQChannel = SDADC1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
 
  /* configure calibration to be performed on conf0 */
  SDADC_CalibrationSequenceConfig(MPX2102_SDADC, SDADC_CalibrationSequence_1);
  /* start MPX2102_SDADC Calibration */
  SDADC_StartCalibration(MPX2102_SDADC);
  /* Set calibration timeout: 5.12 ms at 6 MHz in a single calibration sequence */
  SDADCTimeout = SDADC_CAL_TIMEOUT;
  /* wait for MPX2102_SDADC Calibration process to end */
  while((SDADC_GetFlagStatus(MPX2102_SDADC, SDADC_FLAG_EOCAL) == RESET) && (--SDADCTimeout != 0));
 
  if(SDADCTimeout == 0)
  {
    /* EOCAL flag can not set */
    return 2;
  }
     
    /* Configure and enable TIM19 to trigger the SDADC conversions */
  TIM_OCInitTypeDef TIM_OCInitStructure;
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
 
  /* Enable TIM19 clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM19, ENABLE);
 
  /* TIM19 Configuration */
  TIM_DeInit(TIM19);
 
  /* Fills each TIM_TimeBaseInitStruct member with its default value */
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
 
  /* Time base configuration: MPX2102_SDADC will be triggered each sysclk/Period
    = 72MHz/3000 = 24 KHz */
    TIM_TimeBaseStructure.TIM_Period = 3000;
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM19, &TIM_TimeBaseStructure);
 
  /* PWM1 Mode configuration: Channel2 (OC2) */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period/2;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OC2Init(TIM19, &TIM_OCInitStructure);
 
  /* Enable TIM19 counter */
  TIM_Cmd(TIM19, ENABLE);   
 
  return 0;
}

Outcomes