Jump to content


ADC Config


  • Please log in to reply
5 replies to this topic

#1 Brian

Brian

    Core Developer

  • Members
  • PipPipPip
  • 567 posts
  • LocationTucson, AZ
  • Country: flag of United States United States


Posted 25 October 2011 - 04:43 AM

I'm trying to add an ADC channel, and there's obviously something I'm not understanding.  I'm starting with the CC config and just trying to add a channel.  The following is the configuration.  The normal defines are the standard CC defines, and they work.  If I define ADD_ONE_ADC, I don't get valid values on any channel.  There must be some other configuration that I'm missing, but I can't find it.

I know that PA0 work because I've tried other configurations that worked on PA0.  I have another 6 channel configuration where all channels on ADC1 work, but none on ADC2, which led me to believe that it was the ADC, but this configuration uses ACD2, and it works.

Any idea what I might be missing?  I am re-sizing my queue buffer correct, so it's not that.

#define PIOS_ADC_USE_TEMP_SENSOR				1
#define PIOS_ADC_TEMP_SENSOR_ADC				ADC1
#define PIOS_ADC_TEMP_SENSOR_ADC_CHANNEL		1

#define PIOS_ADC_PIN1_GPIO_PORT				 GPIOA				   // PA4 (Gyro X)
#define PIOS_ADC_PIN1_GPIO_PIN				  GPIO_Pin_4			  // ADC12_IN4
#define PIOS_ADC_PIN1_GPIO_CHANNEL			  ADC_Channel_4
#define PIOS_ADC_PIN1_ADC					   ADC2
#define PIOS_ADC_PIN1_ADC_NUMBER				1

#define PIOS_ADC_PIN2_GPIO_PORT				 GPIOA				   // PA5 (Gyro Y)
#define PIOS_ADC_PIN2_GPIO_PIN				  GPIO_Pin_5			  // ADC123_IN5
#define PIOS_ADC_PIN2_GPIO_CHANNEL			  ADC_Channel_5
#define PIOS_ADC_PIN2_ADC					   ADC1
#define PIOS_ADC_PIN2_ADC_NUMBER				2

#define PIOS_ADC_PIN3_GPIO_PORT				 GPIOA				   // PA3 (Gyro Z)
#define PIOS_ADC_PIN3_GPIO_PIN				  GPIO_Pin_3			  // ADC12_IN3
#define PIOS_ADC_PIN3_GPIO_CHANNEL			  ADC_Channel_3
#define PIOS_ADC_PIN3_ADC					   ADC2
#define PIOS_ADC_PIN3_ADC_NUMBER				2

#ifdef ADD_ONE_ADC
#define PIOS_ADC_PIN4_GPIO_PORT				 GPIOA				   // PA0
#define PIOS_ADC_PIN4_GPIO_PIN				  GPIO_Pin_0			  // ADC12_IN0
#define PIOS_ADC_PIN4_GPIO_CHANNEL			  ADC_Channel_0
#define PIOS_ADC_PIN4_ADC					   ADC1
#define PIOS_ADC_PIN4_ADC_NUMBER				3

#define PIOS_ADC_NUM_PINS					   4

#define PIOS_ADC_PORTS						  { PIOS_ADC_PIN1_GPIO_PORT, PIOS_ADC_PIN2_GPIO_PORT, PIOS_ADC_PIN3_GPIO_PORT, PIOS_ADC_PIN4_GPIO_PORT }
#define PIOS_ADC_PINS						   { PIOS_ADC_PIN1_GPIO_PIN, PIOS_ADC_PIN2_GPIO_PIN, PIOS_ADC_PIN3_GPIO_PIN, PIOS_ADC_PIN4_GPIO_PIN }
#define PIOS_ADC_CHANNELS					   { PIOS_ADC_PIN1_GPIO_CHANNEL, PIOS_ADC_PIN2_GPIO_CHANNEL, PIOS_ADC_PIN3_GPIO_CHANNEL, PIOS_ADC_PIN4_GPIO_CHANNEL }
#define PIOS_ADC_MAPPING						{ PIOS_ADC_PIN1_ADC, PIOS_ADC_PIN2_ADC, PIOS_ADC_PIN3_ADC, PIOS_ADC_PIN4_ADC }
#define PIOS_ADC_CHANNEL_MAPPING				{ PIOS_ADC_PIN1_ADC_NUMBER, PIOS_ADC_PIN2_ADC_NUMBER, PIOS_ADC_PIN3_ADC_NUMBER, PIOS_ADC_PIN4_ADC_NUMBER }

#else

#define PIOS_ADC_NUM_PINS					   3

#define PIOS_ADC_PORTS						  { PIOS_ADC_PIN1_GPIO_PORT, PIOS_ADC_PIN2_GPIO_PORT, PIOS_ADC_PIN3_GPIO_PORT }
#define PIOS_ADC_PINS						   { PIOS_ADC_PIN1_GPIO_PIN, PIOS_ADC_PIN2_GPIO_PIN, PIOS_ADC_PIN3_GPIO_PIN }
#define PIOS_ADC_CHANNELS					   { PIOS_ADC_PIN1_GPIO_CHANNEL, PIOS_ADC_PIN2_GPIO_CHANNEL, PIOS_ADC_PIN3_GPIO_CHANNEL }
#define PIOS_ADC_MAPPING						{ PIOS_ADC_PIN1_ADC, PIOS_ADC_PIN2_ADC, PIOS_ADC_PIN3_ADC }
#define PIOS_ADC_CHANNEL_MAPPING				{ PIOS_ADC_PIN1_ADC_NUMBER, PIOS_ADC_PIN2_ADC_NUMBER, PIOS_ADC_PIN3_ADC_NUMBER }
#endif

#define PIOS_ADC_NUM_CHANNELS				   (PIOS_ADC_NUM_PINS + PIOS_ADC_USE_TEMP_SENSOR)
#define PIOS_ADC_NUM_ADC_CHANNELS			   2
#define PIOS_ADC_USE_ADC2					   1
#define PIOS_ADC_CLOCK_FUNCTION				 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2, ENABLE)
#define PIOS_ADC_ADCCLK						 RCC_PCLK2_Div8
/* RCC_PCLK2_Div2: ADC clock = PCLK2/2 */
/* RCC_PCLK2_Div4: ADC clock = PCLK2/4 */
/* RCC_PCLK2_Div6: ADC clock = PCLK2/6 */
/* RCC_PCLK2_Div8: ADC clock = PCLK2/8 */
#define PIOS_ADC_SAMPLE_TIME					ADC_SampleTime_239Cycles5
/* Sample time: */
/* With an ADCCLK = 14 MHz and a sampling time of 239.5 cycles: */
/* Tconv = 239.5 + 12.5 = 252 cycles = 18�s */
/* (1 / (ADCCLK / CYCLES)) = Sample Time (�S) */
#define PIOS_ADC_IRQ_PRIO					   PIOS_IRQ_PRIO_LOW

// Currently analog acquistion hard coded at 480 Hz
// PCKL2 = HCLK / 16
// ADCCLK = PCLK2 / 2
#define PIOS_ADC_RATE		   (72.0e6 / 1.0 / 8.0 / 252.0 / (PIOS_ADC_NUM_CHANNELS >> PIOS_ADC_USE_ADC2))
#define PIOS_ADC_MAX_OVERSAMPLING			   36


#2 Brian

Brian

    Core Developer

  • Members
  • PipPipPip
  • 567 posts
  • LocationTucson, AZ
  • Country: flag of United States United States


Posted 25 October 2011 - 02:20 PM

I solved the problem of a sort.  It looks like the number of ADC channels needs to be even.  I was able to get 4 (and 6) ADC channels by turning off the temperature channel.  Does that make sense?

#3 Kenn Sebesta

Kenn Sebesta

    Controls Master!

  • Members
  • PipPipPip
  • 896 posts
  • Country: flag of Luxembourg Luxembourg


Posted 25 October 2011 - 02:59 PM

It's been a while since I used the ADC on the STM32, but it doesn't make sense to me that it absolutely needs to be sampling an even number of channels. Perhaps this has something to do with DMA? Don't quote me on this, but I think the DMA needs to write things in 32-bit chunks, so it would be somewhat logical that two 16-bit ADC values get written at once.

#4 peabody124

peabody124

    Crash Dummy

  • Administrators
  • 4110 posts
  • LocationHouston, TX
  • Country: flag of United States United States


Posted 25 October 2011 - 03:05 PM

Sorry I was going to post this last night and got distracted.  Yes the way the driver is written it needs to be even.  The hardware will support odd though, I think.  Basically the driver is written for dual ADC simultaneously sampling mode.  Each ADC produces a 16 bit word and the DMA engine reads them together into memory in 32-bit chunks.  

If you have an odd number of channels there will be a time where I think it reads a random value and the right value.  However, all the calculations for where that sample is in memory become incorrect for the second half of the double buffer.  It's also possible during dual channel mode a configuration with an odd number of channels breaks the hardware config - it's been a while.

#5 Brian

Brian

    Core Developer

  • Members
  • PipPipPip
  • 567 posts
  • LocationTucson, AZ
  • Country: flag of United States United States


Posted 25 October 2011 - 04:15 PM

No problem.  I still have plenty hair to pull out!

Buy one ADC, get one Free!  Pizza! Pizza! :)

#6 Kenn Sebesta

Kenn Sebesta

    Controls Master!

  • Members
  • PipPipPip
  • 896 posts
  • Country: flag of Luxembourg Luxembourg


Posted 25 October 2011 - 04:33 PM

View PostBrian, on 25 October 2011 - 04:15 PM, said:

Buy one ADC, get one Free!  Pizza! Pizza! :)

Completely off-topic, it was one of those Little Caesar's commercial that motivated me to learn my powers of two. "Then I'll pay for 512 pizzas." "Then you'll get 1024."