Forum: Mikrocontroller und Digitale Elektronik STM32F103 Uart DMA Rx Problem


von Georg I. (dschi-ai)


Lesenswert?

Hallo zusammen,

ich habe einige Zeit mit dem STM32F407 verbracht und habe mir da eine 
schöne Bibliothek gebaut, um die Uarts per Interrupt und DMA betreiben 
zu können. Klappt tadellos. Nun versuche ich gerade, alles auf den 
STM32F103RBT6 zu portieren, hänge aber bei 99%.
Konkret geht es darum, mit dem ESP8266 zu kommunizieren und eingehende 
TCP Pakete per DMA zu verarbeiten. Rein kommt bspw. ein:
1
+IPD,1,10:

gefolgt von 10 Bytes an Daten, die hier mal
1
abcdefghij

sein sollen.
Tatsächlich empfange ich mit dem DMA, den ich eben auf 10 Bytes 
konfiguriert habe, folgendes:
1
:abcdefghi

Er schiebt das letzte per Interrupt empfangene Byte also direkt in den 
DMA. Und ich hab absolut keine Ahnung, warum.
1
void startUart2RxDma(uint16_t dma_buffer_length)
2
{
3
  //USART_ReceiveData(USART2);
4
  //USART_ClearITPendingBit(USART2,USART_IT_RXNE);
5
  //USART_ClearFlag(USART2,USART_FLAG_RXNE);
6
  //while(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){};
7
  USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
8
  DMA_ClearFlag(DMA1_FLAG_TC6);
9
  DMA_Cmd(DMA1_Channel6, DISABLE);
10
  DMA_SetCurrDataCounter(DMA1_Channel6, dma_buffer_length);
11
12
  DMA_Cmd(DMA1_Channel6, ENABLE);
13
}
14
15
//UART2 RX Interrupt
16
void USART2_IRQHandler(void)
17
{
18
  char data='\0';
19
  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
20
  {
21
    data = USART_ReceiveData(USART2);
22
23
    UartReceiveByte(&U2,data);
24
  }
25
}

In UartReceiveByte() reagiere ich auf den ':' und rufe schließlich 
startUart2RxDma() auf. Nach den 10 Bytes lande ich dann im 
DMA1_Channel6_IRQHandler(), der Transfer schließt also ab. Ich habe 
schon einiges ausprobiert, warten, Flags resetten, etc., aber nichts hat 
geholfen.

Hat jemand eine Idee, wie man das lösen könnte? Bug, Feature, oder bin 
ich zu doof?

Gruß,
Georg

von grundschüler (Gast)


Lesenswert?

wo ist das Problem? Wenn du ':' empfangen hast, muss es aus dem buffer 
entfernt werden, damit es nicht mittels dma übertragen wird. Wenn es zu 
Beginn der Übertragung noch drin steht, wird es halt mit übertragen.

von Jim M. (turboj)


Lesenswert?

Der Fehler ist in dem Teil des Codes den der OP nicht gepostet hat...

von Georg I. (dschi-ai)


Lesenswert?

Mit USART_ReceiveData(USART2) lese ich das letzte per Interrupt 
empfangene Zeichen, hier ':', aus dem Puffer aus. Somit sollte er leer 
sein und eigentlich auch das RXNE resettet werden. Manuelles resetten 
bringt auch nichts, ebenso wie warten auf das rücksetzen des RXNE. Wie 
kann man ihm also sonst verklickern, dass der Eingang verarbeitet wurde?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Georg I. schrieb:
> Hat jemand eine Idee, wie man das lösen könnte? Bug, Feature, oder bin
> ich zu doof?

 a) DMA auf len+1 einstellen.
 b) Mit 2 Buffern arbeiten, nach ":" DMA auf RxBuff2.

 c) Vollständigen Code posten, vielleicht sieht jemand wo dein
    Fehler liegt.

von Georg I. (dschi-ai)


Angehängte Dateien:

Lesenswert?

Im Anhang die relevanten Dateien.

Die Funktion UartReceiveByte() hängt nur das empfangene Byte an einen 
Ringpuffer an oder, falls das Zeichen ein ':' ist und davor '+IPD,x,y:' 
steht, startet sie mit startUart2RxDma() den DMA. Alles, was mit der 
Uart Hardware zu tun hat, ist in den drei Dateien im Anhang.

von aSma>> (Gast)


Lesenswert?

Georg I. schrieb:
> void USART2_IRQHandler(void)

Ohne dein Code vollständig gelsen zu haben, wenn du mit DMA arbeitest 
dann nehme auch die entsprechende DMA1_Channel6 ISR.

Ich würde dazu raten ein Protkoll mit einen Buffer ohne DMA ans Herz 
legen.
Sonst gucke dir die entsprechenden AppNotes von ST an. Die Schwierigkeit 
liegt hierbei zu erkennen wann die Übertragung fertig ist.

Wenn das eh nicht zeitkritisch ist, dann polle einfach (nicht 
blockierend)

mfg

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.