[AT91SAM] IRQ-getriebener DMA-Transfer auf UART führt zu Absturz

Gast #2519487
Hallo Mikros!

UART 1-Kanal ist per DMA angebunden zum Empfangen (RX) und Senden (TX) 
zum PC-Terminalprogramm (Baudrate 57600).

Beim Empfang eines Bytes wird dieses verarbeitet und sofort 
zurückgesandt (echo). Das Verarbeiten ist sehr fix und wird innerhalb 
der IRQ-Routine erledigt, die vom beendeten DMA-Transfer ausgelöst wird. 
(siehe UART1_irqHandler()).

Versuche ich nun, das eben empfangene Byte zurückzusenden 
(UART1_sendCharacter()), scheint irgendwas im Mikro schief zu laufen 
(sieht so aus, als ob ein Reset folgt ... bin mir unsicher). Auf jeden 
Fall reagiert danach der UART 1 nicht mehr (und einige andere Dinge auch 
nicht).

Vermutung:
Aus einer Interrupt-Routine (RX-Zweig) wird Senden ausgeführt, welches 
so fix fertig ist, dass noch während des Sendens ein weiterer Interrupt 
ausgelöst wird (TX).

Kann mit jmd bei der Deutung ein paar Tipps geben?

Danke fürs Lesen,
Paule

PS: Hier der Code-Schnippsel.
1
/** Connection baud rate. */
2
#define    BAUDRATE    57600
3

4
/** Debug input (RX) buffer. */
5
char    inBuffer[4];
6
/** Debug output (TX) buffer. */
7
char    outBuffer[128];
8

9
/**
10
 * Sends a single character to device connected on UART 1.
11
 *
12
 * Blocks, if sending of previous buffer is in progress.
13
 *
14
 * @param[in]  character    single character to send
15
 */
16
void     UART1_sendCharacter(
17
    const char      character){
18

19
  /* wait until former communication ends */
20
  USART1_waitForEndTx();
21

22
  /* make local copy of value */
23
  outBuffer[0] = character;
24

25
  AT91C_BASE_US1->US_TCR  = 1;
26
  AT91C_BASE_US1->US_PTCR = AT91C_PDC_TXTEN;
27
}
28

29
/**
30
 * IRQ handler for incoming (RX) and outgoing (TX) UART 1 communication.
31
 *
32
 * Incoming signals are sent byte-wise to user command unit.
33
 */
34
void    UART1_irqHandler() {
35

36
  if ((AT91C_BASE_US1->US_CSR & AT91C_US_ENDRX) == AT91C_US_ENDRX) {      /* reception done interrupt (ENDRX) */
37

38
    AT91C_BASE_US1->US_RCR = 1;            /* restore the receive count - clears ENDRX flag */
39
    AT91C_BASE_US1->US_RPR = (AT91_REG)inBuffer;  /* address of DMA input buffer */
40

41
    USERCMD_addCharacterToCommand(inBuffer[0]);    /* try to add character to user command input buffer */
42
    
43
    UART1_sendCharacter(inBuffer[0]);        // <<<<<---- crashes
44
    
45

46
  } else if ((AT91C_BASE_US1->US_CSR & AT91C_US_ENDTX) == AT91C_US_ENDTX) {  /* transmission done interrupt (ENDTX) */
47

48
    AT91C_BASE_US1->US_PTCR = AT91C_PDC_TXTDIS;
49
    AT91C_BASE_US1->US_TCR = 1;            /* restore the transmit count - clears ENDTX flag */
50
    AT91C_BASE_US1->US_TPR = (AT91_REG)outBuffer;  /* address of DMA output buffer */
51

52
  }
53
}
Gast #2520613
Hallo,

ich denke da fehlt noch was in der UART1_sendCharacter. Vorschlag:

AT91C_BASE_US1->US_TCR  = 1;
AT91C_BASE_US1->US_TPR  = (AT91_REG)outBuffer;
AT91C_BASE_US1->US_PTCR = AT91C_PDC_TXTEN;

Damit wäre die DMA Adresse des Buffers nicht mehr NULL wenn zum ersten 
mal zurück gesendet werden soll und noch kein TX-Ready IRQ kam.

Gruß Micoman
Gast #2521877
Hallo Micoman,

mein Fehler: Die Initialisierung des Buffers wird in einer anderen 
Methode einmalig vorgenommen. Danach soll das die IRQ-Routine 
übernehmen.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.