;---------------------------------------------------------------------------
; reserved access bank locations
- udata_acs
+ udata_acs
-psave_w res 1
-psave_t res 1
psave_intcon res 1
psave_bsr res 1
-psave_latc res 1
-psave_tablat res 1
-psave_tblptr res 3
-psave_fsr0 res 2
-psave_fsr1 res 2
-psave_prod res 2
-panicst res 1
-panicst_acked equ 7
+panicst res 1
+panicst_restart_i2c equ 7
+panicst_acked equ 5
+panicst_ferroerr equ 4
+panicst_writeslave equ 3
+panicst_i2cmours equ 2
+panicst_i2cmenable equ 1
+
+panic_valcount res 1
-panic_vars_section udata 0x060 ; not available via access bank
-panic_vars
+panic_vars_section udata 0x060 + maxpics ; not available via access bank
; used in panic routine for temporary storage:
flash_pattern res 1
t0l_count res 1
t0h_count res 1
+psave_latc res 1
+psave_t res 1
+psave_tablat res 1
+psave_tblptr res 3
+psave_fsr0 res 2
+psave_fsr1 res 2
+psave_prod res 2
+psave_stkptr res 1
+
+stack_depth equ 31
+panic_stack res stack_depth*3
+
;****************************************************************************
- code
+pan_ code
;****************************************************************************
-panic_routine
+
+panic_routine @
; switch off interrupts and power
; reconfigure timer0 for writing diagnostic msg to the LED
mov_ff INTCON, psave_intcon
- clr_f INTCON ; disable all interrupts EVER
+ bc_f INTCON, GIEH ; disable all interrupts
mov_ff BSR, psave_bsr
- banksel panic_vars
+ banksel flash_pattern
mov_ff LATC, psave_latc
- mov_wf psave_w
-
-; now we have time to copy the panic message address out of WREG
+; now we have time to save registers etc
; (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
mov_ff t, psave_t
mov_ff TABLAT, psave_tablat
mov_ff FSR1H, psave_fsr1+1
mov_ff PRODL, psave_prod
mov_ff PRODH, psave_prod+1
+ mov_ff STKPTR, psave_stkptr
+
+ mov_lfsr panic_stack + stack_depth*3 - 1, 0
+ mov_lw stack_depth
+ mov_wf STKPTR
+stacksave_loop
+ mov_ff TOSU, POSTDEC0
+ mov_ff TOSH, POSTDEC0
+ mov_ff TOSL, POSTDEC0
+ dec_f_ifnz STKPTR
+ bra stacksave_loop
+ clr_f STKPTR ; avoids stack overruns
clr_f panicst
call panic_kill_hook
-; re-initialise timer0 config
+; re-initialise timer0 config, etc.
call read_pic_no
bra_z panic_setup_if_master
+ ; must be slave:
+
panic_setup_if_slave
- morse_t0setup sclock, (1<<TMR0ON), t0l_count, t0h_count
+ movlw (1<<TMR0ON) | morse_slave_t0scale
+ movwf T0CON
+ movlw morse_slave_t0inith
+ movwf t0h_count
+ movlw morse_slave_t0initl
+ movwf t0l_count
+
bra panic_setup_endif_masterslave
+
panic_setup_if_master
- morse_t0setup mclock, (1<<TMR0ON), t0l_count, t0h_count
+ movlw (1<<TMR0ON) | morse_master_t0scale
+ movwf T0CON
+ movlw morse_master_t0inith
+ movwf t0h_count
+ movlw morse_master_t0initl
+ movwf t0l_count
+
+ pin_l p0_booster_userfault
+
+ mov_lw 0x0b ; AAARGH
+ bt_f_if1 TXSTA, TXEN
+ call serial_write_char
+;...
panic_setup_endif_masterslave
; get # bytes of morse msg, # registers in panic readout, message start addr.
waiting
; waits for a fixed interval, depending on the configuration of TMR0
+ bt_f_if1 idloc1,idloc1_master
+ pin_z p0_booster_userfault
+
bc_f INTCON,2 ; clear timer0 interrupt bit (p109)
; Interrupt happens on overflow. So start at 65535-morse_t0cycles:
mov_fw t0h_count
bt_f_if1 INTCON,TMR0IF
return
+ bt_f_if1 idloc1, idloc1_master
+ bra waiting_master
+ ; slave:
+
bt_f_if0 SSPCON1, SSPEN
bra waiting_loop ; no readouts if i2c is disabled
+ ; slave, i2c enabled:
- bt_f_if1 idloc1, idloc1_master
- bra waiting_loop ; no readouts on master yet
-
- call i2cs_interrupt ; check for i2c interrupt
+ bt_f_if1 PIR1, SSPIF
+ call pan_i2cs_interrupt
bra waiting_loop
-
;****************************************************************************
-; MEMORY READOUT
+; MEMORY READOUT - CRASH DUMP
+
+;----------------------------------------
+; MASTER'S PANIC SERIAL PORT HANDLING
+
+;--------------------
+waiting_master
+ bt_f_if1 PIR1,RCIF ; host sent us something ?
+ call panicd_serialrx
+
+ bt_f_if0 SSPCON1, SSPEN
+ bra waiting_loop
+ ; master, i2c enabled:
+
+ bt_f_if0 panicst, panicst_i2cmenable
+ bra waiting_loop
+
+ bt_f_if1 PIR1, SSPIF
+ rcall pan_i2cm_interrupt
+
+ bra waiting_loop
+
+;----------
+panicst_oerrferr
+ mov_fw RCREG
+ xor_lw 0x11
+ bra_z panic_reset
+ xor_lw 0x10 ^ 0x11
+ bra_nz panicd_serialrx_err_loop
+ ; yay! host ack'd ferr/oerr
+ bc_f panicst, panicst_ferroerr
+ return ; return from panicd_serialrx
+
+;----------
+panicd_serialrx_err
+ bs_f panicst, panicst_ferroerr
+ bc_f RCSTA, RCEN ; disable } to clear FERR/OERR
+ mov_fw RCREG ; read RCREG } (see PIC18FXX8 DS p182)
+ bs_f RCSTA, RCEN ; reenable }
+panicd_serialrx_err_loop
+ bt_f_if0 PIR1, RCIF ; wait for a byte 0x10 to ack the overrun/error
+ bra panicd_serialrx_err_loop
+;...
+;----------
+panicd_serialrx
+ pin_nz p0_booster_userfault
+ bt_f_if1 RCSTA,FERR
+ bra panicd_serialrx_err
+ bt_f_if1 RCSTA,OERR
+ bra panicd_serialrx_err
+ bt_f_if1 panicst, panicst_ferroerr
+ bra panicst_oerrferr
+
+ mov_fw RCREG
+ bra panicd_process_input_byte
+
+;----------------------------------------
+; CRASHREAD MASTER/SLAVE COMMON COMMAND BYTE HANDLING
;----------
-i2csu_write_panicd
+pan_i2csu_write_data
+ call led_green
panicd_process_input_byte
; W instruction from host or master
tst_w_ifnz
;----------
write_ifnot_00
bt_f_if0 panicst, panicst_acked ; well, ignore that !
- return
+ bra write_only_tellmode
; OK, we have an instruction:
bt_w_if1 7 ; huh?
- return
+ bra write_if_setbytetowrite
bt_w_if1 6
- bra write_if_setpointer
+ bra panic_crashread_setpointer
bt_f_if0 idloc1,idloc1_master
- return ; all the remaining options are for master only
-;nyi bt_w_if1 5
-;nyi bra write_if_selectslave
-;nyi bt_w_if1 4
-;nyi bra write_if_readout
- return ; huh ?
+ bra write_ifnot0_ifnotmaster
+ ; the next few options are for master only:
+
+ bt_w_if1 5
+ bra write_if_master_slaveselect
+ bt_w_if1 4
+ bra write_if_master_masterread
+ bt_w_if0 3
+ bra write_if_master_slaveread
+;...
+write_ifnot0_ifnotmaster
+ xor_lw 0x09
+ bra_z panic_reset
+ xor_lw 0x09
+;...
+write_only_tellmode
+ xor_lw 0x0a
+ bra_z panic_tellmode
+ ; nope, well, we ignore it
+ return
;----------
-write_if_setpointer
+panic_crashread_setpointer
+; W byte from master or host undefined
+; FSR1* crashread pointer updated
+; t, STATUS, PROD* any undefined
+; all others any preserved
mov_wf t
mov_lw 1<<6
mul_wf FSR1L
and_lw 0x3f
ior_wfw PRODL
mov_wf FSR1L
+panic_noop
+ return
+
+;======================================================================#
+; SPECIAL COMMANDS 0x08..0x0f
+
+;----------
+panic_reset
+ reset
+
+;----------
+panic_tellmode
+ bt_f_if0 idloc1,idloc1_master
+ return
+ mov_lw 0x0b
+ bc_f panicst, panicst_acked
+ goto serial_write_char
+
+;======================================================================
+; MASTER READOUT AND MASTER READOUT OF SLAVES
+
+;----------
+write_if_setbytetowrite
+ bt_f_if0 idloc1,idloc1_master
+ return ; for master only
+
+ bc_w 7
+ mov_wf panic_valcount
+ bs_f panicst, panicst_writeslave
+ bs_f panicst, panicst_i2cmenable
return
;----------
-i2csu_read_begin_panicd
+write_if_master_slaveread
+ mov_wf panic_valcount
+ bc_f panicst, panicst_writeslave
+ return
+
+;----------
+write_if_master_slaveselect
+ bc_w 5
+ btg_w 4
+ bs_f panicst, panicst_i2cmours
+ bt_f_if1 panicst, panicst_writeslave
+ bra pan_i2cm_write_start
+ bra pan_i2cm_read_start
+
+;----------
+write_if_master_masterread
+ bc_w 4
+ mov_wf panic_valcount
+write_if_master_masterread_loop
+ mov_fw POSTINC1
+ call serial_write_char
+ dec_f_ifnz panic_valcount
+ bra write_if_master_masterread_loop
+ return
+
+;----------
+pan_i2cmu_read_got_byte
+ bt_f_if0 panicst, panicst_i2cmours
+ return
+ call serial_write_char
+ dec_f_ifnz panic_valcount
+ bra pan_i2cm_read_another
+ return
+
+;----------
+pan_i2cmu_write_next_byte
+ mov_fw panic_valcount
+ bc_f STATUS, Z
+ bt_f_if0 panicst, panicst_i2cmours
+ retlw 0x00
+ bt_f_if0 panicst, panicst_writeslave
+ bs_f STATUS, Z
+ bc_f panicst, panicst_writeslave
+ return
+
+;----------
+pan_i2cmu_done
+ mov_lw ' '
+ goto serial_write_char
+
+;----------
+pan_i2cmu_slave_no_ack
+ i2cpanic morse_SP
+
+;======================================================================
+; SLAVE I2C
+
+pan_near_i2csu code
+;----------
+pan_i2csu_write_begin
+ return
+
+;----------
+pan_i2csu_read_begin
mov_lw 0x80 ; M0000000
bt_f_if0 panicst, panicst_acked
goto i2cs_read_data
goto i2cs_read_data
;----------
-i2csu_read_another_panicd
+pan_i2csu_read_another
bt_f_if1 panicst, panicst_acked
bra i2csu_read_panicd_ok
; not ok
mov_lw 0x0b ; AARGH
goto i2cs_read_data
+near_gots code
+;----------
+got_aargh @
+ panic morse_T
+
+command_crashed_section code 0x2100
+;----------
+command_crashed @
+panic_crashread_commanded @
+ panic morse_E
+
;***************************************************************************
include final.inc