Forum: Mikrocontroller und Digitale Elektronik Usart DMA auf ARM7 funktioniert nicht.


von Florian (Gast)


Lesenswert?

Hallo zusammen,

ich grübel seit einigen Tagen an folgendem Problem:
Irgendwie funktioniert der USART-Datenversand mittels DMA nicht.
Habe folgenden Code verwendet:
1
    u_pUSART0->US_TPR = (AT91_REG)buff; // address of DMA output buffer
2
    u_pUSART0->US_TCR = length; //we'll transmit length bytes via DMA
3
4
    // enable transmit DMA transfers, disable receive DMA transfers
5
    u_pUSART0->US_PTCR = AT91C_PDC_TXTEN;
6
7
    // just wait for end of transmission
8
    while(! (u_pUSART0->US_CSR & AT91C_US_ENDTX));

Es gehen aber keine Daten raus und dementsprechend bleibt er auch in der 
While-Schleife hängen.
Woran kann das liegen? Also buff und length sind an der Stelle definitiv 
richtig belegt. Die USART Clock habe ich auch vorher aktiviert:
1
    //enable the clock of USART
2
    u_pPMC->PMC_PCER = 1<<AT91C_ID_US0;
3
4
    //Reset receiver and transmitter
5
    u_pUSART0->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS;
6
7
    //set baud rate divisor register
8
    u_pUSART0->US_BRGR = 3003428/baudrate; // 3003428 = 48Mhz / 16

Irgendwelche Ideen? Danke!

Gruß
Florian

von Lupin (Gast)


Lesenswert?

warum setzt du AT91C_US_RXDIS und AT91C_US_TXDIS? Wie soll er da was 
senden wenn du das senden disablest?

Gibt es nicht noch einen generellen Enable für den USART? Also ein US_MR 
Register?

Meist hilft das Datenblatt bei solchen Problemen.

Ansonsten würde ich mich näherungsweise an das Problem wagen und 
zunächst normale Transfers ohne DMA zum laufen bringen.

von Lupin (Gast)


Lesenswert?


von Florian (Gast)


Lesenswert?

Hey,
danke erstmal!

Beim Initialisieren schreibe ich natürlich in diese Register, hatte ich 
vorhin vergessen mit raus zu kopieren:
1
    // set mode
2
    u_pUSART0->US_MR = AT91C_US_USMODE_NORMAL | AT91C_US_NBSTOP_1_BIT | AT91C_US_PAR_NONE | AT91C_US_CHRL_8_BITS | AT91C_US_CLKS_CLOCK;
3
    // enable transmitter and receiver now
4
    u_pUSART0->US_CR = AT91C_US_RXEN | AT91C_US_TXEN;

Schau mir jetzt aber erstmal den Link an.

von Heiko S. (heiko_s)


Lesenswert?

Hi Florian,
wo sind denn die Sequenzen um den UART zu aktivieren?
Vielleicht solltest Du die Dokumentation doch lesen!

  /* Configure PIO for UART */
  AT91C_BASE_PIOA->PIO_PDR = (UART0_RXD | UART0_TXD);
  AT91C_BASE_PIOA->PIO_ASR = (UART0_RXD | UART0_TXD);

  /* Enable UART Unit */
  AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US0);

Dann kann man die Pufferadressen füllen

  AT91C_BASE_PDC_US0->PDC_TPR = (unsigned int) tmp_char_p;
  AT91C_BASE_PDC_US0->PDC_TCR = strlen((const char *) tmp_char_p);

und mit

  /* start the PDC transfer */
  AT91C_BASE_PDC_US0->PDC_PTCR = AT91C_PDC_TXTEN;

den transfer starten!

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.