Hallo liebe Forenmitglieder, ich habe ein kleines Problem mit einem AVR32 UC3A1512. Ich habe zuvor ein NOKIA6610 Display mit einem Atmega16 über SOFT SPI angesteuert. Da der Bildaufbau mit 16MHz nicht schnell genug war, dacht ich mir ich nehm einen AVR32 mit 60MHz. Das Programm läuft bereits erfolgreich auf dem AVR32. Nur die Geschwindigkeit vom Bildaufbau hat Schneckentempo und ist damit sogar noch langsamer als der Atmega16. Ich bin ich Sachen AVR32 Studio noch sehr neu auf dem Gebiet. Kannst mir jemand sagen, wie ich die Taktrate des UC3A1512 erhöhe? Ich glaube nämlich nicht, dass der im Moment auf 60MHz läuft. mfg Sebastian
Hi, Also wenn du dich um die PLL noch nicht gekümmert hast, dann läuft dein AVR32 auf ka 125khz. Wenn du die CPU einstellen willst schau dir das mal an: Beitrag "Re: AVR32 EVK1100 PWM Beispiel" Gruß Zippi
Danke für deine Hilfe! Der Code aus dem Beitrag funktioniert. Bin glücklich :-)
OK, Mal ne frage zu dem Display, hast du ihn auch via Software SPI angesteuert? Wenn ja, solltest du dir mal die normalen SPI anschauen. Dann bekommst du es auch noch ca. 4x so schnell hin. Wenn du dann noch DMA machst, kann die nichts mehr bremsen ;). Gruß Zippi
Ja im Moment nutze ich noch SOFT SPI. Hab auch schon gemerkt, dass da einfach die Grenze erreicht ist. Ich versuche die nächsten Tage mal den HARD SPI aus. Hast du zufällig Erfahrung mit dem NOKIA 6100 oder 6610 Display? Wenn du da ein Stück Beispielcode für den HARD SPI bzw. DMA hast, wäre das echt super. mfg Sebastian
Eine Frage habe ich noch. Ich habe den Controller jetzt laut der Routine aus dem Beitrag: "Re: AVR32 EVK1100 PWM Beispiel" auf 66 MHz eingestellt. Lustigerweise kann ich beim SOFT SPI keinen Geschwindigkeitsunterschied zwischen dem Atmega16 mit 16MHz und dem UC3 mit 66 MHz feststellen. Bei beiden ist der Bildaufbau am Nokia Display gleich schnell. Das kann doch eigentlich nicht sein oder? Habe ich den UC3 dann doch nicht auf 66 MHz? Oder ist da einfach eine Begrenzung der Geschwindigkeit, wenn ich das mit Pingewackle mache?
Hi, also mit den Einstellungen befinder der sich schon auf 66Mhz(achja der code ist von mir). Ein großes Problem ist die GPIO geschwindigkeit. Die sind langsamer als beim ATmega. Desweiteren kannst du auch mal die optimierung anschalten vom avr32 studio. Ich hab es damals mit einem S65 display gemacht. Anfangs lief das auch alles schleppent mit software spi etc. Aber am Ende konnte ich aber mit unter 500000 cyclen das display neu schreiben. Somit konnte ich bei 66Mhz mehr als 130Fps erreichen(was natürlich kein sinn macht, da das display ja ne wiederholungsrate von ca. 60hz hat). Durch DMA hat es dabei aber natürlich keine Rechenzeit verschwendet. Und dann kann man auch sowas machen: http://www.youtube.com/watch?v=Lzbz_tU4f3g Also versuch erstmal Hardware SPI ans laufen zu bekommen. Und DMA dann einzufügen ist ein Kinderspiel. Gruß Zippi
Hi Zippi, dein Video kenn ich schon und hat mich schwer beeindruckt! Ich hab jetzt beim Atmega16 den Hard SPI hinbekommen und der Unterschied ist enorm! Der Atmega läuft auf 16MHz und der SPI kann maximal Clock/2. Würde das gerne noch schneller hinbekommen aber es scheint so als wäre der Atmega16 da am Ende. Ich versuche jetzt den Hard SPI am AVR32. Leider hab ich noch kein Beispiel dafür gefunden. Hast du da eventuell was für mich? z.b. -Initialisierung SPI -Ein/Ausschalten SPI -Senden SPI mfg Sebastian
Hi, Hier ist mal meine Display init:
1 | void display_lcd_init() |
2 | {
|
3 | |
4 | //*************************************************************
|
5 | //**************DISPLAY POWER INIT*****************************
|
6 | //*************************************************************
|
7 | |
8 | |
9 | AVR32_GPIO.port[0].oders = 1 << 11; // The output driver is enabled for the corresponding pin |
10 | AVR32_GPIO.port[0].gpers = 1 << 11; // Set GPIO PA11 to output |
11 | |
12 | AVR32_GPIO.port[0].ovrc = 1 << 11; // Display power on. |
13 | |
14 | //*************************************************************
|
15 | //**************DISPLAY SPI INIT*******************************
|
16 | //*************************************************************
|
17 | |
18 | AVR32_SPI0.mr = 1 << AVR32_SPI_MR_MSTR_OFFSET | // SPI0 mode 0 = slave 1 = master |
19 | 1 << AVR32_SPI_MR_MODFDIS_OFFSET ; // SPI0 mode fault detection 0 = enable 1 = disable |
20 | |
21 | |
22 | int csr = 0 << AVR32_SPI_CSR0_CPOL_OFFSET | // inactive clock is 0; |
23 | 1 << AVR32_SPI_CSR0_NCPHA_OFFSET | // Active Edge == rising |
24 | 0 << AVR32_SPI_CSR0_CSAAT_OFFSET | // deselect device |
25 | 8 << AVR32_SPI_CSR0_BITS_OFFSET | // (BITS+8)Bits per transfer |
26 | 2 << AVR32_SPI_CSR0_SCBR_OFFSET | // clk == MCLK / scbr; |
27 | 0 << AVR32_SPI_CSR0_DLYBS_OFFSET | // 0 = 1 clk delay when chip selected |
28 | 0 << AVR32_SPI_CSR0_DLYBCT_OFFSET; // 0 = No delay between 2 transfers.AVR32_SPI.csr0 = csr; |
29 | |
30 | AVR32_SPI0.csr0 = csr; |
31 | AVR32_SPI0.csr1 = csr; |
32 | AVR32_SPI0.csr2 = csr; |
33 | AVR32_SPI0.csr3 = csr; |
34 | |
35 | AVR32_SPI0.cr = AVR32_SPI_CR_SPIEN_MASK; // Enable SPI0 |
36 | |
37 | while((AVR32_SPI0.sr & AVR32_SPI_SR_SPIENS_MASK)!= AVR32_SPI_SR_SPIENS_MASK); // Wait for enable status |
38 | |
39 | //*************************************************************
|
40 | //**************DISPLAY DMA INIT*******************************
|
41 | //*************************************************************
|
42 | |
43 | AVR32_PDCA.channel[0].cr = 1 << AVR32_PDCA_CR_TDIS_OFFSET ; // Disable transfer |
44 | |
45 | |
46 | AVR32_PDCA.channel[0].mar = 0; // DMA address |
47 | AVR32_PDCA.channel[0].psr = 15; // PID SPI0 = 15 |
48 | AVR32_PDCA.channel[0].tcr = 0; // DMA Counter |
49 | |
50 | AVR32_PDCA.channel[0].marr = 0; // DMA reload address |
51 | AVR32_PDCA.channel[0].tcrr = 0; // DMA reload counter |
52 | |
53 | AVR32_PDCA.channel[0].mr = 1; // PDCA Mode (byte(0)/Half-Word(1)/Word(2)) |
54 | |
55 | //********Interrupt settings********
|
56 | |
57 | AVR32_PDCA.channel[0].ier = // Interrupt Enable Register |
58 | 0 << AVR32_PDCA_IER_RCZ_OFFSET | // Reload counter zero interrupt |
59 | 0 << AVR32_PDCA_IER_TRC_OFFSET | // Transfer complete interrupt |
60 | 0 << AVR32_PDCA_IER_TERR_OFFSET; // Transfer error interrupt |
61 | |
62 | |
63 | AVR32_PDCA.channel[0].idr = // Interrupt Disable Register |
64 | 1 << AVR32_PDCA_IDR_RCZ_OFFSET | // Reload counter zero interrupt |
65 | 1 << AVR32_PDCA_IDR_TRC_OFFSET | // Transfer complete interrupt |
66 | 1 << AVR32_PDCA_IDR_TERR_OFFSET; // Transfer error interrupt |
67 | |
68 | //****************Hardware init ready****************************
|
69 | |
70 | AVR32_GPIO.port[0].oders = CLK | RESET | SELECT | COMMAND | DATA; // The output driver is enabled for the corresponding pin |
71 | AVR32_GPIO.port[0].gpers = CLK | RESET | SELECT | COMMAND | DATA; // The GPIO controls the corresponding pin |
72 | |
73 | AVR32_GPIO.port[0].gperc = DACL; |
74 | |
75 | wait_us(50000); |
76 | |
77 | AVR32_GPIO.port[0].ovrc = RESET; // RESET 4 times |
78 | wait_us(50000); |
79 | AVR32_GPIO.port[0].ovrs = RESET; |
80 | wait_us(50000); |
81 | AVR32_GPIO.port[0].ovrc = RESET; |
82 | wait_us(50000); |
83 | AVR32_GPIO.port[0].ovrs = RESET; |
84 | wait_us(50000); |
85 | |
86 | display_send_16bit( &init_data[0], 1); |
87 | wait_us(50000); //Wait ca. 50ms |
88 | display_send_16bit( &init_data[1], 10); |
89 | wait_us(50000); //Wait ca. 50ms |
90 | display_send_16bit( &init_data[11], 21); |
91 | wait_us(50000); //Wait ca. 50ms |
92 | display_send_16bit( &init_data[32], 2); |
93 | wait_us(50000); //Wait ca. 50ms |
94 | |
95 | AVR32_GPIO.port[0].ovrs = SELECT; |
96 | |
97 | api.clear(0xffff); |
98 | display_send_data((int)&vram->savarray[0],0); |
99 | }
|
Und dann noch die SPI 16bit sende funktion:
1 | void display_send_data(int ramadd, char power) |
2 | {
|
3 | AVR32_GPIO.port[0].ovrc = SELECT; |
4 | asm("nop"); |
5 | AVR32_GPIO.port[0].ovrs = COMMAND; |
6 | |
7 | display_send_window( windowdata, 6); |
8 | |
9 | AVR32_GPIO.port[0].ovrc = COMMAND; |
10 | |
11 | AVR32_PDCA.channel[0].tcr = 23232; // DMA Counter |
12 | AVR32_PDCA.channel[0].mar = ramadd; // DMA address |
13 | |
14 | AVR32_PDCA.channel[0].cr = 1 << AVR32_PDCA_CR_TEN_OFFSET ; // Enable transfer |
15 | |
16 | // *****************************************
|
17 | display_freetime(power); |
18 | |
19 | //******************************************
|
20 | displayrunning = 0; |
21 | while(AVR32_PDCA.channel[0].tcr) |
22 | displayrunning++; |
23 | |
24 | wait_us(0); |
25 | AVR32_PDCA.channel[0].cr = 1 << AVR32_PDCA_CR_TDIS_OFFSET ; // Disable transfer |
26 | AVR32_GPIO.port[0].ovrs = SELECT; |
27 | }
|
Die Übertragung ist hier mit DMA. Das CS Signal für das Display(SPI-Slave) wurde mit GPIO erzeugt. SPIclk = MCLK/2. Kannst es auch auf SPIclk = MCLK stellen(Ich glaube das ist dann aber nicht mehr spezifisch, hat bei mir trozdem fehlerfrei funktioniert). Gruß Zippi
Danke für den Code! Ich werds bei Gelegenheit ausprobieren. Aber ich verstehe das alles nicht so ganz. Eigentlich müsste doch der Atmega16 mit Hard SPI ausreichen! Im Nokia Handy ist ja sicher auch kein Highend Microcontroller für das Display verbaut. Zeichne ich einfach nur ein blaues Bild, so muss ich die 132x132 Pixel in einer Schleife durchlaufen. Also 17424 Pixel x 12 Bit Farbwert ergibt doch 25,5 KB/s. Das muss ich hinsenden um einen Bildaufbau hinzubekommen. Der Hard SPI ist auf 8MHz. Somit sollte es doch kein Problem sein, 24mal in der Sekunde ein farbiges bild zu malen, oder? Hier ein Video von meinem jetzigen stand. http://www.youtube.com/watch?v=oJieMCGs3S8 Im Video zeichne ich hintereinander ohne Pause eine grünes,blaues,rotes Bild mit Hard SPI. In der ersten Hälfte des Videos ist es schon recht schnell. Im zweiten Teil habe ich im Avr Studio die Optimization auf -O3 gestellt. Jetzt läuft der Bildaufbau schneller. Aber ich habe immer noch das Gefühl, dass ich so nie 24 fps schaffe. Vielleicht bremse ich den Controller auch aus, da ich vor jedem Command oder Data Senden dem Display mitteilen muss (per CS,CLK,DATA) ob ich jetzt ein Command oder Daten sende. Um ihm das Anzuzeigen, schalte ich den Hard SPI kurz aus, wackle an den Pins und schalte ihn dann wieder zum Übertragen des 12Bit Farbwertes wieder ein. Ich brauch noch Tipps, was ich verbessern könnte. mfg Sebastian
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.