chiark / gitweb /
undo broken deletion
[trains.git] / detpic / i2clib.inc
1 ;######################################################################
2 ; i2clib.inc - I2C LIBRARY - DECLARATIONS AND DOCUMENTATION
3 ;
4 ;
5 ;============================================================
6 ; GENERAL INFORMATION
7 ;
8 ; Naming scheme:
9 ;  i2cm_...  on master   or  i2cmu_... for upcalls
10 ;  i2cs_...  on slave    or  i2csu_... for upcalls
11 ; ie,
12 ;  i2c?_...     are for use by the rest of the program and
13 ;                are the entrypoints which enable I2C use.
14 ;  i2c?u_...    must be defined in the rest of the program
15 ;                with the functionality and behaviour described.
16 ;  i2cm_...     may only be called on the master PIC.
17 ;  i2cs_...     may only be called on slave PICs.
18
19 ; At all times following i2c[ms]_init, the i2c hardware in the PIC is
20 ; completely reserved to the routines defined in i2clib.asm.  Nothing
21 ; else is allowed to read or modify the i2c controller state.
22 ; Likewise, the memory locations (variables) defined there are for use
23 ; by those routines only and must not be touched by the main program.
24
25 ; Unless otherwise stated, all routines accept any value in, and may
26 ; trash, W and the flags.  All other registers and locations not
27 ; specifically mentioned here will be preserved by the
28 ; i2c?_... routines (and are therefore reserved for the rest of the
29 ; program).  In all cases, routines are called with CALL or RCALL or
30 ; the equivalent, and routines are allowed to have subroutines (ie, to
31 ; use the call/return address stack).
32
33 ; Slave numbers (PIC numbers) are the actual PIC number, not the i2c
34 ; address.  So, they start at 1 for the first slave.  (PIC #0 is the
35 ; master but the master doesn't have an i2c address and its PIC number
36 ; is never required by or supplied to i2clib.)
37 ; They must be between 1 and 63 inclusive.
38
39 ; i2c?_... routines except i2c?_interrupt will never _directly_ call
40 ; any i2c?u_... routine; when we say `causes' this means that the
41 ; relevant i2c?u_... routine will be called at some later point from
42 ; i2c?_interrupt.  i2c?u_... routines are allowed to call appropriate
43 ; i2c?_... routines (except i2c?_interrupt) directly if the context
44 ; and State allows.
45
46 ; All routines except i2c?_init must be called only:
47 ;   * During an appropriate interrupt (high-priority for the slave;
48 ;     low-priority for the master).
49 ;   * From the main loop with those interrupts disabled; or
50 ;   * From within an i2c?u_... routine (which are always called
51 ;     from within i2c?_interrupt).
52 ; This is to avoid having one i2c_... routine running in an interrupt
53 ; which interrupted the middle of another i2c_... routine.
54
55 ; Some time between calling i2cs_init and waiting for the first event,
56 ; the main program should of course enable interrupts.
57
58 ;============================================================
59 ; COMMON ADMINISTRATIVE ROUTINES
60
61 ;--------------------
62   extern i2cm_init
63 ;
64 ; Initialises the i2c system for use by a master PIC.  Must be called
65 ; exactly once, which must be before any other i2c?_... function.
66 ;                               At call                 On return
67 ;   i2c controller              any                     for use by i2clib
68 ;   i2c interrupt config        any                     enabled, low priority
69 ;   global interrupt enable     disabled                unchanged
70 ;   State                       Not-in-use              Idle (as master)
71
72 ;--------------------
73   extern i2cs_init
74 ;
75 ; Initialises the i2c system for use by a slave PIC.  Must be called
76 ; exactly once, which must be before any other i2c?_... function.
77 ; W is the slave number.
78 ;                               At call                 On return
79 ;   i2c controller              any                     for use by i2clib
80 ;   i2c interrupt config        any                     enabled, low priority
81 ;   global interrupt enable     disabled                unchanged
82 ;   State                       Not-in-use              Idle (as slave)
83 ;   W                           slave number            any
84
85 ;--------------------
86   extern i2cm_interrupt
87   extern i2cm_interrupt_definite
88   extern i2cs_interrupt
89 ;
90 ; Must be called by the main program's interrupt handler;
91 ; high-priority for the slave or low-priority for the master.
92 ;
93 ; For i2cm_interrupt, the main program's interrupt handler is
94 ; responsible for saving W and the flags register and other
95 ; interrupt-related administrivia.  i2cm_interrupt checks for
96 ; SSPIF and handles any interrupt.  i2cm_interrupt_definite
97 ; should only be called if SSPIF is set and handles it.  In
98 ; both cases the ISR returns with `return'.
99 ;
100 ; For i2cs_interrupt, it must be the only high-priority interrupt
101 ; source and expects to be called from the interrupt handler (and it
102 ; will return; the caller must retfie_r).
103 ;
104 ; If there is an i2c interrupt, the i2c?_interrupt will service it, taking
105 ; any necessary action including calling appropriate
106 ; i2c?u_... routines, and clear the interrupt flag[*].
107 ;
108 ;                               At call                 On return
109 ;   State                       any except Not-in-use   may change
110 ;   i2c interrupt state         any                     cleared[*]
111 ;
112 ; [*] The interrupt event on entry, if any, will be dealt with.  If
113 ; interrupt processing takes a long time, another interrupt will occur
114 ; and this may result in the i2c interrupt flag being set on return
115 ; from i2c?_interrupt.
116
117
118 ;======================================================================
119 ; MASTER
120 ;
121 ; States:
122 ;                       [Not-in-use]
123 ;                            |
124 ;                            |init
125 ;                            v
126 ;                          [Idle]<-------------------------<------.
127 ;                           / \                                   |
128 ;                          / _ \ _____________________<______     |
129 ;                         /,'   \                            `.   |
130 ;             write_start//      \read_start                  |   |
131 ;                       //        \  ,------------------<---. |   |
132 ;                      //          \ |                      | |   |
133 ;                     VV            VV                      | |   |
134 ;            [Writing-Setup]   [Reading-Busy]<----------.   | |   |
135 ;                   |              |  |                 |   | |   |
136 ;                   |              |  |                 |   | |   |
137 ;                   |  slave_no_ack|  |                 |   | |   |
138 ;                   |      (1st    |  |                 |   | |   |
139 ;    write_next_byte|       byte  /   |read_got_byte    |   | |   |
140 ;    must return NZ |       only)/    |                 |   | |   |
141 ;                   V           /     V                 |   | |   |
142 ;           ,-->[Writing]      /  [Reading-Wait]        |   | |   |
143 ;           `-------'  \      |     / ||  `.___________,'   | |   |
144 ;    write_next_byte    \     |    /  ||   read_another     | |   |
145 ;       returns NZ       |    |   /   ||                    | |   |
146 ;                        |    |  /    |`.__________________,' |   |
147 ;                        |    | |     |        read_start     |   |
148 ;         write_next_byte|    | |     `._____________________,'   |
149 ;             returns Z  |    | |               write_start       |
150 ;                        |    | |read_done                        |
151 ;                        V    V V                                 |
152 ;                       [Stopping]                                |
153 ;                           |           done                      |
154 ;                           `-------------------------------------'
155
156 ;--------------------
157   extern i2cmu_done
158
159 ; Called to notify that the previous conversation with the slave has
160 ; been finished as requested.  The i2c system is now available and
161 ; i2cm_*_start can be called.
162 ;
163 ;               Beforehand      At call
164 ;   State       Stopping        Idle
165
166 ;--------------------
167   extern i2cmu_slave_no_ack
168
169 ; Called to notify that the slave did not acknowledge its address when
170 ; we attempted to read from it.  The i2c system is now clearing down
171 ; the i2c bus to prepare for another transaction.
172 ;
173 ;               Beforehand      At call
174 ;   State       Reading-Busy*   Stopping
175 ;
176 ;  * only Reading-Busy reached by calling read_start;
177 ;    not Reading-Busy due to read_another.
178
179 ;========================================
180 ; MASTER - WRITES (ie, transmission of data to the slave)
181
182 ;--------------------
183   extern i2cm_write_start
184 ;
185 ; Requests that a slave be contacted for writing.  When communication
186 ; has been established, i2cmu_write_next_byte will be called.
187 ;
188 ;                               At call         On return
189 ;   State                    Idle/Reading-Wait  Writing-Setup
190 ;   W                           slave number    any
191
192   extern i2cmu_write_next_byte
193 ;
194 ; Called to notify the main program that we are now ready to transmit
195 ; a byte to the slave that we're currently talking to.  This may be
196 ; either because i2cm_write_start was previously called and
197 ; communication has been established, or because tranmission of the
198 ; previous byte is complete.
199 ;
200 ; The main program must immediately supply the actual data byte.  This
201 ; byte will then be transmitted to the slave, and then
202 ; i2cmu_write_next_byte will be called again.
203
204 ; Alternatively the main program may indicate that the tranmission
205 ; should finish by setting the Z flag on return.  In this case the
206 ; slave will be told that this is the end of the message and the i2c
207 ; conversation will be finished.  When the conversation is finished
208 ; and the bus and i2c controller are free again, i2cmu_done will be
209 ; called.
210 ;
211 ;  When transmission should continue:
212 ;
213 ;               Beforehand      At call         On return       After return
214 ;   State       Writing[-Setup] Writing         Writing         Writing
215 ;   Status Z                    any             0 (NZ, not zero, not equal)
216 ;   W                           any             data for slave
217 ;
218 ;  When transmission should finish:
219 ;
220 ;               Beforehand      At call         On return       After return
221 ;   State       Writing         Writing         Writing         Stopping
222 ;   Status Z                    any             1 (Z, zero, equal)
223 ;   W                           any             any
224
225 ;========================================
226 ; MASTER - READS (ie, reception of data from the slave)
227
228 ;--------------------
229   extern i2cm_read_start
230 ;
231 ; Requests that a slave be contacted for reading.  When communication
232 ; has been established and the first byte received,
233 ; i2cmu_read_got_byte will be called.
234 ;
235 ;                               At call         On return
236 ;   State                    Idle/Reading-Wait  Reading-Busy
237 ;   W                           slave number    any
238
239   extern i2cmu_read_got_byte
240 ;
241 ; Called to notify the main program that a byte has been recieved from
242 ; the slave PIC.  The byte value is supplied.  Communication with the
243 ; slave will be suspended (with the i2c bus blocked) until the main
244 ; program calls i2cm_read_another or i2cm_read_done.  The main program
245 ; must call one of these two before doing anything else with the i2c.
246 ;
247 ;               Beforehand      At call
248 ;   State       Reading         Reading-Wait
249 ;   W                           data from slave
250
251   extern i2cm_read_another
252 ;
253 ; Requests that the communication with the slave continue and another
254 ; byte be read.  When this is complete, i2cmu_read_got_byte will be
255 ; called.
256 ;
257 ;                               At call         On return
258 ;   State                       Reading-Wait    Reading-Busy
259
260   extern i2cm_read_done
261 ;
262 ; Requests that reading from the slave be terminated.  When the
263 ; conversation is finished and the bus and i2c controller are free
264 ; again, i2cmu_done will be called.
265 ;
266 ;                               At call         On return
267 ;   State                       Reading-Wait    Stopping
268
269
270 ;======================================================================
271 ; SLAVE
272 ;
273 ; States:
274 ;
275 ;                   [Not-in-use]
276 ;                        |
277 ;                        |init
278 ;                        |
279 ;                        V
280 ;                      [Idle]
281 ;                        |
282 ;                        |<----------------------------.
283 ;                        +                             |
284 ;                       / \                            |
285 ;                      /   \                           |
286 ;          write_begin/     \read_begin                |
287 ;                    /       \                         |
288 ;                   V         V                        |
289 ;       ,->[Receiving]      [Transmit-Wait]<-.         |
290 ;       `-----'     |         |              |         |
291 ;     write_data    |         |read_data     |         |
292 ;                   |         V              |         |
293 ;                   |       [Transmit-Busy]  |         |
294 ;                   |         |       `------'         |
295 ;                   |         |        read_another    |
296 ;                   |         \                        |
297 ;                   `----------+->---------------------'
298
299 ;========================================
300 ; SLAVE - WRITES (ie, reception of data from the master)
301
302 ;--------------------
303   extern i2csu_write_begin
304 ;
305 ; Called to notify the main program that the master PIC has selected this
306 ; slave to talk to, for writing.  There is no data at this stage; when
307 ; data is received, i2csu_write_data will be called.
308 ;
309 ;               Beforehand      At call                 On return
310 ;   State       Idle            Receiving               Receiving
311
312 ;--------------------
313   extern i2csu_write_data
314 ;
315 ; Called to notify the main program that the master PIC has
316 ; transmitted a byte of data.  Provides the byte we received.
317 ;
318 ;               Beforehand      At call                 On return
319 ;   State       Receiving       Receiving               Receiving
320 ;   W                           data from master        any
321
322 ;========================================
323 ; SLAVE - READS (ie, transmission of data to the master)
324
325 ;--------------------
326   extern i2csu_read_begin
327 ;
328 ; Called to notify the main program that the master PIC has selected
329 ; this slave to talk to, for reading.  The main program should invoke
330 ; i2cs_read_data with first byte of data that we should transmit to
331 ; the master.
332 ;
333 ;               Beforehand      At call
334 ;   State       Idle            Transmit-Wait
335
336 ;--------------------
337   extern i2cs_read_data
338 ; Transmits the byte of data to the master
339 ;
340 ;               Beforehand      At call                 On return
341 ;   State       Transmit-Wait   Transmit-Busy           Transmit-Busy
342 ;   W                           byte for master         any
343 ;
344 ; There is also a macro  i2cs_read_data_macro
345 ; in i2clib.incm, which does the same thing.
346
347 ;--------------------
348   extern i2csu_read_another
349 ;
350 ; Called to notify the main program that the master PIC has continued
351 ; by asking for another byte of data.  The main program should once
352 ; more invoke i2cs_read_data.
353 ;
354 ;               Beforehand      At call
355 ;   State       Transmit-Busy   Transmit-Wait