Hallo Zusammen,
ich sitze schon einige Stunden/Tage an einem Problem das mich zum
verzweifeln bring. Ich versuche mit einem STM32 (NUCLEO - F429 Board)
das Input Register vom Port E in den Ram zu schreiben. Leider ohne
Erfolg. Der DMA wird durch ein Timer Input Capture Event getriggert.
Der Timer triggert mit einer Frequenz von 6 MHz.
Wenn ich den DMA aktiviere setzt er sofort das transfer error interrupt
flag (TEIF4) für den verwendeten Stream (Stream4) und schaltet sich ab.
Ich bin bereits das Reference Manual RM0090 mehrere Male diesbezüglich
durchgegangen. Leider finde ich dort nichts brauchbares bzgl. dieses
Error Flags. " A bus error occurs during a DMA read or a write access"
ist auch nicht wirklich hilfreich.
Das ist mein erstes mal das ich den DMA verwende und hoffe das mir
jemand einen Tipp geben kann was ich falsch mache. Ich habe noch die
relevanten Codeabschnitte beigefügt:
Peripherie Clock aktivieren:
1 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOE, ENABLE);
|
2 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
|
3 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
|
4 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
|
Globale Variable deklarieren:
1 | // Image buffer
|
2 | volatile uint16_t frame_buffer[IMG_ROWS * IMG_COLUMNS];
|
GPIO Pins und DMA configurieren:
1 | ///////////////// DMA configuration ///////////////////////
|
2 | ///////////////////////////////////////////////////////////
|
3 | /* Init PE8-PE15 for DMA source */
|
4 | GPIO_StructInit(GPIO_InitStructure);
|
5 | GPIO_InitStructure.GPIO_Pin = 0xFF00; // Pin8 .. Pin15
|
6 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
7 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
|
8 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
|
9 | GPIO_Init(GPIOE,&GPIO_InitStructure);
|
10 |
|
11 | DMA_StructInit(&DMA_InitStructure);
|
12 | DMA_Cmd(DMA1_Stream4, DISABLE);
|
13 | while (DMA1_Stream4->CR & DMA_SxCR_EN);
|
14 | DMA_InitStructure.DMA_Channel = DMA_Channel_5; // TIM3_CH1 as Trigger
|
15 | DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(GPIOE->IDR); //address should be 0x40021011 but IDR allows only word read
|
16 | DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&frame_buffer[0]; //frame buffer in RAM
|
17 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //direction of transfer
|
18 | DMA_InitStructure.DMA_BufferSize = IMG_ROWS * IMG_COLUMNS / 2; //define size of buffer
|
19 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
20 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
21 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //not sure
|
22 | DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
|
23 | DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //using of non circular mode
|
24 | DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
25 | DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; //enable FIFO mode
|
26 | DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; //
|
27 | DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
|
28 | DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
|
29 | DMA_Init(DMA1_Stream4, &DMA_InitStructure);
|
30 | //Note: stream is activated later
|
31 | TIM_DMACmd(TIM3, TIM_DMA_CC1, ENABLE); //Capture/Compare 1 DMA request enable
|
Der DMA wird später im Code aktiviert:
1 | DMA1->HIFCR = DMA_FLAG_FEIF4|DMA_FLAG_DMEIF4|DMA_FLAG_TEIF4|DMA_FLAG_HTIF4|DMA_FLAG_TCIF4; //clear all event flags of stream 4
|
2 | DMA_Cmd(DMA1_Stream4, ENABLE);
|
den Timer code habe ich weggelassen, da dieser funktioniert. Ich hoffe
ich habe nichts vergessen. Ich verwende zum Teil die Standard Lib von
ST.
Vielen Dank schon mal
Sebastian