NOTICE: The Processors Wiki will End-of-Life on January 15, 2021. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.

Software - MAVRK I2C Bus Functions

From Texas Instruments Wiki
Jump to: navigation, search
MAVRK Banner.png

MAVRK is no longer an active TI evaluation platform. Please contact TI application support if you need further information on TI products or support.

This page is up to date and active. Please feel free to contribute or make improvements.

MAVRK I2C Bus Basics[edit]

There is a single physical I2C bus on the MAVRK MB-PRO-MVK motherboard connected to each motherboard slot including MAVRK_RF(1-4),  MAVRK_AFE(1-4), MAVRK_SCI(1-4), MAVRK_PMU and MAVRK_MCU. MAVRK software provides I2C functions written in C, to communicate with components on MAVRK modules installed in motherboard slots. MAVRK software provides I2C Master Mode Driver functions which support device slave address and MAVRK motherboard device_slot parameters in all functions. 100KHz and 400Khz Clock Rate as well as 7 and 10 Bit Address Mode settings are also supported on a per motherboard device slot basis. I2C bus signals SCL and SDA are pulled up to 3.3V via resistor by the MCU module installed in the MAVRK MCU slot on the MB-PRO-MVK motherboard.  

For a more detailed discussion of I2C bus protocol, see Wikipedia's Inter-Integrated Circuit(I2C) Interface Bus.

Initializing the I2C function in MAVRK[edit]

mvk_Init_MAVRK_Standard_Settings( ) is first MAVRK  function called in every in  main.c of a MAVRK application. This function initializes the installed MAVRK MCU Power Management, internal clock rates,  I/O ports and all communication ports including I2C to default settings. Basic I2C port initialization is performed by calling the functons listed below:

  • mvk_Init_I2C_Ports() - Initializes the MCU I2C Bus I/O signal pins to the required configuration 
  • mvk_Init_I2C_Functions() - Initializes MAVRK software data structures used in management of I2C communication including interrupt processing 
  • mvk_Configure_I2C_Device_Working_Settings() - Configures the default I2C Address Mode and Clock Rate for all MB-PRO-MVK motherboard device slots

The user can specify I2C settings different from the mvk_Init_MAVRK_Standard_Settings( ) defaults by calling mvk_Configure_I2C_Device_Working_Settings()  with different values. The I2C working settings are stored for each device slot and are re-applied to MCU I2C hardware control registers by the MAVRK software prior to each I2C bus communication.

MAVRK I2C Master Mode Functions[edit]

Standard I2C communications are performed using the following commands:

  • mvk_Write_I2C() - Writes one or more bytes of data 
  • mvk_Read_Register_I2C() -  Writes a single register address to the I2C slave device, signals an I2C Restart,  then reads one or more bytes from the slave device.
  • mvk_Read_Register_Use_Stop_I2C() - Similar to mvk_Read_Register_I2C() , except an I2C stop is signaled instead of a Restart. Some slave devices will not work after a signaled Restart.
  • mvk_Write_Restart_Read_I2C() - Writes one or more bytes of data to set a single byte register address or a multi-byte memory address for I2C data storage devices. An I2C Restart is then signaled and one or more bytes of data are read beginning with the specified register or memory address.
  • mvk_Write_Stop_Read_I2C() - Similar to mvk_Write_Restart_Read_I2C(),  except a Stop condition is signaled  at the end of the Write activity before the I2C Start is signaled at the beginning of an I2C Read.  This function was created because some slave devices cannot be read successfully unless there is Stop Condition followed by a Start Condition between Write and Read portions of the I2C bus activity.
  • mvk_Read_I2C() -  Reads one or more bytes from an I2C slave device. This function is used when data must be read directly from a slave device without a preceding write of a register address.

These above I2C functions require user specified parameters including device slave address, device register address, MAVRK motherboard device slot,  write and read data buffer pointers and the number of bytes to be to to be written/read to or from the I2C slave device. MAVRK software automatically handles the configuration of the I2C bus prior to communications using settings provided during initialization. MAVRK Module Select control lines are activated when  required, based on the user provided MAVRK motherboard device slot.

Example Code
[edit]

Example of mvk_I2C_Write writing one byte to a slave device register:

mvk_I2C_Write() prototype can be found in I2C_Functions.h
unsigned char mvk_Write_I2C (unsigned int I2C_device_address,
                             unsigned char device_slot,
                             unsigned char* I2C_write_data,
                             unsigned char num_write_bytes);
---------------------------------------------------------------

// I2C Slave address and register definitions can be found in the MAVRK Library Component header files
#define ANY_PART_I2C_SLAVE_ADDRESS               0x34       
#define ANY_PART_CONFIGURATION_REGISTER_ADDRESS  0x1D   // 29(Decimal)
#define I2C_2_BYTES 2


void my_sample_code (void)
{
    unsigned char errChk;
    unsigned char device_slot = MAVRK_RF1;
    unsigned char I2C_write_data[I2C_2_BYTES];
 
    I2C_write_data[0] = ANY_PART_CONFIGURATION_REGISTER_ADDRESS;
    I2C_write_data[1] = 0xDF;  // 223(Decimal)
 
    errChk = mvk_Write_I2C (ANY_PART_I2C_SLAVE_ADDRESS, device_slot, I2C_write_data, I2C_2_BYTES);
    if (errChk != I2C_OPERATION_SUCCESSFUL)
    {
        mvk_Error_Trap (0x01, errChk, ERROR_HIGH_LEVEL);
    }  

}                              

Executing the mvk_I2C_Write() code above generates the I2C waveform shown below:

MAVRK SW I2C Write 1ByteTrace.png

                                                           S=Start Condition    W=Write Command       A=Acknowledge/ACK       N=Not Acknowledged/NACK    P=Stop Condition



Example of mvk_Read_Register_I2C reading one register byte:

mvk_Read_Register_I2C() prototype can be found in I2C_Functions.h
unsigned char mvk_Read_Register_I2C (unsigned int I2C_device_address,
                                     unsigned char I2C_register_address,
                                     unsigned char device_slot,
                                     unsigned char* I2C_read_data,
                                     unsigned char num_read_bytes);
-------------------------------------------------------------------------

// I2C Slave address and register definitions can be found in the MAVRK Library Component header files
#define ANY_PART_I2C_SLAVE_ADDRESS               0x34       
#define ANY_PART_CONFIGURATION_REGISTER_ADDRESS  0x1D  // 29(Decimal)
#define I2C_1_BYTE 1

void my_sample_code (void)
{
    unsigned char errChk;
    unsigned char device_slot = MAVRK_RF1;
    unsigned char I2C_read_data;
 
    errChk = mvk_Read_Register_I2C (ANY_PART_I2C_SLAVE_ADDRESS,
                                    ANY_PART_CONFIGURATION_REGISTER_ADDRESS,
                                    device_slot, 
                                    &I2C_read_data, 
                                    I2C_1_BYTE);
    
    if (errChk != I2C_OPERATION_SUCCESSFUL)
    {
        mvk_Error_Trap (0x01, errChk, ERROR_HIGH_LEVEL);
    }  
}
 

Executing the mvk_Read_Register_I2C() code above generates the I2C waveform shown below:

MAVRK SW I2C Read Register 1Byte.png

                                                             S=Start Condition   Sr = Restart     W=Write Command       A=Acknowledge/ACK     N=Not Acknowledged/NACK     P=Stop Condition




Example of mvk_Write_I2C() writing multiple bytes to an I2C EEPROM:

mvk_I2C_Write() prototype can be found in I2C_Functions.h
unsigned char mvk_Write_I2C (unsigned int I2C_device_address,
                             unsigned char device_slot,
                             unsigned char* I2C_write_data,
                             unsigned char num_write_bytes);
-------------------------------------------------------------------------

// I2C Slave address and register definitions can be found in the MAVRK Library Component header files
#define SOME_EEPROM_I2C_SLAVE_ADDRESS    0x51       
#define SOME_EEPROM_MEMORY_ADDRESS       0x0000  // 0(Decimal)
#define I2C_5_BYTES 5

void my_sample_code (void)
{
    unsigned char errChk;
    unsigned char device_slot = MAVRK_MCU;
    unsigned char I2C_write_data[5];

    I2C_write_data[0] = 0x00;  // MSB Port of 16 bit EEPROM memory address
    I2C_write_data[1] = 0x00;  // LSB Port of 16 bit EEPROM memory address
    I2C_write_data[2] = 0xAA;  // 170(Decimal) to be written at EEPROM Memory Address 0x0000  
    I2C_write_data[2] = 0x55;  //  85(Decimal) to be written at EEPROM Memory Address 0x0001
    I2C_write_data[2] = 0x99;  // 153(Decimal) to be written at EEPROM Memory Address 0x0002
    

    errChk = mvk_Write_I2C (SOME_EEPROM_I2C_SLAVE_ADDRESS,
                            device_slot,
                            I2C_write_data, 
                            I2C_5_BYTES);
 
    if (errChk != I2C_OPERATION_SUCCESSFUL)
    {
        mvk_Error_Trap (0x01, errChk, ERROR_HIGH_LEVEL);
    }  
}
 


Executing the mvk_Write_I2C() writing multiple bytes to an I2C EEPROM code above generates the I2C waveform shown below:

MAVRK SW I2C Write 3ByteTrace.png

                                                                      S=Start Condition   Sr = Restart     W=Write Command     A=Acknowledge/ACK    N=Not Acknowledged/NACK    P=Stop Condition



Example of mvk_Write_Restart_Read_I2C() reading multiple bytes:

mvk_Write_Restart_Read_I2C() prototype can be found in I2C_Functions.h
unsigned char mvk_Write_Restart_Read_I2C (unsigned int I2C_device_address,
                                          unsigned char device_slot,
                                          unsigned char* I2C_write_data, 
                                          unsigned char num_write_bytes,
                                          unsigned char* I2C_read_data, 
                                          unsigned char num_read_bytes);
-------------------------------------------------------------------------

// I2C Slave address and register definitions can be found in the MAVRK Library Component header files
#define SOME_EEPROM_I2C_SLAVE_ADDRESS    0x51       
#define SOME_EEPROM_MEMORY_ADDRESS       0x0000  // 0(Decimal)
#define I2C_2_BYTES 2
#define I2C_3_BYTES 3

void my_sample_code (void)
{
    unsigned char errChk;
    unsigned char device_slot = MAVRK_MCU;
    unsigned char I2C_write_data[2];
    unsigned char I2C_read_data[3];   
 
    I2C_write_data[0] = 0x00;  // MSB Port of 16 bit EEPROM memory address
    I2C_write_data[1] = 0x00;  // LSB Port of 16 bit EEPROM memory address
    
    

    errChk = mvk_Write_Restart_Read_I2C (SOME_EEPROM_I2C_SLAVE_ADDRESS,
                                         device_slot,
                                         I2C_write_data, 
                                         I2C_2_BYTES,
                                         I2C_read_data, 
                                         I2C_3_BYTES);

    if (errChk != I2C_OPERATION_SUCCESSFUL)
    {
        mvk_Error_Trap (0x01, errChk, ERROR_HIGH_LEVEL);
    }  
}
 

Executing the mvk_Write_Restart_Read_I2C() code above generates the I2C waveform shown below:

MAVRK SW I2C Write Restart Read 3Bytes.png

                                                                 S=Start Condition    Sr = Restart    W=Write Command     A=Acknowledge/ACK     N=Not Acknowledged/NACK     P=Stop Condition


Example of mvk_Write_Stop_Read_I2C() reading multiple bytes:

mvk_Write_Stop_Read_I2C() prototype can be found in I2C_Functions.h
unsigned char mvk_Write_Stop_Read_I2C (unsigned int I2C_device_address,
                                       unsigned char device_slot,
                                       unsigned char* I2C_write_data, 
                                       unsigned char num_write_bytes,
                                       unsigned char* I2C_read_data, 
                                       unsigned char num_read_bytes);
-------------------------------------------------------------------------

// I2C Slave address and register definitions can be found in the MAVRK Library Component header files
#define SOME_EEPROM_I2C_SLAVE_ADDRESS    0x51       
#define SOME_EEPROM_MEMORY_ADDRESS       0x0000  // 0(Decimal)
#define I2C_2_BYTES 2
#define I2C_3_BYTES 3

void my_sample_code (void)
{
    unsigned char errChk;
    unsigned char device_slot = MAVRK_MCU;
    unsigned char I2C_write_data[2];
    unsigned char I2C_read_data[3];   
 
    I2C_write_data[0] = 0x00;  // MSB Port of 16 bit EEPROM memory address
    I2C_write_data[1] = 0x00;  // LSB Port of 16 bit EEPROM memory address
    
    

    errChk = mvk_Write_Stop_Read_I2C (SOME_EEPROM_I2C_SLAVE_ADDRESS,
                                      device_slot,
                                      I2C_write_data, 
                                      I2C_2_BYTES,
                                      I2C_read_data, 
                                      I2C_3_BYTES);

    if (errChk != I2C_OPERATION_SUCCESSFUL)
    {
        mvk_Error_Trap (0x01, errChk, ERROR_HIGH_LEVEL);
    }  
}
 

Executing the mvk_Write_Stop_Read_I2C() code above generates the I2C waveform shown below:

MAVRK SW I2C Write Stop Read 3Bytes.png
           

                                                        S=Start Condition     Sr = Restart     W=Write Command     A=Acknowledge/ACK     N=Not Acknowledged/NACK     P=Stop Condition




MAVRK I2C Troubleshooting Tips and Tricks[edit]

1.) Why am I stuck in this loop?:   while (I2C_port_ptr->I2C_Control_1_register->Generate_Start_Condition);

If you find yourself stuck in the loop above the first time a MAVRK I2C Function is called, here are a few thing to look at

  • The MAVRK MCU global interrupts have not been enabled: 


The mvk_Enable_Global_Interrupts () function must be called before any MAVRK Com Port software (I2C, SPI, UART, etc) will execute properly. The code snippet below depicts global interrupts being enabled before the I2C controlled RF-TCA8418-MVK keypad can be initialized.

  mvk_Enable_Global_Interrupts ();                                    // Enable MCU Global Interrupts   
errChk =  mvk_Init_TCA8418(device_slot, TCA8418_I2C_SLAVE_ADDRESS); // Initialize TCA8418 Component  


  • The I2C Bus signals SCL and/or SDA are at logic level 0: 


I2C protocol defines specific SCL and SDA signal logic states and edge transitions to properly generate an I2C Start condition. In the logic analyzer trace below at T+0, SDA transitions from a High to Low logic state while SCL is in a High logic state before and for a short time after the SDA High to Low transition.

MAVRK SW I2C Write 1ByteTrace.png


When SDA and/or SCL are held in a continuous Low Logic State, an I2C Start condition cannot be generated.   MAVRK I2C functions will spin in a loop waiting for the Start condition to occur.  This type of problem is typically hardware related where another signal is inappropriately driving the SDA or SCL signals to Low logic state. This may occur when using the MAVRK breakout modules to connect I2C to other EVM's. Logic analyzers and oscilliscopes are usually required to figure out what is happening signal wise. 

MAVRK I2C logic levels should alway be ~3.3 Volts for a High logic level and ~0.0 Volts for a Low logic level. If you measure SCL or SDA at voltages in 0.5 to 2.5 Volt range, then its a indication of mutiple two different sources driving the same signal. If you don't have an oscilliscope or logic analyzer its possible to determine the logic levels with either the IAR or CCS Debuggers. 


Below is snapshot of the MCU-430F5438A-MVK schematic, which is shipped with the MAVRK Starter Kit . It shows device pin 77 (Port10.Pin1) as I2C_SDA and device pin 78 (Port10.Pin2) as I2C_SCL. This information can be used to determine the logic levels of SDA and SCL signals using Toolchain debuggers.    

MAVRK MCU-430F5438A I2C SCH.png


Code Composer Studio (CCS) and IAR Embedded Workbench for MSP430 can be used to compile, link, download and debug MAVRK I2C applications. Below is the example of using CCS to debug the RF-TCA8418-MVK keypad Module Test Application running on a MB-PRO-MVK motherboard with a MCU-430F5438A-MVK processor and RF-TCA8418-MVK keypad installed. The application was executed up to the point where the TCA8418 keypad scanner device is about to be initialized via I2C. Port 10 Pin values can be displayed by selecting Registers from the View menu. Once in the list of Registers, select Port_9_10 and select P10IN. As shown in the red box area below both SCL P10.Pin2 and SDA P10.Pin1 are both Logic High as they should be to permit a Start condition. If either Pin was Low a Start could not be generated.  The IAR Embedded Workbench for MSP430 has the same capability to view signal logic levels. 

   

     MAVRK CCS I2C Logic Levels.png



/********************************************************************************************************************************************************************************************************************/

2.) Why is my I2C function returning I2C_WRITE_FAILED_NACK?

This error occurs when none of the slave devices attached to the MAVRK I2C bus recognize the slave address being sent by the MAVRK MCU as their slave address. Therefore no slave device acknowledges the slave address. The most common cause of this problem is an incorrect slave address. 


Incorrect Slave Device Address: 

The most common cause of this problem is shifted bit position of thet slave address.


 Below is a table from a device data sheet specifying the part's 7-bit I2C slave address

MAVRK I2C Address.png

Bit 0(LSB) is not considered part of the 7-bit slave address.  However it is not always mentioned in data sheets and could be misinterpreted as 0x68hex. 

Using only Bits (7-1) the hex value of the 7-bit slave address yields the correct slave address as 0x34hex. 


Notice in the logic analyzer screen capture below, the slave address is shown as W:34h, an I2C Write transaction to slave address 0x34. Looking at the SDA and SCL signal timing clearly depicts a rising clock edge on  8 data bits in the following order  01101000 or 0x68 in hex.   

MAVRK SW I2C Write 1ByteTrace.png

In summary always use Bits 7-1 as the device slave address to pass to MAVRK I2C functions.


/********************************************************************************************************************************************************************************************************************/



I2C API Documentation[edit]

For a more complete discussion of the various software API functions, please see the MAVRK API Documentation.


E2e.jpg {{
  1. switchcategory:MultiCore=
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article Software - MAVRK I2C Bus Functions here.

Keystone=
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article Software - MAVRK I2C Bus Functions here.

C2000=For technical support on the C2000 please post your questions on The C2000 Forum. Please post only comments about the article Software - MAVRK I2C Bus Functions here. DaVinci=For technical support on DaVincoplease post your questions on The DaVinci Forum. Please post only comments about the article Software - MAVRK I2C Bus Functions here. MSP430=For technical support on MSP430 please post your questions on The MSP430 Forum. Please post only comments about the article Software - MAVRK I2C Bus Functions here. OMAP35x=For technical support on OMAP please post your questions on The OMAP Forum. Please post only comments about the article Software - MAVRK I2C Bus Functions here. OMAPL1=For technical support on OMAP please post your questions on The OMAP Forum. Please post only comments about the article Software - MAVRK I2C Bus Functions here. MAVRK=For technical support on MAVRK please post your questions on The MAVRK Toolbox Forum. Please post only comments about the article Software - MAVRK I2C Bus Functions here. For technical support please post your questions at http://e2e.ti.com. Please post only comments about the article Software - MAVRK I2C Bus Functions here.

}}

Hyperlink blue.png Links

Amplifiers & Linear
Audio
Broadband RF/IF & Digital Radio
Clocks & Timers
Data Converters

DLP & MEMS
High-Reliability
Interface
Logic
Power Management

Processors

Switches & Multiplexers
Temperature Sensors & Control ICs
Wireless Connectivity