Ich kopiere einfach mal meinen Beitrag aus dem Polo 9N . Info Forum hier rein, vieleicht hilft es jemandem.
@OP: wie hast Du die einzelnen Pixel ansteuern können? Beim Polo gibt es im Navi-Zeichensatz zwar einen Punkt, doch dann wäre beim Beschreiben des Displays die BUS Last sehr hoch und der Bildaufbau sehr langsam
So sieht das nacher auf dem LCD aus:
https://www.youtube.com/watch?v=eoAqhVP7CjE
Ein CAN Logger und Versuche im Auto sind unerlässlich, um sich in die Materie einarbeiten zu können. Dieses Tutorial ist eine Hilfestellung, um die auf dem CAN vorhandenen Telegramme bezüglich des Transportprotokolls, des Displaydatenprotokolls und des OSEK Heartbeat Rings zu verstehen.
Um an das MFA Display Daten senden zu können, muss man in erster Linie das Transport Protokoll 1.6 verstehen. Das Display Datenprotokoll wird nämlich mit Hilfe von Nutzdatennachrichten übertragen. Ursprünglich wird das TP 1.6 zum Übertragen von Diagnosedaten zwischen Gateway und Steuergerät genutzt, da die K-Line entfiel.
Ich versuche das TP 1.6 Tutorial so allgemein wie möglich zu halten, werde es aber dennoch mit den Teilnehmern Tacho und Radio erklären.
[size=150]
Transport Protokoll 1.6[/size]
Grundlegender Ablauf der Kommunikation bei TP 1.6:
1. Aufbau eines Kommunikationskanals mit dem Aushandeln der Kommunikations IDs
2. Austauschen von protokollbedingten Daten z.B. Timingwerte (Schon ab hier mit den ausgehandelten Kommunikations IDs)
3. Senden von Nutzdaten
4. Richtungswechsel
5. Empfangen von Nutzdaten
6. Richtungswechsel oder Beendigung der Kommunikation
// Im Falle der Beendigung ist hier schluss, bei Richtungswechsel allerdings nicht!
7. Senden von Nutzdaten
8. Richtungswechsel
9. USW....
[size=150]
Aufbau des Kommunikationskanals[/size]
Wenn das Radio beginnt:
1. Radio frägt an
2. Tacho antwortet
Wenn Tacho beginnt:
1. Tacho frägt an
2. Radio antwortet
Die Nachricht für Anfrage und Antwort ist 3 Datenbytes groß und besteht aus CAN ID (AAA), Geräte ID des Steuergerätes mit dem kommuniziert werden soll (BB),
OP Code (CC), Die später gewünschte eigene Kommunikations ID (DD)
0xAAA 0xBB 0xCC 0xDD
Der 1. Schritt ist CAN Identifier (AAA).
Jeder Teilnehmer hat eine Basis ID und eine Geräte ID.
Die Basis ID des Radios ist
0x4A0
Die Geräte ID des Radios ist
0x36 oder
0x39. Beides ist später möglich, ich gehe nun weiterhin von
0x36 aus.
Die Basis ID des Tachos ist
0x2E0
Die Geräte ID des Tachos ist
0x08.
Um den Identifier für die Anfrage zu erhalten, addiert man Basis ID und Geräte ID:
Radio =
0x4D6
Tacho =
0x2E8
Der 2. Schritt ist der OP Code (CC)
Es gibt 3 Möglichkeiten:
0xC0 = Anfrage
0xD0 = Antwort
0xD8 = Ablehnen der Kommunikation
Der 3. Schritt ist die Kommunikations ID (DD)
Sie errechnet sich aus der Basis
0x600 + Geräte ID Radio
0x36 + eines Gerätespezifischen Offsets Tacho
0x60, Radio
0x80, jeh nach dem wer die Nachricht sendet.
Man verrechnet an dieser Stelle die Geräte ID des Radios, da mehrere Teilnehmer gleichzeitig einen TP Kanal zum Tacho geöffnet haben können.
Daraus resultieren die Kommunikation IDs:
Tacho:
0x696
Radio:
0x6B6
Da die Basis von
0x600 anscheinend offensichtlich ist, wird jeweils nur das niederwertige Byte übertragen, d.h. für das Radio
0xB6 und für den Tacho
0x96.
Nun ein Beispiel zu einem kompletten Kommunikationsablauf
bei dem das Radio die Kommunikation aufbaut:
0x4D6 0x08 0xC0 0xB6
0x2E8 0x36 0xD0 0x96
bei dem der Tacho die Kommunikation aufbaut:
0x2E8 0x36 0xC0 0x96
0x4D6 0x08 0xD0 0xB6
[size=150]
Austauschen von protokollbedingten Daten[/size]
Soweit so gut, Die Kommunikation ist aufgebaut, die Identifier für weitere Übertragungen ausgehandelt (
0xB6 und
0x96 )
Nun werden protokollbedingte Daten ausgetauscht, wie Blockgröße ( Wird später erläutert ) und Timingwerte.
Wenn das Radio die Kommunikation initiierte:
1. Radio sendet protokollbedingte Daten
2. Tacho antwortet mit protokollbedingten Daten
Wenn der Tacho die Kommunikation initiiert hat, ist das Ganze genau andersrum.
Die Nachricht dafür ist 6 Datenbytes groß und besteht aus CAN ID (AAA), OP Code (BB), Blockgröße (CC) und den Timingwerten (T0 - T3)
0xAAA 0xBB 0xCC 0xT0 0xT1 0xT2 0xT3
Der 1. Schritt ist die CAN ID (AAA)
Ab hier werden bis zur Beendigung/Quittierung des TP Kanals die Kommunikations IDs der sendenden Teilnehmer verwendet.
Wenn das Radio die Nachricht sendet:
0x6B6
Der Tacho:
0x696
Der 2. Schritt ist der OP Code (BB)
Hier gibt es 2 Möglichkeiten:
0xA0 = Anfrage
0xA1 = Antwort
Der 3. Schritt ist die Blockgröße (CC)
Die Blockgröße gibt an, ab wieviel gesendeten Nutzdatennachrichten ein Acknowledge erwartet wird. Dazu später mehr.
Der Wertebereich liegt zwischen
0x01 und 0x0F
Der 4. Schritt sind Timingwerte (T0 - T3)
T0: Maximale Zeit zwischen zwei Nachrichten (Bei überschreiten erfolgt Quittierung)
T1: Maximale Zeit zwischen zwei Blöcken
T2: Minimalste Zeit zwischen zwei Nachrichten
T3: Maximale Zeit in der als Empfänger Telegramme erwartet werden
Jedes Timingbyte besteht aus einem 2 Bit Prescaler und einem 6 Bit Multiplikator.
( PRESC1 | PRESC0 | MUL5 | MUL4 | ... | MUL0 )
Prescalerwerte:
00 = 100 µS
01 = 1 mS
10 = 10 mS
11 = 100 mS
Multiplikatorwerte:
0x00 - 0x3F
Der Prescaler wird einfach mit dem Multiplikator multipliziert... wie der Name schon sagt
Nun ein Beispiel für den Kommunikationsablauf
wenn das Radio die Kommunikation initiierte:
0x6B6 0xA0 0x04 0x82 0x84 0x46 0xC5
0x696 0xA1 0x04 0x8A 0x85 0x43 0x94
wenn der Tacho die Kommunikation initiierte:
0x696 0xA0 0x04 0x8A 0x85 0x43 0x94
0x6B6 0xA1 0x04 0x82 0x84 0x46 0xC5
[size=150]
Senden von Nutzdaten[/size]
Eine Nutzdatennachricht ist 1 - 8 Datenbytes groß und besteht aus der CAN ID (AAA), dem Kontrollbyte (BB) und den Nutzdatenbytes (D0 - D6)
0xAAA 0xBB 0xD0 0xD1 0xD2 0xD3 0xD4 0xD5 0xD6
Der 1. Schritt ist die CAN ID (AAA)
Hier werden wieder die Kommunikations IDs verwendet (0x6B6 und 0x696).
Der 2. Schritt ist das Kontrollbyte (BB)
Hier wird es komplizierter, da dieses Byte einen großen Teil des TP 1.6 beinhaltet.
Die einelnen Bits des Bytes:
( NV | NV | /ACK ANFORDERN | RICHTUNGSWECHSEL | ZÄHLERBITS 3 - 0 )
Bit 7 und 6 sind nicht verwendet.
Bit 5 ist 0-Aktiv. Ist dieses "LOW" schickt der Empfänger ein Acknowledgement.
Bit 4 ist 1-Aktiv. Ist dieses "HIGH" so wird ein Richtungswechsel erzwungen und der Empfänger fängt an Daten zu senden.
Das Lownipple (Bit 3 - 0) des Kontrollbytes wird mit jeder verschickten Nachricht inkementiert. Bei einem Überlauf (> 0xf) geht es einfach wieder bei 0x0 weiter.
Nach einem Richtungswechsel geht es ebenfalls wieder mit 0x0 weiter.
Die Acknowledgement Botschaft ist 1 Byte lang und besteht aus CAN ID (AAA) und der eigentlichen ACK Botschaft (BB).
0xAAA 0xBB
Der 1. Schritt ist die CAN ID (AAA)
Hier werden wieder die Kommunikations IDs verwendet (0x6B6 und 0x696).
Der 2. Schritt ist die ACK Botschaft (BB)
Das Highnipple ist immer
0xB
Das Lownipple inkrementiert mit jeder bereits erhaltenen Nutzdatennachricht.
Nun habe ich die richtige Stelle erreicht um das Thema mit den "Blöcken" anzuschneiden. Ein Block besteht aus einer gewissen Anzahl von Nutzdatennachrichten.
Diese Anzahl wird wie schon beschrieben, beim Austausch von protokollbedingten Daten festgelegt. In Falle meines Beispiels oben ist ein Block 4 Nutzdatennachrichten groß.
Das heißt: Bei jeder 4. Nutzdatennachricht wird Bit 5 des Kontrollbytes "LOW" und der Empfänger schickt eine ACK Nachricht. Wird ein Block nicht voll ( Nur 1 - 3 Nutzdatennachrichten ),
so sendet der Empfänger das letzte Acknowledgement beim Richtungswechsel.
Nach dem Richtungswechsel sendet der ursprüngliche Empfänger (wird zum Sender) seine Daten nach dem gleichen Schema.
Nachdem ein Richtungswechsel stattgefunden hat und der nun sendende Teilnehmer keine Daten zum Senden hat, Quittiert der Teilnehmer die Kommunikation.
Die Quittierungsbotschaft ist 1 Byte lang und besteht aus CAN ID (AAA) und dem OP Code (BB).
0xAAA 0xBB
Der 1. Schritt ist die CAN ID (AAA)
Hier werden wieder die Kommunikations IDs verwendet (0x6B6 und 0x696).
Der 2. Schritt ist der OP Code (BB)
0xA8 = Quittieren
Ein Beispiel zum Kommunikationsablauf:
0x4D6 0x08 0xC0 0xB6 // Initiieren der Kommunikation
0x2E8 0x39 0xD0 0x96
0x6B6 0xA0 0x04 0x82 0x84 0x46 0xC5 // Austauschen der protokollbezogenen Parameter
0x699 0xA1 0x04 0x8A 0x85 0x43 0x94
0x6B6 0x20 0x00 0x00 0x00 0x00 0x00 0x00 0x00 // Senden von Nutzdaten
0x6B6 0x21 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x6B6 0x22 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x6B6 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 // 4er Block voll, Acknowledgement angefordert
0x696 0xB4 // Acknowledgement: 4 Nutzdatennachrichten erhalten
0x6B6 0x24 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x6B6 0x15 0x00 0x00 0x00 0x00 0x00 0x00 0x00 // Letzte Nutzdatennachricht, Richtungswechsel!
0x696 0xB6 // Acknowledgement: 6 Nutzdatennachrichten erhalten
0x696 0x20 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x696 0x11 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x6B6 0xB2 // Acknowledgement: 2 Nutzdatennachrichten erhalten
0x6B6 0xA8 // Kommunikation quittieren
Hiermit wäre das Transport Protokoll 1.6 erklärt.
[size=150]
Das Display Datenprotokoll:[/size]
Da das DDP Tutorial schon älter ist, wird in den späteren Kommunikationsbeispielen von der Radio Geräte ID 0x39 ausgegangen, nicht mehr von 0x36 wie im TP 1.6 Tutorial.
In den Erklärungen sind die IDs mit "X" allerdings variabel gehalten.
Eine DDP Nachricht wird je nach Länge auf mehrere TP 1.6 Nutzdatennachrichten aufgeteilt.
Das Display ist in 3 Segmente unterteilt. Radioanzeige, MFA/Navianzeige und Ganganzeige. Diese können einzeln oder Barrierefrei genutzt werden, daraus ergeben sich insgesamt 6 mögliche Segmente.
Um nun Text oder Symbole auf dem Display anzuzeigen, muss für jedes verwendete Displaysegment ein Datenkanal geöffnet werden. Jeder Datenkanal hat eine Nummer von 0x00 - 0xFF, diese wird bei der Anmeldung eines Kanals vom Tacho vergeben. Pro Teilnehmer können maximal 3 Kanäle angemeldet werden.
Nachdem für ein Segment ein Datenkanal erstellt und mit der Erstellung konfiguriert wurde, kann dieser Datenkanal beschrieben werden, solange der Tacho diesen freigibt. Ein Datenkanal kann auch in einem gewissen Rahmen nachträglich umkonfiguriert, oder auch gelöscht werden.
[size=150]
OP Codes der DDP Nachrichten[/size]
Das erste Byte deiner DDP Nachricht beinhaltet einen OPcode, der bestimmt, welche Funktion die Nachricht erfüllen soll:
Opcodes Radio / DDP Teilnehmer
0x00 = Löschen aller DDP Kanäle deines DDP Teilnehmers (OP/Geräte ID)
0x01 = Displaysegment-Größe anfordern (OP/Segmentnummer [Erklärung Segmente siehe OP Code 0x02])
0x02 = DDP Kanal anmelden (genaue Beschreibung siehe unten)
0x05 = DDP Kanal abmelden (OP/Kanalnummer)
0x06 = DDP Kanal Menümodus ändern (OP/Kanalnummer/Menümodus [Erklärung Menümodus siehe OP Code 0x02])
0x09 = Daten für DDP Kanal senden (genaue Beschreibung siehe unten)
0x0A = Zum Menüeintrag des Kanals springen (OP/Kanalnummer)
0x0B = Displaysegment wechseln (OP/Kanalnummer/Neues Segment)
0x0C = DDP Kanal priorisieren (OP/Kanalnummer)
0x0D = Alle Kanäle des DDP Teilnehmers löschen (OP/0x00/0x00)
0x15 = DDP Teilnehmer Status senden (OP/Geräte ID/0x20/0x01/Status [0x00 = Aus, 0x01 = Ein])
Opcodes Tacho
0x20 = Alle DDP Kanäle des DDP Teilnehmers gelöscht.
0x21 = Senden von Display-Segmentgrößen (OP/Tachointerne Segmentnummer/0x00/Breite in Pixel High/Breite in Pixel Low/Höhe in Pixel High/Höhe in Pixel Low)
0x23 = Aufforderung zum Senden von Daten für DDP Kanal, Übertragen von Kanal Parametern (OP/Kanalnummer/Kanalstatus [0x00 = gesperrt, 0x01 = Daten erwünscht)
0x25 = Allgemeine Bestätigung
0x27 = Status von DDP Kanal, Übertragen von Kanal Parametern (OP/Kanalnummer/Kanalstatus)
0x2A = DDP Kanal mit Menüeintrag durch Sprung ins Hauptmenü verlassen (OP/Kanalnummer)
0x2B = Fehler (OP/Kanalnummer/Fehlercode)
Fehlercodes:
0x01: Unbekannter Opcode
0x02: Nachricht unvollständig
0x03: Unbekannte Kanalnummer
0x04: Unbekanntes Segment
0x05: Fehler in Displaydaten
0x06: ?
0x07: x Koordinate zu groß fuer Segment
0x08: Y Koordinate zu groß fuer Segment
0x09: Maximum an Kanälen (3) überschritten
0x35 = DDP Teilnehmer abgemeldet (OP)
[size=150]
Anmelden eines Datenkanals[/size]
Ein Datenkanal hat verschiedene Parameter:
- Mit / ohne Menüeintrag und Name
- Displaysegment
Nachrichtenaufbau zur Anmeldung eines Datenkanals:
Header:
Byte 0: OP Code Datenkanal erstellen = 0x02
Nachricht:
Byte 0: Mit Menüeintrag = 0x70, Ohne Menüeintrag = 0x71 - 0x85 (Je niedriger desto höher die Priorität)
Byte 1: Geräte ID = 0x3X
Byte 2: Alle Segmente = 0x00, Mittleres Segment = 0x10, Oberes Segment = 0x20, Unteres Segment = 0x30, Oberes + Mittleres Segment = 0x40, Mittleres + Unteres Segment = 0x50
Byte n: Beschriftung Menüeintrag ASCII (wenn Byte 0 = 0x70)
[size=150]
Beschreiben eines Datenkanals[/size]
Bei jeder Text-/ Grafiknachricht wird die entsprechende Datenkanalnummer mit übertragen.
Nachrichtenaufbau zur Übertragung von Text- / Grafiknachrichten (gesendet von DDP Teilnehmer):
Header:
Byte 0: OP Code Daten für DDP Kanal senden = 0x09
Byte 1: Datenkanalummer
Nachricht:
Byte 0: Charactergröße: 0x57 (Mittlere Character), 0x69 (große Character), 0x55 (kleine Character)
Byte 1: 0x05 + Länge der nach Byte 6 folgenden Zeichenkette
Byte 2 Bit
0: Aktive Pixel des Characters auf Display toggeln
1: Normale Schrift = 1, Invertierte Schrift = 0
2: Schmale Schrift = 1, Normale Schrift = 0
3: Grafikbausteine = 1, Schriftzeichen = 0
4: Große Schriftzeichen = 1, Normale Schriftzeichen = 0
5: Mittenorientiert = 1, Linksorientiert = 0
6: Displayzeile überschreiben = 1, Display komplett löschen = 0
7: Nicht verwendet
Byte 3: X Position in Pixel Low
Byte 4: X Position in Pixel High
Byte 5: Y Position in Pixel Low
Byte 6: Y Position in Pixel High
Byte n: Pfeildaten 0x00 - 0x74, Textdaten ASCII
Byte n
: Abschluss = 0x08
Beispiel:
Die Nachrichten des DDPs werden einfach nacheinander in die 7 Bytes der Nutzdatennachrichten des Transport Protokolls geschrieben.
Eröffnen eines Datenkanals
0x4D9 0x08 0xC0 0xB9
0x2E8 0x39 0xD0 0x99
0x6B9 0xA0 0x04 0x82 0x84 0x46 0xC5
0x699 0xA1 0x04 0x8A 0x85 0x43 0x94
0x6B9 0x20 0x02 0x70 0x39 0x10 0x41 0x42 0x43 // Mit Menüeintrag (0x70) Name: ABCDE, Segment: Mitte (0x10)
0x6B9 0x11 0x44 0x45
0x699 0xB2
0x699 0x10 0x23 0x04 0x01 // Tacho fragt Kanal an, Kanalnummer = 0x04, Tacho möchte Text/Grafikdaten für diesen Kanal.
0x6B9 0xB1
0x6B9 0xA8
Beschreiben des Datenkanals
0x4D9 0x08 0xC0 0xB9
0x2E8 0x39 0xD0 0x99
0x6B9 0xA0 0x04 0x82 0x84 0x46 0xC5
0x699 0xA1 0x04 0x8A 0x85 0x43 0x94
0x6B9 0x20 0x09 0x04 0x57 0x0a 0x02 0x02 0x00 // Kanalnummer = 0x04, Anzahl der zu übertragenden Zeichen = 5, nichtinvertierte Schrift, X Position = 0x02
0x6B9 0x21 0x03 0x00 0x48 0x41 0x4c 0x4c 0x4f // Y Position = 0x03, Text = HALLO
0x6B9 0x12 0x08 // Abschluss
0x699 0xB3
0x699 0x10 0x27 0x04 0x01 // Statusübermittlung, Datenkanalnummer = 0x04, Tacho möchte weiterhin Daten für diesen Kanal.
0x6B9 0xB1
0x6B9 0xA8
Löschen des Datenkanals
0x4D9 0x08 0xC0 0xB9
0x2E8 0x39 0xD0 0x99
0x6B9 0xA0 0x04 0x82 0x84 0x46 0xC5
0x699 0xA1 0x04 0x8A 0x85 0x43 0x94
0x6B9 0x10 0x05 0x04 // Abmelden, Kanalnummer = 0x04
0x699 0xB1
0x699 0x10 0x25 0x04 // Abgemeldet, Kanalnummer = 0x04
0x6B9 0xB1
0x6B9 0xA8
Allgemeine Anmerkung:
Der Tacho hat ein haufen Zeug zu tun. Das Display ist daher die unwichtigste Funktion dieses Steuergeräts (siehe die hohen Identifier der CAN Kommunikation)
Der Tacho benötigt Zeit um Daten zu verarbeiten. Sendet man Datenpakete zu schnell hintereinander, vergisst er einfach mal eine Datenanfrage zu senden oder zeigt die gesendeten Daten einfach nicht an. Also immer mit der Ruhe.
Das Display ist daher nicht für hohe Aktualisierungsraten geeignet.
[size=150]
Der Heartbeat-Ring:[/size]
Die Steuergeräte am Komfort CAN Senden Heartbeatmessages nach einer gewissen Reihenfolge. Ein Steuergerät verweist immer auf das Nächste, das Letzte immer auf das Erste. Ringmaster sind Gateway (Geräte ID 0x00) und Tacho (Geräte ID 0x08).
Unmittelbar nach "Zündung ein" startet das Gateway die Ringinitialisierung. 30ms später beendet der Tacho diese. Innerhalb dieser 30ms sendet jeder verbleibende Ringteilnehmer eine Initialisierungsbotschaft.
Steuergeräte, die sich später in den Ring einbuchen, senden einfach ihre Initialisierungsbotschaft und warten bis ein vorauslaufendes Steuergerät auf sie verweist. Das neue STGR verweist erst einmal auf das Gateway, also 0x00. Falls ein bereits angemeldetes Steuergerät darüber liegt, welches nun übergangen wurde, wird es sich mit einer Neuinitialisierung melden. Auf diese muss das neue Steuergerät hören und beim nächsten Ringdurchlauf dann darauf verweisen.
Die Identifier der Heartbeatmessages bestehen aus der Basis
0x400 addiert mit der Geräte ID.
Im Falle eines DDP Teilnehmers also
0x43X
Die Message besteht aus 6 Bytes.
Das erste Byte enthält bei erkanntem Fehler oder der Anmeldung (also die erste Heartbeatmessage die ein Steuergerät verschickt) die eigene Verweis ID. Bei Geräte ID 0x39 ist die Verweis ID 0x19, bei Geräte ID 0x36 allerdings 0x16.
Byte 0: Verweis ID des nächsten Steuergeräts (
0x00 bis
0x1f) / Bei Anmeldung oder Fehler die eigene.
Byte 1: Eigener Status: 0x01 = Normaler Betriebsmodus; 0x02 = Fehler erkannt; 0x11 = Bereit für Standby; 0x31 = Wenn ein Steuergerät erkennt dass es selbst und alle anderen bereit für den Standby sind, legt dieser Wert den Ring für den Standby lahm. Der Ring wird erst wieder aufgeweckt wenn der Ringmaster 0x400 seine Initialisierungsbotschaft schickt.
Byte 3: 0x00 = Normalmodus; 0x80 = Anmeldung
Der beim Polo zugelassene CAN ID Bereich liegt bei:
0x400 - 0x43F