; (we don't usually mention SMP, CKE and UA below)
; Labels of the form s_event_* are branches of the interrupt
-; handler and are supposed to finish with retfie_r.
+; handler and are supposed to finish with return.
; Some macros:
;----------
s_event_idle_addrrecvread
bs_f st, st_awaiting
- call i2csu_read_begin ; 26cy until 1st insn of read_begin
- retfie_r
+ goto i2csu_read_begin ; 26cy until 1st insn of read_begin
;----------
s_event_reading
mov_fw SSPSTAT
xor_lw 0xac ; D,!P, S,R,!BF
bra_nz s_event_reading_not_another
- call i2csu_read_another
+ goto i2csu_read_another
; 24cy until 1st insn of i2csu_read_another
+
+;----------
s_event_reading_datanack
- retfie_r
+ return
-;...
+;----------
s_event_reading_not_another
; Whatever is happening, we're done reading now !
clr_f st
; i2c controller waiting due to SEN etc continuing with next byte
mov_fw SSPBUF
bs_f SSPCON1, CKP
- retfie_r
+ return
;----------
s_event_writing
and_lw 0xc7 ; ?D_A, ?P; ?S
xor_lw 0x80 ; SMP, !CKE, !R_W, !UA, !BF
bra_nz s_event_bad
- retfie_r
+ return
;----------
s_event_writing_datarecv
rcall s_write_slurpbyte
bt_f_if1 st, st_subsequent
- bra s_event_writing_datarecv_subsequent
+ goto i2csu_write_another
bs_f st, st_subsequent
- call i2csu_write_begin
- retfie_r
-
-s_event_writing_datarecv_subsequent
- rcall i2csu_write_another
- retfie_r
+ goto i2csu_write_begin
;======================================================================
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
panic_vars_section udata 0x060 ; not available via access bank
panic_vars
; 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
mov_ff PRODH, psave_prod+1
clr_f panicst
+ bs_f picno, picno_panicd
call panic_kill_hook
+;x bt_f_if1 SSPCON1, SSPEN
+;x bs_f panicst, panicst_restart_i2c
+;x bc_f SSPCON1, SSPEN
+
; re-initialise timer0 config
call read_pic_no
bra_z panic_setup_if_master
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
- return
+ bra waiting_done
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
- call i2cs_interrupt ; check for i2c interrupt
+ bt_f_if1 PIR1, SSPIF
+ call i2cs_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
;****************************************************************************
; MEMORY READOUT
; flashes blue flash every once in a while
;
; Input characters:
-; 1-9 if first byte of buffer is not negative:
+; 1-9 if we are to write (readwrite -ve):
; i2cm_write_start; i2cmu_write_next_byte will be handled
-; automatically: if next byte in buffer is negative we
-; set Z on return.
-; afterwards, buffer pointer is reset to start
-; but buffer contents is not changed
-; if first byte of buffer _is_ negative:
+; automatically: we transmit every byte before the
+; buffer pointer.
+; if we are to read (readwrite 0 or +ve):
; i2cm_read_start (buffer empty)
;
-; 0x00 ignored
+; 0x00 selects reading, manual advance
;
; 0x80-ff make buffer consisting of only that byte
; (ie, clear top bit, store at start of buffer,
-; set buffer pointer to next byte and clear that one)
+; set buffer pointer to next byte, and select writing)
;
-; 0x01-0f store value in readnext counter
+; 0x01-0f select reading, automatic advance: store this in readwrite
;
; 0x10-1f panic, showing character code
-;
-; , i2cm_read_another } if readnext_counter<7> is clear
+;
+; ^ set top bit of first byte of buffer
+;
+; , i2cm_read_another } if readwrite is zero
; . i2cm_read_done } then these are not called;
; } instead, we count down automatically
;
-; SPC set buffer pointer to start, set that byte to 0xff
-; 0 set buffer pointer to start, clear that byte
-; other append char to buffer, clear byte at buffer pointer
+; SPC set buffer pointer to start, select reading (manual)
+; 0 set buffer pointer to start, select writing
+; other append char to buffer, select writing
;
; + turn on booster (polarity=L) and cdu
; $ toggle hex mode for reading
;
; Output characters:
-; SPC i2cmu_done (only if readnext_counter<7> is set;
-; if it is clear we store 0xff in
-; readnext_counter)
+; SPC i2cmu_done (writing or manual reading)
; other i2cmu_read_got_byte
-;
-; On slave PIC:
-; we maintain a circular buffer with a separate
-; read and write pointer, initially initialised to
-; 01234567 (ascii)
-; ^
-; i2csu_write_begin sets led to red, writes byte to buffer
-; i2csu_write_another writes byte to buffer
-; i2csu_write_done writes '$' to current buffer loc, sets led to black
-; i2csu_read_begin sets led to green, reads byte from buffer
-; i2csu_read_another reads byte from buffer
-; i2csu_read_done sets led to black
-; special byte values that when written aren't just
-; writen to the buffer:
-; < reset read and write pointers
-; ! do that and also erase buffer
-; set led to red when writing, blue when reading
;
;======================================================================
ch res 1
mode res 1
mode_readhex equ 0
-readnext_counter res 1
+
+readwrite res 1
+ ; ff means we're writing or going to write, FSR1
+ ; 00 means we're to read interactively
+ ; 01-0f is counter of bytes to read
delay_countfast res 1
delay_countmedium res 1
;
; buffer is 0x200 onwards
; FSR0 is buffer pointer
-; FSR1 permanently points to start of buffer
+; FSR2 is the write cursor
master
clr_f mode
mov_lfsr 0x0200, 1
rcall m_buffer_reset
- set_f INDF1
- set_f readnext_counter
+ clr_f readwrite
mov_lw '|'
rcall serial_write_char
- mov_lw (1<<GIEH) | (1<<GIEL)
- mov_wf INTCON
+
+ bs_f INTCON, GIEH
+ bs_f INTCON, GIEL
m_infinite
call m_delay
mov_lw ~0x0f
and_wfw ch
- bra_z m_ch_setreadnext
+ bra_z m_ch_setreadwrite
mov_lw ~0x1f
and_wfw ch
xor_wfw ch
bra_z m_ch_comma
+ mov_lw '^'
+ xor_wfw ch
+ bra_z m_ch_hat
+
mov_lw '.'
xor_wfw ch
bra_z m_ch_stop
mov_fw ch
and_lw 0x7f
mov_wf POSTINC0
- clr_f INDF0
-m_ch_ignore
+ set_f readwrite
return
;----------
panic morse_X
;----------
-m_ch_setreadnext
+m_ch_hat
+ mov_lfsr 0x200,1
+ bs_f INDF1, 7
+ return
+
+;----------
+m_ch_setreadwrite
mov_fw ch
- bra_z m_ch_ignore
- mov_wf readnext_counter
- bra m_ch_spc
+ mov_wf readwrite
+ return
;----------
m_ch_comma
;----------
m_ch_digit
; W now contains intended slave number
- bt_f_if1 INDF1,7 ; first byte negative ?
+ bt_f_if0 readwrite,7 ; reading?
bra i2cm_read_start
; writing, eh ?
;----------
m_ch_spc
rcall m_buffer_reset
- set_f INDF0
+ clr_f readwrite
return
;----------
m_ch_0
rcall m_buffer_reset
- clr_f INDF0
+ set_f readwrite
return
;----------
;----------------------------------------
i2cmu_done
mov_lw ' '
- bt_f_if1 readnext_counter, 7
+ bt_f_if1 readwrite, 7 ; ff is writing, so we ack
bra serial_write_char
- set_f readnext_counter
- return
+ tst_f_ifnz readwrite ; non-0 is automatic mode
+ return ; no ack
+ bra serial_write_char ; manual mode, we ack
;----------
i2cmu_read_got_byte
rcall read_got_print
-
- bt_f_if1 readnext_counter, 7
+ tst_f_ifnz readwrite ; non-0 is automatic mode
+ bra i2cmu_read_got_byte_automatic
+ ; manual, we just return:
return
- ; ok, so we're in automatic mode:
- dec_f_ifnz readnext_counter
+
+i2cmu_read_got_byte_automatic
+ dec_f_ifnz readwrite
bra i2cm_read_another
+ ; now we'd be in manual mode
+ inc_f readwrite ; we leave ourselves in automatic mode, count=1
bra i2cm_read_done
;----------
bra serial_write_char
bra serial_write_hex
-;----------
-i2cmu_done_ifreadnextauto
- set_f readnext_counter
- return
-
;----------
i2cmu_write_next_byte
+ mov_fw FSR0L
+ xor_wfw FSR2L
+ bt_f_if1 STATUS,Z
+ return ; end of message
+ ; no, not end:
mov_fw POSTINC2
+ bc_f STATUS,Z
return
;----------
pin_l p0_cdu_enable
return
-;----------------------------------------------------------------------
-; SLAVE TESTING VERSION
-; buffer is at 0x100..0x107
-; FSR0 is write pointer
-; FSR1 is read pointer
-
-;----------
-QQ_detect_slave_init
- mov_lb 0x1
- mov_fw picno
- mov_wf t
-;...
-s_shownum_loop
- call s_delay
- call led_red
- call s_delay
- call led_black
-
- dec_f_ifnz t
- bra s_shownum_loop
-; Exit loop:
-
- mov_lw 0x07
- mov_wf qqTRISE
- set_f qqTRISD
- set_f qqTRISC
- set_f qqTRISB
- mov_lw 0x7f
- mov_wf qqTRISA
-
- mov_lw 0x5
- mov_wf qqLATE
- mov_lw 0x55
- mov_wf qqLATD
- mov_wf qqLATC
- mov_wf qqLATB
- mov_wf qqLATA
-
- mov_lw 0x1a
- mov_wf qqTRISA-1
- mov_lw 0x2b
- mov_wf qqTRISE+1
- mov_lw 0x3c
- mov_wf qqLATE+1
- mov_lw 0x4d
- mov_wf test_sofar_slave_buf-1
- mov_wf test_sofar_slave_buf-2
- mov_wf test_sofar_slave_buf-3
- mov_wf test_sofar_slave_buf-4
-
-;...
-;----------
-s_buffer_reset
- mov_lfsr test_sofar_slave_buf, 0
- mov_lfsr test_sofar_slave_buf, 1
-
- mov_lfsr 0x300,1
- return
-
-;----------
-QQ_i2csu_read_begin
- rcall led_green
-QQ_i2csu_read_another
- mov_fw POSTINC1
- ;qq bc_f FSR1L, test_sofar_s_bufbit
- goto i2cs_read_data
-
-
-;----------
-s_panic_req
- clr_f ch
- panic morse_X
-
;======================================================================
m_delay4 rcall m_delay2