ftdi_ft4222: Added GPIO interrupt support for language bindings.
- FT4222 GPIO ISR implementation was specific to C/C++ and ignored language binding support. This is now fixed via adv_func updates. - GPIO ISR code has been refactored to reduce i2c traffic when using I/O expanders - Added support for built-in FT4222 GPIO interrupts Signed-off-by: Henry Bruce <henry.bruce@intel.com>
This commit is contained in:
committed by
Brendan Le Foll
parent
d2fcb88c4b
commit
1fd4ed5736
@@ -53,7 +53,8 @@ typedef struct {
|
|||||||
mraa_result_t (*gpio_write_pre) (mraa_gpio_context dev, int value);
|
mraa_result_t (*gpio_write_pre) (mraa_gpio_context dev, int value);
|
||||||
mraa_result_t (*gpio_write_post) (mraa_gpio_context dev, int value);
|
mraa_result_t (*gpio_write_post) (mraa_gpio_context dev, int value);
|
||||||
mraa_result_t (*gpio_mmap_setup) (mraa_gpio_context dev, mraa_boolean_t en);
|
mraa_result_t (*gpio_mmap_setup) (mraa_gpio_context dev, mraa_boolean_t en);
|
||||||
void* (*gpio_interrupt_handler_replace) (mraa_gpio_context dev);
|
mraa_result_t (*gpio_interrupt_handler_init_replace) (mraa_gpio_context dev);
|
||||||
|
mraa_result_t (*gpio_wait_interrupt_replace) (mraa_gpio_context dev);
|
||||||
|
|
||||||
mraa_result_t (*i2c_init_pre) (unsigned int bus);
|
mraa_result_t (*i2c_init_pre) (unsigned int bus);
|
||||||
mraa_result_t (*i2c_init_bus_replace) (mraa_i2c_context dev);
|
mraa_result_t (*i2c_init_bus_replace) (mraa_i2c_context dev);
|
||||||
|
|||||||
@@ -268,18 +268,21 @@ static void*
|
|||||||
mraa_gpio_interrupt_handler(void* arg)
|
mraa_gpio_interrupt_handler(void* arg)
|
||||||
{
|
{
|
||||||
mraa_gpio_context dev = (mraa_gpio_context) arg;
|
mraa_gpio_context dev = (mraa_gpio_context) arg;
|
||||||
if (IS_FUNC_DEFINED(dev, gpio_interrupt_handler_replace))
|
int fp = -1;
|
||||||
return dev->advance_func->gpio_interrupt_handler_replace(dev);
|
|
||||||
|
|
||||||
mraa_result_t ret;
|
mraa_result_t ret;
|
||||||
|
|
||||||
// open gpio value with open(3)
|
if (IS_FUNC_DEFINED(dev, gpio_interrupt_handler_init_replace)) {
|
||||||
char bu[MAX_SIZE];
|
if (dev->advance_func->gpio_interrupt_handler_init_replace(dev) != MRAA_SUCCESS)
|
||||||
sprintf(bu, SYSFS_CLASS_GPIO "/gpio%d/value", dev->pin);
|
return NULL;
|
||||||
int fp = open(bu, O_RDONLY);
|
} else {
|
||||||
if (fp < 0) {
|
// open gpio value with open(3)
|
||||||
syslog(LOG_ERR, "gpio: failed to open gpio%d/value", dev->pin);
|
char bu[MAX_SIZE];
|
||||||
return NULL;
|
sprintf(bu, SYSFS_CLASS_GPIO "/gpio%d/value", dev->pin);
|
||||||
|
fp = open(bu, O_RDONLY);
|
||||||
|
if (fp < 0) {
|
||||||
|
syslog(LOG_ERR, "gpio: failed to open gpio%d/value", dev->pin);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_PTHREAD_CANCEL
|
#ifndef HAVE_PTHREAD_CANCEL
|
||||||
@@ -309,11 +312,15 @@ mraa_gpio_interrupt_handler(void* arg)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ret = mraa_gpio_wait_interrupt(dev->isr_value_fp
|
if (IS_FUNC_DEFINED(dev, gpio_wait_interrupt_replace)) {
|
||||||
|
ret = dev->advance_func->gpio_wait_interrupt_replace(dev);
|
||||||
|
} else {
|
||||||
|
ret = mraa_gpio_wait_interrupt(dev->isr_value_fp
|
||||||
#ifndef HAVE_PTHREAD_CANCEL
|
#ifndef HAVE_PTHREAD_CANCEL
|
||||||
, dev->isr_control_pipe[0]
|
, dev->isr_control_pipe[0]
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
}
|
||||||
if (ret == MRAA_SUCCESS && !dev->isr_thread_terminating) {
|
if (ret == MRAA_SUCCESS && !dev->isr_thread_terminating) {
|
||||||
#ifdef HAVE_PTHREAD_CANCEL
|
#ifdef HAVE_PTHREAD_CANCEL
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||||
@@ -391,8 +398,10 @@ mraa_gpio_interrupt_handler(void* arg)
|
|||||||
#ifdef HAVE_PTHREAD_CANCEL
|
#ifdef HAVE_PTHREAD_CANCEL
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||||
#endif
|
#endif
|
||||||
close(dev->isr_value_fp);
|
if (fp != -1) {
|
||||||
dev->isr_value_fp = -1;
|
close(dev->isr_value_fp);
|
||||||
|
dev->isr_value_fp = -1;
|
||||||
|
}
|
||||||
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
|
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
|
||||||
|
|
||||||
if(dev->isr == mraa_java_isr_callback) {
|
if(dev->isr == mraa_java_isr_callback) {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
#define PCA9672_PINS 8
|
#define PCA9672_PINS 8
|
||||||
#define PCA9545_BUSSES 4
|
#define PCA9545_BUSSES 4
|
||||||
#define GPIO_PORT_IO_RESET GPIO_PORT2
|
#define GPIO_PORT_IO_RESET GPIO_PORT2
|
||||||
#define GPIO_PORT_IO_STATUS GPIO_PORT3
|
#define GPIO_PORT_IO_INT GPIO_PORT3
|
||||||
|
|
||||||
static FT_HANDLE ftHandleGpio = (FT_HANDLE) NULL; //GPIO Handle
|
static FT_HANDLE ftHandleGpio = (FT_HANDLE) NULL; //GPIO Handle
|
||||||
static FT_HANDLE ftHandleI2c = (FT_HANDLE) NULL; //I2C/SPI Handle
|
static FT_HANDLE ftHandleI2c = (FT_HANDLE) NULL; //I2C/SPI Handle
|
||||||
@@ -52,6 +52,36 @@ static int numI2cGpioExpanderPins = 8;
|
|||||||
static int numI2cSwitchBusses = 4;
|
static int numI2cSwitchBusses = 4;
|
||||||
static int currentI2cBus = 0;
|
static int currentI2cBus = 0;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
mraa_ftdi_ft4222_sleep_ms(unsigned long mseconds)
|
||||||
|
{
|
||||||
|
struct timespec sleepTime;
|
||||||
|
|
||||||
|
sleepTime.tv_sec = mseconds / 1000; // Number of seconds
|
||||||
|
sleepTime.tv_nsec = (mseconds % 1000) * 1000000; // Convert fractional seconds to nanoseconds
|
||||||
|
|
||||||
|
// Iterate nanosleep in a loop until the total sleep time is the original
|
||||||
|
// value of the seconds parameter
|
||||||
|
while ((nanosleep(&sleepTime, &sleepTime) != 0) && (errno == EINTR))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
mraa_ftdi_ft4222_get_tick_count_ms()
|
||||||
|
{
|
||||||
|
static unsigned int startTick = 0;
|
||||||
|
unsigned int ticks;
|
||||||
|
struct timeval now;
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
ticks = now.tv_sec * 1000;
|
||||||
|
ticks += now.tv_usec / 1000;
|
||||||
|
if (startTick == 0)
|
||||||
|
startTick = ticks;
|
||||||
|
return ticks - startTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
mraa_result_t
|
mraa_result_t
|
||||||
mraa_ftdi_ft4222_init()
|
mraa_ftdi_ft4222_init()
|
||||||
{
|
{
|
||||||
@@ -181,7 +211,8 @@ 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);
|
||||||
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)) {
|
||||||
@@ -189,6 +220,7 @@ mraa_ftdi_ft4222_i2c_read_internal(FT_HANDLE handle, uint8_t addr, uint8_t* data
|
|||||||
FT4222_I2CMaster_Reset(handle);
|
FT4222_I2CMaster_Reset(handle);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
syslog(LOG_NOTICE, "FT4222_I2CMaster_Read completed");
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +229,7 @@ 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);
|
||||||
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)) {
|
||||||
@@ -209,6 +241,7 @@ mraa_ftdi_ft4222_i2c_write_internal(FT_HANDLE handle, uint8_t addr, const uint8_
|
|||||||
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");
|
||||||
return bytesWritten;
|
return bytesWritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,6 +275,17 @@ ftdi_ft4222_set_internal_gpio_dir(int pin, GPIO_Dir direction)
|
|||||||
return MRAA_SUCCESS;
|
return MRAA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mraa_result_t
|
||||||
|
ftdi_ft4222_set_internal_gpio_trigger(int pin, GPIO_Trigger trigger)
|
||||||
|
{
|
||||||
|
FT4222_STATUS ft4222Status = FT4222_GPIO_SetInputTrigger(ftHandleGpio, pin, trigger);
|
||||||
|
if (ft4222Status == FT4222_OK)
|
||||||
|
return MRAA_SUCCESS;
|
||||||
|
else
|
||||||
|
return MRAA_ERROR_UNSPECIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Function detects known I2C switches and returns the number of busses.
|
// Function detects known I2C switches and returns the number of busses.
|
||||||
// On startup switch is disabled so default bus will be integrated i2c bus.
|
// On startup switch is disabled so default bus will be integrated i2c bus.
|
||||||
static int
|
static int
|
||||||
@@ -260,6 +304,7 @@ static mraa_result_t
|
|||||||
mraa_ftdi_ft4222_i2c_select_bus(int bus)
|
mraa_ftdi_ft4222_i2c_select_bus(int bus)
|
||||||
{
|
{
|
||||||
if (bus != currentI2cBus) {
|
if (bus != currentI2cBus) {
|
||||||
|
syslog(LOG_NOTICE, "mraa_ftdi_ft4222_i2c_select_bus switching to bus %d", bus);
|
||||||
uint8_t data;
|
uint8_t data;
|
||||||
if (bus == 0)
|
if (bus == 0)
|
||||||
data = 0;
|
data = 0;
|
||||||
@@ -292,34 +337,6 @@ mraa_ftdi_ft4222_i2c_context_write(mraa_i2c_context dev, uint8_t* data, int leng
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
mraa_ftdi_ft4222_sleep_ms(unsigned long mseconds)
|
|
||||||
{
|
|
||||||
struct timespec sleepTime;
|
|
||||||
|
|
||||||
sleepTime.tv_sec = mseconds / 1000; // Number of seconds
|
|
||||||
sleepTime.tv_nsec = (mseconds % 1000) * 1000000; // Convert fractional seconds to nanoseconds
|
|
||||||
|
|
||||||
// Iterate nanosleep in a loop until the total sleep time is the original
|
|
||||||
// value of the seconds parameter
|
|
||||||
while ((nanosleep(&sleepTime, &sleepTime) != 0) && (errno == EINTR))
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int
|
|
||||||
mraa_ftdi_ft4222_get_tick_count_ms()
|
|
||||||
{
|
|
||||||
static unsigned int startTick = 0;
|
|
||||||
unsigned int ticks;
|
|
||||||
struct timeval now;
|
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
ticks = now.tv_sec * 1000;
|
|
||||||
ticks += now.tv_usec / 1000;
|
|
||||||
if (startTick == 0)
|
|
||||||
startTick = ticks;
|
|
||||||
return ticks - startTick;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************* I2C functions *******************/
|
/******************* I2C functions *******************/
|
||||||
|
|
||||||
@@ -488,13 +505,27 @@ mraa_ftdi_ft4222_gpio_init_internal_replace(mraa_gpio_context dev, int pin)
|
|||||||
static mraa_result_t
|
static mraa_result_t
|
||||||
mraa_ftdi_ft4222_gpio_mode_replace(mraa_gpio_context dev, mraa_gpio_mode_t mode)
|
mraa_ftdi_ft4222_gpio_mode_replace(mraa_gpio_context dev, mraa_gpio_mode_t mode)
|
||||||
{
|
{
|
||||||
return MRAA_SUCCESS;
|
return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static mraa_result_t
|
static mraa_result_t
|
||||||
mraa_ftdi_ft4222_gpio_edge_mode_replace(mraa_gpio_context dev, mraa_gpio_edge_t mode)
|
mraa_ftdi_ft4222_gpio_edge_mode_replace(mraa_gpio_context dev, mraa_gpio_edge_t mode)
|
||||||
{
|
{
|
||||||
return MRAA_SUCCESS;
|
if (mraa_ftdi_ft4222_is_internal_gpio(dev->pin)) {
|
||||||
|
switch (mode) {
|
||||||
|
case MRAA_GPIO_EDGE_NONE:
|
||||||
|
return ftdi_ft4222_set_internal_gpio_trigger(dev->pin, 0);
|
||||||
|
case MRAA_GPIO_EDGE_BOTH:
|
||||||
|
return ftdi_ft4222_set_internal_gpio_trigger(dev->pin, GPIO_TRIGGER_RISING | GPIO_TRIGGER_FALLING);
|
||||||
|
case MRAA_GPIO_EDGE_RISING:
|
||||||
|
return ftdi_ft4222_set_internal_gpio_trigger(dev->pin, GPIO_TRIGGER_RISING);
|
||||||
|
case MRAA_GPIO_EDGE_FALLING:
|
||||||
|
return ftdi_ft4222_set_internal_gpio_trigger(dev->pin, GPIO_TRIGGER_FALLING);
|
||||||
|
default:
|
||||||
|
return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
return MRAA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -581,49 +612,61 @@ mraa_ftdi_ft4222_gpio_dir_replace(mraa_gpio_context dev, mraa_gpio_dir_t dir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mraa_boolean_t
|
||||||
static void*
|
mraa_ftdi_ft4222_has_internal_gpio_triggered(int pin)
|
||||||
mraa_ftdi_ft4222_gpio_interrupt_handler_replace(mraa_gpio_context dev)
|
|
||||||
{
|
{
|
||||||
#ifdef USE_FT4222_GPIO_TRIGGER
|
uint16 num_events = 0;
|
||||||
// FIXME: Use big buffer; shouldn't be more than this many events to read
|
FT4222_STATUS ft4222Status = FT4222_GPIO_GetTriggerStatus(ftHandleGpio, pin, &num_events);
|
||||||
GPIO_Trigger event_buf[256];
|
if (num_events > 0) {
|
||||||
int prev_level = mraa_ftdi_ft4222_gpio_read_replace(dev);
|
int i;
|
||||||
while (1) {
|
uint16 num_events_read;
|
||||||
uint16 num_events = 0;
|
GPIO_Trigger event;
|
||||||
FT4222_STATUS status = FT4222_GPIO_GetTriggerStatus(ftHandleGpio, GPIO_PORT_IO_STATUS, &num_events);
|
for (i = 0; i < num_events; ++i)
|
||||||
if (status != FT4222_OK)
|
FT4222_GPIO_ReadTriggerQueue(ftHandleGpio, pin, &event, 1, &num_events_read);
|
||||||
printf("FT4222_GPIO_GetTriggerStatus failed with code %d\n", status);
|
return TRUE;
|
||||||
printf("%u: FT4222_GPIO_GetTriggerStatus Events = %d\n", mraa_ftdi_ft4222_get_tick_count_ms(), num_events);
|
} else
|
||||||
if (num_events > 0) {
|
return FALSE;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
static mraa_result_t
|
||||||
mraa_ftdi_ft4222_sleep_ms(20);
|
mraa_ftdi_ft4222_gpio_interrupt_handler_init_replace(mraa_gpio_context dev)
|
||||||
// int level = mraa_ftdi_ft4222_gpio_read_replace(dev);
|
{
|
||||||
// printf("level = %d\n", level);
|
if (mraa_ftdi_ft4222_is_internal_gpio(dev->pin)) {
|
||||||
|
mraa_ftdi_ft4222_has_internal_gpio_triggered(dev->phy_pin);
|
||||||
|
} else {
|
||||||
|
ftdi_ft4222_set_internal_gpio_dir(GPIO_PORT_IO_INT, GPIO_INPUT);
|
||||||
|
ftdi_ft4222_set_internal_gpio_trigger(GPIO_PORT_IO_INT, GPIO_TRIGGER_FALLING);
|
||||||
|
mraa_ftdi_ft4222_has_internal_gpio_triggered(GPIO_PORT_IO_INT);
|
||||||
}
|
}
|
||||||
#else
|
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);
|
int prev_level = mraa_ftdi_ft4222_gpio_read_replace(dev);
|
||||||
while (1) {
|
mraa_boolean_t is_internal_pin = mraa_ftdi_ft4222_is_internal_gpio(dev->pin);
|
||||||
int level = mraa_ftdi_ft4222_gpio_read_replace(dev);
|
mraa_boolean_t interrupt_detected = FALSE;
|
||||||
// MRAA_GPIO_EDGE_BOTH
|
|
||||||
if (level != prev_level) {
|
// INT pin of i2c PCA9672 GPIO expander is connected to FT4222 GPIO #3
|
||||||
dev->isr(dev->isr_args);
|
// We use INT to detect any expander GPIO level change
|
||||||
prev_level = level;
|
while (!dev->isr_thread_terminating && !interrupt_detected) {
|
||||||
|
if (is_internal_pin) {
|
||||||
|
interrupt_detected = mraa_ftdi_ft4222_has_internal_gpio_triggered(dev->phy_pin);
|
||||||
}
|
}
|
||||||
mraa_ftdi_ft4222_sleep_ms(100);
|
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);
|
||||||
}
|
}
|
||||||
#endif
|
return MRAA_SUCCESS;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -653,7 +696,8 @@ mraa_ftdi_ft4222_populate_gpio_func_table(mraa_adv_func_t* func_table)
|
|||||||
func_table->gpio_dir_replace = &mraa_ftdi_ft4222_gpio_dir_replace;
|
func_table->gpio_dir_replace = &mraa_ftdi_ft4222_gpio_dir_replace;
|
||||||
func_table->gpio_read_replace = &mraa_ftdi_ft4222_gpio_read_replace;
|
func_table->gpio_read_replace = &mraa_ftdi_ft4222_gpio_read_replace;
|
||||||
func_table->gpio_write_replace = &mraa_ftdi_ft4222_gpio_write_replace;
|
func_table->gpio_write_replace = &mraa_ftdi_ft4222_gpio_write_replace;
|
||||||
func_table->gpio_interrupt_handler_replace = &mraa_ftdi_ft4222_gpio_interrupt_handler_replace;
|
func_table->gpio_interrupt_handler_init_replace = &mraa_ftdi_ft4222_gpio_interrupt_handler_init_replace;
|
||||||
|
func_table->gpio_wait_interrupt_replace = &mraa_ftdi_ft4222_gpio_wait_interrupt_replace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -752,3 +796,4 @@ mraa_ftdi_ft4222()
|
|||||||
sub_plat->adv_func = func_table;
|
sub_plat->adv_func = func_table;
|
||||||
return sub_plat;
|
return sub_plat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user