Hallo Zusammen,
Ich habe ein Problem mit meinem DMA in Verbindung mit SPI auf einem
STM32F1. In meinem System ist ein Raspberry (SPI Master) mit dem STM32F1
(SPI Slave) verbunden.
An sich funktioniert das Ganze recht gut, - der Raspberry triggert hin
und wieder einen SPI Transfer an und Daten werden ausgetauscht. Die MISO
und MOSI Buffergrößen sind identisch und liegen bei 75 Byte und diese
werden per DMA an den SPI angebunden.
Wenn ich jetzt aber meine Debug-Umgebung verlasse und das System
schneller operieren lasse, bekomme ich Datenkonsistenzprobleme in MISO
Richtung.
So ist der Plan für einen Programmzyklus:
1. Raspberry triggert einen Transfer an
2. STM32F1 wird auf "DMA1_IT_TC2" geriggert (keine Interrupts, einfach
eine while())
3. STM32F1 bereitet MISO Buffer vor: kopiert Daten in den MISO Buffer
und setzt am Ende vom Buffer einen inkrementellen Index
4. Raspberry triggert so lange SPI Transfers, bis sich der Index ändert
-> "neue Daten vorhanden"
Mein Problem ist nun, dass der Raspberry im ersten Zyklus, nachdem er
einen neuen Index im MISO Buffer sieht, noch alte Daten im ersten Byte
des Buffers stehen:
Erster Zyklus mit Index 1:
1 | AA AA AA 00 00 00 00 .... 00 00 01
|
Zweiter Zykus mit Index 2:
1 | BB BB BB 00 00 00 00 .... 00 00 02
|
Der Raspberry sieht aber:
1 | AA BB BB 00 00 00 00 .... 00 00 02
|
Triggert der Raspberry jetzt noch einmal den Transfer, so steht das
richtige Datum im Buffer. Im Datenregister des STM32-SPIs steht sicher
noch was Altes, ohne das es mit dem DMA Speicher abgeglichen wird. Meine
Frage ist nun, wie kann man dem SPI am besten mitteilen, dass er seine
Daten aktualisieren soll?
Wäre über Tipps sehr dankbar!
Grüße
Chris
P.S. hier noch meine DMA konfiguration:
1 | /********************************** MOSI DMA ***************************************/
|
2 | /* Configure DMA1 - Channel2== (SPI -> memory) */
|
3 | DMA_DeInit(MOSI_DMA_Channel); /* Set DMA registers to default values */
|
4 | DMA_StructInit(&DMA_InitStructure);
|
5 | DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR; /* Address of peripheral the DMA must map to */
|
6 | DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&abyData_MOSI[0]; /* Variable to which received data will be stored */
|
7 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
|
8 | DMA_InitStructure.DMA_BufferSize = SPI_MOSI_BUFF_SIZE; /* Buffer size */
|
9 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
10 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
11 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
12 | DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;
|
13 | DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
|
14 | DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
15 | DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
16 | DMA_Init(MOSI_DMA_Channel, &DMA_InitStructure); /* Initialise the DMA */
|
17 | DMA_Cmd(MOSI_DMA_Channel, ENABLE); /* Enable the DMA1 - Channel2 */
|
18 |
|
19 | /********************************** MISO DMA ***************************************/
|
20 | /* Configure DMA1 - Channel3== (memory -> SPI) */
|
21 | DMA_DeInit(MISO_DMA_Channel); /* Set DMA registers to default values */
|
22 | DMA_StructInit(&DMA_InitStructure);
|
23 | DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR; /* Address of peripheral the DMA must map to */
|
24 | DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&abyData_MISO[0]; /* Variable from which data will be transmitted */
|
25 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
|
26 | DMA_InitStructure.DMA_BufferSize = SPI_MISO_BUFF_SIZE; /* Buffer size */
|
27 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
28 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
29 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
30 | DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;
|
31 | DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
|
32 | DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
33 | DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
34 | DMA_Init(MISO_DMA_Channel, &DMA_InitStructure); /* Initialise the DMA */
|
35 | DMA_Cmd(MISO_DMA_Channel, ENABLE); /* Enable the DMA1 - Channel3 */
|