Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
NuttX RTOS
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
f4grx
NuttX RTOS
Commits
a932578e
Commit
a932578e
authored
8 years ago
by
Gregory Nutt
Browse files
Options
Downloads
Patches
Plain Diff
GPIO driver: Add support for receiving signals from interrupt pins.
parent
9b9b7214
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
drivers/ioexpander/gpio.c
+112
-67
112 additions, 67 deletions
drivers/ioexpander/gpio.c
include/nuttx/ioexpander/gpio.h
+48
-42
48 additions, 42 deletions
include/nuttx/ioexpander/gpio.h
with
160 additions
and
109 deletions
drivers/ioexpander/gpio.c
+
112
−
67
View file @
a932578e
...
...
@@ -41,6 +41,7 @@
#include
<sys/types.h>
#include
<stdio.h>
#include
<signal.h>
#include
<assert.h>
#include
<errno.h>
...
...
@@ -53,6 +54,7 @@
* Private Function Prototypes
****************************************************************************/
static
int
gpio_handler
(
FAR
struct
gpio_dev_s
*
dev
);
static
int
gpio_open
(
FAR
struct
file
*
filep
);
static
int
gpio_close
(
FAR
struct
file
*
filep
);
static
ssize_t
gpio_read
(
FAR
struct
file
*
filep
,
FAR
char
*
buffer
,
...
...
@@ -66,23 +68,7 @@ static int gpio_ioctl(FAR struct file *filep, int cmd,
* Private Data
****************************************************************************/
static
const
struct
file_operations
g_gpio_input_ops
=
{
gpio_open
,
/* open */
gpio_close
,
/* close */
gpio_read
,
/* read */
NULL
,
/* write */
NULL
,
/* seek */
gpio_ioctl
/* ioctl */
#ifndef CONFIG_DISABLE_POLL
,
NULL
/* poll */
#endif
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
,
NULL
/* unlink */
#endif
};
static
const
struct
file_operations
g_gpio_output_ops
=
static
const
struct
file_operations
g_gpio_drvrops
=
{
gpio_open
,
/* open */
gpio_close
,
/* close */
...
...
@@ -102,6 +88,21 @@ static const struct file_operations g_gpio_output_ops =
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: gpio_handler
*
* Description:
* Standard character driver open method.
*
****************************************************************************/
static
int
gpio_handler
(
FAR
struct
gpio_dev_s
*
dev
)
{
DEBUGASSERT
(
dev
!=
NULL
);
kill
(
dev
->
gp_pid
,
dev
->
gp_signo
);
return
OK
;
}
/****************************************************************************
* Name: gpio_open
*
...
...
@@ -167,7 +168,7 @@ static ssize_t gpio_write(FAR struct file *filep, FAR const char *buffer,
static
int
gpio_ioctl
(
FAR
struct
file
*
filep
,
int
cmd
,
unsigned
long
arg
)
{
FAR
struct
inode
*
inode
;
FAR
struct
gpio_
common_
dev_s
*
dev
;
FAR
struct
gpio_dev_s
*
dev
;
int
ret
;
DEBUGASSERT
(
filep
!=
NULL
&&
filep
->
f_inode
!=
NULL
);
...
...
@@ -177,20 +178,16 @@ static int gpio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
switch
(
cmd
)
{
/* Command: GPIO_WRITE
/* Command: GPIO
C
_WRITE
* Description: Set the value of an output GPIO
* Argument: 0=output a low value; 1=outut a high value
*/
case
GPIO_WRITE
:
if
(
dev
->
gp_
output
)
case
GPIO
C
_WRITE
:
if
(
dev
->
gp_
pintype
==
GPIO_OUTPUT_PIN
)
{
FAR
struct
gpio_output_dev_s
*
outdev
=
(
FAR
struct
gpio_output_dev_s
*
)
dev
;
DEBUGASSERT
(
outdev
->
gpout_write
!=
NULL
&&
((
arg
==
0UL
)
||
(
arg
==
1UL
)));
ret
=
outdev
->
gpout_write
(
outdev
,
(
int
)
arg
);
DEBUGASSERT
(
arg
==
0ul
||
arg
==
1ul
);
ret
=
dev
->
gp_ops
->
go_write
(
dev
,
(
int
)
arg
);
}
else
{
...
...
@@ -198,36 +195,62 @@ static int gpio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
break
;
/* Command: GPIO_READ
/* Command: GPIO
C
_READ
* Description: Read the value of an input or output GPIO
* Argument: A pointer to an integer value to receive the result:
* 0=low value; 1=high value.
*/
case
GPIO_READ
:
case
GPIO
C
_READ
:
{
FAR
int
*
ptr
=
(
FAR
int
*
)((
uintptr_t
)
arg
);
DEBUGASSERT
(
ptr
!=
NULL
);
if
(
dev
->
gp_o
utput
)
{
FAR
struct
gpio_output_dev_s
*
outdev
=
(
FAR
struct
gpio_output_dev_s
*
)
dev
;
ret
=
dev
->
gp_o
ps
->
go_read
(
dev
,
ptr
);
DEBUGASSERT
(
ret
<
0
||
*
ptr
==
0
||
*
ptr
==
1
);
}
break
;
DEBUGASSERT
(
outdev
->
gpout_read
!=
NULL
);
ret
=
outdev
->
gpout_read
(
outdev
,
ptr
);
}
else
{
FAR
struct
gpio_input_dev_s
*
indev
=
(
FAR
struct
gpio_input_dev_s
*
)
dev
;
/* Command: GPIOC_REGISTER
* Description: Register to receive a signal whenever there an
* interrupt is received on an input gpio pin. This
* feature, of course, depends upon interrupt GPIO
* support from the platform.
* Argument: The number of signal to be generated when the
* interrupt occurs.
*/
DEBUGASSERT
(
indev
->
gpin_read
!=
NULL
);
ret
=
indev
->
gpin_read
(
indev
,
ptr
);
}
case
GPIOC_REGISTER
:
if
(
dev
->
gp_pintype
==
GPIO_INTERRUPT_PIN
)
{
/* Make sure that the pin interrupt is disabled */
DEBUGASSERT
(
ret
<
0
||
*
ptr
==
0
||
*
ptr
==
1
);
}
ret
=
dev
->
gp_ops
->
go_enable
(
dev
,
false
);
if
(
ret
>=
0
)
{
/* Save signal information */
DEBUGASSERT
(
GOOD_SIGNO
(
arg
));
dev
->
gp_pid
=
getpid
();
dev
->
gp_signo
=
(
uint8_t
)
arg
;
/* Register our handler */
ret
=
dev
->
gp_ops
->
go_attach
(
dev
,
(
pin_interrupt_t
)
gpio_handler
);
if
(
ret
>=
0
)
{
/* Enable pin interrupts */
ret
=
dev
->
gp_ops
->
go_enable
(
dev
,
true
);
}
}
}
else
{
ret
=
-
EACCES
;
}
break
;
/* Unrecognized command */
...
...
@@ -245,41 +268,63 @@ static int gpio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
****************************************************************************/
/****************************************************************************
* Name: gpio_in
put
_register
* Name: gpio_
p
in_register
*
* Description:
* Register GPIO
input
pin device driver.
* Register GPIO pin device driver.
*
****************************************************************************/
int
gpio_in
put
_register
(
FAR
struct
gpio_
input_
dev_s
*
dev
,
int
minor
)
int
gpio_
p
in_register
(
FAR
struct
gpio_dev_s
*
dev
,
int
minor
)
{
FAR
const
char
*
fmt
;
char
devname
[
16
];
int
ret
;
DEBUGASSERT
(
dev
!=
NULL
&&
!
dev
->
gpin_output
&&
dev
->
gpin_read
!=
NULL
&&
(
unsigned
int
)
minor
<
100
);
DEBUGASSERT
(
dev
!=
NULL
&&
dev
->
gp_ops
!=
NULL
&&
(
unsigned
int
)
minor
<
100
);
snprintf
(
devname
,
16
,
"/dev/gpin%u"
,
(
unsigned
int
)
minor
);
return
register_driver
(
devname
,
&
g_gpio_input_ops
,
0444
,
dev
);
}
switch
(
dev
->
gp_pintype
)
{
case
GPIO_INPUT_PIN
:
{
DEBUGASSERT
(
dev
->
gp_ops
->
go_read
!=
NULL
);
fmt
=
"/dev/gpin%u"
;
}
break
;
/****************************************************************************
* Name: gpio_output_register
*
* Description:
* Register GPIO output pin device driver.
*
****************************************************************************/
case
GPIO_OUTPUT_PIN
:
{
DEBUGASSERT
(
dev
->
gp_ops
->
go_read
!=
NULL
&&
dev
->
gp_ops
->
go_write
!=
NULL
);
fmt
=
"/dev/gpout%u"
;
}
break
;
int
gpio_output_register
(
FAR
struct
gpio_output_dev_s
*
dev
,
int
minor
)
{
char
devname
[
16
];
case
GPIO_INTERRUPT_PIN
:
{
DEBUGASSERT
(
dev
->
gp_ops
->
go_read
!=
NULL
&&
dev
->
gp_ops
->
go_attach
!=
NULL
&&
dev
->
gp_ops
->
go_enable
!=
NULL
);
DEBUGASSERT
(
dev
!=
NULL
&&
dev
->
gpout_output
&&
dev
->
gpout_read
!=
NULL
&&
dev
->
gpout_write
!=
NULL
&&
(
unsigned
int
)
minor
<
100
);
/* Make sure that the pin interrupt is disabled */
ret
=
dev
->
gp_ops
->
go_enable
(
dev
,
false
);
if
(
ret
<
0
)
{
return
ret
;
}
fmt
=
"/dev/gpint%u"
;
}
break
;
default:
return
-
EINVAL
;
}
snprintf
(
devname
,
16
,
"/dev/gpout%u"
,
(
unsigned
int
)
minor
);
return
register_driver
(
devname
,
&
g_gpio_
output_
ops
,
0
222
,
dev
);
snprintf
(
devname
,
16
,
fmt
,
(
unsigned
int
)
minor
);
return
register_driver
(
devname
,
&
g_gpio_
drvr
ops
,
0
666
,
dev
);
}
#endif
/* CONFIG_DEV_GPIO */
This diff is collapsed.
Click to expand it.
include/nuttx/ioexpander/gpio.h
+
48
−
42
View file @
a932578e
...
...
@@ -47,64 +47,80 @@
* Pre-processor Definitions
****************************************************************************/
/* Command: GPIO_WRITE
/* Command: GPIO
C
_WRITE
* Description: Set the value of an output GPIO
* Argument: 0=output a low value; 1=outut a high value
*
* Command: GPIO_READ
* Command: GPIO
C
_READ
* Description: Read the value of an input or output GPIO
* Argument: A pointer to an integer value to receive the result:
* 0=low value; 1=high value.
*
* Command: GPIOC_REGISTER
* Description: Register to receive a signal whenever there an interrupt
* is received on an input gpio pin. This feature, of course,
* depends upon interrupt GPIO support from the platform.
* Argument: The number of signal to be generated when the interrupt
* occurs.
*/
#define GPIO_WRITE _GPIOC(1)
#define GPIO_READ _GPIOC(2)
#define GPIOC_WRITE _GPIOC(1)
#define GPIOC_READ _GPIOC(2)
#define GPIOC_REGISTER _GPIOC(3)
/****************************************************************************
* Public Types
****************************************************************************/
/* Common interface definition. Must be cast-compatible with struct
* gpio_input_dev_s and struct gpio_output_dev_s
*/
/* Identifies the type of the GPIO pin */
struct
gpio_common_dev_s
enum
gpio_pintype_e
{
bool
gp_output
;
uint8_t
gp_unused
[
3
];
GPIO_INPUT_PIN
=
0
,
GPIO_OUTPUT_PIN
,
GPIO_INTERRUPT_PIN
};
/* The interface to a GPIO input pin */
struct
gpio_input_dev_s
{
/* Common fields */
/* Interrupt callback */
bool
gpin_output
;
uint8_t
gpin_unused
[
3
];
typedef
CODE
int
(
*
pin_interrupt_t
)(
FAR
struct
gpio_dev_s
*
dev
);
/*
Fields unique to input pins
*/
/*
Pin interface definition.
*/
CODE
int
(
*
gpin_read
)(
FAR
struct
gpio_input_dev_s
*
dev
,
FAR
int
*
value
);
struct
gpio_dev_s
;
struct
gpio_operations_s
{
/* Interface methods */
/* Lower-half private definitions may follow */
CODE
int
(
*
go_read
)(
FAR
struct
gpio_dev_s
*
dev
,
FAR
int
*
value
);
CODE
int
(
*
go_write
)(
FAR
struct
gpio_dev_s
*
dev
,
int
value
);
CODE
int
(
*
go_attach
)(
FAR
struct
gpio_dev_s
*
dev
,
pin_interrupt_t
callback
);
CODE
int
(
*
go_enable
)(
FAR
struct
gpio_dev_s
*
dev
,
bool
enable
);
};
/*
The
interface
to a GPIO input pin
*/
/*
Pin
interface
definition.
*/
struct
gpio_
output_
dev_s
struct
gpio_dev_s
{
/* Common fields */
/* Information provided from the lower half driver to the upper half
* driver when gpio_pin_register() is called.
*/
uint8_t
gp_pintype
;
/* See enum gpio_pintype_e */
;
/* Writable storage used by the upper half driver */
bool
gpout_output
;
uint8_t
gpout_unused
[
3
];
uint8_t
gp_signo
;
/* signo to use when signaling a GPIO interrupt */
pid_t
gp_pid
;
/* The task to be signalled */
/* Fields unique to output pins */
/* Read-only pointer to GPIO device operations (also provided by the
* lower half driver).
*/
CODE
int
(
*
gpout_read
)(
FAR
struct
gpio_output_dev_s
*
dev
,
FAR
int
*
value
);
CODE
int
(
*
gpout_write
)(
FAR
struct
gpio_output_dev_s
*
dev
,
int
value
);
FAR
const
struct
gpio_operations_s
*
gp_ops
;
/*
Lower-half private defini
tion
s
may follow */
/*
Device specific informa
tion may follow */
};
/****************************************************************************
...
...
@@ -120,24 +136,14 @@ extern "C"
#endif
/****************************************************************************
* Name: gpio_input_register
*
* Description:
* Register GPIO input pin device driver.
*
****************************************************************************/
int
gpio_input_register
(
FAR
struct
gpio_input_dev_s
*
dev
,
int
minor
);
/****************************************************************************
* Name: gpio_output_register
* Name: gpio_pin_register
*
* Description:
* Register GPIO
output
pin device driver.
* Register GPIO pin device driver.
*
****************************************************************************/
int
gpio_
output
_register
(
FAR
struct
gpio_
output_
dev_s
*
dev
,
int
minor
);
int
gpio_
pin
_register
(
FAR
struct
gpio_dev_s
*
dev
,
int
minor
);
#ifdef __cplusplus
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment