;****************************************************************************************************** ; Radio Transmit-Receive Sequencer, By Bertrand Zauhar, VE2ZAZ ; For more details, visit VE2ZAZ's website at: ; http://www3.sympatico.ca/b.zauhar ;****************************************************************************************************** ; Filename: TR_Seq.asm ; Date: 28/02/2007 ; Software Version: 2 ; ; Designed to run on PICmicro PIC18F2220. ; ; Author: Bertrand Zauhar ;****************************************************************************************************** ; Files required: P18F2220.INC ; Assembles using Microchip's MPASM assembler software ;****************************************************************************************************** LIST P=18F2220 ;directive to define processor #include ;processor specific variable definitions ;****************************************************************************************************** ;Configuration bits ; The __CONFIG directive defines configuration data within the .ASM file. ; The labels following the directive are defined in the P18F2220.INC file. ; The PIC18F2220/2320/4220/4320 Data Sheet explains the functions of the ; configuration bits. ; NOTE: LOW VOLTAGE PROGRAMMING IS DISABLED BECAUSE THE PGM PIN IS USED FOR PORT B, BIT 5 AS AN I/O PIN. __CONFIG _CONFIG1H, _INTIO2_OSC_1H & _FSCM_OFF_1H & _IESO_OFF_1H __CONFIG _CONFIG2L, _PWRT_OFF_2L & _BORV_42_2L & _BOR_ON_2L __CONFIG _CONFIG2H, _WDTPS_1_2H & _WDT_OFF_2H __CONFIG _CONFIG3H, _MCLRE_ON_3H & _PBAD_DIG_3H & _CCP2MX_C1_3H __CONFIG _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVR_OFF_4L __CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L __CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H __CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L __CONFIG _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H __CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L __CONFIG _CONFIG7H, _EBTRB_OFF_7H ;****************************************************************************************************** ;Bank 1 has 256 locations available ;Bank 0 is skipped to simplify variable access. CBLOCK 0x100 ;All of these variables are located in the RAM Bank 1. WREG_TEMP ;0_variable used for context saving when interrupt occurs STATUS_TEMP ;1_variable used for context saving when interrupt occurs BSR_TEMP ;2_variable used for context saving when interrupt occurs ARM_PTT_STAT1 ;3_This is the PTT and ARMING status flag register ; 7-Sequencing process requested ; 6-Disarming process requested flag. requested (1), not requested (0) ; 5-Arming process requested flag. requested (1), not requested (0) ; 4-Arming button debouncing happening flag. Happening (1), not happening (0) ; 3-Arm button already treated flag. Already treated (1), not treated (0) ; 2-Old PTT pin state: High (1), Low (0). Used for debouncing. ; 1-Debounced PTT state. PTT enabled (1), PTT disabled (0) ; 0-System armed (1), disarmed (0) ARM_PTT_STAT2 ;4_This is the PTT and ARMING status flag register ; 7-(not used) ; 6-(not used) ; 5-(not used) ; 4-(not used) ; 3-(not used) ; 2-PTT already treated flag. Already treated (1), not treated (0) ; 1-Disarming process running. (1) running ; 0-Arming process running. (1) running TX_SEQUENCING_STAT1 ;5_Tx sequencing status byte 1 ; 7-(not used) ; 6-(not used) ; 5-(not used) ; 4-(not used) ; 3-(not used) ; 2-Tx output delay timer started. Started (1), not started (0) ; 1-Tx output feedback timer started. Started (1), not started (0) ; 0-Tx sequencing over flag. Over (1), in progress (0) RX_SEQUENCING_STAT1 ;6_Rx sequencing status byte 1 ; 7-(not used) ; 6-(not used) ; 5-(not used) ; 4-(not used) ; 3-Rx Pre-Switch feedback alarm detected (1), not detected (0) ; 2-Rx output delay timer started. Started (1), not started (0) ; 1-Rx output feedback timer started. Started (1), not started (0) ; 0-Rx sequencing over flag. Over (1), in progress (0) TX_RX_OUTPUT_STAT ;7_Tx/Rx output status byte ; 7-(not used) ; 6-(not used) ; 5-Output 6 in Tx or Rx state. Tx (1) ; 4-Output 5 in Tx or Rx state. Tx (1) ; 3-Output 4 in Tx or Rx state. Tx (1) ; 2-Output 3 in Tx or Rx state. Tx (1) ; 1-Output 2 in Tx or Rx state. Tx (1) ; 0-Output 1 in Tx or Rx state. Tx (1) TX_RX_SEQ_DONE ;8_Tx/Rx sequence done for outputs status byte ; 7-(not used) ; 6-(not used) ; 5-Tx or Rx sequence has Output 6 completed. Completed (1) ; 4-Tx or Rx sequence has Output 5 completed. Completed (1) ; 3-Tx or Rx sequence has Output 4 completed. Completed (1) ; 2-Tx or Rx sequence has Output 3 completed. Completed (1) ; 1-Tx or Rx sequence has Output 2 completed. Completed (1) ; 0-Tx or Rx sequence has Output 1 completed. Completed (1) TX_RX_SW_REQ_STAT ;9_Tx/Rx output switching requested status byte ; 7-DO NOT USE ; 6-DO NOT USE ; 5-Output 6 Tx/Rx switch requested. Requested (1) ; 4-Output 5 Tx/Rx switch requested. Requested (1) ; 3-Output 4 Tx/Rx switch requested. Requested (1) ; 2-Output 3 Tx/Rx switch requested. Requested (1) ; 1-Output 2 Tx/Rx switch requested. Requested (1) ; 0-Output 1 Tx/Rx switch requested. Requested (1) TX_FB_ALM_STAT ;10_Tx switching feedback failure status byte ; 7-DO NOT USE ; 6-DO NOT USE ; 5-Output 6 Tx feedback fail alarm. Alarmed (1) ; 4-Output 5 Tx feedback fail alarm. Alarmed (1) ; 3-Output 4 Tx feedback fail alarm. Alarmed (1) ; 2-Output 3 Tx feedback fail alarm. Alarmed (1) ; 1-Output 2 Tx feedback fail alarm. Alarmed (1) ; 0-Output 1 Tx feedback fail alarm. Alarmed (1) RX_FB_ALM_STAT ;11_Rx switching feedback failure status byte ; 7-DO NOT USE ; 6-DO NOT USE ; 5-Output 6 Rx feedback fail alarm. Alarmed (1) ; 4-Output 5 Rx feedback fail alarm. Alarmed (1) ; 3-Output 4 Rx feedback fail alarm. Alarmed (1) ; 2-Output 3 Rx feedback fail alarm. Alarmed (1) ; 1-Output 2 Rx feedback fail alarm. Alarmed (1) ; 0-Output 1 Rx feedback fail alarm. Alarmed (1) TX_FB_PRESENT_STAT ;12_Tx switching feedback present status byte ; 7-(not used) ; 6-(not used) ; 5-Output 6 Tx feedback present. Present (1) ; 4-Output 5 Tx feedback present. Present (1) ; 3-Output 4 Tx feedback present. Present (1) ; 2-Output 3 Tx feedback present. Present (1) ; 1-Output 2 Tx feedback present. Present (1) ; 0-Output 1 Tx feedback present. Present (1) RX_FB_PRESENT_STAT ;13_Rx switching feedback present status byte ; 7-(not used) ; 6-(not used) ; 5-Output 6 Rx feedback present. Present (1) ; 4-Output 5 Rx feedback present. Present (1) ; 3-Output 4 Rx feedback present. Present (1) ; 2-Output 3 Rx feedback present. Present (1) ; 1-Output 2 Rx feedback present. Present (1) ; 0-Output 1 Rx feedback present. Present (1) TX_RX_FB_REQ_STAT ;14_This register is used to flag that Feedback detection is requested on a specific output ; 7-(not used) ; 6-(not used) ; 5-Output 6 feedback detection requested. Requested (1) ; 4-Output 5 feedback detection requested. Requested (1) ; 3-Output 4 feedback detection requested. Requested (1) ; 2-Output 3 feedback detection requested. Requested (1) ; 1-Output 2 feedback detection requested. Requested (1) ; 0-Output 1 feedback detection requested. Requested (1) TX_Ox_POS_PTR ;15_Bit pointer used in the Tx Sequencing loop RX_Ox_POS_PTR ;16_Bit pointer used in the Rx Sequencing loop ARM_PTT_LED_STAT ;17_LED status and control register ; 7-(not used) ; 6-(not used) ; 5-(not used) ; 4-ARM/PTT LED to be set to Flashing ; 3-ARM/PTT LED to be set to Red ; 2-ARM/PTT LED to be set to Amber ; 1-ARM/PTT LED to be set to Green ; 0-ARM/PTT LED to be set to OFF LED_DIM_CTR ;18_Counter to allow to detect when to turn off a LED and create a dimmed effect SERIAL_STAT ;19_This is the USART status flag register ; 7-unused ; 6-unused ; 5-Request to Transmit Remote Monitoring Info ; 4-Setup mode enabled (comms with PC active) ; 3-tx cycle being performed. ; 2-Request to transmit parameters information ; 1-LF character received (end of user command entry) ; 0-New character transmission cycle required GENERAL1_STAT ;20_This is a general purpose status flag register ; 7-(not used) ; 6-Flag when a Tx (too long) Auto-Disarm delay is counting ; 5-Flag when a feedback alarm Auto-Disarm delay is counting ; 4-Flag when a sequence tone is currnetly sounding ; 3-Flag when a timeout tone is currently sounding ; 2-Flag when the timeout cycle is running ; 1-Flag when a timeout tone cycle start is requested ; 0-Flag when a parameter EEPROM Write cycle is required TEMP1_HI ;21_Temporary 16-bit variable available throughout code execution. TEMP1_LO ;22_ " TEMP2_HI ;23_Temporary 16-bit variable available throughout code execution. TEMP2_LO ;24_ " TEMP3_HI ;25_Temporary 16-bit variable available throughout code execution. Do not use during serial port transactions. TEMP3_LO ;26_ " Do not use during serial port transactions. WRT_EEPROM_POS ;27_EEPROM Writing Counter. Indicates what parameter to write in EEPROM PWM_CYCLE_CTR ;28_This is the number of cycles that a normal tone will have PWM_CYCLE_ALM_CTR ;29_Counter used When an alarm tone (long) is sent MAX_NUM_PWM_CYCLE ;30_The maximum number of periodes (cycles) to reach before stopping the tone TONE_REQ_STAT ;31_This is the Output Tone requested status register ; 7-(not used) ; 6-(not used) ; 5-Flags when a tone is requested for output 6. Requested (1) ; 4-Flags when a tone is requested for output 5. Requested (1) ; 3-Flags when a tone is requested for output 4. Requested (1) ; 2-Flags when a tone is requested for output 3. Requested (1) ; 1-Flags when a tone is requested for output 2. Requested (1) ; 0-Flags when a tone is requested for output 1. Requested (1) ARM_DEBOUNCE_CTR ;32_Register used to debounce the ARM button TMOUT_TMR0_CTR ;33_Register used to count the number of 5 second cycles for the timeout tone TONES_STAT ;34_This is a general purpose status flag register ; 7-Flag when a sequence completed tone is sent (used by remote monitoring tool) ; 6-Flag when a sequence started tone is sent (used by remote monitoring tool) ; 5-(not used) ; 4-Flag when a feedback alarm tone is requested ; 3-Flag when a sequence tone is currently sounding ; 2-Flag when a timeout tone is currently sounding ; 1-Flag when the timeout cycle is running ; 0-Flag when a timeout tone cycle start is requested Ox_HIGH_LOW ;35_High/Low output status byte ; 7-(not used) ; 6-(not used) ; 5-Output 6 is in High (1) state or Low (0) state ; 4-Output 5 is in High (1) state or Low (0) state ; 3-Output 4 is in High (1) state or Low (0) state ; 2-Output 3 is in High (1) state or Low (0) state ; 1-Output 2 is in High (1) state or Low (0) state ; 0-Output 1 is in High (1) state or Low (0) state ARM_DISARM_Ox_POS ;36_Indicates what output is being armed or disarmed PTT_DEBOUNCE_CTR_H ;37_Registers used to debounce the ARM button PTT_DEBOUNCE_CTR_L ;38_ " TX_RX_PRESW_FB_REQ_STAT ;39_This register is used to flag that Pre-switch Feedback detection is requested on a specific output ; 7-(not used) ; 6-(not used) ; 5-Output 6 Pre-switch feedback detection requested. Requested (1) ; 4-Output 5 Pre-switch feedback detection requested. Requested (1) ; 3-Output 4 Pre-switch feedback detection requested. Requested (1) ; 2-Output 3 Pre-switch feedback detection requested. Requested (1) ; 1-Output 2 Pre-switch feedback detection requested. Requested (1) ; 0-Output 1 Pre-switch feedback detection requested. Requested (1) TX_RX_PRESW_FB_PRES_STAT;40_This register is used to flag that Pre-switch Feedback detection is requested on a specific output ; 7-(not used) ; 6-(not used) ; 5-Output 6 Pre-switch feedback detection requested. Requested (1) ; 4-Output 5 Pre-switch feedback detection requested. Requested (1) ; 3-Output 4 Pre-switch feedback detection requested. Requested (1) ; 2-Output 3 Pre-switch feedback detection requested. Requested (1) ; 1-Output 2 Pre-switch feedback detection requested. Requested (1) ; 0-Output 1 Pre-switch feedback detection requested. Requested (1) TX_RX_PRESW_FB_ALM_STAT ;41_This register is used to flag that Pre-switch Feedback alarm is identified on a specific output ; 7-(not used) ; 6-(not used) ; 5-Output 6 Pre-switch feedback alarm latched. Latched (1) ; 4-Output 5 Pre-switch feedback alarm latched. Latched (1) ; 3-Output 4 Pre-switch feedback alarm latched. Latched (1) ; 2-Output 3 Pre-switch feedback alarm latched. Latched (1) ; 1-Output 2 Pre-switch feedback alarm latched. Latched (1) ; 0-Output 1 Pre-switch feedback alarm latched. Latched (1) AUTO_DISARM_TMR0_CTR ;42_Register used to count the number of 5 second cycles for the auto-disarm process SERIAL_TX_INT_FSR0L_SAVE;43_Register that allow to save FSR0L value after a TX interrupt was treated SERIAL_RX_INT_FSR0L_SAVE;44_Register that allow to save FSR0L value after a RX interrupt was treated CHKSUM ;45_Register used to calculate the checksum during RS-232 RX and Tx exchange ENDC CBLOCK 0x15A O1_LED_STAT ;OUTPUT LEDs status and control register O2_LED_STAT ; 7-(not used) O3_LED_STAT ; 6-(not used) O4_LED_STAT ; 5-(not used) O5_LED_STAT ; 4-Output 1-6 LED to be set to Flashing O6_LED_STAT ; 3-Output 1-6 LED to be set to Red ; 2-Output 1-6 LED to be set to Amber ; 1-Output 1-6 LED to be set to Green ; 0-Output 1-6 LED to be set to OFF ENDC ;USER VARIABLES AND SYSTEM VARIABLES THAT ARE UPDATED BY THE WINDOWS CONFIG. SOFTWARE CBLOCK 0x140 Ox_LOGIC ;variable used to store the 6 output logics. 0 means Ox has active low Tx logic. 1 means active high. O1_O2_DEL ; 0x141 ;variable used to store the O1-to-O2 switching delay O2_O3_DEL ;variable used to store the O2-to-O3 switching delay O3_O4_DEL ;variable used to store the O3-to-O4 switching delay O4_O5_DEL ;variable used to store the O4-to-O5 switching delay O5_O6_DEL ;variable used to store the O5-to-O6 switching delay O6_O5_DEL ; 0x146 ;variable used to store the O6-to-O5 switching delay O5_O4_DEL ;variable used to store the O5-to-O4 switching delay O4_O3_DEL ;variable used to store the O4-to-O3 switching delay O3_O2_DEL ;variable used to store the O3-to-O2 switching delay O2_O1_DEL ;variable used to store the O2-to-O1 switching delay LAST_ENABLED_Ox ;variable used to indicate the last output that is enabled (ex. 00100000 means O6 is the last output enabled) PTT_USER_LOGIC ;PTT logic: active low (0) active high (1) Ox_FB_ENABLED ;variable used to indicate if feedback detection is enabled for the 6 outputs(ex. 00000110 means O2 and O3 have feedback enabled) TONES_ENABLED ;Tone enabled register. Enabled (1), disabled (0) ; 2-Feedback alarm tone ; 1-Timeout tone ; 0-Sequencing tones TMOUT_TONE_DURATION ;This is the Tx timeout duration (in minutes) used to compare to Timer0 for rollover ENDC ;########### Maximum 192 variables in the blocks above!############. CBLOCK 0x160 SERIAL_RX_BUFF ;Serial USART Receive Buffer memory. 48 positions reserved. ENDC CBLOCK 0x190 SERIAL_TX_BUFF ;Serial USART Transmit Buffer memory. 48 positions reserved. ENDC ;****************************************************************************************************** ;Constant definitions ;Bit or Pin Positions lf_eoc_received EQU .1 ;position of the new cycle of character reception is required send_parameters EQU .2 ;position of the bit to request sending parameters information tx_cycle_on EQU .3 ;position of the tx cycle being performed flag write_cycle_req EQU .0 ;bit position for flagging when a FLL parameter Write in EEPROM is req'd setup_mode EQU .4 ;bit position of SERIAL_STAT to flag when the setup mode using a PC is enabled old_ptt_pin_state EQU .2 ;bit position in ARM_PTT_STAT1 to flag that PTT is in transition to enabled state. ptt_in_pin EQU .6 ;pin position for PTT input line on PORT B sys_armed EQU .0 ;bit position in ARM_PTT_STAT1 for system arming state ptt_debounced_state EQU .1 ;bit position in ARM_PTT_STAT1 for debounced PTT state arm_button_pin EQU .7 ;pin position for ARM button input line on PORT B arm_butt_treated EQU .3 ;bit position in ARM_PTT_STAT1 to flag that the button has already been treated ptt_treated EQU .2 ;bit position in ARM_PTT_STAT2 to flag that the PTT has already been debounced. arming_process_req EQU .5 ;bit position in ARM_PTT_STAT1 to flag that the arming process is requested. disarming_process_req EQU .6 ;bit position in ARM_PTT_STAT1 to flag that the disarming process is requested. sequencing_process_req EQU .7 ;bit position in ARM_PTT_STAT1 to flag that a sequencing process is requested arming_process_run EQU .0 ;bit position in ARM_PTT_STAT2 to flag that the arming process is happening. disarming_process_run EQU .1 ;bit position in ARM_PTT_STAT2 to flag that the disarming process is happening. seq_over EQU .0 ;bit position in TX/RX_SEQUENCING_STAT1 to flag that the Tx sequencing is over fb_tmr_started EQU .1 ;bit position in TX/RX_SEQUENCING_STAT1 to flag that the feedback delay timer is started. del_tmr_started EQU .2 ;bit position in TX/RX_SEQUENCING_STAT1 to flag that the waiting delay is started. o1_done EQU .0 ;bit position in TX_RX_OUTPUT_STAT to flag that output 1 Tx sequencing is done. o2_done EQU .1 ;bit position in TX_RX_OUTPUT_STAT to flag that output 1 Tx sequencing is done. o3_done EQU .2 ;bit position in TX_RX_OUTPUT_STAT to flag that output 1 Tx sequencing is done. o4_done EQU .3 ;bit position in TX_RX_OUTPUT_STAT to flag that output 1 Tx sequencing is done. o5_done EQU .4 ;bit position in TX_RX_OUTPUT_STAT to flag that output 1 Tx sequencing is done. o6_done EQU .5 ;bit position in TX_RX_OUTPUT_STAT to flag that output 1 Tx sequencing is done. o1_switch_req EQU .0 ;bit position in TX_RX_SW_REQ_STAT to flag that output 1 Tx switch is requested. o2_switch_req EQU .1 ;bit position in TX_RX_SW_REQ_STAT to flag that output 2 Tx switch is requested. o3_switch_req EQU .2 ;bit position in TX_RX_SW_REQ_STAT to flag that output 3 Tx switch is requested. o4_switch_req EQU .3 ;bit position in TX_RX_SW_REQ_STAT to flag that output 4 Tx switch is requested. o5_switch_req EQU .4 ;bit position in TX_RX_SW_REQ_STAT to flag that output 5 Tx switch is requested. o6_switch_req EQU .5 ;bit position in TX_RX_SW_REQ_STAT to flag that output 6 Tx switch is requested. o1_tx_fb_fail_alm EQU .0 ;bit position in TX_FB_ALM_STAT to flag that output 1 failed to switch to Tx. o2_tx_fb_fail_alm EQU .1 ;bit position in TX_FB_ALM_STAT to flag that output 2 failed to switch to Tx. o3_tx_fb_fail_alm EQU .2 ;bit position in TX_FB_ALM_STAT to flag that output 3 failed to switch to Tx. o4_tx_fb_fail_alm EQU .3 ;bit position in TX_FB_ALM_STAT to flag that output 4 failed to switch to Tx. o5_tx_fb_fail_alm EQU .4 ;bit position in TX_FB_ALM_STAT to flag that output 5 failed to switch to Tx. o6_tx_fb_fail_alm EQU .5 ;bit position in TX_FB_ALM_STAT to flag that output 6 failed to switch to Tx. o1_rx_fb_fail_alm EQU .0 ;bit position in RX_FB_ALM_STAT to flag that output 1 failed to switch to Rx. o2_rx_fb_fail_alm EQU .1 ;bit position in RX_FB_ALM_STAT to flag that output 2 failed to switch to Rx. o3_rx_fb_fail_alm EQU .2 ;bit position in RX_FB_ALM_STAT to flag that output 3 failed to switch to Rx. o4_rx_fb_fail_alm EQU .3 ;bit position in RX_FB_ALM_STAT to flag that output 4 failed to switch to Rx. o5_rx_fb_fail_alm EQU .4 ;bit position in RX_FB_ALM_STAT to flag that output 5 failed to switch to Rx. o6_rx_fb_fail_alm EQU .5 ;bit position in RX_FB_ALM_STAT to flag that output 6 failed to switch to Rx. o1_fb_present EQU .0 ;bit position in TX_FB_PRESENT_STAT to flag that output 1 Ts switch feedback is detected. o2_fb_present EQU .1 ;bit position in TX_FB_PRESENT_STAT to flag that output 2 Ts switch feedback is detected. o3_fb_present EQU .2 ;bit position in TX_FB_PRESENT_STAT to flag that output 3 Ts switch feedback is detected. o4_fb_present EQU .3 ;bit position in TX_FB_PRESENT_STAT to flag that output 4 Ts switch feedback is detected. o5_fb_present EQU .4 ;bit position in TX_FB_PRESENT_STAT to flag that output 5 Ts switch feedback is detected. o6_fb_present EQU .5 ;bit position in TX_FB_PRESENT_STAT to flag that output 6 Ts switch feedback is detected. led_off EQU .0 ;bit position in O1_LED_STAT and ARM_PTT_LED_STAT to signal to turn off the LED led_green EQU .1 ;bit position in O1_LED_STAT and ARM_PTT_LED_STAT to signal to make the LED green led_amber EQU .2 ;bit position in O1_LED_STAT and ARM_PTT_LED_STAT to signal to make the LED amber led_red EQU .3 ;bit position in O1_LED_STAT and ARM_PTT_LED_STAT to signal to make the LED red led_flashing EQU .4 ;bit position in O1_LED_STAT and ARM_PTT_LED_STAT to signal to make the LED flash arm_ptt_led_pin EQU .7 ;bit position in Port A for the Arm/PTT LED. tmout_tone_cycl_req EQU .0 ;bit position in GENERAL_STAT1 to flag that a timeout tone cycle is required tmout_tone_cycl_run EQU .1 ;bit position in GENERAL_STAT1 to flag that a timeout tone cycle is runing tmout_tone_sounding EQU .2 ;bit position in GENERAL_STAT1 to flag that a timeout tone is currently sounding seq_tone_sounding EQU .3 ;bit position in GENERAL_STAT1 to flag when a sequence tone is currnetly sounding seq_tone_enabled EQU .0 ;bit position in TONES_ENABLED to flag when the sequence tones are enabled tmout_tone_enabled EQU .1 ;bit position in TONES_ENABLED to flag when the timeout tone is enabled fb_alm_tone_req EQU .4 ;bit position in TONES_ENABLED to flag when the fb alarm tone is required fb_alm_tone_sounding EQU .5 ;bit position in TONES_ENABLED to flag when the fb alarm tone is sounding fb_tone_enabled EQU .2 ;bit position in TONES_ENABLED to flag when the feedback tone is enabled ccp2_pin EQU .1 ;pin position on PortC for the CCP2 (Tone output) auto_disarm_alm_del_cnting EQU .5 ;bit position in GENERAL1_STAT to indicate that an alarm auto-disarm delay is counting auto_disarm_tx_del_cnting EQU .6 ;bit position in GENERAL1_STAT to indicate that a TX auto-disarm delay is counting remote_mon_req EQU .5 ;bit position in SERIAL_STAT to request a transmission of the Remote Monitoring Information seq_end_tone_sounding EQU .7 ;bit position in TONES_STAT to signal to the remote monitoring tool that an end of sequence tone is sounding seq_start_tone_sounding EQU .6 ;bit position in TONES_STAT to signal to the remote monitoring tool that an start of sequence tone is sounding ;Bit Masks new_tx_cycle EQU b'00000001' ;mask to test if new cycle of character transmission is required ;Initialization Values ;W EQU .0 ;Is the working Register flag in various commands (defined in .INC file) F EQU .1 ;File register flag in various commands number_param_to_stor EQU .16 ;This is the number of parameters that are saved/restored in Data EEPROM, incl. addr. 0. eecon1_data_eeprom_access EQU b'00000000' ;will initialize EECON1 register for a Data EEPROM access. eecon1_prog_ee_access EQU b'10000000' ;will initialize EECON1 register for a Data EEPROM access. firmware_version EQU .2 max_arm_debounce_ctr EQU .255 max_ptt_debounce_ctr_h EQU .1 ;This corresponds to a PTT debounce of ~160ms max_ptt_debounce_ctr_l EQU .170 fb_alm_auto_disarm_del EQU .36 ;number of 5 second slices (3 minutes) before auto-disarming after a feedback alarm. tx_auto_disarm_del EQU .132 ;number of 5 second slices (11 minutes) before auto-disarming when a transmission is too long. ;****************************************************************************** ;Reset vector ; This code will start executing when a reset occurs. ORG 0x0000 GOTO MAIN ;go to start of main code ;****************************************************************************************************** ;High priority interrupt vector ; This code will start executing when a high priority interrupt occurs or ; when any interrupt occurs if interrupt priorities are not enabled. ORG 0x0008 BRA HIGHINT ;go to high priority interrupt routine ;****************************************************************************************************** ;LOWINT ;Low priority interrupt vector and routine ; This code will start executing when a low priority interrupt occurs. ORG 0x0018 LOWINT MOVFF STATUS,STATUS_TEMP ;save STATUS register MOVFF WREG,WREG_TEMP ;save working register MOVFF BSR,BSR_TEMP ;save BSR register CLRWDT ;Repeatedly clears the WatchDog timer. SERIAL_INT_CHECK BTFSS PIE1,TXIE ;Is TX interrupt enabled? BRA SERIAL_RX_CHECK ;No, go to test RX BTFSC PIR1,TXIF ;Yes, Did USART TX cause interrupt? BRA USART_TX_INT ;Yes, service it. SERIAL_RX_CHECK BTFSS PIE1,RCIE ;Is RX interrupt enabled? BRA NO_VALID_INT ;No, go to other test BTFSC PIR1,RCIF ;Yes, Did USART RX cause interrupt? BRA USART_RX_INT ;Yes, service it. NO_VALID_INT BRA LOWINT_EXIT ;no, branch to leave interrupt routine USART_TX_INT BTFSS SERIAL_STAT,new_tx_cycle ;verify if new character tx cycle initiated BRA NO_NU_CYCLE ;no, go to next validation LFSR FSR0,0x190 ;load Serial Tx buffer's base address in FSR register BCF SERIAL_STAT,new_tx_cycle ;yes, clear new Tx cycle flag BRA NU_TX_CYCLE ;branch to process a new Tx cycle NO_NU_CYCLE MOVFF SERIAL_TX_INT_FSR0L_SAVE,FSR0L ;Save TX FSR0L indirect addressing register value NU_TX_CYCLE TSTFSZ INDF0 ;is there a character in the buffer? BRA CHAR_PRESENT ;yes, go load it in tx buffer BCF SERIAL_STAT,tx_cycle_on ;nom clear the tx_cycle_on flag BCF PIE1,TXIE ;disable future TX interrupts BCF PIR1,TXIF ;Clear interrupt request Flag. BRA LOWINT_EXIT_TX ;go to end of ISR, restore context, return CHAR_PRESENT MOVFF INDF0,TXREG ;transfer (indirect addressing) character to Tx register CLRF POSTINC0 ;clear character and increase indirect pointer BCF PIR1,TXIF ;Clear interrupt request Flag. BRA LOWINT_EXIT_TX ;go to end of ISR, restore context, return USART_RX_INT BCF PIR1,RCIF ;clear Rx char. available interrupt flag MOVLW 06h ;Mask out unwanted bits ANDWF RCSTA,W ;Check for errors BTFSS STATUS,Z ;Was either error status bit set? BRA RXERROR ;Found error, flag it TSTFSZ SERIAL_RX_BUFF ;is there a character in the first rx buffer cell? BRA NO_NU_RX_CYCLE ;yes, go read next character LFSR FSR0,0x160 ;no, load Serial rx buffer's base address in FSR register BRA NU_RX_CYCLE ;Branch to process a new Rx cycle NO_NU_RX_CYCLE MOVFF SERIAL_RX_INT_FSR0L_SAVE,FSR0L ;Save RX FSR0L indirect addressing register value NU_RX_CYCLE MOVFF RCREG,POSTINC0 ;Get rx character from USART and increment indirect addr. pointer MOVLW h'8F' ;Has end of Rx buffer been reached (address 0x17F)? CPFSLT FSR0L ;" BRA END_RX_CYCLE ;Yes, go end Rx cycle MOVLW .10 ;No, Load LF char in Wreg CPFSEQ RCREG ;Is character received LF BRA LOWINT_EXIT_RX ;No, go to end of ISR, restore context, return END_RX_CYCLE BSF SERIAL_STAT,lf_eoc_received ;Yes, lift the end of user command flag BRA LOWINT_EXIT ; go to end of ISR, restore context, return RXERROR MOVF RCREG,W ;Discard received errored byte BCF RCSTA,CREN ;Clear receiver status BSF RCSTA,CREN ; " LOWINT_EXIT_RX MOVFF FSR0L,SERIAL_RX_INT_FSR0L_SAVE ;Recover previous RX FSR0L indirect addressing register value BRA LOWINT_EXIT ;Leave interrupt Routine LOWINT_EXIT_TX MOVFF FSR0L,SERIAL_TX_INT_FSR0L_SAVE ;Recover previous TX FSR0L indirect addressing register value LOWINT_EXIT MOVFF BSR_TEMP,BSR ;Restore BSR register MOVFF WREG_TEMP,WREG ;Restore working register MOVFF STATUS_TEMP,STATUS ;Restore STATUS register RETFIE 0 ;This exits and re-enable low priority interrupts ;****************************************************************************************************** ;HIGHINT ;High priority interrupt routine ; no need to save status registers for a high priority interrupt routine HIGHINT INCF PWM_CYCLE_CTR,F ;Increment the dither counter. BCF PIR1,TMR2IF ;Clear TIMER2 interrupt request flag RETFIE FAST ;This restores the 3 status registers and exits interrupt routine. ;****************************************************************************************************** ;MAIN ;Start of main program ;Initialization Area. This stuff is executed only once and at Reset time. MAIN MOVLB .1 ;Select RAM bank 1 for all variable accesses CLRF INTCON ;disable interrupts MOVLW b'10000000' ;enable interrupt priorities (high/low) MOVWF RCON ; " MOVLW b'01110010' ;select internal oscillator and set it to 8MHz MOVWF OSCCON ; " MOVLW b'10000111' ;Set Timer0 to operate on internal clock with a prescaler value of 256. MOVWF T0CON MOVLW b'00110010' ;enable Timer2=PR2 interrupt, Rx interrupt, Tx Interrupt MOVWF PIE1 ; " MOVLW b'00000001' ;enable CCP2 interrupt MOVWF PIE2 ; " MOVLW b'00000010' ;assign low priority to CCP1 interrupt, Timer1 ovfl, USART Tx MOVWF IPR1 ; and high priority to CCP2=PR2 (PWM) MOVLW b'10111111' ;PORTC set as follows: All set as inputs (except bit 7) to turn off LEDs MOVWF TRISC ; 7-Serial input ; 6-Serial output ; 5-Output LED 5 ; 4-Output LED 4 ; 3-Output LED 3 ; 2-Output LED 2 ; 1-CCP2 PWM output. Reserved for Piezzo buzzer. ; 0-Output LED 1 BCF INTCON2,NOT_RBPU ;Enables pullup resistors on Port B. MOVLW 0x0F ;Set RB<7:0> as MOVWF ADCON1 ; digital I/O pins MOVLW b'11111111' ;PORTB set as follows: MOVWF TRISB ; 7-Arm button input. Has internal pull-up. ; 6-PTT input. Has internal pull-up. ; 5-Feedback input for output 6. Has internal pull-up. ; 4-Feedback input for output 5. Has internal pull-up. ; 3-Feedback input for output 4. Has internal pull-up. ; 2-Feedback input for output 3. Has internal pull-up. ; 1-Feedback input for output 2. Has internal pull-up. ; 0-Feedback input for output 1. Has internal pull-up. SETF PORTA ;Put all ones on Port A outputs. BCF ADCON0,.0 ;Disable ADC conversion MOVLW b'01111111' ;PORTA set as follows: MOVWF TRISA ; 7-ARM/PTT LED ; 6-Output LED 6 ; 5-Sequencing output 6 ; 4-Sequencing output 5 (this one has an open drain output) ; 3-Sequencing output 4 ; 2-Sequencing output 3 ; 1-Sequencing output 2 ; 0-Sequencing output 1 STARTUP_DELAY ;This 1 sec delay is added to let the supply voltage stabilize. MOVLW h'E1' ;Load 1 second equivalent (500ns * 256 * (0x10000 - 0xE17B)) into timer0 value MOVWF TMR0H ; " MOVLW h'7B' ; " MOVWF TMR0L ; " BCF INTCON,TMR0IF ;Clear the timer0 overflow interrupt flag STARTUP_DELAY_LOOP BTFSS INTCON,TMR0IF ;Is flag raised (timer0 overflow)? BRA STARTUP_DELAY_LOOP ;No, loop to test again CONT_AFTER_DELAY ;Yes, continue with initialization MOVLW b'00000011' ;set timer2 to prescaler div. by 16 MOVWF T2CON ; but don't enable it yet MOVLW b'00001100' ;enables ccp2 in PWM mode MOVWF CCP2CON ; " CLEAR_VARIABLES ;Clear all variables, except the RS232 buffers and the EEPROM variables LFSR FSR1,0x100 ;Load indirect addressing register with base address of the variables to clear CLR_VARS_LOOP CLRF POSTINC1 ;Clear variable and increase indirect addressing pointer MOVLW 0x40 ;Have it reached end of buffer addresses CPFSEQ FSR1L ; " BRA CLR_VARS_LOOP ;No, loop again. READ_EEPROM_PARAMS ;Parameters are transfered from Data EEPROM to RAM variables LFSR FSR1,0x140 ;Load indirect addressing register with base address of the parameter variables CLRF TEMP1_HI ;Clear temporary variable used as EEPROM address offset READ_EEPROM_LOOP INCF TEMP1_HI,F ;Increment EEPROM address offset MOVF TEMP1_HI,W ;Load it in Wreg CALL READ_EEPROM_DATA ;Read data from EEPROM address MOVWF POSTINC1 ;Transfer EEPROM value to the parameter variable MOVLW number_param_to_stor ;Is this the last address (parameter) to read? CPFSLT TEMP1_HI ; " BRA CONT_INITIALIZE ;Yes leave EEPROM reading loop BRA READ_EEPROM_LOOP ;No, loop to read next EEPROM value CONT_INITIALIZE MOVLW b'00100100' ;Enable USART TX, 8 bits, Async, High Speed MOVWF TXSTA ; " MOVLW .207 ;Set baud rate to 2400 bps @ 8MHz CPU frequency MOVWF SPBRG ; " MOVLW b'10010000' ;Enable Serial port, enable Rx, 8 bits on Rx, Async MOVWF RCSTA ; " LFSR FSR1,0x160 ;Load indirect addressing register with base address of the USART Receive buffer CLR_RX_BUFFER_LOOP CLRF POSTINC1 ;Clear Rx buffer cell and increase indirect addressing pointer MOVLW 0x90 ;Have it reached end of buffer addresses CPFSEQ FSR1L ; " BRA CLR_RX_BUFFER_LOOP ;No, loop again. CONFIG_VARIABLES MOVLW b'00111111' ;Initialize the Sequence done Register MOVWF TX_RX_SEQ_DONE ; " BSF RX_SEQUENCING_STAT1,.0 ;Sets the Rx sequencing over flag BCF SERIAL_STAT,setup_mode ;Disable the setup mode INIT_OUTPUT_LOGIC_RX CLRF Ox_HIGH_LOW ;Clear the output high/low register MOVLW b'00000001' ;Initialize TEMP1_HI as bit position mask MOVWF TEMP1_HI ; " INIT_LOGIC_LOOP MOVF TEMP1_HI,W ;Transfer bit position mask to Wreg ANDWF Ox_LOGIC,W ;Mask Ox logic high/low bit BZ SET_LOGIC_Ox_Tx_LOW ;Is Ox logic high/low bit 0? Yes, go set low logic on Tx for that output SET_LOGIC_Ox_Tx_HIGH COMF TEMP1_HI,W ;Complement Ox logic high/low bit mask and transfer it into Wreg ANDWF Ox_HIGH_LOW,F ;Clear the corresponding Ox bit in the output high/low register BRA PREP_LOGIC_LOOP ;Go prepare the looping for another Output SET_LOGIC_Ox_Tx_LOW MOVF TEMP1_HI,W ;Move Ox logic high/low bit mask into Wreg IORWF Ox_HIGH_LOW,F ;Set the corresponding Ox bit in the output high/low register PREP_LOGIC_LOOP MOVLW b'00100000' ;Load the last output bit mask into Wreg CPFSLT TEMP1_HI ;Is the last output treated? BRA INIT_LOGIC_COMPLETE ;Yes, leave logic initialization loop RLNCF TEMP1_HI,F ;No, shift the bit position mask to the next Ox BRA INIT_LOGIC_LOOP ;Loop to treat next Ox INIT_LOGIC_COMPLETE BSF WDTCON,0 ;Enable WatchDog Timer MOVLW 0x46 ;load initial (50%) eight duty cycle MSb's in CCP2 register MOVWF CCPR2L ; " BCF CCP2CON,4 ;clear two duty cycle LSb's in CCP register BCF CCP2CON,5 ; " CLRF PIR1 ;Clear all interrupt request flags CLRF PIR2 ; " BCF PIR1,RCIF ;Clear RCIF Interrupt Flag BSF INTCON,GIEH ;enable high priority interrupts BSF INTCON,GIEL ;enable low priority interrupts ;****************************************************************************************************** ;TR_SEQ_MAIN ;This is the main loop that repeats indefinitely TR_SEQ_MAIN CLRWDT ;Clear the WatchDog timer. CALL READ_ARM_BUTTON ;Read, debounce and interpret the Arm/Disarm button CALL CTRL_ARMING ;Control the Output Arming process CALL CTRL_DISARMING ;Control the Output Disarming process CALL READ_PTT ;Read and debounce PTT line CALL CTRL_TX_SEQUENCING ;Control the Output Sequencing in Transmit mode CALL CTRL_RX_SEQUENCING ;Control the Output Sequencing in Receive mode CLRWDT ;Clear the WatchDog timer. CALL CTRL_OUTPUTS ;Control the Output pins CALL READ_PRESW_FEEDBACK ;Read Pre-switch output feedback CALL READ_FEEDBACK ;Read the Output feedback CALL CTRL_TMR0 ;Updates Timer0 and increases various counters CALL CTRL_TIMEOUT_TONE ;Control the Timeout Tone process CALL CTRL_FB_ALM_TONE ;Control the feedback alarm tone CALL CTRL_SEQ_TONES ;Control the Sequencing Tones process CALL CTRL_FB_ALARM_AUTO_DISARM ;Control a delayed disarming when a feedback alarm is present CLRWDT ;Clear the WatchDog timer. CALL CTRL_TX_AUTO_DISARM ;Controls the auto-disarm when a transmission lasts too long CALL CTRL_ARM_PTT_LED ;Control the ARM/PTT LED CALL CTRL_OUTPUT_LEDS ;Control the 6 Output LEDs CALL CTRL_PARAM_INFO_TX ;Control contents of the parameter line sent over serial port CALL CTRL_PARAM_INFO_RX ;Receives commands and parameters sent over serial port CALL CTRL_PARAM_UPD_EEPROM ;Control Writing in Flash EEPROM of parameters GOTO TR_SEQ_MAIN ;Loop back to beginning ;****************************************************************************************************** ;READ_ARM_BUTTON ;This routine detects the arm button action and requests an arming or disarming process READ_ARM_BUTTON BTFSC SERIAL_STAT,setup_mode ;Is the setup mode enabled? BRA CLEAR_BUTTON_FLAGS ;Yes, cancel ARM button reading and leave routine BTFSC PORTB,arm_button_pin ;No, Is Arm button pushed (pin low)? BRA CLEAR_BUTTON_FLAGS ;No, go clear button flags and leave routine BTFSC ARM_PTT_STAT1,arm_butt_treated ;Yes, Is the arm button already treated flag raised? BRA READ_ARM_RET ;Yes, leave routine TEST_ARM_DEBOUNCING MOVLW max_arm_debounce_ctr ;No, load the maximum value of debounce counter into Wreg CPFSLT ARM_DEBOUNCE_CTR ;Is the debounce counter less than the maximum BRA TEST_ARM_BUT_AGAIN ;No, Go validate the arm button again INCF ARM_DEBOUNCE_CTR,F ;Yes, increment the debounce counter BRA READ_ARM_RET ;Leave routine TEST_ARM_BUT_AGAIN BTFSS PORTB,arm_button_pin ;Is Arm button still pushed (pin low)? BRA ARM_BUTT_VALIDATED ;Yes, go update Arm button debounced state BRA CLEAR_BUTTON_FLAGS ;No, go clear button flags and leave routine ARM_BUTT_VALIDATED CLRF ARM_DEBOUNCE_CTR ;Clear the debounce counter BSF ARM_PTT_STAT1,arm_butt_treated ;Raise the arm button already treated flag BTFSC ARM_PTT_STAT1,sys_armed ;Check if system is armed? BRA DO_DISARMING ;Yes, go disarm system DO_ARMING BTFSC ARM_PTT_STAT1,ptt_debounced_state ;No, is the PTT active? BRA READ_ARM_RET ;Yes, leave routine BTFSS RX_SEQUENCING_STAT1,seq_over ;No, is the Rx sequencing process over BRA READ_ARM_RET ;No, leave routine BSF ARM_PTT_STAT1,arming_process_req ;Raise the arming process requested flag BRA READ_ARM_RET ;Leave routine DO_DISARMING BCF ARM_PTT_STAT1,sys_armed ;Change system armed flag to disarmed BSF ARM_PTT_STAT1,disarming_process_req ;Raise the disarming process requested flag BRA READ_ARM_RET ;Leave routine CLEAR_BUTTON_FLAGS BCF ARM_PTT_STAT1,arm_butt_treated ;Clear the Arm button already treated flag READ_ARM_RET RETURN ;Leave routine ;****************************************************************************************************** ;CTRL_ARMING ;This routine controls the arming process when requested by the arm button. It enables outputs starting at ;the last enabled outputs and ending at output #1. It inserts proper sequence delays between outputs activation. CTRL_ARMING BTFSC SERIAL_STAT,setup_mode ;Is the setup mode enabled? BRA CTRL_ARM_RET ;Yes, leave routine BTFSC ARM_PTT_STAT2,arming_process_run ;Is the arming process currently running? BRA CONTINUE_ARMING ;Yes, continue to treat it BTFSS ARM_PTT_STAT1,arming_process_req ;No, is the arming process requested flag raised? BRA CTRL_ARM_RET ;No, leave routine ARMING_START MOVFF LAST_ENABLED_Ox,ARM_DISARM_Ox_POS ;Yes, transfer the last enabled output bit into the arming output position pointer BCF ARM_PTT_STAT1,arming_process_req ;Clear the arming process required flag BSF ARM_PTT_STAT2,arming_process_run ;Set the arming process running flag MOVF PORTA,W ;Put all outputs to '0' in preparation for the output arm process ANDLW b'11000000' ; " MOVWF PORTA ; " LFSR FSR1,0x146 ;Load the Rx sequence delays base address into the indirect addressing register MOVLW b'00100000' ;Initialize TEMP1_HI to output-6 position MOVWF TEMP1_HI ; " ARM_PREP_LOOP CPFSLT LAST_ENABLED_Ox ;Is the last enabled Ox register less than the temporary pointer BRA ARM_Ox ;No, Go arm the first output RRNCF TEMP1_HI,F ;Yes, roll right the temporary pointer MOVF TEMP1_HI,W ;Move this temporary pointer to Wreg INCF FSR1L,F ;Increment the indirect pointer by one location BRA ARM_PREP_LOOP ;Loop to next iteration CONTINUE_ARMING BTFSS INTCON,TMR0IF ;Is the Timer 0 count rollover flag set? BRA CTRL_ARM_RET ;No, leave routine ARM_Ox MOVFF Ox_LOGIC,TEMP1_LO ;Yes, transfer the output logic variable into TEMP1_LO MOVF ARM_DISARM_Ox_POS,W ;Transfer the currently treated Ox into Wreg ANDWF TEMP1_LO,F ;Mask the current Ox logic bit COMF TEMP1_LO,W ;Complement the current Ox logic bit register and load into Wreg ANDWF PORTA,F ;Toggle PortA pin corresponding to current Ox accordingly ANDWF Ox_HIGH_LOW,F ;Also Toggle the current Ox output pin state into the high/low register COMF ARM_DISARM_Ox_POS,W ;Complement the currently treated Ox and transfer result into Wreg ANDLW b'01111111' ;But first prepare bits 7 and 8 of port A mode so that they are not changed when AND'ing ANDWF TRISA,F ;Set the current output Port A pin in output mode MOVLW b'00000001' ;Is last output treated? CPFSGT ARM_DISARM_Ox_POS ; " BRA END_ARMING ;Yes, go end the arming process RRNCF ARM_DISARM_Ox_POS,F ;No, shift the currently treated Ox bit right to treat the next Ox on the next pass CALL READ_DELAY_TABLE ;Read the corresponding output sequence delay INCF FSR1L,F ;Increment the indirect pointer by one location MOVFF TEMP2_HI,TMR0H ;Transfer these values into Timer0 high latch MOVFF TEMP2_LO,TMR0L ;Transfer these values into Timer0 low latch BCF INTCON,TMR0IF ;Clear the Timer 0 count rollover flag BRA CTRL_ARM_RET ;Leave routine END_ARMING CLRF TX_RX_OUTPUT_STAT ;Clear the Tx/Rx status register BSF ARM_PTT_STAT1,sys_armed ;Yes, change system armed flag to armed BCF ARM_PTT_STAT2,arming_process_run ;Clear the arming process running flag CLRF TX_FB_ALM_STAT ;Clear the Tx feedback alarm status register CLRF RX_FB_ALM_STAT ;Clear the Rx feedback alarm status register CLRF TX_RX_PRESW_FB_ALM_STAT ;Clear the Rx pre-switch feedback alarm status register CTRL_ARM_RET RETURN ;Leave routine ;****************************************************************************************************** ;CTRL_DISARMING ;This routine controls the disarming process when requested by the arm button. It enables outputs starting at ;output #1 and ending with output #6. It inserts proper sequence delays between outputs de-activation. CTRL_DISARMING BTFSC SERIAL_STAT,setup_mode ;Is the setup mode enabled? BRA CTRL_DISARM_RET ;Yes, leave routine BTFSC ARM_PTT_STAT2,disarming_process_run ;Is the disarming process running? BRA CONTINUE_DISARMING ;Yes, continue to treat disarming BTFSS ARM_PTT_STAT1,disarming_process_req ;Is the disarming process requested flag set? BRA CTRL_DISARM_RET ;No, leave routine DISARMING_START MOVLW b'00000001' ;Yes, Initialize the disarming output position pointer witht the first output position to treat MOVWF ARM_DISARM_Ox_POS ; " BCF ARM_PTT_STAT1,disarming_process_req ;Clear the disarming process required flag BSF ARM_PTT_STAT2,disarming_process_run ;Set the disarming process running flag LFSR FSR1,0x141 ;Load the Tx sequence delays base address into the indirect addressing register BRA DISARM_Ox ;Go disarm the first output CONTINUE_DISARMING BTFSS INTCON,TMR0IF ;Is the Timer 0 count rollover flag set? BRA CTRL_DISARM_RET ;No, leave routine DISARM_Ox MOVF ARM_DISARM_Ox_POS,W ;Yes, Transfer the output position bit into Wreg IORWF TRISA,F ;Set the corresponding Port A output pin as an input MOVF LAST_ENABLED_Ox,W ;Is the last output treated? CPFSLT ARM_DISARM_Ox_POS ; " BRA END_DISARMING ;Yes, go end the disarming process RLNCF ARM_DISARM_Ox_POS,F ;No, roll left the output position bit to treat the next output on the next pass CALL READ_DELAY_TABLE ;Read the corresponding output sequence delay INCF FSR1L,F ;Increment the indirect pointer by one location MOVFF TEMP2_HI,TMR0H ;Transfer these values into Timer0 high latch MOVFF TEMP2_LO,TMR0L ;Transfer these values into Timer0 low latch BCF INTCON,TMR0IF ;Clear the Timer 0 count rollover flag BRA CTRL_DISARM_RET ;Leave routine END_DISARMING ;Portion of code that makes sure that the output LEDs show the right status after disarming regardless of when disarm button is pressed. MOVF Ox_LOGIC,W ;Load Output logic register into Wreg BTFSS ARM_PTT_STAT1,ptt_debounced_state ;Is the PTT active? BRA DISARM_PTT_LOW ;No, Disarm while PTT is inactive DISARM_PTT_HIGH ANDLW b'00111111' ;Yes, isolate the 6 output logic bits MOVWF Ox_HIGH_LOW ;Transfet these into the output high/low status byte BSF TX_SEQUENCING_STAT1,seq_over ;Mark the Tx sequence as over MOVLW b'00111111' ;Load Tx/Rx output states into Wreg BRA DISARM_PTT_CONT ;Go continue to disarm DISARM_PTT_LOW COMF Ox_LOGIC,W ;Complement the output logic register ANDLW b'00111111' ;Isolate the complemented output logic bits MOVWF Ox_HIGH_LOW ;Transfet these into the output high/low status byte BSF RX_SEQUENCING_STAT1,seq_over ;Mark the Rx sequence as over MOVLW b'00000000' ;Load Tx/Rx output states into Wreg DISARM_PTT_CONT MOVWF TX_RX_OUTPUT_STAT ;Transfer these into the Tx/Rx output status register BCF ARM_PTT_STAT2,disarming_process_run ;Clear the disarming process running flag BCF T2CON,TMR2ON ;Disable Timer2 (Turns off any tone) BSF TRISC,ccp2_pin ;Put the CCP2 pin in input mode (disables) BCF TONES_STAT,tmout_tone_cycl_run ;Clear the timeout tone cycle running flag BCF TONES_STAT,tmout_tone_cycl_req ;Clear the timeout tone cycle required flag BCF TONES_STAT,tmout_tone_sounding ;Clear the timeout tone sounding flag BCF TONES_STAT,fb_alm_tone_req ;Clear the feedback alarm tone requested flag BCF TONES_STAT,fb_alm_tone_sounding ;Clear the feedback alarm tone sounding flag BCF TONES_STAT,seq_tone_sounding ;Clear the sequencing tone sounding flag MOVLW b'00111111' ;Mark the Sequence as completed MOVWF TX_RX_SEQ_DONE ; " CLRF TX_FB_ALM_STAT ;Clear the Tx feedback alarm status register CLRF RX_FB_ALM_STAT ;Clear the Rx feedback alarm status register CLRF TX_RX_PRESW_FB_ALM_STAT ;Clear the pre-switch feedback alarm status register BCF GENERAL1_STAT,auto_disarm_alm_del_cnting;Clear the alarm auto disarm delay counting flag BCF GENERAL1_STAT,auto_disarm_tx_del_cnting ;Clear the Tx auto disarm delay counting flag CLRF AUTO_DISARM_TMR0_CTR ;Clear the timer0 Counter CTRL_DISARM_RET RETURN ;Leave routine ;****************************************************************************************************** ; READ_PTT ;This routine reads and debounces the sequencer PTT line. READ_PTT MOVFF PORTB,TEMP1_HI ;Take a snapshot of the PTT pin by copying PORTB into TEMP1_HI BTFSS ARM_PTT_STAT1,old_ptt_pin_state ;Is previous PTT pin state high? BRA TEST_PTT_OLD_LOW ;No, it is low. Go test when previous PTT state is low TEST_PTT_OLD_HIGH BTFSS TEMP1_HI,ptt_in_pin ;Yes, is the current PTT pin state in high? BRA PTT_IN_TRANSITION ;No, go flag a PTT pin transition BTFSS ARM_PTT_STAT2,ptt_treated ;Yes, is the PTT already treated flag set? BRA OLD_NEW_PTT_SAME ;No, go validate debounced PTT state BRA READ_PTT_RET ;Yes, leave routine TEST_PTT_OLD_LOW BTFSC TEMP1_HI,ptt_in_pin ;Is the current PTT pin state in low? BRA PTT_IN_TRANSITION ;No, go validate PTT in transition state BTFSS ARM_PTT_STAT2,ptt_treated ;Yes, is the PTT already treated flag set? BRA OLD_NEW_PTT_SAME ;No, go validate debounced PTT state BRA READ_PTT_RET ;Yes, leave routine OLD_NEW_PTT_SAME INFSNZ PTT_DEBOUNCE_CTR_L ;Increment the PTT debouncing counter INCF PTT_DEBOUNCE_CTR_H ; " TEST_DEBNC_CNTR MOVLW max_ptt_debounce_ctr_h ;Load the maximum value high of debounce counter into Wreg CPFSGT PTT_DEBOUNCE_CTR_H ;Is the debounce counter high less than the maximum BRA READ_PTT_RET ;Yes, leave routine MOVLW max_ptt_debounce_ctr_l ;Load the maximum value low of debounce counter into Wreg CPFSGT PTT_DEBOUNCE_CTR_L ;Is the debounce counter low less than the maximum BRA READ_PTT_RET ;Yes, leave routine BSF ARM_PTT_STAT2,ptt_treated ;No, set the PTT treated flag TSTFSZ PTT_USER_LOGIC ;Is PTT logic set to active low? BRA PTT_LOGIC_HI ;No, Go treat active high PTT logic BRA PTT_LOGIC_LO ;Yes, Go treat active low PTT logic PTT_LOGIC_LO BTFSS TEMP1_HI,ptt_in_pin ;Active low PTT logic. Is PTT pin high (inverse of real PTT line)? BRA PTT_DISABLED ;No, Go set the PTT state to disabled BRA PTT_ENABLED ;Yes, go enable PTT PTT_LOGIC_HI BTFSC TEMP1_HI,ptt_in_pin ;Active high PTT logic. Is PTT pin low (inverse of real PTT line)? BRA PTT_DISABLED ;No, Go set the PTT state to disabled PTT_ENABLED BTFSC ARM_PTT_STAT1,ptt_debounced_state ;Yes, Is the debounced PTT already active BRA READ_PTT_RET ;Yes, leave routine BSF ARM_PTT_STAT1,ptt_debounced_state ;No, Set the debounced PTT state flag to enabled BSF ARM_PTT_STAT1,sequencing_process_req ;Set the new sequencing process requested flag BCF TX_SEQUENCING_STAT1,seq_over ;Clear the Tx Sequencing over flag BRA READ_PTT_RET ;leave routine PTT_DISABLED BTFSS ARM_PTT_STAT1,ptt_debounced_state ;Yes, Is the debounced PTT already inactive BRA READ_PTT_RET ;Yes, leave routine BCF ARM_PTT_STAT1,ptt_debounced_state ;No, Clear the debounced PTT state flag to disabled BSF ARM_PTT_STAT1,sequencing_process_req ;Set the new sequencing process requested flag BCF RX_SEQUENCING_STAT1,seq_over ;Clear the rx Sequencing over flag BRA READ_PTT_RET ;leave routine PTT_IN_TRANSITION CLRF PTT_DEBOUNCE_CTR_H ;Clear the PTT debouncing counter CLRF PTT_DEBOUNCE_CTR_L ; " BTFSS TEMP1_HI,ptt_in_pin ;Is the current PTT pin state in high? BCF ARM_PTT_STAT1,old_ptt_pin_state ;No, set the previous PTT state flag to low BTFSC TEMP1_HI,ptt_in_pin ;Yes, Is the current PTT pin state in low? BSF ARM_PTT_STAT1,old_ptt_pin_state ;No, set the previous PTT state flag to high BCF ARM_PTT_STAT2,ptt_treated ;Clear the PTT already treated flag READ_PTT_RET RETURN ;Leave routine ;****************************************************************************************************** ;CTRL_TX_SEQUENCING ;This procedure controls the transfer from Rx to Tx by switching outputs one at a time while checking ;feedback for switching confirmation and inserting a user-defined delay between outputs. CTRL_TX_SEQUENCING BTFSC SERIAL_STAT,setup_mode ;Is the setup mode enabled? BRA CTRL_TX_SEQ_RET ;Yes, leave routine BTFSC ARM_PTT_STAT2,arming_process_run ;No, is the arming process running flag set? BRA CTRL_TX_SEQ_RET ;Yes, leave routine BTFSS ARM_PTT_STAT1,ptt_debounced_state ;No, Is the debounced PTT state flag raised BRA CTRL_TX_SEQ_RET ;No, leave routine BTFSC TX_SEQUENCING_STAT1,seq_over ;Yes, is the Tx sequencing over? BRA CTRL_TX_SEQ_RET ;Yes, leave routine TSTFSZ TX_FB_ALM_STAT ;No, Did any of the feedback points failed? BRA CTRL_TX_SEQ_RET ;Yes, leave routine TSTFSZ RX_FB_ALM_STAT ;No, Did any of the feedback points failed? BRA CTRL_TX_SEQ_RET ;Yes, leave routine TSTFSZ TX_RX_PRESW_FB_ALM_STAT ;No, Did any of the pre-switchfeedback points failed? BRA CTRL_TX_SEQ_RET ;Yes, leave routine BTFSS ARM_PTT_STAT1,sequencing_process_req ;Is this a new sequencing process requested flag? BRA CHECK_Ox_TX_DONE ;No, go check the outputs MOVFF TX_RX_OUTPUT_STAT,TX_RX_SEQ_DONE ;Transfer the Tx/Rx Status byte into the sequence done register BCF ARM_PTT_STAT1,sequencing_process_req ;Clear the new sequencing process requested flag CLRF TX_FB_PRESENT_STAT ;Clear the Tx feedback present register BCF TX_SEQUENCING_STAT1,fb_tmr_started ;Clear the Tx feedback timer started flag BCF RX_SEQUENCING_STAT1,fb_tmr_started ;Clear the Rx feedback timer started flag BCF TX_SEQUENCING_STAT1,del_tmr_started ;clear the Tx delay timer started flag CLRF TX_RX_PRESW_FB_PRES_STAT ;Clear the TX/RX Pre-switch Feedback Present Status register CLRF TX_RX_PRESW_FB_REQ_STAT ;Clear the TX/RX Pre-switch Feedback request Status register CLRF RX_FB_ALM_STAT ;Clear the Rx feedback alarm points MOVLW b'00000001' ;Initialize the Tx output position pointer to output 1 MOVWF TX_Ox_POS_PTR ; " LFSR FSR1,0x141 ;load Tx Delay registers base address into indirect addressing pointer CHECK_Ox_TX_DONE MOVF TX_RX_SEQ_DONE,W ;Move the sequencing done register into Wreg ANDWF TX_Ox_POS_PTR,W ;Mask the current output's sequencing done bit. Is current output switch completed? BNZ PREP_TX_LOOP ;Yes, go test next output CONT_Ox_CHECK_DONE BTFSC TX_SEQUENCING_STAT1,del_tmr_started ;No, delay timer started? BRA CHECK_Ox_Oy_TX_DELAY ;Yes, go test timer for delay expiry BTFSC TX_SEQUENCING_STAT1,fb_tmr_started ;No, feedback timer started? BRA CHECK_Ox_TX_FB_DELAY ;Yes, go test timer for feedback or feedback delay expiry BTFSS ARM_PTT_STAT1,sys_armed ;No, check if system is armed BRA NO_TX_PRESWITCH_CHECK ;No, don't validate Pre-switch feedback MOVF TX_RX_PRESW_FB_REQ_STAT,W ;Yes, is a Pre-switch feedback test requested for currently treated output? ANDWF TX_Ox_POS_PTR,W ; " BZ TX_PRESW_REQ_FB_CHECK ;No, go request for a feedback check MOVF TX_RX_PRESW_FB_PRES_STAT,W ;Yes, is the feedback checked and present for the currently treated output? ANDWF TX_Ox_POS_PTR,W ; " BZ TX_FB_SET_ALM ;No, go set the alarm for that output CLRF TX_RX_PRESW_FB_PRES_STAT ;Yes, clear the TX/RX Pre-switch Feedback Present Status register CLRF TX_RX_PRESW_FB_REQ_STAT ;Clear the TX/RX Pre-switch Feedback request Status register NO_TX_PRESWITCH_CHECK MOVFF TX_Ox_POS_PTR,TX_RX_SW_REQ_STAT ;Request to switch o1 to Tx CALL START_FB_TIMER ;Start the feedback timer BSF TX_SEQUENCING_STAT1,fb_tmr_started ;Set the feedback timer started flag BRA CTRL_TX_SEQ_RET ;Leave routine TX_PRESW_REQ_FB_CHECK MOVFF TX_Ox_POS_PTR,TX_RX_PRESW_FB_REQ_STAT ;Request to check pre-switch feedback on current output BRA CTRL_TX_SEQ_RET ;Leave routine CHECK_Ox_Oy_TX_DELAY BTFSS INTCON,TMR0IF ;Is the Timer 0 count rollover flag set? BRA CTRL_TX_SEQ_RET ;No, Leave routine BCF TX_SEQUENCING_STAT1,del_tmr_started ;Yes, clear the delay timer started flag BRA CTRL_TX_SEQ_RET ;Leave routine CHECK_Ox_TX_FB_DELAY BTFSS ARM_PTT_STAT1,sys_armed ;Check if system is armed BRA Ox_TX_SWITCH_DONE ;No, don't validate feedback MOVF TX_Ox_POS_PTR,W ;Yes, Is feedback sensing enabled for this output? ANDWF Ox_FB_ENABLED,W ; " BZ Ox_TX_SWITCH_DONE ;No, don't validate feedback MOVF TX_FB_PRESENT_STAT,W ;Yes, mask feedback present bit for current output ANDWF TX_Ox_POS_PTR,W ;Is feed back detected for current output? BNZ Ox_TX_SWITCH_DONE ;Yes, go mark switching of output 1 as done BTFSS INTCON,TMR0IF ;No, Is the Timer 0 count rollover flag set? BRA CTRL_TX_SEQ_RET ;No, leave routine TX_FB_SET_ALM MOVF TX_Ox_POS_PTR,W ;Yes, Transfer Tx output position pointer into Wreg IORWF TX_FB_ALM_STAT,F ;Set the feedback alarm for the current output BSF TONES_STAT,fb_alm_tone_req ;set the feedback alarm tone requested flag TSTFSZ TX_RX_PRESW_FB_REQ_STAT ;Are there any pre-switch feedback requests active? MOVFF TX_RX_PRESW_FB_REQ_STAT,TX_RX_PRESW_FB_ALM_STAT ;Yes, Transfer the request bit into an alarm bit CLRF TX_RX_PRESW_FB_PRES_STAT ;Clear the TX/RX Pre-switch Feedback Present Status register CLRF TX_RX_PRESW_FB_REQ_STAT ;Clear the TX/RX Pre-switch Feedback request Status register BRA CTRL_TX_SEQ_RET ;leave routine Ox_TX_SWITCH_DONE MOVF TX_Ox_POS_PTR,W ;Transfer Tx output position pointer into Wreg IORWF TX_RX_SEQ_DONE,F ;Set flag for current output Tx switch completed MOVF LAST_ENABLED_Ox,W ;Is last output treated CPFSLT TX_Ox_POS_PTR ; " BRA TX_SEQ_OVER ;Yes, go end the Tx sequence BCF TX_SEQUENCING_STAT1,fb_tmr_started ;No, Clear the feedback timer started flag CALL READ_DELAY_TABLE ;Go read the corresponding output delay from the table MOVFF TEMP2_HI,TMR0H ;Transfer these values into Timer0 high latch MOVFF TEMP2_LO,TMR0L ;Transfer these values into Timer0 low latch BCF INTCON,TMR0IF ;Clear the Timer 0 count rollover flag BSF TX_SEQUENCING_STAT1,del_tmr_started ;Set the delay timer flag BRA PREP_TX_LOOP ;Go prepare next pass and leave routine TX_SEQ_OVER CLRF TX_RX_FB_REQ_STAT ;Clear the feedback request register CLRF TX_FB_ALM_STAT ;Clear the Tx output feedback alarm status register CLRF TX_FB_PRESENT_STAT ;Clear the feedback present register BSF TX_SEQUENCING_STAT1,seq_over ;Set the Tx Sequencing over flag BCF TX_SEQUENCING_STAT1,fb_tmr_started ;Clear the feedback timer started flag BSF TONES_STAT,tmout_tone_cycl_req ;Request a start of the the timeout timer BRA CTRL_TX_SEQ_RET ;Leave routine PREP_TX_LOOP RLNCF TX_Ox_POS_PTR,F ;shift left the output position pointer bit for next pass. INCF FSR1L,F ;Increment the indirect pointer by one location CTRL_TX_SEQ_RET RETURN ;Leave routine ;****************************************************************************************************** ;CTRL_RX_SEQUENCING ;This procedure controls the transfer from Tx to Rx by switching outputs one at a time while checking ;feedback for switching confirmation and inserting a user-defined delay between outputs. CTRL_RX_SEQUENCING BTFSC SERIAL_STAT,setup_mode ;Is the setup mode enabled? BRA CTRL_RX_SEQ_RET ;Yes, leave routine BTFSC ARM_PTT_STAT1,ptt_debounced_state ;Is the debounced PTT state flag cleared BRA CTRL_RX_SEQ_RET ;No, leave routine BTFSC RX_SEQUENCING_STAT1,seq_over ;Yes, is the Rx sequencing over? BRA CTRL_RX_SEQ_RET ;Yes, leave routine TSTFSZ RX_FB_ALM_STAT ;No, Did any of the feedback points failed? BRA CTRL_RX_SEQ_RET ;Yes, leave routine TSTFSZ TX_FB_ALM_STAT ;No, Did any of the feedback points failed? BRA CTRL_RX_SEQ_RET ;Yes, leave routine BTFSS ARM_PTT_STAT1,sequencing_process_req ;Is this a new sequencing process requested flag? BRA CHECK_Ox_RX_DONE ;No, go check the outputs COMF TX_RX_OUTPUT_STAT,W ;Yes, read the invert of the the Rx output state register ANDLW b'00111111' ;isolate the 6 output bits MOVWF TX_RX_SEQ_DONE ;Transfer the inversion into the sequence done register BCF ARM_PTT_STAT1,sequencing_process_req ;Clear the new sequencing process requested flag BCF RX_SEQUENCING_STAT1,seq_over ;Clear the rx Sequencing over flag CLRF RX_FB_PRESENT_STAT ;Clear the rx feedback present register BCF RX_SEQUENCING_STAT1,fb_tmr_started ;Clear the feedback timer started flag BCF RX_SEQUENCING_STAT1,del_tmr_started ;clear the delay timer started flag BCF TX_SEQUENCING_STAT1,fb_tmr_started ;Clear the feedback timer started flag CLRF TX_RX_PRESW_FB_PRES_STAT ;Clear the TX/RX Pre-switch Feedback Present Status register CLRF TX_RX_PRESW_FB_REQ_STAT ;Clear the TX/RX Pre-switch Feedback request Status register MOVFF LAST_ENABLED_Ox,RX_Ox_POS_PTR ;Initialize the Tx output position pointer to the last enabled output LFSR FSR1,0x146 ;load Rx Delay registers base address into indirect addressing pointer MOVLW b'00100000' ;Initialize TEMP1_HI as the Tx output position pointer to output 6 MOVWF TEMP1_HI ; " RX_SEQ_PREP_LOOP CPFSLT RX_Ox_POS_PTR ;Is the current output pointer less than the temporary pointer BRA CHECK_Ox_RX_DONE ;No, go check Ox output RRNCF TEMP1_HI,F ;Yes, roll right the temporary pointer MOVF TEMP1_HI,W ;Move this temporary pointer to Wreg INCF FSR1L,F ;Increment the indirect pointer by one location BRA RX_SEQ_PREP_LOOP ;Loop to next iteration CHECK_Ox_RX_DONE MOVF TX_RX_SEQ_DONE,W ;Move the sequencing done register into Wreg ANDWF RX_Ox_POS_PTR,W ;Mask the current output's sequencing done bit. Is current output switch completed? BNZ PREP_RX_LOOP ;Yes, go test next output BTFSC RX_SEQUENCING_STAT1,del_tmr_started ;No, delay timer started? BRA CHECK_Ox_Oy_RX_DELAY ;Yes, go test timer for delay expiry BTFSC RX_SEQUENCING_STAT1,fb_tmr_started ;No, feedback timer started? BRA CHECK_Ox_RX_FB_DELAY ;Yes, go test timer for feedback or feedback delay expiry BTFSS ARM_PTT_STAT1,sys_armed ;No, Check if system is armed BRA NO_RX_PRESWITCH_CHECK ;No, don't validate Pre-switch feedback MOVF TX_RX_PRESW_FB_REQ_STAT,W ;Yes, Is a Pre-switch feedback test requested for currently treated output? ANDWF RX_Ox_POS_PTR,W ; " BZ RX_PRESW_REQ_FB_CHECK ;No, go request for a feedback check MOVF TX_RX_PRESW_FB_PRES_STAT,W ;Yes, is the feedback checked and present for the currently treated output? ANDWF RX_Ox_POS_PTR,W ; " BZ RX_PRESW_FB_SET_ALM ;No, go set the alarm for that output CLRF TX_RX_PRESW_FB_PRES_STAT ;Yes, clear the TX/RX Pre-switch Feedback Present Status register CLRF TX_RX_PRESW_FB_REQ_STAT ;Clear the TX/RX Pre-switch Feedback request Status register NO_RX_PRESWITCH_CHECK MOVFF RX_Ox_POS_PTR,TX_RX_SW_REQ_STAT ;Request to switch o1 to Rx CALL START_FB_TIMER ;Start the feedback timer BSF RX_SEQUENCING_STAT1,fb_tmr_started ;Set the feedback timer started flag BRA CTRL_RX_SEQ_RET ;Leave routine RX_PRESW_REQ_FB_CHECK MOVFF RX_Ox_POS_PTR,TX_RX_PRESW_FB_REQ_STAT ;Request to check pre-switch feedback for the current output BRA CTRL_RX_SEQ_RET ;Leave routine CHECK_Ox_Oy_RX_DELAY BTFSS INTCON,TMR0IF ;Is the Timer 0 count rollover flag set? BRA CTRL_RX_SEQ_RET ;No, Leave routine BCF RX_SEQUENCING_STAT1,del_tmr_started ;Yes, clear the delay timer started flag BRA CTRL_RX_SEQ_RET ;Leave routine CHECK_Ox_RX_FB_DELAY BTFSS ARM_PTT_STAT1,sys_armed ;Check if system is armed BRA Ox_RX_SWITCH_DONE ;No, don't validate feedback MOVF RX_Ox_POS_PTR,W ;Yes, is feedback sensing enabled for this output? ANDWF Ox_FB_ENABLED,W ; " BZ Ox_RX_SWITCH_DONE ;No, don't validate feedback MOVF RX_FB_PRESENT_STAT,W ;Yes, validate feedback ANDWF RX_Ox_POS_PTR,W ;Is feed back detected for output 1? BNZ Ox_RX_SWITCH_DONE ;Yes, go mark switching of output 1 as done BTFSS INTCON,TMR0IF ;No, Is the Timer 0 count rollover flag set? BRA CTRL_RX_SEQ_RET ;No, leave routine BRA RX_FB_SET_ALM ;Yes, go set feedback alarm RX_PRESW_FB_SET_ALM CLRF TX_RX_PRESW_FB_PRES_STAT ;Clear the TX/RX Pre-switch Feedback Present Status register CLRF TX_RX_PRESW_FB_REQ_STAT ;Clear the TX/RX Pre-switch Feedback request Status register RX_FB_SET_ALM MOVF RX_Ox_POS_PTR,W ;Yes, Raise the feedback alarm flag for that output. IORWF RX_FB_ALM_STAT,F ; " BSF TONES_STAT,fb_alm_tone_req ;Set the feedback alarm tone requested flag BRA CTRL_RX_SEQ_RET ;Leave routine Ox_RX_SWITCH_DONE MOVF RX_Ox_POS_PTR,W ;Set flag for current output Rx switch completed IORWF TX_RX_SEQ_DONE,F ; " MOVLW b'00000001' ;Is the last output treated CPFSGT RX_Ox_POS_PTR ; " BRA RX_SEQ_OVER ;Yes, go terminate the Rx sequence BCF RX_SEQUENCING_STAT1,fb_tmr_started ;No, clear the feedback timer started flag CALL READ_DELAY_TABLE ;Load the Rx output delay form the lookup table MOVFF TEMP2_HI,TMR0H ;Transfer these values into Timer0 high latch MOVFF TEMP2_LO,TMR0L ;Transfer these values into Timer0 low latch BCF INTCON,TMR0IF ;Clear the Timer 0 count rollover flag BSF RX_SEQUENCING_STAT1,del_tmr_started ;Set the delay timer flag BRA PREP_RX_LOOP ;Go prepare next pass and leave routine RX_SEQ_OVER CLRF TX_RX_FB_REQ_STAT ;Clear the feedback request register CLRF RX_FB_ALM_STAT ;Clear the Rx output feedback status register CLRF RX_FB_PRESENT_STAT ;Clear the feedback present register BSF RX_SEQUENCING_STAT1,seq_over ;Set the rx Sequencing over flag BCF RX_SEQUENCING_STAT1,fb_tmr_started ;Clear the feedback timer started flag BRA CTRL_RX_SEQ_RET ;Leave routine PREP_RX_LOOP RRNCF RX_Ox_POS_PTR,F ;shift right the output position pointer bit for next pass. INCF FSR1L,F ;Increment the indirect pointer by one location CTRL_RX_SEQ_RET RETURN ;Leave routine ;****************************************************************************************************** ;START_FB_TIMER ;This sub-routine is called by the Tx and Rx sequencing codes to initialize a waiting period for feedback ;detection. Timer 0 is used. START_FB_TIMER MOVLW h'F8' ;Load Timer0 H register with the proper value for a 200 milli-second count MOVWF TMR0H ; " MOVLW h'5F' ;Load Timer0 L register with the proper value for a 200 milli-second count MOVWF TMR0L ; " BCF INTCON,TMR0IF ;Clear the Timer 0 count rollover flag RETURN ;Leave routine ;****************************************************************************************************** ;CTRL_OUTPUTS ;This piece of code control the switching of the 6 outputs and initiates a switching feedback request. CTRL_OUTPUTS BTFSC ARM_PTT_STAT2,arming_process_run ;Is the arming process currently running? BRA CTRL_OUTPUTS_RET ;Yes, leave routine MOVF TX_RX_SW_REQ_STAT,W ;No, load the switching request register into Wreg BZ CTRL_OUTPUTS_RET ;Any switching request? No, go leave routine SWITCH_TX_RX_OUTS XORWF PORTA,F ;Yes, update the Port A outputs XORWF TX_RX_OUTPUT_STAT,F ;Update the Tx/Rx status register XORWF Ox_HIGH_LOW,F ;Update the Output high/low state register MOVFF TX_RX_SW_REQ_STAT,TX_RX_FB_REQ_STAT ;Request for feedback check by setting the proper bit in the feedback request register CTRL_OUTPUTS_RET CLRF TX_RX_SW_REQ_STAT ;Clear the switching request register RETURN ;Leave routine ;****************************************************************************************************** ;READ_FEEDBACK ;This portion of code manages the post-switching feedback detection and issue a switching tone request. READ_FEEDBACK BTFSS ARM_PTT_STAT1,sys_armed ;Check if system is armed? BRA READ_FB_RET ;No, leave routine TSTFSZ RX_FB_ALM_STAT ;No, Did any of the Rx feedback points failed? BRA READ_FB_RET ;Yes, leave routine TSTFSZ TX_FB_ALM_STAT ;No, Did any of the Tx feedback points failed? BRA READ_FB_RET ;Yes, leave routine TSTFSZ TX_RX_FB_REQ_STAT ;Yes, is any Output feedback detection requested? BRA CHECK_FB_ENABLED ;Yes, go test feedback condition BRA READ_FB_RET ;No, leave routine CHECK_FB_ENABLED MOVF TX_RX_FB_REQ_STAT,W ;Yes, Is feedback sensing enabled for this output? ANDWF Ox_FB_ENABLED,W ; " BZ END_FB_PRESENT ;No, don't validate feedback CHECK_FB_Ox MOVF TX_RX_FB_REQ_STAT,W ;Find what output logic the current output is set to. ANDWF Ox_LOGIC,W ; " BNZ FB_Ox_POS_LOGIC ;Is output logic positive (active high)? Yes, go test for positive logic FB_Ox_NEG_LOGIC BTFSS TX_SEQUENCING_STAT1,fb_tmr_started ;No, is the Tx feedback timer started? BRA FB_Ox_NEG_RX ;No, Go test Rx, negative logic. FB_Ox_NEG_TX MOVF TX_RX_FB_REQ_STAT,W ;Yes, test for Tx, negative logic. ANDWF PORTB,W ; " BTFSC STATUS,Z ;Detect if feedback is present on input pin of the treated output. is Port B, bit 0 low? BRA READ_FB_RET ;No, leave routine MOVF TX_RX_FB_REQ_STAT,W ;Yes, set the Output 1 Tx feedback present bit. IORWF TX_FB_PRESENT_STAT,F ; " COMF TX_RX_FB_REQ_STAT,W ;Clear the feedback alarm flag for that output. ANDWF TX_FB_ALM_STAT,F ; " BRA END_FB_PRESENT ;Go request for a sequence tone and leave routine FB_Ox_NEG_RX MOVF TX_RX_FB_REQ_STAT,W ;Test for Rx, negative logic. ANDWF PORTB,W ; " BTFSS STATUS,Z ;Detect if feedback is present on input pin of the treated output. Is Port B, bit 0 high? BRA READ_FB_RET ;No, leave routine MOVF TX_RX_FB_REQ_STAT,W ;Yes, set the Output 1 Rx feedback present bit. IORWF RX_FB_PRESENT_STAT,F ; " COMF TX_RX_FB_REQ_STAT,W ;Clear the feedback alarm flag for that output. ANDWF RX_FB_ALM_STAT,F ; " BRA END_FB_PRESENT ;Go request for a sequence tone and leave routine FB_Ox_POS_LOGIC BTFSS TX_SEQUENCING_STAT1,fb_tmr_started ;Is the Tx feedback timer started? BRA FB_Ox_POS_RX ;No, Rx feedback timer started. Go test Rx, positive logic. FB_Ox_POS_TX MOVF TX_RX_FB_REQ_STAT,W ;Test for Tx, positive logic. ANDWF PORTB,W ; " BTFSS STATUS,Z ;Detect if feedback is present on input pin of the treated output. Is Port B, bit 0 low? BRA READ_FB_RET ;No, leave routine MOVF TX_RX_FB_REQ_STAT,W ;Yes, set the Output 1 Tx feedback present bit. IORWF TX_FB_PRESENT_STAT,F ; " COMF TX_RX_FB_REQ_STAT,W ;Clear the feedback alarm flag for that output. ANDWF TX_FB_ALM_STAT,F ; " BRA END_FB_PRESENT ;Go request for a sequence tone and leave routine FB_Ox_POS_RX MOVF TX_RX_FB_REQ_STAT,W ;Test for Rx, positive logic. ANDWF PORTB,W ; " BTFSC STATUS,Z ;Detect if feedback is present on input pin of the treated output. Is Port B, bit 0 high? BRA READ_FB_RET ;No, leave routine MOVF TX_RX_FB_REQ_STAT,W ;Yes, set the Output 1 Rx feedback present bit. IORWF RX_FB_PRESENT_STAT,F ; " COMF TX_RX_FB_REQ_STAT,W ;Clear the feedback alarm flag for that output. ANDWF RX_FB_ALM_STAT,F ; " END_FB_PRESENT MOVFF TX_RX_FB_REQ_STAT,TONE_REQ_STAT ;Feedback present. Set the sequence tone requested flag for that output. CLRF TX_RX_FB_REQ_STAT ;Clear the feedback requested flag register. READ_FB_RET RETURN ;Leave routine ;****************************************************************************************************** ;READ_PRESW_FEEDBACK ;This portion of code manages the pre-switching feedback detection. READ_PRESW_FEEDBACK BTFSS ARM_PTT_STAT1,sys_armed ;Check if system is armed? BRA READ_PRESW_FB_RET ;No, leave routine TSTFSZ RX_FB_ALM_STAT ;No, Did any of the Rx feedback points failed? BRA READ_PRESW_FB_RET ;Yes, leave routine TSTFSZ TX_FB_ALM_STAT ;No, Did any of the Tx feedback points failed? BRA READ_PRESW_FB_RET ;Yes, leave routine TSTFSZ TX_RX_PRESW_FB_REQ_STAT ;Yes, is any Output pre-switch feedback detection requested? BRA CHECK_PRESW_FB_ENABLED ;Yes, go test feedback condition BRA READ_PRESW_FB_RET ;No, leave routine CHECK_PRESW_FB_ENABLED MOVF TX_RX_PRESW_FB_REQ_STAT,W ;Yes, Is feedback sensing enabled for this output? ANDWF Ox_FB_ENABLED,W ; " BZ SW_FB_PRESENT ;No, don't validate feedback CHECK_PRESW_FB_Ox MOVF TX_RX_PRESW_FB_REQ_STAT,W ;Find what output logic the current output is set to. ANDWF Ox_LOGIC,W ; " BNZ PRESW_FB_Ox_POS_LOGIC ;Is output logic positive (active high)? Yes, go test for positive logic PRESW_FB_Ox_NEG_LOGIC MOVF TX_RX_PRESW_FB_REQ_STAT,W ;Yes, test for Tx, negative logic. BTFSS ARM_PTT_STAT1,ptt_debounced_state ;Is the debounced PTT already active BRA PRESW_FB_Ox_NEG_RX ;No, Go test Rx, negative logic. PRESW_FB_Ox_NEG_TX ANDWF PORTB,W ;Detect if feedback is present on input pin of the treated output. is Port B, bit 0 low? BTFSS STATUS,Z ; " BRA READ_PRESW_FB_RET ;No, leave routine BRA SW_FB_PRESENT ;Yes, go treat with FB present PRESW_FB_Ox_NEG_RX ANDWF PORTB,W ;Detect if feedback is present on input pin of the treated output. Is Port B, bit 0 high? BTFSC STATUS,Z ; " BRA READ_PRESW_FB_RET ;No, leave routine BRA SW_FB_PRESENT ;Yes, go treat with FB present PRESW_FB_Ox_POS_LOGIC MOVF TX_RX_PRESW_FB_REQ_STAT,W ;Test for Tx, negative logic. BTFSS ARM_PTT_STAT1,ptt_debounced_state ;Is the debounced PTT already active BRA PRESW_FB_Ox_POS_RX ;No, Rx feedback timer started. Go test Rx, positive logic. PRESW_FB_Ox_POS_TX ANDWF PORTB,W ;Detect if feedback is present on input pin of the treated output. Is Port B, bit 0 low? BTFSC STATUS,Z ; " BRA READ_PRESW_FB_RET ;No, leave routine BRA SW_FB_PRESENT ;Yes, go treat with FB present PRESW_FB_Ox_POS_RX ANDWF PORTB,W ;Detect if feedback is present on input pin of the treated output. Is Port B, bit 0 high? BTFSS STATUS,Z ; " BRA READ_PRESW_FB_RET ;No, leave routine SW_FB_PRESENT MOVFF TX_RX_PRESW_FB_REQ_STAT,TX_RX_PRESW_FB_PRES_STAT;Feedback present. Set the pre-switch feedback present for that output. COMF TX_RX_PRESW_FB_REQ_STAT,W ;Clear the feedback alarm flag for that output. ANDWF RX_FB_ALM_STAT,F ; " READ_PRESW_FB_RET RETURN ;Leave routine ;****************************************************************************************************** ;CTRL_TMR0 ;Timer 0 is shared by several functions. This piece of code treats Timer 0 for the Transmit (11 minutes of transmission) ;auto-disarm function and for the feedback alarm (3 minutes after a feedback alarm). CTRL_TMR0 BTFSS ARM_PTT_STAT1,sys_armed ;Check if system is armed BRA CTRL_TMR0_RET ;No, leave routine BTFSC GENERAL1_STAT,auto_disarm_alm_del_cnting;No, is the feedback alarm auto-disarm delay counting? BRA TREAT_ALM_OR_TX ;Yes, go treat timer0 BTFSC GENERAL1_STAT,auto_disarm_tx_del_cnting;No, is the auto disarm delay counting? BRA TREAT_ALM_OR_TX ;Yes, go treat timer0 BRA CTRL_TMR0_RET ;No, leave routine TREAT_ALM_OR_TX BTFSS INTCON,TMR0IF ;Is the timer 0 rollover flag set? BRA CTRL_TMR0_RET ;No, leave routine INCF TMOUT_TMR0_CTR,F ;Yes, increment the Timeout counter INCF AUTO_DISARM_TMR0_CTR,F ;Yes, increment the auto-disarm counter MOVLW 0x67 ;Yes, initialize timer 0 for a 5 second rollover delay MOVWF TMR0H ; " MOVLW 0x69 ; " MOVWF TMR0L ; " BCF INTCON,TMR0IF ;Clear the Timer 0 count rollover flag CTRL_TMR0_RET RETURN ;Leave Routine ;****************************************************************************************************** ;CTRL_TIMEOUT_TONE ;This code controls the Timeout Timer tone function. The delay before the sounding of the alarm is set by ;the user via the Windows program. CTRL_TIMEOUT_TONE BTFSS TONES_ENABLED,tmout_tone_enabled ;Is the timeout tone feature enabled? BRA CTRL_TIMEOUT_TONE_RET ;No, leave routine BTFSS ARM_PTT_STAT1,sys_armed ;Yes, check if system is armed BRA CTRL_TIMEOUT_TONE_RET ;No, leave routine MOVF TX_FB_ALM_STAT,W ;Yes, test to see if there is any feedback alarm IORWF RX_FB_ALM_STAT,W ; " BNZ CTRL_TIMEOUT_TONE_RET ;Yes, leave routine BTFSC TONES_STAT,tmout_tone_cycl_req ;No, is a timeout tone cycle requested? BRA START_TIMOUT_CYCLE ;Yes, go start a timeout tone cycle BTFSS TONES_STAT,tmout_tone_cycl_run ;No, Is a timeout tone cycle currently running? BRA CTRL_TIMEOUT_TONE_RET ;No, leave routine BTFSC ARM_PTT_STAT1,ptt_debounced_state ;Yes, is the system PTT in Tx mode? BRA TST_TMOUT_EXPIRED ;Yes, go test if timeout is expired CLEAR_TIMOUT_PROC BTFSC TONES_STAT,tmout_tone_sounding ;No, is the timeout tone currently sounding? BCF T2CON,TMR2ON ;Yes, Disable Timer2 BSF TRISC,ccp2_pin ;Put the CCP2 pin in input mode (disables) BCF TONES_STAT,tmout_tone_cycl_run ;Clear the timeout tone cycle running flag BCF TONES_STAT,tmout_tone_sounding ;Clear the timeout tone sounding flag BRA CTRL_TIMEOUT_TONE_RET ;Leave routine START_TIMOUT_CYCLE BSF TONES_STAT,tmout_tone_cycl_run ;Set the timeout tone cycle running flag BCF TONES_STAT,tmout_tone_cycl_req ;Clear the timeout tone cycle requested flag CLRF TMOUT_TMR0_CTR ;Clear the timeout timer 0 rollover counter register MOVLW 0x67 ;Initialize timer 0 for a 5 second rollover delay MOVWF TMR0H ; " MOVLW 0x69 ; " MOVWF TMR0L ; " BRA CTRL_TIMEOUT_TONE_RET ;Leave routine TST_TMOUT_EXPIRED BTFSC TONES_STAT,tmout_tone_sounding ;Is the timeout tone sounding? BRA CTRL_TIMEOUT_TONE_RET ;Yes, leave routine INCF TMOUT_TONE_DURATION,W ;Increment the timeout tone duration register and it into Wreg MULLW .6 ;Multiply it by 6 to get 30 secs slices since each timer 0 rollover is 5 secs. MOVF PRODL,W ;Load multiplication result into Wreg CPFSLT TMOUT_TMR0_CTR ;Is the rollover counter less than the timeout delay BRA START_TMOUT_TONE ;No, go sound timeout tone BRA CTRL_TIMEOUT_TONE_RET ;Leave routine START_TMOUT_TONE MOVLW 0x33 ;Load timer 2 with the proper timeout tone pitch on the PWM MOVWF PR2 ; " MOVLW 0x1A ;Load timer 2 for a 50% duty cycle on the PWM MOVWF CCPR2L ; " BCF PIR1,TMR2IF ;Clear Timer2 interrupt flag CLRF TMR2 ;Clear the timer 2 counter BSF T2CON,TMR2ON ;Enable Timer2 BCF TRISC,ccp2_pin ;Put the CCP2 pin in output mode (enables) BSF TONES_STAT,tmout_tone_sounding ;Set the timeout tone sounding flag CTRL_TIMEOUT_TONE_RET RETURN ;Leave routine ;****************************************************************************************************** ;CTRL_FB_ALM_TONE ;This routine controls the emission of the feedback alarm tone. The feature can be disabled within the Windows ;tool. CTRL_FB_ALM_TONE BTFSS TONES_ENABLED,fb_tone_enabled ;Is the feedback tone feature enabled? BRA CTL_FB_TONE_RET ;No, leave routine BTFSC TONES_STAT,fb_alm_tone_sounding ;Is the feedback alarm tone sounding? BRA CONTINUE_ALM_TONE ;Yes, go treat sounding alarm BTFSC TONES_STAT,fb_alm_tone_req ;No, is a feedback tone requested? BRA START_ALM_TONE ;Yes, go start a feedback tone BRA CTL_FB_TONE_RET ;No, leave routine START_ALM_TONE CLRF PWM_CYCLE_CTR ;Clear the PWM cycle counter CLRF PWM_CYCLE_ALM_CTR ;Clear the alarm tone cycle counter MOVLW 0x33 ;Load the alarm tone pitch and duty cycle into CCP2 period register MOVWF PR2 ; " MOVLW 0x1A ;Load the alarm tone duty cycle into CCP2 duty cycle register MOVWF CCPR2L ; " BCF TONES_STAT,fb_alm_tone_req ;Clear the feedback alarm tone requested flag MOVLW .16 ;Load the maximun number of cycles for the alarm tone MOVWF MAX_NUM_PWM_CYCLE ; " BCF PIR1,TMR2IF ;Clear Timer2 interrupt flag CLRF TMR2 ;Clear the Timer2 counter BSF T2CON,TMR2ON ;Enable Timer2 BCF TRISC,ccp2_pin ;Put the CCP2 pin in output mode (enables) BSF TONES_STAT,fb_alm_tone_sounding ;Set the alarm tone sounding flag BRA CTL_FB_TONE_RET ;Leave routine CONTINUE_ALM_TONE MOVF RX_FB_ALM_STAT,W ;Load the Rx feedback alarm status register into Wreg IORWF TX_FB_ALM_STAT,W ;Or it with the Tx feedback alarm status register and load result into Wreg BZ END_ALM_TONE ;Any feedback alarm? No, go end alarm tone MOVF MAX_NUM_PWM_CYCLE,W ;Yes, transfer maximum number of cycles into Wreg CPFSEQ PWM_CYCLE_CTR ;Is the PWM cycle counter at the maximum number of cycles? BRA CTL_FB_TONE_RET ;No, leave routine MOVLW .200 ;Yes, has the alarm tone cycle counter reached the limit? CPFSLT PWM_CYCLE_ALM_CTR ; " BRA END_ALM_TONE ;Yes, go end the alarm tone INCF PWM_CYCLE_ALM_CTR,F ;No, increment the alarm tone cycle counter CLRF PWM_CYCLE_CTR ;Clear the pwm cycle counter BRA CTL_FB_TONE_RET ;Leave routine END_ALM_TONE BCF PIR1,TMR2IF ;Clear Timer2 interrupt flag BCF T2CON,TMR2ON ;Enable Timer2 BSF TRISC,ccp2_pin ;Put the CCP2 pin in input mode (disables) BCF TONES_STAT,fb_alm_tone_sounding ;Clear the feedback alarm tone sounding flag CTL_FB_TONE_RET RETURN ;****************************************************************************************************** ;CTRL_SEQ_TONES ;This routine controls the emission of the switching tones. The last tone lasts longer than the other switching ;tones to indicate to the user that the sequence is over. The feature can be disabled within the Windows ;tool. CTRL_SEQ_TONES BTFSS TONES_ENABLED,seq_tone_enabled ;Is the sequence tone feature enabled? BRA CTRL_TONES_RET ;No, leave routine BTFSC ARM_PTT_STAT1,sys_armed ;Yes, check if system is armed BRA TONES_SYS_IS_ARMED ;Yes, go treat the sequence tone CLRF TONE_REQ_STAT ;Clear the Tone requested flags BRA CTRL_TONES_RET ;Leave routine TONES_SYS_IS_ARMED BTFSC TONES_STAT,fb_alm_tone_sounding ;Is the feedback alarm tone sounding? BRA CTRL_TONES_RET ;Yes, leave routine BTFSC TONES_STAT,seq_tone_sounding ;Is the sequence tone sounding? BRA CONTINUE_TONE ;Yes, go treat the tone TSTFSZ TONE_REQ_STAT ;No, is there a request for a tone seuqence? BRA START_TONE ;Yes, go start tone BRA CTRL_TONES_RET ;No, leave routine CONTINUE_TONE MOVF MAX_NUM_PWM_CYCLE,W ;Is the maximum number of PWM cycles reached? CPFSEQ PWM_CYCLE_CTR ; " BRA CTRL_TONES_RET ;No, leave routine END_TONE CLRF TONE_REQ_STAT ;Yes, Clear the requested tone flags BCF PIR1,TMR2IF ;Clear Timer2 interrupt flag BCF T2CON,TMR2ON ;Disable Timer2 BSF TRISC,ccp2_pin ;Put the CCP2 pin in input mode (disables) BCF TONES_STAT,seq_tone_sounding ;Clear the sequence tone warning flag BRA CTRL_TONES_RET ;Leave routine START_TONE CLRF PWM_CYCLE_CTR ;Clear the PWM cycle counter CLRF PWM_CYCLE_ALM_CTR ;Clear the PWM alarm counter MOVLW high Ox_TONE_PERIOD_LOCN ;Load the tone period table lookup table high address location in the table pointer H MOVWF TBLPTRH ; " MOVLW low Ox_TONE_PERIOD_LOCN ;Load the tone period table low address location in the table pointer L MOVWF TBLPTRL ; " CLRF TBLPTRU ;Clear the upper table pointer address CLRF TEMP1_LO ;Clear TEMP1_LO temporary variable MOVLW b'00000001' ;Load TEMP1_HI with the first output bit position MOVWF TEMP1_HI ; " START_TONE_LOOP1 CPFSGT TONE_REQ_STAT ;Are we treating the last tone request in the sequence BRA END_START_TONE_LOOP1 ;Yes, exit the current start loop RLNCF TEMP1_HI,F ;No, shift-left the temporary output position pointer MOVF TEMP1_HI,W ;Transfer the current output position pointer into Wreg INCF TBLPTRL,F ;Increment the table pointer position BRA START_TONE_LOOP1 ;Jump back to loop beginning END_START_TONE_LOOP1 MOVLW eecon1_prog_ee_access ;Initialize EEPROM data configuration registrer MOVWF EECON1 ; " TBLRD* ;Read into TABLAT and increment TBLPTR MOVFF TABLAT,TEMP1_LO ;copy period into TEMP1_LO INCF TEMP1_LO,F ;50% duty cycle = (PR2 + 1) / 2. Add 1 to period and RRNCF TEMP1_LO,F ;Divide result by 2 to get duty cycle = 50% BCF TEMP1_LO,.7 ; " MOVFF TEMP1_LO,CCPR2L ;Transfer duty cycle into CCPR2L MOVFF TABLAT,PR2 ;Transfer period value into the period register PR2 MOVLW .8 ;Load default tone duration for the first (lowest pitch) tone MOVWF TEMP1_LO ; " MOVLW b'00000001' ;Load temp variable TEMP1_HI with initial output position pointer MOVWF TEMP1_HI ; " START_TONE_LOOP2 MOVF TONE_REQ_STAT,W ;Are we positioned on the requested tone output? CPFSLT TEMP1_HI ; " BRA END_START_TONE_LOOP2 ;Yes, leave loop RLNCF TEMP1_HI,F ;No, shift-left output position pointer INCF TEMP1_LO,F ;Increment the number of tone cycles to send BRA START_TONE_LOOP2 ;Jump to beginning of loop END_START_TONE_LOOP2 BTFSS ARM_PTT_STAT1,ptt_debounced_state ;Is the debounced PTT already active BRA SET_TONE_RX ;No, go set a Rx tone to be sent MOVF LAST_ENABLED_Ox,W ;Yes, are we treating the last enabled output position? CPFSEQ TEMP1_HI ; " BRA SET_TONE ;No, go set normal tone BRA MULT_TONE_LENGTH ;Yes, go set a long tone SET_TONE_RX MOVLW b'00000001' ;This is a Rx cycle. Are we treating the last output tone? CPFSEQ TEMP1_HI ; " BRA SET_TONE ;No, go send a normal tone duration MULT_TONE_LENGTH SWAPF TEMP1_LO,F ;Yes, lengthen the tone by a factor of 16 BSF TONES_STAT,seq_end_tone_sounding ;indicate to the remote monitoring tool to send a tone SET_TONE MOVFF TEMP1_LO,MAX_NUM_PWM_CYCLE ;Load the number of periods (cycle to send) BCF PIR1,TMR2IF ;Clear Timer2 interrupt flag CLRF TMR2 ;Clear the Timer2 counter BSF T2CON,TMR2ON ;Enable Timer2 BCF TRISC,ccp2_pin ;Put the CCP2 pin in output mode (enables) BSF TONES_STAT,seq_tone_sounding ;Set the tone sounding flag CTRL_TONES_RET RETURN ;Leave routine ;****************************************************************************************************** ;CTRL_FB_ALARM_AUTO_DISARM ;This piece of code controls the automatic disarming when a feedback alarm has happened and the user does ;not disarm the sequencer manually. The delay is hard-set at 3 minutes. CTRL_FB_ALARM_AUTO_DISARM BTFSS ARM_PTT_STAT1,sys_armed ;Check if system is armed BRA CTRL_AUTO_DISARM_RET ;No , leave routine MOVF TX_FB_ALM_STAT,W ;Yes, test to see if there is any feedback alarm IORWF RX_FB_ALM_STAT,W ; " BZ CTRL_AUTO_DISARM_RET ;No, leave routine BTFSS GENERAL1_STAT,auto_disarm_alm_del_cnting;Yes, is the auto disarm delay counting? BRA START_TIMER0_AUTODSRM_DEL ;No, go start a delay counting TST_AUTODSRM_DEL_EXPIRED MOVLW fb_alm_auto_disarm_del ;Yes, the auto disarm delay is 36 x 5 = 180 secondes CPFSLT AUTO_DISARM_TMR0_CTR ;Is the rollover counter less than the auto-disarm delay BRA INITIATE_AUTO_DISARM ;No, go initiate an auto-disarm BRA CTRL_AUTO_DISARM_RET ;Yes, Leave routine START_TIMER0_AUTODSRM_DEL CLRF AUTO_DISARM_TMR0_CTR ;Clear the auto-disarm Counter BSF GENERAL1_STAT,auto_disarm_alm_del_cnting;Set the feedback alarm auto disarm delay counting flag BRA CTRL_AUTO_DISARM_RET ;Leave routine INITIATE_AUTO_DISARM BCF ARM_PTT_STAT1,sys_armed ;Change system armed flag to disarmed BSF ARM_PTT_STAT1,disarming_process_req ;Raise the disarming process requested flag BCF GENERAL1_STAT,auto_disarm_alm_del_cnting;Clear the auto disarm delay counting flag CTRL_AUTO_DISARM_RET RETURN ;Leave routine ;****************************************************************************************************** ;CTRL_TX_AUTO_DISARM ;This piece of code controls the automatic disarming when a transmission reaches an 11 minute duration. ;The delay is hard-set at 11 minutes. CTRL_TX_AUTO_DISARM BTFSS ARM_PTT_STAT1,sys_armed ;Check if system is armed BRA CTRL_TX_AUTO_DISARM_RET ;No, leave routine BTFSS ARM_PTT_STAT1,ptt_debounced_state ;Yes, is the debounced PTT state flag raised BRA RESET_TX_DISARM_STATUS ;No, go reset the Tx auto-disarm counting flag and leave routine BTFSS TX_SEQUENCING_STAT1,seq_over ;Yes, is the the Tx Sequencing over flag set BRA RESET_TX_DISARM_STATUS ;No, leave routine BTFSS GENERAL1_STAT,auto_disarm_tx_del_cnting;Yes, is the auto disarm delay counting? BRA START_TMR0_AUTODSRM_DEL ;No, go start a delay counting TST_TX_AUTODSRM_DEL_EXPIRED MOVLW tx_auto_disarm_del ;Yes, the auto disarm delay is 132 x 5 = 660 secondes (11 minutes) CPFSLT AUTO_DISARM_TMR0_CTR ;Is the rollover counter less than the auto-disarm delay BRA INITIATE_TX_AUTO_DISARM ;No, go initiate an auto-disarm BRA CTRL_TX_AUTO_DISARM_RET ;Yes, leave routine START_TMR0_AUTODSRM_DEL CLRF AUTO_DISARM_TMR0_CTR ;Clear the auto-disarm Counter BSF GENERAL1_STAT,auto_disarm_tx_del_cnting ;Set the Tx auto disarm delay counting flag BRA CTRL_TX_AUTO_DISARM_RET ;Leave routine INITIATE_TX_AUTO_DISARM BCF ARM_PTT_STAT1,sys_armed ;Change system armed flag to disarmed BSF ARM_PTT_STAT1,disarming_process_req ;Raise the disarming process requested flag RESET_TX_DISARM_STATUS BCF GENERAL1_STAT,auto_disarm_tx_del_cnting ;Clear the Tx auto disarm delay counting flag CTRL_TX_AUTO_DISARM_RET RETURN ;Leave routine ;****************************************************************************************************** ;CTRL_ARM_PTT_LED ;This LED control routine determines the PTT/Status LED color based on the sequencer state at that moment. ;This firmware will work when a bi-color LEDs are used. Three colors are supported Red, Green and Amber. CTRL_ARM_PTT_LED CLRF ARM_PTT_LED_STAT ;Clear the ARM_PTT_LED_STAT register. It will get updated after BTFSC ARM_PTT_STAT1,sys_armed ;Check if system is armed? BRA SET_ARM_LED_COLOR ;Yes, go treat the armed mode BTFSC ARM_PTT_STAT2,arming_process_run ;No, Is the arming process currently running? BRA SET_ARM_LED_COLOR ;Yes, go treat the LED in armed mode SET_ARM_LED_DISARMED MOVLW b'00000111' ;No, disarmed state. Test if the last 3 bits of the dimming counter are set ANDWF LED_DIM_CTR,W ; This effectively divides the "high" time by 8 and causes a dim SUBLW b'00000111' ; " BZ SET_ARM_LED_COLOR ;If no dim is required, go treat LED color MOVLW b'00000111' ;No, disarmed state. Test if the last 3 bits of the dimming counter are cleared ANDWF LED_DIM_CTR,W ; This effectively divides the "low" time by 8 and causes a dim SUBLW b'00000000' ; " BZ SET_ARM_LED_COLOR ;If no dim is required, go treat LED color BSF ARM_PTT_LED_STAT,led_off ;Dim required. Turn off the LED this pass to create a dim effect BRA SW_ARM_LED_OUT ;Yes, Go switch the LED pin SET_ARM_LED_COLOR BTFSS ARM_PTT_STAT1,ptt_debounced_state ;Yes, is the debounced PTT active? BSF ARM_PTT_LED_STAT,led_green ;No, set the green flag on BTFSC ARM_PTT_STAT1,ptt_debounced_state ;Yes, Is the debounced PTT inactive? BSF ARM_PTT_LED_STAT,led_amber ;No, set the amber flag on SW_ARM_LED_OUT BTFSC ARM_PTT_LED_STAT,led_off ;Is the off flag cleared? BSF TRISA,arm_ptt_led_pin ;No, set the LED output pin in input mode BTFSC ARM_PTT_LED_STAT,led_green ;Yes, Is the green flag raised? BCF PORTA,arm_ptt_led_pin ;Yes, set the LED output pin low BTFSC ARM_PTT_LED_STAT,led_red ;No, Is the red flag raised? BSF PORTA,arm_ptt_led_pin ;Yes, set the LED output pin high BTFSC ARM_PTT_LED_STAT,led_amber ;No, Is the amber flag raised? BTG PORTA,arm_ptt_led_pin ;Yes, toggle the LED output pin BTFSS ARM_PTT_LED_STAT,led_off ;No,Is the off flag raised? BCF TRISA,arm_ptt_led_pin ;No, set the LED output pin in output mode CTRL_ARM_LED_RET RETURN ;Leave routine ;****************************************************************************************************** ;CTRL_OUTPUT_LEDS ;This routine controls the behavior of the six Output LEDs. The amber color is generated by toggling rapidly ;between green and red. LED 6 is a separate case since it is not phisically located on the same physical port as the other 5 ones. CTRL_OUTPUT_LEDS BTFSC SERIAL_STAT,setup_mode ;Is the setup mode enabled? BRA CTRL_OUT_LEDS_RET ;Yes, leave routine LFSR FSR2,0x15A ;Load Indirect pointer with base address of output LEDs status register MOVLW b'00000001' ;Initialize temporary variable to output 1 LED position MOVWF TEMP1_HI ; " MOVWF O3_LED_STAT ;Initialize LED 3-6 status registers by setting the off flags MOVWF O4_LED_STAT ; " MOVWF O5_LED_STAT ; " MOVWF O6_LED_STAT ; " LOOP_OUT_LED CLRF INDF2 ;Clear the pointed output LED status register BTFSS ARM_PTT_STAT1,sys_armed ;Check if system is armed BRA TEST_LED_NO_ALM ;Yes, go to set LED when armed TEST_LED_ALM MOVF TX_FB_ALM_STAT,W ;Yes, test to see if there is any feedback alarm IORWF RX_FB_ALM_STAT,W ; " ANDWF TEMP1_HI,W ;Isolate the currently treated output feedback alarm BZ TEST_LED_NO_ALM ;No, go set the LED for no-alarm condition BSF INDF2,led_red ;Yes, set the red LED flag into the pointed output LED status register BRA PREP_OUT_LED_LOOP ;Go prepare for next output LED pass (loop) TEST_LED_NO_ALM MOVF TEMP1_HI,W ;Transfer the pointed output LED status register into Wreg ANDWF Ox_HIGH_LOW,W ;Is the output pin low (output active)? BZ SET_LED_AMBER ;Yes, go set the current output LED amber flag BSF INDF2,led_green ;No, set the green LED flag the pointed output LED status register BRA PREP_OUT_LED_LOOP ;Go prepare for next output LED pass SET_LED_AMBER BSF INDF2,led_amber ;Set the amber LED into the pointed output LED status register BRA PREP_OUT_LED_LOOP ;Go prepare for next output LED pass PREP_OUT_LED_LOOP MOVF LAST_ENABLED_Ox,W ;Is the currently treated output LED the last one? CPFSLT TEMP1_HI ; " BRA SW_OUT_LEDS ;Yes, go switch the output LED pins RLNCF TEMP1_HI ;No, roll left the current LED treated pointer INCF FSR2L,F ;Increment the pointer to the current output LED status register BRA LOOP_OUT_LED ;loop to treat the next output LED SW_OUT_LEDS INCF LED_DIM_CTR ;Icrement the dimming counter LFSR FSR2,0x15A ;Load Indirect pointer with base address of output LEDS status register MOVLW b'00000001' ;Initialize temporary variable to output 1 LED position MOVWF TEMP1_HI ; " SW_OUT_LEDS_LOOP BTFSC TEMP1_HI,6 ;Are we treating the 6th output LED (special case due to pin position)? BRA SW_O6_LED ;Yes, go set the output LED 6 BTFSS INDF2,led_off ;No, is the treated LED status flag set to off? BRA TEST_Ox_LED_GREEN ;No, go test for green flag MOVF TEMP1_HI,W ;Yes, set the output pin to input mode IORWF TRISC,F ; " BRA PREP_SW_OUT_LEDS_LOOP ;Go prepare for next output LED setting TEST_Ox_LED_GREEN COMF TEMP1_HI,W ;Complement the current LED treated indicator and store into Wreg ANDWF TRISC,F ;Set the current LED pin as an output to turn on LED BTFSS INDF2,led_green ;Is the treated LED status flag set to green? BRA TEST_Ox_LED_RED ;No, go test for red flag COMF TEMP1_HI,W ;Complement the current LED treated indicator and store into Wreg ANDWF PORTC,F ;Set the current LED pin as output low (green) BRA PREP_SW_OUT_LEDS_LOOP ;Go prepare for next output LED setting TEST_Ox_LED_RED BTFSS INDF2,led_red ;Is the treated LED status flag set to red? BRA TEST_Ox_LED_AMBER ;No, go test for amber flag MOVF TEMP1_HI,W ;Yes, Store the current LED treated indicator into Wreg IORWF PORTC,F ;Set the current LED output pin as output high (red) BRA PREP_SW_OUT_LEDS_LOOP ;Go prepare for next output LED setting TEST_Ox_LED_AMBER BTFSS INDF2,led_amber ;Is current LED amber flag set? BRA PREP_SW_OUT_LEDS_LOOP ;No, Go prepare for next output LED setting MOVF TEMP1_HI,W ;Yes, Store the current LED treated indicator into Wreg XORWF PORTC,F ;Toggle the current LED pin (fast red-green toggle gives amber color) PREP_SW_OUT_LEDS_LOOP BTFSC ARM_PTT_STAT1,sys_armed ;Check if system is armed BRA ARMED_NO_DIM ;Yes, go set current LED in full brightness BTFSC ARM_PTT_STAT2,disarming_process_run ;Is the disarming process running ? BRA ARMED_NO_DIM ;Yes, go set current LED in full brightness MOVLW b'00001111' ;No, test if the last 4 bits of the dimming counter are set ANDWF LED_DIM_CTR,W ; This effectively divides the "hi" time by 16 and causes a dim SUBLW b'00001111' ; " BZ ARMED_NO_DIM ;If, no dim is required in this pass, go prepare for next LED MOVLW b'00001111' ;No, test if the last 4 bits of the dimming counter are cleared ANDWF LED_DIM_CTR,W ; This effectively divides the "low" time by 16 and causes a dim SUBLW b'00000000' ; " BZ ARMED_NO_DIM ;If, no dim is required in this pass, go prepare for next LED MOVF TEMP1_HI,W ;Dim required. Turn off the LED this pass to create a dim effect IORWF TRISC,F ; " ARMED_NO_DIM INCF FSR2L,F ;Increnment indirect pointer to currently treated LED status register RLNCF TEMP1_HI,F ;Roll left the current LED treated indicator BTFSC TEMP1_HI,.1 ;Are we preparing for output 2 LED? RLNCF TEMP1_HI,F ;Yes, roll left another time (due to port C output pin assignment skipping) BRA SW_OUT_LEDS_LOOP ;Loop for next output LED treatment SW_O6_LED BTFSS O6_LED_STAT,led_off ;Treating output 6 LED. Is the off flag set? BRA TEST_O6_LED_GREEN ;No, go test for greed color BSF TRISA,.6 ;Yes, set output 6 LED to input (turn off) BRA TEST_O6_LED_DIM ;GO test Output 6 LED for dimming TEST_O6_LED_GREEN BCF TRISA,.6 ;Set output 6 LED pin to output (turn on) BTFSS O6_LED_STAT,led_green ;Is green flag set? BRA TEST_O6_LED_RED ;No, go treat red color BCF PORTA,.6 ;Yes, set output 6 LED pin to low (green) BRA TEST_O6_LED_DIM ;GO test Output 6 LED for dimming TEST_O6_LED_RED BTFSS O6_LED_STAT,led_red ;Is the red flag set? BRA TEST_O6_LED_AMBER ;No, go test for amber color BSF PORTA,.6 ;Yes, set output LED 6 pin to high (red) BRA TEST_O6_LED_DIM ;GO test Output 6 LED for dimming TEST_O6_LED_AMBER BTFSS O6_LED_STAT,led_amber ;Is the amber flag set? BRA CTRL_OUT_LEDS_RET ;No, leave routine BTG PORTA,.6 ;Yes, toggle output 6 LED pin (fast red-green toggle gives amber color) TEST_O6_LED_DIM BTFSC ARM_PTT_STAT1,sys_armed ;Is system armed? BRA CTRL_OUT_LEDS_RET ;Yes, leave routine BTFSC ARM_PTT_STAT2,disarming_process_run ;Is the disarming process running ? BRA CTRL_OUT_LEDS_RET ;Yes, go set current LED in full brightness MOVLW b'00001111' ;No, test if the last 4 bits of the dimming counter is set ANDWF LED_DIM_CTR,W ; This effectively divides the "on" time by 16 and causes a dim SUBLW b'00001111' ; " BZ CTRL_OUT_LEDS_RET ;If no dim is required, leave routine MOVLW b'00001111' ;No, test if the last 4 bits of the dimming counter is set ANDWF LED_DIM_CTR,W ; This effectively divides the "on" time by 16 and causes a dim SUBLW b'00000000' ; " BZ CTRL_OUT_LEDS_RET ;If no dim is required, leave routine BSF TRISA,.6 ;Dim required. Turn off the LED this pass to create a dim effect CTRL_OUT_LEDS_RET RETURN ;Leave routine ;****************************************************************************************************** ;CTRL_PARAM_INFO_TX ;This piece of code processes the transmission of the Sequencer parameters string to the serial port. It transfers the ;parameters and formats the ASCII string. CTRL_PARAM_INFO_TX BTFSC SERIAL_STAT,tx_cycle_on ;Is the transmit cycle already happening? BRA USART_INFO_RET ;Yes, exit routine BTFSC SERIAL_STAT,remote_mon_req ;Is it requested to send Remote Monitoring Info string? BRA TREAT_REMOTE_MON_TX ;Yes, go treat the Remote monitoring string BTFSC SERIAL_STAT,send_parameters ;No, Is it requested to send parameter string? BRA TREAT_PARAM_TX ;Yes, go prepare the parameter string BRA USART_INFO_RET ;No, leave routine TREAT_REMOTE_MON_TX ;Here, Indirect addressing cannot be used since we are not in Setup mode and FSR regs are used everywhere. MOVLW "M" ;Load character M into Wreg MOVWF SERIAL_TX_BUFF ;Load this character into the first Rx Buffer memory cell MOVFF ARM_PTT_STAT1,TEMP1_HI ;Transfer the hex value of ARM_PTT_STAT1 into TEMP1_HI CALL HEX_2_ASCII ;Convert to ASCII value. MOVFF TEMP1_LO,SERIAL_TX_BUFF+.1 ;Transfer the lower nibble ASCII equivalent into the Tx buffer MOVFF O1_LED_STAT,TEMP1_HI ;Transfer the hex value of O1_LED_STAT into TEMP1_HI CALL HEX_2_ASCII ;Convert to ASCII value. MOVFF TEMP1_LO,SERIAL_TX_BUFF+.2 ;Transfer the lower nibble ASCII equivalent into the Tx buffer MOVFF O2_LED_STAT,TEMP1_HI ;Transfer the hex value of O2_LED_STAT into TEMP1_HI CALL HEX_2_ASCII ;Convert to ASCII value. MOVFF TEMP1_LO,SERIAL_TX_BUFF+.3 ;Transfer the lower nibble ASCII equivalent into the Tx buffer MOVFF O3_LED_STAT,TEMP1_HI ;Transfer the hex value of O3_LED_STAT into TEMP1_HI CALL HEX_2_ASCII ;Convert to ASCII value. MOVFF TEMP1_LO,SERIAL_TX_BUFF+.4 ;Transfer the lower nibble ASCII equivalent into the Tx buffer MOVFF O4_LED_STAT,TEMP1_HI ;Transfer the hex value of O4_LED_STAT into TEMP1_HI CALL HEX_2_ASCII ;Convert to ASCII value. MOVFF TEMP1_LO,SERIAL_TX_BUFF+.5 ;Transfer the lower nibble ASCII equivalent into the Tx buffer MOVFF O5_LED_STAT,TEMP1_HI ;Transfer the hex value of O5_LED_STAT into TEMP1_HI CALL HEX_2_ASCII ;Convert to ASCII value. MOVFF TEMP1_LO,SERIAL_TX_BUFF+.6 ;Transfer the lower nibble ASCII equivalent into the Tx buffer MOVFF O6_LED_STAT,TEMP1_HI ;Transfer the hex value of O6_LED_STAT into TEMP1_HI CALL HEX_2_ASCII ;Convert to ASCII value. MOVFF TEMP1_LO,SERIAL_TX_BUFF+.7 ;Transfer the lower nibble ASCII equivalent into the Tx buffer MOVFF TONES_STAT,TEMP1_HI ;Transfer the hex value of TONES_STAT into TEMP1_HI CALL HEX_2_ASCII ;Convert to ASCII value. MOVFF TEMP1_HI,SERIAL_TX_BUFF+.8 ;Transfer the higher nibble ASCII equivalent into the Tx buffer MOVLW "\r" ;Load CR MOVWF SERIAL_TX_BUFF+.9 ; into Tx buffer MOVLW "\n" ;Load LF MOVWF SERIAL_TX_BUFF+.10 ; into Tx buffer MOVLW 00h ;Load Null MOVWF SERIAL_TX_BUFF+.11 ; into Tx buffer BCF TONES_STAT,seq_end_tone_sounding ;Clear the flag that indicates to the remote monitoring tool to send a tone BRA END_TX_COMMAND ;Go end the Tx string TREAT_PARAM_TX CLRF TEMP2_HI ;Clear TEMP2_HI. Will be used as a counter LFSR FSR1,0x140 ;Load the Parameters' base address in FSR1 register LFSR FSR2,0x190 ;Load Serial Tx buffer's base address in FSR2 register MOVLW "P" ;Load "P" character MOVWF POSTINC2 ; into Tx buffer MOVLW firmware_version ;Load the firmware version value in TEMP1_HI MOVWF TEMP1_HI ; " CALL HEX_2_ASCII ;Convert to two ASCII characters MOVFF TEMP1_HI,POSTINC2 ;Conversion routine returns TEMP1_HI/TEMP1_HI. Load first Hex char into Tx buffer. MOVFF TEMP1_LO,POSTINC2 ; and second hex char into Tx buffer. PARAM_TX_XFER_LOOP INCF TEMP2_HI,F ;Increment parameter counter MOVFF POSTINC1,TEMP1_HI ;Load the current parameter register in TEMP1_HI CALL HEX_2_ASCII ;Convert to two ASCII characters MOVFF TEMP1_HI,POSTINC2 ;Conversion routine returns TEMP1_HI/TEMP1_HI. Load first Hex char into Tx buffer. MOVFF TEMP1_LO,POSTINC2 ; and second hex char into Tx buffer. MOVLW number_param_to_stor ;Has the maximum number of parameters to store been reached CPFSEQ TEMP2_HI ; " BRA PARAM_TX_XFER_LOOP ;No, loop to treat the next parameter SEND_CR_LF MOVLW "\r" ;Yes, Load CR MOVWF POSTINC2 ; into Tx buffer MOVLW "\n" ;Load LF MOVWF POSTINC2 ; into Tx buffer MOVLW 00h ;Load Null MOVWF POSTINC2 ; into Tx buffer END_TX_COMMAND BSF SERIAL_STAT,new_tx_cycle ;Raise new TX cycle flag BCF SERIAL_STAT,send_parameters ;Clear the parameter string request flag BCF SERIAL_STAT,remote_mon_req ;Clear the Remote Monitoring String request flag BSF SERIAL_STAT,tx_cycle_on ;Raise the transmit cycle flag BSF PIE1,TXIE ;Enable TX interrupts USART_INFO_RET RETURN ;Leave routine ;****************************************************************************************************** ;CTRL_PARAM_INFO_RX ;This piece of code processes the reception of the Sequencer parameters string from the serial port. It transfers the ;parameters and formats the ASCII string. CTRL_PARAM_INFO_RX BTFSC SERIAL_STAT,tx_cycle_on ;Is a Tx cycle being processed? BRA USART_RX_RET ;Yes, leave (Indirect addressing reg. FSR2 shared with CTRL_TX_STRING) BTFSS SERIAL_STAT,lf_eoc_received ;No, has end of command flag (LF) been detected by interrupt routine BRA USART_RX_RET ;No, leave routine BCF PIE1,RCIE ;Yes, disable RX interrupts MOVLW "M" ;Load character M into Wreg CPFSEQ SERIAL_RX_BUFF ;Is it the Remote Monitor Request command command? BRA CONT_PARAM_TREAT ;No, go to next validation BSF SERIAL_STAT,remote_mon_req ;Yes, clear the remote monitoring string requested flag BCF SERIAL_STAT,lf_eoc_received ;Clear the end of command flag CLRF SERIAL_RX_BUFF ;Clear the Rx buffer CLRF SERIAL_RX_BUFF+.1 ; " CLRF SERIAL_RX_BUFF+.2 ; " BRA USART_RX_RET ;Leave routine CONT_PARAM_TREAT ;A pre-screening is required here to reject any non-supported command MOVLW "U" ;Load character U into Wreg SUBWF SERIAL_RX_BUFF,W ;Is it the parameters update command? BZ VALID_RX_COMMAND ;Yes, go treat it MOVLW "S" ;Load character S into Wreg SUBWF SERIAL_RX_BUFF,W ;Is it the Send parameters command? BZ VALID_RX_COMMAND ;Yes, go treat it MOVLW "R" ;Load character R into Wreg SUBWF SERIAL_RX_BUFF,W ;Is it Reset command? BNZ CLR_RX_BUFF ;No, go clear the Rx buffer VALID_RX_COMMAND BTFSC ARM_PTT_STAT2,disarming_process_run ;Yes, is the disarming process currently running? BRA USART_RX_NOINT_RET ;Yes, leave BTFSS ARM_PTT_STAT1,sys_armed ;No, check if system is armed? BRA RX_OK_TREAT ;No, continue with RX process BCF ARM_PTT_STAT1,sys_armed ;Yes, Change system armed flag to disarmed BSF ARM_PTT_STAT1,disarming_process_req ;Invoke a disarming process by setting the right bit BRA USART_RX_NOINT_RET ;Leave routine RX_OK_TREAT CLRF TEMP2_HI ;Yes, clear the TEMP2_HI variable. Will be used as a counter BSF SERIAL_STAT,setup_mode ;Enable the setup mode LFSR FSR1,0x140 ;Load the Parameters' base address in FSR1 register LFSR FSR2,0x160 ;Load Serial rx buffer's base address in FSR2 register MOVFF POSTINC2,TEMP1_LO ;Transfer first char into temp variable TST_U_COMMAND MOVLW "U" ;Load character U into Wreg CPFSEQ TEMP1_LO ;Is it the parameters update command? BRA TST_S_COMMAND ;No, go to next validation RX_CHECKSUM_CHECK MOVLW .0 ;Clear the checksum CLRF CHKSUM ; " RX_CHKSUM_LOOP MOVF POSTINC2,W ;Read the following character from the Rx buffer ADDWF CHKSUM,F ;Add its ASCII value to the checksum MOVLW 0x81 ;Checksum position in the Rx Buffer CPFSEQ FSR2L ;Have we reach the end of the string to compute the checksum from? BRA RX_CHKSUM_LOOP ;No, loop to calculate checksum for next character MOVFF POSTINC2,TEMP1_HI ;Yes, Transfer received checksum high character of hex into TEMP1_HI MOVFF POSTINC2,TEMP1_LO ;Transfer received checksum low character of hex into TEMP1_LO CALL ASCII_2_HEX ;Convert to hex value. MOVF TEMP1_HI,W ;Transfer hex value of the received checksum into Wreg CPFSEQ CHKSUM ;Does received checksum equals computed checksum? BRA CLR_RX_BUFF ;No, do not process command and go empty rx buffer LFSR FSR2,0x161 ;Yes, Load Serial rx buffer's first parameter position in FSR2 register CLRF TEMP2_HI ;Clear the TEMP2_HI variable. Will be used as a counter U_XFER_LOOP INCF TEMP2_HI,F ;Increment the TEMP2_HI counter MOVFF POSTINC2,TEMP1_HI ;Transfer high character of hex into TEMP1_HI MOVFF POSTINC2,TEMP1_LO ;Transfer low character of hex into TEMP1_LO CALL ASCII_2_HEX ;Convert to hex value. Zero Flag is valid here. MOVFF TEMP1_HI,POSTINC1 ;Transfer hex value into the parameter variable MOVLW number_param_to_stor ;Has the maximum number of parameters to store been reached CPFSEQ TEMP2_HI ; " BRA U_XFER_LOOP ;No, loop to continue to treat the U command transfer BSF GENERAL1_STAT,write_cycle_req ;Yes, set the flag to write the EEPROM with the DAC value and all other parameters BRA CLR_RX_BUFF ;go empty rx buffer TST_S_COMMAND MOVLW "S" ;Load character S into Wreg CPFSEQ TEMP1_LO ;Is it the Send parameters command? BRA TST_R_COMMAND ;No, go to next validation BSF SERIAL_STAT,send_parameters ;Yes, set the send parameters information flag BRA CLR_RX_BUFF ;go empty rx buffer TST_R_COMMAND MOVLW "R" ;Load character R into Wreg CPFSEQ TEMP1_LO ;Is it Reset command? BRA CLR_RX_BUFF ;No, go empty rx buffer RESET ;Execute device reset CLR_RX_BUFF BCF SERIAL_STAT,lf_eoc_received ;Clear the end of command flag LFSR FSR2,0x160 ;load Serial rx buffer's base address in FSR register. CLR_RX_BUFF_LOOP CLRF POSTINC2 ;Clear Rx buffer cell and increase indirect addressing pointer MOVLW 0x80 ;Has the whole Rx buffer been erased? CPFSEQ FSR2L ; " BRA CLR_RX_BUFF_LOOP ;No, loop again. USART_RX_RET BSF PIE1,RCIE ;Yes, enable RX interrupts USART_RX_NOINT_RET RETURN ;exit routine ;****************************************************************************************************** ;CTRL_PARAM_UPD_EEPROM ;This portion of code writes the Sequencer parameters to data EEPROM. This is a multi-pass process. Before the ;next byte write cycle can be processed, s/w must wait for the previous byte write cycle to complete. CTRL_PARAM_UPD_EEPROM BTFSS GENERAL1_STAT,write_cycle_req ;Is a Parameter Write cycle required or in progress? BRA UPDATE_PARAM_RET ;No, leave routine BTFSC SERIAL_STAT,tx_cycle_on ;Is a Tx cycle being processed? BRA UPDATE_PARAM_RET ;Yes, leave (EEPROM access of Data and Program must not happen concurrently) EXECUTE_WRITE LFSR FSR1,0x140 ;Load indirect addressing pointer with first parameter address NEXT_PARAM_WRITE_LOOP MOVLW .0 ;Is is time to load the valid Data Flag (00) parameter in the first location? CPFSEQ WRT_EEPROM_POS ; " BRA WRITE_PARAMS ;No, go write next parameter in EEPROM CLRF TEMP1_LO ;Yes, load 0 in TEMP1_LO BRA CALL_WRITE_DATA ;go call EEPROM writing routine WRITE_PARAMS MOVF WRT_EEPROM_POS,W ;Load the current EEPROM address (position) into Wreg MOVFF POSTINC1,TEMP1_LO ;Load current parameter into temporary variable CALL_WRITE_DATA CALL WRITE_EEPROM_DATA ;Call EEPROM writing routine WRITE_WAIT_LOOP CLRWDT ;Repeatedly clears the WatchDog timer. BTFSC EECON1,WR ;Yes, is Write cycle happening BRA WRITE_WAIT_LOOP ;Yes, loop until write cycle is over MOVLW number_param_to_stor ;Is this the last address (parameter) to write? CPFSLT WRT_EEPROM_POS ; " BRA END_WRITE_CYCLE ;Yes, go end the EEPROM writing process INCF WRT_EEPROM_POS,F ;No, Increment EEPROM Writing Position BRA NEXT_PARAM_WRITE_LOOP ;Go treat the next parameter to Write END_WRITE_CYCLE BCF GENERAL1_STAT,write_cycle_req ;Clear the write cycle flag CLRF WRT_EEPROM_POS ;Clear write position UPDATE_PARAM_RET RETURN ;Leave routine ;****************************************************************************************************** ;HEX_2_ASCII ;This code converts an hexadecimal byte to the equivalent two ASCII characters. HEX_2_ASCII ;The hex value is expected to be in TEMP1_HI when the routine is called MOVLW .58 ;Load ASCII equivalent of 10 into temporary var. MOVWF TEMP3_LO ; " LO_NIBBLE MOVF TEMP1_HI,W ;Move hex value into Wreg ANDLW h'0F' ;isolate lower nibble ADDLW .48 ;add ASCII ofset CPFSGT TEMP3_LO ;verify if ASCII char is higher than "9" ADDLW .7 ;yes, add additional ASCII offset MOVWF TEMP1_LO ;No, low ASCII characters is returned in TEMP1_LO HI_NIBBLE SWAPF TEMP1_HI,W ;load nibble-swapped hex value into Wreg ANDLW h'0F' ;isolate lower nibble ADDLW .48 ;add ASCII ofset CPFSGT TEMP3_LO ;verify if ASCII char is higher than "9" ADDLW .7 ;yes, add additional ASCII offset MOVWF TEMP1_HI ;No, high ASCII characters is returned in TEMP1_HI RETURN ;Leave routine. Result are in TEMP1_HI and TEMP1_LO ;****************************************************************************************************** ;ASCII_2_HEX ;This code converts two ASCII characters representing a hexadecimal byte to its numerical equivalent. ASCII_2_HEX ; The ASCII characters are expected to be in TEMP1_HI and TEMP1_LO when the routine is called MOVLW .10 ;load the offset required to test for gap between ASCII code for 9 and A MOVWF TEMP3_LO ; " HIGH_CHAR MOVLW .48 ;load ASCII offset equiv. into Wreg SUBWF TEMP1_HI,W ;substract 48 from ASCII character CPFSGT TEMP3_LO ;is ASCII character higher than "9" (like A,B,C,D,E,F) ADDLW .249 ;yes, substract an additional ASCII offset of 7 (adding 249 does the same) MOVWF TEMP1_HI ;no, load result into TEMP1_HI SWAPF TEMP1_HI,F ;swap nibbles to move to higher hex position LO_CHAR MOVLW .48 ;load ASCII offset equiv. into Wreg SUBWF TEMP1_LO,W ;substract 48 from ASCII character CPFSGT TEMP3_LO ;is ASCII character higher than "9" (like A,B,C,D,E,F) ADDLW .249 ;yes, substract an additional ASCII offset of 7 (adding 249 does the same) ADDWF TEMP1_HI,F ;add the result to the higher hex result RETURN ;Leave routine. Result is in TEMP1_HI ;****************************************************************************************************** ;READ_EEPROM_DATA ;This sub-routine reads one byte of Data EEPROM READ_EEPROM_DATA MOVWF EEADR ;Address to read is in Wreg BCF EECON1, CFGS ;Point to DATA memory BCF EECON1,EEPGD ;Point to DATA memory BSF EECON1,RD ;EEPROM Read MOVF EEDATA,W ;value read is moved to Wreg RETURN ;Leave sub-routine ;****************************************************************************************************** ;WRITE_EEPROM_DATA ;This sub-routine writes one byte of Data EEPROM WRITE_EEPROM_DATA MOVWF EEADR ;Data Memory Address to write is in Wreg MOVFF TEMP1_LO,EEDATA ;Data memory value is in TEMP1_LO BCF EECON1, CFGS ;Point to DATA memory BCF EECON1, EEPGD ;Point to DATA memory BSF EECON1, WREN ;Enable writes BCF INTCON, GIE ;Disable Interrupts MOVLW h'55' MOVWF EECON2 ;Write 55h MOVLW h'AA' MOVWF EECON2 ;Write AAh BSF EECON1, WR ;Set WR bit to begin write BCF EECON1, WREN ;Disable writes BSF INTCON, GIE ;Enable Interrupts RETURN ;Leave sub-routine ;****************************************************************************************************** ;READ_DELAY_TABLE ;This sub-routine determines the values to load to the timer that generates the switching delays based ;on user input (data flash values) as sent by the Windows program. READ_DELAY_TABLE MOVLW high Ox_DEL_TABLE_LOCN ;Load Output Delay lookup table high address location in the table pointer H MOVWF TBLPTRH ; " MOVLW low Ox_DEL_TABLE_LOCN ;Load Output Delay lookup tabl low address location in the table pointer L MOVWF TBLPTRL ; " CLRF TBLPTRU ;Load TBLPTR with the base address of the word RLNCF INDF1,W ;Multiply the current output delay index by 2 ANDLW b'11111110' ; " ADDWF TBLPTRL,F ;Add it to the lower table pointer MOVLW eecon1_prog_ee_access ;Initialize EEPROM data configuration registrer MOVWF EECON1 ; " TBLRD*+ ;Read to TABLAT and increment TBLPTR MOVFF TABLAT,TEMP2_LO ;Transfer low delay value into TEMP2_LO TBLRD* ;Read into TABLAT MOVFF TABLAT,TEMP2_HI ;Transfer high delay value into TEMP2_HI RETURN ;Leave sub-routine ;****************************************************************************************************** ;This is the Output Delay Lookup table and it is placed in Program Memory ; The values in this table are loaded into Timer0 to count the output delay specified by the user. ORG 0x0FC0 Ox_DEL_TABLE_LOCN ; 20ms , 30ms , 40ms , 50ms , 60ms , 70ms , 80ms , 90ms , 100ms, 150ms DW 0xFF64,0xFF16,0xFEC8,0xFE79,0xFE2B,0xFDDD,0xFD8F,0xFD41,0xFCF3,0xFB6C ; 200ms, 250ms, 300ms, 400ms, 500ms, 600ms, 700ms, 800ms, 900ms,1000ms DW 0xF9E5,0xF85F,0xF6D8,0xF3CB,0xF0BE,0xEDB0,0xEAA3,0xE796,0xE489,0xE17B ;****************************************************************************************************** ;This is the Output Tone period lookup table. The values saved are for the CCP2 PR2 register and will make ;the PWM produce the frequencies listed below. This table is saved in Program Memory. ORG 0x0FE8 Ox_TONE_PERIOD_LOCN ; O1:523Hz , O2:587Hz , O3:659Hz , O4:698Hz , O5:784Hz , O6:880Hz DB 0xEE , 0xD4 , 0xBD , 0xB2 , 0x9E , 0x8D ;****************************************************************************************************** ;Default Sequencer parameter values added into Data EEPROM locations, starting at address 0x00 ;Make sure the number_param_to_stor constant is updated when changing the number of parameters saved. ORG 0xF00000 PARAMETERS_LOCN ; NULL , Ox_LOGIC , O1_O2_DEL , O2_O3_DEL , O3_O4_DEL , O4_O5_DEL , O5_O6_DEL , O6_O5_DEL , O5_O4_DEL , O4_O3_DEL DE 0x00 , 0x00 , 0x08 , 0x08 , 0x08 , 0x08 , 0x08 , 0x08 , 0x08 , 0x08 ; O3_O2_DEL , O2_O1_DEL , LAST_ENABLED_Ox , PTT_USER_LOGIC , Ox_FB_ENABLED , TONES_ENABLED , TMOUT_TONE_DURATION , NULL DE 0x08 , 0x08 , 0x20 , 0x01 , 0x00 , 0x03 , 0x07 , 0xFF ;Then we fill the remaining data EEPROM values (except the last two) with FF. This makes the PIC burner happy. DE 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF DE 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF DE 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF DE 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF DE 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF DE 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF DE 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF DE 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF DE 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF DE 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF DE 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF DE 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF DE 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF DE 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF DE 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ;****************************************************************************************************** ;The last Data EEPROM value stores the FW VERSION to allow to read the firmware version from PICMicro burner, ;whitout running the firmware. It is not saved or retrieved by firmware. It is located in the last Data EEPROM Byte. ; BLANK , FW VERSION DE 0xFF , .2 ;****************************************************************************************************** ;End of program END