Forum: Mikrocontroller und Digitale Elektronik STM32 DMA Neustart, erstes Byte falsch


von Holger K. (holgerkraehe)


Lesenswert?

Hallo

Ich habe folgendes Szenario:

STM32F105 als SPI Slave.
Dieser soll bei erhalt eines Bytes oder mehrere Bytes mittels DMA einen 
definierten Buffer zurücksenden.

Leider klappt das nicht so wie es soll.
Es wird immer erst ab dem zweiten Byte das erste des buffers 
zurückgesendet.
Das erste byte welches über SPI zurückgeht ist das letzte welches zuvor 
gesendet wurde.


Der DMA scheint immer ein byte zu benötigen, bis er sich konfiguriert 
hat.
Also sozusagen ein dummy byte bevor die Übetragung beginnt.
Ist dies so üblich?

Es scheint, als wäre etwas irgendwo im zwischenspeicher.
Was mache ich falsch?

: Bearbeitet durch User
von Rainer U. (r-u)


Lesenswert?

Holger K. schrieb:
> Es wird immer erst ab dem zweiten Byte das erste des buffers
> zurückgesendet.

Ich hab zumindest einige SPI-Bausteine gesehen, die so funktioniert 
haben. Woher soll er auch wissen, was er zurückgeben soll, bevor er das 
allererste Byte vollständig empfangen und ausgewertet hat?

von Holger K. (holgerkraehe)


Lesenswert?

Rainer U. schrieb:
> Holger K. schrieb:
>> Es wird immer erst ab dem zweiten Byte das erste des buffers
>> zurückgesendet.
>
> Ich hab zumindest einige SPI-Bausteine gesehen, die so funktioniert
> haben. Woher soll er auch wissen, was er zurückgeben soll, bevor er das
> allererste Byte vollständig empfangen und ausgewertet hat?

Nein du vestehst das nicht ganz.

Ich konfiguriere den DMA BEVOR ich bytes empfange.
Bei der Konfiguration teile ich dem DMA mit, was er zu senden hat.

Wenn der Master nun ein byte sendet und ich dieses als Slave empfange, 
so soll bereits beim ersten Bytetransfert der DMA die konfigurierten 
Daten absenden.

Dies tut er jedoch erst beim zweiten emfpangenen byte.

Es muss nichts ausgewertet werden.

von Dr. Sommer (Gast)


Lesenswert?

Hast du das DMA korrekt abgeschaltet nach dem vorherigen Transfer?
Ala
1
DMA1->CCR = 0; // EN bit abschalten!
2
while (DMA1->CCR & DMA_CCR_EN);

von Holger K. (holgerkraehe)


Angehängte Dateien:

Lesenswert?

Dr. Sommer schrieb:
> Hast du das DMA korrekt abgeschaltet nach dem vorherigen Transfer?
> AlaDMA1->CCR = 0; // EN bit abschalten!
> while (DMA1->CCR & DMA_CCR_EN);

Bisher noch nicht.

Nun habe ich das angepasst.
Aktuell sieht mein Code so aus:
1
uint8_t  dataSendB[4] = {0x14, 0x41, 0x63, 0x20};
2
...
3
void SPI2_IRQHandler(void)
4
{
5
  uint8_t cmd;
6
7
  SPI_I2S_ClearITPendingBit(SPI2,SPI_I2S_IT_RXNE);
8
  cmd = SPI2->DR;
9
10
  if(cmd != 0xD8)
11
  {
12
    //DMA Deaktivieren
13
    DMA1_Channel5->CCR &= (uint16_t)(~DMA_CCR1_EN);
14
    while (DMA1_Channel5->CCR & DMA_CCR1_EN);
15
    
16
    
17
    DMA1_Channel5->CMAR = (uint32_t)&dataSendB[0];
18
    DMA1_Channel5->CNDTR = 2;    
19
    
20
    //DMA Aktivieren
21
    DMA1_Channel5->CCR |= DMA_CCR1_EN;
22
  }
23
//Interrupt deaktivieren. Wird beim CS Low->HIGH wieder aktiviert
24
//Dadurch bekomme ich nur das erste Byte (CMD) mit
25
SPI_I2S_ITConfig(SPI2,SPI_I2S_IT_RXNE,DISABLE);
26
}


Ich empfange das erste byte mittels interrupt.
Dann schaue ich mir dieses an und aktiviere den DMA für die nächste 
übertragung.

Anbei ein Bild.

Eigentlich müsste dann 0x14 0x41 kommen
Jedoch kommt zuerst 0x02.
Das ist jenes byte, welches ich an anderer Codestelle zuletzt mit dem 
DMA übertragen habe.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.