Thanks for the answer, and sorry for the delay, I had to work on other stuff.
Here is the I2C read function:
uint8_t *readI2C(uint32_t address, uint32_t size, uint8_t slave)
{
i2c_master_transfer_t masterXfer = {0};
/*if size is bigger than buffer, return error*/
if(size > I2C_DATA_LENGTH)
{
return NULL;
}
/*lock I2C*/
if( lockI2C() < 0 )
{
//could not lock i2c - return null pointer
return NULL;
}
/* subAddress = 0x01, data = i2cTransfers.receiveBfr - read from slave.
start + slaveaddress(w) + subAddress + repeated start + slaveaddress(r) + rx data buffer + stop */
masterXfer.slaveAddress = slave;
masterXfer.direction = kI2C_Read;
masterXfer.subaddress = address;
masterXfer.subaddressSize = 1;
masterXfer.data = i2cTransfers.receiveBfr;
masterXfer.dataSize = size;
masterXfer.flags = kI2C_TransferDefaultFlag;
/* Reset master completion flag to false. */
setNotCompletedI2C();
if ( I2C_MasterTransferNonBlocking(I2C_MASTER, &g_m_handle, &masterXfer) != kStatus_Success )
{
/*free lock and return*/
freeI2C();
return NULL;
}
/* Wait for transfer completed. */
while (!isCompletedI2C()) {};
/*check for errors*/
if( isErrorI2C() )
{
/*free lock, clean error flag and return*/
freeI2C();
resetErrorI2C();
return NULL;
}
//change the completed flag
setNotCompletedI2C();
//remove the lock
freeI2C();
//return data pointer
return i2cTransfers.receiveBfr;
}
Example of I2C read from main function:
uint8_t *buf = readI2C(0x00, 5, 57);
for(int i = 0 ; i < 5 ; i ++)
usb_echo("%02x: %02x\r\n",i, buf[i]);
Output:
0: 0
1: 0
2: 1
3: 20
4: 71
Signals:

Now doing the same from a ctimer callback:
void callback()
{
usb_echo("READ START:\r\n");
uint8_t *buf = readI2C(0x00, 5, 57);
for(int i = 0 ; i < 5 ; i ++)
usb_echo("%02x: %02x\r\n",i, buf[i]);
usb_echo("READ END\r\n");
}
ctimer_callback_t ctimerCallbackTable[] = {
NULL, callback, callback, NULL, NULL, NULL, NULL, NULL};
/*init ctimer*/
void initCTIMER()
{
ctimer_config_t config;
ctimer_match_config_t matchConfig;
/*init ctimer*/
CTIMER_GetDefaultConfig(&config);
CTIMER_Init(CONSUMPTION_ADC_CTIMER_BASE, &config);
/* set timer configuration */
matchConfig.enableCounterReset = true;
matchConfig.enableCounterStop = false;
matchConfig.matchValue = CONSUMPTION_ADC_CTIMER_CLK_FREQ * 5;//5 sec
matchConfig.outControl = kCTIMER_Output_Toggle;
matchConfig.outPinInitState = false;
matchConfig.enableInterrupt = true;
/*register timer callback*/
CTIMER_RegisterCallBack(CONSUMPTION_ADC_CTIMER_BASE, &ctimerCallbackTable[0], kCTIMER_MultipleCallback);
CTIMER_SetupMatch(CONSUMPTION_ADC_CTIMER_BASE, CONSUMPTION_ADC_CTIMER_MAT0_OUT, &matchConfig);
/*init timer*/
CTIMER_StartTimer(CONSUMPTION_ADC_CTIMER_BASE);
}
Output (appears after 5 seconds):
READ START:
Signals:

Adding more debug prints:
uint8_t *readI2C(uint32_t address, uint32_t size, uint8_t slave)
{
i2c_master_transfer_t masterXfer = {0};
/*if size is bigger than buffer, return error*/
if(size > I2C_DATA_LENGTH)
{
return NULL;
}
usb_echo("1\r\n");
/*lock I2C*/
if( lockI2C() < 0 )
{
//could not lock i2c - return null pointer
return NULL;
}
usb_echo("2\r\n");
/* subAddress = 0x01, data = i2cTransfers.receiveBfr - read from slave.
start + slaveaddress(w) + subAddress + repeated start + slaveaddress(r) + rx data buffer + stop */
masterXfer.slaveAddress = slave;
masterXfer.direction = kI2C_Read;
masterXfer.subaddress = address;
masterXfer.subaddressSize = 1;
masterXfer.data = i2cTransfers.receiveBfr;
masterXfer.dataSize = size;
masterXfer.flags = kI2C_TransferDefaultFlag;
/* Reset master completion flag to false. */
setNotCompletedI2C();
usb_echo("3\r\n");
if ( I2C_MasterTransferNonBlocking(I2C_MASTER, &g_m_handle, &masterXfer) != kStatus_Success )
{
/*free lock and return*/
usb_echo("4\r\n");
freeI2C();
return NULL;
}
usb_echo("5\r\n");
/* Wait for transfer completed. */
while (!isCompletedI2C()) {};
usb_echo("6\r\n");
/*check for errors*/
if( isErrorI2C() )
{
/*free lock, clean error flag and return*/
freeI2C();
resetErrorI2C();
return NULL;
}
//change the completed flag
setNotCompletedI2C();
//remove the lock
freeI2C();
//return data pointer
return i2cTransfers.receiveBfr;
}
Output:
READ START:
1
2
3
5
So code is stuck in loop
while (!isCompletedI2C()) {};
Which is implemented:
bool isCompletedI2C()
{
return i2cTransfers.completed;
}
This flag is changed to true from setCompletedI2C function
void setCompletedI2C(I2C_Type *base, i2c_master_handle_t *handle, status_t status, void *userData)
{
i2cTransfers.completed = true;
/*indicates if an error occured*/
i2cTransfers.transferError = status != kStatus_Success;
}
Which is registered as the I2C handle in initI2C function (initI2C is called from main)
void initI2C()
{
i2c_master_config_t masterConfig;
/*reset flexcomm*/
RESET_PeripheralReset(kFC5_RST_SHIFT_RSTn);
/*init i2c struct parameters*/
initStructI2C();
/*get i2c master config*/
I2C_MasterGetDefaultConfig(&masterConfig);
/*set baudrate*/
masterConfig.baudRate_Bps = I2C_BAUDRATE;
/*init i2c*/
I2C_MasterInit(I2C_MASTER, &masterConfig, I2C_MASTER_CLOCK_FREQUENCY);
/* Create the I2C handle for the non-blocking transfer */
I2C_MasterTransferCreateHandle(I2C_MASTER, &g_m_handle, setCompletedI2C, NULL);
}
Maybe you know what's wrong?
Thanks