Private
Public Access
2
0

ftdi_ft4222: Fixed i2c synchronization bug

Synchronization must be done at "context" level so that i2c bus
cannot be unexpectedly changed by a different thread.

Signed-off-by: Henry Bruce <henry.bruce@intel.com>
Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
This commit is contained in:
Henry Bruce
2016-02-12 13:57:39 -08:00
committed by Brendan Le Foll
parent 511332cda5
commit c770c4c669

View File

@@ -220,18 +220,15 @@ mraa_ftdi_ft4222_i2c_read_internal(FT_HANDLE handle, uint8_t addr, uint8_t* data
uint16 bytesRead = 0; uint16 bytesRead = 0;
uint8 controllerStatus; uint8 controllerStatus;
// syslog(LOG_NOTICE, "FT4222_I2CMaster_Read(%#02X, %#02X)", addr, length); // syslog(LOG_NOTICE, "FT4222_I2CMaster_Read(%#02X, %#02X)", addr, length);
mraa_ftdi_ft4222_sleep_ms(1); // mraa_ftdi_ft4222_sleep_ms(1);
pthread_mutex_lock(&ft4222_lock);
FT4222_STATUS ft4222Status = FT4222_I2CMaster_Read(handle, addr, data, length, &bytesRead); FT4222_STATUS ft4222Status = FT4222_I2CMaster_Read(handle, addr, data, length, &bytesRead);
ft4222Status = FT4222_I2CMaster_GetStatus(ftHandleI2c, &controllerStatus); ft4222Status = FT4222_I2CMaster_GetStatus(ftHandleI2c, &controllerStatus);
if (FT4222_OK != ft4222Status || I2CM_ERROR(controllerStatus)) { if (FT4222_OK != ft4222Status || I2CM_ERROR(controllerStatus)) {
syslog(LOG_ERR, "FT4222_I2CMaster_Read failed for address %#02x\n", addr); syslog(LOG_ERR, "FT4222_I2CMaster_Read failed for address %#02x\n", addr);
FT4222_I2CMaster_Reset(handle); FT4222_I2CMaster_Reset(handle);
pthread_mutex_unlock(&ft4222_lock);
return 0; return 0;
} }
// syslog(LOG_NOTICE, "FT4222_I2CMaster_Read completed"); // syslog(LOG_NOTICE, "FT4222_I2CMaster_Read completed");
pthread_mutex_unlock(&ft4222_lock);
return bytesRead; return bytesRead;
} }
@@ -241,20 +238,17 @@ mraa_ftdi_ft4222_i2c_write_internal(FT_HANDLE handle, uint8_t addr, const uint8_
uint16 bytesWritten = 0; uint16 bytesWritten = 0;
uint8 controllerStatus; uint8 controllerStatus;
// syslog(LOG_NOTICE, "FT4222_I2CMaster_Write(%#02X, %#02X, %d)", addr, *data, bytesToWrite); // syslog(LOG_NOTICE, "FT4222_I2CMaster_Write(%#02X, %#02X, %d)", addr, *data, bytesToWrite);
pthread_mutex_lock(&ft4222_lock);
FT4222_STATUS ft4222Status = FT4222_I2CMaster_Write(handle, addr, (uint8_t*) data, bytesToWrite, &bytesWritten); FT4222_STATUS ft4222Status = FT4222_I2CMaster_Write(handle, addr, (uint8_t*) data, bytesToWrite, &bytesWritten);
ft4222Status = FT4222_I2CMaster_GetStatus(ftHandleI2c, &controllerStatus); ft4222Status = FT4222_I2CMaster_GetStatus(ftHandleI2c, &controllerStatus);
if (FT4222_OK != ft4222Status || I2CM_ERROR(controllerStatus)) { if (FT4222_OK != ft4222Status || I2CM_ERROR(controllerStatus)) {
syslog(LOG_ERR, "FT4222_I2CMaster_Write failed address %#02x\n", addr); syslog(LOG_ERR, "FT4222_I2CMaster_Write failed address %#02x\n", addr);
FT4222_I2CMaster_Reset(handle); FT4222_I2CMaster_Reset(handle);
pthread_mutex_unlock(&ft4222_lock);
return 0; return 0;
} }
pthread_mutex_unlock(&ft4222_lock);
if (bytesWritten != bytesToWrite) if (bytesWritten != bytesToWrite)
syslog(LOG_ERR, "FT4222_I2CMaster_Write wrote %u of %u bytes.\n", bytesWritten, bytesToWrite); syslog(LOG_ERR, "FT4222_I2CMaster_Write wrote %u of %u bytes.\n", bytesWritten, bytesToWrite);
syslog(LOG_NOTICE, "FT4222_I2CMaster_Write completed"); // syslog(LOG_NOTICE, "FT4222_I2CMaster_Write completed");
return bytesWritten; return bytesWritten;
} }
@@ -322,19 +316,23 @@ mraa_ftdi_ft4222_i2c_select_bus(int bus)
static int static int
mraa_ftdi_ft4222_i2c_context_read(mraa_i2c_context dev, uint8_t* data, int length) mraa_ftdi_ft4222_i2c_context_read(mraa_i2c_context dev, uint8_t* data, int length)
{ {
int bytes_read = 0;
pthread_mutex_lock(&ft4222_lock);
if (mraa_ftdi_ft4222_i2c_select_bus(dev->busnum) == MRAA_SUCCESS) if (mraa_ftdi_ft4222_i2c_select_bus(dev->busnum) == MRAA_SUCCESS)
return mraa_ftdi_ft4222_i2c_read_internal(dev->handle, dev->addr, data, length); bytes_read = mraa_ftdi_ft4222_i2c_read_internal(dev->handle, dev->addr, data, length);
else pthread_mutex_unlock(&ft4222_lock);
return 0; return bytes_read;
} }
static int static int
mraa_ftdi_ft4222_i2c_context_write(mraa_i2c_context dev, uint8_t* data, int length) mraa_ftdi_ft4222_i2c_context_write(mraa_i2c_context dev, uint8_t* data, int length)
{ {
int bytes_written = 0;
pthread_mutex_lock(&ft4222_lock);
if (mraa_ftdi_ft4222_i2c_select_bus(dev->busnum) == MRAA_SUCCESS) if (mraa_ftdi_ft4222_i2c_select_bus(dev->busnum) == MRAA_SUCCESS)
return mraa_ftdi_ft4222_i2c_write_internal(dev->handle, dev->addr, data, length); bytes_written = mraa_ftdi_ft4222_i2c_write_internal(dev->handle, dev->addr, data, length);
else pthread_mutex_unlock(&ft4222_lock);
return 0; return bytes_written;
} }