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.

SW-EK-TM4C123GXL: EK-TM4C123GXL + I2C + MAX30100 sensor

Part Number: SW-EK-TM4C123GXL
Other Parts Discussed in Thread: EK-TM4C123GXL

Hello,

I am trying to get values from Max 30100 sensor via I2C to EK-TM4C123GXL. I am having issues where it says that 'I do not have the permission to read the register'  and points to the I2CSend function. The code also doesn't get to the point of I2C interrupt handler. The following is the code I have written,

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_i2c.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "driverlib/i2c.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
//***********************************************************   Global   ************************************************************************//
  int i;
  uint8_t Fifo_WR_PTR;
  uint8_t Fifo_RD_PTR;
  uint16_t Num_Samples_Available;
  uint16_t Num_Samples_Read;
  uint8_t ir1;
  uint8_t ir2;
  uint8_t red1;
  uint8_t red2;
  uint16_t ir;
  uint16_t red;
//**************************************************   Initialize I2C module 0   ***************************************************************//
  void InitI2C0(void)
{
    //enable I2C module 0
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);

    //reset module
    SysCtlPeripheralReset(SYSCTL_PERIPH_I2C0);

    //enable GPIO peripheral that contains I2C 0
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    // Configure the pin muxing for I2C0 functions on port B2 and B3.
    GPIOPinConfigure(GPIO_PB2_I2C0SCL);
    GPIOPinConfigure(GPIO_PB3_I2C0SDA);

    // Select the I2C function for these pins.
    GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);

    // Enable and initialize the I2C0 master module.  Use the system clock for
    // the I2C0 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.
    I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), true);

    //clear I2C FIFOs
    HWREG(I2C0_BASE + I2C_O_FIFOCTL) = 80008000;
}
//**************************************************   I2C Send function   ***************************************************************//
void I2CSend(uint16_t device_address, uint16_t device_register, uint8_t device_data)
{
    //specify that we want to communicate to device address with an intended write to bus
    I2CMasterSlaveAddrSet(I2C0_BASE, device_address, false);

    //register to be read
    I2CMasterDataPut(I2C0_BASE, device_register);

    //send control byte and register address byte to slave device
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);

    //wait for MCU to finish transaction
    while(I2CMasterBusy(I2C0_BASE));
    I2CMasterSlaveAddrSet(I2C0_BASE, device_address, false);

    //specify data to be written to the above mentioned device_register
    I2CMasterDataPut(I2C0_BASE, device_data);

    //wait while checking for MCU to complete the transaction
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);

    //wait for MCU & device to complete transaction
    while(I2CMasterBusy(I2C0_BASE));
}
//**************************************************   I2C Single Receive function   ***************************************************************//
uint32_t I2CReceiveS(uint32_t slave_addr, uint8_t reg)
{
    //specify that we are writing (a register address) to the slave device
    I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, false);

    //specify register to be read
    I2CMasterDataPut(I2C0_BASE, reg);

    //send control byte and register address byte to slave device
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);

    //wait for MCU to finish transaction
    while(I2CMasterBusy(I2C0_BASE));

    //specify that we are going to read from slave device
    I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, true);

    //send control byte and read from the register we specified
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);

    //wait for MCU to finish transaction
    while(I2CMasterBusy(I2C0_BASE));

    //return data pulled from the specified register
    return I2CMasterDataGet(I2C0_BASE);
}
//**************************************************   I2C Burst Receive function   ***************************************************************//
uint32_t I2CReceiveB(uint32_t slave_addr, uint8_t reg)
{
    //specify that we are writing (a register address) to the slave device
    I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, false);

    //specify register to be read
    I2CMasterDataPut(I2C0_BASE, reg);

    //send control byte and register address byte to slave device
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);

    //wait for MCU to finish transaction
    while(I2CMasterBusy(I2C0_BASE));

    //specify that we are going to read from slave device
    I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, true);

    //send control byte and read from the register we specified
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);

    //wait for MCU to finish transaction
    while(I2CMasterBusy(I2C0_BASE));

    //return data pulled from the specified register
    return I2CMasterDataGet(I2C0_BASE);
}
//**************************************************   Slave Fifo Reset Function   ***************************************************************//
void resetFifo ()
{
    I2CSend(0x57, 0x02, 0x00);                                              // Reset FIFO Write Pointer
    I2CSend(0x57, 0x04, 0x00);                                              // Reset FIFO Read Pointer
    I2CSend(0x57, 0x03, 0x00);                                              // Reset FIFO Overflow Counter
}
//**************************************************   I2C Interrupt Handler Function   ***************************************************************//
void I2C0MasterIntHandler (void)
{
    I2CMasterIntClear(I2C0_BASE);                                           // Clear the I2C interrupt flag
    resetFifo();                                                            // Reset Slave Fifo
    Fifo_WR_PTR = I2CReceiveS(0x57, 0x02);                                  // Read FIFO Write Pointer
    Num_Samples_Available = Fifo_WR_PTR - Fifo_RD_PTR;                      // Evaluating Number of samples to be read from FIFO
//    Num_Samples_Read =< Num_Samples_Available;                              //
    for (i = 0; i < Num_Samples_Available; i++)
    {
        ir1 = I2CReceiveB(0x57, 0x05);                                      // Receive first byte of sample
        ir2 = I2CReceiveB(0x57, 0x05);                                      // Receive second byte of sample
        ir = (uint16_t) ir1 << 16 | (uint16_t) ir2;                         // Complete iR sample
        red1 = I2CReceiveB(0x57, 0x05);                                     // Receive third byte of sample
        red2 = I2CReceiveB(0x57, 0x05);                                     // Receive fourth byte of sample
        red = (uint16_t) red1 << 16 | (uint16_t) red2;                      // Complete Red sample
    }
}
//*************************************************************   Main   **************************************************************************//
int main()
{
    SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_INT | SYSCTL_XTAL_16MHZ);                     // System Clock
    InitI2C0();                                                             // I2C Initialization
    resetFifo();                                                            // Reset Slave Fifo
    I2CSend(0x57, 0x06, 0x03);                                              // Mode Configuration
    I2CSend(0x57, 0x07, 0x47);                                              // SpO2 Configuration
    I2CSend(0x57, 0x09, 0x44);                                              // LEDs Configuration
    I2CSend(0x57, 0x00, 0xB1);                                              // Interrupt Status
    I2CSend(0x57, 0x01, 0xB0);                                              // Interrupt Enable
}

I am still not processing the values. I am just trying to get the iRed and Red values and observe them in the debugger.

I have no clue what I did wrong. Any help would be appreciated!!

  • Hello Chinmay,

    I see you are trying to receive data in the I2C Interrupt handler, however I do not see any interrupt enabling being done. You won't enter the ISR unless you properly initialize the I2C module to use interrupts.

    Please reference our slave_receive_int.c example provided in TivaWare under the 'examples/peripherals/i2c' folder for the fundamentals of how to initialize interrupt for I2C. And make sure you have included the I2C0MasterIntHandler into your startup_ccs.c file for I2C0 so it doesn't try and use the default ISR handler.