Hallo,
Ich arbeite mit dem ZYNQ Zedboard (version d, PS7000). Ich habe eine
Hardware synthetisiert, und teilweise getestet. Zu sehen ist das Design
im Anhang.
Im C Code mache ich folgendes um den DMA anzusteuern, die adressen
stimmen, da es wie unten beschrieben auch manchmal geht:
1 | // 1 verify CDMASR = idle
|
2 | uint32_t value;
|
3 | do{
|
4 | value = Xil_In32(XPAR_AXI_CDMA_0_BASEADDR + 0x04); // read status register
|
5 | }while (!(value & 0x02));
|
6 |
|
7 | // deactivate interrupts
|
8 | Xil_Out32(XPAR_AXI_CDMA_0_BASEADDR + 0x04, (value & ~0x5000));
|
9 |
|
10 | // init dma controller
|
11 | // programm dma engine to copy data
|
12 | Xil_Out32(XPAR_AXI_CDMA_0_BASEADDR + 0x18, source); //write source address
|
13 | Xil_Out32(XPAR_AXI_CDMA_0_BASEADDR + 0x20, dest); //write destination address
|
14 | Xil_Out32(XPAR_AXI_CDMA_0_BASEADDR + 0x28, len); //write length
|
15 |
|
16 | do{
|
17 | value = Xil_In32(XPAR_AXI_CDMA_0_BASEADDR + 0x04); // read status register
|
18 | }while (!(value & 0x02));
|
19 |
|
20 | // clear interrupt ..
|
21 | Xil_Out32(XPAR_AXI_CDMA_0_BASEADDR + 0x04, value | 0x1000);
|
Das ist alles aus dem Reference Manual für den DMA. In der Main rufe ich
vorher die beiden Funktionen zum Initialisieren der Hardware auf:
1 | // init functions
|
2 | init_platform();
|
3 | ps7_post_config();
|
Das Programm schreibt Daten in das lokale RAM, die dann von dem DMA in
den Block Memory kopiert werden sollen. Von da lese ich die Werte wieder
über einen seperaten AXI Controller zurück.
Leider stellt sich folgende Eigenart ein: Erst nach 2 oder 3 maligem
durchlauf des gesamten Codes (übrigens mit sleep Funktionen) stimmen die
Datenwerte überein. Als ob der DMA nicht immer gestartet wird, bzw er
nicht korrekt gestartet wird. Im Manual steht dazu nur, dass er immer
dann startet, wenn man die zu übertragende Länge neu schreibt. (passiert
im Code ...)
Habt ihr noch Ideen woran es liegen kann?
Gruß,
Jens