forked from xuos/xiuos
add ch438_ioctl
This commit is contained in:
parent
68d30d3df2
commit
87910b03a4
|
@ -44,6 +44,7 @@ static int ch438_open(FAR struct file *filep);
|
||||||
static int ch438_close(FAR struct file *filep);
|
static int ch438_close(FAR struct file *filep);
|
||||||
static ssize_t ch438_read(FAR struct file *filep, FAR char *buffer, size_t buflen);
|
static ssize_t ch438_read(FAR struct file *filep, FAR char *buffer, size_t buflen);
|
||||||
static ssize_t ch438_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
|
static ssize_t ch438_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
|
||||||
|
static int ch438_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
|
||||||
static int ch438_register(FAR const char *devpath, uint8_t ext_uart_no);
|
static int ch438_register(FAR const char *devpath, uint8_t ext_uart_no);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -51,6 +52,7 @@ static int ch438_register(FAR const char *devpath, uint8_t ext_uart_no);
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
struct ch438_dev_s
|
struct ch438_dev_s
|
||||||
{
|
{
|
||||||
|
sem_t devsem;
|
||||||
uint8_t port; /* ch438 port number*/
|
uint8_t port; /* ch438 port number*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -90,7 +92,6 @@ static uint8_t offsetadd[CH438PORTNUM] = {0x00,0x10,0x20,0x30,0x08,0x18,0x28,0x3
|
||||||
|
|
||||||
static uint8_t gInterruptStatus;
|
static uint8_t gInterruptStatus;
|
||||||
|
|
||||||
static bool g_ch438open[CH438PORTNUM];
|
|
||||||
static const struct file_operations g_ch438fops =
|
static const struct file_operations g_ch438fops =
|
||||||
{
|
{
|
||||||
ch438_open,
|
ch438_open,
|
||||||
|
@ -98,7 +99,7 @@ static const struct file_operations g_ch438fops =
|
||||||
ch438_read,
|
ch438_read,
|
||||||
ch438_write,
|
ch438_write,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
ch438_ioctl,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -600,15 +601,18 @@ static int ch438_open(FAR struct file *filep)
|
||||||
FAR struct inode *inode = filep->f_inode;
|
FAR struct inode *inode = filep->f_inode;
|
||||||
FAR struct ch438_dev_s *priv = inode->i_private;
|
FAR struct ch438_dev_s *priv = inode->i_private;
|
||||||
uint8_t port = priv->port;
|
uint8_t port = priv->port;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
DEBUGASSERT(port >= 0 && port < CH438PORTNUM);
|
DEBUGASSERT(port >= 0 && port < CH438PORTNUM);
|
||||||
|
|
||||||
if(g_ch438open[port])
|
ret = nxsem_wait_uninterruptible(&priv->devsem);
|
||||||
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
return -EBUSY;
|
return ret;
|
||||||
}
|
}
|
||||||
g_ch438open[port] = true;
|
nxsem_post(&priv->devsem);
|
||||||
|
|
||||||
return OK;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -619,10 +623,18 @@ static int ch438_close(FAR struct file *filep)
|
||||||
FAR struct inode *inode = filep->f_inode;
|
FAR struct inode *inode = filep->f_inode;
|
||||||
FAR struct ch438_dev_s *priv = inode->i_private;
|
FAR struct ch438_dev_s *priv = inode->i_private;
|
||||||
uint8_t port = priv->port;
|
uint8_t port = priv->port;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
DEBUGASSERT(port >= 0 && port < CH438PORTNUM);
|
DEBUGASSERT(port >= 0 && port < CH438PORTNUM);
|
||||||
|
|
||||||
g_ch438open[port] = false;
|
ret = nxsem_wait_uninterruptible(&priv->devsem);
|
||||||
return OK;
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
nxsem_post(&priv->devsem);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -634,8 +646,16 @@ static ssize_t ch438_read(FAR struct file *filep, FAR char *buffer, size_t bufle
|
||||||
FAR struct inode *inode = filep->f_inode;
|
FAR struct inode *inode = filep->f_inode;
|
||||||
FAR struct ch438_dev_s *priv = inode->i_private;
|
FAR struct ch438_dev_s *priv = inode->i_private;
|
||||||
uint8_t port = priv->port;
|
uint8_t port = priv->port;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
DEBUGASSERT(port >= 0 && port < CH438PORTNUM);
|
DEBUGASSERT(port >= 0 && port < CH438PORTNUM);
|
||||||
|
|
||||||
|
ret = nxsem_wait_uninterruptible(&priv->devsem);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
return (ssize_t)ret;
|
||||||
|
}
|
||||||
|
|
||||||
length = ImxrtCh438ReadData(port);
|
length = ImxrtCh438ReadData(port);
|
||||||
memcpy(buffer, buff[port], length);
|
memcpy(buffer, buff[port], length);
|
||||||
|
|
||||||
|
@ -643,6 +663,7 @@ static ssize_t ch438_read(FAR struct file *filep, FAR char *buffer, size_t bufle
|
||||||
{
|
{
|
||||||
length = buflen;
|
length = buflen;
|
||||||
}
|
}
|
||||||
|
nxsem_post(&priv->devsem);
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
@ -655,13 +676,57 @@ static ssize_t ch438_write(FAR struct file *filep, FAR const char *buffer, size_
|
||||||
FAR struct inode *inode = filep->f_inode;
|
FAR struct inode *inode = filep->f_inode;
|
||||||
FAR struct ch438_dev_s *priv = inode->i_private;
|
FAR struct ch438_dev_s *priv = inode->i_private;
|
||||||
uint8_t port = priv->port;
|
uint8_t port = priv->port;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
DEBUGASSERT(port >= 0 && port < CH438PORTNUM);
|
DEBUGASSERT(port >= 0 && port < CH438PORTNUM);
|
||||||
|
|
||||||
|
ret = nxsem_wait_uninterruptible(&priv->devsem);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
return (ssize_t)ret;
|
||||||
|
}
|
||||||
ImxrtCh438WriteData(port, buffer, buflen);
|
ImxrtCh438WriteData(port, buffer, buflen);
|
||||||
|
nxsem_post(&priv->devsem);
|
||||||
|
|
||||||
return buflen;
|
return buflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: ch438_ioctl
|
||||||
|
****************************************************************************/
|
||||||
|
static int ch438_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||||
|
{
|
||||||
|
FAR struct inode *inode = filep->f_inode;
|
||||||
|
FAR struct ch438_dev_s *priv = inode->i_private;
|
||||||
|
uint8_t port = priv->port;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
|
DEBUGASSERT(port >= 0 && port < CH438PORTNUM);
|
||||||
|
|
||||||
|
/* Get exclusive access */
|
||||||
|
ret = nxsem_wait_uninterruptible(&priv->devsem);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(cmd)
|
||||||
|
{
|
||||||
|
case OPE_CFG:
|
||||||
|
case OPE_INT:
|
||||||
|
CH438PortInit(port, (uint32_t)arg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ch438info("Unrecognized cmd: %d\n", cmd);
|
||||||
|
ret = -ENOTTY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nxsem_post(&priv->devsem);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: ch438_register
|
* Name: ch438_register
|
||||||
|
@ -686,12 +751,12 @@ static int ch438_register(FAR const char *devpath, uint8_t port)
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->port = port;
|
priv->port = port;
|
||||||
|
nxsem_init(&priv->devsem, 0, 1);
|
||||||
|
|
||||||
/* Register the character driver */
|
/* Register the character driver */
|
||||||
ret = register_driver(devpath, &g_ch438fops, 0666, priv);
|
ret = register_driver(devpath, &g_ch438fops, 0666, priv);
|
||||||
if(ret < 0)
|
if(ret < 0)
|
||||||
{
|
{
|
||||||
ch438err("ERROR: Failed to register driver: %d\n", ret);
|
|
||||||
kmm_free(priv);
|
kmm_free(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <nuttx/semaphore.h>
|
#include <nuttx/semaphore.h>
|
||||||
#include <nuttx/time.h>
|
#include <nuttx/time.h>
|
||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/fs/fs.h>
|
||||||
|
#include <nuttx/fs/ioctl.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -333,7 +334,6 @@
|
||||||
#define CH438_D7_PIN_INPUT (GPIO_INPUT | \
|
#define CH438_D7_PIN_INPUT (GPIO_INPUT | \
|
||||||
GPIO_PORT1 | GPIO_PIN29)
|
GPIO_PORT1 | GPIO_PIN29)
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_CH438_ERROR
|
#ifdef CONFIG_DEBUG_CH438_ERROR
|
||||||
# define ch438err _err
|
# define ch438err _err
|
||||||
#else
|
#else
|
||||||
|
@ -352,6 +352,10 @@
|
||||||
# define ch438info _none
|
# define ch438info _none
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define OPE_INT 0x0000
|
||||||
|
#define OPE_CFG 0x0001
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
Loading…
Reference in New Issue