;----------------------------------------------------------------\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
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
\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
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
\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
; 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
\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
\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
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
call TxLCD ; And send that one as well\r
\r
return\r
+\r
;----------------------------------------------------------------\r
; RxLCDB - recv a byte from the LCD\r
\r
; 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
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
\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