I've been scratching my head for the past few days as I try to
understand why and what is going on... So here it goes:
Current config: stm32f407VG (same as stm32f4 discovery)
I set up a project using the default linker and startup files from
www.onarm.com.
Init the ADC & DMA's
1 | ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;
|
2 | ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
|
3 | ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
|
4 |
|
5 | DMA_InitTypeDef DMA_InitStructure;
|
6 | NVIC_InitTypeDef NVIC_InitStructure;
|
7 |
|
8 | DMA_InitStructure.DMA_Channel = DMA_Channel_0;
|
9 | DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &RawADCData.adcRaw1;
|
10 | DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) ADC_CCR_ADDRESS;
|
11 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
|
12 | DMA_InitStructure.DMA_BufferSize = ADC_SAMPLE_NUM * ADC_NUM * ADC_BUFFER_MULTIPLIER;
|
13 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
14 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
15 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
|
16 | DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
|
17 | DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
|
18 | DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
19 | DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
|
20 | DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
|
21 | DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
|
22 | DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
|
23 | DMA_Init(DMA2_Stream0, &DMA_InitStructure);
|
24 |
|
25 | /*Interrupt when half of DMA is done, so we do not overwrite our values when processing*/
|
26 | DMA_ITConfig(DMA2_Stream0, DMA_IT_HT | DMA_IT_TC, ENABLE);
|
27 | DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TEIF0 | DMA_IT_DMEIF0 | DMA_IT_FEIF0 | DMA_IT_TCIF0 | DMA_IT_HTIF0);
|
28 |
|
29 | // Enable the DMA2_Stream0 global Interrupt
|
30 | NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
|
31 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
|
32 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
33 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
34 | NVIC_Init(&NVIC_InitStructure);
|
35 |
|
36 | /* DMA2_Stream0 enable */
|
37 | DMA_Cmd(DMA2_Stream0, ENABLE);
|
--Symptom A:
Compile on GCC with CooCox as IDE, the DMA values are all garbled, after
looking at the memory, it seems like the DMA values were sometimes
offset by 1 word.
--Symptom B: Floats do not print correctly, printf works, but they are
not passed on VA_ARGS correctly, offset by x bytes, x is pretty random.
--Sympton C: I add a struct into my file somewhere, say
1 | struct b
|
2 | {
|
3 | float z[40];
|
4 | }
|
Everything begins to work, prints are correct, DMA is correct.
I add anther struct into anther file
1 | struct b
|
2 | {
|
3 | float z[80];
|
4 | int z[3];
|
5 | }
|
DMA is correct, but printf does not work again. If i twitter around with
the structs, DMA can be broken, but printf works, or they all can be
broken.
I have a feeling that it is a linker error or alignment error, but do
not know where else to look.
The entire codebase is here
(http://code.google.com/p/narwhalroboticsquad/source/browse/?r=25#svn%2Ftrunk%2FNarwhalQuad)
if you are curious, built with Coocox IDE with the GNU ARM toolchain.