title --- "Luxman System Bus Interface for the Luxman T-235" ; ; DESCRIPTION: ; Allows remote control for the Luxman T-235 tuner from the Luxman ; System Bus signals coming out from the Luxman A-383. The device ; id is TUNER, and the switch on the RA-383 remote controller must ; be set to TUNER-TAPE1. The buttons on the remote have been mapped ; as follows: ; Remote TUNING << -> Tuner TUNING DOWN PORTB.0 ; Remote TUNING >> -> Tuner TUNING UP PORTB.1 ; Remote PRESET << -> Tuner PRESET DOWN PORTB.2 ; Remote PRESET >> -> Tuner PRESET DOWN PORTB.3 ; Remote BAND -> Tuner BAND PORTB.4 ; Remote +10 -> Tuner A.SCAN PORTB.5 ; Remote SLEEP -> Tuner SLEEP PORTB.6 ; Remote POWER ON -> Tuner POWER ON PORTB.7 (X) ; Remote POWER OFF -> Tuner POWER OFF PORTB.7 (X) ; ; The frequency of the crystal used is 4.0000Mhz. When using another ; crystal, the delays on the program have to be recalculated. The ; circuit needs +5V power supply and the System Bus line. The outputs ; from PORTB to the buttons of the deck have been isolated via 4N35 ; optocouplers, allowing operation of the deck buttons while the ; interface is running. Control Signals: ; ; Tuner ON Signal : PORTA.2 ; Line Bus Signal : PORTA.1 ; Debug Signal : PORTA.0 LIST P=16F84, F=INHX8M, R=DEC errorlevel 0,-305 INCLUDE ".\include\P16F84.inc" __CONFIG _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON ; PIC Hardware cfg. PAGE ; Program Body org 0 ; clrf PORTB bsf STATUS, RP0 ; Bank1 will be adressed movlw 0x000 ; Set RA7..RA0 as OUTputs movwf TRISA & 0x07F ; bsf TRISA & 0x07F, 1 ; Set RA1 as INput (Bus Line) bsf TRISA & 0x07F, 2 ; Set RA2 as INput (Tuner ON) movlw 0x000 ; Set RB7..RB0 as OUTputs movwf TRISB & 0x07F ; bcf STATUS, RP0 ; Bank0 is adressed again ; Registers DelayH EQU 12 DelayL EQU 13 Flash_Data EQU 14 Flash_Cntr EQU 15 Flash_Temp EQU 16 Bus_Status EQU 17 Read_Code_Cntr EQU 18 Code_In_Data_H EQU 19 Code_In_Data_L EQU 20 Wait_Bus_Stable_H EQU 21 Wait_Bus_Stable_L EQU 22 Buttons EQU 23 Tuner_Power EQU 24 ; Program movlw 0x0FF ; If the interface runs the LED flashes movwf Flash_Data ; call Flash_Byte ; clrf Tuner_Power ; Get tuner power status btfsc PORTA, 2 ; bsf Tuner_Power,0 ; LoopForever btfss Tuner_Power,0 ; Test previous tuner power status goto Tuner_Was_Off ; goto Tuner_Was_On ; Tuner_Was_Off btfsc PORTA,2 ; goto Tuner_Chg_On ; Tuner power changes to ON goto Test_Bus_Status ; Tuner power does not change Tuner_Was_On btfss PORTA,2 ; goto Tuner_Chg_Off ; Tuner power changes to OFF goto Test_Bus_Status ; Tuner power does not change Tuner_Chg_On ; Put POWER ON code on the bus bsf Tuner_Power,0 ; Change Tuner power status to ON call Send_PWRON_Code ; Put power ON code on the Bus goto LoopForever Tuner_Chg_Off ; Put POWER OFF code on the bus bcf Tuner_Power,0 ; Change Tuner power status to OFF call Send_PWROFF_Code ; Put power OFF code on the Bus goto LoopForever Test_Bus_Status btfsc PORTA,1 ; goto LoopForever ; call Read_Bus_Code ; call Match_Code ; Match the received code call Button_Press ; Simulate button press on the deck call Wait_Bus_Stable ; Delay betwheen codes goto LoopForever ; ROUTINES - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Send_PWRON_Code bsf STATUS, RP0 ; Bank1 will be adressed bcf TRISA & 0x07F, 1 ; Set RA1 as OUTput (Bus Line) bcf STATUS, RP0 ; Bank1 will be adressed call Send_Bus_Header call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_0 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 bsf STATUS, RP0 ; Bank1 will be adressed bsf TRISA & 0x07F, 1 ; Set RA1 as INput (Bus Line) bcf STATUS, RP0 ; Bank1 will be adressed return Send_PWROFF_Code bsf STATUS, RP0 ; Bank1 will be adressed bcf TRISA & 0x07F, 1 ; Set RA1 as OUTput (Bus Line) bcf STATUS, RP0 ; Bank1 will be adressed call Send_Bus_Header call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 call Send_Bus_1 bsf STATUS, RP0 ; Bank1 will be adressed bsf TRISA & 0x07F, 1 ; Set RA1 as INput (Bus Line) bcf STATUS, RP0 ; Bank1 will be adressed return Send_Bus_Header bcf PORTA, 1 ; Header LOW movlw 11+1 ; movwf DelayH ; movlw 148+1 ; movwf DelayL ; call Delay_Aux ; bsf PORTA, 1 ; Header HIGH movlw 4 ; movwf DelayH ; movlw 228 ; movwf DelayL ; call Delay_Aux ; return Send_Bus_0 bcf PORTA, 1 ; '1' LOW movlw 0+1 ; movwf DelayH ; movlw 197+1 ; movwf DelayL ; call Delay_Aux ; bsf PORTA, 1 ; '1' HIGH movlw 3+1 ; movwf DelayH ; movlw 27+1 ; movwf DelayL ; call Delay_Aux ; return Send_Bus_1 bcf PORTA, 1 ; '0' LOW movlw 2+1 ; movwf DelayH ; movlw 84+1 ; movwf DelayL ; call Delay_Aux ; bsf PORTA, 1 ; '0' HIGH movlw 1+1 ; movwf DelayH ; movlw 84+1 ; movwf DelayL ; call Delay_Aux ; return Button_Press movfw Buttons ; Simulate button press movwf PORTB ; movlw 0x0FF ; The button remains pressed some time movwf DelayH ; movlw 0x000 ; movwf DelayL ; call Delay_Aux ; clrf PORTB ; Release button return ; Wait_Bus_Stable clrf Wait_Bus_Stable_H ; clrf Wait_Bus_Stable_L ; Wait_Bus_Stable_a ; incf Wait_Bus_Stable_L ; Guess Bus is HIGH btfsc PORTA,1 ; Test Bus State goto WBS_Gate ; clrf Wait_Bus_Stable_H ; Bus is LOW, reset Counter clrf Wait_Bus_Stable_L ; goto Wait_Bus_Stable_a ; WBS_Gate ; Bus is High, inc Counter movfw Wait_Bus_Stable_L ; sublw 0x0FF ; btfss STATUS,Z ; goto Wait_Bus_Stable_a ; Counter_Low is not FF incf Wait_Bus_Stable_H ; Counter_Low is FF, inc Counter_High movfw Wait_Bus_Stable_H ; sublw 0x008 ; btfss STATUS,Z ; goto Wait_Bus_Stable_a ; return ; Bus was enough time stable Match_Code clrf Buttons ; No button is pressed movfw Code_In_Data_H ; sublw 0x0FF ; btfss STATUS,Z ; goto Match_Tuner ; It is not a system command code movfw Code_In_Data_L ; sublw 0x07F ; btfsc STATUS,Z ; goto Was_Power_On ; It is POWER ON code movfw Code_In_Data_L ; sublw 0x0FF ; btfsc STATUS,Z ; goto Was_Power_Off ; It is POWER OFF code return ; It was system, but not POWER ON, POWER OFF Was_Power_Off btfsc Tuner_Power,0 ; bsf Buttons,7 ; Press POWER button return ; Tuner was already OFF Was_Power_On btfss Tuner_Power,0 ; bsf Buttons,7 ; Press POWER button return ; Tuner was already ON Match_Tuner movfw Code_In_Data_H ; Verify Tuner Identity sublw 0x080 ; btfss STATUS,Z ; return ; It was not a TUNER code movfw Code_In_Data_L ; sublw 0x06B ; btfsc STATUS,Z ; bsf Buttons,0 ; It is TUNING << code movfw Code_In_Data_L ; Verify TUNING >> sublw 0x0EB ; btfsc STATUS,Z ; bsf Buttons,1 ; It is TUNING >> code movfw Code_In_Data_L ; sublw 0x067 ; btfsc STATUS,Z ; bsf Buttons,2 ; It is PRESET << code movfw Code_In_Data_L ; sublw 0x0E7 ; btfsc STATUS,Z ; bsf Buttons,3 ; It is PRESET >> code movfw Code_In_Data_L ; sublw 0x0BD ; btfsc STATUS,Z ; bsf Buttons,4 ; It is BAND >> code movfw Code_In_Data_L ; sublw 0x02F ; btfsc STATUS,Z ; bsf Buttons,5 ; It is +10 Code movfw Code_In_Data_L ; sublw 0x0FB ; btfsc STATUS,Z ; bsf Buttons,6 ; Press SLEEP button movlw 0x0FF ; If a NOT-SYSTEM tuner code was received movwf Flash_Data ; the debug LED flashes call Flash_Byte ; return ; Read_Bus_Code btfss PORTA,1 ; Waiting for Header_End goto $-1 ; movlw 0x009 ; High Bits +1 Counter Initialization movwf Read_Code_Cntr ; Read_Code_H_Loop decfsz Read_Code_Cntr ; Test how many bits have been received goto $+2 ; If <8 bits received the read high byte goto Read_Code_Low ; If 8 bits received then read low byte rlf Code_In_Data_H ; Shift the Received High Data Byte bcf Code_In_Data_H,0 ; Guess the Bit will be a 0 btfsc PORTA,1 ; Waiting for Bit start goto $-1 ; movlw 1+1 ; Delay initialization for getting bits movwf DelayH ; movlw 140+1 ; movwf DelayL ; call Delay_Aux ; Delay for reading the Bit btfss PORTA,1 ; Read Bit bsf Code_In_Data_H,0 ; Bus_Line is low, Bit is a 1, not a 0 btfss PORTA,1 ; Waiting for Bit end goto $-1 ; goto Read_Code_H_Loop ; Read_Code_Low movlw 0x009 ; Low Bits+1 Counter Initialization movwf Read_Code_Cntr ; Read_Code_L_Loop decfsz Read_Code_Cntr ; Test how many bits have been received goto $+2 ; return ; rlf Code_In_Data_L ; Shift the Received Data Bytes bcf Code_In_Data_L,0 ; Guess the Bit will be a 0 btfsc PORTA,1 ; goto $-1 ; movlw 1+1 ; Delay initialization for getting bits movwf DelayH ; movlw 140+1 ; movwf DelayL ; call Delay_Aux ; Delay for reading the Bit btfss PORTA,1 ; Read Bit bsf Code_In_Data_L,0 ; Bus_Line is low, Bit was a 1, not a 0 btfss PORTA,1 ; Waiting for bit end goto $-1 ; goto Read_Code_L_Loop ; Flash_Byte movf Flash_Data,W ; Data Byte to be flashed movwf Flash_Temp ; movlw 8 ; Number of bits to be flashed movwf Flash_Cntr ; Flash_Loop ; Flash the entire byte rlf Flash_Temp ; btfsc STATUS,C ; goto Flash_1 ; call Led_0 ; goto Flash_End ; Flash_1 ; call Led_1 ; Flash_End ; decfsz Flash_Cntr ; goto Flash_Loop ; return Led_1 movlw 0x008 ; Delay Time Initialization for Led ON movwf DelayH ; movlw 0x000 ; movwf DelayL ; bsf PORTA,0 ; Led ON call Delay_Aux ; movlw 0x002 ; Delay Time Initialization for Led OFF movwf DelayH ; movlw 0x000 ; movwf DelayL ; bcf PORTA,0 ; LED OFF call Delay_Aux ; return Led_0 movlw 0x002 ; Delay Time Initialization for Led ON movwf DelayH ; movlw 0x000 ; movwf DelayL ; bsf PORTA,0 ; Led ON call Delay_Aux ; movlw 0x002 ; Delay Time Initialization for Led OFF movwf DelayH ; movlw 0x000 ; movwf DelayL ; bcf PORTA,0 ; LED OFF call Delay_Aux ; return Delay_Aux ; DelayH,DelayL AS PARAMETERS decfsz DelayL ; goto $ -1 ; decfsz DelayH ; goto Delay_Aux ; return ; end ; Execution never reaches this point