source: rtems/cpukit/libi2c/README_libi2c

Last change on this file was 0446f680, checked in by Marçal Comajoan Cara <mcomajoancara@…>, on 12/03/18 at 20:37:32

Spelling and grammar fixes in source code comments (GCI 2018)

  • Property mode set to 100644
File size: 13.0 KB
Line 
1=====================
2Copyright and License
3=====================
4
5For Copyright and License of the source code, see the header in
6libi2c.c.
7
8=========
9Overview
10========
11
12This directory contains a general I2C/SPI API library. It offers a
13standard API to I2C or SPI based device drivers, abstracting the low
14level driver (dealing with the I2C/SPI controller hardware of the
15board) from the high-level drivers (dealing with devices connected to
16the I2C or SPI bus).
17
18In most cases throughout this document, i2c and spi devices are
19handled in a similar way. Therefore spi will not be explicitly named
20in every location.
21
22=========
23Features
24=========
25
26  + supports multiple i2c and/or spi busses
27
28  + supports multiple devices connected to each i2c/spi bus
29
30  + handles bus and device registration to the I/O manager
31
32=========
33Structure
34=========
35
36This library defines a layered API to i2c and spi devices. The
37layering is:
38
39  +----------------------------------------+
40 6|            Application                 |
41  +----------------------------------------+
42 5|         RTEMS I/O Manager              |
43  +----------------------------------------+
44 4|**      libi2c OS adaption layer      **|
45  +----------------------------------------+
46 3|     high level i2c device driver       |
47  |          (EEPROM, RTC, ...)            |
48  |     (e.g. in c/src/libchip/i2c)        |
49  +----------------------------------------+
50 2|** libi2c low level abstraction layer **|
51  +----------------------------------------+
52 1|      i2c controller driver             |
53  |              (in BSP)                  |
54  +----------------------------------------+
55
56This document will describe the following interfaces in separate
57sections:
58
59  + the interface between the RTEMS I/O Manager and the libi2c OS
60  interface (5<->4)
61
62  + the interface between the libi2c OS interface and the high level
63  i2c device driver (4<->3)
64
65  + the interface between the high level i2c device driver and the
66  libi2c low level abstraction layer (3<->2)
67
68  + the interface between the libi2c low level abstraction layer and
69  the i2c controller driver (2<->1)
70
71===================================
72Differences between i2c and spi bus
73===================================
74SPI and I2C has many similarities, but also some differences:
75
76- I2C uses inband addressing (the first bits sent select, which slave
77device is addressed) while SPI uses dedicated select lines to address
78a slave device
79
80- SPI supports combined full duplex read-write transactions while I2C
81either sends or receives data from a slave device
82
83- SPI supports a varity of per-slave options, which include:
84  - number of bits per character to transfer
85  - polarity and phase of clock wrt data
86  - clock frequency
87
88The libi2c API defines a superset of functions to handle both flavours
89of serial data transmission, but care should be taken not to use
90features dedicated to the wrong type of serial bus.
91
92
93======================
94Library Initialization
95======================
96Before any libi2c API is used, the library must be initialized. This
97is achived with a call to function
98
99    rtems_libi2c_initialize ().
100
101It creates a global mutex to lock internal data structures and
102registers the OS adaption layer to the RTEMS I/O manager.
103
104Any subsequent call to this function will be silently ignored.
105
106Typically the BSP startup code will perform this initialization.
107
108A proper place for initializing the i2c layer and populating it
109with busses and device drivers (see 'Bus Registration' and
110'Device/Driver Registration' below) is the 'predriver_hook'
111where most facilities (such as malloc, libio) are already
112available. Note, however, that 'stdio' is not yet functional
113at this point and all i2c bus and device drivers should carefully
114avoid using stdio so that other drivers which may build on top
115of i2c devices may be initialized properly (this may happen
116just after 'predriver_hook' when stdio is still not available).
117E.g., drivers listed in the configuration table are initialized
118during this step.
119
120Note that while 'libi2c' could be initialized from the rtems
121configuration table like other drivers there is no easy
122way of populating the i2c framework with bus- and device-
123drivers at this point (unless a special 'i2c' configuration
124table describing the bus layout is implemented in the future).
125
126For the time being, we must rely on the BSP (predriver_hook)
127to initialize the i2c system if it is used by other drivers
128(e.g., the RTC driver may have to use a i2c device).
129
130===================
131Bus Registration
132===================
133Each i2c and/or spi bus available must be registerd with a call to
134
135int rtems_libi2c_register_bus (char *name,
136                               rtems_libi2c_bus_t * bus)
137
138It registers the bus to the libi2c internal data structures and
139creates a device node in the RTEMS filesystem with the given name. If
140no name is given (name==NULL), then the default name "/dev/i2c" is
141used instead.
142
143With the second calling parameter "rtems_libi2c_bus_t * bus" the
144caller passes in a set of function pointers, which define the entries
145into the i2c controller driver (defined in the BSP).
146
147This call returns an integer bus number, which can be used in
148subsequent calls to register devices attached to this bus (see below).
149
150Typically the BSP startup code will perform this registration for each
151bus available on the board.
152
153==========================
154Device/Driver Registration
155==========================
156Each device attached to an i2c or spi bus must be registered with a
157call to
158
159int
160rtems_libi2c_register_drv (char *name, rtems_libi2c_drv_t * drvtbl,
161                           unsigned bus, unsigned i2caddr);
162
163With this call, libi2c is informed, that:
164
165- a device is attached to the given "bus" number (which in fact is the
166return value received from a previous rtems_libi2c_register_bus()
167call) with the address "i2caddr"
168
169- the device is managed by a driver, who's entry functions are listed
170  in "drvtbl"
171
172- the device should be registered with the given "name" in the device
173  tree of the filesystem.
174
175The call will create a proper minor device number, which has the bus
176number and i2c_address encoded. This minor number is the return value
177of the call and is also associated with the filesystem node created
178for this device.
179
180Note: If you have multiple devices of the same type, you must register
181each of them through a separate call (with the same "drvtbl", but
182different name/bus/i2caddr).
183
184====================================================================
185(5<->4) RTEMS I/O Manager and the libi2c OS adaption layer IF
186====================================================================
187
188The RTEMS I/O Manager regards the libi2c OS adaption layer as a normal
189RTEMS Device Driver with one unique major number and a set of minor
190numbers, one for each bus and one for each device attached to one of
191the busses.
192
193Therefore the libi2c OS adaption layer provides the standard calls:
194
195static rtems_driver_address_table libi2c_io_ops = {
196  initialization_entry:  i2c_init,
197  open_entry:            i2c_open,
198  close_entry:           i2c_close,
199  read_entry:            i2c_read,
200  write_entry:           i2c_write,
201  control_entry:         i2c_ioctl
202};
203
204These calls perform some parameter checking and then call the
205appropriate high level i2c device driver function, if available,
206according to the entries in the "drvtbl" passed in the
207rtems_libi2c_register_drv() call.
208
209There are two exceptions: when i2c_read or i2c_write is called with a
210minor number specifying a bus (and not a device attached to the bus),
211then the respective transfer is performed as a raw byte stream
212transfer to the bus.
213
214The main reason for the libi2c OS adaption layer is, that it
215dispatches the RTEMS I/O Manager calls to the proper device driver
216according to the minor number used.
217
218====================================================================
219libi2c OS adaption layer and the high level i2c device driver IF
220====================================================================
221
222Each high level i2c device driver provides a set of functions in the
223rtems_libi2c_drv_t data structure passed the libi2c when the device is
224registered (see "Device registration" above). These function directly match
225the RTEMS I/O Mangers calls "open", "close", "read", "write",
226"control", and they are passed the same arguments. Functions not
227needed may be omited (and replaced by a NULL pointer in
228rtems_libi2c_drv_t).
229
230======================================================================
231high level i2c device driver and libi2c low level abstraction layer IF
232======================================================================
233libi2c provides a set of functions for the high level drivers. These
234functions are:
235
236rtems_libi2c_send_start();
237rtems_libi2c_send_stop();
238rtems_libi2c_send_addr();
239rtems_libi2c_read_bytes();
240rtems_libi2c_write_bytes();
241rtems_libi2c_start_read_bytes();
242rtems_libi2c_start_write_bytes();
243rtems_libi2c_ioctl();
244
245Please look into libi2c.h for the proper parameters and return codes.
246
247These functions perform the proper i2c operations when called.
248
249A typical access sequence for the I2C bus would be:
250
251rtems_libi2c_send_start();
252rtems_libi2c_send_addr();
253rtems_libi2c_write_bytes();
254rtems_libi2c_send_stop();
255
256Alternatively, the rtems_libi2c_write_bytes() call could be relpaced
257with a
258          rtems_libi2c_read_bytes()
259
260call or a sequence of multiple calls.
261
262Note: rtems_libi2c_send_start() locks the i2c/spi bus used, so no other
263device can use this i2c/spi bus, until rtems_libi2c_send_stop() function
264is called for the same device.
265
266Special provisions for SPI devices:
267===================================
268For SPI devices and their drivers, the libi2c interface is used
269slightly differently:
270
271rtems_libi2c_send_start() will lock access to the SPI bus, but has no
272effect on the hardware bus interface.
273
274rtems_libi2c_ioctl(...,RTEMS_LIBI2C_IOCTL_SET_TFRMODE,...) will set
275the transfer mode (bit rate, clock phase and polaritiy, bits per
276char...) according to the rtems_libi2c_tfr_mode_t structure passed in.
277
278rtems_libi2c_send_addr() will activate the proper select line to
279address a certain SPI device. The correspondance between an address
280and the select line pulled is BSP specific.
281
282rtems_libi2c_send_stop(); will deactivate the address line and unlock
283the bus.
284
285A typical access sequence for the SPI bus would be:
286
287rtems_libi2c_send_start();
288rtems_libi2c_ioctl(...,RTEMS_LIBI2C_IOCTL_SET_TFRMODE,...);
289rtems_libi2c_send_addr();
290rtems_libi2c_write_bytes();
291rtems_libi2c_send_stop();
292
293Alternatively, the rtems_libi2c_write_bytes() call could be relpaced
294with a
295         rtems_libi2c_read_bytes()
296or a
297         rtems_libi2c_ioctl(...,RTEMS_LIBI2C_IOCTL_READ_WRITE,...)
298call or a sequence of multiple calls.
299
300====================================================================
301libi2c low level abstraction layer and i2c controller driver IF
302====================================================================
303Each low level i2c/spi driver must provide a set of bus_ops functions
304as defined in the rtems_libi2c_bus_ops_t structure.
305
306typedef struct rtems_libi2c_bus_ops_
307{
308  /* Initialize the bus; might be called again to reset the bus driver */
309  rtems_status_code (*init) (rtems_libi2c_bus_t * bushdl);
310  /* Send start condition */
311  rtems_status_code (*send_start) (rtems_libi2c_bus_t * bushdl);
312  /* Send stop  condition */
313  rtems_status_code (*send_stop) (rtems_libi2c_bus_t * bushdl);
314  /* initiate transfer from (rw!=0) or to a device */
315  rtems_status_code (*send_addr) (rtems_libi2c_bus_t * bushdl,
316                                  uint32_t addr, int rw);
317  /* read a number of bytes */
318  int (*read_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes,
319                     int nbytes);
320  /* write a number of bytes */
321  int (*write_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes,
322                      int nbytes);
323  /* ioctl misc functions */
324  int (*ioctl) (rtems_libi2c_bus_t * bushdl,
325                int   cmd,
326                void *buffer;
327                );
328} rtems_libi2c_bus_ops_t;
329
330Each of these functions performs the corresponding function to the i2c
331bus.
332
333Special provisions for SPI devices:
334===================================
335For SPI busses, special behaviour is required:
336
337(*send_start) (rtems_libi2c_bus_t * bushdl)
338              normally is an empty function.
339
340 (*send_addr) (rtems_libi2c_bus_t * bushdl, uint32_t addr, int rw)
341              will activate the SPI select line matching to addr.
342
343(*send_stop) (rtems_libi2c_bus_t * bushdl)
344              will deactivate the SPI select line
345
346(*ioctl(...,RTEMS_LIBI2C_IOCTL_SET_TFRMODE,...)
347             will set the transfer mode (bit rate, clock phase and
348             polaritiy, bits per char...) according to the
349             rtems_libi2c_tfr_mode_t structure passed in.
350
351(*ioctl(...,RTEMS_LIBI2C_IOCTL_READ_WRITE,...)
352             will send and receive data at the same time.
353
354Note:
355
356- low-level I2C drivers normally are specific to the master
357device, but independent from the board hardware. So in many cases they
358can totally reside in libcpu or libchip.
359
360- low-level SPI drivers are mostly board independent, but the
361  addressing is board/BSP dependent. Therefore the (*send_start),
362  (*send_addr) and (*send_stop) functions are typically defined in the
363  BSP. The rest of the functions can reside in libcpu or libchip.
Note: See TracBrowser for help on using the repository browser.