Sample data from ADC with Sigfox / Telecom-Design

I just finished a program started a couple of month ago. When I stared to it, I had a hard work to find how to sample a group of  256 values at 32Khz with the EFM32 device embedded in the Telecom Design TD1204 / TD1208 used for my SigFox project. This post details how to do this task

You have a ot of complex solution to get 256 values in a table with this micro-controler, in fact i feel them too complex for my usage and I just do 256 unitary sampling just making sure I’ll be ready to start a new one as soon as the previous will finish. For this reason, I configured as ADC_INITSINGLE_DEFAULT. single_init.ret is set to true to indicate I expect to restart an acquisition right after the previous one.

When you want to sample data from the ADC at a certain frequency, you have to understand that for each data you have a sampling time and a decoding time once capture. To capture a data you need 4 cycles. For each bit you want to decode you need 1 cycle. This depend on the configuration you choose, this is based on the one I have chosen.According to this, as I chose 8 bits / 4 cycle per sample and I’m expecting to sample at 32Khz, the duration of a cycle have to be 384000 ( 32000*(8+4) ). This is what I put in the ADC_PrescaleCalc. The acqTime is also configured to adcAcqTime4 to match the 4 cycle of acquisition.

The only one ADC available in the TD1204 and TD1208 is the Channel 6 (frankly speaking, to have the ability to get another one from the given GPIO would be really usefull !). This is indicated by setting single_init.input = adcSingleInpCh6. The rest of the configuration is the Reference at 2.5V, the resolution adcRes8Bit (8bits) .

To fire the sampling, ADC_Start is called.

/* Base the ADC configuration on the default setup. */
ADC_InitSingle_TypeDef single_init = ADC_INITSINGLE_DEFAULT;
ADC_Init_TypeDef init = ADC_INIT_DEFAULT;
init.timebase = ADC_TimebaseCalc(0);
init.prescale = ADC_PrescaleCalc(384000, 0);   // 384KHz sampling / 4 cycle per sample + 8 cycle decoding = 32KHz
init.warmUpMode = adcWarmupKeepADCWarm;
CMU_ClockEnable(cmuClock_ADC0, true);
ADC_Init(ADC0, &init);
single_init.reference = adcRef2V5;
single_init.input = adcSingleInpCh6;
single_init.resolution = adcRes8Bit;
single_init.acqTime = adcAcqTime4;
single_init.rep = true;                       // auto rearm
ADC_InitSingle(ADC0, &single_init);
ADC_Start(ADC0, adcStartSingle);
int sample_ptr = 0;
while ( sample_ptr < SAMPLE_SIZE ) {
   // Active wait for ADC to complete
   while ((ADC0->STATUS & ADC_STATUS_SINGLEDV) == 0);
   samples[sample_ptr] = ADC_DataSingleGet(ADC0);
   sample_ptr++;
}
CMU_ClockEnable(cmuClock_ADC0, false);

For each of the acquisition, I’m waiting for the end of the sampling looking to ADC0->Status and get the value calling ADC_DataSingleGet(ADC0)

At the end, CMU_ClockEnable(… false) is disabling the ADC clock and stop acquisition.

As a tips, to ensure the duration of the capture is the one you are expecting, you can measure the time by using:

tfp_printf(">%d\r\n",RTC->CNT);

This is printing the 32KHz cycle counter. In this case, the counter difference between start and stop of the sampling should be 256.

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

    • The only ADC pin is ADC0 – PIN20 – Once you sample a value and get it in the digital world you can send it over sigfox network for sure.

  1. Hello Paul (Salut !)

    Is there any special initialisation to setup ? I’m using the Channel 0 (and not Channel 6) but I have wrong values, even when I set the ADC input to input using the GPIO_PinModeSet function.

    Léo

  2. I answer myself, it looks like the input is adcSingleInpCh6 even if the datasheet speaks about #0