X-Git-Url: http://git.xnk.nu/?p=wj-unilink.git;a=blobdiff_plain;f=wj-uni.asm;h=c1623e0be2b719b2130a5770bf1139bf591070ed;hp=69624e62955af3d5e02108ca56ff6d1dacda0f77;hb=HEAD;hpb=68e0b7acbba32b2b6786ce364128377fae40572f diff --git a/wj-uni.asm b/wj-uni.asm index 69624e6..c1623e0 100644 --- a/wj-uni.asm +++ b/wj-uni.asm @@ -33,13 +33,13 @@ ;---------------------------------------------------------------- ; TODO ;---------------------------------------------------------------- +; Check how the slave should sense "power off" de-selection. Now it continues to play, as the slave doesn't stop requesting updates! ; Investigate whether I actually have to save PCLATH in ISH, maybe save FSR? - Not saving any of them for now ; Check Overrun errors from the UART -; Implement lots of other Unilink commands (Text display, time display etc.) ; Implement the Watchdog Timer (might be useful even though I haven't seen it hang yet..) ; Make the bit shift routine at the beginning of the ISR timeout if the clock suddenly stops (in the middle of a byte) ; (will keep it from hanging until the next bit gets clocked out, just ignore the faulty bits and carry on) -; Implement command b0 0x (change CD to x (1-a)) +; Implement command b0 0x (change CD to x (1-a))? ; Implement command 08 10 (Tel Mute on) and 08 18 (Tel Mute off)? ;---------------------------------------------------------------- @@ -47,6 +47,8 @@ ;---------------------------------------------------------------- ; Version ; +; 0.9 Interrupt driven UART RX for status updates, using raw unilink packets for everything else, dynamic text +; 0.8 Some text commands implemented, only static text for now though ; 0.7 Debug Serial TX in ISR now, checksum check for incoming packets in place, A/D works, solved the master reset prob ; (by calling the INT handler from TMR2 ISR code (too much interrupt latency when transmitting) ; 0.6 Some more LCD info and clean-up of the Unilink recovery code, some problems with master resetting :( @@ -95,54 +97,23 @@ ;---------------------------------------------------------------- ; FILE REGISTER USAGE ;---------------------------------------------------------------- -TrackName00 equ 20h ; Buffer for TrackName -TrackName01 equ 21h -TrackName02 equ 22h -TrackName03 equ 23h -TrackName04 equ 24h -TrackName05 equ 25h -TrackName06 equ 26h -TrackName07 equ 27h -TrackName08 equ 28h -TrackName09 equ 29h -TrackName0a equ 2ah -TrackName0b equ 2bh -TrackName0c equ 2ch -TrackName0d equ 2dh -TrackName0e equ 2eh -TrackName0f equ 2fh -TrackName10 equ 30h -TrackName11 equ 31h -TrackName12 equ 32h -TrackName13 equ 33h -TrackName14 equ 34h -TrackName15 equ 35h -TrackName16 equ 36h -TrackName17 equ 37h -TrackName18 equ 38h -TrackName19 equ 39h -TrackName1a equ 3ah -TrackName1b equ 3bh -TrackName1c equ 3ch -TrackName1d equ 3dh -TrackName1e equ 3eh -TrackName1f equ 3fh -TrackName20 equ 40h -TrackName21 equ 41h -TrackName22 equ 42h -TrackName23 equ 43h -TrackName24 equ 44h -TrackName25 equ 45h -TrackName26 equ 46h -TrackName27 equ 47h -TrackName28 equ 48h -TrackName29 equ 49h -TrackName2a equ 4ah -TrackName2b equ 4bh -TrackName2c equ 4ch -TrackName2d equ 4dh -TrackName2e equ 4eh -TrackName2f equ 4fh + +; Free from 20h-48h + +TrackName equ 20h +TracknameEnd equ 3eh + +DiscName equ 3fh +DiscNameEnd equ 48h + +CurDisc equ 49h +CurTrack equ 4ah +CurMins equ 4bh +CurSecs equ 4ch + +RecvType equ 4dh +TargetPos equ 4eh +CurRecvPos equ 4fh UnilinkRAD equ 50h ; Beginning of Unilink packet - the Receiving Address UnilinkTAD equ 51h ; Transmitter address @@ -196,38 +167,8 @@ IRQPCLATH equ 7dh ; ISH storage IRQSTATUS equ 7eh ; Needs to be located in a shared area accessible from all register banks IRQW equ 7fh ; -DiscName00 equ 0a0h ; Buffer for DiscName -DiscName01 equ 0a1h -DiscName02 equ 0a2h -DiscName03 equ 0a3h -DiscName04 equ 0a4h -DiscName05 equ 0a5h -DiscName06 equ 0a6h -DiscName07 equ 0a7h -DiscName08 equ 0a8h -DiscName09 equ 0a9h -DiscName0a equ 0aah -DiscName0b equ 0abh -DiscName0c equ 0ach -DiscName0d equ 0adh -DiscName0e equ 0aeh -DiscName0f equ 0afh -DiscName10 equ 0b0h -DiscName11 equ 0b1h -DiscName12 equ 0b2h -DiscName13 equ 0b3h -DiscName14 equ 0b4h -DiscName15 equ 0b5h -DiscName16 equ 0b6h -DiscName17 equ 0b7h -DiscName18 equ 0b8h -DiscName19 equ 0b9h -DiscName1a equ 0bah -DiscName1b equ 0bbh -DiscName1c equ 0bch -DiscName1d equ 0bdh -DiscName1e equ 0beh -DiscName1f equ 0bfh +RecvBuf equ 0a0h ; Buffer for received data from PC (32 bytes) +RecvBufEnd equ 0bfh ; subtitl "Startup" page @@ -319,7 +260,7 @@ IRQTMR2LowDataOK clrf SlaveBreakState -; incf Counter,f +; incf Counter,f : Debug! btfss DisplayStatus,7 ; Only do this if high bit is set goto IRQAfterTMR2 @@ -363,6 +304,119 @@ IRQAfterTMR2 IRQNotTMR2 + call IRQCheckINT ; Check the Unilink INT as well + + btfss PIR1,RCIF ; Check if it's the UART RX interrupt + goto IRQNotRCIF ; No it's not, check the other sources +;---------------------------------------------------------------- +; This is the UART RX routine, this should be control info from the connected PC we're receiving + + movf CurRecvPos,w ; Load fsr + movwf FSR + movf RCREG,w ; Get the byte + bcf PIR1,RCIF ; Clear current interrupt condition + movwf INDF ; Store the recv byte at the position waiting + movlw RecvType + xorwf FSR,w ; Check if it's the recvtype coming in + bnz NotRecvType + + call IRQCheckINT ; Check the Unilink INT as well + + movf RecvType,w ; Load type + bz RecvTimeUpdate ; Position update + xorlw 1 ; Track Name perhaps? + bz RecvTrackName + xorlw 3 ; this is xor 1 and then xor 2, disc name? + bz RecvDiscName + + call IRQCheckINT ; Check the Unilink INT as well + + btfss RecvType,7 ; Check Hi byte + goto IRQNotRCIF + + movf RecvType,w + xorlw 81h + bnz NotText + + call IRQCheckINT ; Check the Unilink INT as well + + movf RecvType,w + goto TextUpdate +NotText + call IRQCheckINT ; Check the Unilink INT as well + + movf RecvType,w + btfss DisplayStatus,7 ; Only if not updating already! +TextUpdate + movwf DisplayStatus ; Force it into DisplayStatus + goto Finished + +RecvTimeUpdate + movlw CurDisc ; Load DL start here + movwf CurRecvPos + movlw CurSecs+1 ; And stop here + movwf TargetPos + goto IRQNotRCIF + +RecvTrackName + movlw TrackName ; Load DL start here + movwf CurRecvPos + movlw TracknameEnd+1 ; And stop here + movwf TargetPos + goto IRQNotRCIF + +RecvDiscName + movlw DiscName ; Load DL start here + movwf CurRecvPos + movlw DiscNameEnd+1 ; And stop here + movwf TargetPos + goto IRQNotRCIF + +NotRecvType + incf CurRecvPos,f + + call IRQCheckINT ; Check the Unilink INT as well + + movf CurRecvPos,w ; Check if we're done + xorwf TargetPos,w + bnz NotFinished +Finished + call IRQCheckINT ; Check the Unilink INT as well + +; movlw 81h ; Assume we do it from the beginning (text and pos) +; movf RecvType,f ; Just check for time-update cmd +; skpnz ; No adjustment if another cmd +; movlw 85h ; Skip the first 4 display cmds +; movwf DisplayStatus + +; call IRQCheckINT ; Check the Unilink INT as well + + movlw RecvType ; restore for another go + movwf CurRecvPos + +NotFinished + +IRQNotRCIF + + call IRQCheckINT ; Check the Unilink INT as well + + btfss PIR1,TXIF ; Check if it's the UART TX interrupt + goto IRQNotTXIF ; No it's not, check the other sources + bsf STATUS,RP0 ; Reg bank 1 + btfss PIE1,TXIE ; As TXIF is set as long as nothing gets sent, is the interrupt actually enabled? + goto IRQTXIFDisabled +;---------------------------------------------------------------- +; This is the UART TX routine, gets called when TXIE has been set and the TX load register is empty + + + + + +IRQTXIFDisabled + bcf STATUS,RP0 ; Make sure we're going back to reg bank 0 + +IRQNotTXIF + ; Finally restore CPU state and return from the ISR ; If I have to save the FSR in the beginning I also need to restore it here... @@ -625,12 +679,18 @@ IRQINTParseNot0112 goto IRQINTParseComplete call ClearUnilinkBuffer + movlw 70h ; Sending to Display Group addwf UnilinkParity1,f movwf UnilinkRAD movf UnilinkID,w ; This is my ID addwf UnilinkParity1,f movwf UnilinkTAD + + movf DisplayStatus,w + xorlw 80h ; First slave break? + bnz IRQINTParse0113Not80 + movlw 90h addwf UnilinkParity1,f movwf UnilinkCMD1 @@ -641,25 +701,256 @@ IRQINTParseNot0112 movf UnilinkParity1,w ; Carry the parity forward movwf UnilinkParity2M - movf DisplayStatus,w + movf CurTrack,w addwf UnilinkParity2M,f movwf UnilinkData1 - movlw 00h + movf CurMins,w addwf UnilinkParity2M,f movwf UnilinkData2 - movlw 01h + movf CurSecs,w addwf UnilinkParity2M,f movwf UnilinkData3 ; movlw 0c0h + movf CurDisc,w +; andlw 0f0h +; iorlw 0eh + + addwf UnilinkParity2M,f + movwf UnilinkData4 + +; clrf DisplayStatus +; goto IRQINTParseBypassClear ; Don't clear the data, the buffer will be sent as the next packet + + goto IRQINTParse0113Complete + +IRQINTParse0113Not80 + + movf DisplayStatus,w + xorlw 81h ; Second slave break? + bnz IRQINTParse0113Not81 + + movlw 0cdh ; Disc name + addwf UnilinkParity1,f + movwf UnilinkCMD1 + movf DiscName,w + addwf UnilinkParity1,f + movwf UnilinkCMD2 + + movf UnilinkParity1,w ; Carry the parity forward + movwf UnilinkParity2 + + movf DiscName+1,w + addwf UnilinkParity2,f + movwf UnilinkData1 + movf DiscName+2,w + addwf UnilinkParity2,f + movwf UnilinkData2 + movf DiscName+3,w + addwf UnilinkParity2,f + movwf UnilinkData3 + movf DiscName+4,w + addwf UnilinkParity2,f + movwf UnilinkData4 + movf DiscName+5,w + addwf UnilinkParity2,f + movwf UnilinkData5 + movf DiscName+6,w + addwf UnilinkParity2,f + movwf UnilinkData6 + movf DiscName+7,w + addwf UnilinkParity2,f + movwf UnilinkData7 + movlw 00h + addwf UnilinkParity2,f + movwf UnilinkData8 + movlw 0eh + addwf UnilinkParity2,f + movwf UnilinkData9 + goto IRQINTParse0113Complete + +IRQINTParse0113Not81 + + movf DisplayStatus,w + xorlw 82h ; Third slave break? + bnz IRQINTParse0113Not82 + + movlw 0cdh ; Disc name + addwf UnilinkParity1,f + movwf UnilinkCMD1 + movf DiscName+8,w + addwf UnilinkParity1,f + movwf UnilinkCMD2 + + movf UnilinkParity1,w ; Carry the parity forward + movwf UnilinkParity2 + + movf DiscName+9,w + addwf UnilinkParity2,f + movwf UnilinkData1 + movlw 0 + addwf UnilinkParity2,f + movwf UnilinkData2 + movlw 0 + addwf UnilinkParity2,f + movwf UnilinkData3 + movlw 0 + addwf UnilinkParity2,f + movwf UnilinkData4 + movlw 0 + addwf UnilinkParity2,f + movwf UnilinkData5 + movlw 0 + addwf UnilinkParity2,f + movwf UnilinkData6 + movlw 0 + addwf UnilinkParity2,f + movwf UnilinkData7 + movlw 00h + addwf UnilinkParity2,f + movwf UnilinkData8 + movlw 1eh + addwf UnilinkParity2,f + movwf UnilinkData9 + goto IRQINTParse0113Complete + +IRQINTParse0113Not82 + + movf DisplayStatus,w + xorlw 83h ; Fourth slave break? + bnz IRQINTParse0113Not83 + + movlw 0c9h ; Track name 1 + addwf UnilinkParity1,f + movwf UnilinkCMD1 + movf TrackName,w + addwf UnilinkParity1,f + movwf UnilinkCMD2 + + movf UnilinkParity1,w ; Carry the parity forward + movwf UnilinkParity2 + + movf TrackName+1,w + addwf UnilinkParity2,f + movwf UnilinkData1 + movf TrackName+2,w + addwf UnilinkParity2,f + movwf UnilinkData2 + movf TrackName+3,w + addwf UnilinkParity2,f + movwf UnilinkData3 + movf TrackName+4,w + addwf UnilinkParity2,f + movwf UnilinkData4 + movf TrackName+5,w + addwf UnilinkParity2,f + movwf UnilinkData5 + movf TrackName+6,w + addwf UnilinkParity2,f + movwf UnilinkData6 + movf TrackName+7,w + addwf UnilinkParity2,f + movwf UnilinkData7 + movlw 00h + addwf UnilinkParity2,f + movwf UnilinkData8 + movlw 0eh + addwf UnilinkParity2,f + movwf UnilinkData9 + + goto IRQINTParse0113Complete + +IRQINTParse0113Not83 + movf DisplayStatus,w - andlw 0f0h + xorlw 84h ; Fifth slave break? + bnz IRQINTParse0113Not84 + + movlw 0c9h ; Track name (2) + addwf UnilinkParity1,f + movwf UnilinkCMD1 + movf TrackName+8,w + addwf UnilinkParity1,f + movwf UnilinkCMD2 + + movf UnilinkParity1,w ; Carry the parity forward + movwf UnilinkParity2 + + movf TrackName+9,w + addwf UnilinkParity2,f + movwf UnilinkData1 + movf TrackName+10,w + addwf UnilinkParity2,f + movwf UnilinkData2 + movf TrackName+11,w + addwf UnilinkParity2,f + movwf UnilinkData3 + movf TrackName+12,w + addwf UnilinkParity2,f + movwf UnilinkData4 + movf TrackName+13,w + addwf UnilinkParity2,f + movwf UnilinkData5 + movf TrackName+14,w + addwf UnilinkParity2,f + movwf UnilinkData6 + movf TrackName+15,w + addwf UnilinkParity2,f + movwf UnilinkData7 + movlw 00h + addwf UnilinkParity2,f + movwf UnilinkData8 + movlw 1eh + addwf UnilinkParity2,f + movwf UnilinkData9 + goto IRQINTParse0113Complete + +IRQINTParse0113Not84 + + movf DisplayStatus,w + xorlw 85h ; Sixth slave break? + bnz IRQINTParse0113Not85 + + movlw 90h + addwf UnilinkParity1,f + movwf UnilinkCMD1 + movlw 50h + addwf UnilinkParity1,f + movwf UnilinkCMD2 + + movf UnilinkParity1,w ; Carry the parity forward + movwf UnilinkParity2M + + movf CurTrack,w + addwf UnilinkParity2M,f + movwf UnilinkData1 + movf CurMins,w + addwf UnilinkParity2M,f + movwf UnilinkData2 + movf CurSecs,w + addwf UnilinkParity2M,f + movwf UnilinkData3 + +; movlw 0c0h + movf CurDisc,w +; andlw 0f0h +; iorlw 0eh addwf UnilinkParity2M,f movwf UnilinkData4 - - incf DisplayStatus,f ; Temporary debug info - bsf DisplayStatus,7 + + clrf DisplayStatus ; for now! + goto IRQINTParse0113Complete + +IRQINTParse0113Not85 + clrf DisplayStatus + incf DisplayStatus,f ; Skip step one for now + goto IRQINTParseComplete + +IRQINTParse0113Complete + + incf DisplayStatus,f ; Increment display state counter +; bsf DisplayStatus,7 goto IRQINTParseBypassClear ; Don't clear the data, the buffer will be sent as the next packet @@ -799,6 +1090,21 @@ IRQINTParseNot01 IRQINTParseNot02 +; Check for CMD1 = 80h (Display button) + movf UnilinkCMD1,w + xorlw 080h + bnz IRQINTParseNot80 + + movf UnilinkID,w ; Check if I'm currently selected + xorwf UnilinkCurID,w + skpnz ; No, skip this command +; bsf DisplayStatus,7 ; Make sure we update the display again + movlw 81h + movwf DisplayStatus + goto IRQINTParseComplete + +IRQINTParseNot80 + ; Check for CMD1 = 87h (Power control) movf UnilinkCMD1,w xorlw 087h @@ -826,7 +1132,7 @@ IRQINTParseNot02 ; ; Also bit field of CMD2 for now: ; 7 6 5 4 3 2 1 0 -; X X - These two bits are set when changing color, beep etc, but now when actually powering on/off the system??? +; X X - These two bits are set when changing color, beep etc, but not when actually powering the system on or off??? ; X - Always set to 1 on my headunit ; X - Always set to 0 on my headunit ; X - Set to 1 when power is on, 0 when powering off (last command sent before bus dies is 87 22 on my unit) @@ -886,7 +1192,9 @@ IRQINTParseNot90 bnz IRQINTParseF0Deselect bsf UnilinkSelected,7 ; Now we're selected - bsf DisplayStatus,7 +; bsf DisplayStatus,7 + movlw 81h + movwf DisplayStatus goto IRQINTParseComplete IRQINTParseF0Deselect @@ -988,6 +1296,10 @@ Main movlw 0ffh ; Set infinite attenuation to begin with movwf UnilinkAttenuation + clrf RecvType + movlw RecvType + movwf CurRecvPos + clrf UnilinkReInits ; Clear the bus re-initialization counter bsf STATUS,RP0 ; Reg bank 1 @@ -1209,14 +1521,6 @@ MainSkipScroll ; Display scroll part ends here... -; movf DataCount,w ; Load bit counter (if 0 then byte is available) -; skpz -; goto MainLoop - -; decf DataCount,f ; Set it non-zero - -; movf DataStore,w -; call BootTXB ; Send to terminal goto MainLoop @@ -1252,6 +1556,7 @@ IRQInit bsf INTCON,INTE ; Enable the RB0/INT bsf INTCON,PEIE ; Enable the peripheral interrupts bsf PIE1,TMR2IE ; Enable the Timer2 peripheral interrupt + bsf PIE1,RCIE ; Enable the UART receive interrupt bsf INTCON,GIE ; Enable global interrupts bsf TXSTA,TXEN ; Enable UART TX @@ -1277,12 +1582,12 @@ LCDInit ; This is a standard reset sequence for the LCD controller - movlw 160 ; Need to delay for at least 15ms, let's go for 16ms delay + movlw 170 ; Need to delay for at least 15ms, let's go for 17ms delay call DelayW movlw 3 ; Write 3 to the LCD call TxLCD ; Send to LCD - movlw 50 ; Need to delay for at least 4.1ms, let's go for 5ms delay + movlw 60 ; Need to delay for at least 4.1ms, let's go for 6ms delay call DelayW movlw 3 ; Write 3 to the LCD @@ -1616,7 +1921,15 @@ DefaultText1 DT "----- WJ", "MyID:xx ", "xx dB at", "Sel:xx B", "Inits:xx" DT " Unilink", "CurID:xx", "t Dsp:xx", "atxx.xxV", " " - +PCWaitText0 +; DT ">Waiting" +; DT "Wait->PC" + DT "Booting." +PCWaitText1 +; DT " for PC<" +; DT " Booting" + DT "..",0,0,0,0,0,0 + LookUp movwf PCL ; Go to it (this assumes PCLATH == 06h) @@ -1917,15 +2230,13 @@ BootEEX ; To produce compact code the end zero byte has to be in the LSB (that means an even number of chars in every string) BootStartText -; "WJBoot - press ESC to flash\x00" - DW 0x2bca,0x216f,0x37f4,0x102d,0x1070,0x3965,0x39f3,0x1045,0x29c3,0x1074,0x37a0,0x336c,0x30f3,0x3400 + DA "WJBoot - press ESC to flash\x00" + BootFlashText -; "\r\nSend INHX8 file now...\r\x00" - DW 0x068a,0x29e5,0x3764,0x1049,0x2748,0x2c38,0x1066,0x34ec,0x32a0,0x376f,0x3bae,0x172e,0x0680 -BootRunText -; "\r\nExiting loader\r\x00" - DW 0x068a,0x22f8,0x34f4,0x34ee,0x33a0,0x366f,0x30e4,0x32f2,0x0680 + DA "\r\nSend INHX8 file now...\r\x00" +BootRunText + DA "\r\nExiting loader\r\x00" ;---------------------------------------------------------------------- ; EE Data (64 bytes), located at 2100h