; *************************************************************** ; * Copyright by mad.dax@t-online.de * ; * DCC-Decoder Testversion * ; * 14 / 28 und 126 Fahrstufen ( Fahrstufe 14 = 27 ) * ; * Übergbnge Stufenlos * ; * PWM mit 6125 HZ, internes Timing mit CV6 trimmbar * ; * kurze und lange Adressierung ( 7 und 14 Bit je nach CV ) * ; * F1 / F2 als Ausgänge * ; * Programming on the Track mit DDW-Server V 0.7.5 und * ; * Java DCC Railroad Network Client V 4.11 getestet * ; * Bedienung auch mit GPlan V 0.70 getestet * ; * Version: 06.06 in Arbeit * ; *************************************************************** ; * Abgeänderter Code Zum Funktionsdecoder für Wagenbeleuchtung * ; * oder Häuser, Bahnübergang , Baustellenblitz ,Sound , Neonblinken ,Polizei, Krankenwagenbeleuchtung etc...* ; * Hardware muß geändert werden / Schaltung nur mit Transistoren an den PB´s * ; * Bit 1 bis 8 bei diversen Programmern werden diese auch 0 bis 7 bezeichnet hier 1 bis 8 * ; * CV28 Bit 1 auf 1 ( 01 in dezimal ) dann F1 bis F4 Dauerlicht Ein/Aus* ; * CV28 Bit 2 auf 1 ( 02 in dezimal ) dann F1 u F2 und FL ( Steuerwagenfunktion ein ) bei Nothalt FL aus * ; * CV28 Bit 2 und 1 auf 1 ( 03 in dezimal ) dann F1 u F2 und FL ( Steuerwagenfunktion ein ) bei Nothalt FL bleibt an * ; * CV28 Bit 3 auf 1 ( 04 in dezimal ) dann F1 - F4 Aktiv und Blinkfunktion der Ausgaenge F1 und F2 ( Dauerblinken / Reklameschild etc..) * ; * CV28 Bit 4 auf 1 und Bit 1 auf 1 ( 09 in dezimal ) dann F1 - F4 Aktiv und Blinkfunktion der Ausgaenge die in CV25 auf 1 gesetzt sind ; * CV 25 ( Bit 4 und 5 für F1 und F2 und Bit 1 und 2 für F3 und F4 ) Reklame Funktion / Bahnübergang / Baustellenblitz etc* ; * CV28 Bit 5 auf 1 ( 16 in dezimal ) für Polizei / Feuerwehr / Rettungswagen Funktion, so blinken die Ausgänge ; * wenn FL ein ist F1 und F2 im wechsel ( Blaulicht ), F3 blinkt ( Fernlicht ) und F4 Blinkt (Warnblinkanlage) wenn FL aus dann Dauerlicht* ; * CV28 Bit 6 auf 1 ( 32 in dezimal ) dann F1 und F2 blinken ( Neonsimulation für Wagonbeleuchtung ) mit F3 und F4 als Dauerlicht ; * sonst Bit 1/2 mit setzten ( Steuerwagen Funktion ) / ( 34 oder 35 in dezimal ) * ; * CV26 hier werden die Anzahl in Wiederholungen des blinkens eingestellt in dezimal ( Standart 05 ) bis Dauerleuchten eingestellt wird. ; * CV27 hier kann man die Blinkfrequenz einstellen ( Sie berechnet sich aus CV 26 und CV 27 ) je kleiner desto schneller blikt es. ; * Getestet mit Twin Center und Intellibox * ; * Code geändert, damit 4 Stellige Adressen erkannt werden können* ; * Code ausdokumentiert * ; * Danke an alle Mitwirkenden * ; * Verzögertes einschalten ( einstellbar ) für Stützelkoladung ( damit nicht alle gleichzeitig Laden )* ; * diese Änderungen by Muetze 10.2009 * ; *************************************************************** ; ; Hardware Anforderungen: ; ; Standard Belegung ; ; Tiny 15 PDIP/SOIC ; ;(RESET/ADC0) PB5 = 1 8 = VCC ;(ADC3) PB4 = 2 7 = PB2 (ADC1/SCK/T0/INT0) ;(ADC2) PB3 = 3 6 = PB1 (AIN1/MISO/OC1A) ; GND = 4 5 = PB0 (AIN0/AREF/MOSI) ; ; DCC Decoder ; ;RESET PB5 = 1 8 = VCC ;Funktion 2 PB4 = 2 7 = PB2 DCC Eingang ;Funktion 1 PB3 = 3 6 = PB1 Ausgang Rückwärts / Funktion 3 ; GND = 4 5 = PB0 Ausgang Vorwärts / Funktion 4 ;Funktion FL für Steuerwagen verwenden, dann kein F3 und F4 möglich ;Funktion F1 und F2 sollen zum einschalten der Wagenbeleuchtung benutzt werden ;Funktion F3 und F4 für Zubehör ( Sound etc.. ) verwendet werden ;NB: NMRA-DCC Basisprotokoll (abs. FRU, 7-bit-Adr., 14 FS) ;N1: NMRA-DCC erweitert (abs. FRU, 7-bit-Adr., 5 Funkt., 28 FS) ;N2: NMRA-DCC erweitert (abs. FRU, 7-bit-Adr., 5 Funkt., 128 FS) ;N3: NMRA-DCC erweitert (abs. FRU, 14-bit-Adr., 5 Funkt., 28 FS) ;N4: NMRA-DCC erweitert (abs. FRU, 14-bit-Adr., 5 Funkt., 128 FS) ; ; Software Funktionen: ; .NOLIST .INCLUDE "tn15def.inc" ; Datei des verwendetetn prozessors von AVR Studio ; ; Konstanten FlagReg ; .equ CONREV = 4 ; Consist Reverse Direction bei 1 .equ SERVMODE = 3 ; Programmiermodus .equ BitNew =2 ; Flag Neues Bit eingetroffen .equ LoTiF =1 ; Long Time Flag .equ Bit =0 ; Bit Wert ; ; Konstanten Funktion ; .equ FLGeschw = 0 ; FLGeschw Funktionsbit Bit Nr.0 CV28 .equ FTasten = 1 ; F Tasten Funktionsbit Bit Nr.1 CV28 .equ Neon = 2 ; Funktion Neonblinken Bit Nr.2 CV28 .equ BlinkenAusw = 3 .equ Police = 4 ; Konstanten DCCReg ; .equ LongADR = 7 ; Lange Adresse bei 1 .equ RevDir = 6 ; Fahrtrichtung reversiert bei 1 .equ DIR =5 ; Fahrtrichtung 1=vorwärts, 0=rückwürts .equ FL =4 ; Fahr Licht .equ F4 =3 ; F4 Funktionstaste F4 Port B1 .equ F3 =2 ; F3 Rangiergang bei 1-Signal oder F3 Port B0 .equ F2 =1 ; F2 Funktionstaste F2 Port B4 .equ F1 =0 ; F1 Funktionstaste F1 Port B3 .equ SampleTime = 255 - 105 ; 139- ca. 30 Befehlszyklen 75% der High-Signal Periodendauer = 87us ohne Precaler .equ WaitTime = 255 - 200 ; 250? maximale Bitlänge = 10000us bei Prescaler 64 .equ EEAdresse = 0 ; Speicherplatz eigene Adresse im EEPROM .equ EEStart = 1 ; Speicherplatz Start-Speed nicht benutzt .equ EEIncrease = 2 ; Speicherplatz Beschleunigungskonstante im EEPROM .equ EEDecrease = 3 ; Speicherplatz Verzögerungskonstante im EEPROM .equ EEAusgang = 24 ; Speicherplatz Welche Ausgänge sollen Flackern / Invertieren der Ausgänge .equ EEAnzahl = 25 ; Speicherplatz Anzahl Flackerdurchläufe im EEPROM .equ EEOSCCAL = 5 ; Speicherplatz OSCCAL im EEPROM .equ EELongADR = 28 ; Speicherplatz Lange Adresse gesetzt im EEPROM .equ EELongADRHI =16 ; Speicherplatz Lange Adresse EEPROM .equ EELongADRLO = 17 ; Speicherplatz Lange Adresse EEPROM .equ EECONAdr = 18 ; Speicherplatz Consist Adresse EEPROM .equ ACKTime = 63 ; 5 ms bei Timer 1 = CK/128 .equ RESTime = 250 ; 20 ms bei Timer 1 = CK/128 .equ EEFunktion = 27 ; Speicherplatz Funktionsart EEPROM Bit 0 = 0 dann Nothalt An bei 1 Aus ; Bit 1 = 0 dann Funktionsdec bei 1 Steuerwagedec / Bit 2 = 0 dann Blinken aus bei 1 An .equ EETest = 20 ; Speicherplatz Funktionsart EEPROM Testzwecke .equ EEBlink = 26 ; Speicherplatz Funktionsart EEPROM Blinkfrequenz 1 - 255 CV 27 ; Benutzte Register ; .def RAM = R0 ; Reserviert für RAM Zugriff .def Ausgang = R1 ; berechnete Geschwindigkeit .def Frequenz = R2 ; Soll Frequenz für Blinken 1 Takt entspricht ca 30µs .def Neonz1 = R3 ; Zaehler für Flackerstufen .def Neonz2 = R4 ; Zaehler wird erhöt wenn Zähler 1 abgelaufen .def PortbReg = R5 ; PortbReg speichert die PortB Ausgänge zum setzten im Portregister .def Zaehl = R6 ; Bremskonstante .def Anzahl = R7 ; Anzahl der Flackerstufen .def ByteA = R8 ; Empfangenes Byte .def ByteB = R9 ; Empfangenes Byte .def ByteC = R10 ; Empfangenes Byte .def ByteD = R11 ; Empfangenes Byte .def ByteE = R12 ; Empfangenes Byte .def ByteF = R13 ; Empfangenes Byte .def HIAdresse = R14 ; eigene Adresse HI-Byte für lange Adresse .def LoAdresse = R15 ; eigene Adresse Lo-Byte für lange Adresse .def TEMPS = R16 ; SREG Sicherungsregister .def TEMPI = R17 ; TEMP Register für Initialisierung und Interupt-Schmierregister .def TEMP1 = R18 ; TEMP Register für Hauptprogramm und Initialisierung .def TEMP2 = R19 ; TEMP Register für Hauptprogramm .def TEMP3 = R20 ; TEMP Register für Hauptprogramm .def CONAdr = R21 ; Consist-Adresse ( Mehrfachtraktion ) .def Adresse = R22 ; eigene Adresse .def FlagReg = R23 ; Flag Register .def DCCReg = R24 ; DCC Register für Funktionen und Fahrtrichtung .def ByteCNT = R25 ; Bytezähler für Datenhandling .def BitCNT = R26 ; Bitzähler für Datenhandling .def PRGCHECK = R27 ; Checkbyte für CV Schreiben .def Funktion = R28 ; Welche Funktion ist ausgewählt Bit0 = 0 bei Geschw = 0 FL aus / ; Bit1 = 0 Funktionsdec oder Bit2 = 1 Steuerwagedec oder Bit 3 = 1 dann Neonblinken bei F1 und F2 ein .def STOP = R29 ; Bit 0 = 1 dann Fahrlicht Aus bei Nothalt wenn CV28 Bit 0 = 1 ;def Reserviert = R30 ;def Reserviert = R31 ; ; ; Code beginnt hier ; .CSEG .ORG $0000 ; ; Reset- und Interrupt-Vektoren rjmp RESET ; Reset handler rjmp EXT_INT0 ; IRQ0 handler reti ;PIN_CHANGE ; Pin change handler reti ;TIM1_CMP ; Timer1 compare match rjmp TIM1_OVF ; Timer1 overflow handler rjmp TIM0_OVF ; Timer0 overflow handler reti ;EE_RDY ; EEPROM Ready handler reti ;ANA_COMP ; Analog Comparator handler reti ;ADC ; ADC Conversion Handler ; ; ; **************** Ende der Interrupt Service Routinen ********************* ; ; ; 8x8 Bit Unsigned Multiplication von ATMEL ;def TEMP1 =r16 ; multiplicand ;def TEMP2 =r17 ; multiplier ;def TEMP2 =r17 ; result Low byte ;def TEMP3 =r18 ; result High byte MUL8X8: clr TEMP3 ; Lösche Inhalt von Temp3 / clear result High byte ldi ByteCNT,8 ; Lade in ByteCnt eine 8 / init loop counter lsr TEMP2 ; schiebe das Register TEMP2 um einen nach rechts / rotate multiplier MULSTART: brcc MULMORE ; ist das Carry Flag = 0 springe zu MULMORE / carry set add TEMP3,TEMP1 ; Addition von Inhalt und Temp1 zu Temp3 / add multiplicand to result High byte MULMORE: ror TEMP3 ; In Temp3 alls um einen nach rechts / rotate right result High byte ror TEMP2 ; In Temp2 alls um einen nach rechts / rotate right result L byte and multiplier dec ByteCNT ; Zähle den inhalt von ByteCNT runter / decrement loop counter brne MULSTART ; Ist der Wert von MULSTART nicht gleich mit ByteCNT dann springe zu MULSTART / if not done, loop more ret ; zurück zur Sprungmarke ( rcall ) writeEEPROM: sbic EECR,EEWE ; wird momentan noch geschrieben ? rjmp PC-1 ; Schleife out EEAR,TEMP1 ; Erfasse EEProm Schreibadresse out EEDR,TEMP2 ; Erfasse EEProm Schreibdaten cli ; alle Interrupts ausschalten sbi EECR,EEMWE ; Setze EEProm Master-Schreibbit sbi EECR,EEWE ; Setze EEProm Schreib-Befehl sbic EECR,EEWE ; wird momentan noch geschrieben ? rjmp PC-1 ; Schleife sei ; alle Interrupts wieder einschalten ret ; Rücksprung readEEPROM: sbic EECR, EEWE ; wird noch geschrieben ? rjmp PC-1 ; Schleife out EEAR, TEMP1 ; Erfasse EEProm-Leseadresse sbi EECR, EERE ; Setze EEProm-Lesebefehl in TEMP2, EEDR ; Lese EEprom-Daten ret ; Rücksprung EXT_INT0: ;Flankenwechsel von Low auf High in TEMPS,SREG ; SREG sichern clr TEMPI ; Timer anhalten out TCCR0,TEMPI ; Prescaler steht auf STOP-Counter mit 000 in TEMPI,TIFR ; lösche Timer 0 Interrupt Flag andi TEMPI,0b00000010 ; das eventuell während dieses Interuptaufrufes out TIFR,TEMPI ; gesetzt worden ist cbr FlagReg, (1< 0 Abschalten cbr STOP,0b10000000 ; lösche das Bit 0 nach Muster 0b00000001 in STOP ( Register 29 Bit 1 gestezt ) cpi TEMP1,0b00000010 ; vergleiche Temp1 mit Muster / Geschwindigkeit Stufe 1 wurde gesendet brsh pc+3 ; den Programmcounter um 3 vor cbr stop, 0b01000000 ; lösche im STOP Register das Bit 1 rjmp pc+2 ; Springe im Programmcounter 2 vor sbr stop, 0b01000000 ; setzte das Bit 1 auf 1 ret ; Springe zurück ;******************** Timer aus Prozessortakt *************************************************************** Zaehler: inc Neonz1 ; Neonzähler 1 um einen erhöhen cp Neonz1,Frequenz ; vergleiche den Zähler 1 mit der vorgewählten Frequenz Breq pc+2 ; Wenn der Zähler gleich der Frequenz dann im Programmcounter 2 vor rjmp PC+14 ; sonst im Programmcounter 12 vor clr Neonz1 ; Lösche den Zähler 1 inc Neonz2 ; Neonzähler 2 um einen erhöhen cp Neonz2,Anzahl ; vergleiche den Zähler 2 mit der vorgewählten Anzahl Breq pc+2 ; Wenn der Zähler gleich der Frequenz dann im Programmcounter 2 vor rjmp PC+9 ; sonst im Programmcounter 5 vor sbrs stop,3 ; Ist das Bit 3 im Stopregister auf 0 sbr stop,0b00001001 ; setze die Bits im Muster mit einer 1 auf 1 / Bit 3 im Stop Register setzten sbrs stop,0 ; Ist das Bit 0 im Stopregister auf 0 cbr stop,0b00001000 ; steze die Bits im Muster mit einer 1 auf 1 clr Neonz2 ; Lösche den Zähler 2 cp Zaehl,Anzahl breq pc+2 inc Zaehl ; erhöhe Zähler für die Anzahl der Flackerwiederholungen cbr stop,0b00000001 ; lösche die Bits im Muster mit einer 1 auf 0 ;************************************************************************************************************* ;******* BlinkfunktionEN ** CV 28 Bit 3 bis 5 **************************************************************** ;********** An / Aus ***************************************************************************************** ;***** Blinkfunktion Neonflackern / mit F1 starten ( Port PB3 und PB4 / CV28 Bit 3 )************************* bst Funktion,NEON bld stop,4 ;***** Blinkfunktion Gesetzte Bits rest normal / mit FL starten ( Port PB3 und PB4 / CV28 Bit 3 )************************* bst Funktion,3 bld stop,2 ;************************************************************************************************************* ;***** Blinkfunktion Neonflackern / mit FL starten ( Port PB3 und PB4 / CV28 Bit 3 )************************* bst Funktion,Police bld Stop,5 ;******* An ************************************************************************************************** ;************************************************************************************************************* sbrs DCCreg,FL ; Starten nur wenn fahrlicht an ist cbr Stop, 0b00100100 ret ; ****************** Blinken CV28 Bit 3 oder 5 *************************************************************** ; Ist das Bit 3 in CV 28 für Blinken der Ausgänge für die Funktionen F1 und F2 angewählt Blinken die ; eigeschalteten Funktion dauerhaft. ; Ist das bit 5 in CV 28 für Polizei / Feuerwehr / Rettungswagen eingeschalten so blinken die Ausgänge ; wenn FL ein ist. F1 und F2 im wechsel ( Blaulicht ), F3 blinkt ( Fernlicht ) und F4 Blinkt (Warnblinkanlage) ; Blinken: sbrs stop,3 ; Ist das Bit 3 im Stopregister auf 0 sbrs stop,5 ; Überprüfung auf Polizei Funktion aus rjmp pc+3 sbr Temp1,0b00010000 ; steze die Bits im Muster mit einer 1 auf 1 cbr Temp1,0b00001001 ; lösche die Bits im Muster mit einer 1 auf 0 sbrc stop,3 ; Ist das Bit 3 im Stopregister auf 1 cbr Temp1,0b00011000 sbrc stop,3 sbrs stop,5 ; Überprüfung auf Polizei Funktion aus rjmp pc+3 cbr Temp1,0b00010010 ; lösche die Bits im Muster mit einer 1 auf 0 sbr Temp1,0b00001000 ; steze die Bits im Muster mit einer 1 auf 1 ret ; ************************************************************************************************************ ; ******** Blinken Auswahl in CV 28 Bit 4 gesetzt************************************************************* ; Alle in CV 25 mit Bit auf 1 Gekenzeichneten Ausgänge Blinken die mit 0 sind ganz normal ; einzuschalten. Gilt also für F1 bis F4 ( Reklamebeleuchtung , Hausbeleuchtung , Bahnübergang etc.. ; ************************************************************************************************************ BlinkCV25: ; Unterprogramm für CV 25 / Auswahl Blinkmodus für F-Tasten sbrs Stop,3 ; ist das Bit 3 im Register Stop nicht gestezt / Timer Abgelaufen rjmp pc+3 ; dann springe im Programmcounter 3 vor or Temp1,Ausgang ; sonst bilde das Oder von Temp1 und dem Ausgangsregister eor Temp1,Ausgang ; und dannach das exclusivoder von Temp1 und dem Ausgangsregister ret ; return zur Sprungmarke / Procedure ende ; ************************************************************************************************************ ; **************** Wagenlicht soll flackern CV28 bit 6 auf 1 ************************************************* ; gilt für die Funktionstasten F1 und F2 ist nur eine Taste betätigt, so Blinkt der entsprechnde ; Ausgang.Sind beide Aktiv so ist ein Wechselbliken der beiden Ausgänge aktiv . ; Ist der Zaehler (in CV 26 einstellbar ) abgelaufen leuchten Beide bzw. der eingeschaltete Ausgang ; Dauerhaft. ; ************************************************************************************************************ Wagenfl: ; Wagellicht mit Neonflackern einschalten cp Zaehl,Anzahl ; Vergleiche Zaehl mit Anzahl wenn der vergleich Gleich dann, breq PC+5 ; Springe im Programmcouter 5 Vor / Tue nichts und springe zurück sbrs Stop,3 ; ist das Bit 3 im Register Stop nicht gestezt / Timer nicht abgelaufen cbr Temp1,0b00001000 ; lösche das 3 Bit in Temp1 sbrc Stop,3 ; ist das Bit 3 im Register Stop nicht gestezt / Timer abgelaufen cbr Temp1,0b00010000 ; lösche das Bit 4 in Temp1 ret ; return zur Sprungmarke / Procedure ende ;************************************************************************************************************* ;****************** hier beginnt das EEProm ****************************************************************** .ESEG .ORG $0000 .db 0x03, 0x00 ; CV1 Adresse und CV2 StartSpeed .db 0x80, 0x80 ; CV3 IncVAL und CV4 DecVal .db 0x80, 0x69 ; CV5 MaxSpeed und CV6 OSCCAL .db 0xFF, 0x01 ; CV7 Hersteller und CV8 Typ ID .db 0xFF, 0xFF ; CV9 Frei und CV10 Frei .db 0xFF, 0xFF ; CV11 Frei und CV12 Frei .db 0xFF, 0xFF ; CV13 Frei und CV14 Frei .db 0xFF, 0xFF ; CV15 Frei und CV16 Frei .db 0xC8, 0x8A ; CV17 HI-Byte und CV18 LO-Byte .db 0x00, 0xFF ; CV19 Consist und CV20 Frei .db 0xFF, 0xFF ; CV21 Frei und CV22 Frei .db 0xFF, 0xFF ; CV23 Frei und CV24 Frei .db 0x30, 0x0A ; CV25 Bitmuster für Neon Blinker und CV26 Wiederholungen des blinkens .db 0x04, 0x02 ; CV27 Blinkfrequenz und CV28 Funktionauswahl .db 0x00, 0xFF ; CV29 Configuration Data und CV30 Frei