2013-11-19 02:26 PM
2013-11-19 06:38 PM
Well, I figured out part of my problem, but not sure I understand why. It seemed that the interrupt was firing twice as fast as it was supposed to. With a cycle time of 239.5 (+12), and the ADC clocked at 48 MHz, it should complete a conversion at a rate of about 47.7 kHz. I was getting ADC complete interrupts at a rate twice that.
If I ignore every other interrupt, then I get the right ADC values, but still only half of them. It seems that there is an extra DMA transfer, corresponding with an extra ADC conversion (of what?), and so the Index gets incremented twice as much as it should.2013-11-19 07:02 PM
I'm confused by the reason to enable a second ADC sample, and the temp/ref stuff?
ADC_TempSensorCmd(ENABLE);
/* Convert the ADC1 Vref with 5 Cycles as sampling time */
ADC_ChannelConfig(ADC1, ADC_Channel_Vrefint , ADC_SampleTime_239_5Cycles);
ADC_VrefintCmd(ENABLE);
Then again, I'm not spending any time with the F0 and ADC
The use of DMA seems unnecessary if you're collecting/processing on EOC. I'd also wonder about if the DMA pointer is the slot the next sample goes too, not where the last one was stored.
2013-11-19 07:19 PM
.....and the F0 ADC clock is 14 MHz.
Cheers, Hal2013-11-19 07:23 PM
EGADS! Thank you and your eagle eyes.
I removed that extra ADC_ChannelConfig, and now all is well! That's what I get for a sloppy copy and paste job, now that seems obvious where the second ''mystery'' conversion was coming from. Thanks again, Marten2013-11-19 07:27 PM
I thought that the maximum permitted ADC clock was 14 MHz, and the actual clock speed would depend on how it was configured. With a 48 MHz system clock, and /4 for the ADC clock, it ends up at 12 MHz, unless the ADC clock is setup asynchronously from some other source, like a timer.
Is that not correct? Marten2013-11-19 07:34 PM
Regarding the DMA pointer, I think it is more convoluted then that. The DMA_CNDTRx register counts down, indicating how many values are left to transfer, while the data in the circular buffer counts up (I think). So the location of the last data is (Buf_Size - Index) (+/- 1), I'm not exactly sure.
2013-11-20 01:09 PM
FWIW, here are some photos of the filter working. This was done mainly for my education and familiarization with the STM32 F0 discovery board.
I think that the code could be improved a lot, by either with some inline ASM, or at least unrolling the for loop. Code snippets://9 tap filter, 45% Available processing time
uint8_t Filter[NumTaps] = {5,12,31,50,58,50,31,12,5};
// Get index value NDT from DMA_CNDTR1 register
Index = DMA1_Channel1->CNDTR;
for(i = 0; i <
NumTaps
; i++)
{
Acc += Filter[i]*InputData[(9-Index+i)%8];
//Divide by 256 to make gain unity in pass band
Acc >>= 8;
DAC_SetChannel1Data(DAC_Align_12b_R, Acc );
2013-11-20 01:13 PM
FWIW, here are some photos of the filter working. This was done mainly for my education and familiarization with the STM32 F0 discovery board.
I think that the code could be improved a lot, by either with some inline ASM, or at least unrolling the for loop. Code snippets://9 tap filter, 45% Available processing time
uint8_t Filter[NumTaps] = {5,12,31,50,58,50,31,12,5};
// Get index value NDT from DMA_CNDTR1 register
Index = DMA1_Channel1->CNDTR;
for(i = 0; i <
NumTaps
; i++)
{
Acc += Filter[i]*InputData[(9-Index+i)%8];
}
//Divide by 256 to make gain unity in pass band
Acc >>= 8;
DAC_SetChannel1Data(DAC_Align_12b_R, Acc );