v0.6 - Some more LCD info and clean-up of the Unilink recovery code, some problems...
authorWerner Johansson <wj@xnk.nu>
Sun, 9 Mar 2003 15:40:52 +0000 (07:40 -0800)
committerWerner Johansson <wj@xnk.nu>
Sun, 17 Oct 2010 00:34:29 +0000 (17:34 -0700)
Signed-off-by: Werner Johansson <wj@xnk.nu>

wj-uni.asm

index 08ddc24..c6e4840 100644 (file)
 ;----------------------------------------------------------------\r
 ;  TODO\r
 ;----------------------------------------------------------------\r
-;  Fix the DelayW routine so it actually delays W/10 ms...\r
 ;  No checksum checking is done on incoming packets\r
-;  Investigate whether I actually have to save PCLATH in ISH, maybe save FSR?\r
+;  Investigate whether I actually have to save PCLATH in ISH, maybe save FSR? - Not saving any of them for now\r
 ;  Move RS232 code into ISH\r
 ;  Check Overrun errors from the UART\r
 ;  Implement lots of other Unilink commands (Text display, time display etc.)\r
 ;  Implement the Watchdog Timer (might be useful even though I haven't seen it hang yet..)\r
+;  Make the bit shift routine at the beginning of the ISR timeout if the clock suddenly stops (in the middle of a byte)\r
+;   (will keep it from hanging until the next bit gets clocked out, just ignore the faulty bits and carry on)\r
 \r
 ;----------------------------------------------------------------\r
 ;  HISTORY\r
 ;----------------------------------------------------------------\r
 ;  Version\r
 ;\r
+;  0.6  Some more LCD info and clean-up of the Unilink recovery code, some problems with master resetting :(\r
 ;  0.5  Issues slave breaks seemingly without hickups (!)\r
 ;  0.4  Some fixups in the bootstrap code (I actually had to put the PIC in my PICSTART Plus programmer again :))\r
 ;  0.3  Implementing more Unilink commands and RingIndicator control (to wake the computer from sleep)\r
@@ -157,7 +159,8 @@ e_LEN               equ     6fh
 Counter                equ     70h\r
 DataCount      equ     71h             ; Temp storage for the bit counter used during bit shifts (Unilink TX/RX)\r
 DataStore      equ     72h             ; This is a kludge\r
-\r
+DisplayCounter equ     73h\r
+UnilinkAttenuation     equ     74h     ; The amount of attenuation the volume control is currently set to\r
 IRQPCLATH      equ     7dh             ; ISH storage\r
 IRQSTATUS      equ     7eh             ; Needs to be located in a shared area accessible from all register banks\r
 IRQW           equ     7fh             ; \r
@@ -626,6 +629,26 @@ IRQINTParse87PowerOn
 \r
 IRQINTParseNot87\r
 \r
+; Check for CMD1 = 90h (Display/DSP info, volume etc.)\r
+       movf    UnilinkCMD1,w\r
+       xorlw   090h\r
+       bnz     IRQINTParseNot90\r
+\r
+; Check for 90 10 (Current Volume)\r
+       movf    UnilinkCMD2,w\r
+       xorlw   010h\r
+       bnz     IRQINTParseNot9010\r
+\r
+       movf    UnilinkData1,w          ; Store current volume setting\r
+       movwf   UnilinkAttenuation\r
+\r
+       goto    IRQINTParseComplete     ; Don't send any reply to this (clear the packet buffer though)\r
+\r
+IRQINTParseNot9010\r
+\r
+\r
+IRQINTParseNot90\r
+\r
 ; Check for CMD1 = f0h (Source Select)\r
        movf    UnilinkCMD1,w\r
        xorlw   0f0h\r
@@ -676,14 +699,14 @@ IRQNotINT
        btfss   PIR1,TMR2IF             ; Check if it's the TMR2 interrupt (0.5ms timing)\r
        goto    IRQNotTMR2              ; No it's not, check the other sources\r
 \r
+       incf    Counter,f               ; Increment the general purpose counter (increments every 0.5ms)\r
+\r
 ; Slave break opportunity detection here - the logic works as follows:\r
 ; Look for a data low period of at least 5 ms (10 loops)\r
 ; Look for a data high period of at least 2 ms (4 loops)\r
 ; If the Slave Break request bit has been set, issue a slave break by holding the data line low for 4ms (8 loops)\r
 ; If a bit would be received (CLK activates) the packet handler automatically clears out the SlaveBreakState, which means start all over\r
 \r
-;      incf    Counter,f               ; Increment the general purpose counter\r
-\r
        btfsc   SlaveBreakState,5       ; Check if already pulling the data line low\r
        goto    IRQTMR2SlaveBreak\r
 \r
@@ -721,7 +744,7 @@ IRQTMR2LowDataOK
 \r
        clrf    SlaveBreakState\r
 \r
-       incf    Counter,f\r
+;      incf    Counter,f\r
 \r
        btfss   DisplayStatus,7         ; Only do this if high bit is set\r
        goto    IRQAfterTMR2\r
@@ -827,11 +850,25 @@ ClearUnilinkBuffer
 ; Here all other house keeping tasks are performed, like displaying info on the LCD.. \r
 \r
 Main\r
-       movlw   high LookUp\r
+       movlw   high LookUp             ; Set the high PC bits to indicate data lookup page\r
        movwf   PCLATH\r
 \r
-       movlw   low StartUpText1        ; Show something on the LCD\r
-       call    TxLCD16B\r
+       movlw   0ffh\r
+       movwf   UnilinkAttenuation\r
+\r
+       movlw   8                       ; Display page timing (approx 8/sec)\r
+       movwf   DisplayCounter\r
+\r
+       bcf     LCD_RS_BIT              ; LCD Command mode\r
+       movlw   80h                     ; DisplayRam 0\r
+       call    TxLCDB\r
+       bsf     LCD_RS_BIT\r
+\r
+       movlw   low DefaultText1\r
+       movwf   Icount\r
+       movlw   80\r
+       movwf   e_LEN\r
+       call    TxLCD8BLoop             ; Send 80 bytes to the LCD\r
 \r
 MainLoop\r
 \r
@@ -870,6 +907,84 @@ MainLoop
 \r
 MainDontPrintCmd\r
 \r
+; Default text (see data declarations for actual text)\r
+; UnilinkID @ 11-12\r
+; UnilinkAttenuation @ 16-17\r
+; UnilinkSelected @ 53-54\r
+; DisplayStatus @ 62-63\r
+\r
+       bcf     LCD_RS_BIT              ; LCD Command mode\r
+       movlw   80h+11                  ; DisplayRam 11\r
+       call    TxLCDB\r
+       bsf     LCD_RS_BIT\r
+\r
+       movf    UnilinkID,w\r
+       call    TxLCDHEX\r
+\r
+       bcf     LCD_RS_BIT              ; LCD Command mode\r
+       movlw   80h+16                  ; DisplayRam 16\r
+       call    TxLCDB\r
+       bsf     LCD_RS_BIT\r
+\r
+       movf    UnilinkAttenuation,w\r
+       call    TxLCDHEX\r
+\r
+       bcf     LCD_RS_BIT              ; LCD Command mode\r
+       movlw   80h+40h+13              ; DisplayRam 53\r
+       call    TxLCDB\r
+       bsf     LCD_RS_BIT\r
+\r
+       movf    UnilinkSelected,w\r
+       call    TxLCDHEX\r
+\r
+       bcf     LCD_RS_BIT              ; LCD Command mode\r
+       movlw   80h+40h+22              ; DisplayRam 62\r
+       call    TxLCDB\r
+       bsf     LCD_RS_BIT\r
+\r
+       movf    DisplayStatus,w\r
+       call    TxLCDHEX\r
+\r
+; This part handles display "scroll" by shifting one screen at a time\r
+\r
+       btfss   Counter,7               ; Test high bit\r
+       goto    MainCounterLow\r
+\r
+; So bit is high, set high bit of displaycounter as well...\r
+       bsf     DisplayCounter,7\r
+       goto    MainSkipScroll\r
+\r
+MainCounterLow\r
+; OK, bit is low, now figure out whether it was high or low last time -> check high bit of DisplayCounter\r
+       btfss   DisplayCounter,7\r
+       goto    MainSkipScroll\r
+\r
+       bcf     DisplayCounter,7        ; Clear the high bit to allow countdown to commence\r
+       movf    Counter,w               ; Load it\r
+       skpz\r
+       goto    MainSkipScroll\r
+       decfsz  DisplayCounter,f\r
+       goto    MainSkipScroll\r
+       \r
+       movlw   8\r
+       movwf   DisplayCounter\r
+\r
+       bcf     LCD_RS_BIT              ; LCD Command mode\r
+       movlw   18h                     ; Display shift Left\r
+       call    TxLCDB                  ; Shift it 8 positions\r
+       call    TxLCDB\r
+       call    TxLCDB\r
+       call    TxLCDB\r
+       call    TxLCDB\r
+       call    TxLCDB\r
+       call    TxLCDB\r
+       call    TxLCDB\r
+       bsf     LCD_RS_BIT\r
+       \r
+MainSkipScroll\r
+\r
+; Display scroll part ends here...\r
+\r
        movf    DataCount,w             ; Load bit counter (if 0 then byte is available)\r
        skpz\r
        goto    MainLoop\r
@@ -1001,10 +1116,48 @@ LCDInit
 \r
        movlw   06h                     ; Auto Increment cursor position\r
        call    TxLCDB\r
-       \r
+\r
+       bsf     LCD_RS_BIT              ; Accept data\r
+\r
        return\r
    \r
 ;----------------------------------------------------------------\r
+;  TxLCDHEX\r
+;  Sends two characters hex to the LCD\r
+\r
+TxLCDHEX\r
+\r
+; Original binary to 2-digit hex conversion from piclist.com, modified to fit here\r
+\r
+       movwf   Icount\r
+       swapf   Icount,w\r
+       andlw   0x0f\r
+\r
+       addlw   6\r
+       skpndc\r
+       addlw   'A'-('9'+1)\r
+       addlw   '0'-6\r
+\r
+       xorwf   Icount,w\r
+       xorwf   Icount,f\r
+       xorwf   Icount,w\r
+\r
+       andlw   0x0f\r
+\r
+       addlw   6\r
+       skpndc\r
+       addlw   'A'-('9'+1)\r
+       addlw   '0'-6\r
+\r
+       movwf   e_LEN\r
+       movf    Icount,w\r
+       call    TxLCDB\r
+       movf    e_LEN,w\r
+       call    TxLCDB\r
+\r
+       return\r
+\r
+;----------------------------------------------------------------\r
 ;  TxLCD16B\r
 ;  Send a string to the LCD.\r
 \r
@@ -1031,12 +1184,13 @@ TxLCD8B
        movlw   8\r
        movwf   e_LEN                   ; Move to e_LEN\r
 \r
-Txm_lp movf    Icount,w                ; get the byte\r
+TxLCD8BLoop\r
+       movf    Icount,w                ; get the byte\r
        call    LookUp\r
        incf    Icount,f                ; ...else ++Icount (table index)\r
        call    TxLCDB                  ; Send out the byte\r
        decfsz  e_LEN,f\r
-       goto    Txm_lp\r
+       goto    TxLCD8BLoop\r
        return\r
 \r
 ;----------------------------------------------------------------\r
@@ -1067,6 +1221,7 @@ NotReady
        call    TxLCD                   ; And send that one as well\r
 \r
        return\r
+\r
 ;----------------------------------------------------------------\r
 ; RxLCDB - recv a byte from the LCD\r
 \r
@@ -1167,11 +1322,18 @@ DelayInner
 ;  Data can be stored between 600 and 6ffh...\r
 \r
        org     600h\r
-StartUpText1\r
-       DT      "----- WJ UniLink"\r
 \r
-InfoText1\r
-       DT      "WJ UniLink      "               \r
+; Default text\r
+; UnilinkID @ 11-12\r
+; UnilinkAttenuation @ 16-17\r
+; UnilinkSelected @ 53-54\r
+; DisplayStatus @ 62-63\r
+\r
+DefaultText1\r
+       DT      "----- WJ", "ID:xx Se", "xx dB at", "LCDPage3", "LCDPage4"\r
+       DT      " Unilink", "lect:xx ", "t Dsp:xx", " Right 3", " Right 4"\r
+\r
+               \r
 LookUp movwf   PCL                     ; Go to it (this assumes PCLATH == 06h)\r
 \r
 \r
@@ -1218,7 +1380,8 @@ Bootstrap
        movlw   low BootStartText       ; Send boot banner to the serial port\r
        call    BootTXStr\r
 \r
-       movlw   0e8h                    ; Initialize timeout timer\r
+;      movlw   0e8h                    ; Initialize timeout timer (e8 is about 3 secs)\r
+       movlw   0fdh                    ; Initialize timeout timer (e8 is about 3 secs)\r
        movwf   BootTimerL\r
        movwf   BootTimerM\r
        movwf   BootTimerH\r
@@ -1391,10 +1554,14 @@ BootRXW1
 \r
 BootRXHEXNibble\r
        call    BootRXB                 ; Receive nibble\r
+\r
+; This code is from piclist.com, really neat!\r
+\r
        addlw   -'A'                    ; Convert from BCD to binary nibble\r
        skpc                            ; Test if if was 0-9 or A-F, skip if A-F\r
        addlw  'A' - 10 - '0'           ; It was numeric '0'\r
        addlw   10                      ; Add 10 (A get to be 0ah etc.)\r
+\r
        return\r
 \r
 ;----------------------------------------------------------------------\r