Hallo,
ich hab da ein Problem mit dem TXEMPTY Interrupt des UC3A1512 (AVR32).
Ich möchte auf einer Leitung senden und empfangen, dafür schalte ich den
Transmitter zum Senden an und für den Empfang ab (Master Slave
Kommunikation). Um einen Datenblock zu senden verwende ich den TXRDY
Interrupt (was wunderbar funktioniert) zum Abschalten des Transmitters
hätte ich gerne den TXEMPTY Interrupt verwendet um den Sender
abzuschalten und auf Empfang zu schalten. In der Theorie sollte das
gehen (bereits in einem AVR realisiert) doch nun zur Praxis:
TXEMPTY Interrupt ist aktiviert und in der ISR behandelt. Das Problem
ist: die Stelle in der ISR , die dafür vorgesehen ist (siehe Pfeil in
der ISR), wird nicht angesprungen. Warum?
hier ein paar Codeteile:
Initialisierung:
Den Prozessor kenne ich nur vom oberflächlichen Lesen des Datenblattes.
Was mich zunächst wundert: gibt es nur einen Interruptvector für USART1?
Keinen für Rx1, Tx1 und TxEmpty1?
Egal.
Stimmt der Wert von AVR32_USART_CSR_TXEMPTY_MASK? Hast Du die Abfrage
auf TxE mal ganz an den Anfang der Int-Routine gestellt? Wird das
enable-Bit vielleicht irgendwo gelöscht? Sind Lesezugriffe auf
USART1->csr vielleicht destruktiv? Könntest Du TxE explizit noch einmal
aktivieren, wenn der Puffer der zu sendenen Zeichen leer ist (tx_ptr >=
length)?
Gast wrote:
> Was mich zunächst wundert: gibt es nur einen Interruptvector für USART1?> Keinen für Rx1, Tx1 und TxEmpty1?
Genau so ist es (werden durch Abfragen des CSR in der ISR unterschieden)
> Stimmt der Wert von AVR32_USART_CSR_TXEMPTY_MASK?
Stimmt (als 0x00000200 definiert in der Header-Datei), vgl. Datenblatt
> Hast Du die Abfrage> auf TxE mal ganz an den Anfang der Int-Routine gestellt? Wird das> enable-Bit vielleicht irgendwo gelöscht? Sind Lesezugriffe auf> USART1->csr vielleicht destruktiv?
Das glaub ich weniger, denn sonst würde der Empfangs-Interrupt auch nie
durchkommen (am Ende).
> Könntest Du TxE explizit noch einmal> aktivieren, wenn der Puffer der zu sendenen Zeichen leer ist (tx_ptr >=> length)?
Auch schon probiert, leider ohne Erfolg
Ich seh schon, wird eine harte Nuss...
>Das glaub ich weniger, ...
Ich glaube an nichts und mache es daher trotzdem.
Ein weiter Schritt wäre, am Anfang gleich mit:
unsigned long csr_temp = USART1->csr;
den aktuellen Wert zu retten und mit diesem die Vergleiche
durchzuführen. Da Du offensichtlich keine großen Möglichkeiten zur
Fehlersuche hast, könntest Du auch an einem Ausgang eine LED aktivieren,
sobald ein TxEmpty-Zustand erkannt wird (nicht wieder löschen!). Damit
könnte festgestellt werden, ob jemals das Bit überhaupt gesetzt wurde.
....
"RS485 AVR32* "
Der mode ist z.B für RS458
Google mal mit dem stichwort RS485 AVR32.
Aber im Google "CodeSearch".
Da sind die Code Beispiele für diesen Mode drin.
Die IRQ Vectoren ca 10 Stück.
So solten die Suchergebnisse dan kommen.
Du soltest das z.B auf RS485 einstellen.
Um das z.B Transmit Register Empty zu bekommen.
/*----------------------------------------------------------------------
-----+
|
|
| TRANSMIT/RECEIVE FUNCTIONS |
|
|
+-----------------------------------------------------------------------
----*/
/**
* Description: While in RS485-mode, receviers only accept data
addressed to them.
* A packet/char with the address tag set has to preceed
any data.
* usart_send_addr() is used to address a receiver. This
receiver should read
* all the following data, until an address packet
addresses someone else.
* Arguments: *usart: Base address of the usart
* addr: the address of the target device
* Returns: USART_SUCCESS if the current mode is RS485
* USART_MODE_FAULT if called while in wrong mode
*/
int usart_send_addr(volatile struct avr32_usart_t * usart, int addr);
/*!
* If the transmitter is ready; write the given character to the TX
buffer
* 'param *usart Base address of the usart
* 'param c The character (up to 9 bits) to transmit
* 'return USART_SUCCESS when the transmitter is ready
* USART_TX_BUSY when the transmitter is busy
*/
@Sab
Deinem Vorschlag folgend, habe ich versucht über die Suchmaschine etwas
in Erfahrung zu bringen: ohne Erfolg.
Hast Du vielleicht eine Quelle beim Hersteller, wo man die erwähnten
"IRQ Vectoren ca 10 Stück" dokumentiert hat. Im Datenblatt des
AT32UC3A... scheinen sie nicht aufgeführt zu sein.
Hab jetzt mal folgendes ausprobiert:
- hab die if else if else Verschachtelungen in der ISR in ganz normale
if if if aufgebrochen
- CSR habe ich in eine Variable eingelesen und diese auf die Int-Flags
geprüft (falls das Lesen destruktiv wirkt)
Und siehe da! Es geht juhu!!!
Welche von beiden Maßnahmen nun geholfen hat, weiss ich nicht (evtl.
sogar beide). Hab jetzt auch kaum Zeit um es herauszufinden. Mal sehen
vielleicht mal in einer etwas ruhigeren Minute. Im Moment bin ich
einfach nur froh, dass es tut.
Danke für die Hinweise, ich hätt mir sonst einen Wolf gesucht
Gruß Willi
Habe Deine Erfolgsmeldung erst heute gelesen - nun ist ja gut!
Ich tippe ja auf das destruktive Lesen des Status. Was mich aber nach
wie vor irritiert, daß es nur einen Interruptvektor für die USART gibt.
Das erinnert doch sehr an 8051 & Co.