Ich möchte den 8-bit Datenstrom eines OV7670 per DMA zunächst in den RAM
eines LPC1768 speichern.
Der DMA soll durch pclk, vsync und href gesteuert werden.
Wenn ich das manual richtig verstanden habe, muss ein
Software-Burst-Request ausgelößt werden.
D.h. die CPU wertet vsync, href und pclk aus und schreibt dann in
DMACSoftBreq 1<<9. Der DMA wertet dies dann als Timer0/mach1 und leitet
den Datentransfer von src nach dest ein.
Ist das ungefähr zutreffend?
ich habe jetzt das Beispiel AN10850 - Memory to IOPin - umgesetzt
Erstes Problem: Mir ist nicht klar, wie das Pin-Register dem
DMA-Zielregister DMACCDestAddr zugewiesen wird.
Funktion und Funktionsaufruf in der main:
1
/* extensions for test DMA to FIOPIN */
2
int32_tdma_start_m2pin(int32_tch,
3
void*src,
4
void*dest,
5
DMAC_LL_T*plli,
6
int32_ttrans)
7
{
8
int32_tsts=_ERROR;
9
10
/* Verify that the selected channel has been allocated */
Es wird doch nur der Anfang des Pin-Registers übergeben, woher weiß das
Programm welcher Pin gemeint ist?
Wie ändere ich die DMACCDestAddr so, dass der von mir gewünschte PIn
3.25 blinkt?
Vielen Dank für die breite Unterstützung. Es werden immer ganze 32-bit
Register übertragen. Die Auswahl der Pins geschieht über Transfer Width.
Die LEDs blinken jetzt per DMA.
kleine DMA-Fortschritte. Das Programm überträgt den Registerinhalt
DMA_SRC nach GPIO3-Port und läßt die dort angeschlossenen LEDs blinken.
Request-Quelle ist Timer1 und LPC_GPDMA->DMACSoftSReq=(1<<9):
Danke für die Dokumentation deiner Fortschritte. Auch, wenn keiner
antwortet: Andere sind grade an ähnlicher Stelle oder sind es in einem
Jahr, da kann das immer noch hilfreich sein :)
Ich habe mich gestern endlich dazu durchgerungen, die Non-FIFO-Kamera an
den STM32F103 anzuschließen. Das Verkabeln alleine hat länger als eine
Viertelstunde gedauert. Jetzt muss ich mich nur aufraffen, I2C zu
basteln, XCLK auf PA8 mit Takt versorgen, ... das dürfte noch ein paar
Tage dauern bei mir. Ganz am Ende steht dann auch die Idee, die Daten
per DMA umzuschieben.
Dirk K. schrieb:> Auch, wenn keiner> antwortet
Danke für die aufmunternden Worte. ich befinde mich wohl in der
LPC-Diaspora. Beim Stichwort STM-DSM wird erhält man sicher mehr
Unterstützung. Wahrscheinlich auch beim Stichwort DSM-Bascom - aus
Neugier, Schadenfreude oder Mitleid.
LPCs hat kaum jemand. Dass es DMA gibt, habe ich vor einer Woche nicht
gewusst. LPC-Anwender mit DMA-Kenntnissen sind wohl sehr selten.
Im Prinzip ist es für die Aufgabebstellung OV7670 aber egal, ob man mit
LPC oder Stm arbeitet. Gleicher Arm-Kern und ähnliche Eclipse-Ide. Ich
habe hier noch ein StmF103-board rumliegen, an welches ich mich bislang
nicht herangetraut habe, einfach weil ich mit LPC sehr zufrieden bin.
Vielleicht löte ich dafür aber jetzt den Anschluss an eine
2o-Pin-Streifenrasterplatine zusammen, dann kann die Cam auch an dieses
board.
Jedenfalls lese ich ideinen thread immer mit. Ich denke, wir können uns
bei der Umsetzung der OV7670 Aufgabe gegenseitig unterstützen, da wir
beide das Problem der Umsetzung des parallelen Dateneingangs auf seriell
haben.
Ein kleiner Teilerfolg, das erste brauchbare Foto auf dem Display- noch
auf dem Atmega1284.
Der code ist soweit optimiert, dass mit einem Prescaler 17 (->knapp
1Mhz) alle Pixel gelesen werden können:
statt in den buffer zu schreiben, wird das spi-tft direkt beschrieben.
Das TFT ist im Prinzip ein Speicher mit 240x320x2=153.600byte. Statt des
TFTs könnte man sicher auch andere spi-speicher nehmen.
Die Geschwindigkeit geht jetzt beim 16Mhz-Atmega hoch bis prescaler-12
(ca. 1,5Mhz)
das Programm ließ sich relativ einfach vom avr auf den arm übertragen.
Auch der arm liefert inzwischen ein brauchbares Bild.
Überaschende Erkenntnis: Die Verarbeitungsgeschwindigkeit ist beim
100Mhz-Arm nur halb so groß, wie beim AVR. Unter Prescaler 32 liefert
der Arm kein brauchbares Bild.
Kann es sein, dass die Verarbeitungsgeschwindigkeit des AVR-Spi/Spi-Takt
8Mhz größer ist als beim Arm-SSP/Takt 25Mhz?
Auf meinen stm32f0/1 ist SPI zwar eine Zicke, ich bin jedoch schneller
als auf dem AVR (ATmega328p). Mit 18 MHz SPI erreiche ich im Polling von
der Kamera mit umschalten und neu-adressieren sauber etwa 500 kByte/s.
Das DMA-Initial-Setup compiliert ohne Fehler, jetzt muss ich 'nur noch'
den Transfer darauf umstellen. Sehe noch nicht, wie das klappen soll,
dass der DMA auf PCLK wartet, um das nächste Byte zu übertragen. Aber
kommt langes Wochenende, kommt Rat ;-)
Dirk K. schrieb:> Warten auf PCLK
Meine Überlegung dazu:
pixelweise in einen fifo-buffer schreiben lassen, wenn 512 byte
geschrieben sind, durch einen software-single-request die
DMA-Übertragung auslößen...
Als Problem beim Speichern auf sd-Karte stellte sich heraus, dass eine
gleichzeitige Steuerung des Pixelinputs und des Fat-Überbaus
erforderlich ist. Ich wollte den Pixelinput über Interrupt steuern, das
verlangsamt aber das Programm. Zwischenzeitlich durfte ich beim
Hauptzollamt das AL422-Fifo-Modul abholen.
Das Fifo-Modul läuft inzwischen auf dem Atmega. Der Fifo ist eher
schwieriger zu programmieren, da die Rücksetzung des Speichers nicht
ganz einfach ist. Das Modul läuft mit Prescaler 30=>400khz sehr stabil.
Der Datentransfer erfolgt zur Zeit aber noch innerhalb des vsync-Zyclus,
so dass im Prinzip nur eine Zeile im Fifo zwischengespeichert wird. Das
hat den Vorteil, dass der Code zukünftig für ein Mt9d112-Modul genutzt
werden kann.
Der Durchbruch mit dem Fifo-Modul:
Das Schreiben in den Fifo wird über einen vsync-Interrupt beendet.
Dadurch entfällt die Überwachung der Zeilen beim Lesen des Fifos. Die
write-Geschwindigkeit darf so hoch sein, dass zum Zeitpunkt vsync 50%
des Bildes gelesen sind - der Rest passt in den Fifo. Sie muss höher als
die Lesegeschwindigkeit sein.
Nach Umsetzung im Programm schafft der AVR wahrscheinlich auch das
Schreiben eines vollständigen Bildes in eine sd-Karte. Die bekommt er
als nächsten Schritt verpasst.
Durch das parallele Arbeiten mit AVR und ARM ist darüberhinaus ein für
beide Systeme einsetzbarer Code entstanden.
Das Programm schreibt jetzt QVGA auf die sd-karte. Die Bitmap-Datei wird
nach dem Schreiben geöffnet und in das Lcd eingelesen.
Beim Wechsel auf VGA kommt es zu unerklärlichen Problemen. Dies auch bei
einem Format von 640x120 was eigentlich programmtechnisch keinen
Unterschied zu 320x240 machen dürfte. Die Bilder werden zerstückelt.
Püh, habe ich nicht alleine Probleme mit dem 640x480-Modus - beruhigt
mich zumindest etwas.
Gestern kam meine OV5642 an. Werde wohl die RAM-Bank und die olle OV7670
auf Halde für seeeehr gelangweilte Tage legen und mich langsam mit
SD-Karte auseinandersetzen. Da soll das fertige JPEG aus der Kamera
direkt hin.
Nicht die optimale Lösung, aber die OV7670 raubt mir irgendwie nur die
Nerven ;)
Dirk K. schrieb:> 640x480-Modus
Der ov7670 ist nicht das Problem. Mit
1
#if H_PX==320
2
#define ovregCOM7 0b00010100 //QVGA
3
#else
4
#define ovregCOM7 0b00000100//VGA
5
#endif
kann man zwischen den Formaten schalten.
Es werden rund 420 Zeilen auf dem Lcd einwandfrei angezeigt(jedes
2.Pixel jede 2.Zeile).
Das Problem ist der AL422, der mit meinem code nicht wirklich
zwischenspeichert. Laut Datenblatt braucht er durchgehenden Schreibe-
und Lesetakt von >1Mhz. Das passt mit meinem Code bislang nicht.
Ach siehste, OV7670 mit AL422B habe ich ja auch noch rumfliegen. Der
nächste graue Herbst/Winter kommt bestimmt ... ;)
Kannst du die CLKs für R/W nicht einfach via XCLK abgreifen?
Dirk K. schrieb:> XCLK
das habe ich gerade gemacht - wck mit pck verbunden. Das Problem ist
dass ich jetzt den schnellen Modul-Takt überwachen muss, während ich
bislang die Lesegeschwindigkeit auf die SD-Karte/lcd angepasst hatte.
Wenn ich deine relativ schnellen Speichermodule hätte, wäre ich schon
fertig. Hauptproblem ist die langsame Geschwindigkeit der sd-karte.
Der FIFO soll doch deshalb von Vorteil sein, weil du dir die Bytes
raustaktest, wie es grade passt? Also FIFO-PCK togglen, Byte lesen. Der
Speichertakt ist doch nur RAM Refresh und hat mit der
Ausgabegeschwindigkeit nichts zu tun?
Missverstehe ich am FIFO etwas?
Dirk K. schrieb:> Missverstehe ich am FIFO etwas?
Ich fürchte leider ja. Mein bisheriger code beruhte auf genau dieser
Annahme. Das funktioniert auch, solange man direkt nach dem Schreiben
liest.
zl_hrref =300;
while(zl_hrref);//Zeilen Vorlauf
al422_writeStop();
al422_readStart_cyc();
müsste eigentlich 300 Zeilen in den Fifo laden und dann mit dem Lesen
beginnen. Ein brauchbares Bild bekomme ich aber nur, wenn der Vorlauf
zl_hrref sehr klein ist. D.h. es werden nur wenige Zeilen
zwischengespeichert. Es reicht, um QVGA-Bild auf sd-Karte zu speichern,
mehr nicht.
==>Der Beitrag scheint Spam zu enthalten: "hrref="
Problem bleibt der AL422 Fifo. Er scheint seinen Speicherinhalt zu
verlieren, wenn nicht unmittelbar nach dem Schreiben gelesen wird. Fifo
vollschreiben und dann in Ruhe lesen geht nicht. Laut Datenblatt sollen
beide Taktzyklen kontinuierlich mindestens 1MHZ betragen. Bei 1MHz
W-Clock werden die Bilder jedoch zerstückelt.
Auch der Versuch, W+R-Clock zu verbinden und den Fifo mittels
RClock-Interrupt auszulesen war nicht erfolgreich. Der Fifo funktioniert
nicht wie er soll und ich weiß nicht wirklich woran es liegt.
Immerhin klappt das Speichern auf SD-Karte mit den Teilbildern recht
ordentlich. Ich werde jetzt erst einmal versuchen, das Programm in einen
Webserver zu integrieren.