; Transceiver Controller ; ; (c) Cumbria Designs 2005 ; ; ;========================================================================================== ; ; Controller for T-1 SSB/CW Transceiver Sub-System ; ;========================================================================================== ; ; This program interprets eight control inputs and from these generates 8 sequences of ; 16 bit control outputs to operate the T-1 SSB/CW Sub System. The control inputs are ; presented to PORTB as open (high) or ground (low) conditions. The outputs are produced ; at PORTC and PORTD as 8 parallel bit patterns that are used to drive the T-1 switching ; circuits. The sequence patterns are defined by a series of 8 bit loads in the "Start" ; routine. These may be modified if required. The delays between the output of each sequence ; are defined within the Tx and Rx sequencing routines. ; ; This software is copyright of Cumbria Designs and provided free for non commerical use. ; ; Ron Taylor G4GXO ; ;========================================================================================== ; ; Pin Out ; ;========================================================================================== ; ; *Note 10k Pull Up Resistors on switch control inputs only ; A to D, Ports B and C left open ; ; ; Port A 0 Audio Sample ; 1 AGC Hang Pot Input ; 2 CW Hang Pot Input ; 3 Spare ; 4 Spare ; 5 Spare ; ; Port B 0 MUTE Low Mute IF ; 1 CW Low CW Mode ; 2 FILTER High Wide, Low Narrow ; 3 PTT_KEY PORTB,3 PTT/KEY Line ; 4 AGC_ON_OFF High AGC On, Low AGC Off ; 5 AGC_SPEED High Slow, Low AGC Fast ; 6 AGC_MODE High normal, Low Hang Mode ; 7 USB_LSB High USB Carrier, Low LSB Carrier ; ; Port C 0 AGC Fast ; 1 CW Carrier ; 2 IF Mute ; 3 LSB Carrier ; 4 Spare ; 5 USB Carrier ; 6 TX Control Out ; 7 RX Control Out ; ; Port D 0 AGC Input ; 1 RX Power ; 2 TX Audio Path ; 3 TX Power ; 4 RX Audio Path ; 5 Filter A ; 6 Sidetone Audio Path ; 7 Filter B ; ; Port E 0 Spare ; 1 Spare ; 2 Spare ; ;========================================================================================== ; ; Revision History ; ;========================================================================================== ; Rev:1.0 Date: 25 Feb 2005 Reason: First production release ; Rev:1.1 Date: 3 May 2006 Reason: Program tidy up ; Rev;1.2 Date: 10 Apr 2008 Reason: Correction to replace movf with movlw in steady state routines ;========================================================================================== ; ; Processor ; ;========================================================================================== list p=16f877A ; list directive to define processor ;========================================================================================== ; ; Register Definitions ; ;========================================================================================== #include p16f877A.inc ;========================================================================================== ; ; RAM DEFINITION ; ;========================================================================================== __MAXRAM H'1FF' __BADRAM H'8F'-H'90', H'95'-H'97', H'9A'-H'9D' __BADRAM H'105', H'107'-H'109' __BADRAM H'185', H'187'-H'189', H'18E'-H'18F' ;========================================================================================== ; ; CONFIGURATION BITS ; ;========================================================================================== ;_CP_ALL EQU H'0FCF' ;_CP_HALF EQU H'1FDF' ;_CP_UPPER_256 EQU H'2FEF' ;_CP_OFF EQU H'3FFF' ;_DEBUG_ON EQU H'37FF' ;_DEBUG_OFF EQU H'3FFF' ;_WRT_ENABLE_ON EQU H'3FFF' ;_WRT_ENABLE_OFF EQU H'3DFF' ;_CPD_ON EQU H'3EFF' ;_CPD_OFF EQU H'3FFF' ;_LVP_ON EQU H'3FFF' ;_LVP_OFF EQU H'3F7F' ;_BODEN_ON EQU H'3FFF' ;_BODEN_OFF EQU H'3FBF' ;_PWRTE_OFF EQU H'3FFF' ;_PWRTE_ON EQU H'3FF7' ;_WDT_ON EQU H'3FFF' ;_WDT_OFF EQU H'3FFB' ;_LP_OSC EQU H'3FFC' ;_XT_OSC EQU H'3FFD' ;_HS_OSC EQU H'3FFE' ;_RC_OSC EQU H'3FFF' __config (_CP_ALL & _PWRTE_ON & _DEBUG_OFF & _WDT_OFF & _LVP_OFF & _HS_OSC) ;========================================================================== ; ; PORT Definitions ; ;========================================================================== ; PORT B MUTE EQU 0x00 ; Low Mute IF CW EQU 0X01 ; Low CW Mode FILTER EQU 0X02 ; High Wide, Low Narrow PTT_KEY EQU 0x03 ; PORTB,3 PTT/KEY Line AGC_ON_OFF EQU 0x04 ; High AGC On, Low AGC Off AGC_SPEED EQU 0x05 ; High Slow, Low AGC Fast AGC_MODE EQU 0x06 ; High normal, Low Hang Mode USB_LSB EQU 0x07 ; High USB Carrier, Low LSB Carrier ;========================================================================== ; ; Control Word ; ;========================================================================== ; Basic control words are defined below for Rx to Tx and Tx to Rx transitions. User settings ; are xor'd into each word. This provides the inversion for the Active Low audio controls ; and adds in the user bits to the zero set "X" positions. ; Output Word A (PORTD) ; AGC_INPUT EQU 0x00 ; AGC Input Active Low RX_PWR EQU 0x01 ; RX Power TX_AUDIO EQU 0x02 ; TX Audio Path Active Low TX_PWR EQU 0x03 ; TX Power RX_AUDIO EQU 0x04 ; RX Audio Path Active Low FILTER_A EQU 0x05 ; Filter A SIDETONE EQU 0x06 ; Sidetone Audio Path Active Low FILTER_B EQU 0x07 ; Filter B ; ; Output Word B (PORTC) ; AGC_FAST EQU 0x00 ; AGC Fast CW_CARRIER EQU 0x01 ; CW Carrier IF_MUTE EQU 0x02 ; IF Mute LSB_CARRIER EQU 0x03 ; LSB Carrier SPARE0 EQU 0x04 ; USB_CARRIER EQU 0x05 ; USB Carrier TX_FLAG EQU 0x06 ; TX Control Output RX_FLAG EQU 0x07 ; RX Control Output ; ; Output Word C ; MODE1 EQU 0x00 ; USB Active Low (For connection to FD-01/Minicounter) MODE2 EQU 0x01 ; LSB Active Low MODE3 EQU 0x02 ; CW Active Low ;========================================================================== ; ; Transition State Words ; ;========================================================================== ; Three transition states (A,B,C) are used for Tx>Rx and Rx>Tx changes. These are ; defined in the state words below. Conditions marked "X" in the state map are ; determined by the current user control settings. ; ; Output Word A RX RX>TX TX TX>RX RX ; A B C A B C ; AGC_INPUT EQU 0x00 ; X 0 0 0 0 0 0 0 X PL1 AGC Input ; RX_PWR EQU 0x01 ; 1 0 0 0 0 1 1 1 1 PL2 RX Power ; TX_AUDIO EQU 0x02 ; 0 0 0 0 X 0 0 0 0 PL3 TX Audio Path ; TX_PWR EQU 0x03 ; 0 0 1 1 1 0 0 0 0 PL4 TX Power ; RX_AUDIO EQU 0x04 ; 1 0 0 0 0 0 0 0 1 PL5 RX Audio Path ; FILTER_A EQU 0x05 ; X 0 0 0 X 0 0 0 X PL6 Filter A ; SIDETONE EQU 0x06 ; 0 0 0 X X 0 0 0 0 PL7 Sidetone Audio Path ; FILTER_B EQU 0x07 ; X X 0 0 X X X X X PL8 Filter B ; A STATES #DEFINE A_RX_STATE b'00010010' ; A_RX_STATE #DEFINE A_TX_STATE b'00001000' ; A_TX_STATE ; RX>TX #DEFINE A_R2TSEQ_A b'00000000' ; A_R2TSEQ_A #DEFINE A_R2TSEQ_B b'00001000' ; A_R2TSEQ_B #DEFINE A_R2TSEQ_C b'00001000' ; A_R2TSEQ_C ; TX>RX #DEFINE A_T2RSEQ_A b'00000010' ; A_T2RSEQ_A #DEFINE A_T2RSEQ_B b'00000010' ; A_T2RSEQ_B #DEFINE A_T2RSEQ_C b'00000010' ; A_T2RSEQ_C ; Output Word B RX RX>TX TX TX>RX RX ; A B C TX A B C ; AGC_FAST EQU 0x00 ; X 1 1 1 1 1 1 1 X PL9 AGC Fast ; CW_CARRIER EQU 0x01 ; 0 0 0 0 X 0 0 0 0 PL10 CW Carrier ; IF_MUTE EQU 0x02 ; 0 1 1 1 1 1 1 1 0 PL11 IF Mute ; LSB_CARRIER EQU 0x03 ; X X X X X X X X X PL12 LSB Carrier ; SPARE0 EQU 0x04 ; 0 0 0 0 0 1 0 0 0 PL13 ; USB_CARRIER EQU 0x05 ; X X X X X X X X X PL14 USB Carrier ; RX_LINE EQU 0x06 ; 1 0 0 0 0 1 1 1 1 RX Relay Driver ; TX_LINE EQU 0x07 ; 0 1 1 1 1 0 0 0 0 TX Relay Driver ; B STATES #DEFINE B_RX_STATE b'01000000' ; B_RX_STATE #DEFINE B_TX_STATE b'10000101' ; B_TX_STATE ; RX>TX #DEFINE B_R2TSEQ_A b'10000101' ; B_R2TSEQ_A #DEFINE B_R2TSEQ_B b'10000101' ; B_R2TSEQ_B #DEFINE B_R2TSEQ_C b'10000101' ; B_R2TSEQ_C ; TX>RX #DEFINE B_T2RSEQ_A b'01010101' ; B_T2RSEQ_A #DEFINE B_T2RSEQ_B b'01000101' ; B_T2RSEQ_B #DEFINE B_T2RSEQ_C b'01000101' ; B_T2RSEQ_C ;========================================================================================== ; ; FILE REGISTER EQUATES ; ;========================================================================================== CBLOCK 0x20 ; Start Data Block AF_Sample AF_Sample_old AGC_Sample ; Counter for sampling loop Hang_count ; Fixed delay component for AGC Hang time Silence_count ; Variable delay component for AGC Hang time BI_Delay ; Break in delay counter counter_1 ; 0.5mS Delay Counter counter_2 ; Higher order Delay Counter counter_3 ; Long delay counter scan_address ; Used in Control Scan routine Output_A ; Control Word for outputs 0-7 Output_B ; Control Word for outputs 8-15 Output_C ; Control Word for outputs 16-23 Temp_A ; Temp storage for outputs Temp_B Temp_C count ; General counter byte_count ; Serial Byte Counter bit_count ; Serial Bit Counter delay1 ; Delay counters delay2 output_byte ; Output byte for serial shift temp ; Temp storage Template_A ; Template to convert Active Low bits monitor ; Development probe Input ; PORTB Input word Input_old ; Historic Input word Control_A ; User control words to be factored into outputs Control_B Control_C ENDC ; End of Data Block ;========================================================================================== ; ; MACRO AREA ; ;========================================================================================== ; Bank Select Macros to simplify bank changes Bank0 MACRO bcf STATUS,RP0 ; Select Bank 0 bcf STATUS,RP1 ; ENDM Bank1 MACRO bsf STATUS,RP0 ; Select Bank 1 bcf STATUS,RP1 ; ENDM Bank2 MACRO bcf STATUS,RP0 ; Select Bank 2 bsf STATUS,RP1 ; ENDM Bank3 MACRO bsf STATUS,RP0 ; Select Bank 3 bsf STATUS,RP1 ; ENDM ;========================================================================================== ; ; RESET ENTRY ; ;========================================================================================== ORG 0x000 ; Processor reset vector clrf PCLATH ; Ensure page bits are cleared goto Start ; Go to beginning of program Start ; Initialise Ports Bank0 clrf PORTB clrf PORTC clrf PORTD clrf PORTE Bank1 ; Switch to Bank 1 movlw 0x00 movwf TRISC ; Configure PORTC and PORTD outputs movwf TRISD movlw 0xFF movwf TRISB ; PORTB as inputs bcf OPTION_REG,7 ; Enable weak pull ups Bank0 ; Switch to Bank0 movlw b'01010101' ; Load Template for Output A to set Active Low controls movwf Template_A ; This allows same logic 1= ON, 0=OFF to be used across all controls movwf PORTD ; Send to PortD to close all audio paths ; during intialisation (reduces start up squeak) ; ; A to D set up ; Bank1 ; Switch to bank 1 movlw b'00000100' ; Left justify, 3 analog channel, no Vref movwf ADCON1 movlw b'00000111' movwf TRISA ; PortA 0..2 Inputs for A to D Bank0 ; Switch back to bank 0 movlw b'01000001' ; Fosc/8, A/D enabled movwf ADCON0 ; Load Initial State Control Words ; Set for all functions OFF and audio Muted clrf Output_A ; Clear control output words clrf Output_B clrf Output_C call Shift_Out ; Send to output ports movf PORTB,w ; Capture control states movwf Input_old ; Save for initial comparison in Main call Delay_500mS ; Start up delay to allow audio stages to settle ; ON - Bring module into operation movf PORTB,w ; After turn on delay bring up unit in Rx movwf Input ; call WORD_BUILDER ; in accordance with control settings call RX_STATE ; bsf PORTC,AGC_FAST ; Set AGC to fast to discharge timing capacitor call Delay_500mS ; and hold it on briefly before scanning controls call Delay_500mS ; btfsc Input,AGC_SPEED ; Check AGC control status bcf PORTC,AGC_FAST ; High, set AGC to slow ; Low, jump to Main ;========================================================================================== ; ; Main Routine, all functions are called from here ; ;========================================================================================== MAIN movlw 0xFF ; Set up counter loop for movwf count ; AGC Fast hold-on to discharge bsf PORTC,0 ; AGC capacitor after Tx to Rx change Main1 decfsz count,f ; Decrement hold-on counter goto Main2 ; On zero set AGC to match controls call RX_STATE ; by running RX_State incf count,f ; Set count for next decrement Main2 ; decfsz AGC_Sample,f ; Rolling 255 count Sample counter goto Main3 ; call AGC_Hang ; Zero, perform sample and reload movf AF_Sample,w ; movwf AF_Sample_old ; Update sample Main3 movf PORTB,w ; movwf Input ; Get control inputs movf Input,w clrf STATUS xorwf Input_old,w ; Has the control word changed? btfsc STATUS,Z goto Main1 ; No continue scanning call WORD_BUILDER ; Yes construct new control word ; Tx_Rx_Check btfsc PORTB,PTT_KEY ; Are we in Tx? goto RX ; No, factor in control changes to receive state call R2T_SEQUENCER ; Yes, perform sequence call TX_STATE ; On return Tx to Rx sequence will be executed call WORD_BUILDER ; Ensure that control words are current call T2R_SEQUENCER RX call RX_STATE movf Input,w ; movwf Input_old ; Save new state of control goto MAIN ; Endless loop ; ; Hang AGC routines, if silence (no ADC changes) is seen over N samples then ; fast AGC is temporarily selected to restore gain. The varaible Silence_count ; value taken from the ADC sets hang time in conjunction with fixed delay ; counter Hang_count. ; AGC_Hang ; btfsc Input,AGC_MODE ; Are we in Slow/Hang mode? return ; No call AF_Sampler ; Get Audio Sample clrf STATUS movf AF_Sample,w ; Is there silence? subwf AF_Sample_old,w ; btfsc STATUS,Z ; goto AGC_Hang_count ; Yes, count duration bcf PORTC,AGC_FAST ; No, samples differ, keep slow AGC movlw 0x04 ; Reload Hang_count movwf Hang_count call AGC_Delay ; Get value for Silence_count return ; Back to Main ; Check that silence is real by making ; a count of several samples to confirm ; no change in level, AGC_Hang_count decfsz Hang_count,f ; Decrement fixed delay return movlw 0x04 ; Reload Hang_count movwf Hang_count decfsz Silence_count,f ; Decrement variable delay return ; Back to Main ; If Silence_ counter reaches zero then silence has been continuous and we can ; now revert to fast AGC to re-set the AGC capacitor. AGC_Hang_off ; Silence is real, switch to fast AGC movlw 0xFF ; Reload sample counter movwf AGC_Sample movlw 0x04 ; Reload Hang_count movwf Hang_count call AGC_Delay ; Reload Silence Counter bsf PORTC,AGC_FAST ; Switch AGC to fast return ; Back to Main ;========================================================================================== ; ; WORD BUILDER ; ; This routine forms the output control words by combining the control templates ; associated with each function. For simplicity all controls are treated as Active High, the ; Template_A is applied to Control Word A to account for the active low nature of the audio ; switch bits. The state of the Contol input bits drives the word build. ; ;========================================================================================== WORD_BUILDER ; Step 1 Analyse Input Word ; Step 2 Create Control words to modify output words ; Step 3 Combine Sequence words and control word with OR ; Step 4 Send to interface ; Input Word ; MUTE EQU 0x00 ; High Mute IF ; CW EQU 0X01 ; Low CW Mode ; FILTER EQU 0X02 ; High Wide, Low Narrow ; PTT_KEY EQU 0x03 ; PORTB,3 PTT/KEY Line ; AGC_ON_OFF EQU 0x04 ; High AGC On, Low AGC Off ; AGC_SPEED EQU 0x05 ; High Slow, Low AGC Fast ; AGC_MODE EQU 0x06 ; High normal, Low Hang Mode ; USB_LSB EQU 0x07 ; High USB Carrier, Low LSB Carrier ; Output Word A ; ; AGC_INPUT EQU 0x00 ; AGC Input ; RX_PWR EQU 0x01 ; RX Power ; TX_AUDIO EQU 0x02 ; TX Audio Path ; TX_PWR EQU 0x03 ; TX Power ; RX_AUDIO EQU 0x04 ; RX Audio Path ; FILTER_A EQU 0x05 ; Filter A ; SIDETONE EQU 0x06 ; Sidetone Audio Path ; FILTER_B EQU 0x07 ; Filter B ; Output Word B ; ; AGC_FAST EQU 0x00 ; AGC Fast ; CW_CARRIER EQU 0x01; CW Carrier ; IF_MUTE EQU 0x02 ; IF Mute ; LSB_CARRIER EQU 0x03; LSB Carrier ; SPARE0 EQU 0x04 ; Spare ; USB_CARRIER EQU 0x05; USB Carrier ; TX_LINE EQU 0x06 ; TX Relay Driver ; TX_LED EQU 0x07 ; TX LED ; Form Control Words to interpret user inputs clrf Control_A ; Clear Control Words clrf Control_B ; clrf Control_C ; IF Mute ; Test Input bits btfss Input,MUTE ; Test Mute bsf Control_B,IF_MUTE ; Set Mute ; Filter btfss Input,FILTER ; Test Filter goto Narrow ; Set Filter Narrow bsf Control_A,FILTER_A ; Set Filter Wide bcf Control_A,FILTER_B goto USB ; Goto next function Narrow bcf Control_A,FILTER_A ; Set Filter Narrow bsf Control_A,FILTER_B ; Carrier USB btfss Input,USB_LSB ; Test Carrier Oscillator bit goto LSB bsf Control_B,USB_CARRIER ; Select USB Carrier bcf Control_B,LSB_CARRIER return ; Exit control word routine LSB bcf Control_B,USB_CARRIER ; Select LSB Carrier bsf Control_B,LSB_CARRIER return ; Exit control word routine ;========================================================================================== ; ; Rx to Tx Sequencer ; ; This routine factors the control words into the sequence codes for a receive to transmit ; transistion. ; ;========================================================================================== R2T_SEQUENCER ;------------------------------- ; SEQUENCE A ; Rx to Tx Sequence movlw A_R2TSEQ_A ; Load Default sequences and factor in user controls iorwf Control_A,w ; Factor in Input States movwf Output_A movlw B_R2TSEQ_A ; iorwf Control_B,w ; Factor in Input States movwf Output_B call Shift_Out ; Send to interface call Break_In_Delay ; Get Break In Delay pot setting ;------------------------------- ; SEQUENCE B ; movlw A_R2TSEQ_B ; iorwf Control_A,w ; Factor in Input States movwf Output_A movlw B_R2TSEQ_B ; iorwf Control_B,w ; Factor in Input States movwf Output_B call Shift_Out ; Send to interface call Delay_1mS ; Sequence Delay ;------------------------------- ; CW Filter selection for CW Carrier btfsc Input,CW ; If in CW mode we must now select narrow filter goto Seq_C ; In SSB Mode goto Sequence C btfss Input,FILTER ; Is narrow filter already selected? goto Seq_C ; Yes, goto Sequence C bcf Control_A,FILTER_A ; No, de-select SSB Filter bsf Control_A,FILTER_B ; CW Filter selected to clean up output spectrum ; This will be de-selected if Input word calls for ; this when receive is restored ;------------------------------- ; SEQUENCE C Seq_C movlw A_R2TSEQ_C ; iorwf Control_A,w ; Factor in Input States movwf Output_C movlw B_R2TSEQ_C ; iorwf Control_B,w ; Factor in Input States movwf Output_C call Shift_Out ; Send to interface call Delay_1mS ; Sequence Delay ;------------------------------- return ; We are now ready to enable Tx state ;========================================================================================== ; ; TX STATE ; ; This routine enables Tx operation and configures for selected mode ; ;========================================================================================== TX_STATE ; Final Tx State btfsc Input,CW ; If in CW mode we can now turn on the carrier goto SSB_Audio CW_Audio ; Prepare signal paths for CW bsf Control_A,SIDETONE ; Sidetone audio ON bsf Control_B,CW_CARRIER; CW bit low so turn ON carrier call Load_Tx_State ; Load in CW settings goto Tx1 SSB_Audio ; Prepare signal paths for SSB bsf Control_A,TX_AUDIO ; Mic audio ON bcf Control_A,SIDETONE ; Sidetone audio OFF call Load_Tx_State ; Load in CW settings ; Now in Tx State, wait for PTT/Key to change to Rx, do not allow control changes in this state ; by bypassing control scan routine Tx1 btfss PORTB,PTT_KEY ; Scan PTT/KEY Line goto Tx1 ; Still in Tx mode, continue scan call Delay ; De-bounce btfss PORTB,PTT_KEY ; Is the key up? goto Tx1 ; No, re-test bcf Control_B,CW_CARRIER; Yes, turn off CW carrier (Regardless of SSB/CW mode) call Load_Tx_State ; Send to interface ; Break In Delay ; Max 255 x 2mSec movf BI_Delay,w ; Load up delay value from A to D movwf temp incf temp,f ; Increase by 1 to prevent decf going to 255 ; on zero value Tx2 call Delay_1mS ; Break In incremental delay 2mS call Delay_1mS ; decfsz temp,f ; Decrement CW hang counter goto Tx3 ; Poll Key state during break in delay goto Tx_Exit Tx3 btfsc PORTB,PTT_KEY ; Scan PTT/KEY Line goto Tx2 ; Re-poll key state during break in delay period bsf Control_B,CW_CARRIER; Key down again, turn on carrier call Load_Tx_State ; Send to interface goto Tx1 ; Back into transmission loop Tx_Exit ; Timed out, exit ; Close Tx audio paths and ensure carrier remains off during sequencing bcf Control_A,TX_AUDIO ; Mic audio OFF bcf Control_A,SIDETONE ; Sidetone audio OFF call Load_Tx_State ; Send to interface return ; Exit Tx State ;----------------------------------------------------------------------------------------- ; ; Sub routine used by TX_STATE to set output states. This approach is used instead of ; direct change of port bits to ensures that control states remain consistent for ; TX to Rx sequencing avoiding wrong settings on first sequence. ; Load_Tx_State ; Merge changes into output word movlw A_TX_STATE ; Load up Tx State codes in iorwf Control_A,w ; preparation for factoring movwf Output_A ; in mode related controls movlw B_TX_STATE iorwf Control_B,w movwf Output_B call Shift_Out ; Send to interface return ;========================================================================================== ; ; Tx to Rx Sequencer ; ; This routine factors the control words into the sequence codes for a transmit to receive ; transistion. ; ;========================================================================================== T2R_SEQUENCER ; Tx to Rx Sequence ;------------------------------- ; SEQUENCE A movlw A_T2RSEQ_A ; Load Default sequences and factor in user controls iorwf Control_A,w ; Factor in Input States movwf Output_A movlw B_T2RSEQ_A ; iorwf Control_B,w ; Factor in Input States movwf Output_B call Shift_Out ; Send to interface call Delay_1mS ; Sequence Delay call Delay_1mS ; Sequence Delay ;------------------------------- ; SEQUENCE B movlw A_T2RSEQ_B ; iorwf Control_A,w movwf Output_A movlw B_T2RSEQ_B ; iorwf Control_B,w movwf Output_B call Shift_Out ; Send to interface call Delay_1mS ; Sequence Delay call Delay_1mS ; Sequence Delay ;------------------------------- ; SEQUENCE C movlw A_T2RSEQ_C ; iorwf Control_A,w movwf Output_A movlw B_T2RSEQ_C ; iorwf Control_B,w movwf Output_B call Shift_Out ; Send to interface call Delay_1mS ; Sequence Delay return ; Now configured for Rx ;========================================================================================== ; ; RX STATE ; ; This routine enables Rx operation and configures Mute and AGC for selected state ; ;========================================================================================== RX_STATE ; Final Rx State btfsc Input,MUTE ; Is IF Mute selected? goto Rx_Filter ; No, goto Filter tests bsf Control_B,MUTE ; Set Mute bit Rx_Filter ; Belt and braces filter check btfss Input,FILTER ; Is wide filter selected? goto Rx_Narrow ; No, set to narrow filter bsf Control_A,FILTER_A ; Yes, set to wide filter bcf Control_A,FILTER_B ; CW Filter selected to clean up output spectrum goto AGC ; Goto AGC routines Rx_Narrow bcf Control_A,FILTER_A ; Yes, set to narrow filter bsf Control_A,FILTER_B ; AGC btfsc Input,AGC_ON_OFF; Test AGC On/Off bit bsf Control_A,0 ; Turn on AGC btfss Input,AGC_MODE ; Is Hang AGC Selected? goto AGC1 ; Yes, leave AGC speed control to Hang Routine in Main btfss Input,AGC_SPEED ; No, test AGC Speed bsf Control_B,AGC_FAST ; Set AGC to Fast goto AGC3 AGC1 btfss PORTC,0 ; Test current Hang State goto AGC2 bsf Control_B,AGC_FAST ; Set AGC Fast to copy Hang state goto AGC3 AGC2 bcf Control_B,AGC_FAST ; Set AGC Slow to copy hang state AGC3 movlw A_RX_STATE iorwf Control_A,w movwf Output_A movlw B_RX_STATE iorwf Control_B,w movwf Output_B call Shift_Out ; Send to interface ; Now in Rx State return ; Back to Main in Receive Mode ;========================================================================================== ; ; SHIFT OUT ; ; This routine sends the output control words to PORTC and PORTD. ; ; The Template word accounts for the active low audio commands, inverting them. This allows ; the control word definitions to be written in the same logic sense. ; ;========================================================================================== Shift_Out movf Template_A,w ; Apply template to condition active xorwf Output_A,w ; low audio routing controls movwf PORTD ; Result aready in w, move to Port movf Output_B,w movwf PORTC return ;========================================================================================== ; ; A to D ROUTINES ; ; These routines are used to measure the settings of the AGC hang time and Break In delay ; pots. ; ;========================================================================================== AF_Sampler ; Measure Audio Sample on movlw b'01000001' ; Channel 0 movwf ADCON0 call Delay ; Acquisition delay bsf ADCON0,GO ; Start A to D Wait_AF_Sample btfsc ADCON0,GO ; goto Wait_AF_Sample ; Wait for conversion to complete movf ADRESH,w ; Save upper 8 bit result andlw b'11111110' ; Get rid of precision bits movwf AF_Sample ; to react to signals above noise return AGC_Delay ; Measure AGC Hang Pot setting movlw b'01001001' ; Channel 1 movwf ADCON0 call Delay ; Acquisition delay bsf ADCON0,GO ; Start A to D Wait_AGC_Hang btfsc ADCON0,GO ; goto Wait_AGC_Hang ; Wait for conversion to complete movf ADRESH,w ; Save upper 8 bit result movwf Silence_count ; for use in Hang delay loop return Break_In_Delay ; Measure Break In pot Voltage movlw b'01010001' ; Channel 2 movwf ADCON0 call Delay ; Acquisition delay bsf ADCON0,GO ; Start A to D Wait_Break_In btfsc ADCON0,GO ; goto Wait_Break_In ; Wait for conversion to complete movf ADRESH,w ; Save upper 8 bit result movwf BI_Delay ; for use in delay loop return ;========================================================================================== ; ; DELAY ROUTINES ; ; Libary of delays used during start up and sequencing ; ; 20MHz Clock gives a 200nS instruction cycle, 5000 cycles = 1mS ; ;========================================================================================== ; Basic 0.5mS Delay used as a building block by other delay routines Delay ; 250 x 2uS = 0.5mS (Approx) movlw 0xFA ; Load 250 into w movwf counter_1 loop1 ; 10 x 200nS = 2uS per pass nop ; 1 nop ; 2 nop ; 3 nop ; 4 nop's to pad out delay nop ; 5 nop ; 6 nop ; 7 decfsz counter_1,f ; 8 Decrement goto loop1 ; 10 return ; Longer delays use multiples of basic 0.5 mS delay Delay_1mS ; **************************** 2 x Delay call Delay call Delay return Delay_100mS; **************************** 200 x Delay movlw 0xC8 ; Load 200 into w movwf counter_2 loop1002 call Delay ; Call 0.5mS Delay decfsz counter_2,f goto loop1002 return Delay_500mS; **************************** Delay of around 0.5 sec movlw 0x05 ; Load 5 into w movwf counter_3 long_loop1 call Delay_100mS ; Call 100mS Delay decfsz counter_3,f goto long_loop1 return END