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