;====================================================================== ; panic.asm ; ; This file implements panic_routine, which is called by the ; `panic' macro in panic.inc. See panic.inc for the functionality ; of `panic'. include common.inc ;--------------------------------------------------------------------------- ; reserved access bank locations udata_acs ; used in panic routine for temporary storage: flash_pattern res 1 morse_counter res 1 register_counter res 1 bit_counter res 1 panic_address res 1 ; condensed form of message start addr. panic_morse res 1 ; # bytes of morse msg in panic readout panic_regs res 1 ; # registers in panic readout t0l_count res 1 t0h_count res 1 ;**************************************************************************** code ;**************************************************************************** panic_routine ; switch off interrupts and power ; reconfigure timer0 for writing diagnostic msg to the LED clr_f INTCON ; disable all interrupts EVER bc_f PORTC,1 ; switch off booster ; now we have time to copy the panic message address out of WREG ; (turning off interrupts is urgent (we might get interrupted while ; panicing which would be bad because we might forget to panic). mov_wf panic_address clr_f STKPTR ; avoids stack overruns call panic_kill_hook ; re-initialise timer0 config call read_pic_no bra_z panic_setup_if_master panic_setup_if_slave morse_t0setup sclock, (1<=panic_morse return ; return to panic tblrd *+ mov_ff TABLAT,flash_pattern rcall morse_readout inc_f morse_counter bra morse_loop ;-------------------------- morse_readout ; Flashes the per-pic led and black in a specified pattern. ; ; The pattern is specified as the state for 8 identically-long time ; periods each as long as a morse `dot', encoded into a byte with ; most significant bit first. ; On entry On exit ; W any undefined ; flash_pattern flash pattern preserved ; bit_counter any undefined mov_lw 9 mov_wf bit_counter rr_f flash_pattern morse_readout_loop dec_f_ifz bit_counter ; done all the bits yet ? return ; No: rl_f flash_pattern ; top bit goes into N, ;ie Negative if 1 bra_n morse_readout_if_led_1 morse_readout_if_led_0 call led_black bra morse_readout_endif_led morse_readout_if_led_1 call led_red morse_readout_endif_led rcall waiting bra morse_readout_loop ;-------------------------- ;-------------------------- registermsg register_msg_start clr_f register_counter ; clear loop counter register_loop mov_fw panic_regs cmp_fw_ifge register_counter ; if loop counter >=panic_regs return ; return to panic tblrd *+ mov_fw TABLAT ; TABLAT has the 8-bit version mov_wf FSR0L ; of the address. So, 8 bits ; go straight into FSR0L. mov_lw 0x0f ; For FSR0H, we see if the mov_fw FSR0H ; address XX is >=0x60. ; If it is then we meant 0xfXX; mov_lw 0x5f ; if not then we meant 0x0XX. cmp_fw_ifle FSR0L ; (This is just like PIC does clr_f FSR0H ; for insns using Access Bank) mov_ff INDF0,flash_pattern rcall register_readout inc_f register_counter ;increment loop counter rcall waiting8 bra register_loop ;-------------------------- register_readout ; Flashes the per-pic led red(0) and green(1) in a specified pattern. ; (black gap between each bit) ; ; The pattern is specified as the state for 8 identically-long time ; periods each as long as a morse `dot', encoded into a byte with ; most significant bit first. ; On entry On exit ; W any undefined ; flash_pattern flash pattern preserved ; bit_counter any undefined clr_f bit_counter ; clear loop counter rr_f flash_pattern register_readout_loop mov_lw 8 cmp_fw_ifge bit_counter ; if loop counter >=8 (register ; length), return return mov_lw 4 cmp_fw_ifne bit_counter ; if loop counter !=4 (nybble length), ; skip insertion of extra black space bra not_nybble_boundary rcall waiting4 not_nybble_boundary rl_f flash_pattern ; top bit goes into N flag, ; ie Negative if 1 bra_n register_readout_if_led_1 register_readout_if_led_0 call led_red bra register_readout_endif_led register_readout_if_led_1 call led_green register_readout_endif_led inc_f bit_counter ; increment loop counter rcall waiting call led_black rcall waiting bra register_readout_loop ;**************************************************************************** ; GENERAL SUBROUTINES ;---------------------------------------- waiting16 rcall waiting8 waiting8 rcall waiting4 waiting4 rcall waiting2 waiting2 rcall waiting waiting ; waits for a fixed interval, depending on the configuration of TMR0 bc_f INTCON,2 ; clear timer0 interrupt bit (p109) ; Interrupt happens on overflow. So start at 65535-morse_t0cycles: mov_fw t0h_count mov_wf TMR0H ; p107 set high byte of timer0 (buffered, ; only actually set when write to tmr0l occurs) mov_fw t0l_count mov_wf TMR0L ; set timer0 low byte - timer now set waiting_loop bt_f_if0 INTCON,TMR0IF bra waiting_loop ; wait for timer0 interrupt return ;**************************************************************************** include final.inc