//########################################################################### // // FILE: i2c.h // // TITLE: C28x I2C driver. // //########################################################################### // $Copyright: // Copyright (C) 2022 Texas Instruments Incorporated - http://www.ti.com // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //########################################################################### #ifndef I2C_H #define I2C_H //***************************************************************************** // // If building with a C++ compiler, make all of the definitions in this header // have a C binding. // //***************************************************************************** #ifdef __cplusplus extern "C" { #endif //***************************************************************************** // //! \addtogroup i2c_api I2C //! @{ // //***************************************************************************** #include "inc/hw_i2c.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "cpu.h" #include "debug.h" #include "hw_reg_inclusive_terminology.h" //***************************************************************************** // // Defines for the API. // //***************************************************************************** #ifndef DOXYGEN_PDF_IGNORE //***************************************************************************** // // I2C Controller commands. // //***************************************************************************** #define I2C_CONTROLLER_SEND_MODE 0x0600U //!< Controller-transmitter mode #define I2C_CONTROLLER_RECEIVE_MODE 0x0400U //!< Controller-receiver mode #define I2C_TARGET_SEND_MODE 0x0200U //!< Target-transmitter mode #define I2C_TARGET_RECEIVE_MODE 0x0000U //!< Target-receiver mode #define I2C_REPEAT_MODE 0x0080U //!< Only applies to Controller mode #define I2C_START_BYTE_MODE 0x0010U //!< Enable start byte mode #define I2C_FREE_DATA_FORMAT 0x0008U //!< Enable free data (no addr) format //***************************************************************************** // // I2C interrupts for use with the intFlags parameter of I2C_enableInterrupt(), // I2C_disableInterrupt(), and I2C_clearInterruptStatus() and to be returned by // I2C_getInterruptStatus(). // //***************************************************************************** #define I2C_INT_ARB_LOST 0x00001U //!< Arbitration-lost interrupt #define I2C_INT_NO_ACK 0x00002U //!< NACK interrupt #define I2C_INT_REG_ACCESS_RDY 0x00004U //!< Register-access-ready interrupt #define I2C_INT_RX_DATA_RDY 0x00008U //!< Receive-data-ready interrupt #define I2C_INT_TX_DATA_RDY 0x00010U //!< Transmit-data-ready interrupt #define I2C_INT_STOP_CONDITION 0x00020U //!< Stop condition detected #define I2C_INT_ADDR_TARGET 0x00200U //!< Addressed as target interrupt #define I2C_INT_RXFF 0x10000U //!< RX FIFO level interrupt #define I2C_INT_TXFF 0x20000U //!< TX FIFO level interrupt // // Helpful define to mask out the bits in the I2CSTR register that aren't // associated with interrupts. // #define I2C_STR_INTMASK ((uint16_t)I2C_INT_ARB_LOST | \ (uint16_t)I2C_INT_NO_ACK | \ (uint16_t)I2C_INT_REG_ACCESS_RDY | \ (uint16_t)I2C_INT_RX_DATA_RDY | \ (uint16_t)I2C_INT_TX_DATA_RDY | \ (uint16_t)I2C_INT_STOP_CONDITION | \ (uint16_t)I2C_INT_ADDR_TARGET) //***************************************************************************** // // Flags for use as the stsFlags parameter of I2C_clearStatus() and to be // returned by I2C_getStatus(). // //***************************************************************************** #define I2C_STS_ARB_LOST 0x0001U //!< Arbitration-lost #define I2C_STS_NO_ACK 0x0002U //!< No-acknowledgment (NACK) #define I2C_STS_REG_ACCESS_RDY 0x0004U //!< Register-access-ready (ARDY) #define I2C_STS_RX_DATA_RDY 0x0008U //!< Receive-data-ready #define I2C_STS_TX_DATA_RDY 0x0010U //!< Transmit-data-ready #define I2C_STS_STOP_CONDITION 0x0020U //!< Stop condition detected #define I2C_STS_ADDR_ZERO 0x0100U //!< Address of all zeros detected #define I2C_STS_ADDR_TARGET 0x0200U //!< Addressed as target #define I2C_STS_TX_EMPTY 0x0400U //!< Transmit shift register empty #define I2C_STS_RX_FULL 0x0800U //!< Receive shift register full #define I2C_STS_BUS_BUSY 0x1000U //!< Bus busy, wait for STOP or reset #define I2C_STS_NACK_SENT 0x2000U //!< NACK was sent #define I2C_STS_TARGET_DIR 0x4000U //!< Addressed as target transmitter #endif //***************************************************************************** // //! I2C interrupts to be returned by I2C_getInterruptSource(). // //***************************************************************************** typedef enum { I2C_INTSRC_NONE, //!< No interrupt pending I2C_INTSRC_ARB_LOST, //!< Arbitration-lost interrupt I2C_INTSRC_NO_ACK, //!< NACK interrupt I2C_INTSRC_REG_ACCESS_RDY, //!< Register-access-ready interrupt I2C_INTSRC_RX_DATA_RDY, //!< Receive-data-ready interrupt I2C_INTSRC_TX_DATA_RDY, //!< Transmit-data-ready interrupt I2C_INTSRC_STOP_CONDITION, //!< Stop condition detected I2C_INTSRC_ADDR_TARGET //!< Addressed as target interrupt } I2C_InterruptSource; //***************************************************************************** // //! Values that can be passed to I2C_setFIFOInterruptLevel() as the \e txLevel //! parameter, returned by I2C_getFIFOInterruptLevel() in the \e txLevel //! parameter, and returned by I2C_getTxFIFOStatus(). // //***************************************************************************** typedef enum { I2C_FIFO_TXEMPTY = 0x0000U, //!< Transmit FIFO empty I2C_FIFO_TX0 = 0x0000U, //!< Transmit FIFO empty I2C_FIFO_TX1 = 0x0001U, //!< Transmit FIFO 1/16 full I2C_FIFO_TX2 = 0x0002U, //!< Transmit FIFO 2/16 full I2C_FIFO_TX3 = 0x0003U, //!< Transmit FIFO 3/16 full I2C_FIFO_TX4 = 0x0004U, //!< Transmit FIFO 4/16 full I2C_FIFO_TX5 = 0x0005U, //!< Transmit FIFO 5/16 full I2C_FIFO_TX6 = 0x0006U, //!< Transmit FIFO 6/16 full I2C_FIFO_TX7 = 0x0007U, //!< Transmit FIFO 7/16 full I2C_FIFO_TX8 = 0x0008U, //!< Transmit FIFO 8/16 full I2C_FIFO_TX9 = 0x0009U, //!< Transmit FIFO 9/16 full I2C_FIFO_TX10 = 0x000AU, //!< Transmit FIFO 10/16 full I2C_FIFO_TX11 = 0x000BU, //!< Transmit FIFO 11/16 full I2C_FIFO_TX12 = 0x000CU, //!< Transmit FIFO 12/16 full I2C_FIFO_TX13 = 0x000DU, //!< Transmit FIFO 13/16 full I2C_FIFO_TX14 = 0x000EU, //!< Transmit FIFO 14/16 full I2C_FIFO_TX15 = 0x000FU, //!< Transmit FIFO 15/16 full I2C_FIFO_TX16 = 0x0010U, //!< Transmit FIFO full I2C_FIFO_TXFULL = 0x0010U //!< Transmit FIFO full } I2C_TxFIFOLevel; //***************************************************************************** // //! Values that can be passed to I2C_setFIFOInterruptLevel() as the \e rxLevel //! parameter, returned by I2C_getFIFOInterruptLevel() in the \e rxLevel //! parameter, and returned by I2C_getRxFIFOStatus(). // //***************************************************************************** typedef enum { I2C_FIFO_RXEMPTY = 0x0000U, //!< Receive FIFO empty I2C_FIFO_RX0 = 0x0000U, //!< Receive FIFO empty I2C_FIFO_RX1 = 0x0001U, //!< Receive FIFO 1/16 full I2C_FIFO_RX2 = 0x0002U, //!< Receive FIFO 2/16 full I2C_FIFO_RX3 = 0x0003U, //!< Receive FIFO 3/16 full I2C_FIFO_RX4 = 0x0004U, //!< Receive FIFO 4/16 full I2C_FIFO_RX5 = 0x0005U, //!< Receive FIFO 5/16 full I2C_FIFO_RX6 = 0x0006U, //!< Receive FIFO 6/16 full I2C_FIFO_RX7 = 0x0007U, //!< Receive FIFO 7/16 full I2C_FIFO_RX8 = 0x0008U, //!< Receive FIFO 8/16 full I2C_FIFO_RX9 = 0x0009U, //!< Receive FIFO 9/16 full I2C_FIFO_RX10 = 0x000AU, //!< Receive FIFO 10/16 full I2C_FIFO_RX11 = 0x000BU, //!< Receive FIFO 11/16 full I2C_FIFO_RX12 = 0x000CU, //!< Receive FIFO 12/16 full I2C_FIFO_RX13 = 0x000DU, //!< Receive FIFO 13/16 full I2C_FIFO_RX14 = 0x000EU, //!< Receive FIFO 14/16 full I2C_FIFO_RX15 = 0x000FU, //!< Receive FIFO 15/16 full I2C_FIFO_RX16 = 0x0010U, //!< Receive FIFO full I2C_FIFO_RXFULL = 0x0010U //!< Receive FIFO full } I2C_RxFIFOLevel; //***************************************************************************** // //! Values that can be passed to I2C_setBitCount() as the \e size parameter. // //***************************************************************************** typedef enum { I2C_BITCOUNT_1 = 1U, //!< 1 bit per data byte I2C_BITCOUNT_2 = 2U, //!< 2 bits per data byte I2C_BITCOUNT_3 = 3U, //!< 3 bits per data byte I2C_BITCOUNT_4 = 4U, //!< 4 bits per data byte I2C_BITCOUNT_5 = 5U, //!< 5 bits per data byte I2C_BITCOUNT_6 = 6U, //!< 6 bits per data byte I2C_BITCOUNT_7 = 7U, //!< 7 bits per data byte I2C_BITCOUNT_8 = 0U //!< 8 bits per data byte } I2C_BitCount; //***************************************************************************** // //! Values that can be passed to I2C_setAddressMode() as the \e mode parameter. // //***************************************************************************** typedef enum { I2C_ADDR_MODE_7BITS = 0x0000U, //!< 7-bit address I2C_ADDR_MODE_10BITS = 0x0100U //!< 10-bit address } I2C_AddressMode; //***************************************************************************** // //! Values that can be passed to I2C_setEmulationMode() as the \e mode //! parameter. // //***************************************************************************** typedef enum { //! If SCL is low, keep it low. If high, stop when it goes low again. I2C_EMULATION_STOP_SCL_LOW = 0x0000U, //! Continue I2C operation regardless I2C_EMULATION_FREE_RUN = 0x4000U } I2C_EmulationMode; //***************************************************************************** // //! Values that can be passed to I2C_initController() as the \e dutyCycle //! parameter. // //***************************************************************************** typedef enum { I2C_DUTYCYCLE_33, //!< Clock duty cycle is 33% I2C_DUTYCYCLE_50 //!< Clock duty cycle is 55% } I2C_DutyCycle; //***************************************************************************** // // Prototypes for the APIs. // //***************************************************************************** //***************************************************************************** // //! \internal //! Checks an I2C base address. //! //! \param base is the base address of the I2C instance used. //! //! This function determines if a I2C module base address is valid. //! //! \return Returns \b true if the base address is valid and \b false //! otherwise. // //***************************************************************************** #ifdef DEBUG static inline bool I2C_isBaseValid(uint32_t base) { return( (base == I2CA_BASE) || (base == I2CB_BASE) ); } #endif //***************************************************************************** // //! Enables the I2C module. //! //! \param base is the base address of the I2C instance used. //! //! This function enables operation of the I2C module. //! //! \return None. // //***************************************************************************** static inline void I2C_enableModule(uint32_t base) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); HWREGH(base + I2C_O_MDR) |= I2C_MDR_IRS; } //***************************************************************************** // //! Disables the I2C module. //! //! \param base is the base address of the I2C instance used. //! //! This function disables operation of the I2C module. //! //! \return None. // //***************************************************************************** static inline void I2C_disableModule(uint32_t base) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); HWREGH(base + I2C_O_MDR) &= ~(I2C_MDR_IRS); } //***************************************************************************** // //! Enables the transmit and receive FIFOs. //! //! \param base is the base address of the I2C instance used. //! //! This functions enables the transmit and receive FIFOs in the I2C. //! //! \return None. // //***************************************************************************** static inline void I2C_enableFIFO(uint32_t base) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Enable the FIFO. // HWREGH(base + I2C_O_FFTX) |= I2C_FFTX_I2CFFEN | I2C_FFTX_TXFFRST; HWREGH(base + I2C_O_FFRX) |= I2C_FFRX_RXFFRST; } //***************************************************************************** // //! Disables the transmit and receive FIFOs. //! //! \param base is the base address of the I2C instance used. //! //! This functions disables the transmit and receive FIFOs in the I2C. //! //! \return None. // //***************************************************************************** static inline void I2C_disableFIFO(uint32_t base) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Disable the FIFO. // HWREGH(base + I2C_O_FFTX) &= ~(I2C_FFTX_I2CFFEN | I2C_FFTX_TXFFRST); HWREGH(base + I2C_O_FFRX) &= ~I2C_FFRX_RXFFRST; } //***************************************************************************** // //! Sets the FIFO level at which interrupts are generated. //! //! \param base is the base address of the I2C instance used. //! \param txLevel is the transmit FIFO interrupt level, specified as //! \b I2C_FIFO_TX0, \b I2C_FIFO_TX1, \b I2C_FIFO_TX2, . . . or //! \b I2C_FIFO_TX16. //! \param rxLevel is the receive FIFO interrupt level, specified as //! \b I2C_FIFO_RX0, \b I2C_FIFO_RX1, \b I2C_FIFO_RX2, . . . or //! \b I2C_FIFO_RX16. //! //! This function sets the FIFO level at which transmit and receive interrupts //! are generated. The transmit FIFO interrupt flag will be set when the FIFO //! reaches a value less than or equal to \e txLevel. The receive FIFO //! flag will be set when the FIFO reaches a value greater than or equal to //! \e rxLevel. //! //! \return None. // //***************************************************************************** static inline void I2C_setFIFOInterruptLevel(uint32_t base, I2C_TxFIFOLevel txLevel, I2C_RxFIFOLevel rxLevel) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Set the FIFO interrupt levels. // HWREGH(base + I2C_O_FFTX) = (HWREGH(base + I2C_O_FFTX) & (~I2C_FFTX_TXFFIL_M)) | (uint16_t)txLevel; HWREGH(base + I2C_O_FFRX) = (HWREGH(base + I2C_O_FFRX) & (~I2C_FFRX_RXFFIL_M)) | (uint16_t)rxLevel; } //***************************************************************************** // //! Gets the FIFO level at which interrupts are generated. //! //! \param base is the base address of the I2C instance used. //! \param txLevel is a pointer to storage for the transmit FIFO level, //! returned as one of \b I2C_FIFO_TX0, \b I2C_FIFO_TX1, //! \b I2C_FIFO_TX2, . . . or \b I2C_FIFO_TX16. //! \param rxLevel is a pointer to storage for the receive FIFO level, //! returned as one of \b I2C_FIFO_RX0, \b I2C_FIFO_RX1, //! \b I2C_FIFO_RX2, . . . or \b I2C_FIFO_RX16. //! //! This function gets the FIFO level at which transmit and receive interrupts //! are generated. The transmit FIFO interrupt flag will be set when the FIFO //! reaches a value less than or equal to \e txLevel. The receive FIFO //! flag will be set when the FIFO reaches a value greater than or equal to //! \e rxLevel. //! //! \return None. // //***************************************************************************** static inline void I2C_getFIFOInterruptLevel(uint32_t base, I2C_TxFIFOLevel *txLevel, I2C_RxFIFOLevel *rxLevel) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Extract the transmit and receive FIFO levels. // *txLevel = (I2C_TxFIFOLevel)(HWREGH(base + I2C_O_FFTX) & I2C_FFTX_TXFFIL_M); *rxLevel = (I2C_RxFIFOLevel)(HWREGH(base + I2C_O_FFRX) & I2C_FFRX_RXFFIL_M); } //***************************************************************************** // //! Get the transmit FIFO status //! //! \param base is the base address of the I2C instance used. //! //! This function gets the current number of words in the transmit FIFO. //! //! \return Returns the current number of words in the transmit FIFO specified //! as one of the following: //! \b I2C_FIFO_TX0, \b I2C_FIFO_TX1, \b I2C_FIFO_TX2, \b I2C_FIFO_TX3, //! ..., or \b I2C_FIFO_TX16 // //***************************************************************************** static inline I2C_TxFIFOLevel I2C_getTxFIFOStatus(uint32_t base) { uint16_t level; // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Get the current FIFO status // level = ((HWREGH(base + I2C_O_FFTX) & I2C_FFTX_TXFFST_M) >> I2C_FFTX_TXFFST_S); return((I2C_TxFIFOLevel)level); } //***************************************************************************** // //! Get the receive FIFO status //! //! \param base is the base address of the I2C instance used. //! //! This function gets the current number of words in the receive FIFO. //! //! \return Returns the current number of words in the receive FIFO specified //! as one of the following: //! \b I2C_FIFO_RX0, \b I2C_FIFO_RX1, \b I2C_FIFO_RX2, \b I2C_FIFO_RX3, //! ..., or \b I2C_FIFO_RX16 // //***************************************************************************** static inline I2C_RxFIFOLevel I2C_getRxFIFOStatus(uint32_t base) { uint16_t level; // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Get the current FIFO status // level = ((HWREGH(base + I2C_O_FFRX) & I2C_FFRX_RXFFST_M) >> I2C_FFRX_RXFFST_S); return((I2C_RxFIFOLevel)level); } //***************************************************************************** // //! Reads I2C Module clock prescaler value. //! //! \param base is the base address of the I2C instance used. //! //! This function reads the I2C prescaler value which configures the I2C module //! clock by dividing down the SYSCLK. I2C_MODULE_CLK = SYSCLK / (I2CPSC + ) //! //! \return Returns the I2C prescaler(I2CPSC) cast as an uint16_t. // //***************************************************************************** static inline uint16_t I2C_getPreScaler(uint32_t base) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Return the contents of the Prescaler register. // return(HWREGH(base + I2C_O_PSC)); } //***************************************************************************** // //! Sets the address that the I2C Controller places on the bus. //! //! \param base is the base address of the I2C instance used. //! \param targetAddr 7-bit or 10-bit target address //! //! This function configures the address that the I2C Controller places on the bus //! when initiating a transaction. //! //! \return None. // //***************************************************************************** static inline void I2C_setTargetAddress(uint32_t base, uint16_t targetAddr) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); ASSERT(targetAddr <= I2C_TAR_TAR_M); HWREGH(base + I2C_O_TAR) = targetAddr; } //***************************************************************************** // //! Sets the own address for this I2C module. //! //! \param base is the base address of the I2C Target module. //! \param Addr is the 7-bit or 10-bit address //! //! This function writes the specified address. //! //! The parameter \e Addr is the value that is compared against the //! target address sent by an I2C controller. //! //! \return None. // //***************************************************************************** static inline void I2C_setOwnAddress(uint32_t base, uint16_t Addr) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); ASSERT(Addr <= I2C_OAR_OAR_M); HWREGH(base + I2C_O_OAR) = Addr; } //***************************************************************************** // //! Indicates whether or not the I2C bus is busy. //! //! \param base is the base address of the I2C instance used. //! //! This function returns an indication of whether or not the I2C bus is busy. //! This function can be used in a multi-controller environment to determine if the //! bus is free for another data transfer. //! //! \return Returns \b true if the I2C bus is busy; otherwise, returns //! \b false. // //***************************************************************************** static inline bool I2C_isBusBusy(uint32_t base) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); return((HWREGH(base + I2C_O_STR) & I2C_STR_BB) == I2C_STR_BB); } //***************************************************************************** // //! Gets the current I2C module status. //! //! \param base is the base address of the I2C instance used. //! //! This function returns the status for the I2C module. //! //! \return The current module status, enumerated as a bit field of //! - \b I2C_STS_ARB_LOST - Arbitration-lost //! - \b I2C_STS_NO_ACK - No-acknowledgment (NACK) //! - \b I2C_STS_REG_ACCESS_RDY - Register-access-ready (ARDY) //! - \b I2C_STS_RX_DATA_RDY - Receive-data-ready //! - \b I2C_STS_TX_DATA_RDY - Transmit-data-ready //! - \b I2C_STS_STOP_CONDITION - Stop condition detected //! - \b I2C_STS_ADDR_ZERO - Address of all zeros detected //! - \b I2C_STS_ADDR_TARGET - Addressed as Target //! - \b I2C_STS_TX_EMPTY - Transmit shift register empty //! - \b I2C_STS_RX_FULL - Receive shift register full //! - \b I2C_STS_BUS_BUSY - Bus busy, wait for STOP or reset //! - \b I2C_STS_NACK_SENT - NACK was sent //! - \b I2C_STS_TARGET_DIR- Addressed as Target transmitter // //***************************************************************************** static inline uint16_t I2C_getStatus(uint32_t base) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Return contents of the status register // return(HWREGH(base + I2C_O_STR)); } //***************************************************************************** // //! Clears I2C status flags. //! //! \param base is the base address of the I2C instance used. //! \param stsFlags is a bit mask of the status flags to be cleared. //! //! This function clears the specified I2C status flags. The \e stsFlags //! parameter is the logical OR of the following values: //! - \b I2C_STS_ARB_LOST //! - \b I2C_STS_NO_ACK, //! - \b I2C_STS_REG_ACCESS_RDY //! - \b I2C_STS_RX_DATA_RDY //! - \b I2C_STS_STOP_CONDITION //! - \b I2C_STS_NACK_SENT //! - \b I2C_STS_TARGET_DIR //! //! \note Note that some of the status flags returned by I2C_getStatus() cannot //! be cleared by this function. Some may only be cleared by hardware or a //! reset of the I2C module. //! //! \return None. // //***************************************************************************** static inline void I2C_clearStatus(uint32_t base, uint16_t stsFlags) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Write to the status registers to clear them. // HWREGH(base + I2C_O_STR) = stsFlags; } //***************************************************************************** // //! Controls the state of the I2C module. //! //! \param base is the base address of the I2C instance used. //! \param config is the command to be issued to the I2C module. //! //! This function is used to control the state of the controller and target send and //! receive operations. The \e config is a logical OR of the following options. //! //! One of the following four options: //! - \b I2C_CONTROLLER_SEND_MODE - Controller-transmitter mode //! - \b I2C_CONTROLLER_RECEIVE_MODE - Controller-receiver mode //! - \b I2C_TARGET_SEND_MODE - Target-transmitter mode //! - \b I2C_TARGET_RECEIVE_MODE - Target-receiver mode //! //! Any of the following: //! - \b I2C_REPEAT_MODE - Sends data until stop bit is set, ignores data count //! - \b I2C_START_BYTE_MODE - Use start byte mode //! - \b I2C_FREE_DATA_FORMAT - Use free data format, transfers have no address //! //! \return None. // //***************************************************************************** static inline void I2C_setConfig(uint32_t base, uint16_t config) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Write the selected options to the mode register. // HWREGH(base + I2C_O_MDR) = (HWREGH(base + I2C_O_MDR) & ~(I2C_MDR_CNT | I2C_MDR_TRX | I2C_MDR_RM | I2C_MDR_STB | I2C_MDR_FDF)) | config; } //***************************************************************************** // //! Sets the data byte bit count the I2C module. //! //! \param base is the base address of the I2C instance used. //! \param size is the number of bits per data byte. //! //! The \e size parameter is a value I2C_BITCOUNT_x where x is the number of //! bits per data byte. The default and maximum size is 8 bits. //! //! \return None. // //***************************************************************************** static inline void I2C_setBitCount(uint32_t base, I2C_BitCount size) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Write the selected options to the mode register. // HWREGH(base + I2C_O_MDR) = (HWREGH(base + I2C_O_MDR) & ~I2C_MDR_BC_M) | (uint16_t)size; } //***************************************************************************** // //! Issues an I2C START condition. //! //! \param base is the base address of the I2C instance used. //! //! This function causes the I2C module to generate a start condition. This //! function is only valid when the I2C module specified by the \b base //! parameter is a controller. //! //! \return None. // //***************************************************************************** static inline void I2C_sendStartCondition(uint32_t base) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Set the START condition bit. // HWREGH(base + I2C_O_MDR) |= I2C_MDR_STT; } //***************************************************************************** // //! Issues an I2C STOP condition. //! //! \param base is the base address of the I2C instance used. //! //! This function causes the I2C module to generate a stop condition. This //! function is only valid when the I2C module specified by the \b base //! parameter is a controller. //! //! To check on the status of the STOP condition, I2C_getStopConditionStatus() //! can be used. //! //! \return None. // //***************************************************************************** static inline void I2C_sendStopCondition(uint32_t base) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Set the STOP condition bit. // HWREGH(base + I2C_O_MDR) |= I2C_MDR_STP; } //***************************************************************************** // //! Issues a no-acknowledge (NACK) bit. //! //! \param base is the base address of the I2C instance used. //! //! This function causes the I2C module to generate a NACK bit. This is only //! applicable when the I2C module is acting as a receiver. //! //! \return None. // //***************************************************************************** static inline void I2C_sendNACK(uint32_t base) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Set the NACK mode bit. // HWREGH(base + I2C_O_MDR) |= I2C_MDR_NACKMOD; } //***************************************************************************** // //! Receives a byte that has been sent to the I2C. //! //! \param base is the base address of the I2C instance used. //! //! This function reads a byte of data from the I2C Data Receive Register. //! //! \return Returns the byte received from by the I2C cast as an uint16_t. // //***************************************************************************** static inline uint16_t I2C_getData(uint32_t base) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Return the contents of the receive register. // return(HWREGH(base + I2C_O_DRR)); } //***************************************************************************** // //! Transmits a byte from the I2C. //! //! \param base is the base address of the I2C instance used. //! \param data is the data to be transmitted from the I2C Controller. //! //! This function places the supplied data into I2C Data Transmit Register. //! //! \return None. // //***************************************************************************** static inline void I2C_putData(uint32_t base, uint16_t data) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Place the data into the transmit register. // HWREGH(base + I2C_O_DXR) = data; } //***************************************************************************** // //! Get stop condition status. //! //! \param base is the base address of the I2C instance used. //! //! This function reads and returns the stop condition bit status. //! //! \return Returns \b true if the STP bit has been set by the device to //! generate a stop condition when the internal data counter of the I2C module //! has reached 0. Returns \b false when the STP bit is zero. This bit is //! automatically cleared after the stop condition has been generated. // //***************************************************************************** static inline bool I2C_getStopConditionStatus(uint32_t base) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Check the stop condition bit and return appropriately. // return((HWREGH(base + I2C_O_MDR) & I2C_MDR_STP) != 0U); } //***************************************************************************** // //! Set number of bytes to be to transfer or receive when repeat mode is off. //! //! \param base is the base address of the I2C instance used. //! \param count is the value to be put in the I2C data count register. //! //! This function sets the number of bytes to transfer or receive when repeat //! mode is off. //! //! \return None. // //***************************************************************************** static inline void I2C_setDataCount(uint32_t base, uint16_t count) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Write the count value to the appropriate register. // HWREGH(base + I2C_O_CNT) = count; } //***************************************************************************** // //! Sets the addressing mode to either 7-bit or 10-bit. //! //! \param base is the base address of the I2C instance used. //! \param mode is the address mode, 7-bit or 10-bit. //! //! This function configures the I2C module for either a 7-bit address //! (default) or a 10-bit address. The \e mode parameter configures the address //! length to 10 bits when its value is \b I2C_ADDR_MODE_10BITS and 7 bits when //! \b I2C_ADDR_MODE_7BITS. //! //! \return None. // //***************************************************************************** static inline void I2C_setAddressMode(uint32_t base, I2C_AddressMode mode) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Write the appropriate value to the address expansion bit. // HWREGH(base + I2C_O_MDR) = (HWREGH(base + I2C_O_MDR) & ~I2C_MDR_XA) | (uint16_t)mode; } //***************************************************************************** // //! Sets I2C emulation mode. //! //! \param base is the base address of the I2C instance used. //! \param mode is the emulation mode. //! //! This function sets the behavior of the I2C operation when an emulation //! suspend occurs. The \e mode parameter can be one of the following: //! //! - \b I2C_EMULATION_STOP_SCL_LOW - If SCL is low when the breakpoint occurs, //! the I2C module stops immediately. If SCL is high, the I2C module waits //! until SCL becomes low and then stops. //! - \b I2C_EMULATION_FREE_RUN - I2C operation continues regardless of a //! the suspend. //! //! \return None. // //***************************************************************************** static inline void I2C_setEmulationMode(uint32_t base, I2C_EmulationMode mode) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Write the desired emulation mode to the register. // HWREGH(base + I2C_O_MDR) = (HWREGH(base + I2C_O_MDR) & ~I2C_MDR_FREE) | (uint16_t)mode; } //***************************************************************************** // //! Enables I2C loopback mode. //! //! \param base is the base address of the I2C instance used. //! //! This function enables loopback mode. This mode is only valid during controller //! mode and is helpful during device testing as it causes data transmitted out //! of the data transmit register to be received in data receive register. //! //! \return None. // //***************************************************************************** static inline void I2C_enableLoopback(uint32_t base) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Set the bit that enables loopback mode. // HWREGH(base + I2C_O_MDR) |= I2C_MDR_DLB; } //***************************************************************************** // //! Disables I2C loopback mode. //! //! \param base is the base address of the I2C instance used. //! //! This function disables loopback mode. Loopback mode is disabled by default //! after reset. //! //! \return None. // //***************************************************************************** static inline void I2C_disableLoopback(uint32_t base) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Clear the bit that enables loopback mode. // HWREGH(base + I2C_O_MDR) &= ~I2C_MDR_DLB; } //***************************************************************************** // //! Returns the current I2C interrupt source. //! //! \param base is the base address of the I2C instance used. //! //! This function returns the event that generated an I2C basic (non-FIFO) //! interrupt. The possible sources are the following: //! - \b I2C_INTSRC_NONE //! - \b I2C_INTSRC_ARB_LOST //! - \b I2C_INTSRC_NO_ACK //! - \b I2C_INTSRC_REG_ACCESS_RDY //! - \b I2C_INTSRC_RX_DATA_RDY //! - \b I2C_INTSRC_TX_DATA_RDY //! - \b I2C_INTSRC_STOP_CONDITION //! - \b I2C_INTSRC_ADDR_TARGET //! //! Calling this function will result in hardware automatically clearing the //! current interrupt code and if ready, loading the next pending enabled //! interrupt. It will also clear the corresponding interrupt flag if the //! source is \b I2C_INTSRC_ARB_LOST, \b I2C_INTSRC_NO_ACK, or //! \b I2C_INTSRC_STOP_CONDITION. //! //! \note Note that this function differs from I2C_getInterruptStatus() in that //! it returns a single interrupt source. I2C_getInterruptSource() will return //! the status of all interrupt flags possible, including the flags that aren't //! necessarily enabled to generate interrupts. //! //! \return None. // //***************************************************************************** static inline I2C_InterruptSource I2C_getInterruptSource(uint32_t base) { // // Check the arguments. // ASSERT(I2C_isBaseValid(base)); // // Return the interrupt source value // return((I2C_InterruptSource)(HWREGH(base + I2C_O_ISRC) & I2C_ISRC_INTCODE_M)); } //***************************************************************************** // //! Initializes the I2C Controller. //! //! \param base is the base address of the I2C instance used. //! \param sysclkHz is the rate of the clock supplied to the I2C module //! (SYSCLK) in Hz. //! \param bitRate is the rate of the controller clock signal, SCL. //! \param dutyCycle is duty cycle of the SCL signal. //! //! This function initializes operation of the I2C Controller by configuring the //! bus speed for the controller. Note that the I2C module \b must be put into //! reset before calling this function. You can do this with the function //! I2C_disableModule(). //! //! A programmable prescaler in the I2C module divides down the input clock //! (rate specified by \e sysclkHz) to produce the module clock (calculated to //! be around 10 MHz in this function). That clock is then divided down further //! to configure the SCL signal to run at the rate specified by \e bitRate. The //! \e dutyCycle parameter determines the percentage of time high and time low //! on the clock signal. The valid values are \b I2C_DUTYCYCLE_33 for 33% and //! \b I2C_DUTYCYCLE_50 for 50%. //! //! The peripheral clock is the system clock. This value is returned by //! SysCtl_getClock(), or it can be explicitly hard coded if it is //! constant and known (to save the code/execution overhead of a call to //! SysCtl_getClock()). //! //! \return None. // //***************************************************************************** extern void I2C_initController(uint32_t base, uint32_t sysclkHz, uint32_t bitRate, I2C_DutyCycle dutyCycle); //***************************************************************************** // //! Enables I2C interrupt sources. //! //! \param base is the base address of the I2C instance used. //! \param intFlags is the bit mask of the interrupt sources to be enabled. //! //! This function enables the indicated I2C Controller interrupt sources. Only the //! sources that are enabled can be reflected to the processor interrupt. //! Disabled sources have no effect on the processor. //! //! The \e intFlags parameter is the logical OR of any of the following: //! //! - \b I2C_INT_ARB_LOST - Arbitration-lost interrupt //! - \b I2C_INT_NO_ACK - No-acknowledgment (NACK) interrupt //! - \b I2C_INT_REG_ACCESS_RDY - Register-access-ready interrupt //! - \b I2C_INT_RX_DATA_RDY - Receive-data-ready interrupt //! - \b I2C_INT_TX_DATA_RDY - Transmit-data-ready interrupt //! - \b I2C_INT_STOP_CONDITION - Stop condition detected //! - \b I2C_INT_ADDR_TARGET - Addressed as target interrupt //! - \b I2C_INT_RXFF - RX FIFO level interrupt //! - \b I2C_INT_TXFF - TX FIFO level interrupt //! //! \note \b I2C_INT_RXFF and \b I2C_INT_TXFF are associated with the I2C FIFO //! interrupt vector. All others are associated with the I2C basic interrupt. //! //! \return None. // //***************************************************************************** extern void I2C_enableInterrupt(uint32_t base, uint32_t intFlags); //***************************************************************************** // //! Disables I2C interrupt sources. //! //! \param base is the base address of the I2C instance used. //! \param intFlags is the bit mask of the interrupt sources to be disabled. //! //! This function disables the indicated I2C Target interrupt sources. Only //! the sources that are enabled can be reflected to the processor interrupt. //! Disabled sources have no effect on the processor. //! //! The \e intFlags parameter has the same definition as the \e intFlags //! parameter to I2C_enableInterrupt(). //! //! \return None. // //***************************************************************************** extern void I2C_disableInterrupt(uint32_t base, uint32_t intFlags); //***************************************************************************** // //! Gets the current I2C interrupt status. //! //! \param base is the base address of the I2C instance used. //! //! This function returns the interrupt status for the I2C module. //! //! \return The current interrupt status, enumerated as a bit field of //! - \b I2C_INT_ARB_LOST //! - \b I2C_INT_NO_ACK //! - \b I2C_INT_REG_ACCESS_RDY //! - \b I2C_INT_RX_DATA_RDY //! - \b I2C_INT_TX_DATA_RDY //! - \b I2C_INT_STOP_CONDITION //! - \b I2C_INT_ADDR_TARGET //! - \b I2C_INT_RXFF //! - \b I2C_INT_TXFF //! //! \note This function will only return the status flags associated with //! interrupts. However, a flag may be set even if its corresponding interrupt //! is disabled. // //***************************************************************************** extern uint32_t I2C_getInterruptStatus(uint32_t base); //***************************************************************************** // //! Clears I2C interrupt sources. //! //! \param base is the base address of the I2C instance used. //! \param intFlags is a bit mask of the interrupt sources to be cleared. //! //! The specified I2C interrupt sources are cleared, so that they no longer //! assert. This function must be called in the interrupt handler to keep the //! interrupt from being triggered again immediately upon exit. //! //! The \e intFlags parameter has the same definition as the \e intFlags //! parameter to I2C_enableInterrupt(). //! //! \note \b I2C_INT_RXFF and \b I2C_INT_TXFF are associated with the I2C FIFO //! interrupt vector. All others are associated with the I2C basic interrupt. //! //! \note Also note that some of the status flags returned by //! I2C_getInterruptStatus() cannot be cleared by this function. Some may only //! be cleared by hardware or a reset of the I2C module. //! //! \return None. // //***************************************************************************** extern void I2C_clearInterruptStatus(uint32_t base, uint32_t intFlags); //***************************************************************************** // //! Configures I2C Module Clock Frequency //! //! \param base is the base address of the I2C instance used. //! \param sysclkHz is the rate of the clock supplied to the I2C module //! (SYSCLK) in Hz. //! //! This function configures I2C module clock frequency by initializing //! prescale register based on SYSCLK frequency. //! Note that the I2C module \b must be put into //! reset before calling this function. You can do this with the function //! I2C_disableModule(). //! //! \return None. // //***************************************************************************** extern void I2C_configureModuleFrequency(uint32_t base, uint32_t sysclkHz); //***************************************************************************** // // Close the Doxygen group. //! @} // //***************************************************************************** //***************************************************************************** // // Mark the end of the C bindings section for C++ compilers. // //***************************************************************************** #ifdef __cplusplus } #endif #endif // I2C_H