;---------------------------------------------------------------------------
; reserved access bank locations
- udata_acs
+ udata_acs
psave_intcon res 1
psave_bsr res 1
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_vars_section udata 0x060 ; not available via access bank
+panic_valcount res 1
+
+panic_vars_section udata 0x060 + maxpics ; not available via access bank
; used in panic routine for temporary storage:
flash_pattern res 1
;****************************************************************************
- code
+pan_ code
;****************************************************************************
-panic_routine
+panic_routine @
; switch off interrupts and power
; reconfigure timer0 for writing diagnostic msg to the LED
clr_f STKPTR ; avoids stack overruns
clr_f panicst
- bs_f picno, picno_panicd
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
mov_wf TMR0L ; set timer0 low byte - timer now set
waiting_loop ; wait for timer0 interrupt, or some other interrupt
bt_f_if1 INTCON,TMR0IF
- bra waiting_done
+ 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
-
- bt_f_if1 idloc1, idloc1_master
- bra waiting_loop ; no readouts on master yet
+ ; slave, i2c enabled:
bt_f_if1 PIR1, SSPIF
- call i2cs_interrupt
+ call pan_i2cs_interrupt
bra waiting_loop
+;****************************************************************************
+; 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
+
;----------
-waiting_done
-;x bt_f_if0 panicst, panicst_restart_i2c
- return
- bc_f panicst, panicst_restart_i2c
- mov_lw picno
- and_lw 0x7f
- bra_z waiting_done_if_master
- call i2cs_init
-lgl
- call led_green
- bra lgl
- goto i2cs_init
-
-waiting_done_if_master
- return
+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
-;****************************************************************************
-; MEMORY READOUT
+;----------
+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 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
;----------
panic_crashread_setpointer
and_lw 0x3f
ior_wfw PRODL
mov_wf FSR1L
+panic_noop
return
+;======================================================================#
+; SPECIAL COMMANDS 0x08..0x0f
+
;----------
-panic_crashread_commanded
- bs_f panicst, panicst_acked ; since we were asked to
- panic morse_E
+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
+
+;----------
+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
;----------
-i2csu_read_begin_panicd
+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