static int mraa_ftdi_ft4222_i2c_read_bytes_data(mraa_i2c_context dev, uint8_t command, uint8_t* data, int length) { if (mraa_ftdi_ft4222_i2c_write_internal(dev->handle, dev->addr, &command, 1) != 1) return 0; return mraa_ftdi_ft4222_i2c_read_internal(dev->handle, dev->addr, data, length); }
static mraa_result_t mraa_ftdi_ft4222_gpio_write_replace(mraa_gpio_context dev, int write_value) { uint8_t pin = dev->pin; if (mraa_ftdi_ft4222_is_internal_gpio(pin)) { // FTDI GPIO FT4222_STATUS ft4222Status = FT4222_GPIO_Write(ftHandleGpio, dev->phy_pin, write_value); if (FT4222_OK != ft4222Status) { syslog(LOG_ERR, "FT4222_GPIO_Write failed (error %d)!\n", ft4222Status); return MRAA_ERROR_UNSPECIFIED; } } else { // Expander GPIO uint8_t mask = 1 << dev->phy_pin; uint8_t value; if (mraa_ftdi_ft4222_i2c_read_internal(ftHandleI2c, PCA9672_ADDR, &value, 1) != 1) return MRAA_ERROR_UNSPECIFIED; if (write_value == 1) value |= mask; else value &= (~mask); if (mraa_ftdi_ft4222_i2c_write_internal(ftHandleI2c, PCA9672_ADDR, &value, 1) != 1) return MRAA_ERROR_UNSPECIFIED; } return MRAA_SUCCESS; }
static int mraa_ftdi_ft4222_i2c_context_read(mraa_i2c_context dev, uint8_t* data, int length) { if (mraa_ftdi_ft4222_i2c_select_bus(dev->busnum) == MRAA_SUCCESS) return mraa_ftdi_ft4222_i2c_read_internal(dev->handle, dev->addr, data, length); else return 0; }
static int mraa_ftdi_ft4222_i2c_context_read(mraa_i2c_context dev, uint8_t* data, int length) { int bytes_read = 0; if (mraa_ftdi_ft4222_i2c_select_bus(dev->busnum) == MRAA_SUCCESS) bytes_read = mraa_ftdi_ft4222_i2c_read_internal(dev->handle, dev->addr, data, length); return bytes_read; }
static int mraa_ftdi_ft4222_i2c_read(mraa_i2c_context dev, uint8_t* data, int length) { pthread_mutex_lock(&ft4222_lock); int bytes_read = mraa_ftdi_ft4222_i2c_read_internal(dev->handle, dev->addr, data, length); pthread_mutex_unlock(&ft4222_lock); return bytes_read; }
static uint8_t mraa_ftdi_ft4222_i2c_read_byte(mraa_i2c_context dev) { uint8_t data; if (mraa_ftdi_ft4222_i2c_read_internal(dev->handle, dev->addr, &data, 1) == 1) return data; else return 0; }
// Function detects known I2C I/O expanders and returns the number of GPIO pins on expander static int mraa_ftdi_ft4222_detect_io_expander() { uint8_t data; if(mraa_ftdi_ft4222_i2c_read_internal(ftHandleI2c, PCA9672_ADDR, &data, 1) == 1) { return PCA9672_PINS; } return 0; }
static int mraa_ftdi_ft4222_gpio_read_replace(mraa_gpio_context dev) { uint8_t pin = dev->phy_pin; uint8_t mask = 1 << pin; uint8_t value; if (mraa_ftdi_ft4222_i2c_read_internal(ftHandle, PCA9672_ADDR, &value, 1) != 1) return -1; return (value & mask) == mask; }
// Function detects known I2C switches and returns the number of busses. // On startup switch is disabled so default bus will be integrated i2c bus. static int mraa_ftdi_ft4222_detect_i2c_switch() { uint8_t data; if(mraa_ftdi_ft4222_i2c_read_internal(ftHandleI2c, PCA9545_ADDR, &data, 1) == 1) { data = 0; return mraa_ftdi_ft4222_i2c_write_internal(ftHandleI2c, PCA9545_ADDR, &data, 1) == 1 ? PCA9545_BUSSES : 0; } return 0; }
static mraa_result_t mraa_ftdi_ft4222_i2c_read_io_expander(uint16_t* value) { int bytes_read = 0; uint8_t reg = PCA9555_INPUT_REG; pthread_mutex_lock(&ft4222_lock); switch (gpio_expander_chip) { case IO_EXP_PCA9672: bytes_read = mraa_ftdi_ft4222_i2c_read_internal(ftHandleI2c, PCA9672_ADDR, (uint8_t*)value, 1); break; case GPIO_TYPE_PCA9555: if (mraa_ftdi_ft4222_i2c_write_internal(ftHandleI2c, PCA9555_ADDR, ®, 1) == 1) bytes_read = mraa_ftdi_ft4222_i2c_read_internal(ftHandleI2c, PCA9555_ADDR, (uint8_t*)value, 2); break; default:; } pthread_mutex_unlock(&ft4222_lock); return bytes_read > 0 ? MRAA_SUCCESS : MRAA_ERROR_UNSPECIFIED; }
static uint16_t mraa_ftdi_ft4222_i2c_read_word_data(mraa_i2c_context dev, uint8_t command) { uint8_t buf[2]; uint16_t data; if (mraa_ftdi_ft4222_i2c_write_internal(dev->handle, dev->addr, &command, 1) != 1) return 0; if (mraa_ftdi_ft4222_i2c_read_internal(dev->handle, dev->addr, buf, 2) != 2) return 0; data = *(uint16_t*)buf; return data; }
// Function detects known I2C I/O expanders and returns the number of GPIO pins on expander static int mraa_ftdi_ft4222_detect_io_expander() { uint8_t data; if (mraa_ftdi_ft4222_i2c_read_internal(ftHandleI2c, PCA9672_ADDR, &data, 1) == 1) { gpio_expander_chip = IO_EXP_PCA9672; return PCA9672_PINS; } else if (mraa_ftdi_ft4222_i2c_read_internal(ftHandleI2c, PCA9555_ADDR, &data, 1) == 1) { gpio_expander_chip = IO_EXP_PCA9555; uint8_t reg = PCA9555_OUTPUT_REG; mraa_ftdi_ft4222_i2c_write_internal(ftHandleI2c, PCA9555_ADDR, ®, 1); mraa_ftdi_ft4222_i2c_read_internal(ftHandleI2c, PCA9555_ADDR, (uint8_t*)&pca9555OutputValue, 2); reg = PCA9555_DIRECTION_REG; mraa_ftdi_ft4222_i2c_write_internal(ftHandleI2c, PCA9555_ADDR, ®, 1); mraa_ftdi_ft4222_i2c_read_internal(ftHandleI2c, PCA9555_ADDR, (uint8_t*)&pca9555DirectionValue, 2); return PCA9555_PINS; } else { gpio_expander_chip = IO_EXP_NONE; return 0; } }
static mraa_result_t mraa_ftdi_ft4222_gpio_write_replace(mraa_gpio_context dev, int write_value) { switch (mraa_ftdi_ft4222_get_gpio_type(dev->pin)) { case GPIO_TYPE_BUILTIN: { FT4222_STATUS ft4222Status = dl_FT4222_GPIO_Write(ftHandleGpio, dev->phy_pin, write_value); if (FT4222_OK != ft4222Status) { syslog(LOG_ERR, "FT4222_GPIO_Write failed (error %d)!\n", ft4222Status); return MRAA_ERROR_UNSPECIFIED; } return MRAA_SUCCESS; } case GPIO_TYPE_PCA9672: { uint8_t mask = 1 << dev->phy_pin; uint8_t value; int bytes_written = 0; pthread_mutex_lock(&ft4222_lock); int bytes_read = mraa_ftdi_ft4222_i2c_read_internal(ftHandleI2c, PCA9672_ADDR, &value, 1); if (bytes_read == 1) { if (write_value == 1) value = value | mask | pca9672DirectionMask; else value &= (~mask); bytes_written = mraa_ftdi_ft4222_i2c_write_internal(ftHandleI2c, PCA9672_ADDR, &value, 1); } pthread_mutex_unlock(&ft4222_lock); return bytes_written == 1 ? MRAA_SUCCESS : MRAA_ERROR_UNSPECIFIED; } case GPIO_TYPE_PCA9555: { uint16_t mask = 1 << dev->phy_pin; if (write_value) pca9555OutputValue |= mask; else pca9555OutputValue &= (~mask); uint8_t buf[3]; buf[0] = PCA9555_OUTPUT_REG; buf[1] = (uint8_t)(pca9555OutputValue & 0xFF); buf[2] = (uint8_t)(pca9555OutputValue >> 8); pthread_mutex_lock(&ft4222_lock); int bytes_written = mraa_ftdi_ft4222_i2c_write_internal(ftHandleI2c, PCA9555_ADDR, buf, sizeof(buf)); pthread_mutex_unlock(&ft4222_lock); return bytes_written == sizeof(buf) ? MRAA_SUCCESS : MRAA_ERROR_UNSPECIFIED; } default: return MRAA_ERROR_INVALID_RESOURCE; } }
static mraa_result_t mraa_ftdi_ft4222_gpio_write_replace(mraa_gpio_context dev, int write_value) { uint8_t pin = dev->phy_pin; uint8_t mask = 1 << pin; uint8_t value; if (mraa_ftdi_ft4222_i2c_read_internal(ftHandle, PCA9672_ADDR, &value, 1) != 1) return MRAA_ERROR_UNSPECIFIED; if (write_value == 1) value |= mask; else value &= (~mask); if (mraa_ftdi_ft4222_i2c_write_internal(ftHandle, PCA9672_ADDR, &value, 1) != 1) return MRAA_ERROR_UNSPECIFIED; return MRAA_SUCCESS; }
static int mraa_ftdi_ft4222_gpio_read_replace(mraa_gpio_context dev) { uint8_t pin = dev->pin; if (mraa_ftdi_ft4222_is_internal_gpio(pin)) { // FTDI GPIO BOOL value; FT4222_STATUS ft4222Status = FT4222_GPIO_Read(ftHandleGpio, dev->phy_pin, &value); if (FT4222_OK != ft4222Status) { syslog(LOG_ERR, "FT4222_GPIO_Read failed (error %d)!\n", ft4222Status); return -1; } return value; } else { // Expander GPIO uint8_t mask = 1 << dev->phy_pin; uint8_t value; if (mraa_ftdi_ft4222_i2c_read_internal(ftHandleI2c, PCA9672_ADDR, &value, 1) != 1) return -1; return (value & mask) == mask; } }
static mraa_boolean_t mraa_ftdi_ft4222_detect_io_expander() { uint8_t data; return mraa_ftdi_ft4222_i2c_read_internal(ftHandle, PCA9672_ADDR, &data, 1) == 1; }
static int mraa_ftdi_ft4222_i2c_read(mraa_i2c_context dev, uint8_t* data, int length) { return mraa_ftdi_ft4222_i2c_read_internal(dev->handle, dev->addr, data, length); }