STM32F407 Weitere IN Token am EP1

#5896240
Lesenswert?

Ich habe einen Virtual ComPort von STM realisiert, Anmelden am System 
funktioniert, jetzt gehe ich über, Daten hin und her zu schicken. Die 
erste Testidee war, nach einem Erhalt von 5 Zeichen im uC eine Antwort 
mit z.B. 36 Zeichen an den PC zu schicken.

Ich erhalte auch die Zeichen, dann initialisiere ich die Senderoutine 
mit:
1
dieptsiz1.d32 = USB.INEP_REGS[1]->DIEPTSIZ;
2
dieptsiz1.b.xfrsiz = 36;
3
dieptsiz1.b.pktcnt = 1;
4
USB.INEP_REGS[1]->DIEPTSIZ = dieptsiz1.d32;
5
USB.INEP_REGS[1]->DIEPCTL |= DIEPCTLx_EPENA|DIEPCTLx_CNAK;
6
for (uint32_t i = 0; i < 9; i++){
7
  *(USB).DFIFO[1]=USB_buffer[i];
8
}
Daten werden auch am PC empfangen und ein XFRC (transfer complete) am 
EP1 IN wird ausgelöst. Danach kommt aber ein weiterer IN token und ich 
bekomme ein ITTXFE (IN token received while Tx empty) interrupt.

Eigentlich ist doch dem Host durch vorherige Anweisung bekannt, dass ich 
nur 36 Bytes senden möchte, warum kommt da ein weiteres IN Token?
Persönliche Seite #5901971
Lesenswert?

Tycho B. schrieb:
> Eigentlich ist doch dem Host durch vorherige Anweisung bekannt, dass ich
> nur 36 Bytes senden möchte, warum kommt da ein weiteres IN Token?

Der Host sendet doch immer wieder "IN", bis Daten im Puffer sind. 
Solange keine Daten da sind, antwortet die Peripherie automatisch mit 
"NAK". Diese ankommenden "IN" sollten die Software aber normalerweise 
nicht interessieren. Den ITTXFE Interrupt kannst du daher komplett 
weglassen und abgeschaltet lassen.

Im Transfer Complete Interrupt kannst du zur Sicherheit wieder NAK 
aktivieren, aber das sollte eigentlich nicht nötig sein:
1
USB.INEP_REGS[1]->DIEPCTL |= USB_OTG_DIEPCTL_SNAK_Msk;
#5903798
Lesenswert?

Ich bin mir nicht sicher ob es so stimmt. Ich sende ja bei der 
Enumeration Deskriptoren an das System. Danach taucht dieses ITTXFE 
nicht auf. Ich dachte, wenn ich SNAK setze, dann sendet der uc nacks an 
den PC transparent ohne mich zu belästigen. Erst wenn ich mit
1
USB.INEP_REGS[1]->DIEPCTL |= DIEPCTLx_EPENA|DIEPCTLx_CNAK;
starte und etwas falsch konfiguriere oder sende, dann kommt ITTXFE und 
sagt mir, dass der Host noch Daten erwartet.
Gast #5904227
Lesenswert?

Tycho B. schrieb:
> Ich dachte das geschieht automatisch.

Das muss automatisch passieren, sonst würde die Kommunikation abreißen 
wenn der Interrupt nicht extrem schnell kommt...

Tycho B. schrieb:
> Danach taucht dieses ITTXFE nicht auf.

Ja, weil der Host auf dem EP0 nicht kontinuierlich IN sendet.

Tycho B. schrieb:
> Ich dachte, wenn ich SNAK setze, dann sendet der uc nacks an den PC
> transparent ohne mich zu belästigen

Jo.

Vermutlich sendet der uC bei leerem FIFO automatisch immer NAK, aber 
wenn du das NAK Bit nicht gesetzt hast ("SNAK") kommt der ITTXFE 
Interrupt, den du aber eigentlich ignorieren kannst.
#5923665
Lesenswert?

Um die Funktionalität zu testen habe ich ein kleines Beispielprogramm 
geschrieben: wenn der uC 5 Zeichen erhält, dann sendet er 60 zurück an 
den PC.
1
    dieptsiz1.d32 = USB.INEP_REGS[1]->DIEPTSIZ;
2
    dieptsiz1.b.xfrsiz = 60;
3
    dieptsiz1.b.pktcnt = 1;
4
    USB.INEP_REGS[1]->DIEPTSIZ = dieptsiz1.d32;
5
    USB.INEP_REGS[1]->DIEPCTL |= DIEPCTLx_EPENA|DIEPCTLx_CNAK;
6
    for (uint32_t i = 0; i < 15; i++){
7
      *(USB).DFIFO[1]=USB_buffer[i];
8
    }

Wenn diese IN Übertragung durch ist, also 60 Zeichen an den PC gesendet 
wurden, dann wird das DIEPINT_XFRC (IN Transfer completed interrupt) 
ausgelöst und in dieser ISR SNAK gesetzt, damit ITTXFE(IN token received 
when TxFIFO is empty) beim nächsten IN Token nicht aktiv wird.
1
USB.INEP_REGS[1]->DIEPCTL |= DIEPCTLx_SNAK;
Das funktioniert auch mehrere Male, nur irgendwann mal antwortet uC 
nicht mit 60 Zeichen, sondern  mit Status 0xC0000004 - STALL_PID.

Und das ist für mich nicht verständlich - warum plötzlich STALL wenn der 
Transfer davor 10 mal funktioniert hat (siehe PNG)?

PS.: Wenn ich kontinuierlich Daten sende und nicht nur 60 Zeichen, dann 
funktioniert es(
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