;###################################################################### ; i2clib.inc - I2C LIBRARY, DECLARATIONS AND DOCUMENTATION ; ; ;============================================================ ; GENERAL INFORMATION ; ; Naming scheme: ; i2cm_... on master or i2cmu_... for upcalls ; i2cs_... on slave or i2csu_... for upcalls ; ie, ; i2c?_... are for use by the rest of the program and ; are the entrypoints which enable I2C use. ; i2c?u_... must be defined in the rest of the program ; with the functionality and behaviour described. ; i2cm_... may only be called on the master PIC. ; i2cs_... may only be called on slave PICs. ; At all times following i2c[ms]_init, the i2c hardware in the PIC is ; completely reserved to the routines defined in i2clib.asm. Nothing ; else is allowed to read or modify the i2c controller state. ; Likewise, the memory locations (variables) defined there are for use ; by those routines only and must not be touched by the main program. ; Unless otherwise stated, all routines accept any value in, and may ; trash, W and the flags. All other registers and locations not ; specifically mentioned here will be preserved by the ; i2c?_... routines (and are therefore reserved for the rest of the ; program). In all cases, routines are called with CALL or RCALL or ; the equivalent, and routines are allowed to have subroutines (ie, to ; use the call/return address stack). ; Slave numbers (PIC numbers) are the actual PIC number, not the i2c ; address. So, they start at 1 for the first slave. (PIC #0 is the ; master but the master doesn't have an i2c address and its PIC number ; is never required by or supplied to i2clib.) ; They must be between 1 and 63 inclusive. ; i2c?_... routines except i2c?_interrupt will never _directly_ call ; any i2c?u_... routine; when we say `causes' this means that the ; relevant i2c?u_... routine will be called at some later point from ; i2c?_interrupt. i2c?u_... routines are allowed to call appropriate ; i2c?_... routines (except i2c?_interrupt) directly if the context ; 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 ; * 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 ; which interrupted the middle of another i2c_... routine. ; Some time between calling i2cs_init and waiting for the first event, ; the main program should of course enable interrupts. ;============================================================ ; COMMON ADMINISTRATIVE ROUTINES ;-------------------- 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. ; At call On return ; i2c controller any for use by i2clib ; i2c interrupt config any enabled, low priority ; global interrupt enable disabled unchanged ; State Not-in-use Idle ;-------------------- 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 is the slave number. ; At call On return ; i2c controller any for use by i2clib ; i2c interrupt config any enabled, low priority ; global interrupt enable disabled unchanged ; State Not-in-use Idle ; W slave number any extern i2cs_interrupt extern i2cm_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 ; 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[*]. ; ; At call On return ; State any except Not-in-use may change ; i2c interrupt state any cleared[*] ; ; [*] 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. ;====================================================================== ; SLAVE ; ; States: ; ; [Not-in-use] ; | ; |init ; v ; [Idle]<-----------------------. ; write_begin/ \ | ; / \read_begin | ; V V | ; ,->[Receiving] [Transmitting]<-. | ; `-----' | | `------' | ; write_another | | read_another | ; | read_done| | ; write_done| \ | `--------------+->--------------' ;======================================== ; SLAVE - WRITES (ie, reception of data from the master) ;-------------------- 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. ; ; Beforehand At call On return ; State Idle Receiving Receiving ; W data from master any ;-------------------- 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. ; ; 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 ; ; 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. ; ; Beforehand At call On return ; State Idle Transmitting Transmitting ; W any data for master ;-------------------- 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. ; ; Beforehand At call On return ; State Transmitting Transmitting Transmitting ; W any data for master ;-------------------- extern i2csu_read_done ; ; 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. ; ; i2cm_write_start ; slave no. ; causes ; i2cmu_write_next_byte ; must return byte to transmit ; must say whether to stop ; stop causes ; i2cmu_done ; ; 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