Forum: Compiler & IDEs AP7000 und usart


von André S. (rudi400)


Lesenswert?

Hallo zusammen. Ich versuche gerade über den USART meines NGW100 Zeichen 
auszugeben. Doch irgendwie will das nicht so recht funktionieren. Das 
ganze läuft als Standaloneapplikation.
Hiermal der Quellcode:
#ifndef IO_H
#include <avr32\io.h>
#endif
#include <stdint.h>
#define CPUHZ           24576000

int main(int argc, char** argv){
  uint32_t i=0;
  /* PIO Enable Register. Pin-Maske für die Pins, welche durch den
       PIO-Controller gesteuert werden sollen. */

  //UART
        //UART-Reset
    AVR32_USART1.idr = 0xffffffff;
    AVR32_USART1.mr = 0;
    AVR32_USART1.rtor = 0;
    AVR32_USART1.ttgr = 0;
    AVR32_USART1.cr = (1 << AVR32_USART_CR_RSTRX_OFFSET) |
    (1 << AVR32_USART_CR_RSTTX_OFFSET) |
    (1 << AVR32_USART_CR_RSTSTA_OFFSET) |
    (1 << AVR32_USART_CR_RSTIT_OFFSET) |
    (1 << AVR32_USART_CR_RSTNACK_OFFSET) |
    (1 << AVR32_USART_CR_DTRDIS_OFFSET) |
    (1 << AVR32_USART_CR_RTSDIS_OFFSET);
    //Register initialisieren
    AVR32_USART1.mr =0x800008C0;
    AVR32_USART1.cr |= (1<<AVR32_USART_CR_TXEN_OFFSET);
    //PIO-Mask
    AVR32_PIOA.pdr|=(1<<17);
    AVR32_PIOA.pudr|=(1<<17);
    AVR32_PIOA.asr|=(1<<17);
    AVR32_PIOA.pdr|=(1<<18);
    AVR32_PIOA.pudr|=(1<<18);
    AVR32_PIOA.asr|=(1<<18);


  while(1){

    for(i=0;i<1000000;i++);

    AVR32_USART1.thr = 0x00000078;
  }
  return 0;
}
Das ganze soll bei 38400 baud laufen. Jemand eine Idee?

von Simon K. (simon) Benutzerseite


Lesenswert?

> Doch irgendwie will das nicht so recht funktionieren.
Ist das deine Fehlerbeschreibung?

PS: http://www.avrfreaks.net/ hat ein AVR32 Forum.

von André S. (rudi400)


Lesenswert?

Naja, eine richtige Fehlerbeschreibung gibt es nicht. Im Hyperterminal, 
welches ich an den UART-Port angeschlossen habe, werden keine Zeichen 
ausgegeben. Woran kann das liegen?

von Simon K. (simon) Benutzerseite


Lesenswert?

André Schimschar wrote:
> Naja, eine richtige Fehlerbeschreibung gibt es nicht.
Dann solltest du dich damit abfinden können, dass es keine richtige 
Hilfe gibt.

> Im Hyperterminal,
> welches ich an den UART-Port angeschlossen habe, werden keine Zeichen
> ausgegeben. Woran kann das liegen?
Du hast etwas vergessen oder falsch gemacht :P

Mal im Ernst: Entweder du gibst mehr Informationen (Hardwareaufbau, 
kompilierbares Programm, etc..) oder es wird wohl nichts mehr.

Einfach ein bisschen Code reinhauen und andere Leute ans Fehlersuchen 
schicken ist nicht gerade eine beliebte Art der Fehlerbehebung.

von 900ss (900ss)


Lesenswert?

Mit folgendem Codeschnispel läuft eine Standalone-Anwendung auf dem
Grasshopper. Es ist nicht notwendig, den UART zu initialisieren,
das kann die NEWLIB schon.
Du weißt das es für Standalone-Anwendungen eine 2.
Toolchain gibt? Wenn Du alles unter Windows installiert hast, ist
glaube ich, beides (Linux / Standalone) installiert.
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
#include <sys/cpu.h>
5
#include <sys/usart.h>
6
7
//--- Inform the newlib library about the CPU clock   
8
set_cpu_hz(20000000);     // my board is clocked with 20MHz after reset
9
10
//--- setup UART0 one for stdio (e.g. printf....)
11
set_usart_base((void*)AVR32_USART0_ADDRESS);  // init UART driver (set UART0 adress)
12
usart_init(115200);                            // init UART0 with 115200 baud
13
  
14
//--- We are finish to send the world a message
15
  printf("\r\nHello World\r\n");

Viel Spaß

von André S. (rudi400)


Lesenswert?

Wow!
DANKE,DANKE,DANKE!
Gibt es so was einfaches auch für den SPI-Bus???

von 900ss (900ss)


Lesenswert?

André Schimschar wrote:
> Wow!
> DANKE,DANKE,DANKE!

Gerne doch :-)

> Gibt es so was einfaches auch für den SPI-Bus???

Keine Ahnung. Ich habe in den Sourcen der Newlib gegraben, bis
ich das mit dem UART gefunden habe. Es gibt keine Doku.
Die lassen das den Kunden machen. Ist echt Schlamperei.
Das einzige was es gibt, sind die Application-Nores. Die solltest
Du Dir mal ansehen, vielleicht ist das etwas dabei.

von André S. (rudi400)


Lesenswert?

1
#ifndef _IO_H_
2
#include <avr32\io.h>
3
#endif
4
#include <stdint.h>
5
#include <stdio.h>
6
#include <stdlib.h>
7
#include <sys/cpu.h>
8
#include <sys/usart.h>
9
int main(){
10
  set_cpu_hz(20000000);
11
  
12
  set_usart_base((void*) AVR32_USART1_ADDRESS);  
13
  usart_init(115200);
14
  while(1){
15
    printf("Hello");
16
    udelay(1000000);
17
  }
18
  return 0;
19
}
Diesen Quelltext habe ich nun mal getestet. USART1 musste ich nehmen, 
weil dieser derjenige für den Standard RS232-Stecker des ngw100 ist. 
Allerdings empfange ich immer noch keine Signale. Ich habe mal 
nachgemessen, die RX-Leitung des NGW ist 5,56V, und die TX bei 0V. Diese 
Potentiale verändern sich auch nicht. Beim Hyperterminal habe ich 115200 
und 8-N-1 ohne Handshake eingestellt. Liegt es vielleicht auch daran, 
dass mein jtag ice mk II noch angesteckt ist. Ich bin mittlerweile 
ziemlich ratlos...

von 900ss (900ss)


Lesenswert?

Ich kenne das NGW100 leider garnicht.
Womit hast du denn geprüft, ob die Leitungen sich ändern?

Also die Signalzustände sprechen dafür, dass etwas faul ist.
An der RX-Leitung 5V? und an der TX 0V? Das sieht schon ziemlich
falsch aus. Ich vermute es sind Levelkonverter auf dem NGW für die
RS232. Dann sollten die Spannungen genau umgekehrt sein. Die 5V
könnten auch noch mehr sein.

An dem angesteckten JTAG ICE liegt es nicht. Mit dem könntest du
ja sonst kein Programm debuggen.

Wenn Signale bei TX zu sehen sind, ist aber noch nicht sichergestellt,
ob die Baudrate (115200) stimmt, da ich nicht weiß, ob das NGW
nach Reset mit 20MHz läuft. Die Zeile
set_cpu_hz(20000000);
informiert nur die NEWLIB Library, dass die Frequenz so ist.
Die Frequenz der CPU wird damit nicht gesetzt.
Mit diesem Faktor werden dann die Baudratenteiler eingestellt,
wenn du die Baudrate setzt.

Aber du mußt erstmal deine Hardware prüfen. Die Pegel sind nicht OK.
Siehe auch: RS-232 oder
http://de.wikipedia.org/wiki/Rs232

Edit: Habe gerade mal in das Schaltbild des NGW gesehen. Dort ist
ein Level-Konverter (MAX-3232) drauf. Also hast Du wahrscheinlich
beim messen RX/TX vertauscht? Und hast du ein Oszilloskop um zu
messen, dass sich die Signale ändern?
Das Hyperterminal ist richtig eingestellt, wenn denn dein Board mit
20MHz läuft.

von André S. (rudi400)


Lesenswert?

Ein Oszi kann ich erst nächste Woche besorgen. Und wie lege ich jetzt 
den CPU-Takt fest. Wird das in irgendwelchen Registern festgelegt?

von 900ss (900ss)


Lesenswert?

André Schimschar wrote:
> Ein Oszi kann ich erst nächste Woche besorgen. Und wie lege ich jetzt
> den CPU-Takt fest. Wird das in irgendwelchen Registern festgelegt?

Der CPU-Takt ist solange nebensächlich, wie Du die Hardware nicht OK 
hast. Definitiv kann es so nicht funktionieren, da Deine Pegel faul 
sind. Es sei denn Du hast die Namen hier falsch angegeben oder was auch 
immer.
Solange brauchst Du auch kein Oszi, der wird auch nichts anzeigen.

Den CPU-Takt einzustellen muß mittels der PLLs auf der CPU gemacht 
werden. Hab ich auch auch noch nicht gemacht. Du mußt sehen, was für ein 
Quartz an CLK0 Eingang der CPU liegt, ich meine damit ist dann die CPU 
getaktet. Und den Frequenzwert übergibts Du der NEWLIB.

von André S. (rudi400)


Lesenswert?

Juchu, ich hab es nun hinbekommen.
Zuerst habe ich die CPU-Hz auf 20 MHZ gesetzt und das ganze über den 
PLL. Der PLL ist die Quelle der Masterclock. Und den CPU-Takt habe ich 
auf den Masterclock eingestellt.
1
AVR32_PM.pll0        =  (1<<AVR32_PM_PLL0_PLLEN_OFFSET)   
2
                       |(0<<AVR32_PM_PLL0_PLLOSC_OFFSET)
3
                       |(4<<AVR32_PM_PLL0_PLLOPT_OFFSET)
4
                       |(1<<AVR32_PM_PLL0_PLLDIV_OFFSET)
5
                       |(1<<AVR32_PM_PLL0_PLLMUL_OFFSET)
6
                       |(16<<AVR32_PM_PLL0_PLLCOUNT_OFFSET);
7
  while (AVR32_PM.ISR.lock0 == 0);
8
  AVR32_PM.mcctrl      = 1<<AVR32_PM_MCCTRL_PLLSEL_OFFSET;
9
  AVR32_PM.cksel=0x00000000;
Das ganze habe ich mit udelay überprüft.
Danach habe ich die einzelnen Register fürs USART1 eingestellt.
1
AVR32_USART1.idr = 0xFFFFffff;
2
  
3
           AVR32_USART1.mr = 0;
4
           AVR32_USART1.rtor = 0;
5
           AVR32_USART1.ttgr = 0;
6
  
7
           AVR32_USART1.cr = (1 << AVR32_USART_CR_RSTRX_OFFSET) |
8
                       (1 << AVR32_USART_CR_RSTTX_OFFSET) |
9
                       (1 << AVR32_USART_CR_RSTSTA_OFFSET) |
10
                      (1 << AVR32_USART_CR_RSTIT_OFFSET) |
11
                      (1 << AVR32_USART_CR_RSTNACK_OFFSET) |
12
                       (1 << AVR32_USART_CR_DTRDIS_OFFSET) |
13
                       (1 << AVR32_USART_CR_RTSDIS_OFFSET);
14
           if ( baudrate < (cpu_hz/16)  ){
15
                           /* Use 8x oversampling */
16
                   AVR32_USART1.mr |= (1<<AVR32_USART_MR_OVER_OFFSET);
17
                           cd = cpu_hz / (8*baudrate);
18
           
19
                           
20
                           AVR32_USART1.brgr = (cd << AVR32_USART_BRGR_CD_OFFSET);
21
                  } else {
22
                          /* Use 16x oversampling */
23
                    AVR32_USART1.mr &= ~(1<<AVR32_USART_MR_OVER_OFFSET);
24
                            cd =  cpu_hz / (16*baudrate);
25
            
26
                           
27
                   }
28
           AVR32_USART1.brgr = (cd << AVR32_USART_BRGR_CD_OFFSET);
29
           
30
           AVR32_USART1.mr |=  ((charlength-5) << AVR32_USART_MR_CHRL_OFFSET);
31
           AVR32_USART1.mr |= (0 << AVR32_USART_MR_CHMODE_OFFSET) | (4 << AVR32_USART_MR_PAR_OFFSET);
32
           AVR32_USART1.mr |= (0 << AVR32_USART_MR_NBSTOP_OFFSET);
33
           AVR32_USART1.cr |= (1<<AVR32_USART_CR_TXEN_OFFSET) | (1<<AVR32_USART_CR_RXEN_OFFSET);
34
           AVR32_PIOA.pdr |= ( 1<<17 );
35
           AVR32_PIOA.pdr |= ( 1<<18 );
36
           AVR32_PIOA.pudr |= ( 1<<17 );
37
           AVR32_PIOA.pudr |= ( 1<<18 );
38
           AVR32_PIOA.asr |= ( 1<<17 );
39
           AVR32_PIOA.asr |= ( 1<<18 );
40
           if ((AVR32_USART1.csr & (1<<AVR32_USART_CSR_TXRDY_OFFSET)) != 0) {
41
                         AVR32_USART1.thr = 0x00000000;}
Anschließend konnte ich einzelne Zeichen ausgeben.
1
if ((AVR32_USART1.csr & (1<<AVR32_USART_CSR_TXRDY_OFFSET)) != 0) {
2
                         AVR32_USART1.thr |= 0x58;}
Und dann funktioniert plötzlich auch:
1
set_cpu_hz(20000000);
2
             
3
           set_usart_base((void*) AVR32_USART1_ADDRESS);  
4
           usart_init(115200);
5
printf("Hello");
Ich hoffe, dass dies jemanden weiterhilft...

von Tip (Gast)


Lesenswert?

Na meinen Glückwunsch :-)
Wie sieht es mit den Pegeln aus?

> nachgemessen, die RX-Leitung des NGW ist 5,56V, und die TX bei 0V. Diese

Hattest Du Dich da vertan? Und wo hattest Du gemessen?
Würde mich mal interessieren. Die Pegel sprechen wie gesagt für falsches 
messen. Der Empfänger sollte keine Spannung haben (RX).

Funktioniert es auch, wenn Du folgendes machst?
1) Init. PLL mit 20MHz
2) set_cpu_hz(20000000);
3) set_usart_base((void*) AVR32_USART1_ADDRESS);
4) usart_init(115200);
5) printf("Hello");

Ich denke, dass geholfen hat, die PLL zu initialisieren. Darum geht es 
dann später auch mit der Aufrufen 2-5 hier oben.
Wenn das nicht geht, hat die NEWLIB von ATMEL!! wohl einen Bug bzw. hast 
Du auch die neuesten Versionen der Toolchain?

von André S. (rudi400)


Lesenswert?

Genau, hatte RX und TX vertauscht, auch den - und + Pol hatte ich beim 
messen verdreht...

von Tip (Gast)


Lesenswert?

Ja wer mißt mißt Mist ;-)

Hast Du noch die Sequenz aus meinem letzten Posting probiert?
Sieht etwas eleganter aus :-)
Aber denke ich, damit sollte es auch gehen.

Aber eigentlich sollte es auch funktionieren, ohne die PLL zu
initialisieren. Sie läuft nach Reset mit Defaulteinstellungen
und das sollte der 1. Quartz für Clock am AVR32 sein. Diese
Frequenz übergibts Du dann set_cpu_hz().

von André S. (rudi400)


Lesenswert?

Ohne die PLL Sequenz gehts, aber nicht ohne die lange 
USART-Initialisierung. Komisch, oder?

von 900ss (900ss)


Lesenswert?

Ja das finde ich auch sehr komisch. Dann fehlt der usart_init()  wohl 
etwas. Nur merkwürdig, dass es bei dem Grasshopper funktioniert. Das 
will mir so garnicht in den Kopf.

Aber ich kann das so schnell auch nicht überblicken, dafür kenne ich die 
UART-Register nicht. Müßte man mal das Datenblatt ansehen und auch den 
Source der usart_init(). Dann wird man sicher schlauer.

Danke für die Info, fand ich auch interessant.

von kingloui (Gast)


Lesenswert?

hi, könntest du mal deinen kompletten c code hochladen?
Würde das gern mal ausprobiere ob das auch als linux excutable projekt 
funktioniert.
Wenn jemand sagt das funktioniert net dann würde ich gern wissen wie das 
als linux executable funktioniert.

Mfg

von ... (Gast)


Lesenswert?

Nekrophil? Wieso fledderst Du hier 2 Jahre alte Leichen.

Das wird als linux-executeable definitiv nicht funktionieren, da Du da 
keinen direkten Zugriff auf die Hardware hast. Dafür ist schließlich der 
Kernel samt passende Treiber zuständig.
Und wenn Du in Google mal "linux serial port" eingibst, findest Du mehr 
darüber als Du wahrscheinlich jemals lesen kannst.

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.