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.

CC2650EM-7ID-RD: I2C communication issue CC2560

Part Number: CC2650EM-7ID-RD
Other Parts Discussed in Thread: CC2650, SYSBIOS, CC2560, MSP430G2553

Hello, 

I am working with CC2650 and MAX30100 sensors, in my code I manage to initialize i2c communication but I could not read the sensor data from the fifo buffer.

I even tried using Semaphore_post to make sure the task is still running but I end up on the same result

Note: I couldn't see the state of my task, thought the reason is because the task is static and not dynamic (created by construct function)

here below my code

/*
* I2C PINS : RF1.18(MOSI) SCL
* RF1.20(MISO) SDA
* */
/* I2C */
//#define Board_I2C0_SDA0 IOID_8 //RF1.20
//#define Board_I2C0_SCL0 IOID_9 //RF1.18
/* XDCtools Header files */
#include <xdc/std.h>
#include <stdint.h>
#include <stdlib.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Memory.h>
#include <xdc/runtime/Error.h>

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Clock.h>

/* TI-RTOS Header files */
#include <ti/drivers/PIN.h>
#include <ti/drivers/UART.h>
#include <ti/drivers/I2C.h>
#include <ti/drivers/i2c/I2CCC26XX.h>

/* Board Header files */
#include "Board.h"

/* MAX30100 Header files */
#include "MAX30100_Registers.h"
#include "MAX30100_Filters.h"
#include "MAX30100_SpO2Calculator.h"
#include "ringbuffer.h"

/* MAX30100 defines */
#define MAX_BUFFER_SIZE 64

#define SLAVE_ADDR 0x57 //MAX30100 address

#define DEFAULT_MODE MAX30100_MODE_HRONLY
#define DEFAULT_SAMPLING_RATE MAX30100_SAMPRATE_100HZ
#define MAX30100_SPC_PW_16BITS MAX30100_SPC_PW_1600US_16BITS
#define MAX30100_SPC_PW_13BITS MAX30100_SPC_PW_200US_13BITS
#define DEFAULT_RED_LED_CURRENT MAX30100_LED_CURR_50MA
#define DEFAULT_IR_LED_CURRENT MAX30100_LED_CURR_50MA
#define RED_LED_CURRENT_START MAX30100_LED_CURR_27_1MA
#define EXPECTED_PART_ID 0x11

/* Stack Size */
#define I2CTASKSTACKSIZE 2048
#define UARTTASKSTACKSIZE 1024


/* Global memory storage for a PIN_Config table */
static PIN_State ledPinState;
PIN_Handle ledPinHandle;
/*
* Application LED pin configuration table:
* - All LEDs board LEDs are off.
*/
PIN_Config ledPinTable[] = {
Board_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
Board_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
PIN_TERMINATE
};
/* MAX30100 Variable */
ringBuffer_typedef(uint16_t, fifoBuffer);
fifoBuffer redBuffer, irBuffer;
fifoBuffer* redBuffer_ptr;
fifoBuffer* irBuffer_ptr;
static uint8_t tempo[6] = {0};

/* Semaphore Variable */
static Semaphore_Handle i2cSem;
/* I2C Config */

static uint8_t txBuffer[2];
static uint8_t rxBuffer[MAX_BUFFER_SIZE];
static bool transferDone = false;
static I2C_Handle i2c;
static I2C_Params i2cParams;
static I2C_Transaction i2cTransaction;

Task_Struct i2cTaskStruct;
Char i2cTaskStack[I2CTASKSTACKSIZE];

Task_Struct uartTaskStruct;
Char uartTaskStack[UARTTASKSTACKSIZE];
/*I2C State Machine functions */
uint8_t readRegister(uint8_t slv_reg);
void writeRegister(uint8_t slv_reg, uint8_t data);
void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
bool begin();
uint8_t getPartId();
void setMode(Mode mode);
void setLedsPulseWidth(LEDPulseWidth ledPulseWidth);
void setSamplingRate(SamplingRate samplingRate);
void setLedsCurrent(LEDCurrent irLedCurrent, LEDCurrent redLedCurrent);
void setHighresModeEnabled(bool enabled);
void readFifoData();
void burstRead(uint8_t baseAddress, uint8_t *buffer, uint8_t length);
bool getRawValues(uint16_t *ir, uint16_t *red);

static Void taskFxn(UArg arg0, UArg arg1);

/******************** Read Register ************************/
uint8_t readRegister(uint8_t slv_reg)
{
txBuffer[0] = slv_reg;
i2cTransaction.slaveAddress = SLAVE_ADDR;
i2cTransaction.writeBuf = txBuffer;
i2cTransaction.writeCount = 1;
i2cTransaction.readBuf = rxBuffer;
i2cTransaction.readCount = 1;
if( I2C_transfer(i2c, &i2cTransaction))
{
return rxBuffer[0];
}
else
{
System_printf("I2C Error Reading \n");
System_flush();
return 0;
}

}

void burstRead(uint8_t baseAddress, uint8_t *buffer, uint8_t length)
{
txBuffer[0] = baseAddress;
i2cTransaction.slaveAddress = SLAVE_ADDR;
i2cTransaction.writeBuf = txBuffer;
i2cTransaction.writeCount = 1;
i2cTransaction.readBuf = rxBuffer;
i2cTransaction.readCount = length;
if(I2C_transfer(i2c, &i2cTransaction))
{
CopyArray(rxBuffer, buffer, length);
}
else
{
System_printf("I2C Error Burst Reading \n");
System_flush();
}

}

/********************* Write Rgister ***********************/
void writeRegister(uint8_t slv_reg, uint8_t data)
{
txBuffer[0] = slv_reg;
txBuffer[1] = data;

i2cTransaction.slaveAddress = SLAVE_ADDR;
i2cTransaction.writeBuf = txBuffer;
i2cTransaction.writeCount =2;
i2cTransaction.readBuf = rxBuffer;
i2cTransaction.readCount =0;
I2C_transfer(i2c, &i2cTransaction);

}

void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
{
uint8_t copyIndex = 0;
for (copyIndex = 0; copyIndex < count; copyIndex++)
{
dest[copyIndex] = source[copyIndex];
}
}

bool begin()
{
if(getPartId() != EXPECTED_PART_ID)
return false;

setMode(DEFAULT_MODE);
setLedsPulseWidth(MAX30100_SPC_PW_13BITS);// remember to change it every time you change sample rate
setSamplingRate(MAX30100_SAMPRATE_1000HZ);
setLedsCurrent(DEFAULT_IR_LED_CURRENT, DEFAULT_RED_LED_CURRENT);
setHighresModeEnabled(true);

bufferInit(redBuffer,16, uint16_t);
bufferInit(irBuffer,16, uint16_t);
redBuffer_ptr = &redBuffer;
irBuffer_ptr = &irBuffer;

return true;
}

uint8_t getPartId()
{
return readRegister(MAX30100_REG_PART_ID);
}

void setMode(Mode mode)
{
writeRegister(MAX30100_REG_MODE_CONFIGURATION, mode);
}

void setLedsPulseWidth(LEDPulseWidth ledPulseWidth)
{
uint8_t previous = readRegister(MAX30100_REG_SPO2_CONFIGURATION);
writeRegister(MAX30100_REG_SPO2_CONFIGURATION, (previous & 0xfc) | ledPulseWidth);
}

void setSamplingRate(SamplingRate samplingRate)
{
uint8_t previous = readRegister(MAX30100_REG_SPO2_CONFIGURATION);
writeRegister(MAX30100_REG_SPO2_CONFIGURATION, (previous & 0xe3) | (samplingRate << 2));
}

void setLedsCurrent(LEDCurrent irLedCurrent, LEDCurrent redLedCurrent)
{
writeRegister(MAX30100_REG_LED_CONFIGURATION, redLedCurrent << 4 | irLedCurrent);
}

void setHighresModeEnabled(bool enabled)
{
uint8_t previous = readRegister(MAX30100_REG_SPO2_CONFIGURATION);
if (enabled) {
writeRegister(MAX30100_REG_SPO2_CONFIGURATION, previous | MAX30100_SPC_SPO2_HI_RES_EN);
} else {
writeRegister(MAX30100_REG_SPO2_CONFIGURATION, previous & ~MAX30100_SPC_SPO2_HI_RES_EN);
}
}


void readFifoData()
{
uint8_t buffer[MAX30100_FIFO_DEPTH*4];
uint8_t toRead, i;
uint16_t redWrite, irWrite;

toRead = (readRegister(MAX30100_REG_FIFO_WRITE_POINTER) - readRegister(MAX30100_REG_FIFO_READ_POINTER)) & (MAX30100_FIFO_DEPTH-1);

if(toRead)
{
burstRead(MAX30100_REG_FIFO_DATA, buffer, 4 * toRead);

for (i=0 ; i < toRead ; ++i)
{
irWrite = (uint16_t)((buffer[i*4] << 8) | buffer[i*4 + 1]);
redWrite = ((buffer[i*4 + 2] << 8) | buffer[i*4 + 3]);
bufferWrite(irBuffer_ptr,irWrite);
bufferWrite(redBuffer_ptr,redWrite);
}
}

}

bool getRawValues(uint16_t *ir, uint16_t *red)
{
if(!isBufferEmpty(irBuffer_ptr) && !isBufferEmpty(redBuffer_ptr))
{
bufferRead(irBuffer_ptr, *ir);
bufferRead(redBuffer_ptr, *red);
return true;
}
else
return false;
}
/*
* ======== echoFxn ========
* Task for this function is created statically. See the project's .cfg file.
*/
static Void taskFxn(UArg arg0, UArg arg1)
{ /* Create a semaphore for Async */
Semaphore_Params semParams;
Error_Block eb;

/* Init params */
Semaphore_Params_init(&semParams);
Error_init(&eb);

/* Create semaphore instance */
i2cSem = Semaphore_create(0, &semParams, &eb);
/* Create I2C for usage */
I2C_Params_init(&i2cParams);
i2cParams.bitRate = I2C_400kHz;
i2cParams.transferMode = I2C_MODE_BLOCKING;
i2cParams.transferCallbackFxn = NULL;

i2c = I2C_open(0, &i2cParams);
//i2c = I2C_open(Board_I2C0, &i2cParams);
i2cTransaction.slaveAddress = SLAVE_ADDR;
if (i2c == NULL) {
System_abort("Error Initializing I2C\n");

}
else {
System_printf("I2C Initialized!\n");
System_flush();
}
/* Configure MAX30100 */
bool ready = begin();

if(!ready)
{
System_printf("Cannot Initialize MAX30100\n");
System_flush();
while(1);
}
Task_sleep(50);
PIN_setOutputValue(ledPinHandle, Board_LED2,!PIN_getOutputValue(Board_LED2));
setMode(MAX30100_MODE_SPO2_HR);
setLedsCurrent(DEFAULT_IR_LED_CURRENT, RED_LED_CURRENT_START);

setHighresModeEnabled(true);
writeRegister(MAX30100_REG_INTERRUPT_ENABLE, MAX30100_IE_ENB_SPO2_RDY); //enable SpO2 interruption
uint16_t rawIRValue, rawRedValue;
tempo[0] = 0xFF;
tempo[1] = 0xFF;
while(1){
System_printf("****** 1 ****\n" );
System_flush();
while(!(readRegister(MAX30100_REG_INTERRUPT_STATUS) & 0x10));// wait until the interrupt occur//change to 0x20 in case of HR IE
/* {
Semaphore_pend(i2cSem, BIOS_WAIT_FOREVER);
}*/

System_printf("****** 2 ****\n" );

readFifoData();
System_printf("****** 3 ****\n" );

while(getRawValues(&rawIRValue, &rawRedValue))
{
System_printf("****** 4 ****\n" );

tempo[2] = rawIRValue;
tempo[3] = (rawIRValue >> 8);
tempo[4] = rawRedValue;
tempo[5] = (rawRedValue >> 8);
for(i = 0; i<6; i++){
System_printf("%u : \n",tempo[i] );
System_flush();
}
// Semaphore_post(i2cSem);
}

/* else{
System_printf("I2C Bus fault\n");
}*/


//System_flush();
// Task_sleep(1000000 / Clock_tickPeriod);
}

/* Deinitialized I2C */
I2C_close(i2c);
System_printf("I2C closed!\n");

System_flush();
}

/*
* ======== main ========
*/
int main(void)
{

Task_Params taskParams;

/* Call board init functions */
Board_initGeneral();
Board_initI2C();

/* Construct I2C Task thread */
Task_Params_init(&taskParams);
taskParams.stackSize = I2CTASKSTACKSIZE;
taskParams.stack = &i2cTaskStack;
taskParams.priority = 2;
Task_construct(&i2cTaskStruct, (Task_FuncPtr)taskFxn, &taskParams, NULL);

/* Open LED pins */
ledPinHandle = PIN_open(&ledPinState, ledPinTable);
if(!ledPinHandle) {
System_abort("Error initializing board LED pins\n");
}

PIN_setOutputValue(ledPinHandle, Board_LED1, 1);

System_printf("Starting the I2C example\nSystem provider is set to SysMin."
" Halt the target to view any SysMin contents in ROV.\n");
/* SysMin will only print to the console when you call flush or exit */
System_flush();

/* Start BIOS */
BIOS_start();

return (0);
}

when i debegged the program i figured out that  the function "getRawValues(&rawIRValue, &rawRedValue)" always return false

here the console

here below the output of the SCL(yellow) and SDA(Blue) signals

I will appreciate any help to solve my problem

Best regards