source: rtems/cpukit/libi2c/libi2c.h @ c85ab23

4.104.11
Last change on this file since c85ab23 was c85ab23, checked in by Joel Sherrill <joel.sherrill@…>, on Aug 5, 2009 at 6:17:12 PM

2009-08-05 Sebastian Huber <sebastian.huber@…>

  • libcsupport/include/rtems/libio_.h, libcsupport/src/fs_null_handlers.c: Null handlers are now const.
  • libi2c/libi2c.c, libi2c/libi2c.h: Documentation. Do not create semaphores on the fly.
  • cpukit/libblock/src/bdpart.c: Fixed format specifier.
  • cpukit/libblock/include/rtems/bdbuf.h, rtems/include/rtems.h, rtems/include/rtems/rtems/asr.h, rtems/include/rtems/rtems/attr.h, rtems/include/rtems/rtems/barrier.h, rtems/include/rtems/rtems/barriermp.h, rtems/include/rtems/rtems/cache.h, rtems/include/rtems/rtems/clock.h, rtems/include/rtems/rtems/config.h, rtems/include/rtems/rtems/dpmem.h, rtems/include/rtems/rtems/event.h, rtems/include/rtems/rtems/eventmp.h, rtems/include/rtems/rtems/eventset.h, rtems/include/rtems/rtems/intr.h, rtems/include/rtems/rtems/message.h, rtems/include/rtems/rtems/modes.h, rtems/include/rtems/rtems/mp.h, rtems/include/rtems/rtems/msgmp.h, rtems/include/rtems/rtems/object.h, rtems/include/rtems/rtems/part.h, rtems/include/rtems/rtems/partmp.h, rtems/include/rtems/rtems/ratemon.h, rtems/include/rtems/rtems/region.h, rtems/include/rtems/rtems/regionmp.h, rtems/include/rtems/rtems/rtemsapi.h, rtems/include/rtems/rtems/sem.h, rtems/include/rtems/rtems/semmp.h, rtems/include/rtems/rtems/signal.h, rtems/include/rtems/rtems/signalmp.h, rtems/include/rtems/rtems/status.h, rtems/include/rtems/rtems/support.h, rtems/include/rtems/rtems/taskmp.h, rtems/include/rtems/rtems/tasks.h, rtems/include/rtems/rtems/timer.h, rtems/include/rtems/rtems/types.h, rtems/inline/rtems/rtems/support.inl: Documentation.
  • include/rtems/irq-extension.h: Documentation. Added API for interrupt servers.
  • Property mode set to 100644
File size: 16.7 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup libi2c
5 *
6 * @brief I2C library.
7 */
8
9#ifndef _RTEMS_LIBI2C_H
10#define _RTEMS_LIBI2C_H
11/*$Id$*/
12
13/*
14 * Authorship
15 * ----------
16 * This software was created by
17 *     Till Straumann <strauman@slac.stanford.edu>, 2005,
18 *         Stanford Linear Accelerator Center, Stanford University.
19 *
20 * Acknowledgement of sponsorship
21 * ------------------------------
22 * This software was produced by
23 *     the Stanford Linear Accelerator Center, Stanford University,
24 *         under Contract DE-AC03-76SFO0515 with the Department of Energy.
25 *
26 * Government disclaimer of liability
27 * ----------------------------------
28 * Neither the United States nor the United States Department of Energy,
29 * nor any of their employees, makes any warranty, express or implied, or
30 * assumes any legal liability or responsibility for the accuracy,
31 * completeness, or usefulness of any data, apparatus, product, or process
32 * disclosed, or represents that its use would not infringe privately owned
33 * rights.
34 *
35 * Stanford disclaimer of liability
36 * --------------------------------
37 * Stanford University makes no representations or warranties, express or
38 * implied, nor assumes any liability for the use of this software.
39 *
40 * Stanford disclaimer of copyright
41 * --------------------------------
42 * Stanford University, owner of the copyright, hereby disclaims its
43 * copyright and all other rights in this software.  Hence, anyone may
44 * freely use it for any purpose without restriction. 
45 *
46 * Maintenance of notices
47 * ----------------------
48 * In the interest of clarity regarding the origin and status of this
49 * SLAC software, this and all the preceding Stanford University notices
50 * are to remain affixed to any copy or derivative of this software made
51 * or distributed by the recipient and are to be affixed to any copy of
52 * software made or distributed by the recipient that contains a copy or
53 * derivative of this software.
54 *
55 * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
56 */ 
57
58#include <rtems.h>
59
60#include <rtems/io.h>
61
62#ifdef __cplusplus
63extern "C" {
64#endif
65
66/**
67 * @defgroup libi2c I2C Library
68 *
69 * @brief I2C library.
70 *
71 * @{
72 */
73
74/* Simple I2C driver API */
75
76/* Initialize the libary - may fail if no semaphore or no driver slot is available */
77extern int rtems_libi2c_initialize (void);
78
79/* Alternatively to rtems_libi2c_initialize() the library can also be
80 * initialized by means of a traditional driver table entry containing
81 * the following entry points:
82 */
83extern rtems_status_code
84rtems_i2c_init (
85        rtems_device_major_number major,
86        rtems_device_minor_number minor,
87    void *arg);
88
89extern rtems_status_code
90rtems_i2c_open (
91        rtems_device_major_number major,
92        rtems_device_minor_number minor,
93    void *arg);
94
95extern rtems_status_code
96rtems_i2c_close (
97        rtems_device_major_number major,
98        rtems_device_minor_number minor,
99    void *arg);
100
101extern rtems_status_code
102rtems_i2c_read (
103        rtems_device_major_number major,
104        rtems_device_minor_number minor,
105    void *arg);
106
107extern rtems_status_code
108rtems_i2c_write (
109        rtems_device_major_number major,
110        rtems_device_minor_number minor,
111    void *arg);
112
113extern rtems_status_code
114rtems_i2c_ioctl (
115        rtems_device_major_number major,
116        rtems_device_minor_number minor,
117    void *arg);
118
119extern const rtems_driver_address_table rtems_libi2c_io_ops;
120
121/* Unfortunately, if you want to add this driver to
122 * a RTEMS configuration table then you need all the
123 * members explicitly :-( (Device_driver_table should
124 * hold pointers to rtems_driver_address_tables rather
125 * than full structs).
126 *
127 * The difficulty is that adding this driver to the
128 * configuration table is not enough; you still need
129 * to populate the framework with low-level bus-driver(s)
130 * and high-level drivers and/or device-files...
131 *
132 * Currently the preferred way is having the BSP
133 * call 'rtems_libi2c_initialize' followed by
134 * 'rtems_libi2c_register_bus' and
135 * 'rtems_libi2c_register_drv' and/or
136 * 'mknod' (for 'raw' device nodes)
137 * from the 'pretasking_hook'.
138 */
139#define RTEMS_LIBI2C_DRIVER_TABLE_ENTRY   \
140{                                         \
141  initialization_entry:  rtems_i2c_init,  \
142  open_entry:            rtems_i2c_open,  \
143  close_entry:           rtems_i2c_close, \
144  read_entry:            rtems_i2c_read,  \
145  write_entry:           rtems_i2c_write, \
146  control_entry:         rtems_i2c_ioctl, \
147}
148
149/* Bus Driver API
150 *
151 * Bus drivers provide access to low-level i2c functions
152 * such as 'send start', 'send address', 'get bytes' etc.
153 */
154
155/* first field must be a pointer to ops; driver
156 * may add its own fields after this.
157 * the struct that is registered with the library
158 * is not copied; a pointer will we passed
159 * to the callback functions (ops).
160 */
161typedef struct rtems_libi2c_bus_t_
162{
163  const struct rtems_libi2c_bus_ops_ *ops;
164  int size;                     /* size of whole structure */
165} rtems_libi2c_bus_t;
166
167/* Access functions a low level driver must provide;
168 *
169 * All of these, except read_bytes and write_bytes
170 * return RTEMS_SUCCESSFUL on success and an error status
171 * otherwise. The read and write ops return the number
172 * of chars read/written or -(status code) on error.
173 */
174typedef struct rtems_libi2c_bus_ops_
175{
176  /* Initialize the bus; might be called again to reset the bus driver */
177  rtems_status_code (*init) (rtems_libi2c_bus_t * bushdl);
178  /* Send start condition */
179  rtems_status_code (*send_start) (rtems_libi2c_bus_t * bushdl);
180  /* Send stop  condition */
181  rtems_status_code (*send_stop) (rtems_libi2c_bus_t * bushdl);
182  /* initiate transfer from (rw!=0) or to a device */
183  rtems_status_code (*send_addr) (rtems_libi2c_bus_t * bushdl,
184                                  uint32_t addr, int rw);
185  /* read a number of bytes */
186  int (*read_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes,
187                     int nbytes);
188  /* write a number of bytes */
189  int (*write_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes,
190                      int nbytes);
191  /* ioctl misc functions */
192  int (*ioctl) (rtems_libi2c_bus_t * bushdl, 
193                int   cmd,
194                void *buffer
195                );
196} rtems_libi2c_bus_ops_t;
197
198
199/*
200 * Register a lowlevel driver
201 *
202 * TODO: better description
203 *
204 * This  allocates a major number identifying *this* driver
205 * (i.e., libi2c) and the minor number encodes a bus# and a i2c address.
206 *
207 * The name will be registered in the filesystem (parent
208 * directories must exist, also IMFS filesystem must exist see
209 * CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM). It may be NULL in which case
210 * the library will pick a default.
211 *
212 * RETURNS: bus # (>=0) or -1 on error (errno set).
213 */
214
215extern int rtems_libi2c_register_bus (const char *name, rtems_libi2c_bus_t * bus);
216
217extern rtems_device_major_number rtems_libi2c_major;
218
219#define RTEMS_LIBI2C_MAKE_MINOR(busno, i2caddr) \
220        ((((busno)&((1<<3)-1))<<10) | ((i2caddr)&((1<<10)-1)))
221
222/* After the library is initialized, a major number is available.
223 * As soon as a low-level bus driver is registered (above routine
224 * returns a 'busno'), a device node can be created in the filesystem
225 * with a major/minor number pair of
226 *
227 *    rtems_libi2c_major / RTEMS_LIBI2C_MAKE_MINOR(busno, i2caddr)
228 *
229 * and a 'raw' hi-level driver is then attached to this device
230 * node.
231 * This 'raw' driver has very simple semantics:
232 *
233 *   'open'         sends a start condition
234 *   'read'/'write' address the device identified by the i2c bus# and address
235 *                  encoded in the minor number and read or write, respectively
236 *                  a stream of bytes from or to the device. Every time the
237 *                  direction is changed, a 're-start' condition followed by
238 *                  an 'address' cycle is generated on the i2c bus.
239 *   'close'        sends a stop condition.
240 *
241 * Hence, using the 'raw' driver, e.g., 100 bytes at offset 0x200 can be
242 * read from an EEPROM by the following pseudo-code:
243 *
244 *   mknod("/dev/i2c-54", mode, MKDEV(rtems_libi2c_major, RTEMS_LIBI2C_MAKE_MINOR(0,0x54)))
245 *
246 *   int fd;
247 *   char off[2]={0x02,0x00};
248 *
249 *   fd = open("/dev/i2c-54",O_RDWR);
250 *   write(fd,off,2);
251 *   read(fd,buf,100);
252 *   close(fd);
253 *
254 */
255
256/* Higher Level Driver API
257 *
258 * Higher level drivers know how to deal with specific i2c
259 * devices (independent of the bus interface chip) and provide
260 * an abstraction, i.e., the usual read/write/ioctl access.
261 *
262 * Using the above example, such a high level driver could
263 * prevent the user from issuing potentially destructive write
264 * operations (the aforementioned EEPROM interprets any 3rd
265 * and following byte written to the device as data, i.e., the
266 * contents could easily be changed!).
267 * The correct 'read-pointer offset' programming could be
268 * implemented in 'open' and 'ioctl' of a high-level driver and
269 * the user would then only have to perform harmless read
270 * operations, e.g.,
271 *
272 *    fd = open("/dev/i2c.eeprom",O_RDONLY) / * opens and sets EEPROM read pointer * /
273 *    ioctl(fd, IOCTL_SEEK, 0x200)                      / * repositions the read pointer       * /
274 *    read(fd, buf, 100)
275 *    close(fd)
276 *
277 */
278
279/* struct provided at driver registration. The driver may store
280 * private data behind the mandatory first fields but the size
281 * must be set to the size of the entire struct, e.g.,
282 *
283 * struct driver_pvt {
284 *      rtems_libi2c_drv_t pub;
285 *      struct {  ...    } pvt;
286 * } my_driver = {
287 *              {  ops: my_ops,
288 *                size: sizeof(my_driver)
289 *              },
290 *              { ...};
291 * };
292 *
293 * A pointer to this struct is passed to the callback ops.
294 */
295
296typedef struct rtems_libi2c_drv_t_
297{
298  const rtems_driver_address_table *ops;      /* the driver ops */
299  int size;                     /* size of whole structure (including appended private data) */
300} rtems_libi2c_drv_t;
301
302/*
303 * The high level driver must be registered with a particular
304 * bus number and i2c address.
305 *
306 * The registration procedure also creates a filesystem node,
307 * i.e., the returned minor number is not really needed.
308 *
309 * If the 'name' argument is NULL, no filesystem node is
310 * created (but this can be done 'manually' using rtems_libi2c_major
311 * and the return value of this routine).
312 *
313 * RETURNS minor number (FYI) or -1 on failure
314 */
315extern int
316rtems_libi2c_register_drv (const char *name, rtems_libi2c_drv_t * drvtbl,
317                           unsigned bus, unsigned i2caddr);
318
319/* Operations available to high level drivers */
320
321/* NOTES: The bus a device is attached to is LOCKED from the first send_start
322 *        until send_stop is executed!
323 *
324 *        Bus tenure MUST NOT span multiple system calls - otherwise, a single
325 *        thread could get into the protected sections (or would deadlock if the
326 *                mutex was not nestable).
327 *                E.g., consider what happens if 'open' sends a 'start' and 'close'
328 *                sends a 'stop' (i.e., the bus mutex would be locked in 'open' and
329 *        released in 'close'. A single thread could try to open two devices
330 *        on the same bus and would either deadlock or nest into the bus mutex
331 *        and potentially mess up the i2c messages.
332 *
333 *        The correct way is to *always* relinquish the i2c bus (i.e., send 'stop'
334 *                from any driver routine prior to returning control to the caller.
335 *                Consult the implementation of the generic driver routines (open, close, ...)
336 *                below or the examples in i2c-2b-eeprom.c and i2c-2b-ds1621.c
337 *
338 * Drivers just pass the minor number on to these routines...
339 */
340extern rtems_status_code rtems_libi2c_send_start (rtems_device_minor_number minor);
341
342extern rtems_status_code rtems_libi2c_send_stop (rtems_device_minor_number minor);
343
344extern rtems_status_code
345rtems_libi2c_send_addr (rtems_device_minor_number minor, int rw);
346
347/* the read/write routines return the number of bytes transferred
348 * or -(status_code) on error.
349 */
350extern int
351rtems_libi2c_read_bytes (rtems_device_minor_number minor,
352                         unsigned char *bytes, int nbytes);
353
354extern int
355rtems_libi2c_write_bytes (rtems_device_minor_number minor,
356                          const unsigned char *bytes, int nbytes);
357
358/* Send start, send address and read bytes */
359extern int
360rtems_libi2c_start_read_bytes (rtems_device_minor_number minor, 
361                               unsigned char *bytes,
362                               int nbytes);
363
364/* Send start, send address and write bytes */
365extern int
366rtems_libi2c_start_write_bytes (rtems_device_minor_number minor, 
367                                const unsigned char *bytes,
368                                int nbytes);
369
370
371/* call misc iocontrol function */
372extern int
373rtems_libi2c_ioctl (rtems_device_minor_number minor,
374                    int cmd,
375                    ...);
376/*
377 * NOTE: any low-level driver ioctl returning a negative
378 * result for release the bus (perform a STOP condition)
379 */
380/*******************************
381 * defined IOCTLs:
382 *******************************/
383#define RTEMS_LIBI2C_IOCTL_READ_WRITE  1
384/*
385 * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
386 *                             RTEMS_LIBI2C_IOCTL_READ_WRITE,
387 *                              rtems_libi2c_read_write_t *arg);
388 *
389 * This call performs a simultanous read/write transfer,
390 * which is possible (and sometimes needed) for SPI devices
391 *
392 *   arg is a pointer to a rd_wr info data structure
393 *
394 * This call is only needed for SPI devices
395 */
396#define RTEMS_LIBI2C_IOCTL_START_TFM_READ_WRITE  2
397/*
398 * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
399 *                             RTEMS_LIBI2C_IOCTL_START_READ_WRITE,
400 *                             unsigned char *rd_buffer,
401 *                             const unsigned char *wr_buffer,
402 *                             int byte_cnt,
403 *                             const rtems_libi2c_tfr_mode_t *tfr_mode_ptr);
404 *
405 * This call addresses a slave and then:
406 * - sets the proper transfer mode,
407 *  - performs a simultanous  read/write transfer,
408 *    (which is possible and sometimes needed for SPI devices)
409 *    NOTE: - if rd_buffer is NULL, receive data will be dropped
410 *          - if wr_buffer is NULL, bytes with content 0 will transmitted
411 *
412 *   rd_buffer is a pointer to a receive buffer (or NULL)
413 *   wr_buffer is a pointer to the data to be sent (or NULL)
414 *
415 * This call is only needed for SPI devices
416 */
417
418#define RTEMS_LIBI2C_IOCTL_SET_TFRMODE 3
419/*
420 * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
421 *                             RTEMS_LIBI2C_IOCTL_SET_TFRMODE,
422 *                             const rtems_libi2c_tfr_mode_t *tfr_mode_ptr);
423 *
424 * This call sets an SPI device to the transfer mode needed (baudrate etc.)
425 *
426 *   tfr_mode is a pointer to a structure defining the SPI transfer mode needed
427 *   (see below).
428 *
429 * This call is only needed for SPI devices
430 */
431
432#define RTEMS_LIBI2C_IOCTL_GET_DRV_T 4
433
434/*
435 * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
436 *                             RTEMS_LIBI2C_IOCTL_GET_DRV_T,
437 *                             const rtems_libi2c_drv_t *drv_t_ptr);
438 *
439 * This call allows the a high-level driver to query its driver table entry,
440 * including its private data appended to it during creation of the entry
441 *
442 */
443
444/**
445 * @brief IO control command for asynchronous read and write.
446 *
447 * @see rtems_libi2c_read_write_done_t and rtems_libi2c_read_write_async_t.
448 *
449 * @warning This is work in progress!
450 */
451#define RTEMS_LIBI2C_IOCTL_READ_WRITE_ASYNC 5
452
453/*
454 * argument data structures for IOCTLs defined above
455 */
456typedef struct {
457  unsigned char       *rd_buf;
458  const unsigned char *wr_buf;
459  int                  byte_cnt;
460} rtems_libi2c_read_write_t;
461
462typedef struct {
463  uint32_t baudrate;       /* maximum bits per second               */
464                           /* only valid for SPI drivers:           */
465  uint8_t  bits_per_char;  /* how many bits per byte/word/longword? */
466  bool     lsb_first;      /* true: send LSB first                  */
467  bool     clock_inv;      /* true: inverted clock (high active)    */
468  bool     clock_phs;      /* true: clock starts toggling at start of data tfr */
469  uint32_t  idle_char;     /* This character will be continuously transmitted in read only functions */
470} rtems_libi2c_tfr_mode_t;
471
472typedef struct {
473  rtems_libi2c_tfr_mode_t   tfr_mode;
474  rtems_libi2c_read_write_t rd_wr;
475} rtems_libi2c_tfm_read_write_t;
476
477/**
478 * @brief Notification function type for asynchronous read and write.
479 *
480 * @see RTEMS_LIBI2C_IOCTL_READ_WRITE_ASYNC and
481 * rtems_libi2c_read_write_async_t.
482 *
483 * @warning This is work in progress!
484 */
485typedef void (*rtems_libi2c_read_write_done_t) \
486  ( int /* return value */, int /* nbytes */, void * /* arg */);
487
488/**
489 * @brief IO command data for asynchronous read and write.
490 *
491 * @see RTEMS_LIBI2C_IOCTL_READ_WRITE_ASYNC and
492 * rtems_libi2c_read_write_done_t.
493 *
494 * @warning This is work in progress!
495 */
496typedef struct {
497  unsigned char                 *rd_buf;
498  const unsigned char           *wr_buf;
499  int                            byte_cnt;
500  rtems_libi2c_read_write_done_t done;
501  void                          *arg;
502} rtems_libi2c_read_write_async_t;
503
504/** @} */
505
506#ifdef __cplusplus
507}
508#endif
509
510#endif
Note: See TracBrowser for help on using the repository browser.