Hallo *, ich arbeite mit einem Philips 8051 basieredem Controller (Genauer P89LPC921) und muss in diesem einen Ringbuffer realisieren. (Die eigentliche Aufgabe des Controllers besteht darin, 2 Byte Daten von I²C auszuwerten und eine Tastaturausgabe (PS/2-Protokoll) zu erzeugen.) Nun habe ich im Netz schon nach Lösungsansätzen gesucht und habe mich für diesen entschieden: http://www.embeddedrelated.com/groups/piclist/show/2273.php (2. Beitrag) Zum Testen habe ich dann mein Programm so gestaltet, dass ich den Ringbuffer händisch fülle (2 Bytes) und dabei den Counter (ebenfalls händisch) hochzähle. Das Befüllen soll später über einen Interrupt erfolgen. (sollte kein Problem sein) Jedenfalls, nach der manuellen Vorbereitung werte ich den Counter aus, und wenn 2 oder mehr Bytes neu in den Puffer gelegt wurden, so sollen diese Daten über das PS/2 Protokoll verschickt werden. Dabei wird der Counter dann wieder dekrementiert. Nun habe ich das Programm einmal in den Chip gebrannt und nachdem ich das Delay verkürzen wollte, lies sich der Controller nicht mehr beschreiben. Leider verfügt er nur über einen ISP-Modus und nicht über MISO/MOSI Leitungen. D.h. wenn ich den ISP Code überschreibe wird der Controller unbrauchbar. Ich weiß, ich habe bei diesem "Ringbuffer" noch keine Abfrage drin, ob der Buffer nicht grade seine Grenze erreicht hat. Das aber auch nur, weil ich R0 bei jedem Scheifendurchgang neu mit der Startadresse des Ringbuffers fülle (oder zumindest denke das zu tun) und ich damit dachte ein überlaufen auszuschließen. Ist der Quellcode den soweit korrekt, oder gibt es einen Fehler, den ich einfach nicht sehe und der mir dann irgendwie den ISP-Code überschrieben haben könnte? Ich danke vielmals für Tips und Hilfestellungen!!!
Irgendwie hat das mit dem Dateianhang grade nicht geklappt. Neuer Versuch
Ich vergaß zu erwähnen, dass vor der Mainloop natürlich die HEAD und TAIL Variablen initialisiert werden: mov HEAD, #RING_BUF mov TAIL, #RING_BUF mov COUNTER, #0 MainLoop: ...
Magnus wrote: > Nun habe ich das Programm einmal in den Chip gebrannt und nachdem ich > das Delay verkürzen wollte, lies sich der Controller nicht mehr > beschreiben. Ja, man kann sich bei den LPC sehr leicht aussperren. Die haben ja keinen PSEN, wie die 40-Pinner mit dem man den Bootloaderstart erzwingen kann. Man muß also bevor man sich aussperrt eine Backdoor installieren: http://www.8052.com/users/erikm/NoTouch932.phtml Peter
>Leider verfügt er nur über einen ISP-Modus und nicht über MISO/MOSI >Leitungen. D.h. wenn ich den ISP Code überschreibe wird der Controller >unbrauchbar. Benutzt Du FlashMagic zum programmieren? Und welchen Adapter? Die LPC900 sind zwar sehr schnell, haben aber beim programmieren ihre Tücken, kann ich bestätigen. Der Bootloadercode der ISP-Typen (ab LPC920) liegt standardmäßig in den obersten Teil des FLASH. Bei FlashMagic gibt es unter Optionen "Protect ISP Code", dies sollte immer aktiviert werden und verhindert das versehendliche Löschen. Oder man bindet gleich die Bootloader-Quelle mit ein und brennt so jedesmal den ISP-Code mit. Möglicherweise hast Du aber auch den Vector zum starten des Bootloaders umprogrammiert! In der Anlage sind die Quellen des LPC9xx Bootloaders enthalten und ein Bsp. wie man sie einbindet. Ist der ISP Bootloader erstmal gelöscht, hilft nur noch die Programmierung per ICP. Dies kann man auch mit einen 2. ISP-fähigen LPC per ICP-Brigde erfolgen, oder mit einen anderen Programmiergerät. Man kann dann auch den Bootloader wieder draufprogrammieren, wird sich bei den geringen Preis aber kaum lohnen. >Ja, man kann sich bei den LPC sehr leicht aussperren. >Die haben ja keinen PSEN, wie die 40-Pinner mit dem man den >Bootloaderstart erzwingen kann. Der Bootloader der LPC9 wird über 3 kurze Impuls am RST-PIN kurz nach dem Einschalten von VDD gestartet. Geht eigentlich problemlos. Das genaue Timing steht im Datenblatt. Hast Recht, bei den Atmel-Typen mit Bootloader kann man sich nicht ganz so leicht aussperren, da der ISP Code in einem separaten Bereich liegt.
Magnus wrote: > Leider verfügt er nur über einen ISP-Modus und nicht über MISO/MOSI > Leitungen. D.h. wenn ich den ISP Code überschreibe wird der Controller > unbrauchbar. Das ist nicht ganz korrekt. Der P89LPC921 verfügt über einen standard parallelen Programmiermodus sowie über ICP und ISP Programmiermöglichkeiten. Also selbst wenn du den Bootloader versehentlich per ISP überschrieben haben solltest, kannst du den Controller per ICP oder mit einem herkömmlichen Programmiergerät wieder beschreiben und auch den Bootloader wieder reinschreiben. Magnus wrote: > Ich weiß, ich habe bei diesem "Ringbuffer" noch keine Abfrage drin, ob > der Buffer nicht grade seine Grenze erreicht hat. > Das aber auch nur, weil ich R0 bei jedem Scheifendurchgang neu mit der > Startadresse des Ringbuffers fülle (oder zumindest denke das zu tun) und > ich damit dachte ein überlaufen auszuschließen. Ein Ringbuffer hat keine "Grenze", da er die Daten ja im Kreis rotierend beinhaltet. Du kannst höchstens prüfen, ob du den Ringbuffer z.B. komplett ausgelesen hast oder ob er voll ist. In letzterem Fall würden neue Daten eben die ältesten Daten einfach wieder überschreiben.
Hallo! Vielen Dank für eure Antworten. Allgemein: Ich habe das Programm leicht modifiziert, da ich im Debugmodus festgestellt habe, dass mit der TAIL-Zeiger wegläuft, da dieser in der Endlosschleife nicht resettet wird (händisch). Dann bin ich heute Morgen hingegangen und habe den Chip gegen einen anderen ersetzt (so eine kniffelarbeit o_O). Dann habe ich zunächst ein Programm, von dem ich weiß, dass alles funktioniert (einfach eine I²C Master Applikation, die meinem Slave die Daten zuschiebt) eingebrannt (2 mal) und es gab keine Probleme beim "wieder bebrennen". Naja und dann habe ich mein eigentliches SlaveProgramm wieder gebrannt und der Chip lies sich danach erneut NICHT brennen :( Dabei sind beide Sourcen fast identisch, da ich den I²C Master selbst aufgesetzt habe. Wenn ich mir die beiden Dateien in diff ansehe, sind die "großen" Verändergungen (also die neben den Kommentaren) lediglich folgende: Beim I²C Master initialisiere ich lediglich einen Stack
1 | ;**************************************************************** |
2 | ; Stack Pointer einrichten |
3 | ;**************************************************************** |
4 | |
5 | STACK SEGMENT IDATA ;Stack wird im indirekten RAM-Bereich |
6 | RSEG STACK ;eingerichtet |
7 | DS 0AH ;Reservierung von 10 Bytes fuer den Stack |
Beim Slave kommt nach dieser Initialisierung noch die vom Buffer:
1 | ;**************************************************************** |
2 | ; Deklaration des Ringbuffers |
3 | ;**************************************************************** |
4 | INDIREKT_1 SEGMENT IDATA |
5 | RSEG INDIREKT_1 |
6 | |
7 | RING_BUF: DS 20H ; 32 Bytes fuer den Ringpuffer |
8 | |
9 | |
10 | DIREKT_1 SEGMENT DATA |
11 | RSEG DIREKT_1 |
12 | |
13 | HEAD: DS 1 ; HEAD, Zeiger auf letzten empfangenen Wert |
14 | ; im Ringbuffer |
15 | TAIL: DS 1 ; TAIL, Zeiger auf letzten gesendeten Wert |
16 | ; im Ringbuffer |
17 | COUNTER: DS 1 ; COUNTER, Zählervariable für den Buffer |
Da ich mir unsicher war, welche RAM-Segmente/Adressen ich direkt nutzen kann, wollte ich es auf dem indirekten Wege machen, wo der Compiler bestimmt, an welcher Adresse der Stack oder der Buffer oder die Variablen angelegt werden. (Hab beim debuggen auch heraus gefunden, wo sie dann liegen aber ich glaube, dass ist hier nicht wichtig, oder?) Mach ich denn bei dieser Initialisierung irgendwas fatal falsch? Die nächste Abweichung in beiden Programmen ist die Initialisierung der Ports und die MainLoop eben, die oben im ersten Anhang zu finden ist. (Es wurde lediglich das Delay nun verkürzt und zum Beginn der MainLoop HEAD auf die Startadresse vom Buffer gesetzt. Im aktuellen Anhang ist aber die Main auch drin.) So und nun zu den speziellen Antworten: @peda: Genau das ist einem Kollegen mit dem Chip mal passiert, deshalb hatte er mich beim Beginn der Arbeit drauf hingewiesen und mir seinen Source-Code als "Grundlage" zur Verfügung gestellt, in dem diese Abfrage durchgeführt wird. Ich habe sie dann einfach übernommen. Ich hänge dir die Abfrage als Anhang dran. @Matthias: Ja, FlashMagic benutze ich. Der Adapter ist von einem Kollegen zusammengeschreinert speziell für diese Platine und der tut dumm vor sich hin ;) Die Option "Protect ISP Code" hab ich in der "Security" immer eingestellt ;) Das mit dem Vector wäre vllt noch eine Möglichkeit, obwohl ich nicht weiß, ob dass dan was mit dem Anlegen des Speicherbereichs für den Buffer zu tun hat. Im Anhang habe ich den ISP/Nicht-ISP Entscheidungscode und die aktuelle Hauptschleife drin. Wenn du es dir ansiehst, sieht du vielleicht auf Anhieb, was falsch ist, wobei ich denke es richtig gemacht zu haben. @quakeman: Vielen Dank: Wieder was gelernt. Das mit dem ICP ist mir irgendwie komplett entgangen. Mit "Grenze" vom Ringbuffer meinte ich die letzte zu beschreibende Adresse, bevor der Zeiger wieder an die Anfangsadresse springt. Ich werde nun mich wieder ans löten begeben und mal sehen, ob es vllt besser ist die Datensegmente am Anfang irgendwie anders zu initialisieren. Ich habe keine Ahnung, welche Zusammenhänge da sein könnten. Aber er will sich halt einfach nicht programmieren lassen :(...
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.