STM32 DMA Neustart, erstes Byte falsch

OP #4701291
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?
OP #4701341
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.
OP #4701421
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.
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren