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.
Hello Paul
How can i send a analog value from pin 6 to the Sigfox network with the TD1208?
regards
Philip
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.
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
I answer myself, it looks like the input is adcSingleInpCh6 even if the datasheet speaks about #0