Thank You for your reply.
Set the latency timer to a value appropriate for the application. Note that a low latency timer
value may result in many short incoming USB packets rather than a single large packet, thus
diminishing performance.
The latency timer is set to 16 ms (the default). Changing the value has only a very small effect on the gaps and and absolutely no effect on the CPU load on Linux.
you should also refer to section 5.3 of the FT4222 datasheet: https://ftdichip.com/wp-content/uploads/2020/07/DS_FT4222H.pdf
This section outlines the I2C bus interface.
I do not understand how this relates to the problem I am reporting here.
also which example are you referring to? the one shown in the LibFT4222 user guide or the one included in the library download?
From the library download. To illustrate my problem I modified the contained I2C example like this:
static int exercise4222(DWORD locationId)
{
int success = 0;
FT_STATUS ftStatus;
FT_HANDLE ftHandle = (FT_HANDLE)NULL;
FT4222_STATUS ft4222Status;
FT4222_Version ft4222Version;
const uint16 slaveAddr = 0x58;
uint16 bytesToRead ;
uint16 bytesRead = 0;
uint16 bytesToWrite;
uint16 bytesWritten = 0;
char *writeBuffer;
uint8_t pageBuffer[BYTES_PER_PAGE + 1];
int page;
ftStatus = FT_OpenEx((PVOID)(uintptr_t)locationId,
FT_OPEN_BY_LOCATION,
&ftHandle);
if (ftStatus != FT_OK)
{
printf("FT_OpenEx failed (error %d)\n",
(int)ftStatus);
goto exit;
}
ft4222Status = FT4222_GetVersion(ftHandle,
&ft4222Version);
if (FT4222_OK != ft4222Status)
{
printf("FT4222_GetVersion failed (error %d)\n",
(int)ft4222Status);
goto exit;
}
printf("Chip version: %08X, LibFT4222 version: %08X\n",
(unsigned int)ft4222Version.chipVersion,
(unsigned int)ft4222Version.dllVersion);
// Configure the FT4222 as an I2C Master
ft4222Status = FT4222_I2CMaster_Init(ftHandle, 400);
if (FT4222_OK != ft4222Status)
{
printf("FT4222_I2CMaster_Init failed (error %d)!\n",
ft4222Status);
goto exit;
}
// Reset the I2CM registers to a known state.
ft4222Status = FT4222_I2CMaster_Reset(ftHandle);
if (FT4222_OK != ft4222Status)
{
printf("FT4222_I2CMaster_Reset failed (error %d)!\n",
ft4222Status);
goto exit;
}
for (;;) {
// Sequential read from slave EEPROM's current word address.
uint8_t content[512];
bytesToRead = sizeof(content);
ft4222Status = FT4222_I2CMaster_Read(ftHandle,
slaveAddr,
content,
bytesToRead,
&bytesRead);
if (FT4222_OK != ft4222Status)
{
printf("FT4222_I2CMaster_Read failed (error %d)\n",
(int)ft4222Status);
goto exit;
}
if (bytesRead != bytesToRead)
{
printf("FT4222_I2CMaster_Read read %u of %u bytes.\n",
bytesRead,
bytesToRead);
goto exit;
}
usleep(100000);
}
success = 1;
exit:
if (ftHandle != (FT_HANDLE)NULL)
{
(void)FT4222_UnInitialize(ftHandle);
(void)FT_Close(ftHandle);
}
return success;
}
It reads out 512 byte chunks in a loop with 100ms sleep in between transfers.
- There are still gaps between 8µs and 17µs between each byte
- The CPU load on a RPi3b is >50% which is unexpectedly high. On a RPi0 it is even higher due to the slower CPU.
I found the following note in the errata (3.1.2):
The FT4222H doesn’t support the latency timer feature and causes the USB scheduler to be busy and
uses too much CPU resource.
This looks exactly like what I am seeing, but I have chip revision D.
Can you reproduce this issue? How to solve it?