include /usr/share/gputils/header/p18f458.inc
radix dec
include ../iwjpictest/insn-aliases.inc
+ include panic.inc
;======================================================================
; NOTATION
; computes slave address in form suitable for use in i2c controller
; actual i2c slave address is (slave number) + 0b0001000
; W slave number i2c address * 2
- add_lw 0b0001000
+ add_lw b'0001000'
rlc_w
return
bra m_event_done_reading
m_event_bad
- panic morse_SM ; master, interrupt, controller in bad state
+ panic morse_SM
;========================================
; MASTER - STARTING, ADDRESSING, STOPPING
and_lw 31
bra_nz m_improper_slave
bs_f i2c_st, st_starting
- bs_f i2c_st, st_working
bs_f SSPCON2, SEN
return
;----------
m_event_done_starting
mov_fw i2c_slave
- bsr slave2addr
+ rcall slave2addr
bt_f_if1 i2c_st, st_reading
bs_w 0 ; address bottom bit means read
bra m_improper_write_start
bs_f i2c_st, st_writing
- bra m_do_start
+ bra m_start
;----------
m_event_done_writing
bra m_improper_read_start
bs_f i2c_st, st_reading
- bra m_do_start
+ bra m_start
;----------
m_event_done_addressing_read
;----------
i2cs_init
; W slave number undefined
- rcall slave2addr2
+ rcall slave2addr
mov_wf SSPADD
clr_f i2c_st
mov_lw 0x16 ; !SSPEN, CKP(release), I2C 7-bit slave no-SP-int
mov_wf SSPCON2
mov_lw 0x8 ; SMP(noslew), !CKE(!smbus)
mov_wf SSPSTAT
-ms_init_enable
+init_enable
; Actually engages the I2C controller, which must already have
; been set up (all but SSPEN):
; SSPADD,SSPCON1,SSPCON2 configured correctly unchanged
chkvals_start_sspstat macro
mov_fw i2c_sspstat
-chkval_lastvalue equ 0
endm
-chkval macro value, label
- xor_lw value ^ chkval_lastvalue
- chkval_lastvalue equ value
+chkval macro lastval, value, label
+ xor_lw value ^ lastval
bra_z label
endm
-chkvals_addrrecv macro
- chkval 0x8c, s_event_idle_addrrecvread ; A,!P, S,R,!BF
- chkval 0x89, s_event_idle_addrrecvwrite ; A,!P, S,W,BF
- endm
+chkvals_addrrecv macro lastval
+ chkval lastval, 0x8c, s_event_idle_addrrecvread ; A,!P, S,R,!BF
+ chkval 0x8c, 0x89, s_event_idle_addrrecvwrite ; A,!P, S,W,BF
+ endm
+chkvals_addrrecv_lastval equ 0x89
;----------
i2cs_interrupt
mov_ff SSPSTAT, i2c_sspstat
mov_ff SSPCON1, i2c_sspcon1
-; Check that nothing obvious is wrong:
- bsr check_wcolsspov
bt_f_if0 i2c_st, st_reading
bra s_event_reading
bra s_event_writing
s_event_idle
- chkvals_start
- chkvals_addrrecv
+ chkvals_start_sspstat
+ chkvals_addrrecv 0
s_event_bad
panic morse_SS ; slave, interrupt, controller in bad state
s_event_idle_addrrecvread
bs_f i2c_st, st_reading
call i2csu_read_begin
- bra s_events_read_datasend
+ bra s_events_reading_datasend
;----------
s_event_reading
chkvals_start_sspstat
- chkval 0xac, s_event_reading_datasent ; D,!P, S,R,!BF
+ chkval 0, 0xac, s_event_reading_datasent ; D,!P, S,R,!BF
; Whatever is happening, we're done reading now !
clr_f i2c_st
call i2csu_read_done
- chkval 0xa8, s_event_reading_datanack ; D,!P, S,!R,!BF
+ chkvals_start_sspstat
+ chkval 0, 0xa8, s_event_reading_datanack ; D,!P, S,!R,!BF
; Or, maybe it was nack and then we were reselected:
- chkvals_addrrecv
+ chkvals_addrrecv 0xa8
bra s_event_bad
;----------
s_event_idle_addrrecvwrite
- bs_f SSPCON, 3 ; we'll need the Stop interrupt
+ bs_f SSPCON1, 3 ; we'll need the Stop interrupt
bs_f i2c_st, st_writing
; well, this is all fine so far, so do carry on:
;----------
s_event_writing
chkvals_start_sspstat
- chkval 0xa9, s_event_writing_datarecv ; D,!P, S,W,BF
+ chkval 0, 0xa9, s_event_writing_datarecv ; D,!P, S,W,BF
; Well, we're done writing now in any case
clr_f i2c_st
; First, the nice cases:
chkvals_start_sspstat
- chkvals_addrrecv
+ chkvals_addrrecv 0
; Then random junk:
mov_fw i2c_sspstat
;======================================================================
+ include panic.fin
include i2clib.inc
+
end
; COMMON ADMINISTRATIVE ROUTINES
;--------------------
-extern i2cm_init
+ extern i2cm_init
;
; Initialises the i2c system for use by a master PIC. Must be called
; exactly once, which must be before any other i2c?_... function.
; State Not-in-use Idle (as master)
;--------------------
-extern i2cs_init
+ extern i2cs_init
;
; Initialises the i2c system for use by a slave PIC. Must be called
; exactly once, which must be before any other i2c?_... function.
; W slave number any
;--------------------
-extern i2cm_interrupt
-extern i2cs_interrupt
+ extern i2cm_interrupt
+ extern i2cs_interrupt
;
; Must be called by the main program's low priority interrupt handler.
; The main program's interrupt handler is responsible for saving W and
; `----------------------------------'
;--------------------
-extern i2cmu_done
+ extern i2cmu_done
; Called to notify that the previous conversation with the slave has
; been finished as requested. The i2c system is now available and
; MASTER - WRITES (ie, transmission of data to the slave)
;--------------------
-extern i2cm_write_start
+ extern i2cm_write_start
;
; Requests that a slave be contacted for writing. When communication
; has been established, i2cmu_write_next_byte will be called.
; State Idle Writing-Setup
; W slave number any
-extern i2cmu_write_next_byte
+ extern i2cmu_write_next_byte
;
; Called to notify the main program that we are now ready to transmit
; a byte to the slave that we're currently talking to. This may be
; MASTER - READS (ie, reception of data from the slave)
;--------------------
-extern i2cm_read_start
+ extern i2cm_read_start
;
; Requests that a slave be contacted for reading. When communication
; has been established and the first byte received,
; State Idle Reading-Busy
; W slave number any
-extern i2cmu_read_got_byte
+ extern i2cmu_read_got_byte
;
; Called to notify the main program that a byte has been recieved from
; the slave PIC. The byte value is supplied. Communication with the
; State Reading Reading-Wait
; W data from slave
-extern i2cm_read_another
+ extern i2cm_read_another
;
; Requests that the communication with the slave continue and another
; byte be read. When this is complete, i2cmu_read_got_byte will be
; At call On return
; State Reading-Wait Reading-Busy
-extern i2cm_read_done
+ extern i2cm_read_done
;
; Requests that reading from the slave be terminated. When the
; conversation is finished and the bus and i2c controller are free
; write_another | | read_another |
; | read_done| |
; write_done| \ |
- `--------------+->----------------'
+; `--------------+->----------------'
;========================================
; SLAVE - WRITES (ie, reception of data from the master)
;--------------------
-extern i2csu_write_begin
+ extern i2csu_write_begin
;
; Called to notify the main program that the master PIC has selected this
; slave to talk to, for writing. Provides the first byte of data
; W data from master any
;--------------------
-extern i2csu_write_another
+ extern i2csu_write_another
;
; Called to notify the main program that the master PIC has continued
; by transmitting another byte of data. Provides the byte we received.
; W data from master any
;--------------------
-extern i2csu_write_done
+ extern i2csu_write_done
;
; Called to notify the main program that the master PIC has stopped
; transmitting data (ie, finished the i2c conversation).
; SLAVE - READS (ie, transmission of data to the master)
;--------------------
-extern i2csu_read_begin
+ extern i2csu_read_begin
;
; Called to notify the main program that the master PIC has selected
; this slave to talk to, for reading, and to obtain the first byte of
; W any data for master
;--------------------
-extern i2csu_read_another
+ extern i2csu_read_another
;
; Called to notify the main program that the master PIC has continued
; by asking for another byte of data. Must provide the byte.
; W any data for master
;--------------------
-extern i2csu_read_done
+ extern i2csu_read_done
;
; Called to notify the main program that the master PIC has stopped
; asking for data (ie, finished receiving).