# I2C can't read from FT201XS

I'm using a cypress microcontroller to read some values from the FT201XS-R chip. I can get acknowledgment, but I can't seem to read. Here's the datasheet. I'm attempting to do a read of register 4 of the MTP memory as outlined on page 39 of the datasheet.

Here's my code

int main{

uint8 WriteBuffer[16];

UART_1_Start();

// I added this because the I2C will be pulled low by a slave when addressing goes wrong. This helps to make it still work
while(I2C_1_sda_Read() == 0) // SDA hang low
{
I2C_1_SET_I2C_SCL_HSIOM_SEL(I2C_1_HSIOM_GPIO_SEL); //Switch to GPIO
I2C_1_scl_Write(0);
CyDelay(1);
I2C_1_scl_Write(1);
CyDelay(1);
I2C_1_SET_I2C_SCL_HSIOM_SEL(I2C_1_HSIOM_I2C_SEL); //Switch to Component
}

WriteBuffer[0] = 0x10; // this is the address mtp signal
status = i2c_send(0x00,WriteBuffer,1u);

WriteBuffer[0] = 0x00;
WriteBuffer[1] = 0x04; // this is register 4

WriteBuffer[0] = 0x14; // this is the mtp register read value
status = i2c_send(0x00,WriteBuffer,1u);

}

uint32 i2c_send(uint8 addr, uint8 * data, uint8 count){
uint32 status=1;
uint8 i =0;
uint8 check;
I2C_1_I2CMasterClearStatus();
while(status){
I2C_1_I2CMasterClearStatus();
I2C_1_I2CMasterSendStop();
CyDelay(10);
}

for (;i<count;i++){
check = *(data+i);
status = I2C_1_I2CMasterWriteByte(*(data+i));
}

I2C_1_I2CMasterSendStop();
CyDelay(10);
return status;

}

uint32 status;
CyDelay(10);
while(status){
I2C_1_I2CMasterClearStatus();
I2C_1_I2CMasterSendStop();
CyDelay(10);
}
I2C_1_I2CMasterSendStop();

}


I am able to do all of the I2C send commands, but when I try to do an I2C recieve, the status hangs on 2, which is the SCB_I2C_MSTR_NOT_READY error. This corresponds to this description:

Master is not ready for to start transfer. A master still has not completed previous transaction or a slave operation is in progress (in multi-master-slave configuration). Nothing was sent on the bus. The attempt has to be retried.

What do I need to change to get the register read to work?

EDIT ***************

I created a new function to perform the read

uint32 i2c_read_mem(uint8 addr, uint8 reg){
uint32 status=1;
uint8 i =0;
uint8 check;

status = I2C_1_I2CMasterSendStart(0x00, 0);
status = I2C_1_I2CMasterWriteByte(0x10);
status = I2C_1_I2CMasterWriteByte(0x00);
status = I2C_1_I2CMasterWriteByte(reg);
status = I2C_1_I2CMasterSendRestart(0x00,0);
status = I2C_1_I2CMasterWriteByte(0x14);
I2C_1_I2CMasterSendStop();

}


With this function, I2C no longer hangs, but it always returns 0. According to this document, I should see the usb vid at byte 2 and 3. yet when I run

for (i=0; i<20; i++){
CyDelay(1);
}


all values returned are 0.

Your abstraction layer is too high, you need to either use the low-level I2C actions for this, or else add a parameter to i2c_send to inhibit the STOP action at the end.
• @LegenDiary: Now that you're using restarts, are you getting acknowledge (the status variable in your new code)? The datasheet says "The acknowledge during the command phase indicates whether or not the MTP memory will be able to service the read request." – Ben Voigt Oct 23 '15 at 22:46