static mraa_result_t mraa_ftdi_ft4222_gpio_wait_interrupt_replace(mraa_gpio_context dev) { int prev_level = mraa_ftdi_ft4222_gpio_read_replace(dev); mraa_boolean_t is_internal_pin = mraa_ftdi_ft4222_is_internal_gpio(dev->pin); mraa_boolean_t interrupt_detected = FALSE; // INT pin of i2c PCA9672 GPIO expander is connected to FT4222 GPIO #3 // We use INT to detect any expander GPIO level change while (!dev->isr_thread_terminating && !interrupt_detected) { if (is_internal_pin) { interrupt_detected = mraa_ftdi_ft4222_has_internal_gpio_triggered(dev->phy_pin); } else { mraa_boolean_t gpio_activity_detected = mraa_ftdi_ft4222_has_internal_gpio_triggered(GPIO_PORT_IO_INT); if (gpio_activity_detected) { int level = mraa_ftdi_ft4222_gpio_read_replace(dev); if (level != prev_level) { interrupt_detected = TRUE; } } } if (!interrupt_detected) mraa_ftdi_ft4222_sleep_ms(20); } return MRAA_SUCCESS; }
static mraa_result_t mraa_ftdi_ft4222_gpio_wait_interrupt_replace(mraa_gpio_context dev) { int prev_level = mraa_ftdi_ft4222_gpio_read_replace(dev); ft4222_gpio_type gpio_type = mraa_ftdi_ft4222_get_gpio_type(dev->pin); mraa_boolean_t interrupt_detected = FALSE; while (!dev->isr_thread_terminating && !interrupt_detected) { switch (gpio_type) { case GPIO_TYPE_BUILTIN: interrupt_detected = mraa_ftdi_ft4222_has_internal_gpio_triggered(dev->phy_pin); break; case GPIO_TYPE_PCA9672: case GPIO_TYPE_PCA9555: interrupt_detected = mraa_ftdi_ft4222_gpio_monitor_is_interrupt_detected(dev->phy_pin); break; default:; } if (!interrupt_detected) mraa_ftdi_ft4222_sleep_ms(20); } if (dev->isr_thread_terminating) mraa_ftdi_ft4222_gpio_monitor_remove_pin(dev->phy_pin); return MRAA_SUCCESS; }
static void* mraa_ftdi_ft4222_gpio_interrupt_handler_replace(mraa_gpio_context dev) { #ifdef USE_FT4222_GPIO_TRIGGER // FIXME: Use big buffer; shouldn't be more than this many events to read GPIO_Trigger event_buf[256]; int prev_level = mraa_ftdi_ft4222_gpio_read_replace(dev); while (1) { uint16 num_events = 0; FT4222_STATUS status = FT4222_GPIO_GetTriggerStatus(ftHandleGpio, GPIO_PORT_IO_STATUS, &num_events); if (status != FT4222_OK) printf("FT4222_GPIO_GetTriggerStatus failed with code %d\n", status); printf("%u: FT4222_GPIO_GetTriggerStatus Events = %d\n", mraa_ftdi_ft4222_get_tick_count_ms(), num_events); if (num_events > 0) { int level = mraa_ftdi_ft4222_gpio_read_replace(dev); uint16 num_events_read; FT4222_GPIO_ReadTriggerQueue(ftHandleGpio, GPIO_PORT_IO_STATUS, event_buf, num_events, &num_events_read); // printf("%u: FT4222_GPIO_ReadTriggerQueue Events= %d\n", mraa_ftdi_ft4222_get_tick_count_ms(), num_events_read); printf("%u: level = %d\n", mraa_ftdi_ft4222_get_tick_count_ms(), level); if (level != prev_level) { dev->isr(dev->isr_args); prev_level = level; } } mraa_ftdi_ft4222_sleep_ms(20); // int level = mraa_ftdi_ft4222_gpio_read_replace(dev); // printf("level = %d\n", level); } #else int prev_level = mraa_ftdi_ft4222_gpio_read_replace(dev); while (1) { int level = mraa_ftdi_ft4222_gpio_read_replace(dev); // MRAA_GPIO_EDGE_BOTH if (level != prev_level) { dev->isr(dev->isr_args); prev_level = level; } mraa_ftdi_ft4222_sleep_ms(100); } #endif return NULL; }
static void* mraa_ftdi_ft4222_gpio_interrupt_handler_replace(mraa_gpio_context dev) { int prev_level = mraa_ftdi_ft4222_gpio_read_replace(dev); while (1) { int level = mraa_ftdi_ft4222_gpio_read_replace(dev); if (level != prev_level) { dev->isr(dev->isr_args); prev_level = level; } // printf("mraa_ftdi_ft4222_gpio_interrupt_handler_replace\n"); mraa_ftdi_ft4222_sleep_ms(100); } return NULL; }
static int mraa_ftdi_ft4222_i2c_read_internal(FT_HANDLE handle, uint8_t addr, uint8_t* data, int length) { uint16 bytesRead = 0; uint8 controllerStatus; // syslog(LOG_NOTICE, "FT4222_I2CMaster_Read(%#02X, %#02X)", addr, length); mraa_ftdi_ft4222_sleep_ms(1); pthread_mutex_lock(&ft4222_lock); FT4222_STATUS ft4222Status = FT4222_I2CMaster_Read(handle, addr, data, length, &bytesRead); ft4222Status = FT4222_I2CMaster_GetStatus(ftHandleI2c, &controllerStatus); if (FT4222_OK != ft4222Status || I2CM_ERROR(controllerStatus)) { syslog(LOG_ERR, "FT4222_I2CMaster_Read failed for address %#02x\n", addr); FT4222_I2CMaster_Reset(handle); pthread_mutex_unlock(&ft4222_lock); return 0; } // syslog(LOG_NOTICE, "FT4222_I2CMaster_Read completed"); pthread_mutex_unlock(&ft4222_lock); return bytesRead; }
// INT pin of i2c PCA9672 GPIO expander is connected to FT4222 GPIO #3 // We use INT to detect any expander GPIO level change static void* mraa_ftdi_ft4222_gpio_monitor(void *arg) { uint16_t prev_value = 0; mraa_ftdi_ft4222_i2c_read_io_expander(&prev_value); while (!gpio_monitor.should_stop) { mraa_boolean_t gpio_activity_detected = mraa_ftdi_ft4222_has_internal_gpio_triggered(GPIO_PORT_IO_INT); if (gpio_activity_detected) { uint16_t value; if (mraa_ftdi_ft4222_i2c_read_io_expander(&value) == MRAA_SUCCESS) { uint16_t change_value = prev_value ^ value; int i; pthread_mutex_lock(&gpio_monitor.mutex); for (i = 0; i < MAX_IO_EXPANDER_PINS; ++i) { uint16_t mask = 1 << i; gpio_monitor.is_interrupt_detected[i] = change_value & mask ? 1 : 0; } pthread_mutex_unlock(&gpio_monitor.mutex); prev_value = value; } } mraa_ftdi_ft4222_sleep_ms(20); } }