Skip to content

Commit ee0b0e3

Browse files
committed
Fixing interrupts
1 parent 9737e17 commit ee0b0e3

3 files changed

Lines changed: 282 additions & 6 deletions

File tree

arch/sim/src/sim/posix/sim_ft2232h.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,79 @@ int host_ft2232h_gpio_direction(struct host_ft2232h_gpio_dev *priv,
112112
return 0;
113113
}
114114

115+
/****************************************************************************
116+
* Name: host_ft2232h_gpio_irq_request
117+
*
118+
* Input Parameters:
119+
* priv - A pointer to instance of Linux ft2232h_gpio.
120+
* pin - The pin number.
121+
* cfgset - The config set of the pin.
122+
*
123+
* Returned Value:
124+
* 0 for success, other for fail.
125+
****************************************************************************/
126+
127+
int host_ft2232h_gpio_irq_request(struct host_ft2232h_gpio_dev *priv, uint8_t pin,
128+
uint16_t cfg)
129+
{
130+
struct gpio_v2_line_request req;
131+
int nonblock = 1;
132+
int ret;
133+
134+
if (priv->line_fd[pin] > 0)
135+
{
136+
close(priv->line_fd[pin]);
137+
priv->line_fd[pin] = -1;
138+
}
139+
140+
memset(&req, 0, sizeof(req));
141+
switch (cfg)
142+
{
143+
case GPIOCHIP_LINE_FLAG_FALLING:
144+
req.config.flags = GPIO_V2_LINE_FLAG_EDGE_FALLING;
145+
break;
146+
case GPIOCHIP_LINE_FLAG_RISING:
147+
req.config.flags = GPIO_V2_LINE_FLAG_EDGE_RISING;
148+
break;
149+
case GPIOCHIP_LINE_FLAG_BOTH:
150+
req.config.flags = GPIO_V2_LINE_FLAG_EDGE_FALLING |
151+
GPIO_V2_LINE_FLAG_EDGE_RISING;
152+
break;
153+
default:
154+
req.config.flags = 0;
155+
break;
156+
}
157+
158+
req.offsets[0] = pin;
159+
req.num_lines = 1;
160+
req.config.flags |= GPIO_V2_LINE_FLAG_INPUT;
161+
if (req.config.flags != GPIO_V2_LINE_FLAG_INPUT)
162+
{
163+
snprintf(req.consumer, sizeof(req.consumer) - 1, "gpio-irq%d", pin);
164+
}
165+
166+
/* Warn only pin 10 can register in ch341A */
167+
168+
ret = host_uninterruptible(ioctl, priv->file, GPIO_V2_GET_LINE_IOCTL,
169+
&req);
170+
if (ret < 0)
171+
{
172+
gpioerr("ERROR: ioctl failed: %s \n", strerror(errno));
173+
return -errno;
174+
}
175+
176+
ret = host_uninterruptible(ioctl, req.fd, FIONBIO, &nonblock);
177+
if (ret < 0)
178+
{
179+
gpioerr("ERROR: Failed to set non-blocking: %s\n", strerror(errno));
180+
return -errno;
181+
}
182+
183+
priv->line_fd[pin] = req.fd;
184+
185+
return 0;
186+
}
187+
115188
/****************************************************************************
116189
* Name: host_ft2232h_gpio_writepin
117190
*
@@ -200,6 +273,37 @@ int host_ft2232h_gpio_readpin(struct host_ft2232h_gpio_dev *priv,
200273
*
201274
****************************************************************************/
202275

276+
/****************************************************************************
277+
* Name: host_ft2232h_gpio_irq_active
278+
*
279+
* Description:
280+
* register gpio for ft2232h_gpio device
281+
*
282+
* Input Parameters:
283+
* priv - A pointer to instance of Linux ft2232h_gpio.
284+
* pin - gpio pin of Linux ft2232h_gpio device.
285+
*
286+
* Returned Value:
287+
* 0 for OK.
288+
*
289+
****************************************************************************/
290+
291+
bool host_ft2232h_gpio_irq_active(struct host_ft2232h_gpio_dev *priv, uint8_t pin)
292+
{
293+
if (priv->line_fd[pin] > 0)
294+
{
295+
struct gpio_v2_line_event ev;
296+
int fd = priv->line_fd[pin];
297+
memset(&ev, 0, sizeof(ev));
298+
if (host_uninterruptible(read, fd, &ev, sizeof(ev)) == sizeof(ev))
299+
{
300+
return true;
301+
}
302+
}
303+
304+
return false;
305+
}
306+
203307
int host_ft2232h_gpio_get_line(struct host_ft2232h_gpio_dev *priv,
204308
uint8_t pin, bool *input)
205309
{

arch/sim/src/sim/sim_ft2232h_ioexpander.c

Lines changed: 170 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@
3333
* Pre-processor Definitions
3434
****************************************************************************/
3535

36-
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
37-
#warning "FT2232H doesn't support GPIO Interrupts!"
38-
#endif
36+
#define SIM_GPIOCHIP_WDOG_DELAY USEC2TICK(500)
3937

4038
/****************************************************************************
4139
* Private Types
@@ -68,6 +66,16 @@ static int sim_ft2232h_gpio_writepin(struct ioexpander_dev_s *dev,
6866
uint8_t pin, bool value);
6967
static int sim_ft2232h_gpio_readpin(struct ioexpander_dev_s *dev,
7068
uint8_t pin, bool *value);
69+
70+
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
71+
static void *sim_ft2232h_gpio_attach(struct ioexpander_dev_s *dev,
72+
uint16_t pinset,
73+
ioe_callback_t callback,
74+
void *arg);
75+
static int sim_ft2232h_gpio_detach(struct ioexpander_dev_s *dev,
76+
void *handle);
77+
#endif
78+
7179
static void sim_ft2232h_deferred_init(FAR void *arg);
7280

7381
/****************************************************************************
@@ -82,8 +90,8 @@ static struct ioexpander_ops_s g_sim_ft2232h_gpio_ops =
8290
.ioe_readpin = sim_ft2232h_gpio_readpin,
8391
.ioe_readbuf = sim_ft2232h_gpio_readpin,
8492
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
85-
.ioe_attach = NULL,
86-
.ioe_detach = NULL,
93+
.ioe_attach = sim_ft2232h_gpio_attach,
94+
.ioe_detach = sim_ft2232h_gpio_detach,
8795
#endif
8896
};
8997

@@ -143,7 +151,47 @@ static int sim_ft2232h_gpio_direction(struct ioexpander_dev_s *dev,
143151
static int sim_ft2232h_gpio_option(struct ioexpander_dev_s *dev, uint8_t pin,
144152
int option, void *val)
145153
{
146-
return -ENOTSUP;
154+
struct sim_ft2232h_gpio_dev_s *priv = (struct sim_ft2232h_gpio_dev_s *)dev;
155+
uint16_t cfgset = 0;
156+
int ret = 0;
157+
158+
if (option == IOEXPANDER_OPTION_INTCFG)
159+
{
160+
switch ((uintptr_t)val)
161+
{
162+
case IOEXPANDER_VAL_FALLING:
163+
cfgset = GPIOCHIP_LINE_FLAG_FALLING;
164+
break;
165+
166+
case IOEXPANDER_VAL_RISING:
167+
cfgset = GPIOCHIP_LINE_FLAG_RISING;
168+
break;
169+
170+
case IOEXPANDER_VAL_BOTH:
171+
cfgset = GPIOCHIP_LINE_FLAG_BOTH;
172+
break;
173+
174+
case IOEXPANDER_VAL_DISABLE:
175+
cfgset = GPIOCHIP_LINE_FLAG_DISABLE;
176+
break;
177+
178+
default:
179+
return -ENOTSUP;
180+
}
181+
182+
ret = host_ft2232h_gpio_irq_request(priv->dev, pin, cfgset);
183+
if (ret < 0)
184+
{
185+
gpioerr("ERROR: Failed to request event: %s\n", strerror(errno));
186+
}
187+
}
188+
else
189+
{
190+
gpioinfo("ft2232h_gpio io option not support\n");
191+
return -ENOTSUP;
192+
}
193+
194+
return ret;
147195
}
148196

149197
/****************************************************************************
@@ -192,6 +240,61 @@ static int sim_ft2232h_gpio_readpin(struct ioexpander_dev_s *dev,
192240
return host_ft2232h_gpio_readpin(priv->dev, pin, value);
193241
}
194242

243+
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
244+
245+
/****************************************************************************
246+
* Name: sim_ft2232h_gpio_attach
247+
*
248+
* Returned Value:
249+
* 0 for success, other for fail.
250+
****************************************************************************/
251+
252+
static void *sim_ft2232h_gpio_attach(struct ioexpander_dev_s *dev,
253+
ioe_pinset_t pinset,
254+
ioe_callback_t callback,
255+
void *arg)
256+
{
257+
struct sim_ft2232h_gpio_dev_s *priv = (struct sim_ft2232h_gpio_dev_s *)dev;
258+
void *handle = NULL;
259+
int i;
260+
261+
for (i = 0; i < CONFIG_IOEXPANDER_NPINS; i++)
262+
{
263+
if (pinset & (1 << i))
264+
{
265+
priv->cb[i].cbarg = arg;
266+
handle = &priv->cb[i];
267+
priv->cb[i].cbfunc = callback;
268+
}
269+
}
270+
271+
return handle;
272+
}
273+
274+
/****************************************************************************
275+
* Name: sim_ft2232h_gpio_detach
276+
*
277+
* Returned Value:
278+
* 0 for success, other for fail.
279+
****************************************************************************/
280+
281+
static int sim_ft2232h_gpio_detach(struct ioexpander_dev_s *dev, void *handle)
282+
{
283+
struct sim_ft2232h_gpio_dev_s *priv = (struct sim_ft2232h_gpio_dev_s *)dev;
284+
struct sim_ft2232h_gpio_callback_s *cb = handle;
285+
286+
if (priv == NULL || cb == NULL)
287+
{
288+
gpioerr("ERROR: Invalid handle\n");
289+
return -EINVAL;
290+
}
291+
292+
cb->cbfunc = NULL;
293+
cb->cbarg = NULL;
294+
return 0;
295+
}
296+
#endif
297+
195298
/****************************************************************************
196299
* Name: sim_ft2232h_gpio_register_gpio
197300
*
@@ -242,6 +345,64 @@ sim_ft2232h_gpio_register_gpio(struct sim_ft2232h_gpio_dev_s *priv)
242345
return 0;
243346
}
244347

348+
/****************************************************************************
349+
* Name: sim_ft2232h_gpio_irq_process
350+
*
351+
* Description:
352+
* work to poll irq event for ft2232h_gpio device
353+
*
354+
* Input Parameters:
355+
* priv - A pointer to instance of sim ft2232h_gpio device.
356+
*
357+
* Returned Value:
358+
* None.
359+
*
360+
****************************************************************************/
361+
362+
static void sim_ft2232h_gpio_irq_process(struct sim_ft2232h_gpio_dev_s *priv)
363+
{
364+
int line;
365+
366+
for (line = 0; line < FT2232_GPIO_NPINS; line++)
367+
{
368+
if (host_ft2232h_gpio_irq_active(priv->dev, line))
369+
{
370+
if (priv->cb[line].cbfunc)
371+
{
372+
priv->cb[line].cbfunc((struct ioexpander_dev_s *)priv,
373+
line, priv->cb[line].cbarg);
374+
}
375+
}
376+
}
377+
}
378+
379+
/****************************************************************************
380+
* Name: sim_ft2232h_gpio_interrupt
381+
*
382+
* Description:
383+
* wdog timer function for ft2232h_gpio device
384+
*
385+
* Input Parameters:
386+
* arg - A pointer to instance of sim ft2232h_gpio device.
387+
*
388+
* Returned Value:
389+
* None.
390+
*
391+
****************************************************************************/
392+
393+
static void sim_ft2232h_gpio_interrupt(wdparm_t arg)
394+
{
395+
struct sim_ft2232h_gpio_dev_s *priv = (struct sim_ft2232h_gpio_dev_s *)arg;
396+
397+
if (priv)
398+
{
399+
sim_ft2232h_gpio_irq_process(priv);
400+
401+
wd_start(&priv->wdog, SIM_GPIOCHIP_WDOG_DELAY,
402+
sim_ft2232h_gpio_interrupt, (wdparm_t)priv);
403+
}
404+
}
405+
245406
/****************************************************************************
246407
* Name: sim_ft2232h_deferred_init
247408
*
@@ -306,6 +467,9 @@ int sim_ft2232h_gpio_initialize(uint8_t pins_dir)
306467
return -ENODEV;
307468
}
308469

470+
wd_start(&priv->wdog, SIM_GPIOCHIP_WDOG_DELAY,
471+
sim_ft2232h_gpio_interrupt, (wdparm_t)priv);
472+
309473
g_ft2232h_gpio = (struct ioexpander_dev_s *)priv;
310474

311475
/* Defer gpio registration to work queue */

arch/sim/src/sim/sim_ft2232h_ioexpander.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838

3939
#define FT2232H_GPIO_LINE_BASE 20
4040
#define FT2232_GPIO_NPINS 8
41+
#define GPIOCHIP_LINE_FLAG_DISABLE (1 << 0)
42+
#define GPIOCHIP_LINE_FLAG_RISING (1 << 1)
43+
#define GPIOCHIP_LINE_FLAG_FALLING (1 << 2)
44+
#define GPIOCHIP_LINE_FLAG_BOTH (1 << 3)
4145

4246
/****************************************************************************
4347
* Type Definitions
@@ -64,4 +68,8 @@ int host_ft2232h_gpio_writepin(struct host_ft2232h_gpio_dev *dev,
6468
uint8_t pin, bool value);
6569
int host_ft2232h_gpio_direction(struct host_ft2232h_gpio_dev *dev,
6670
uint8_t pin, bool input);
71+
int host_ft2232h_gpio_irq_request(struct host_ft2232h_gpio_dev *dev,
72+
uint8_t pin, uint16_t cfgset);
73+
bool host_ft2232h_gpio_irq_active(struct host_ft2232h_gpio_dev *dev,
74+
uint8_t pin);
6775
#endif /* __ARCH_SIM_SRC_SIM_FT2232H_IOEXPANDER_H */

0 commit comments

Comments
 (0)