'Jetibox-Remake
'_______________________________________________________
'Sensorprotokoll für Jeti Duplex
'das Protokoll soll sein:
'9600B,1,9,1,1
'_______________________________________________________
'Anschlüsse:
'Tasten: Left=c2 ; Down=c3 ; Right=c4 ; Up=c0 ; Mitte=c1 ; Port C
'
'Pb5: Eingang am Displayfeld (LCD angeschlossen wenn Masse anliegt)
'PB0: Eingang 2G4-Umschalter: HF-Meldung nicht ausschalten, wenn +5V anliegen
'
'Rxd: pd0, txd: pd1;
'Interrupttasten: pd2=int0
'Pd5: Hintergrundbeleuchtung->Schaltausgang;
'Pd4: Entertasterausgang
'Pb5: Indikator Display angesteckt -> Auf Masse: Display drauf
'
'DOGM162: Rs b.1 : Csb b.2 : Si b.3 : Clk b.4
'_______________________________________________________
$regfile = "M8def.dat"
$initmicro                                                  'Pre-Init
$crystal = 8000000                                          '8Mhz Power =:)
$hwstack = 100                                              'Grosszügige Stacks
$swstack = 100
$framesize = 100


'Ports ---------------------------------------------
Txd_enable Alias Ucsrb.txen : Txd_pullup Alias Portd.1      'Zwischen Rxd und Txd ein 100Ohm-Widerstand
Rxd_enable Alias Ucsrb.rxen : Rxd_pullup Alias Portd.0
'Config Portc = &B11111111 : Portc = &B11111111              'Tastenports als Eingänge, Pullups an
Ddrb = &B11111111 : Portb = &B11111111
Rs Alias Portb.1 : Csb Alias Portb.2 : Si Alias Portb.3 : Clk Alias Portb.4
Portd.2 = 1                                                 'PullUp von PD2/Int0 aktivieren
Licht_ausgang Alias Portd.5 : Config Portd.5 = Output : Licht_ausgang = 0       'Ausgang auf BC547: Hintergrundbeleuchtung an
Enter_key Alias Portd.4 : Config Portd.4 = Output : Enter_key = 1       'Enter auf +5V = Enter-Taster offen
2g4_aus Alias Pinb.0 : Config Pinb.0 = Input : Portb.0 = 1  'Masse an Pin: 2G4 an
'Disable_jetibox Alias Pinb.5 : Config Pinb.5 = Input : Portb.5 = 1       'Masse an Pin: Es hängt ein Display am Port


'Variablen und Konstanten-----------------------------------------------
Start_text Alias &HFE                                       'Start-Byte
End_text Alias &HFF                                         'Stop-Byte
Dim R As Bit : R = 0                                        '1=Etwas empfangen  (Receiver-Indikator)
Dim Start_bit As Bit : Reset Start_bit                      'Start-Byte empfangen
Dim Rs232bufferupper As Byte : Dim Rs232bufferlower As Byte 'Empfangspuffer
Dim Zeile_neu As String * 32 : Dim Zeile_neu_byte(33) As Byte At Zeile_neu Overlay       'Zwischenpuffer für LCD-Ausgabe
Dim Zeile_alt As String * 32 : Dim Zeile_alt_byte(33) As Byte At Zeile_alt Overlay
Dim Zaehler As Byte : Zaehler = 0                           'Zähler für LCD-Puffer (2x16 Zeichen)
Dim Poll_keys_return As Byte                                'Byte-Wert für Tastenrückgabecode
Dim Zeitgeber As Byte : Zeitgeber = 0                       'Zeitzählervariable für Licht-Ausschalter
Dim Reset_bit As Byte : Reset_bit = 0                       'WatchDog-Reset erhalten
Dim Mcucsr_reg As Byte
Dim Display_doubleheight As Byte : Display_doubleheight = 0 ' Doppelte Höhe anzeigen
Const Timervorgabe1 = 26474                                 'Zeitgeber = 5 Sekunden
Const Versionsnummer = "HeigerBox   v1.0"


'Funktionen ---------------------------------------------------
Declare Sub Schreibe_lcd                                    'LCD-Ausgabe durchführen
Declare Sub Txd_on                                          'Transceiver einschalten
Declare Sub Rxd_on                                          'Receiver einschalten
Declare Sub Dogm_init                                       'LCD-Initialisieren
Declare Sub Welcome_message                                 'Welcome_Message auf LCD ausgeben
Declare Sub Send_enter_key                                  'Enter-Taste virtuell drücken
Declare Sub Dogm_write
Declare Sub Dogm_lowerline
Declare Sub Dogm_upperline
Declare Sub Dogm_pushbyte(byval Pushbyte As Byte)
Declare Sub Dogm_pushchar(byval Pushchar As Byte)
Declare Sub Dogm_pushcommand(byval Pushcommand As Byte)
Declare Sub Dogm_doubleheight
Declare Sub Dogm_singleheight
Declare Sub Dogm_clear
Declare Sub Poll_keys
Declare Sub Display_doubleheight_sub


'***************************************************************************************************************
'UART einschalten **********************************************************************************************
Config Com1 = 9600 , Synchrone = 0 , Parity = Odd , Stopbits = 1 , Databits = 9 , Clockpol = 0       'oder Com1 = 9550
Open "com1:" For Random As #1                               'Rs232 an Jeti einschalten


'***************************************************************************************************************
'Interrupts ****************************************************************************************************
Config Int0 = Change : On Int0 Key_pressed : Enable Int0    'Tastentrigger für Mx16-Tasten
Config Timer1 = Timer , Prescale = 1024 : On Timer1 Timer1_irq : Enable Timer1       'Timer für Beleuchtungs-Monoflop
On Urxc Rx_isr : Disable Urxc                               'Receiver-Interrupt
On Utxc Tx_isr : Disable Utxc                               'Transceiver-Interrupt
Enable Interrupts                                           'Interrupts einschalten

'***************************************************************************************************************
'Inits *********************************************************************************************************
'***************************************************************************************************************
Mcucsr_reg = Peek(0)
'If Mcucsr_reg >= 8 Then Reset_bit = 1                       'WD-Resetflag auslesen //Mcucsr.wdrf geht nicht =:-/
Dogm_init                                                   'LCD starten

Welcome_message                                             'Willkommen an LCD ausgeben
If 2g4_aus = 0 Then                                         '2G4-Mode
   Call Rxd_on                                              'Receiver einschalten
   Config Watchdog = 1024                                   'Timeout in Millisekunden
   If Mcucsr_reg.3 = 0 Then                                 'normaler Start
      Licht_ausgang = 1                                     'HGD-Licht an
      Send_enter_key
      Wait 4                                                'For Welcome_message
   Start Watchdog                                           'Falls Kaltstart -> Starte watchdog timer
   End If
Else                                                        'FM-Mode
   Zeile_neu = Versionsnummer + "<<  FM  MODE  >>"
   Schreibe_lcd
End If

'-------------------------------------------------
'MCUCSR
'Bit 3 – WDRF: Watchdog Reset Flag
'Bit 2 – BORF: Brown-out Reset Flag
'Bit 1 – EXTRF: External Reset Flag
'Bit 0 – PORF: Power-on Reset Flag
'-------------------------------------------------

'***************************************************************************************************************
'MAIN **********************************************************************************************************
'***************************************************************************************************************
Do
   If R = 1 Then                                            'Etwas wurde empfangen
      If Reset_bit = 1 Then                                 'Der Watchdog-Reset war aktiv, es wurde aber wieder etwas empfangen
         Start Watchdog                                     'Also: Watchdog wieder starten
         Reset_bit = 0                                      'WD-Bit zurücksetzen, Empfang wieder da
      Else
         Reset Watchdog                                     'Es war kein Timeout da: WD-Counter zurücksetzen
      End If
      R = 0                                                 'Bit zurücksetzen für neuen Empfang
      If Rs232bufferupper.1 = 1 And Start_bit = 1 Then      'Text wurde nach Start-Byte empfangen
            Incr Zaehler                                    'Textzähler hochsetzen
            Zeile_neu_byte(zaehler) = Rs232bufferlower      'Textvariable füllen
      Elseif Rs232bufferupper.1 = 0 Then                    'Steuerzeichen wurde empfangen
         If Rs232bufferlower = Start_text Then              'Das Steuerzeichen war das Start-Byte
            Set Start_bit                                   'Start-Bit setzen
            Zaehler = 0                                     'Zähler zurücksetzen
         Elseif Rs232bufferlower = End_text Then            'Text wurde komplett empfangen
            Reset Start_bit                                 'Start-Bit zurüksetzen
            Txd_on                                          'Transceiver einschalten
            Waitms 4                                        'Etwas warten :-/ wg. Protokoll
            Call Poll_keys
            Ucsrb.0 = 0                                     '9th-Bit auf 0 setzen = Ich sende Steuerzeichen
            Printbin #1 , Poll_keys_return                  'Tastencode senden
            If Zeile_alt <> Zeile_neu Then Schreibe_lcd     'Wenn sich der Text geändert hat -> schreiben
        End If
      End If
   End If

   Debounce Pinc.1 , 0 , Display_doubleheight_sub , Sub     'Mitte-Taste -> Höhenumschaltung im Display

Loop                                                        'Zurück zum Main-Loop
End                                                         'Programm beenden (never happens :-)



'***************************************************************************************************************
'Subs & Ints ***************************************************************************************************
'***************************************************************************************************************
Sub Display_doubleheight_sub
   Select Case Display_doubleheight
      Case 0 : Dogm_doubleheight                            'Von 2 auf 1 Zeile umstellen, untere Zeile ausgeben
      'Case 1 :  incr display_doubleheight                  'Einzeilig Obere Zeile anzeigen
      Case 2 : Dogm_singleheight                            'Auf eine Zeile umstellen
   End Select

   Incr Display_doubleheight
   If Display_doubleheight >= 3 Then Display_doubleheight = 0

   Schreibe_lcd                                             'Refresh
End Sub

'-------------------------------------------------
Sub Poll_keys
   'Tasten: Left=c2 ; Down=c3 ; Right=c4 ; Up=c0 ; Mitte=c1 ; Port C
   Poll_keys_return = &B11110000                            'Keine Taste
   If Pinc.2 = 0 Then Poll_keys_return.7 = 0                'Links
   If Pinc.3 = 0 Then Poll_keys_return.6 = 0                'Unten
   If Pinc.0 = 0 Then Poll_keys_return.5 = 0                'Oben
   If Pinc.4 = 0 Then Poll_keys_return.4 = 0                'Rechts
   'If Pinc.1 = 0 Then Poll_keys_return = &B01100000         'Mitte = rechts+links
End Sub

'-------------------------------------------------
Sub Send_enter_key                                          'Enter virtuell drücken
   Waitms 50                                                'warten...
   Enter_key = 0                                            'Masse an Enter-Taster
   Waitms 50                                                'warten...
   Enter_key = 1                                            'Wieder 5V an Enter-Taster: Taste offen
End Sub

'-------------------------------------------------
Sub Schreibe_lcd                                            'LCD 2x16 schreiben
   Local N As Byte
   If Display_doubleheight = 0 Then                         'zwei zeilen
      Dogm_upperline
      For N = 1 To 16                                       'Obere Zeile schreiben
            Dogm_pushchar Zeile_neu_byte(n)
      Next N
      Dogm_lowerline
      For N = 17 To 32
            Dogm_pushchar Zeile_neu_byte(n)
      Next N
   Elseif Display_doubleheight = 1 Then                     'eine Zeile, untere schreiben
      Dogm_upperline
      For N = 17 To 32
         Dogm_pushchar Zeile_neu_byte(n)
      Next N
   Else                                                     'eine Zeile, obere schreiben
      Dogm_upperline
      For N = 1 To 16
         Dogm_pushchar Zeile_neu_byte(n)
      Next N
   End If
   Zeile_alt = Zeile_neu                                    'OK, neuer Text wurde geschrieben...
End Sub

'-------------------------------------------------
Sub Welcome_message                                         'Welcome-Message oder Timeoutmeldung schreiben
   If Mcucsr_reg.3 = 1 Then                                 'Reset_bit = 1 Then
      Zeile_neu = Versionsnummer + "<<kein  Signal>>"
   Else
      Zeile_neu = Versionsnummer + Bin(mcucsr_reg)             '"Ralf Heigermoser"
   End If
   Schreibe_lcd
End Sub

'-------------------------------------------------
_init_micro:                                                'Initialisierung vor Programmstart
   Config Portd = &B00000000                                'Port D alles auf Eingang
   Set Rxd_pullup                                           'RxD-Pullup wird abgehängt
   Reset Txd_pullup                                         'und TxD bekommt einen Pull Up
   'Mcucsr_reg = Mcucsr                                      'Reset-Flags lesen
   'Mcucsr = $1f
Return

'-------------------------------------------------
Rx_isr:                                                     'Receive-Interrupt                                                   '
   Rs232bufferupper = Ucsrb                                 '9th Bit
   Rs232bufferlower = Udr                                   'Normaler buffer
   R = 1                                                    'Receive-Bit setzen
Return

'-------------------------------------------------
Tx_isr:                                                     'Transceive-Interrupt
   Rxd_on                                                   ' Alles gesendet -> Receiver wieder ein
Return

'-------------------------------------------------
Sub Rxd_on                                                  'Receiver an
   Disable Utxc                                             'Transceiver aus
   Reset Txd_enable
   Set Rxd_enable
   Enable Urxc
End Sub

'-------------------------------------------------
Sub Txd_on                                                  'Transceiver an
   Disable Urxc                                             'Receiver aus
   Reset Rxd_enable
   Set Txd_enable
   Enable Utxc                                              'Transceiver an
End Sub

'-------------------------------------------------
Key_pressed:                                                'Eine Mx16-Taste wurde gedrückt
   Timer1 = Timervorgabe1                                   'Timer1 auf 5 Sekunden setzen
   Zeitgeber = 0                                            'Timervariable zurücksetzen
   If Licht_ausgang = 0 Then Licht_ausgang = 1              'Beleuchtung anschalten wenn sie aus war
Return

'-------------------------------------------------
Timer1_irq:                                                 'Alle 5 Sekunden
   Timer1 = Timervorgabe1                                   'Timer1 auf 5 Sekunden setzen
   Zeitgeber = Zeitgeber + 5                                'Zeitzähler 5 Sekunden hochzählen
   If Zeitgeber >= 20 And Licht_ausgang = 1 Then Licht_ausgang = 0       'Beleuchtung ausschalten wenn 20sec um sind
Return

'-------------------------------------------------
Sub Dogm_init                                               'Lcd initialisieren
   Set Clk
   Set Csb
   Reset Rs
   Waitms 40
   Reset Csb
   Dogm_pushbyte &H38 : Waitus 30                           'function set
   Dogm_pushbyte &H39 : Waitus 30                           'function set
   Dogm_pushbyte &H1C : Waitus 30                           'BIAS
   Dogm_pushbyte &H52 : Waitus 30                           '3V-Booster aus, power control, contrast high byte
   Dogm_pushbyte &H69 : Waitms 200                          'Follover-Control
   Dogm_pushbyte &H74 : Waitus 30                           'Contrast Set  (&H74)  low byte
   Dogm_pushbyte &H0C : Waitus 30                           'Display on,Cursor off
   Dogm_pushbyte &H01 : Waitms 2                            'Clear Display
   Dogm_pushbyte &H06 : Waitus 30                           'entry mode auto increment
   Set Csb
End Sub

'-------------------------------------------------
Sub Dogm_lowerline
   Dogm_pushcommand &HC0                                    ' Cursorposition setzen
End Sub

'-------------------------------------------------
Sub Dogm_upperline
   Dogm_pushcommand &H80                                    ' Cursorposition setzen
End Sub

'-------------------------------------------------
Sub Dogm_pushcommand(byval Pushcommand As Byte)
   Reset Rs
   Dogm_pushbyte Pushcommand
End Sub

'-------------------------------------------------
Sub Dogm_pushbyte(byval Pushbyte As Byte)
   Reset Csb
   Shiftout Si , Clk , Pushbyte , 1 , 8 , 10
   Set Csb
End Sub

'-------------------------------------------------
Sub Dogm_pushchar(byval Pushchar As Byte)
   Set Rs
   Dogm_pushbyte Pushchar
End Sub

'-------------------------------------------------
Sub Dogm_doubleheight
   Dogm_pushcommand &B00101010                              'Set Instruction Table 2
   Dogm_pushcommand &B00011000                              'Select Row 0
   Dogm_pushcommand &B00101100                              'Turns On Double Line Mode
   Dogm_upperline
End Sub

'-------------------------------------------------
Sub Dogm_singleheight
   Dogm_pushcommand &B00101000                              'Double height off
   Dogm_upperline
End Sub

'-------------------------------------------------
Sub Dogm_clear
  Dogm_pushcommand &H01                                     'Clear senden
  Waitms 2                                                  'Timeout abwarten
End Sub
'*************************** The Very End **********************************************