;######################################################################
-; i2clib.inc - I2C LIBRARY, DECLARATIONS AND DOCUMENTATION
+; i2clib.inc - I2C LIBRARY - DECLARATIONS AND DOCUMENTATION
;
;
;============================================================
; and State allows.
; All routines except i2c?_init must be called only:
-; * During a low-priority interrupt;
-; * From the main loop with low-priority interrupts disabled; or
+; * During an appropriate interrupt (high-priority for the slave;
+; low-priority for the master).
+; * From the main loop with those interrupts disabled; or
; * From within an i2c?u_... routine (which are always called
; from within i2c?_interrupt).
; This is to avoid having one i2c_... routine running in an interrupt
; 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.
; i2c controller any for use by i2clib
; i2c interrupt config any enabled, low priority
; global interrupt enable disabled unchanged
-; State Not-in-use Idle
+; 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.
; i2c controller any for use by i2clib
; i2c interrupt config any enabled, low priority
; global interrupt enable disabled unchanged
-; State Not-in-use Idle
+; State Not-in-use Idle (as slave)
; W slave number any
-extern i2cs_interrupt
-extern i2cm_interrupt
+;--------------------
+ extern i2cm_interrupt
+ extern i2cm_interrupt_definite
+ extern i2cs_interrupt
+;
+; Must be called by the main program's interrupt handler;
+; high-priority for the slave or low-priority for the master.
+;
+; For i2cm_interrupt, the main program's interrupt handler is
+; responsible for saving W and the flags register and other
+; interrupt-related administrivia. i2cm_interrupt checks for
+; SSPIF and handles any interrupt. i2cm_interrupt_definite
+; should only be called if SSPIF is set and handles it. In
+; both cases the ISR returns with `return'.
;
-; Must be called by the main program's low priority interrupt handler.
-; The main program's interrupt handler is responsible for saving W and
-; the flags register and other interrupt-related administrivia. If
-; there is an i2c interrupt, this routine will service it, taking any
-; necessary action including calling appropriate i2c?u_... routines,
-; and clear the interrupt flag[*].
+; For i2cs_interrupt, it must be the only high-priority interrupt
+; source and expects to be called from the interrupt handler (and it
+; will return; the caller must retfie_r).
+;
+; If there is an i2c interrupt, the i2c?_interrupt will service it, taking
+; any necessary action including calling appropriate
+; i2c?u_... routines, and clear the interrupt flag[*].
;
; At call On return
; State any except Not-in-use may change
; [*] The interrupt event on entry, if any, will be dealt with. If
; interrupt processing takes a long time, another interrupt will occur
; and this may result in the i2c interrupt flag being set on return
-; from i2c?_inerrupt.
+; from i2c?_interrupt.
+
+
+;======================================================================
+; MASTER
+;
+; States:
+; [Not-in-use]
+; |
+; |init
+; v
+; [Idle]<-------------------------<------.
+; / \ |
+; / _ \ _____________________<______ |
+; /,' \ `. |
+; write_start// \read_start | |
+; // \ ,------------------<---. | |
+; // \ | | | |
+; VV VV | | |
+; [Writing-Setup] [Reading-Busy]<----------. | | |
+; | | | | | | |
+; | | | | | | |
+; | slave_no_ack| | | | | |
+; | (1st | | | | | |
+; write_next_byte| byte / |read_got_byte | | | |
+; must return NZ | only)/ | | | | |
+; V / V | | | |
+; ,-->[Writing] / [Reading-Wait] | | | |
+; `-------' \ | / || `.___________,' | | |
+; write_next_byte \ | / || read_another | | |
+; returns NZ | | / || | | |
+; | | / |`.__________________,' | |
+; | | | | read_start | |
+; write_next_byte| | | `._____________________,' |
+; returns Z | | | write_start |
+; | | |read_done |
+; V V V |
+; [Stopping] |
+; | 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
+; i2cm_*_start can be called.
+;
+; Beforehand At call
+; State Stopping Idle
+
+;--------------------
+ extern i2cmu_slave_no_ack
+
+; Called to notify that the slave did not acknowledge its address when
+; we attempted to read from it. The i2c system is now clearing down
+; the i2c bus to prepare for another transaction.
+;
+; Beforehand At call
+; State Reading-Busy* Stopping
+;
+; * only Reading-Busy reached by calling read_start;
+; not Reading-Busy due to read_another.
+
+;========================================
+; MASTER - WRITES (ie, transmission of data to the slave)
+
+;--------------------
+ extern i2cm_write_start
+;
+; Requests that a slave be contacted for writing. When communication
+; has been established, i2cmu_write_next_byte will be called.
+;
+; At call On return
+; State Idle/Reading-Wait Writing-Setup
+; W slave number any
+
+ 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
+; either because i2cm_write_start was previously called and
+; communication has been established, or because tranmission of the
+; previous byte is complete.
+;
+; The main program must immediately supply the actual data byte. This
+; byte will then be transmitted to the slave, and then
+; i2cmu_write_next_byte will be called again.
+
+; Alternatively the main program may indicate that the tranmission
+; should finish by setting the Z flag on return. In this case the
+; slave will be told that this is the end of the message and the i2c
+; conversation will be finished. When the conversation is finished
+; and the bus and i2c controller are free again, i2cmu_done will be
+; called.
+;
+; When transmission should continue:
+;
+; Beforehand At call On return After return
+; State Writing[-Setup] Writing Writing Writing
+; Status Z any 0 (NZ, not zero, not equal)
+; W any data for slave
+;
+; When transmission should finish:
+;
+; Beforehand At call On return After return
+; State Writing Writing Writing Stopping
+; Status Z any 1 (Z, zero, equal)
+; W any any
+
+;========================================
+; MASTER - READS (ie, reception of data from the slave)
+
+;--------------------
+ extern i2cm_read_start
+;
+; Requests that a slave be contacted for reading. When communication
+; has been established and the first byte received,
+; i2cmu_read_got_byte will be called.
+;
+; At call On return
+; State Idle/Reading-Wait Reading-Busy
+; W slave number any
+
+ 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
+; slave will be suspended (with the i2c bus blocked) until the main
+; program calls i2cm_read_another or i2cm_read_done. The main program
+; must call one of these two before doing anything else with the i2c.
+;
+; Beforehand At call
+; State Reading Reading-Wait
+; W data from slave
+
+ 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
+; called.
+;
+; At call On return
+; State Reading-Wait Reading-Busy
+
+ 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
+; again, i2cmu_done will be called.
+;
+; At call On return
+; State Reading-Wait Stopping
;======================================================================
;
; [Not-in-use]
; |
-; |init
-; v
-; [Idle]<-------------------------.
-; write_begin/ \ |
-; / \read_begin |
-; V V |
-; ,->[Receiving] [Transmitting]<-. |
-; `-----' | | `------' |
-; write_another | | read_another |
-; | read_done| |
-; write_done| \ |
- `--------------+->----------------'
+; |init
+; |
+; V
+; [Idle]
+; |
+; |<----------------------------.
+; + |
+; / \ |
+; / \ |
+; write_begin/ \read_begin |
+; / \ |
+; V V |
+; ,->[Receiving] [Transmit-Wait]<-. |
+; `-----' | | | |
+; write_data | |read_data | |
+; | V | |
+; | [Transmit-Busy] | |
+; | | `------' |
+; | | read_another |
+; | \ |
+; `----------+->---------------------'
;========================================
; 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
-; we received from the master PIC.
+; slave to talk to, for writing. There is no data at this stage; when
+; data is received, i2csu_write_data will be called.
;
; Beforehand At call On return
; State Idle Receiving Receiving
-; W data from master any
;--------------------
-extern i2csu_write_another
+ extern i2csu_write_data
;
-; Called to notify the main program that the master PIC has continued
-; by transmitting another byte of data. Provides the byte we received.
+; Called to notify the main program that the master PIC has
+; transmitted a byte of data. Provides the byte we received.
;
; Beforehand At call On return
; State Receiving Receiving Receiving
; W data from master any
-;--------------------
-extern i2csu_write_done
-;
-; Called to notify the main program that the master PIC has stopped
-; transmitting data (ie, finished the i2c conversation).
-;
-; Beforehand At call On return
-; State Receiving Idle
-
;========================================
; 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
-; data that we should transmit to the master.
+; this slave to talk to, for reading. The main program should invoke
+; i2cs_read_data with first byte of data that we should transmit to
+; the master.
;
-; Beforehand At call On return
-; State Idle Transmitting Transmitting
-; W any data for master
+; Beforehand At call
+; State Idle Transmit-Wait
;--------------------
-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.
+ extern i2cs_read_data
+; Transmits the byte of data to the master
;
; Beforehand At call On return
-; State Transmitting Transmitting Transmitting
-; W any data for master
-
-;--------------------
-extern i2csu_read_done
+; State Transmit-Wait Transmit-Busy Transmit-Busy
+; W byte for master any
;
-; Called to notify the main program that the master PIC has stopped
-; asking for data (ie, finished receiving).
-;
-; Beforehand At call On return
-; State Transmitting Idle
-
-
-
-
-
-; junky bits after here need turning into MASTER sections.
-
+; There is also a macro i2cs_read_data_macro
+; in i2clib.incm, which does the same thing.
+;--------------------
+ extern i2csu_read_another
;
-; i2cm_write_start
-; slave no.
-; causes
-; i2cmu_write_next_byte
-; must return byte to transmit
-; must say whether to stop
-; stop causes
-; i2cmu_done
+; Called to notify the main program that the master PIC has continued
+; by asking for another byte of data. The main program should once
+; more invoke i2cs_read_data.
;
-; i2cm_read_start
-; slave no.
-; causes
-; i2cmu_read_got_byte
-; byte value
-; causes
-; i2cm_read_another or i2cm_read_done
-; causes causes
-; i2cmu_done i2cmu_done
+; Beforehand At call
+; State Transmit-Busy Transmit-Wait