This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP432E401Y: I2C read Register data driverlib example

Former Member
Former Member

Part Number: MSP432E401Y

Hi ,

I'm completely new to msp432 micro controllers,

I'm looking for an I2C driverlib example that can read slave's register data.

regards,

Tex

  • Hi,

      There a quite a few I2C examples that you can reference. First, install SimpleLink SDK for MSP432E and then import these projects from the below directory into CCS.

    You could import the same projects from Resource Explorer from within CCS. 

  • Former Member
    0 Former Member in reply to Charles Tsai

    Hi Charles,

    I need a particular function that reads register data of an i2c slave.. 

    Could you please help me with that..

    Regards,

    Tex

  • Hi,

      What do  you mean by particular function? All documentation are under C:\ti\simplelink_msp432e4_sdk_4_20_00_12\docs. Specifically for TI drivers, you can go to C:\ti\simplelink_msp432e4_sdk_4_20_00_12\docs\tidrivers and bring up tidriversAPIs.html. You will see below. 

    Click I2C.h will bring up documentation for all I2C APIs and examples for using them. Below is a snippet describing how to read/write  I2C data. 

  • Former Member
    0 Former Member in reply to Charles Tsai

    Thank you so much for your valuable information charles,

    I recently started programming with msp432e401y Driverlib it was getting hard to implement

    is there any program that can be easy to implement 

    regards,

    Tex

  • Hi Tex,

      First of all, my bad. In my second reply to you I was showing you the 'TI-driver' based I2C  code. Ti-Driver are normally used along with RTOS. After reading your original post again, you were looking for I2C driverlib examples. In my first reply I gave you a list of i2c driverlib examples. The i2c driverlib examples are non-RTOS based. Did you have a chance to try C:\ti\simplelink_msp432e4_sdk_4_20_00_12\examples\nortos\MSP_EXP432E401Y\driverlib\i2c_mastermode_simple_transfer? This one will do simple I2C transfers. This is supposed to be a simple example for you to start. 

      Here is another example that was developed for TM4C129 MCU. TM4C129 is the same silicon as MSP432E. The driverlib  for TM4C129 is the same as MSP432E. The difference between these two MCUs is that TM4C129 does not use the SimpleLink SDK platform but rather its TivaWare SDK. If you have downloaded TivaWare you can find the example in  C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl-boostxl-senshub\humidity_sht21_simple. I'm also attaching the example code here. 

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_ints.h"
    #include "driverlib/debug.h"
    #include "driverlib/gpio.h"
    #include "driverlib/i2c.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    
    //*****************************************************************************
    //
    //! \addtogroup example_list
    //! <h1>Humidity Measurement with the SHT21 (humidity_sht21_simple)</h1>
    //!
    //! This example demonstrates the usage of the I2C interface to obtain the
    //! temperature and relative humidity of the environment using the Sensirion
    //! SHT21 sensor.
    //!
    //! The I2C7 on the EK-TM4C1294XL launchPad is used to interface with the
    //! SHT21 sensor.  The SHT21 sensor is on the BOOSTXL_SENSHUB boosterPack
    //! expansion board that can be directly plugged into the Booster pack 1
    //! connector of the EK-TM4C1294XL launchPad board.  Please make sure proper
    //! pull-up resistors are on the I2C SCL and SDA buses.
    //!
    //! This example uses the following peripherals and I/O signals.  You must
    //! review these and change as needed for your own board:
    //! - I2C7 peripheral
    //! - GPIO Port D peripheral
    //! - I2C7_SCL - PD0
    //! - I2C7_SDA - PD1
    //!
    //! UART0, connected to the Virtual Serial Port and running at 115,200, 8-N-1,
    //! is used to display messages from this application.
    //
    //*****************************************************************************
    
    //*****************************************************************************
    //
    // Define SHT21 I2C Address.
    //
    //*****************************************************************************
    #define SHT21_I2C_ADDRESS  0x40
    
    //*****************************************************************************
    //
    // Define SHT21 Commands.  Please refer to the SHT21 datasheet for
    // all available commands.
    //
    //*****************************************************************************
    #define SW_RESET                0xFE
    #define TRIGGER_RH_MEASUREMENT  0xF5
    #define TRIGGER_T_MEASUREMENT   0xF3
    
    //*****************************************************************************
    //
    // The variable g_ui32SysClock contains the system clock frequency in Hz.
    //
    //*****************************************************************************
    uint32_t g_ui32SysClock;
    
    //*****************************************************************************
    //
    // Application function to capture ASSERT failures and other debug conditions.
    //
    //*****************************************************************************
    #ifdef DEBUG
    void
    __error__(char *pcFilename, uint32_t ui32Line)
    {
    }
    #endif
    
    //*****************************************************************************
    //
    // Configure the UART and its pins.  This must be called before UARTprintf().
    //
    //*****************************************************************************
    void
    ConfigureUART(void)
    {
        //
        // Enable the GPIO Peripheral used by the UART.
        //
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
        //
        // Enable UART0.
        //
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    
        //
        // Configure GPIO Pins for UART mode.
        //
        MAP_GPIOPinConfigure(GPIO_PA0_U0RX);
        MAP_GPIOPinConfigure(GPIO_PA1_U0TX);
        MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
        //
        // Initialize the UART for console I/O.
        //
        UARTStdioConfig(0, 115200, g_ui32SysClock);
    }
    
    //*****************************************************************************
    //
    // This function sends the specified command to the I2C slave device.
    //
    //*****************************************************************************
    void
    I2CWriteCommand(uint32_t ui32Command)
    {
        //
        // Set up the slave address with write transaction.
        //
        MAP_I2CMasterSlaveAddrSet(I2C7_BASE, SHT21_I2C_ADDRESS, false);
    
        //
        // Store the command data in I2C data register.
        //
        MAP_I2CMasterDataPut(I2C7_BASE, ui32Command);
    
        //
        // Start the I2C transaction.
        //
        MAP_I2CMasterControl(I2C7_BASE, I2C_MASTER_CMD_SINGLE_SEND);
    
        //
        // Wait until the I2C transaction is complete.
        //
        while(MAP_I2CMasterBusy(I2C7_BASE))
        {
        }
    }
    
    //*****************************************************************************
    //
    // This function will read three 8-bit data from the I2C slave. The first
    // two 8-bit data forms the humidity data while the last 8-bit data is the
    // checksum.  This function illustrates three different I2C burst mode
    // commands to read the I2C slave device.
    //
    //*****************************************************************************
    void
    I2CReadCommand(uint32_t * pui32DataRx)
    {
        //
        // Modify the data direction to true, so that seeing the address will
        // indicate that the I2C Master is initiating a read from the slave.
        //
        MAP_I2CMasterSlaveAddrSet(I2C7_BASE, SHT21_I2C_ADDRESS, true);
    
        //
        // Setup for first read.  Use I2C_MASTER_CMD_BURST_RECEIVE_START
        // to start a burst mode read.  The I2C master continues to own
        // the bus at the end of this transaction.
        //
        MAP_I2CMasterControl(I2C7_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
    
        //
        // Wait until master module is done transferring.
        // The I2C module has a delay in setting the Busy flag in the register so
        // there needs to be a delay before checking the Busy bit.  The below loops
        // wait until the Busy flag is set, and then wait until it is cleared to
        // indicate that the transaction is complete.  This can take up to 633 CPU
        // cycles @ 100 kbit I2C Baud Rate and 120 MHz System Clock.  Therefore, a
        // while loop is used instead of SysCtlDelay.
        //
        while(!MAP_I2CMasterBusy(I2C7_BASE))
        {
        }
        while(MAP_I2CMasterBusy(I2C7_BASE))
        {
        }
    
        //
        // Read the first byte data from the slave.
        //
        pui32DataRx[0] = MAP_I2CMasterDataGet(I2C7_BASE);
    
        //
        // Setup for the second read.  Use I2C_MASTER_CMD_BURST_RECEIVE_CONT
        // to continue the burst mode read.  The I2C master continues to own
        // the bus at the end of this transaction.
        //
        MAP_I2CMasterControl(I2C7_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
    
        //
        // Wait until master module is done transferring.
        //
        while(!MAP_I2CMasterBusy(I2C7_BASE))
        {
        }
        while(MAP_I2CMasterBusy(I2C7_BASE))
        {
        }
    
        //
        // Read the second byte data from the slave.
        //
        pui32DataRx[1] = MAP_I2CMasterDataGet(I2C7_BASE);
    
        //
        // Setup for the third read.  Use I2C_MASTER_CMD_BURST_RECEIVE_FINISH
        // to terminate the I2C transaction.  At the end of this transaction,
        // the STOP bit will be issued and the I2C bus is returned to the
        // Idle state.
        //
        MAP_I2CMasterControl(I2C7_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
    
        //
        // Wait until master module is done transferring.
        //
        while(!MAP_I2CMasterBusy(I2C7_BASE))
        {
        }
        while(MAP_I2CMasterBusy(I2C7_BASE))
        {
        }
        
        //
        // Note the third 8-bit data is the checksum byte.  It will be
        // left to the users as an exercise if they want to verify if the
        // checksum is correct.
        pui32DataRx[2] = MAP_I2CMasterDataGet(I2C7_BASE);
    }
    
    //*****************************************************************************
    //
    // Main 'C' Language entry point.
    //
    //*****************************************************************************
    int
    main(void)
    {
        float fTemperature, fHumidity;
        int32_t i32IntegerPart;
        int32_t i32FractionPart;
        uint32_t pui32DataRx[3] = {0};
    
        //
        // Run from the PLL at 120 MHz.
        // Note: SYSCTL_CFG_VCO_240 is a new setting provided in TivaWare 2.2.x and
        // later to better reflect the actual VCO speed due to SYSCTL#22.
        //
        g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                                 SYSCTL_OSC_MAIN |
                                                 SYSCTL_USE_PLL |
                                                 SYSCTL_CFG_VCO_240), 120000000);
    
        //
        // Initialize the UART.
        //
        ConfigureUART();
    
        //
        // Print the welcome message to the terminal.
        //
        UARTprintf("\033[2JSHT21 Example\n");
    
        //
        // The I2C7 peripheral must be enabled before use.
        //
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C7);
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    
        //
        // Configure the pin muxing for I2C7 functions on port D0 and D1.
        // This step is not necessary if your part does not support pin muxing.
        //
        MAP_GPIOPinConfigure(GPIO_PD0_I2C7SCL);
        MAP_GPIOPinConfigure(GPIO_PD1_I2C7SDA);
    
        //
        // Select the I2C function for these pins.  This function will also
        // configure the GPIO pins pins for I2C operation, setting them to
        // open-drain operation with weak pull-ups.  Consult the data sheet
        // to see which functions are allocated per pin.
        //
        MAP_GPIOPinTypeI2CSCL(GPIO_PORTD_BASE, GPIO_PIN_0);
        MAP_GPIOPinTypeI2C(GPIO_PORTD_BASE, GPIO_PIN_1);
    
        //
        // Enable interrupts to the processor.
        //
        MAP_IntMasterEnable();
    
        //
        // Enable and initialize the I2C7 master module.  Use the system clock for
        // the I2C7 module.  The last parameter sets the I2C data transfer rate.
        // If false the data rate is set to 100kbps and if true the data rate will
        // be set to 400kbps.  For this example we will use a data rate of 100kbps.
        //
        MAP_I2CMasterInitExpClk(I2C7_BASE, g_ui32SysClock, false);
    
        //
        // Initialize the SHT21 Humidity and Temperature sensors.
        //
        I2CWriteCommand(SW_RESET);
    
        //
        // Per SHT21 sensor datasheet, wait for at least 15ms before the
        // software reset is complete.  Here we will wait for 20ms.
        //
        MAP_SysCtlDelay(g_ui32SysClock / (50 * 3));
    
        while(1)
        {
            //
            // Write the command to start a humidity measurement.
            //
            I2CWriteCommand(TRIGGER_RH_MEASUREMENT);
    
            //
            // Per SHT21 sensor datasheet, the humidity measurement
            // can take a maximum of 29ms to complete at 12-bit
            // resolution.  Here we will wait for 33ms.
            //
            MAP_SysCtlDelay(g_ui32SysClock / (30 * 3));
    
            //
            // Read the humidity measurements.
            //
            I2CReadCommand(&pui32DataRx[0]);
    
            //
            // Process the raw measurement and convert it to physical
            // humidity percentage.  Refer to the SHT21 datasheet for the
            // conversion formula.
            //
            pui32DataRx[0] = ((pui32DataRx[0] << 8) + (pui32DataRx[1] & 0xFC));
            fHumidity = (float)(-6 + 125 * (float)pui32DataRx[0] / 65536);
    
            //
            // Convert the floats to an integer part and fraction part for easy
            // print.  Humidity is returned as 0.0 to 1.0 so multiply by 100 to get
            // percent humidity.
            //
            i32IntegerPart = (int32_t) fHumidity;
            i32FractionPart = (int32_t) (fHumidity * 1000.0f);
            i32FractionPart = i32FractionPart - (i32IntegerPart * 1000);
            if(i32FractionPart < 0)
            {
                i32FractionPart *= -1;
            }
    
            //
            // Print the humidity value using the integers we just converted.
            //
            UARTprintf("Humidity %3d.%03d\t", i32IntegerPart, i32FractionPart);
    
            //
            // Write the command to start a temperature measurement.
            //
            I2CWriteCommand(TRIGGER_T_MEASUREMENT);
    
            //
            // Per SHT21 sensor datasheet, the temperature measurement
            // can take a maximum of 85ms to complete at 14-bit resolution.
            // Here we will wait for approximately 90ms.
            //
            MAP_SysCtlDelay(g_ui32SysClock / (11 * 3));
    
            //
            // Read the temperature measurements.
            //
            I2CReadCommand(&pui32DataRx[0]);
    
            //
            // Process the raw measurement and convert it to physical
            // temperature.  Refer to the SHT21 datasheet for the
            // conversion formula.
            //
            pui32DataRx[0] = ((pui32DataRx[0] << 8) + (pui32DataRx[1] & 0xFC));
            fTemperature = (float)(-46.85 + 175.72 * (float)pui32DataRx[0]/65536);
    
            //
            // Convert the floats to an integer part and fraction part for easy
            // print.
            //
            i32IntegerPart = (int32_t) fTemperature;
            i32FractionPart = (int32_t) (fTemperature * 1000.0f);
            i32FractionPart = i32FractionPart - (i32IntegerPart * 1000);
            if(i32FractionPart < 0)
            {
                i32FractionPart *= -1;
            }
    
            //
            // Print the temperature as integer and fraction parts.
            //
            UARTprintf("Temperature %3d.%03d\n", i32IntegerPart, i32FractionPart);
    
            //
            // Wait for one second before taking the measurements again.
            //
            MAP_SysCtlDelay(g_ui32SysClock / 3);
        }
    }

      

  • Former Member
    0 Former Member in reply to Charles Tsai

    Thanks for your understanding Charles,

    I wanted to use only "simplelink_msp432e4_sdk_4_20_00_12"

    So i already executed "i2c_mastermode_simple_transfer"

    It is working good but i'm not able to understand the program to customize..

    requesting you to send any example that reads register address of an external slave..

    "register read" function separately in that example to understand..

    Best regards,

    Tex

  • t is working good but i'm not able to understand the program to customize..

    requesting you to send any example that reads register address of an external slave..

    "register read" function separately in that example to understand..

    I thought i2c_mastermode_simple_transfer was already simple enough as a starting point. 

    Basically, the code starts in the main() with the below code to start a read transaction. It puts out the slave address for read and starts the transaction on I2C bus by calling MAP_I2CMasterControl. It then waits in a loop while setI2CState is equal to I2C_MASTER_RX. The setI2CState  state will change to I2C_MASTER_IDLE after all data are read in the I2C ISR handler. 

    Below is what starts in the main() to start the read.

    /* Put the Slave Address on the bus for Read */
    MAP_I2CMasterSlaveAddrSet(I2C1_BASE, SLAVE_ADDRESS, true);

    /* Start the Read transaction */
    MAP_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);

    /* Wait for all the bytes to be received */
    while(setI2CState == I2C_MASTER_RX)
    {
    }

    The below snippet is to read the data in the ISR.

    /* Process data interrupt for the Receive Path */
    if((setI2CState == I2C_MASTER_RX) && (dataIndex < I2C_NUM_DATA-2))
    {
    getData[dataIndex++] = MAP_I2CMasterDataGet(I2C1_BASE);
    MAP_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
    }
    else if((setI2CState == I2C_MASTER_RX) && (dataIndex == I2C_NUM_DATA-2))
    {
    getData[dataIndex++] = MAP_I2CMasterDataGet(I2C1_BASE);
    MAP_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);


    }

    I don't know what type of I2C  device you are trying to read. To read a register you normally do below sequence but you need to read your I2C device datasheet to know what timing and exact sequence is required. 

     - start with a slave address byte for write operation.

     - Write a data that is equal to the register address that you want to access. 

     - Stop the I2C transaction.

     - Start a slave address for read operation.

     - Read the data from the register that was specified in step 2. 

     - Stop the read transaction if you are reading one byte. If you are reading multiple bytes you just continue to read. 

  • Former Member
    0 Former Member in reply to Charles Tsai

    Thanks a lot..

    One last Doubt :

    I replaced slave address and "register address in sendData[I2C_NUM_DATA]"

    I'm not able to read 4 different registers at a time,  for only first 2 registers I'm getting register values remaining 2 showing 0.

    please tell me what mistake I'm doing.

    Best regards,

    Tex

  • You need to use preferably a logic analyzer to look at the waveforms put out by the master. Does the master conform to the below read protocol? If you reading only two and not four, it means the master has issued a NACK to stop further reading from the slave after reading bytes. You need to learn how to debug this thing.