1
1
gpio/utils/gpio-ctrl/gpio-ctrl.c

197 строки
6.3 KiB
C

/*
* (c) 2017, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <devctl.h>
#include <fcntl.h>
#include <devctl.h>
#include <inttypes.h>
#include <sys/iomsg.h>
#include <hw/gpio_am35.h>
typedef struct _gpio_ctrl {
char *devname; /* port prefix */
uint8_t pin; /* pin num or reg mask depending on mode */
uint16_t dir; /* pins direction ( 0 for input, 1 for output ) */
uint16_t outval; /* output pin state */
uint8_t chwait; /* wait for pin change pulse events */
uint8_t verbose;
} gpio_ctrl_t;
void parse_options( int argc, char *argv[], gpio_ctrl_t *gc )
{
int c;
unsigned gpio_pin;
while ( (c = getopt( argc, argv, "n:p:d:o:Wv" ) ) != -1 )
{
switch ( c )
{
case 'n':
gc->devname = optarg;
break;
case 'p':
gpio_pin = strtoul( optarg, NULL, 0 );
if ( (gpio_pin > 191) || (gpio_pin < 0) )
{
printf( "GPIO control: Error! Valid GPIO pin number is from range 0 ~ 191.\n" );
exit( -1 );
}
gc->pin = gpio_pin;
break;
case 'd':
gc->dir = strtoul( optarg, NULL, 0 );
if ( gc->dir != 0 )
gc->dir = GPIO_OUTPUT;
else
gc->dir = GPIO_INPUT;
break;
case 'o':
gc->outval = strtoul( optarg, NULL, 0 );
if ( gc->outval != 0 )
gc->outval = 1;
else
gc->outval = 0;
break;
case 'W':
gc->chwait = 1;
break;
case 'v':
gc->verbose++;
break;
}
}
}
int main( int argc, char *argv[] )
{
gpio_ctrl_t gpio_ctrl;
gpio_devctl_t msg;
int fd;
int status;
memset( &gpio_ctrl, 0 , sizeof( gpio_ctrl_t ) );
gpio_ctrl.devname = GPIO_DEVICE_NAME;
gpio_ctrl.dir = -1;
gpio_ctrl.outval = 0;
gpio_ctrl.verbose = 1;
gpio_ctrl.pin = 178;
parse_options( argc, argv, &gpio_ctrl );
fd = open( gpio_ctrl.devname, O_RDWR );
if ( fd == -1 )
{
printf( "GPIO control: Error! Failed to open %s: %s\n", gpio_ctrl.devname, strerror( errno ) );
return (-1);
}
if ( gpio_ctrl.dir == GPIO_INPUT )
{
printf( "GPIO control: Reading GPIO pin %d \n", gpio_ctrl.pin );
msg.set_input.pin_num = gpio_ctrl.pin;
// Set pin direction
if ( ( status = devctl( fd, DCMD_SET_INPUT, &msg, sizeof( msg ), NULL ) ) )
printf( "GPIO control: Error! GPIO DCMD_SET_INPUT devctl failed; status = %d\n", status );
else
printf( "GPIO control: Pin %d direction: INPUT\n", gpio_ctrl.pin );
if ( ( status = devctl( fd, DCMD_READ, &msg, sizeof( msg ), NULL ) ) )
{
printf( "GPIO control: Error! GPIO DCMD_READ devctl failed; status = %d\n", status );
return (-1);
} else {
printf( "GPIO control: Pin %d value: %d\n", msg.cmd_read.pin_num, msg.cmd_read.data );
return (msg.cmd_read.data);
}
} else
if ( gpio_ctrl.dir == GPIO_OUTPUT )
{
printf( "GPIO control: Setting GPIO pin %d value %d\n", gpio_ctrl.pin, gpio_ctrl.outval );
msg.set_output.pin_num = gpio_ctrl.pin;
// Set pin direction
if ( ( status = devctl( fd, DCMD_SET_OUTPUT, &msg, sizeof( msg ), NULL ) ) )
printf( "GPIO control: Error! GPIO DCMD_SET_OUTPUT devctl failed; status = %d\n", status );
else
printf( "GPIO control: Pin %d direction: OUTPUT\n", gpio_ctrl.pin );
msg.cmd_write.pin_num = gpio_ctrl.pin;
msg.cmd_write.data = gpio_ctrl.outval;
if ( ( status = devctl( fd, DCMD_WRITE, &msg, sizeof( msg ), NULL ) ) )
printf( "GPIO control: Error! GPIO DCMD_WRITE devctl failed; status = %d\n", status );
else
printf( "GPIO control: Pin %d value: %d\n", msg.cmd_write.pin_num, msg.cmd_write.data );
}
if ( gpio_ctrl.chwait )
{
int chid;
int coid;
struct _pulse pulse;
// we need a channel to receive the pulse notification on
chid = ChannelCreate( 0 );
// and we need a connection to that channel for the pulse to be delivered on
coid = ConnectAttach( 0, 0, chid, _NTO_SIDE_CHANNEL, 0 );
msg.cmd_intterupt.pin_num = gpio_ctrl.pin;
msg.cmd_intterupt.level = GPIO_INT_LEVEL_LOW;
msg.cmd_intterupt.coid = coid;
// Set pin direction
if ( ( status = devctl( fd, DCMD_SET_INPUT, &msg, sizeof( msg ), NULL ) ) )
printf( "GPIO control: Error! GPIO DCMD_SET_INPUT devctl failed; status = %d\n", status );
else
printf( "GPIO control: Pin %d direction: INPUT\n", gpio_ctrl.pin );
printf( "GPIO control: Client: enable interrupts from GPIO pin %d \n", msg.cmd_intterupt.pin_num );
if ( ( status = devctl( fd, DCMD_INT_ENABLE_WAIT_PULSE, &msg, sizeof( msg ), NULL ) ) )
printf( "GPIO control: Error! GPIO DCMD_PULSE devctl failed; status = %d\n", status );
else
{
printf( "GPIO control: Client is waiting for pulses...\n" );
printf( "GPIO control: Client: chid %d coid %d \n", chid, coid );
while ( 1 )
{
// wait for the pulse from the resource manager
MsgReceivePulse( chid, &pulse, sizeof( pulse ), NULL );
printf( "GPIO control: Client pulse code %d recieved. GPIO interrupt from PIN %u \n\n", pulse.code, pulse.value.sival_int );
// break;
}
if ( ( status = devctl( fd, DCMD_INT_DISABLE, &msg, sizeof( msg ), NULL ) ) )
printf( "GPIO control: Error! GPIO DCMD_INT_DISABLE devctl failed; status = %d\n", status );
else
printf( "GPIO control: GPIO Interrupt test complete \n" );
}
}
close( fd );
return (EXIT_SUCCESS);
}