Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adc: add IOCTL commands ANIOC_RESET_FIFO and ANIOC_SAMPLES_ON_READ #4288

Merged
merged 1 commit into from
Aug 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
75 changes: 74 additions & 1 deletion drivers/analog/adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/arch.h>
#include <nuttx/analog/adc.h>
#include <nuttx/analog/ioctl.h>
#include <nuttx/random.h>

#include <nuttx/irq.h>
Expand All @@ -78,6 +79,8 @@ static int adc_receive(FAR struct adc_dev_s *dev, uint8_t ch,
static void adc_notify(FAR struct adc_dev_s *dev);
static int adc_poll(FAR struct file *filep, struct pollfd *fds,
bool setup);
static int adc_reset_fifo(FAR struct adc_dev_s *dev);
static int adc_samples_on_read(FAR struct adc_dev_s *dev);

/****************************************************************************
* Private Data
Expand Down Expand Up @@ -431,7 +434,29 @@ static int adc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
FAR struct adc_dev_s *dev = inode->i_private;
int ret;

ret = dev->ad_ops->ao_ioctl(dev, cmd, arg);
switch (cmd)
{
case ANIOC_RESET_FIFO:
{
ret = adc_reset_fifo(dev);
}
break;

case ANIOC_SAMPLES_ON_READ:
{
ret = adc_samples_on_read(dev);
}
break;

default:
{
/* Those IOCTLs might be used in arch specific section */

ret = dev->ad_ops->ao_ioctl(dev, cmd, arg);
}
break;
}

return ret;
}

Expand Down Expand Up @@ -613,6 +638,54 @@ static int adc_poll(FAR struct file *filep, struct pollfd *fds, bool setup)
return ret;
}

/****************************************************************************
* Name: adc_reset_fifo
****************************************************************************/

static int adc_reset_fifo(FAR struct adc_dev_s *dev)
{
irqstate_t flags;
FAR struct adc_fifo_s *fifo = &dev->ad_recv;

/* Interrupts must be disabled while accessing the ad_recv FIFO */

flags = enter_critical_section();

fifo->af_head = fifo->af_tail;

leave_critical_section(flags);

return OK;
}

/****************************************************************************
* Name: adc_samples_on_read
****************************************************************************/

static int adc_samples_on_read(FAR struct adc_dev_s *dev)
{
irqstate_t flags;
FAR struct adc_fifo_s *fifo = &dev->ad_recv;
int16_t ret;

/* Interrupts must be disabled while accessing the ad_recv FIFO */

flags = enter_critical_section();

ret = fifo->af_tail - fifo->af_head;

leave_critical_section(flags);

if (ret < 0)
{
/* Increment return value by the size of FIFO */

ret += CONFIG_ADC_FIFOSIZE;
}

return ret;
}

/****************************************************************************
* Public Functions
****************************************************************************/
Expand Down
40 changes: 24 additions & 16 deletions include/nuttx/analog/ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,32 @@

/* DAC/ADC */

#define ANIOC_TRIGGER _ANIOC(0x0001) /* Trigger one conversion
* IN: None
* OUT: None */
#define ANIOC_WDOG_UPPER _ANIOC(0x0002) /* Set upper threshold for
* watchdog
* IN: Threshold value
* OUT: None */
#define ANIOC_WDOG_LOWER _ANIOC(0x0003) /* Set lower threshold for
* watchdog
* IN: Threshold value
* OUT: None */
#define ANIOC_GET_NCHANNELS _ANIOC(0x0004) /* Get the number of
* configured channels
* IN: None
* OUT: Number of channels */
#define ANIOC_TRIGGER _ANIOC(0x0001) /* Trigger one conversion
* IN: None
* OUT: None */
#define ANIOC_WDOG_UPPER _ANIOC(0x0002) /* Set upper threshold for
* watchdog
* IN: Threshold value
* OUT: None */
#define ANIOC_WDOG_LOWER _ANIOC(0x0003) /* Set lower threshold for
* watchdog
* IN: Threshold value
* OUT: None */
#define ANIOC_GET_NCHANNELS _ANIOC(0x0004) /* Get the number of
* configured channels
* IN: None
* OUT: Number of channels */
#define ANIOC_RESET_FIFO _ANIOC(0x0005) /* Clear data receive FIFO
* IN: None
* OUT: None */
#define ANIOC_SAMPLES_ON_READ _ANIOC(0x0006) /* Get the number of
* samples to be read
* IN: None
* OUT: Number of samples
* waiting to be read */

#define AN_FIRST 0x0001 /* First common command */
#define AN_NCMDS 4 /* Number of common commands */
#define AN_NCMDS 6 /* Number of common commands */

/* User defined ioctl commands are also supported. These will be forwarded
* by the upper-half driver to the lower-half driver via the ioctl()
Expand Down