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 and write functions

Former Member
Former Member
Part Number: MSP432E401Y
Other Parts Discussed in Thread: ENERGIA

Hi forum,

I was trying to learn I2C transmission in MSP432E401Y, now i need to transmit 16bits of data..

regards,

Tex 

  • Hi,

      I thought in this post you were able to use driverlib to develop your I2C application. What is the reason you want to switch to Energia? We have no experience with Energia. Refer to FAQ#5 in the FAQ page for TM4C129 which is the same as MSP432E that we do not support Energia on e2e You can get assistance from https://forum.43oh.com/forum/119-energia/ if you insist to use Energia for your application. Regardless which method you use (driverlib in SDK or Energia), you need to use preferably a logic analyzer to capture the command sequence you send to your external sensor. Are you conforming to the timing and command sequence as spec'ed in the sensor datasheet? If you think your command sequence is correct and the sensor is not returning the correct data then you need to check with the sensor vendor. If the sensor is a TI part, please open a new thread specifying the corresponding sensor part number. Show the full capture of your I2C command sequence to them and let them provide tips as to why it is not working. 

      You can also do Google searches for using Wire.write for I2C.

    https://docs.particle.io/reference/device-os/api/wire-i2c/write/

     https://energia.nu/guide/libraries/wire/wire_write/

      It seems like for multiple byte write, you need to use Wire.write(data, length) syntax, not Wire.write(value) as in yours which is to do individual bytes. In any case, you should consult with https://forum.43oh.com/forum/119-energia/

  • Former Member
    0 Former Member in reply to Charles Tsai

    Thanks for the reply..

    I was actually looking for driverlib program i forgot to mention please try to provide answer..

    Regards

    Tex

  • Hi,

    I was actually looking for driverlib program

      I don't get it. I'm not sure if you were the same person I was assisting in this post https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1233558/msp432e401y-i2c-read-register-data-driverlib-example/4666405?tisearch=e2e-sitesearch&keymatch=%2520user%253A563145#4666405. Sometime, I find several people from the same company sharing the same account. 

     In that post, all the code shown are driverlib functions and I thought you had it working finally. I also showed where to find all I2C examples. Here I will paste my answer on that post again. 

    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. 

    You can find all the driverlib APIs in

    https://software-dl.ti.com/simplelink/esd/simplelink_msp432e4_sdk/3.10.00.11/docs/driverlib/msp432e4/html/

    Although this below example (reading a humidity sensor) is for TM4C129 MCU but it is the same silicon as MSP432E MCU sharing the same driverlib. Here is the example code you can also take a look. 

    #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

    Hi Charles,

    Yes that's me..

    My Apologies.. it was getting really hard when i execute the code

    The above code i'm understanding but can't able to do for 16bit data read by myself because this is my first msp device after arduino..

    could you please give me the read and write functions which can transmit 16bit word data..

    My slave device is MAX17055

    Regards,

    Tex

  • It is your responsibility to find out what is the correct write and read sequence for your 3rd party slave device. Consult your slave vendor to provide waveform diagram. I can't help you with that. Each slave device may be different from each other. Below is an example to read some slave device. Again, bear in mind you need to find out what is the correct sequence to perform read and write to your own slave device. 

    In order to read a memory location from the above example device, you would need:

     1. start with a slave address byte for write operation. See first frame for Slave Write Address. 

     2. Write a data that is equal to the register address that you want to access. See second frame for Memory Address

     3. Re-Start a slave address byte for read operation. See third frame for Slave Read Address

     4. Read the data from the register that was specified in step 2.  See fourth frame for the Current LSB. 

     5. Stop the read transaction if you are reading one byte. If you are reading the second byte you just continue to read. 

    After you finish step 1 and 2. You can start step 3 to 5 using the below example code to read two bytes (16-bit) from the 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 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))
    {
    }

    //
    // Read the second byte. 
    pui32DataRx[1] = MAP_I2CMasterDataGet(I2C7_BASE);
    }

  • Former Member
    0 Former Member in reply to Charles Tsai

    Now i totally understood thanks alot for your kind information 

    Regards

    tex