e. Bridging I2C

<< Click to Display Table of Contents >>

Navigation:  Tutorials > Tutorail 20 - CleO Bridging >

e. Bridging I2C

This tutorial shows how to use bridging commands to access I2C device interface on CleO50. MikroE Heart Rate Click module is used as I2C slave device. The Heart Rate Click in turn uses the MAX30100 Pulse Oximeter sensor.

 

 

Command Prototype

 

int16_t DeviceOpen(uint8_t Slot,  uint8_t Interface,  int16_t bytestowrite,  uint8_t* Buffer)

 

Parameters

Description

Slot

Currently only one Slot is supported. Slot value should be equal to 0.

Interface

Value of this parameter should be BRIDGE_TYPE_I2CM for I2C interface access. Only master configuration is supported.

bytestowrite

Value of this parameter is the total number of bytes to be written through this function which in this case is sizeof i2cm_options structure.

Buffer

Value of this parameter should be a pointer to i2cm_options structure type in Bridge.h.

 

typedef  struct PACK {

 union PACK {

  struct PACK {

   uint16_t SlaveAddress; / Verify if SPIM actually supports 10 bit address ! /

   uint32_t ClockSpeed;

  };

  uint8_t b[6];

 };

}i2cm_options;

 

Structure member description:

 

SlaveAddress: This value should be 7 bit slave address.

 

ClockSpeed: The supported ClockSpeed values are 100 kbps, 400 kbps, 1000 kbps and 3400 kbps.

 

 

Return Value

Description

int16_t

On success, the function returns a valid handle that can be used in subsequent Device*() calls.

On failure, the function returns a negative value of error code with blue screen.

 

 

int16_t DeviceRead(uint8_t DevHandle,  int16_t bytestowrite,  int16_t bytestoread,  uint8_t* Buffer,  uint8_t* rBuffer)

 

Parameters

Description

DevHandle

A I2C handle number that is obtained using DeviceOpen() call.

bytestowrite

Value of this parameter is the total number of bytes to be written to I2C

bytestoread

Value of this parameter is the total number of bytes intend to read from I2C

Buffer

Value of this parameter should be a pointer to type uint8_t.

This buffer holds the data to be written to I2C. "bytestowrite" parameter refers to number of bytes in this Buffer. When "bytestowrite" is 0, this parameter should be NULL..

rBuffer

Value of this parameter should be read buffer pointer to which read result will be updated when the function returns.

 

Return Value

Description

int16_t

On success the function returns the number of bytes read from I2C. On failure the function returns a negative value of error code with blue screen. Return 0 if line is busy.

 

 

int16_t DeviceWrite(uint8_t DevHandle,  int16_t bytestowrite,  uint8_t* Buffer,  int16_t &byteswritten)

 

Parameters

Description

DevHandle

An I2C handle that is obtained using DeviceOpen() call.

bytestowrite

Value of this parameter is the total number of bytes to be written.

Buffer

Value of this parameter should be a pointer to type uint8_t

byteswritten

This variable will be updated with the total number of bytes written to CleO when the function returns.

 

Return Value

Description

int16_t

On success, the function returns 1 and on failure the function returns a negative value of error code with blue screen.

 

 

int16_t DeviceClose( uint8_t DevHandle)

 

Parameters

Description

DevHandle

An I2C handle that is obtained using DeviceOpen() call.

 

Return Value

Description

int16_t

On success, the function returns 1 and on failure the function returns a negative value of error code with blue screen.

 

 

Code

 

 

/* MAX30100 definitions */

#define I2C_ADR 0x57

#define EXP_PART_ID  0x11

 

#define REG_CONFIG_MODE                    0x06

#define REG_CONFIG_LED                            0x09

#define REG_INT_ENABLE                            0x01

#define REG_CONFIG_SPIO2                          0x07

#define REG_FIFO_WRITE_PTR                        0x02

#define REG_FIFO_READ_PTR                        0x04

#define REG_FIFO_OVERFLOW_CNTR            0x03

#define REG_PART_ID                                0xFF

#define REG_REV_ID                                0xFE

 

#define MODE_RESET                                (0x01 << 6)

#define LED_CURRENT                                0x0F

#define ENABLE_HR_INT                            (0x01 << 5)

#define SAMPLE_RATE_CFG                            (0x01 << 2)

#define LED_PW_400                                0x01

#define MODE_HR_ONLY                              0x02

 

int16_t HandleI2C = -1;

int16_t BytesWritten;

 

void setup()

{  

 CleO.begin();

 Serial.begin(115200);

/* Open I2C device using bridging commands */

 Bridge::i2cm_options i2c_open_opt;

 i2c_open_opt.SlaveAddress = I2C_ADR;

 i2c_open_opt.ClockSpeed = 400000;

 HandleI2C = CleO.DeviceOpen(0, BRIDGE_TYPE_I2CM, sizeof(i2c_open_opt), (uint8_t*)&i2c_open_opt);

 if(HandleI2C < 0 )

 {

  /* Failed to open a handle */

   Serial.print("DeviceOpen failed");

 }

 else

 {

  /* Success in opening I2C interface */

   uint8_t data[4];

  /* reset the sensor */                

   data[0] = REG_CONFIG_MODE;

   data[1] = MODE_RESET;

  /* Write I2C device using bridging commands */

   CleO.DeviceWrite(HandleI2C, 2, data, BytesWritten);      

   delay(500);

 

   data[0] = REG_CONFIG_LED;

   data[1] = (uint8_t)LED_CURRENT << 4 | (uint8_t)LED_CURRENT;

   CleO.DeviceWrite(HandleI2C, 2, data, BytesWritten);      

   data[0] = REG_CONFIG_LED;

  /* Read I2C device using bridging commands */

   CleO.DeviceRead(HandleI2C, 1, 1, &data[0], &data[1]);

 

   data[0] = REG_INT_ENABLE;

   data[1] = ENABLE_HR_INT;

   CleO.DeviceWrite(HandleI2C, 2, data, BytesWritten);  

   data[0] = REG_CONFIG_SPIO2;

   data[1] = SAMPLE_RATE_CFG | LED_PW_400;

   CleO.DeviceWrite(HandleI2C, 2, data, BytesWritten);  

 

   data[0] = REG_CONFIG_SPIO2;

   CleO.DeviceRead(HandleI2C, 1, 1, &data[0], &data[1]);

  /* Clear FIFO pointers */

   data[0] = REG_FIFO_WRITE_PTR;

   data[1] = 0;

   CleO.DeviceWrite(HandleI2C, 2, data, BytesWritten);  

   data[0] = REG_FIFO_READ_PTR;

   data[1] = 0;

   CleO.DeviceWrite(HandleI2C, 2, data, BytesWritten);  

   data[0] = REG_FIFO_OVERFLOW_CNTR;

   data[1] = 0;

   CleO.DeviceWrite(HandleI2C, 2, data, BytesWritten);  

   data[0] = REG_CONFIG_MODE;

   data[1] = MODE_HR_ONLY;

   CleO.DeviceWrite(HandleI2C, 2, data, BytesWritten);                  

 

   data[0] = REG_CONFIG_MODE;

   CleO.DeviceRead(HandleI2C, 1, 1, &data[0], &data[1]);                

   data[0] = REG_FIFO_OVERFLOW_CNTR;

   CleO.DeviceRead(HandleI2C, 1, 1, &data[0], &data[1]);

 

   data[0] = REG_PART_ID;

   CleO.DeviceRead(HandleI2C, 1, 1, &data[0], &data[1]);

   if(data[1] != EXP_PART_ID)      

       Serial.println("HR Click Init failed!");      

   else

       Serial.print("Part ID : ");Serial.println(data[1]);

 

   data[0] = REG_REV_ID;

   CleO.DeviceRead(HandleI2C, 1, 1, &data[0], &data[1]);

   Serial.print("Rev ID : ");

   Serial.println(data[1]);

 

  /* Close I2C device using bridging commands */

   HandleI2C = CleO.DeviceClose(HandleI2C);  /* DeviceClose returns 255 for I2C close */

 }

}

 

void loop()

{

}

 

 

Description

 

This tutorial opens a handle to I2C interface using DeviceOpen(). The handle is used to communicate to MikroE Heart Rate Click.  DeviceRead() and DeviceWrite() is used to initialize the click. Click's part id and revision id registers are read using the DeviceRead() bridge library functions.DeviceClose() is used to close the handle.

 

 

Output

 

On successful execution of this tutorial, part id and revision id of click is displayed in the serial monitor window.

 

.

 

If any of bridge command fails, an appropriate error message is displayed in the serial monitor window.