/********************************************************************************
* DCC Wagen Decoder Software V1.0 *
* Copyright 2011 Toralf Wilhelm *
* *
* private Nutzung erwünscht, gewerbliche Nutzung erfordert zwingend meine Zustimmung! *
* Datei: Programmierung.S *
* Kontakt: toralfwilhelm@web.de *
* Webseite: www.toralfwilhelm.de *
* Version: 04/2012 Version 1 Start *
* Beschreibung: programmiert die CV Register der DCC Wagen Decoder Software *
********************************************************************************/
#include "definitionen.h"
CV_edit:
mov w,byteB // w mit Befehlsbyte laden
mov w2,byteC // w2 mit CV Nummer laden
mov w3,byteD // w3 mit CV Daten laden
mov w4,byteE // w4 mit Prüfbyte laden
cbr flag,(1<<neuerBefehl) // Daten gesichert Empfangsspeicher wieder freigeben
cbr w,0b00000011 // adressbits ausblenden nur die ersten 256 CV werden verwendet/benötigt
cpi w,0b11101100 // Befehlsbyte auf CV Byte schreiben testen
breq CV_schreibe_Byte // gehe zu CV Byte schreiben
cpi w,0b11100100
breq CV_vergleiche_Byte // gehe zu CV Byte vergleichen
cpi w,0b11101000
breq CV_manipuliere_Bit // gehe zu CV Bit Manipulation
ret // wenn nicht zurück
CV_schreibe_Byte:
lds w,ProgTest // vergleiche mit vorherigen Daten (XOR-Byte)
cp w,w4 // mit Prüfbyte vergleichen
breq ProgTest_ok // springe wenn gleich
sts ProgTest,w4 // ansonsten merke letzte Daten zum vergleich auf 2x Gleiche Daten
ret // und zurück
ProgTest_ok:
ldi ZL,lo8(CVtest) // zl/h auf CVmin setzen
ldi ZH,hi8(CVtest)
mov w,w2 // zu schreibendes Cv (steht in w2) auf min/max testen
clc
rol w
add ZL,w
clr w
adc ZH,w
lpm w,z+ // CVmin holen
cp w3,w // neue Daten (sind in w3) mit minimal Wert vergleichen
brsh 3f // wenn größer oder gleich
ret // ansonsten Fehler -> zurück
3: lpm w,z // CVmax holen
cp w,w3 // maxWert mit neuen Daten vergleichen
brsh 3f // wenn größer oder gleich
ret // ansonsten Fehler -> zurück
3: sts EE_Adresse,w2 // setzte EEprom Adresse (w2)
mov w,w3 // setze Daten (w3)
rcall eepromschreiben // sichere neue Daten im EEprom
rcall PROG_BEST // jetzt erst bestätigen (damit schreibvorgang nicht gestört wird)
rcall DATEN_NEU_EINLESEN // und Dekoderdaten neu einlesen
ret // und fertig
CV_vergleiche_Byte:
sts EE_Adresse,w2 // setzte EEprom Adresse (CV-Nr steht in w2)
rcall eepromlesen // hole aktuellen Wert der CV
cp w,w3 // Vergleiche
brne 1f
rcall PROG_BEST // wenn gleich bestätige
1: ret
CV_manipuliere_Bit:
sts EE_Adresse,w2 // setzte EEprom Adresse (CV-Nr steht in w2)
rcall eepromlesen // hole aktuellen Wert der CV
sbrc w3,4 // wenn Bit = 0 -> Bit vergleichen 1x springen
rjmp Bit_schreiben
Bit_vergleichen: // einzelnes Bit vergleichen
sbrs w3,3 // je nach bit w4 komplett setzen oder löschen
clr w4 // wenn bit auf Low getestet werden soll w4 löschen
sbrc w3,3
ldi w4,0xFF // wenn bit auf High getestet werden soll w4 setzen
eor w,w4 // vergleiche CV mit w4 (einfach CV xor mit bit)
cbr w3,0b11111000 // Befehlsteil löschen nur Bitnummer stehen lassen
tst w3 // bit0 angefragt ?
brne bit_1_vgl // wenn nicht weiter mit bit1
sbrs w,0 // wenn bit0 ungleich 1x springen -> fertig
rcall PROG_BEST // wenn gleich zu PROG_BEST
ret
bit_1_vgl:
cpi w3,1 // bit1 angefragt ?
brne bit_2_vgl // wenn nicht weiter mit bit2
sbrs w,1 // wenn bit1 ungleich 1x springen -> fertig
rcall PROG_BEST // wenn gleich zu PROG_BEST
ret
bit_2_vgl:
cpi w3,2
brne bit_3_vgl
sbrs w,2 // wenn bit2 ungleich 1x springen -> fertig
rcall PROG_BEST // wenn gleich zu PROG_BEST
ret
bit_3_vgl:
cpi w3,3
brne bit_4_vgl
sbrs w,3 // wenn bit3 ungleich 1x springen -> fertig
rcall PROG_BEST // wenn gleich zu PROG_BEST
ret
bit_4_vgl:
cpi w3,4
brne bit_5_vgl
sbrs w,4 // wenn bit4 ungleich 1x springen -> fertig
rcall PROG_BEST // wenn gleich zu PROG_BEST
ret
bit_5_vgl:
cpi w3,5
brne bit_6_vgl
sbrs w,5 // wenn bit5 ungleich 1x springen -> fertig
rcall PROG_BEST // wenn gleich zu PROG_BEST
ret
bit_6_vgl:
cpi w3,6
brne bit_7_vgl
sbrs w,6 // wenn bit6 ungleich 1x springen -> fertig
rcall PROG_BEST // wenn gleich zu PROG_BEST
ret
bit_7_vgl:
sbrs w,7 // wenn bit7 ungleich 1x springen -> fertig
rcall PROG_BEST // wenn gleich zu PROG_BEST
ret
Bit_schreiben: // einzelnes Bit schreiben
bst w3,3 // das zu schreibene Bit sichern
cbr w3,0b11111000 // Befehlsbits löschen
tst w3 // auf bit0 testen
brne bit_1 // wenn ungleich weiter mit bit 1
bld w,0 // bit ablegen
rjmp CV_sichern // und CV wieder speichern
bit_1: cpi w3,1 // auf bit1 testen
brne bit_2
bld w,1
rjmp CV_sichern // und CV wieder speichern
bit_2: cpi w3,2
brne bit_3
bld w,2
rjmp CV_sichern // und CV wieder speichern
bit_3: cpi w3,3
brne bit_4
bld w,3
rjmp CV_sichern // und CV wieder speichern
bit_4: cpi w3,4
brne bit_5
bld w,4
rjmp CV_sichern // und CV wieder speichern
bit_5: cpi w3,5
brne bit_6
bld w,5
rjmp CV_sichern // und CV wieder speichern
bit_6: cpi w3,6
brne bit_7
bld w,6
rjmp CV_sichern // und CV wieder speichern
bit_7: bld w,7
CV_sichern:
rcall eepromschreiben // sichere neue Daten im EEprom
rcall DATEN_NEU_EINLESEN // und Dekoderdaten neu einlesen
rcall PROG_BEST // und PROG_BEST
ret
/****************************
* CV Progmodus-ServiceMode *
****************************
Format Dekoder Service Mode
wenn Reset/Grundstellungspaket empfangen wurde, dann wird automatisch danach hierher verzweigt
byteA byteB byteC byteD
long-preamble 0 0111CCAA 0 AAAAAAAA 0 DDDDDDDD 0 EEEEEEEE 1
0111-> Direct CV Addressing
CC-> 10 Bit Manipulation
CC-> 01 Verify byte
CC-> 11 Write byte
AA AAAAAAAA-> 10 bit Adresse plus 1 CV #1 is defined by the address 00 00000000
DDDDDDDD-> Datenbyte
EEEEEEEE-> EOR Prüfbyte
CC-> 10 Bit manipulation
AA AAAAAAAA-> 10 bit Adresse plus 1 CV #1 is defined by the address 00 00000000
1110Daaa-> Vergleich in der CV aus Adresse Bit aaa mit Wert in D
1111Daaa-> Schreiben des Wertes in D in das Bit aaa innerhalb der CV aus Adresse
*/
SERVICE_MODE:
tst byteA // auf DekoderReset testen
brne SM_machen // wenn nicht 1x springen
rjmp DCCreset // wenn ja Reset machen
SM_machen:
mov w,byteA // w mit Befehlsbyte laden
mov w2,byteB // w2 mit CV Nummer laden
mov w3,byteC // w3 mit CV Daten laden
mov w4,byteD // w4 mit Prüfbyte laden
cbr flag,(1<<neuerBefehl) // Daten gesichert Empfangsspeicher wieder freigeben
cbr w,0b00000011 // adressbits ausblenden nur die ersten 256 CV werden verwendet/benötigt
cpi w,0b01111100 // prüfe Funktionscode auf CV Write Byte Schreiben
breq SM_schreibe_Byte // gehe zu CV Byte schreiben
cpi w,0b01110100
breq SM_vergleiche_Byte // gehe zu CV Byte vergleichen
cpi w,0b01111000
breq SM_manipuliere_Bit // gehe zu CV Bit Manipulation
cbr flag,(1<<resetbit) // lösche Reset und dann zurück
ret
SM_schreibe_Byte: // Reset hier nicht löschen, weil Daten erst 2x gleich angekommen sein müssen
rcall CV_schreibe_Byte
ret
SM_vergleiche_Byte:
rcall CV_vergleiche_Byte
cbr flag,(1<<resetbit) // lösche Reset und dann normal weiter
ret
SM_manipuliere_Bit:
rcall CV_manipuliere_Bit
cbr flag,(1<<resetbit) // lösche Reset und dann normal weiter
ret
/**************************
* Programmierbestätigung *
**************************/
PROG_BEST:
sbrs flag,resetbit // wenn 1 war reset da als ServiceMode -> Fahrzeug steht ACK durch Stromerhöhung
ret // sonst fertig (hier kann mal Ack über RailCom gemacht werden)
cbr flag,(1<<resetbit) // lösche Reset
sbi Ack_port,Ack_pin
// Timer0 ist frei -> dafür nutzen
in w,TIFR // zuerst Int-Flag löschen
sbr w,(1<<TOV0)
out TIFR,w
ldi w,209 // Zähler auf 209 -> noch 47x bis Überlauf
out TCNT0,w // setze Zeit für Bestätigung
ldi w,0b00000101 // 1 0 1 CK/1024 für Resetzeit
out TCCR0,w
0: in w,TIFR // hole Timer Interuptflag
sbrs w,TOV0 // auf Überlauf warten (1/8MHZ=125µs*1024*56=7,168ms)
rjmp 0b // Schleife
clr w // wenn Ackzeit abgelaufen Timer wieder anhalten
out TCCR0,w
cbi Ack_port,Ack_pin
ret
// min/max für CVs
.type CVtest,@common // nicht disassemblieren
CVtest:
.byte 1,127 //CV1 Dekoderaddresse 1-127
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 0xFF,0xFF //CV6
.byte 42,42 //CV7 Software-Version
.byte 0x0D,0x0D //CV8 Herstellerkennung
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 0,0xFF //CV13 Analogmodus aktive Funktionen 1 = F0 ein 2 = F1 ein bis 255 = F7 ein
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 192,231 //CV17 Erweiterte Adresse Höherwertiges Byte der langen Adresse plus 192
.byte 0,0xFF //CV18 Erweiterte Adresse Niederwertiges Byte der langen Adresse
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 0xFF,0xFF
.byte 0,0xFF //CV29 Konfiguration nach DCC-Norm
.byte 0,1 //CV30 Softwareupdate
.byte 190,230 //CV31 U_LED 205 ca. 4,2V (je nach interner Reverenz)
.byte 0,1 //CV32 1 = Lipobetrieb
.byte 0,0xFF //CV33 AUX_1_FKT
.byte 0,0xFF //CV34
.byte 0,0xFF //CV35
.byte 0,0xFF //CV36
.byte 0,0xFF //CV37
.byte 0,0xFF //CV38
.byte 0,0xFF //CV39
.byte 0,0xFF //CV40
.byte 0,0xFF //CV41
.byte 0,0xFF //CV42
.byte 0,0xFF //CV43
.byte 0,0xFF //CV44
.byte 0,0xFF //CV45
.byte 0,0xFF //CV46
.byte 0,0xFF //CV47
.byte 0,0xFF //CV48
.byte 0,0xFF //CV49
.byte 0,0xFF //CV50 AUX_18_FKT
.byte 0,0xFF //CV51 AUX_1_EFF
.byte 0,0xFF //CV52
.byte 0,0xFF //CV53
.byte 0,0xFF //CV54
.byte 0,0xFF //CV55
.byte 0,0xFF //CV56
.byte 0,0xFF //CV57
.byte 0,0xFF //CV58
.byte 0,0xFF //CV59
.byte 0,0xFF //CV60
.byte 0,0xFF //CV61
.byte 0,0xFF //CV62
.byte 0,0xFF //CV63
.byte 0,0xFF //CV64
.byte 0,0xFF //CV65
.byte 0,0xFF //CV66
.byte 0,0xFF //CV67
.byte 0,0xFF //CV68 AUX_18_EFF
Detected encoding: UTF-8 | 0
|