diff --git a/arch/arm/src/cxd56xx/cxd56_adc.c b/arch/arm/src/cxd56xx/cxd56_adc.c index d75d614061b..1e2fb2988ab 100644 --- a/arch/arm/src/cxd56xx/cxd56_adc.c +++ b/arch/arm/src/cxd56xx/cxd56_adc.c @@ -929,6 +929,14 @@ static int cxd56_adc_ioctl(FAR struct file *filep, int cmd, } break; + case ANIOC_GET_NCHANNELS: + { + /* Return the number of configured channels */ + + ret = 1; + } + break; + default: { if (adc_validcheck(cmd)) diff --git a/arch/arm/src/efm32/efm32_adc.c b/arch/arm/src/efm32/efm32_adc.c index 4b15a281e15..43b936fa2b4 100644 --- a/arch/arm/src/efm32/efm32_adc.c +++ b/arch/arm/src/efm32/efm32_adc.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "arm_internal.h" #include "arm_arch.h" @@ -1174,7 +1175,28 @@ static void adc_rxint(FAR struct adc_dev_s *dev, bool enable) static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) { - return -ENOTTY; + FAR struct efm32_dev_s *priv = (FAR struct efm32_dev_s *)dev->ad_priv; + int ret = -ENOTTY; + + switch (cmd) + { + case ANIOC_GET_NCHANNELS: + { + /* Return the number of configured channels */ + + ret = priv->nchannels; + } + break; + + default: + { + aerr("ERROR: Unknown cmd: %d\n", cmd); + ret = -ENOTTY; + } + break; + } + + return ret; } /**************************************************************************** diff --git a/arch/arm/src/imxrt/imxrt_adc.c b/arch/arm/src/imxrt/imxrt_adc.c index b4927a7f7c7..4dece9d3f50 100644 --- a/arch/arm/src/imxrt/imxrt_adc.c +++ b/arch/arm/src/imxrt/imxrt_adc.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "arm_internal.h" #include "arm_arch.h" @@ -458,11 +459,30 @@ static void adc_rxint(FAR struct adc_dev_s *dev, bool enable) static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) { - /* No ioctl commands supported */ - /* TODO: ANIOC_TRIGGER, for SW triggered conversion */ - return -ENOTTY; + FAR struct imxrt_dev_s *priv = (FAR struct imxrt_dev_s *)dev->ad_priv; + int ret = -ENOTTY; + + switch (cmd) + { + case ANIOC_GET_NCHANNELS: + { + /* Return the number of configured channels */ + + ret = priv->nchannels; + } + break; + + default: + { + aerr("ERROR: Unknown cmd: %d\n", cmd); + ret = -ENOTTY; + } + break; + } + + return ret; } /**************************************************************************** diff --git a/arch/arm/src/lc823450/lc823450_adc.c b/arch/arm/src/lc823450/lc823450_adc.c index 6dded5b8e47..c350c074759 100644 --- a/arch/arm/src/lc823450/lc823450_adc.c +++ b/arch/arm/src/lc823450/lc823450_adc.c @@ -456,35 +456,46 @@ static int lc823450_adc_ioctl(FAR struct adc_dev_s *dev, int cmd, switch (cmd) { case ANIOC_TRIGGER: /* Software trigger */ + { + lc823450_adc_standby(0); - lc823450_adc_standby(0); + lc823450_adc_start(priv); - lc823450_adc_start(priv); + /* Get ADC data */ - /* Get ADC data */ + for (ch = 0; ch < CONFIG_LC823450_ADC_NCHANNELS; ch++) + { + val = getreg32(LC823450_ADC0DT(ch)); - for (ch = 0; ch < CONFIG_LC823450_ADC_NCHANNELS; ch++) - { - val = getreg32(LC823450_ADC0DT(ch)); + /* Give the ADC data to the ADC driver framework. + * adc_receive accepts 3 parameters: + * + * 1) The first is the ADC device instance for this ADC block. + * 2) The second is the channel number for the data, and + * 3) The third is the converted data for the channel. + */ - /* Give the ADC data to the ADC driver framework. - * adc_receive accepts 3 parameters: - * - * 1) The first is the ADC device instance for this ADC block. - * 2) The second is the channel number for the data, and - * 3) The third is the converted data for the channel. - */ + priv->cb->au_receive(dev, priv->chanlist[ch], val); + DEBUGASSERT(ret == OK); + } - priv->cb->au_receive(dev, priv->chanlist[ch], val); - DEBUGASSERT(ret == OK); - } - - lc823450_adc_standby(1); + lc823450_adc_standby(1); + } break; - default: - ret = -ENOTTY; - break; + case ANIOC_GET_NCHANNELS: + { + /* Return the number of configured channels */ + + ret = CONFIG_LC823450_ADC_NCHANNELS; + } + break; + + default: + { + ret = -ENOTTY; + } + break; } lc823450_adc_sem_post(priv); diff --git a/arch/arm/src/nrf52/nrf52_adc.c b/arch/arm/src/nrf52/nrf52_adc.c index 47c2136b3e8..73c38036c15 100644 --- a/arch/arm/src/nrf52/nrf52_adc.c +++ b/arch/arm/src/nrf52/nrf52_adc.c @@ -879,16 +879,23 @@ static int nrf52_adc_ioctl(FAR struct adc_dev_s *dev, int cmd, /* Trigger first sample */ nrf52_adc_putreg(priv, NRF52_SAADC_TASKS_SAMPLE_OFFSET, 1); - - break; } + break; + + case ANIOC_GET_NCHANNELS: + { + /* Return the number of configured channels */ + + ret = priv->chan_len; + } + break; default: { aerr("ERROR: Unknown cmd: %d\n", cmd); ret = -ENOTTY; - break; } + break; } return ret; diff --git a/arch/arm/src/sama5/sam_adc.c b/arch/arm/src/sama5/sam_adc.c index c49cc7be3e9..4012db65c7c 100644 --- a/arch/arm/src/sama5/sam_adc.c +++ b/arch/arm/src/sama5/sam_adc.c @@ -1258,10 +1258,20 @@ static int sam_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg) break; #endif + case ANIOC_GET_NCHANNELS: + { + /* Return the number of configured channels */ + + ret = SAMA5_NCHANNELS; + } + break; + /* Unsupported or invalid command */ default: - ret = -ENOTTY; + { + ret = -ENOTTY; + } break; } diff --git a/arch/arm/src/samd2l2/sam_adc.c b/arch/arm/src/samd2l2/sam_adc.c index e7fea862c4c..1243a04ec55 100644 --- a/arch/arm/src/samd2l2/sam_adc.c +++ b/arch/arm/src/samd2l2/sam_adc.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -387,35 +388,51 @@ static int sam_adc_ioctl(FAR struct adc_dev_s *dev, struct sam_adc_param_s *params = (struct sam_adc_param_s *)arg; switch (cmd) - { - case SAMD_ADC_IOCTL_START: - sam_adc_setup(dev); - sam_adc_rxint(dev, true); - break; - - case SAMD_ADC_IOCTL_STOP: - sam_adc_rxint(dev, false); - sam_adc_shutdown(dev); - break; - - case SAMD_ADC_IOCTL_SET_PARAMS: - if ((getreg8(SAM_ADC_CTRLA) & ADC_CTRLA_ENABLE) != 0) + { + case SAMD_ADC_IOCTL_START: { - ret = -EBUSY; + sam_adc_setup(dev); + sam_adc_rxint(dev, true); break; } - priv->averaging = params->averaging; - priv->prescaler = params->prescaler; - priv->samplen = params->samplen; - break; + case SAMD_ADC_IOCTL_STOP: + { + sam_adc_rxint(dev, false); + sam_adc_shutdown(dev); + break; + } - case SAMD_ADC_IOCTL_GET_PARAMS: - params->averaging = priv->averaging; - params->prescaler = priv->prescaler; - params->samplen = priv->samplen; - break; - } + case SAMD_ADC_IOCTL_SET_PARAMS: + { + if ((getreg8(SAM_ADC_CTRLA) & ADC_CTRLA_ENABLE) != 0) + { + ret = -EBUSY; + break; + } + + priv->averaging = params->averaging; + priv->prescaler = params->prescaler; + priv->samplen = params->samplen; + break; + } + + case SAMD_ADC_IOCTL_GET_PARAMS: + { + params->averaging = priv->averaging; + params->prescaler = priv->prescaler; + params->samplen = priv->samplen; + break; + } + + case ANIOC_GET_NCHANNELS: + { + /* Return the number of configured channels */ + + ret = priv->num_channels; + } + break; + } return ret; } diff --git a/arch/arm/src/stm32/stm32_adc.c b/arch/arm/src/stm32/stm32_adc.c index 0c176885933..31a5f819243 100644 --- a/arch/arm/src/stm32/stm32_adc.c +++ b/arch/arm/src/stm32/stm32_adc.c @@ -3871,6 +3871,14 @@ static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) break; } + case ANIOC_GET_NCHANNELS: + { + /* Return the number of configured channels */ + + ret = priv->rnchannels; + } + break; + case IO_TRIGGER_REG: { /* Start regular conversion if regular channels configured */ diff --git a/arch/arm/src/stm32/stm32_sdadc.c b/arch/arm/src/stm32/stm32_sdadc.c index fdc60f623ca..3ce2e9119e0 100644 --- a/arch/arm/src/stm32/stm32_sdadc.c +++ b/arch/arm/src/stm32/stm32_sdadc.c @@ -1193,12 +1193,24 @@ static int sdadc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) switch (cmd) { case ANIOC_TRIGGER: - sdadc_startconv(priv, true); + { + sdadc_startconv(priv, true); + } + break; + + case ANIOC_GET_NCHANNELS: + { + /* Return the number of configured channels */ + + ret = priv->cchannels; + } break; default: - aerr("ERROR: Unknown cmd: %d\n", cmd); - ret = -ENOTTY; + { + aerr("ERROR: Unknown cmd: %d\n", cmd); + ret = -ENOTTY; + } break; } diff --git a/arch/arm/src/stm32f0l0g0/stm32_adc.c b/arch/arm/src/stm32f0l0g0/stm32_adc.c index 29a62353aa3..4f4124f4500 100644 --- a/arch/arm/src/stm32f0l0g0/stm32_adc.c +++ b/arch/arm/src/stm32f0l0g0/stm32_adc.c @@ -1960,6 +1960,14 @@ static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) break; } + case ANIOC_GET_NCHANNELS: + { + /* Return the number of configured channels */ + + ret = priv->cr_channels; + } + break; + case IO_TRIGGER_REG: { /* Start regular conversion if regular channels configured */ diff --git a/arch/arm/src/stm32f7/stm32_adc.c b/arch/arm/src/stm32f7/stm32_adc.c index f9a142d1190..ab070d67483 100644 --- a/arch/arm/src/stm32f7/stm32_adc.c +++ b/arch/arm/src/stm32f7/stm32_adc.c @@ -1651,12 +1651,24 @@ static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) switch (cmd) { case ANIOC_TRIGGER: - adc_startconv(priv, true); + { + adc_startconv(priv, true); + } + break; + + case ANIOC_GET_NCHANNELS: + { + /* Return the number of configured channels */ + + ret = priv->cchannels; + } break; default: - aerr("ERROR: Unknown cmd: %d\n", cmd); - ret = -ENOTTY; + { + aerr("ERROR: Unknown cmd: %d\n", cmd); + ret = -ENOTTY; + } break; } diff --git a/arch/arm/src/stm32h7/stm32_adc.c b/arch/arm/src/stm32h7/stm32_adc.c index 166714da2b5..a6a4023a37c 100644 --- a/arch/arm/src/stm32h7/stm32_adc.c +++ b/arch/arm/src/stm32h7/stm32_adc.c @@ -1760,7 +1760,17 @@ static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) switch (cmd) { case ANIOC_TRIGGER: - adc_startconv(priv, true); + { + adc_startconv(priv, true); + } + break; + + case ANIOC_GET_NCHANNELS: + { + /* Return the number of configured channels */ + + ret = priv->cchannels; + } break; case ANIOC_WDOG_UPPER: /* Set watchdog upper threshold */ diff --git a/arch/arm/src/stm32l4/stm32l4_adc.c b/arch/arm/src/stm32l4/stm32l4_adc.c index 3c986f61590..a10466c02b9 100644 --- a/arch/arm/src/stm32l4/stm32l4_adc.c +++ b/arch/arm/src/stm32l4/stm32l4_adc.c @@ -1996,6 +1996,14 @@ static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) } break; + case ANIOC_GET_NCHANNELS: + { + /* Return the number of configured channels */ + + ret = priv->cchannels; + } + break; + case ANIOC_WDOG_UPPER: /* Set watchdog upper threshold */ { regval = adc_getreg(priv, STM32L4_ADC_TR1_OFFSET); diff --git a/arch/risc-v/src/esp32c3/esp32c3_adc.c b/arch/risc-v/src/esp32c3/esp32c3_adc.c index bafda50d69c..976a062db7b 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_adc.c +++ b/arch/risc-v/src/esp32c3/esp32c3_adc.c @@ -666,16 +666,27 @@ static int adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg) switch (cmd) { case ANIOC_TRIGGER: + { + /* Start sampling and read ADC value here */ - /* Start sampling and read ADC value here */ + adc_read_work(dev); + ret = OK; + } + break; - adc_read_work(dev); - ret = OK; + case ANIOC_GET_NCHANNELS: + { + /* Return the number of configured channels */ + + ret = 1; + } break; default: - aerr("ERROR: Unknown cmd: %d\n", cmd); - ret = -ENOTTY; + { + aerr("ERROR: Unknown cmd: %d\n", cmd); + ret = -ENOTTY; + } break; } diff --git a/include/nuttx/analog/ioctl.h b/include/nuttx/analog/ioctl.h index dabb12d4358..39860fbbc7d 100644 --- a/include/nuttx/analog/ioctl.h +++ b/include/nuttx/analog/ioctl.h @@ -40,18 +40,24 @@ /* 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_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 AN_FIRST 0x0001 /* First common command */ -#define AN_NCMDS 3 /* Number of common commands */ +#define AN_NCMDS 4 /* 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()