source: rtems/cpukit/include/rtems/libi2c.h @ e97806a

5
Last change on this file since e97806a was 2afb22b, checked in by Chris Johns <chrisj@…>, on 12/23/17 at 07:18:56

Remove make preinstall

A speciality of the RTEMS build system was the make preinstall step. It
copied header files from arbitrary locations into the build tree. The
header files were included via the -Bsome/build/tree/path GCC command
line option.

This has at least seven problems:

  • The make preinstall step itself needs time and disk space.
  • Errors in header files show up in the build tree copy. This makes it hard for editors to open the right file to fix the error.
  • There is no clear relationship between source and build tree header files. This makes an audit of the build process difficult.
  • The visibility of all header files in the build tree makes it difficult to enforce API barriers. For example it is discouraged to use BSP-specifics in the cpukit.
  • An introduction of a new build system is difficult.
  • Include paths specified by the -B option are system headers. This may suppress warnings.
  • The parallel build had sporadic failures on some hosts.

This patch removes the make preinstall step. All installed header
files are moved to dedicated include directories in the source tree.
Let @RTEMS_CPU@ be the target architecture, e.g. arm, powerpc, sparc,
etc. Let @RTEMS_BSP_FAMILIY@ be a BSP family base directory, e.g.
erc32, imx, qoriq, etc.

The new cpukit include directories are:

  • cpukit/include
  • cpukit/score/cpu/@RTEMS_CPU@/include
  • cpukit/libnetworking

The new BSP include directories are:

  • bsps/include
  • bsps/@RTEMS_CPU@/include
  • bsps/@RTEMS_CPU@/@RTEMS_BSP_FAMILIY@/include

There are build tree include directories for generated files.

The include directory order favours the most general header file, e.g.
it is not possible to override general header files via the include path
order.

The "bootstrap -p" option was removed. The new "bootstrap -H" option
should be used to regenerate the "headers.am" files.

Update #3254.

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