1 /* 2 * Copyright (c) 2015-2020, Texas Instruments Incorporated 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of Texas Instruments Incorporated nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 /*!**************************************************************************** 33 * @file I2C.h 34 * @brief Inter-Integrated Circuit (I2C) Driver 35 * 36 * @anchor ti_drivers_I2C_Overview 37 * # Overview 38 * 39 * The I2C driver is designed to operate as an I2C master and will not 40 * function as an I2C slave. Multi-master arbitration is not supported; 41 * therefore, this driver assumes it is the only I2C master on the bus. 42 * This I2C driver's API set provides the ability to transmit and receive 43 * data over an I2C bus between the I2C master and I2C slave(s). The 44 * application is responsible for manipulating and interpreting the data. 45 * 46 * 47 * <hr> 48 * @anchor ti_drivers_I2C_Usage 49 * # Usage 50 * 51 * This section provides a basic @ref ti_drivers_I2C_Synopsis 52 * "usage summary" and a set of @ref ti_drivers_I2C_Examples "examples" 53 * in the form of commented code fragments. Detailed descriptions of the 54 * I2C APIs and their effect are provided in subsequent sections. 55 * 56 * @anchor ti_drivers_I2C_Synopsis 57 * ## Synopsis # 58 * @anchor ti_drivers_I2C_Synopsis_Code 59 * @code 60 * // Import I2C Driver definitions 61 * #include <ti/drivers/I2C.h> 62 * 63 * // Define name for an index of an I2C bus 64 * #define SENSORS 0 65 * 66 * // Define the slave address of device on the SENSORS bus 67 * #define OPT_ADDR 0x47 68 * 69 * // One-time init of I2C driver 70 * I2C_init(); 71 * 72 * // initialize optional I2C bus parameters 73 * I2C_Params params; 74 * I2C_Params_init(¶ms); 75 * params.bitRate = I2C_400kHz; 76 * 77 * // Open I2C bus for usage 78 * I2C_Handle i2cHandle = I2C_open(SENSORS, ¶ms); 79 * 80 * // Initialize slave address of transaction 81 * I2C_Transaction transaction = {0}; 82 * transaction.slaveAddress = OPT_ADDR; 83 * 84 * // Read from I2C slave device 85 * transaction.readBuf = data; 86 * transaction.readCount = sizeof(data); 87 * transaction.writeCount = 0; 88 * I2C_transfer(i2cHandle, &transaction); 89 * 90 * // Write to I2C slave device 91 * transaction.writeBuf = command; 92 * transaction.writeCount = sizeof(command); 93 * transaction.readCount = 0; 94 * I2C_transferTimeout(i2cHandle, &transaction, 5000); 95 * 96 * // Close I2C 97 * I2C_close(i2cHandle); 98 * @endcode 99 * 100 * @anchor ti_drivers_I2C_Examples 101 * ## Examples 102 * 103 * @li @ref ti_drivers_I2C_Example_open "Getting an I2C bus handle" 104 * @li @ref ti_drivers_I2C_Example_write3bytes "Sending 3 bytes" 105 * @li @ref ti_drivers_I2C_Example_read5bytes "Reading 5 bytes" 106 * @li @ref ti_drivers_I2C_Example_writeread "Writing then reading in a single transaction" 107 * @li @ref ti_drivers_I2C_Example_callback "Using Callback mode" 108 * 109 * @anchor ti_drivers_I2C_Example_open 110 * ## Opening the I2C Driver 111 * 112 * After calling I2C_init(), the application can open an I2C instance by 113 * calling I2C_open().The following code example opens an I2C instance with 114 * default parameters by passing @p NULL for the #I2C_Params argument. 115 * 116 * @code 117 * I2C_Handle i2cHandle; 118 * 119 * i2cHandle = I2C_open(0, NULL); 120 * 121 * if (i2cHandle == NULL) { 122 * // Error opening I2C 123 * while (1) {} 124 * } 125 * @endcode 126 * 127 * @anchor ti_drivers_I2C_Example_write3bytes 128 * ## Sending three bytes of data. 129 * 130 * @code 131 * I2C_Transaction i2cTransaction = {0}; 132 * uint8_t writeBuffer[3]; 133 * 134 * writeBuffer[0] = 0xAB; 135 * writeBuffer[1] = 0xCD; 136 * writeBuffer[2] = 0xEF; 137 * 138 * i2cTransaction.slaveAddress = 0x50; 139 * i2cTransaction.writeBuf = writeBuffer; 140 * i2cTransaction.writeCount = 3; 141 * i2cTransaction.readBuf = NULL; 142 * i2cTransaction.readCount = 0; 143 * 144 * status = I2C_transfer(i2cHandle, &i2cTransaction); 145 * 146 * if (status == false) { 147 * // Unsuccessful I2C transfer 148 * if (i2cTransaction.status == I2C_STATUS_ADDR_NACK) { 149 * // I2C slave address not acknowledged 150 * } 151 * } 152 * @endcode 153 * 154 * @anchor ti_drivers_I2C_Example_read5bytes 155 * ## Reading five bytes of data. 156 * 157 * @code 158 * I2C_Transaction i2cTransaction = {0}; 159 * uint8_t readBuffer[5]; 160 * 161 * i2cTransaction.slaveAddress = 0x50; 162 * i2cTransaction.writeBuf = NULL; 163 * i2cTransaction.writeCount = 0; 164 * i2cTransaction.readBuf = readBuffer; 165 * i2cTransaction.readCount = 5; 166 * 167 * status = I2C_transfer(i2cHandle, &i2cTransaction); 168 * 169 * if (status == false) { 170 * if (i2cTransaction.status == I2C_STATUS_ADDR_NACK) { 171 * // I2C slave address not acknowledged 172 * } 173 * } 174 * @endcode 175 * 176 * @anchor ti_drivers_I2C_Example_writeread 177 * ## Writing two bytes and reading four bytes in a single transaction. 178 * 179 * @code 180 * I2C_Transaction i2cTransaction = {0}; 181 * uint8_t readBuffer[4]; 182 * uint8_t writeBuffer[2]; 183 * 184 * writeBuffer[0] = 0xAB; 185 * writeBuffer[1] = 0xCD; 186 * 187 * i2cTransaction.slaveAddress = 0x50; 188 * i2cTransaction.writeBuf = writeBuffer; 189 * i2cTransaction.writeCount = 2; 190 * i2cTransaction.readBuf = readBuffer; 191 * i2cTransaction.readCount = 4; 192 * 193 * status = I2C_transfer(i2cHandle, &i2cTransaction); 194 * 195 * if (status == false) { 196 * if (i2cTransaction->status == I2C_STATUS_ADDR_NACK) { 197 * // slave address not acknowledged 198 * } 199 * } 200 * @endcode 201 * 202 * @anchor ti_drivers_I2C_Example_callback 203 * ## Using callback mode 204 * This final example shows usage of #I2C_MODE_CALLBACK, with queuing 205 * of multiple transactions. Because multiple transactions are simultaneously 206 * queued, separate #I2C_Transaction structures must be used. Each 207 * #I2C_Transaction will contain a custom application argument of a 208 * semaphore handle. The #I2C_Transaction.arg will point to the semaphore 209 * handle. When the callback function is called, the #I2C_Transaction.arg is 210 * checked for @p NULL. If this value is not @p NULL, then it can be assumed 211 * the @p arg is pointing to a valid semaphore handle. The semaphore handle 212 * is then used to call @p sem_post(). Hypothetically, this can be used to 213 * signal transaction completion to the task(s) that queued the 214 * transaction(s). 215 * 216 * @code 217 * void callbackFxn(I2C_Handle handle, I2C_Transaction *msg, bool status) 218 * { 219 * // if transaction failed 220 * if (status == false) { 221 * if (msg->status == I2C_STATUS_ADDR_NACK) { 222 * // slave address not acknowledged 223 * } 224 * else if (msg->status == I2C_STATUS_CANCEL) { 225 * // transaction canceled by I2C_cancel() 226 * } 227 * } 228 * 229 * // Check for a custom argument 230 * if (msg->arg != NULL) { 231 * 232 * // In this example, the custom argument is a semaphore handle 233 * // Perform a semaphore post 234 * sem_post((sem_t *) (msg->arg)); 235 * } 236 * } 237 * @endcode 238 * 239 * Snippets of the thread code that initiates the transactions are shown below. 240 * Note the use of multiple #I2C_Transaction structures. The handle of the 241 * semaphore to be posted is specified via @p i2cTransaction2.arg. 242 * I2C_transfer() is called three times to initiate each transaction. 243 * Since callback mode is used, these functions return immediately. After 244 * the transactions have been queued, other work can be done. Eventually, 245 * @p sem_wait() is called causing the thread to block until the transaction 246 * completes. When the transaction completes, the application's callback 247 * function, @p callbackFxn will be called. Once #I2C_CallbackFxn posts the 248 * semaphore, the thread will be unblocked and can resume execution. 249 * 250 * @code 251 * void thread(arg0, arg1) 252 * { 253 * 254 * I2C_Transaction i2cTransaction0 = {0}; 255 * I2C_Transaction i2cTransaction1 = {0}; 256 * I2C_Transaction i2cTransaction2 = {0}; 257 * 258 * // ... 259 * 260 * i2cTransaction0.arg = NULL; 261 * i2cTransaction1.arg = NULL; 262 * i2cTransaction2.arg = semaphoreHandle; 263 * 264 * // ... 265 * 266 * I2C_transfer(i2c, &i2cTransaction0); 267 * I2C_transfer(i2c, &i2cTransaction1); 268 * I2C_transfer(i2c, &i2cTransaction2); 269 * 270 * // ... 271 * 272 * sem_wait(semaphoreHandle); 273 * } 274 * @endcode 275 * 276 * <hr> 277 * @anchor ti_drivers_I2C_Configuration 278 * # Configuration 279 * 280 * Refer to the @ref driver_configuration "Driver's Configuration" section 281 * for driver configuration information. 282 * <hr> 283 ****************************************************************************** 284 */ 285 286 #ifndef ti_drivers_I2C__include 287 #define ti_drivers_I2C__include 288 289 /*! @cond */ 290 #include <stdbool.h> 291 #include <stddef.h> 292 #include <stdint.h> 293 /*! @endcond */ 294 295 #ifdef __cplusplus 296 extern "C" { 297 #endif 298 299 /** 300 * @defgroup I2C_STATUS I2C Status codes 301 * These macros are reservations for I2C.h 302 * @{ 303 */ 304 305 /*! @cond */ 306 /*! 307 * @private 308 * Common I2C_control status code reservation offset. 309 * I2C driver implementations should offset status codes with 310 * #I2C_STATUS_RESERVED growing negatively. 311 * 312 * Example implementation specific status codes: 313 * @code 314 * #define I2CXYZ_STATUS_ERROR0 I2C_STATUS_RESERVED - 0 315 * #define I2CXYZ_STATUS_ERROR1 I2C_STATUS_RESERVED - 1 316 * #define I2CXYZ_STATUS_ERROR2 I2C_STATUS_RESERVED - 2 317 * @endcode 318 */ 319 #define I2C_STATUS_RESERVED (-32) 320 /*! @endcond */ 321 322 /*! 323 * @brief I2C transaction is queued but has not started 324 */ 325 #define I2C_STATUS_QUEUED (1) 326 327 /*! 328 * @brief Successful status code returned by I2C API. 329 */ 330 #define I2C_STATUS_SUCCESS (0) 331 332 /*! 333 * @brief Generic error status code returned by I2C API. 334 */ 335 #define I2C_STATUS_ERROR (-1) 336 337 /*! 338 * @brief An error status code returned by I2C_control() for undefined 339 * command codes. 340 */ 341 #define I2C_STATUS_UNDEFINEDCMD (-2) 342 343 /*! 344 * @brief I2C operation timed-out 345 */ 346 #define I2C_STATUS_TIMEOUT (-3) 347 348 /*! 349 * @brief I2C serial clock line timeout 350 */ 351 #define I2C_STATUS_CLOCK_TIMEOUT (-4) 352 353 /*! 354 * @brief I2C slave address not acknowledged 355 */ 356 #define I2C_STATUS_ADDR_NACK (-5) 357 358 /*! 359 * @brief I2C data byte not acknowledged 360 */ 361 #define I2C_STATUS_DATA_NACK (-6) 362 363 /*! 364 * @brief I2C multi-master arbitration lost 365 */ 366 #define I2C_STATUS_ARB_LOST (-7) 367 368 /*! 369 * @brief I2C transaction is in progress or returned without completing 370 */ 371 #define I2C_STATUS_INCOMPLETE (-8) 372 373 /*! 374 * @brief I2C bus already in use by another controller. The I2C transaction 375 * was therefore unable to start. 376 */ 377 #define I2C_STATUS_BUS_BUSY (-9) 378 379 /*! 380 * @brief I2C transaction canceled by I2C_cancel() 381 */ 382 #define I2C_STATUS_CANCEL (-10) 383 384 /*! 385 * @brief I2C transaction is invalid. This may occur if: 386 * 1. The #I2C_Transaction.readCount and #I2C_Transaction.writeCount are 387 * both set to 0. 388 * 2. A call to I2C_transfer() is made from a #I2C_CallbackFxn while queued 389 * transactions are being canceled. See also: I2C_cancel() 390 */ 391 #define I2C_STATUS_INVALID_TRANS (-11) 392 /** @} */ 393 394 /*! 395 * @brief Wait forever define used to specify timeouts. 396 */ 397 #define I2C_WAIT_FOREVER (~(0U)) 398 399 /*! 400 * @brief A handle that is returned from an I2C_open() call. 401 */ 402 typedef struct I2C_Config_ *I2C_Handle; 403 404 /*! 405 * @brief Defines a transaction to be used with I2C_transfer() or 406 * I2C_transferTimeout() 407 * 408 * After a call to I2C_transfer(), the #I2C_Transaction.status reflects 409 * the current transfer status. 410 * 411 * @sa I2C_transfer(), I2C_transferTimeout() 412 */ 413 typedef struct { 414 /*! 415 * Pointer to a buffer of at least #I2C_Transaction.writeCount bytes. 416 * If #I2C_Transaction.writeCount is 0, this pointer is not used. 417 */ 418 void *writeBuf; 419 420 /*! 421 * Number of bytes to write to the I2C slave device. A value of 0 422 * indicates no data will be written to the slave device and only a read 423 * will occur. If this value 424 * is not 0, the driver will always perform the write transfer first. 425 * The data written to the I2C bus is preceded by the 426 * #I2C_Transaction.slaveAddress with the write bit set. If 427 * @p writeCount bytes are successfully sent and 428 * acknowledged, the transfer will complete or perform a read--depending 429 * on #I2C_Transaction.readCount. 430 * 431 * @note Both #I2C_Transaction.writeCount and #I2C_Transaction.readCount 432 * can not be 0. 433 */ 434 size_t writeCount; 435 436 /*! 437 * Pointer to a buffer of at least #I2C_Transaction.readCount bytes. 438 * If #I2C_Transaction.readCount is 0, this pointer is not used. 439 */ 440 void *readBuf; 441 442 /*! 443 * Number of bytes to read from the I2C slave device. A value of 0 444 * indicates no data will be read and only a write will occur. If 445 * #I2C_Transaction.writeCount is not 0, this driver will perform the 446 * write first, followed by the read. The data read from the bus is 447 * preceded by the #I2C_Transaction.slaveAddress with the read bit set. 448 * After @p readCount bytes are successfully read, the transfer will 449 * complete. 450 * 451 * @note Both #I2C_Transaction.writeCount and #I2C_Transaction.readCount 452 * can not be 0. 453 */ 454 size_t readCount; 455 456 /*! 457 * Pointer to a custom argument to be passed to the #I2C_CallbackFxn 458 * function via the #I2C_Transaction structure. 459 * 460 * @note The #I2C_CallbackFxn function is only called when operating in 461 * #I2C_MODE_CALLBACK. 462 * 463 * @sa #I2C_MODE_CALLBACK 464 * @sa #I2C_CallbackFxn 465 */ 466 void *arg; 467 468 /*! 469 * I2C status of the current transaction. The status may be used to 470 * determine why a transaction failed. Potential codes are: 471 * @li #I2C_STATUS_SUCCESS 472 * @li #I2C_STATUS_ERROR 473 * @li #I2C_STATUS_TIMEOUT 474 * @li #I2C_STATUS_CLOCK_TIMEOUT 475 * @li #I2C_STATUS_ADDR_NACK 476 * @li #I2C_STATUS_DATA_NACK 477 * @li #I2C_STATUS_ARB_LOST 478 * @li #I2C_STATUS_INCOMPLETE 479 * @li #I2C_STATUS_BUS_BUSY 480 * @li #I2C_STATUS_CANCEL 481 * @li #I2C_STATUS_INVALID_TRANS 482 * 483 * This status may also be used to determine if a transaction is queued 484 * (#I2C_STATUS_QUEUED) or in progress (#I2C_STATUS_INCOMPLETE). 485 */ 486 volatile int_fast16_t status; 487 488 /*! 489 * I2C slave address used for the transaction. The slave address is 490 * the first byte transmitted during an I2C transfer. The read/write bit 491 * is automatically set based upon the #I2C_Transaction.writeCount and 492 * #I2C_Transaction.readCount. 493 */ 494 uint_least8_t slaveAddress; 495 496 /*! 497 * @private This is reserved for use by the driver and must never be 498 * modified by the application. 499 */ 500 void *nextPtr; 501 } I2C_Transaction; 502 503 /*! 504 * @brief Return behavior of I2C_Transfer() specified in the #I2C_Params. 505 * 506 * This enumeration defines the return behaviors for a call to I2C_transfer(). 507 * 508 * @sa #I2C_Params 509 */ 510 typedef enum { 511 /*! 512 * In #I2C_MODE_BLOCKING, calls to I2C_transfer() block until the 513 * #I2C_Transaction completes. Other threads calling I2C_transfer() 514 * while a transaction is in progress are also placed into a blocked 515 * state. If multiple threads are blocked, the thread with the highest 516 * priority will be unblocked first. This implies that arbitration 517 * will not be executed in chronological order. 518 * 519 * @note When using #I2C_MODE_BLOCKING, I2C_transfer() must be called 520 * from a thread context. 521 */ 522 I2C_MODE_BLOCKING, 523 524 /*! 525 * In #I2C_MODE_CALLBACK, calls to I2C_transfer() return immediately. The 526 * application's callback function, #I2C_Params.transferCallbackFxn, is 527 * called when the transaction is complete. Sequential calls to 528 * I2C_transfer() will place #I2C_Transaction structures into an 529 * internal queue. Queued transactions are automatically started after the 530 * previous transaction has completed. This queuing occurs regardless of 531 * any error state from previous transactions. The transactions are 532 * always executed in chronological order. The 533 * #I2C_Params.transferCallbackFxn function will be called asynchronously 534 * as each transaction is completed. 535 */ 536 I2C_MODE_CALLBACK 537 } I2C_TransferMode; 538 539 /*! 540 * @brief The definition of a callback function. 541 * 542 * When operating in #I2C_MODE_CALLBACK, the callback function is called 543 * when an I2C_transfer() completes. The application is responsible for 544 * declaring an #I2C_CallbackFxn function and providing a pointer 545 * in #I2C_Params.transferCallbackFxn. 546 * 547 * @warning The callback function is called from an interrupt context. 548 * 549 * @param[out] handle #I2C_Handle used with the initial call to 550 * I2C_transfer() 551 * 552 * @param[out] transaction Pointer to the #I2C_Transaction structure used 553 * with the initial call to I2C_transfer(). This structure contains the 554 * custom argument specified by @p transaction.arg and the transaction status. 555 * 556 * @param[out] transferStatus Boolean indicating if the I2C transaction 557 * was successful. If @p true, the transaction was successful. If @p false, 558 * the transaction failed. 559 */ 560 typedef void (*I2C_CallbackFxn)(I2C_Handle handle, I2C_Transaction *transaction, 561 bool transferStatus); 562 563 /*! 564 * @brief Bit rate for an I2C driver instance specified in the #I2C_Params. 565 * 566 * This enumeration defines the bit rates used with an I2C_transfer(). 567 * 568 * @note You must check that the device specific implementation supports the 569 * desired #I2C_BitRate. 570 */ 571 typedef enum { 572 I2C_100kHz = 0, /*!< I2C Standard-mode. Up to 100 kbit/s. */ 573 I2C_400kHz = 1, /*!< I2C Fast-mode. Up to 400 kbit/s. */ 574 I2C_1000kHz = 2, /*!< I2C Fast-mode Plus. Up to 1Mbit/s. */ 575 I2C_3330kHz = 3, /*!< I2C High-speed mode. Up to 3.4Mbit/s. */ 576 I2C_3400kHz = 3, /*!< I2C High-speed mode. Up to 3.4Mbit/s. */ 577 } I2C_BitRate; 578 579 /*! 580 * @brief I2C parameters used with I2C_open(). 581 * 582 * I2C_Params_init() must be called prior to setting fields in 583 * this structure. 584 * 585 * @sa I2C_Params_init() 586 */ 587 typedef struct { 588 /*! #I2C_TransferMode for all I2C transfers. */ 589 I2C_TransferMode transferMode; 590 591 /*! 592 * Pointer to a #I2C_CallbackFxn to be invoked after a 593 * I2C_transfer() completes when operating in #I2C_MODE_CALLBACK. 594 */ 595 I2C_CallbackFxn transferCallbackFxn; 596 597 /*! 598 * A #I2C_BitRate specifying the frequency at which the I2C peripheral 599 * will transmit data during a I2C_transfer(). 600 */ 601 I2C_BitRate bitRate; 602 603 /*! Pointer to a device specific extension of the #I2C_Params */ 604 void *custom; 605 } I2C_Params; 606 607 /*! 608 * @private 609 * @brief A function pointer to a driver-specific implementation of 610 * I2C_cancel(). 611 */ 612 typedef void (*I2C_CancelFxn) (I2C_Handle handle); 613 614 /*! 615 * @private 616 * @brief A function pointer to a driver-specific implementation of 617 * I2C_close(). 618 */ 619 typedef void (*I2C_CloseFxn) (I2C_Handle handle); 620 621 /*! 622 * @private 623 * @brief A function pointer to a driver-specific implementation of 624 * I2C_control(). 625 */ 626 typedef int_fast16_t (*I2C_ControlFxn) (I2C_Handle handle, uint_fast16_t cmd, 627 void *controlArg); 628 629 /*! 630 * @private 631 * @brief A function pointer to a driver-specific implementation of 632 * I2C_init(). 633 */ 634 typedef void (*I2C_InitFxn) (I2C_Handle handle); 635 636 /*! 637 * @private 638 * @brief A function pointer to a driver-specific implementation of 639 * I2C_open(). 640 */ 641 typedef I2C_Handle (*I2C_OpenFxn) (I2C_Handle handle, I2C_Params *params); 642 643 /*! 644 * @private 645 * @brief A function pointer to a driver-specific implementation of 646 * I2C_transfer(). 647 */ 648 typedef int_fast16_t (*I2C_TransferFxn) (I2C_Handle handle, 649 I2C_Transaction *transaction, uint32_t timeout); 650 651 /*! 652 * @brief The definition of an I2C function table that contains the 653 * required set of functions to control a specific I2C driver 654 * implementation. 655 */ 656 typedef struct { 657 I2C_CancelFxn cancelFxn; 658 I2C_CloseFxn closeFxn; 659 I2C_ControlFxn controlFxn; 660 I2C_InitFxn initFxn; 661 I2C_OpenFxn openFxn; 662 I2C_TransferFxn transferFxn; 663 } I2C_FxnTable; 664 665 /*! 666 * @brief I2C driver's custom @ref driver_configuration "configuration" 667 * structure. 668 * 669 * @sa I2C_init() 670 * @sa I2C_open() 671 */ 672 typedef struct I2C_Config_ { 673 /*! Pointer to a @ref driver_function_table "function pointer table" 674 * with driver-specific implementations of I2C APIs */ 675 I2C_FxnTable const *fxnTablePtr; 676 677 /*! Pointer to a driver specific @ref driver_objects "data object". */ 678 void *object; 679 680 /*! Pointer to a driver specific @ref driver_hardware_attributes 681 * "hardware attributes structure". */ 682 void const *hwAttrs; 683 } I2C_Config; 684 685 /*! 686 * @brief Cancels all I2C transfers 687 * 688 * This function will cancel asynchronous I2C_transfer() operations by 689 * generating a STOP condition on the I2C bus. 690 * 691 * Calls to I2C_cancel() return immediately; however, the transaction 692 * may not yet be canceled. 693 * 694 * For #I2C_MODE_BLOCKING, the current transaction is canceled. 695 * 696 * For #I2C_MODE_CALLBACK mode, the in progress transfer, as 697 * well as any queued transfers, will be canceled. The individual callback 698 * functions for each transfer will be called in chronological order. The 699 * callback functions are called in an interrupt context. Additional calls 700 * to I2C_transfer() invoked from the callback function of a canceled 701 * transaction will always fail. In such cases, the #I2C_Transaction.status 702 * will indicate #I2C_STATUS_INVALID_TRANS. 703 * 704 * A canceled transaction may be identified when the #I2C_Transaction.status 705 * is set to #I2C_STATUS_CANCEL. 706 * 707 * @note This API may not handle cases where the I2C slave holds the clock 708 * line indefinitely. 709 * 710 * @pre I2C_Transfer() has been called. 711 * 712 * @param[in] handle An #I2C_Handle returned from I2C_open() 713 * 714 * @note Different I2C slave devices will behave differently when an 715 * in-progress transfer fails and needs to be canceled. The slave 716 * may need to be reset, or there may be other slave-specific 717 * steps that can be used to successfully resume communication. 718 * 719 * @sa I2C_transfer() 720 * @sa #I2C_MODE_CALLBACK 721 */ 722 extern void I2C_cancel(I2C_Handle handle); 723 724 /*! 725 * @brief Function to close an I2C driver instance 726 * 727 * @pre I2C_open() has been called. 728 * 729 * @param[in] handle An #I2C_Handle returned from I2C_open() 730 */ 731 extern void I2C_close(I2C_Handle handle); 732 733 /*! 734 * @brief Function performs implementation specific features on a 735 * driver instance. 736 * 737 * @pre I2C_open() has to be called first. 738 * 739 * @param[in] handle An #I2C_Handle returned from I2C_open() 740 * 741 * @param[in] cmd A command value defined by the device specific 742 * implementation 743 * 744 * @param[in] controlArg An optional R/W (read/write) argument that is 745 * accompanied with @p cmd 746 * 747 * @return Implementation specific return codes. Negative values indicate 748 * unsuccessful operations. 749 * 750 * @retval #I2C_STATUS_SUCCESS The call was successful. 751 * @retval #I2C_STATUS_UNDEFINEDCMD The @p cmd value is not supported by 752 * the device specific implementation. 753 */ 754 extern int_fast16_t I2C_control(I2C_Handle handle, uint_fast16_t cmd, 755 void *controlArg); 756 757 /*! 758 * @brief Function to initialize the I2C driver. 759 * 760 * This function must also be called before any otherI2C driver APIs. 761 */ 762 extern void I2C_init(void); 763 764 /*! 765 * @brief Open an I2C driver instance. 766 * 767 * @pre I2C_init() has been called. 768 * 769 * @param[in] index Index in the @p I2C_Config[] array. 770 * 771 * @param[in] params Pointer to an initialized #I2C_Params structure. 772 * If NULL, the default #I2C_Params values are used. 773 * 774 * @return An #I2C_Handle on success, or @p NULL on an error. 775 * 776 * @sa I2C_init() 777 * @sa I2C_close() 778 */ 779 extern I2C_Handle I2C_open(uint_least8_t index, I2C_Params *params); 780 781 /*! 782 * @brief Initialize an #I2C_Params structure to its default values. 783 * 784 * @param[in] params A pointer to #I2C_Params structure for 785 * initialization. 786 * 787 * Defaults values are: 788 * @arg #I2C_Params.transferMode = #I2C_MODE_BLOCKING 789 * @arg #I2C_Params.transferCallbackFxn = @p NULL 790 * @arg #I2C_Params.bitRate = #I2C_100kHz 791 * @arg #I2C_Params.custom = @p NULL 792 */ 793 extern void I2C_Params_init(I2C_Params *params); 794 795 /*! 796 * @brief Perform an I2C transaction with an I2C slave peripheral. 797 * 798 * This function will perform an I2C transfer, as specified by an 799 * #I2C_Transaction structure. 800 * 801 * @note When using #I2C_MODE_BLOCKING, this must be called from a thread 802 * context. 803 * 804 * @param[in] handle An #I2C_Handle returned from I2C_open() 805 * 806 * @param[in] transaction A pointer to an #I2C_Transaction. The application 807 * is responsible for allocating and initializing an #I2C_Transaction 808 * structure prior to passing it to I2C_Transfer(). This 809 * structure must persist in memory unmodified until the transfer is complete. 810 * 811 * @note #I2C_Transaction structures cannot be re-used until the previous 812 * transaction has completed. Upon the completion of a transaction, the 813 * #I2C_Transaction.status may be used for error handling. 814 * 815 * @return In #I2C_MODE_BLOCKING: @p true for a successful transfer; @p false 816 * for an error (for example, an I2C bus fault (NACK)). 817 * 818 * @return In #I2C_MODE_CALLBACK: always @p true. The #I2C_CallbackFxn @p bool 819 * argument will be @p true to indicate success, and @p false to 820 * indicate an error. 821 * 822 * @pre I2C_open() has been called. 823 * 824 * @sa I2C_open(), I2C_transferTimeout() 825 * @sa I2C_Transaction 826 */ 827 extern bool I2C_transfer(I2C_Handle handle, I2C_Transaction *transaction); 828 829 /*! 830 * @brief Perform an I2C transaction with an I2C slave peripheral. 831 * 832 * This function will perform an I2C transfer, as specified by an 833 * #I2C_Transaction structure. If the timeout is exceeded, then the 834 * I2C transaction is canceled. 835 * 836 * @note When using #I2C_MODE_BLOCKING, this must be called from a thread 837 * context. 838 * 839 * @note The timeout restriction is only applied when using 840 * #I2C_MODE_BLOCKING. If using #I2C_MODE_CALLBACK, the application should 841 * manage timeouts using I2C_cancel(). Additionally, this timeout may not 842 * handle cases where the I2C slave holds the clock line indefinitely. 843 * 844 * @param[in] handle An #I2C_Handle returned from I2C_open() 845 * 846 * @param[in] transaction A pointer to an #I2C_Transaction. The application 847 * is responsible for allocating and initializing an #I2C_Transaction 848 * structure prior to passing it to I2C_TransferTimeout(). This 849 * structure must persist in memory unmodified until the transfer is complete. 850 * 851 * @param[in] timeout The time in system ticks to wait for the transaction 852 * to complete. Passing I2C_WAIT_FOREVER into this parameter will cause 853 * I2C_transferTimeout() to behave the same as I2C_transfer() but with a 854 * more detailed return status. 855 * 856 * @note #I2C_Transaction structures cannot be re-used until the previous 857 * transaction has completed. Upon the completion of a transaction, the 858 * #I2C_Transaction.status may be used for error handling. 859 * 860 * @return In #I2C_MODE_CALLBACK: always @p I2C_STATUS_SUCCESS. 861 * The #I2C_CallbackFxn @p transferStatus argument will be @p true 862 * to indicate success, and @p false to indicate an error. 863 * 864 * @return In #I2C_MODE_BLOCKING: Possible return values include: 865 * @li #I2C_STATUS_SUCCESS 866 * @li #I2C_STATUS_ERROR 867 * @li #I2C_STATUS_TIMEOUT 868 * @li #I2C_STATUS_CLOCK_TIMEOUT 869 * @li #I2C_STATUS_ADDR_NACK 870 * @li #I2C_STATUS_DATA_NACK 871 * @li #I2C_STATUS_ARB_LOST 872 * @li #I2C_STATUS_INCOMPLETE 873 * @li #I2C_STATUS_BUS_BUSY 874 * @li #I2C_STATUS_CANCEL 875 * @li #I2C_STATUS_INVALID_TRANS 876 * 877 * @pre I2C_open() has been called. 878 * 879 * @sa I2C_open(), I2C_transfer() 880 * @sa I2C_Transaction 881 */ 882 extern int_fast16_t I2C_transferTimeout(I2C_Handle handle, 883 I2C_Transaction *transaction, uint32_t timeout); 884 885 #ifdef __cplusplus 886 } 887 #endif 888 889 #endif /* ti_drivers_I2C__include */ 890