$10 O-Scope revisited

What are you developing?
arpruss
Posts: 93
Joined: Sat Sep 30, 2017 3:34 am

Re: $10 O-Scope revisited

Post by arpruss » Mon Oct 02, 2017 9:10 pm

By the way, going way back to the original stm32f1 scope, it's worth noting that if one turns off interrupts during sampling, one can get the full maximum sampling rate (1.7msps) without DMA, just by reading the interleaved data in a tight loop in continuous mode:

Code: Select all

void fetch() {  
  int channel = PIN_MAP[analogInPin].adc_channel;
  adc_set_sample_rate(ADC1, ADC_SMPR_1_5); 
  adc_set_sample_rate(ADC2, ADC_SMPR_1_5); 
  adc_set_reg_seqlen(ADC1, 1);
  adc_set_reg_seqlen(ADC2, 1);
  ADC1->regs->SQR3 = channel;
  ADC2->regs->SQR3 = channel;

  ADC1->regs->CR1 |= 0x70000; // ADC_CR1_FASTINT;
  ADC1->regs->CR2 |= ADC_CR2_CONT | ADC_CR2_SWSTART;
  ADC2->regs->CR2 |= ADC_CR2_CONT | ADC_CR2_SWSTART;
  ADC2->regs->CR1 |= 0x70000; // ADC_CR1_FASTINT;
  nvic_globalirq_disable();
  for (int j = 0; j < maxSamples ; j+=2 )
  {
    while (!(ADC1->regs->SR & ADC_SR_EOC))
        ;
    dataPoints[j] = ADC1->regs->DR & ADC_DR_DATA;
    while (!(ADC2->regs->SR & ADC_SR_EOC))
        ;
    dataPoints[j+1] = ADC2->regs->DR & ADC_DR_DATA;
  }
  nvic_globalirq_enable();
}

alexandros
Posts: 42
Joined: Mon Oct 02, 2017 6:51 pm

Re: $10 O-Scope revisited

Post by alexandros » Tue Oct 03, 2017 6:24 am

I'm Looking at the code of O-Scope and i m trying to understand how can i add a second channel for getting samples.
like

Code: Select all

void setADCs ()
{
	  int pinMapADCinA = PIN_MAP[analogInPinA].adc_channel;
	  int pinMapADCinB = PIN_MAP[analogInPinB].adc_channel;
	  adc_set_sample_rate(ADC1, ADC_SMPR_1_5); //7_5 13_5
	  adc_set_sample_rate(ADC2, ADC_SMPR_1_5);

	  //  adc_reg_map *regs = dev->regs;
	  adc_set_reg_seqlen(ADC1, 1);
	  ADC1->regs->SQR3 = pinMapADCinA;
	  ADC1->regs->CR2 |= ADC_CR2_CONT; // | ADC_CR2_DMA; // Set continuous mode and DMA
	  ADC1->regs->CR1 |= ADC_CR1_FASTINT; // Interleaved mode
	  ADC1->regs->CR2 |= ADC_CR2_SWSTART;

	  adc_set_reg_seqlen(ADC2, 1);
	  ADC2->regs->SQR3 = pinMapADCinB;
	  ADC2->regs->CR2 |= ADC_CR2_CONT; // ADC 2 continuos
	  ADC1->regs->CR1 |= ADC_CR1_FASTINT; // Interleaved mode
	  ADC1->regs->CR2 |= ADC_CR2_SWSTART;
} 
This code works fine .
But i have a problem in taking samples for the ADC2

What do i have to do in order to take the ADC2 values ?

Code: Select all

void takeSamplesADC2 ()
{
  // This loop uses dual interleaved mode to get the best performance out of the ADCs
  //

  dma_init(DMA1);
  dma_attach_interrupt(DMA1, DMA_CH1, DMA1_CH1_Event);

  adc_dma_enable(ADC2);
  dma_setup_transfer(DMA1, DMA_CH1, &ADC2->regs->DR, DMA_SIZE_32BITS,
                     dataPoints32, DMA_SIZE_32BITS, (DMA_MINC_MODE | DMA_TRNS_CMPLT));// Receive buffer DMA
  dma_set_num_transfers(DMA1, DMA_CH1, maxSamples / 2);
  dma1_ch1_Active = 1;
  //  regs->CR2 |= ADC_CR2_SWSTART; //moved to setADC
  dma_enable(DMA1, DMA_CH1); // Enable the channel and start the transfer.
  //adc_calibrate(ADC1);
  //adc_calibrate(ADC2);
  samplingTime = micros();
  while (dma1_ch1_Active);
  samplingTime = (micros() - samplingTime);

  dma_disable(DMA1, DMA_CH1); //End of trasfer, disable DMA and Continuous mode.
  // regs->CR2 &= ~ADC_CR2_CONT;

}

arpruss
Posts: 93
Joined: Sat Sep 30, 2017 3:34 am

Re: $10 O-Scope revisited

Post by arpruss » Wed Oct 04, 2017 8:32 pm

You can't do two channel of you're using interleaved mode. If you want two channel, you'll be limited in speed to half the maximum.

User avatar
rexnanet
Posts: 205
Joined: Wed Mar 16, 2016 10:34 am

Re: $10 O-Scope revisited

Post by rexnanet » Sat Oct 07, 2017 6:24 pm

I think that it might be kind of "2 separate channel interleaving". You might get ADC2 samples on the second 16 bits of every 32bit block.
But channel 2 will not be sampled at the same time as channel 1. It will be offset by 7 ADC clocks.
If setting ADC2 to pinB works, than the what I said before should be valid.

EDIT: read http://www.st.com/content/ccc/resource/ ... 258017.pdf

Post Reply