- title "PIC16F870 Unilink(R) Interface by Werner Johansson (c) 2003"\r
+ title "PIC16F870 Unilink(R) Interface by Werner Johansson (c) 2002-2003"\r
subtitl "Definitions"\r
list c=150,P=16F870,R=DEC,F=inhx8m\r
include "p16f870.inc" ; Standard equates & Macros\r
;----------------------------------------------------------------\r
; Version\r
;\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
; 0.2 First attempt at responding to the Anyone command\r
;----------------------------------------------------------------\r
; FILE REGISTER USAGE\r
;----------------------------------------------------------------\r
-Dcount equ 20h\r
-e_LEN equ 21h\r
-\r
-Counter equ 22h\r
-SlaveBreakState equ 23h ; Hold state and time-out information about slave break, indicates when it can happen\r
-Icount equ 2Dh ; Offset of string to print\r
-TxTemp equ 2Eh ; blahblah\r
-TxTemp2 equ 2Fh ; Blahblah2\r
-\r
-LCDWTmp equ 30h\r
-Dcount2 equ 31h\r
-temp equ 32h\r
-\r
-DataCount equ 33h ; Temp storage for the bit counter used during bit shifts (Unilink TX/RX)\r
-DataStore equ 34h ; This is a kludge\r
-\r
-UnilinkSelected equ 3bh\r
-UnilinkBit equ 3ch ; This is my "bitmask" to be used for requests\r
-UnilinkID equ 3dh ; This is my Bus ID\r
-UnilinkCmdLen equ 3eh ; This gets updated with the actual packet length after CMD1 has been received\r
-UnilinkTXRX equ 3fh ; This is a pointer to the Unilink packet below, used with indirect addressing\r
-\r
-UnilinkRAD equ 40h ; Beginning of Unilink packet - the Receiving Address\r
-UnilinkTAD equ 41h ; Transmitter address\r
-UnilinkCMD1 equ 42h ; CMD1 byte\r
-UnilinkCMD2 equ 43h ; CMD2 byte\r
-UnilinkParity1 equ 44h ; First or only parity byte for short packets (6 bytes)\r
-UnilinkData1 equ 45h ; Extra data for medium/large packets, or zero for short packets\r
-UnilinkData2 equ 46h ;\r
-UnilinkData3 equ 47h ;\r
-UnilinkData4 equ 48h ;\r
-UnilinkData5 equ 49h ; Data5 if this is a large packet\r
-UnilinkParity2M equ 49h ; Parity2 shares the same byte if it's a medium sized packet\r
-UnilinkData6 equ 4ah ; Extra data for large packets, or zero for medium packets\r
-UnilinkData7 equ 4bh ;\r
-UnilinkData8 equ 4ch ;\r
-UnilinkData9 equ 4dh ;\r
-UnilinkParity2 equ 4eh ; Parity byte for large packets\r
-UnilinkZero equ 4fh ; Should always be zero (possibly used to signal corrupt packets from slave to master?)\r
+TrackName00 equ 20h ; Buffer for TrackName\r
+TrackName01 equ 21h\r
+TrackName02 equ 22h\r
+TrackName03 equ 23h\r
+TrackName04 equ 24h\r
+TrackName05 equ 25h\r
+TrackName06 equ 26h\r
+TrackName07 equ 27h\r
+TrackName08 equ 28h\r
+TrackName09 equ 29h\r
+TrackName0a equ 2ah\r
+TrackName0b equ 2bh\r
+TrackName0c equ 2ch\r
+TrackName0d equ 2dh\r
+TrackName0e equ 2eh\r
+TrackName0f equ 2fh\r
+TrackName10 equ 30h\r
+TrackName11 equ 31h\r
+TrackName12 equ 32h\r
+TrackName13 equ 33h\r
+TrackName14 equ 34h\r
+TrackName15 equ 35h\r
+TrackName16 equ 36h\r
+TrackName17 equ 37h\r
+TrackName18 equ 38h\r
+TrackName19 equ 39h\r
+TrackName1a equ 3ah\r
+TrackName1b equ 3bh\r
+TrackName1c equ 3ch\r
+TrackName1d equ 3dh\r
+TrackName1e equ 3eh\r
+TrackName1f equ 3fh\r
+TrackName20 equ 40h\r
+TrackName21 equ 41h\r
+TrackName22 equ 42h\r
+TrackName23 equ 43h\r
+TrackName24 equ 44h\r
+TrackName25 equ 45h\r
+TrackName26 equ 46h\r
+TrackName27 equ 47h\r
+TrackName28 equ 48h\r
+TrackName29 equ 49h\r
+TrackName2a equ 4ah\r
+TrackName2b equ 4bh\r
+TrackName2c equ 4ch\r
+TrackName2d equ 4dh\r
+TrackName2e equ 4eh\r
+TrackName2f equ 4fh\r
+\r
+UnilinkRAD equ 50h ; Beginning of Unilink packet - the Receiving Address\r
+UnilinkTAD equ 51h ; Transmitter address\r
+UnilinkCMD1 equ 52h ; CMD1 byte\r
+UnilinkCMD2 equ 53h ; CMD2 byte\r
+UnilinkParity1 equ 54h ; First or only parity byte for short packets (6 bytes)\r
+UnilinkData1 equ 55h ; Extra data for medium/large packets, or zero for short packets\r
+UnilinkData2 equ 56h ;\r
+UnilinkData3 equ 57h ;\r
+UnilinkData4 equ 58h ;\r
+UnilinkData5 equ 59h ; Data5 if this is a large packet\r
+UnilinkParity2M equ 59h ; Parity2 shares the same byte if it's a medium sized packet\r
+UnilinkData6 equ 5ah ; Extra data for large packets, or zero for medium packets\r
+UnilinkData7 equ 5bh ;\r
+UnilinkData8 equ 5ch ;\r
+UnilinkData9 equ 5dh ;\r
+UnilinkParity2 equ 5eh ; Parity byte for large packets\r
+UnilinkZero equ 5fh ; Should always be zero (possibly used to signal corrupt packets from slave to master?)\r
+\r
+UnilinkTimeout equ 60h ; Counts up every 0.5ms to "age out" faulty bytes clocked in\r
+UnilinkSelected equ 61h ; High bit is set when selected\r
+UnilinkBit equ 62h ; This is my "bitmask" to be used for requests\r
+UnilinkID equ 63h ; This is my Bus ID\r
+UnilinkCmdLen equ 64h ; This gets updated with the actual packet length after CMD1 has been received\r
+UnilinkTXRX equ 65h ; This is a pointer to the Unilink packet above, used with indirect addressing\r
+SlaveBreakState equ 66h ; Hold state and time-out information about slave break, indicates when it can happen\r
+DisplayStatus equ 67h ; What information will be put on the display next, bit 7 cleared if nothing\r
+Icount equ 68h ; Offset of string to print\r
+TxTemp equ 69h ; blahblah\r
+TxTemp2 equ 6ah ; Blahblah2\r
+LCDWTmp equ 6bh\r
+Dcount2 equ 6ch\r
+temp equ 6dh\r
+Dcount equ 6eh\r
+e_LEN equ 6fh\r
+\r
+\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
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
+DiscName00 equ 0a0h ; Buffer for DiscName\r
+DiscName01 equ 0a1h\r
+DiscName02 equ 0a2h\r
+DiscName03 equ 0a3h\r
+DiscName04 equ 0a4h\r
+DiscName05 equ 0a5h\r
+DiscName06 equ 0a6h\r
+DiscName07 equ 0a7h\r
+DiscName08 equ 0a8h\r
+DiscName09 equ 0a9h\r
+DiscName0a equ 0aah\r
+DiscName0b equ 0abh\r
+DiscName0c equ 0ach\r
+DiscName0d equ 0adh\r
+DiscName0e equ 0aeh\r
+DiscName0f equ 0afh\r
+DiscName10 equ 0b0h\r
+DiscName11 equ 0b1h\r
+DiscName12 equ 0b2h\r
+DiscName13 equ 0b3h\r
+DiscName14 equ 0b4h\r
+DiscName15 equ 0b5h\r
+DiscName16 equ 0b6h\r
+DiscName17 equ 0b7h\r
+DiscName18 equ 0b8h\r
+DiscName19 equ 0b9h\r
+DiscName1a equ 0bah\r
+DiscName1b equ 0bbh\r
+DiscName1c equ 0bch\r
+DiscName1d equ 0bdh\r
+DiscName1e equ 0beh\r
+DiscName1f equ 0bfh\r
+\r
subtitl "Startup"\r
page\r
;----------------------------------------------------------------\r
swapf STATUS,w ; Get the status register into w\r
clrf STATUS ; Zero out the status reg, gives Reg Bank0\r
movwf IRQSTATUS ; Store the STATUS reg\r
- movf PCLATH,w ; Get the PCLATH reg\r
+; Not using PCLATH for anything in the ISR right now\r
+; movf PCLATH,w ; Get the PCLATH reg\r
; movwf IRQPCLATH ; And store it\r
; clrf PCLATH ; Go to low memory\r
; Maybe save FSR here as well (if there's a need for it in the non-ISR code)\r
andlw 0fh ; and mask - this results in a zero result when finished receiving\r
bnz IRQINTRecvIncomplete ; Packet not ready yet\r
\r
-; Here a packet is actually received a packet, should check the checksum(s) as well, but I don't care right now\r
+; Here a packet is actually received, should check the checksum(s) as well, but I don't care right now\r
; (I need music in my car! :))\r
; This is inefficient, I know, I'll improve it later... (Not that it matters, there's plenty of time here\r
; (there won't be any more communication for at least another 4.8ms))\r
\r
; Check for 01 00 (Bus Re-Initialization)\r
movf UnilinkCMD2,w\r
-; xorlw 00h\r
bnz IRQINTParseNot0100\r
\r
- clrf UnilinkID ; Clear the existing Unilink ID, if any\r
- bcf BUSON_OUT_BIT ; Clear the cascade BUSON pin, not activated again until we have a new ID\r
+ call ClearUnilinkStatus ; Clear everything Unilink (ID, BUSON_OUT)\r
\r
- goto IRQINTParseComplete ; Don't send any reply to this\r
+ goto IRQINTParseComplete ; Don't send any reply to this (clear the packet buffer though)\r
\r
IRQINTParseNot0100\r
\r
movf UnilinkID,w ; Do I have an ID already?\r
bnz IRQINTParseNot0102 ; Yep, I don't want another one!\r
\r
+; clrf UnilinkParity1\r
+ call ClearUnilinkBuffer ; Zero it out completely\r
+\r
movlw 10h ; Sending to Master\r
+ addwf UnilinkParity1,f\r
movwf UnilinkRAD\r
movlw 0d0h ; I'm in the MD changer group\r
+ addwf UnilinkParity1,f\r
movwf UnilinkTAD\r
movlw 8ch ; Device discovery command reply\r
+ addwf UnilinkParity1,f\r
movwf UnilinkCMD1\r
- movlw 00h ; 00??\r
+ movlw 10h ; 00??\r
+ addwf UnilinkParity1,f\r
movwf UnilinkCMD2\r
- movlw 6ch ; Hard coded parity (!)\r
- movwf UnilinkParity1\r
+\r
+ movf UnilinkParity1,w\r
+ movwf UnilinkParity2M\r
+\r
movlw 24h ; My internal MD sends 25 here first time, and then 24 when appointed!??\r
+ addwf UnilinkParity2M,f\r
movwf UnilinkData1\r
- movlw 2ch ; 2c??\r
+ movlw 0a8h ; 2c??\r
+ addwf UnilinkParity2M,f\r
movwf UnilinkData2\r
- movlw 22h ; 22??\r
+ movlw 17h ; 22??\r
+ addwf UnilinkParity2M,f\r
movwf UnilinkData3\r
- movlw 00h ; 00??\r
+ movlw 0a0h ; 00?? 0a0=10 disc?\r
+ addwf UnilinkParity2M,f\r
movwf UnilinkData4\r
- movlw 0deh ; Hard coded parity 2 (!)\r
- movwf UnilinkData5\r
- clrf UnilinkData6\r
+\r
+; clrf UnilinkData6\r
goto IRQINTParseBypassClear ; Don't clear the data, the buffer will be sent as the next packet\r
\r
IRQINTParseNot0102\r
xorwf UnilinkID,w ; Is it for me?\r
bnz IRQINTParseNot0112 ; Nope\r
\r
- clrf UnilinkParity1\r
+; clrf UnilinkParity1\r
+ call ClearUnilinkBuffer\r
movlw 10h ; Sending to Master\r
addwf UnilinkParity1,f\r
movwf UnilinkRAD\r
\r
addwf UnilinkParity1,f\r
movwf UnilinkCMD2\r
- clrf UnilinkData6\r
+; clrf UnilinkData1\r
goto IRQINTParseBypassClear ; Don't clear the data, the buffer will be sent as the next packet\r
\r
IRQINTParseNot0112\r
\r
+; Check for 01 13 (Request Time poll)\r
+ movf UnilinkCMD2,w\r
+ xorlw 13h\r
+ bnz IRQINTParseNot0113\r
+\r
+ movf UnilinkRAD,w\r
+ xorwf UnilinkID,w ; Is it for me?\r
+ bnz IRQINTParseNot0113 ; Nope\r
+\r
+ btfss DisplayStatus,7 ; If not displaying, skip this\r
+ goto IRQINTParseComplete\r
+\r
+; clrf UnilinkParity1\r
+ call ClearUnilinkBuffer\r
+ movlw 70h ; Sending to Display Group\r
+ addwf UnilinkParity1,f\r
+ movwf UnilinkRAD\r
+ movf UnilinkID,w ; This is my ID\r
+ addwf UnilinkParity1,f\r
+ movwf UnilinkTAD\r
+ movlw 90h\r
+ addwf UnilinkParity1,f\r
+ movwf UnilinkCMD1\r
+ movlw 50h\r
+ addwf UnilinkParity1,f\r
+ movwf UnilinkCMD2\r
+\r
+ movf UnilinkParity1,w ; Carry the parity forward\r
+ movwf UnilinkParity2M\r
+\r
+; movlw 01h\r
+ movf DisplayStatus,w\r
+ addwf UnilinkParity2M,f\r
+ movwf UnilinkData1\r
+ movlw 00h\r
+ addwf UnilinkParity2M,f\r
+ movwf UnilinkData2\r
+ movlw 01h\r
+ addwf UnilinkParity2M,f\r
+ movwf UnilinkData3\r
+; movlw 0c0h\r
+ movf DisplayStatus,w\r
+ andlw 0f0h\r
+ addwf UnilinkParity2M,f\r
+ movwf UnilinkData4\r
+ \r
+; clrf UnilinkData6\r
+\r
+ incf DisplayStatus,f ; Temporary debug info\r
+ bsf DisplayStatus,7\r
+\r
+ goto IRQINTParseBypassClear ; Don't clear the data, the buffer will be sent as the next packet\r
+\r
+IRQINTParseNot0113\r
+\r
+; Check for 01 15 (Who sent the slave break?)\r
+ movf UnilinkCMD2,w\r
+ xorlw 15h\r
+ bnz IRQINTParseNot0115\r
+\r
+ btfss DisplayStatus,7 ; First of all check if there should be anything displayed\r
+ goto IRQINTParseComplete ; No, not at this time\r
+ \r
+; clrf UnilinkParity1\r
+ call ClearUnilinkBuffer\r
+ movlw 10h ; Sending to Master\r
+ addwf UnilinkParity1,f\r
+ movwf UnilinkRAD\r
+ movlw 18h ; Broadcast address sending in this special case\r
+ addwf UnilinkParity1,f\r
+ movwf UnilinkTAD\r
+ movlw 82h ; Who wants to talk reply command\r
+ addwf UnilinkParity1,f\r
+ movwf UnilinkCMD1\r
+\r
+ clrw\r
+ call Bit_Frig\r
+ addwf UnilinkParity1,f\r
+ movwf UnilinkCMD2\r
+\r
+ movf UnilinkParity1,w ; Carry the parity forward\r
+ movwf UnilinkParity2M\r
+\r
+ movlw 20h\r
+ call Bit_Frig\r
+ addwf UnilinkParity2M,f\r
+ movwf UnilinkData1\r
+ movlw 40h\r
+ call Bit_Frig\r
+ addwf UnilinkParity2M,f\r
+ movwf UnilinkData2\r
+ movlw 60h\r
+ call Bit_Frig\r
+ addwf UnilinkParity2M,f\r
+ movwf UnilinkData3\r
+ movlw 80h\r
+ call Bit_Frig\r
+ addwf UnilinkParity2M,f\r
+ movwf UnilinkData4\r
+\r
+; clrf UnilinkData6\r
+\r
+ goto IRQINTParseBypassClear ; Don't clear the data, the buffer will be sent as the next packet\r
+\r
+;******************************************************************************\r
+; Bit frig - works out which bit to set in the response to Master Poll\r
+\r
+; W register is input of which stage you are on (0x00, 0x20, 0x30, 0x40 etc)\r
+; and is returned with the byte to write (0x00 if wrong stage).\r
+\r
+Bit_Frig:\r
+ xorwf UnilinkBit, 0\r
+ andlw 0xe0 ; Strip off low bits\r
+\r
+ btfsc STATUS, Z ; Do we have a hit?\r
+ goto Bit_Frig_Hit\r
+\r
+ movlw 0x00\r
+ return\r
+\r
+Bit_Frig_Hit:\r
+ btfss UnilinkBit, 4 ; Do we need to swap nybbles?\r
+ goto Bit_Frig_Swap\r
+\r
+ movf UnilinkBit, 0\r
+ andlw 0x0F\r
+ return\r
+\r
+Bit_Frig_Swap:\r
+ swapf UnilinkBit, 0\r
+ andlw 0xF0\r
+ return\r
+\r
+IRQINTParseNot0115\r
+\r
IRQINTParseNot01\r
\r
; Check for CMD1 = 02h (Appoint)\r
movf UnilinkCMD2,w ; Get the bitmask\r
movwf UnilinkBit ; And store it (this is needed when doing slave breaks and actually responding)\r
\r
- clrf UnilinkParity1\r
+; clrf UnilinkParity1\r
+ call ClearUnilinkBuffer\r
movlw 10h ; Sending to Master\r
addwf UnilinkParity1,f\r
movwf UnilinkRAD\r
movlw 8ch ; Device discovery command again\r
addwf UnilinkParity1,f\r
movwf UnilinkCMD1\r
- movlw 00h\r
+ movlw 10h\r
addwf UnilinkParity1,f\r
movwf UnilinkCMD2\r
\r
movlw 24h\r
addwf UnilinkParity2M,f\r
movwf UnilinkData1\r
- movlw 2ch ; My internal MD sends 1c here... (external/internal difference)\r
+ movlw 0a8h ; My internal MD sends 1c here... (external/internal difference)\r
addwf UnilinkParity2M,f\r
movwf UnilinkData2\r
- movlw 22h\r
+ movlw 17h\r
addwf UnilinkParity2M,f\r
movwf UnilinkData3\r
- movlw 00h\r
+ movlw 0a0h ; 0a0=10disc\r
addwf UnilinkParity2M,f\r
movwf UnilinkData4\r
\r
- clrf UnilinkData6\r
+; clrf UnilinkData6\r
goto IRQINTParseBypassClear ; Don't clear the data, the buffer will be sent as the next packet\r
\r
IRQINTParseNot02\r
bnz IRQINTParseF0Deselect\r
\r
bsf UnilinkSelected,7 ; Now we're selected\r
+ bsf DisplayStatus,7\r
goto IRQINTParseComplete\r
\r
IRQINTParseF0Deselect\r
\r
bcf UnilinkSelected,7 ; Now we're de-selected\r
+ bcf DisplayStatus,7\r
goto IRQINTParseComplete\r
\r
IRQINTParseNotF0\r
\r
IRQINTParseComplete\r
\r
-; The CPU ends up here when parsing is complete and it's not interested in sending any reply back to the master\r
+; The code ends up here when parsing is complete and it's not interested in sending any reply back to the master\r
; (that's why we clear out all the packet buffer bytes)\r
-; TODO: Replace this with an FSR access to save space and make the code neater\r
\r
- clrf UnilinkRAD\r
- clrf UnilinkTAD\r
- clrf UnilinkCMD1\r
- clrf UnilinkCMD2\r
- clrf UnilinkParity1\r
- clrf UnilinkData1\r
- clrf UnilinkData2\r
- clrf UnilinkData3\r
- clrf UnilinkData4\r
- clrf UnilinkData5\r
- clrf UnilinkData6\r
- clrf UnilinkData7\r
- clrf UnilinkData8\r
- clrf UnilinkData9\r
- clrf UnilinkParity2\r
- clrf UnilinkZero\r
+ call ClearUnilinkBuffer\r
\r
IRQINTParseBypassClear\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 5ms (10 loops)\r
-; If a packet would be received the packet handler automatically clears out the SlaveBreakState, which means start all over\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 DATA_BIT ; Looking for a high data line, if it's high - increment state, otherwise wait\r
goto IRQTMR2HighDataOK\r
movlw 080h\r
- btfss SlaveBreakState,6 ; Test the "first time around" bit\r
+ btfsc SlaveBreakState,6 ; Test the "first time around" bit\r
clrw ; Not the beginning of the state, have to restart the entire thing now, not just this state\r
andwf SlaveBreakState,f ; Mask out the 1 upper control bits and restart this state\r
goto IRQAfterTMR2\r
IRQTMR2HighDataOK\r
IRQTMR2LowDataOK\r
bsf SlaveBreakState,6 ; Set the "first time around" bit\r
- btfss SlaveBreakState,4 ; Only increment to 0x10\r
- incf SlaveBreakState,f\r
\r
movf SlaveBreakState,w\r
andlw 1fh\r
goto IRQAfterTMR2\r
\r
; Issue slave break here\r
+\r
+ clrf SlaveBreakState\r
+\r
incf Counter,f\r
-; clrf SlaveBreakState\r
+\r
+ btfss DisplayStatus,7 ; Only do this if high bit is set\r
+ goto IRQAfterTMR2\r
+\r
movlw 20h\r
movwf SlaveBreakState\r
bcf DATA_BIT\r
goto IRQAfterTMR2\r
\r
IRQTMR2FoundLow\r
- xorlw 7\r
+ xorlw 10\r
skpz\r
goto IRQAfterTMR2\r
movlw 80h ; Prepare for state 2, looking for data line high\r
IRQTMR2SlaveBreak\r
movf SlaveBreakState,w\r
andlw 01fh\r
- xorlw 4\r
+ xorlw 8\r
skpz\r
goto IRQAfterTMR2\r
bsf STATUS,RP0\r
clrf SlaveBreakState\r
\r
IRQAfterTMR2\r
+ btfss SlaveBreakState,4 ; Only increment to 0x10\r
+ incf SlaveBreakState,f\r
bcf PIR1,TMR2IF ; Clear the IRQ source bit to re-enable TMR2 interrupts again\r
\r
IRQNotTMR2\r
swapf IRQW,w ; Restore W\r
retfie ; Interrupt return\r
\r
+;----------------------------------------------------------------\r
+; ClearUnilinkStatus - Zeroes out the Unilink state (used when initializing)\r
+\r
+ClearUnilinkStatus\r
+\r
+ clrf UnilinkID ; Clear the existing Unilink ID, if any\r
+ bcf BUSON_OUT_BIT ; Clear the cascade BUSON pin, not activated again until we have a new ID\r
+ clrf DisplayStatus ; No crazy display updates when resetting.. :)\r
+ clrf UnilinkSelected ; We're not selected anymore\r
+\r
+ bsf STATUS,RP0 ; Reg bank 1\r
+ bsf DATA_BIT ; Make sure data is tristated\r
+ bcf STATUS,RP0 ; Reg bank 0\r
+\r
+ movlw UnilinkRAD ; Get the pointer to the first byte in the receive buffer\r
+ movwf UnilinkTXRX ; Store it - this way the next byte that gets received goes into RAD\r
+\r
+ clrf UnilinkCmdLen ; No command length while waiting for a new packet\r
+\r
+ return\r
+ \r
+;----------------------------------------------------------------\r
+; ClearUnilinkBuffer - Zeroes out the Unilink packet buffer\r
+\r
+ClearUnilinkBuffer\r
+\r
+; TODO: Replace this with an FSR access to save space and make the code neater\r
+ clrf UnilinkRAD\r
+ clrf UnilinkTAD\r
+ clrf UnilinkCMD1\r
+ clrf UnilinkCMD2\r
+ clrf UnilinkParity1\r
+ clrf UnilinkData1\r
+ clrf UnilinkData2\r
+ clrf UnilinkData3\r
+ clrf UnilinkData4\r
+ clrf UnilinkData5\r
+ clrf UnilinkData6\r
+ clrf UnilinkData7\r
+ clrf UnilinkData8\r
+ clrf UnilinkData9\r
+ clrf UnilinkParity2\r
+ clrf UnilinkZero\r
+\r
+ return\r
+\r
\r
subtitl "Main loop"\r
page\r
\r
;----------------------------------------------------------------\r
-; Main program begins here. [Called after bootloader, lcdinit and irqinit...]\r
+; Main program begins here. [Called after bootloader, lcdinit and irqinit...]\r
+; Here all other house keeping tasks are performed, like displaying info on the LCD.. \r
\r
-; org 100h ; Maybe not force this to a specific address later\r
Main\r
movlw high LookUp\r
movwf PCLATH\r
\r
; movlw '0'\r
movf SlaveBreakState,w\r
+ andlw 80h\r
btfsc PORTB,0 ; Test CLK\r
movlw 'C'\r
call TxLCDB\r
; Start with clearing the Unilink packet buffer before enabling any interrupts, otherwise the first packet might become corrupt\r
; TODO: Replace this with FSR access\r
clrf UnilinkSelected\r
+ clrf DisplayStatus\r
clrf UnilinkID\r
clrf UnilinkBit\r
clrf UnilinkCmdLen\r
org 600h\r
StartUpText1\r
DT "----- WJ UniLink"\r
- \r
+\r
+InfoText1\r
+ DT "WJ UniLink " \r
LookUp movwf PCL ; Go to it (this assumes PCLATH == 06h)\r
\r
\r