diff --git a/ChangeLog b/ChangeLog index ee0c57f871b3380ff9b2d46dffddba539ba9581c..85a12cccec30bdab547353e771c2f4afb7702289 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2023,4 +2023,8 @@ circles -- both circular outlines and filled circles. * graphic/nxglib/nxglib_spitline.c: Add a "fudge factor" that eliminates some problems for rendering nearly horizontal, wide lines. + * drivers/analog, include/nuttx/analog, arch/arch/src/lpcxx: (1) Add + updates to the ADS1255 driver, (2) fix errors from my last merge (sorry), + (3) Add DAC infrastructure, (4) add AD5410 DAC driver, and (5) add + LPC17xx ADC and DAC drivers. All contributed by Li Zhuoyi (Lzyy). diff --git a/arch/arm/src/lpc17xx/Make.defs b/arch/arm/src/lpc17xx/Make.defs index 09875a979a6ee72bd80e1b4c4ba4515ab25ffc9a..1f779f6d48073b26ee566d2795bca74f439a0077 100755 --- a/arch/arm/src/lpc17xx/Make.defs +++ b/arch/arm/src/lpc17xx/Make.defs @@ -88,3 +88,11 @@ ifeq ($(CONFIG_LPC17_ETHERNET),y) CHIP_CSRCS += lpc17_ethernet.c endif endif + +ifeq ($(CONFIG_LPC17_ADC),y) +CHIP_CSRCS += lpc17_adc.c +endif + +ifeq ($(CONFIG_LPC17_DAC),y) +CHIP_CSRCS += lpc17_dac.c +endif diff --git a/arch/arm/src/lpc17xx/lpc17_adc.c b/arch/arm/src/lpc17xx/lpc17_adc.c new file mode 100644 index 0000000000000000000000000000000000000000..503211b72210f38f01b694144d5d30f355457ed3 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_adc.c @@ -0,0 +1,268 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_adc.c + * + * Copyright (C) 2011 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi <lzyy.cn@gmail.com> + * History: 0.1 2011-08-05 initial version + * + * This file is a part of NuttX: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#include <nuttx/config.h> + +#include <stdio.h> +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <semaphore.h> +#include <errno.h> +#include <debug.h> + +#include <arch/board/board.h> +#include <nuttx/arch.h> +#include <nuttx/analog/adc.h> + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "lpc17_internal.h" +#include "lpc17_syscon.h" +#include "lpc17_pinconn.h" +#include "lpc17_adc.h" + +#if defined(CONFIG_LPC17_ADC) + +#ifndef CONFIG_ADC0_MASK +#define CONFIG_ADC0_MASK 0x01 +#endif +#ifndef CONFIG_ADC0_SPS +#define CONFIG_ADC0_SPS 1000 +#endif +#ifndef CONFIG_ADC0_AVERAGE +#define CONFIG_ADC0_AVERAGE 200 +#endif + +/**************************************************************************** + * ad_private Types + ****************************************************************************/ +struct up_dev_s +{ + uint8_t mask; + uint32_t sps; + int irq; + int32_t buf[8]; + uint8_t count[8]; +}; + +/**************************************************************************** + * ad_private Function Prototypes + ****************************************************************************/ + +/* ADC methods */ + +static void adc_reset(FAR struct adc_dev_s *dev); +static int adc_setup(FAR struct adc_dev_s *dev); +static void adc_shutdown(FAR struct adc_dev_s *dev); +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); +static int adc_interrupt(int irq, void *context); + +/**************************************************************************** + * ad_private Data + ****************************************************************************/ + +static const struct adc_ops_s g_adcops = +{ + .ao_reset =adc_reset, + .ao_setup = adc_setup, + .ao_shutdown = adc_shutdown, + .ao_rxint = adc_rxint, + .ao_ioctl = adc_ioctl, +}; + +static struct up_dev_s g_adcpriv = +{ + .sps = CONFIG_ADC0_SPS, + .mask = CONFIG_ADC0_MASK, + .irq = LPC17_IRQ_ADC, +}; + +static struct adc_dev_s g_adcdev = +{ + .ad_ops = &g_adcops, + .ad_priv= &g_adcpriv, +}; + +/**************************************************************************** + * ad_private Functions + ****************************************************************************/ +/* Reset the ADC device. Called early to initialize the hardware. This +* is called, before ao_setup() and on error conditions. +*/ +static void adc_reset(FAR struct adc_dev_s *dev) +{ + irqstate_t flags; + uint32_t regval; + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; + + flags = irqsave(); + + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCADC; + putreg32(regval, LPC17_SYSCON_PCONP); + + putreg32(ADC_CR_PDN,LPC17_ADC_CR); + + regval = getreg32(LPC17_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_ADC_MASK; + regval |= (SYSCON_PCLKSEL_CCLK8 << SYSCON_PCLKSEL0_ADC_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL0); + + uint32_t clkdiv=LPC17_CCLK/8/65/priv->sps; + clkdiv<<=8; + clkdiv&=0xff00; + putreg32(ADC_CR_PDN|ADC_CR_BURST|clkdiv|priv->mask,LPC17_ADC_CR); + + if(priv->mask&0x01) + lpc17_configgpio(GPIO_AD0p0); + else if(priv->mask&0x02) + lpc17_configgpio(GPIO_AD0p1); + else if(priv->mask&0x04) + lpc17_configgpio(GPIO_AD0p2); + else if(priv->mask&0x08) + lpc17_configgpio(GPIO_AD0p3); + else if(priv->mask&0x10) + lpc17_configgpio(GPIO_AD0p4); + else if(priv->mask&0x20) + lpc17_configgpio(GPIO_AD0p5); + else if(priv->mask&0x40) + lpc17_configgpio(GPIO_AD0p6); + else if(priv->mask&0x80) + lpc17_configgpio(GPIO_AD0p7); + + irqrestore(flags); +} + +/* Configure the ADC. This method is called the first time that the ADC +* device is opened. This will occur when the port is first opened. +* This setup includes configuring and attaching ADC interrupts. Interrupts +* are all disabled upon return. +*/ +static int adc_setup(FAR struct adc_dev_s *dev) +{ + int i; + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; + int ret = irq_attach(priv->irq, adc_interrupt); + if (ret == OK) + { + for(i=0;i<8;i++) + { + priv->buf[i]=0; + priv->count[i]=0; + } + up_enable_irq(priv->irq); + } + return ret; +} + +/* Disable the ADC. This method is called when the ADC device is closed. +* This method reverses the operation the setup method. +*/ +static void adc_shutdown(FAR struct adc_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/* Call to enable or disable RX interrupts */ +static void adc_rxint(FAR struct adc_dev_s *dev, bool enable) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; + if (enable) + putreg32(ADC_INTEN_GLOBAL,LPC17_ADC_INTEN); + else + putreg32(0x00,LPC17_ADC_INTEN); +} + +/* All ioctl calls will be routed through this method */ +static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) +{ + dbg("Fix me:Not Implemented\n"); + return 0; +} + +static int adc_interrupt(int irq, void *context) +{ + uint32_t regval; + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.ad_priv; + unsigned char ch; + int32_t value; + + regval=getreg32(LPC17_ADC_GDR); + ch=(regval>>24)&0x07; + priv->buf[ch]+=regval&0xfff0; + priv->count[ch]++; + if(priv->count[ch]>=CONFIG_ADC0_AVERAGE) + { + value=priv->buf[ch]/priv->count[ch]; + value<<=15; + adc_receive(&g_adcdev,ch,value); + priv->buf[ch]=0; + priv->count[ch]=0; + } + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_adcinitialize + * + * Description: + * Initialize the adc + * + * Returned Value: + * Valid can device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct adc_dev_s *up_adcinitialize( ) +{ + return &g_adcdev; +} +#endif + diff --git a/arch/arm/src/lpc17xx/lpc17_dac.c b/arch/arm/src/lpc17xx/lpc17_dac.c new file mode 100644 index 0000000000000000000000000000000000000000..1fbac13e7d0b0ce631590552841de0cb08a40d28 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_dac.c @@ -0,0 +1,190 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_dac.c + * + * Copyright (C) 2011 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi <lzyy.cn@gmail.com> + * History: 0.1 2011-08-05 initial version + * + * This file is a part of NuttX: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#include <nuttx/config.h> + +#include <stdio.h> +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <semaphore.h> +#include <errno.h> +#include <debug.h> + +#include <arch/board/board.h> +#include <nuttx/arch.h> +#include <nuttx/analog/dac.h> + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "lpc17_internal.h" +#include "lpc17_syscon.h" +#include "lpc17_pinconn.h" +#include "lpc17_dac.h" + +#if defined(CONFIG_LPC17_DAC) + +/**************************************************************************** + * ad_private Types + ****************************************************************************/ + +/**************************************************************************** + * ad_private Function Prototypes + ****************************************************************************/ + +/* DAC methods */ + +static void dac_reset(FAR struct dac_dev_s *dev); +static int dac_setup(FAR struct dac_dev_s *dev); +static void dac_shutdown(FAR struct dac_dev_s *dev); +static void dac_txint(FAR struct dac_dev_s *dev, bool enable); +static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg); +static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg); +static int dac_interrupt(int irq, void *context); + +/**************************************************************************** + * ad_private Data + ****************************************************************************/ + +static const struct dac_ops_s g_dacops = +{ + .ao_reset =dac_reset, + .ao_setup = dac_setup, + .ao_shutdown = dac_shutdown, + .ao_txint = dac_txint, + .ao_send = dac_send, + .ao_ioctl = dac_ioctl, +}; + +static struct dac_dev_s g_dacdev = +{ + .ad_ops = &g_dacops, +}; + +/**************************************************************************** + * ad_private Functions + ****************************************************************************/ + +/* Reset the DAC device. Called early to initialize the hardware. This +* is called, before ao_setup() and on error conditions. +*/ +static void dac_reset(FAR struct dac_dev_s *dev) +{ + irqstate_t flags; + uint32_t regval; + + flags = irqsave(); + + regval = getreg32(LPC17_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_DAC_MASK; + regval |= (SYSCON_PCLKSEL_CCLK8 << SYSCON_PCLKSEL0_DAC_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL0); + + //putreg32(DAC_CTRL_DBLBUFEN,LPC17_DAC_CTRL); ? + + lpc17_configgpio(GPIO_AOUT); + + irqrestore(flags); + +} + +/* Configure the DAC. This method is called the first time that the DAC +* device is opened. This will occur when the port is first opened. +* This setup includes configuring and attaching DAC interrupts. Interrupts +* are all disabled upon return. +*/ +static int dac_setup(FAR struct dac_dev_s *dev) +{ + return OK; +} + +/* Disable the DAC. This method is called when the DAC device is closed. +* This method reverses the operation the setup method. +*/ +static void dac_shutdown(FAR struct dac_dev_s *dev) +{ +} + +/* Call to enable or disable TX interrupts */ +static void dac_txint(FAR struct dac_dev_s *dev, bool enable) +{ +} + +static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg) +{ + putreg32((msg->am_data>>16)&0xfffff,LPC17_DAC_CR); + dac_txdone(&g_dacdev); + return 0; +} + +/* All ioctl calls will be routed through this method */ +static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg) +{ + dbg("Fix me:Not Implemented\n"); + return 0; +} + +static int dac_interrupt(int irq, void *context) +{ +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_dacinitialize + * + * Description: + * Initialize the DAC + * + * Returned Value: + * Valid dac device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct dac_dev_s *up_dacinitialize() +{ + return &g_dacdev; +} +#endif + diff --git a/drivers/analog/Make.defs b/drivers/analog/Make.defs index 4702fc8d89c1c644a0a136ba8f43aa0df9d18974..ed09c709a4b1bbd17c9b5b6b2f783df7fba651a4 100644 --- a/drivers/analog/Make.defs +++ b/drivers/analog/Make.defs @@ -41,8 +41,13 @@ ifeq ($(CONFIG_DAC),y) # Include the common ADC character driver +CSRCS += dac.c + # Include DAC device drivers +ifeq ($(CONFIG_DAC_AD5410),y) + CSRCS += ad5410.c +endif endif # Check for ADC devices diff --git a/drivers/analog/ad5410.c b/drivers/analog/ad5410.c new file mode 100644 index 0000000000000000000000000000000000000000..65e4adf7da086c9b131860cd1f19fbb29b83cd4d --- /dev/null +++ b/drivers/analog/ad5410.c @@ -0,0 +1,206 @@ +/************************************************************************************ + * arch/drivers/analog/ad5410.c + * + * Copyright (C) 2011 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi <lzyy.cn@gmail.com> + * History: 0.1 2011-08-05 initial version + * + * This file is a part of NuttX: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#include <nuttx/config.h> + +#include <stdio.h> +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <semaphore.h> +#include <errno.h> +#include <debug.h> + +#include <arch/board/board.h> +#include <nuttx/arch.h> +#include <nuttx/analog/dac.h> +#include <nuttx/spi.h> +#include "lpc17_internal.h" + +#if defined(CONFIG_DAC_AD5410) + +#define AD5410_REG_NOP 0x00 +#define AD5410_REG_WR 0x01 +#define AD5410_REG_RD 0x02 +#define AD5410_REG_CMD 0x55 +#define AD5410_REG_RST 0x56 + +#define AD5410_CMD_REXT (1<<13) +#define AD5410_CMD_OUTEN (1<<12) +#define AD5410_CMD_SRCLK(x) (x<<8) +#define AD5410_CMD_SRSTEP(x) (x<<5) +#define AD5410_CMD_SREN (1<<4) +#define AD5410_CMD_DCEN (1<<3) +#define AD5410_CMD_420MA 0x05 +#define AD5410_CMD_020MA 0x06 +#define AD5410_CMD_024MA 0x07 + +/**************************************************************************** + * ad_private Types + ****************************************************************************/ +struct up_dev_s +{ + int devno; + FAR struct spi_dev_s *spi; /* Cached SPI device reference */ +}; + +/**************************************************************************** + * ad_private Function Prototypes + ****************************************************************************/ + +/* DAC methods */ + +static void dac_reset(FAR struct dac_dev_s *dev); +static int dac_setup(FAR struct dac_dev_s *dev); +static void dac_shutdown(FAR struct dac_dev_s *dev); +static void dac_txint(FAR struct dac_dev_s *dev, bool enable); +static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg); +static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg); +static int dac_interrupt(int irq, void *context); + +/**************************************************************************** + * ad_private Data + ****************************************************************************/ + +static const struct dac_ops_s g_dacops = +{ + .ao_reset =dac_reset, + .ao_setup = dac_setup, + .ao_shutdown = dac_shutdown, + .ao_txint = dac_txint, + .ao_send = dac_send, + .ao_ioctl = dac_ioctl, +}; + +static struct up_dev_s g_dacpriv; +static struct dac_dev_s g_dacdev = +{ + .ad_ops = &g_dacops, + .ad_priv= &g_dacpriv, +}; + +/**************************************************************************** + * ad_private Functions + ****************************************************************************/ + +/* Reset the DAC device. Called early to initialize the hardware. This +* is called, before ao_setup() and on error conditions. +*/ +static void dac_reset(FAR struct dac_dev_s *dev) +{ + +} + +/* Configure the DAC. This method is called the first time that the DAC +* device is opened. This will occur when the port is first opened. +* This setup includes configuring and attaching DAC interrupts. Interrupts +* are all disabled upon return. +*/ +static int dac_setup(FAR struct dac_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; + FAR struct spi_dev_s *spi = priv->spi; + SPI_SELECT(spi, priv->devno, true); + SPI_SEND(spi,AD5410_REG_CMD); + SPI_SEND(spi,(AD5410_CMD_OUTEN|AD5410_CMD_420MA)>>8); + SPI_SEND(spi,AD5410_CMD_OUTEN|AD5410_CMD_420MA); + SPI_SELECT(spi, priv->devno, false); + return OK; +} + +/* Disable the DAC. This method is called when the DAC device is closed. +* This method reverses the operation the setup method. +*/ +static void dac_shutdown(FAR struct dac_dev_s *dev) +{ +} + +/* Call to enable or disable TX interrupts */ +static void dac_txint(FAR struct dac_dev_s *dev, bool enable) +{ +} + +static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; + FAR struct spi_dev_s *spi = priv->spi; + SPI_SELECT(spi, priv->devno, true); + SPI_SEND(spi,AD5410_REG_WR); + SPI_SEND(spi,(uint8_t)(msg->am_data>>24)); + SPI_SEND(spi,(uint8_t)(msg->am_data>>16)); + SPI_SELECT(spi, priv->devno, false); + dac_txdone(&g_dacdev); + return 0; +} + +/* All ioctl calls will be routed through this method */ +static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg) +{ + dbg("Fix me:Not Implemented\n"); + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_ad5410cinitialize + * + * Description: + * Initialize the selected DAC port + * + * Input Parameter: + * Port number (for hardware that has mutiple DAC interfaces) + * + * Returned Value: + * Valid ad5410 device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct dac_dev_s *up_ad5410initialize(FAR struct spi_dev_s *spi, unsigned int devno) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_dacdev.ad_priv; + priv->spi=spi; + priv->devno=devno; + return &g_dacdev; +} +#endif + diff --git a/drivers/analog/adc.c b/drivers/analog/adc.c index 664bd546192ed4f2577d9232c3b1a26a799c500e..bf3d7bdf6c298442cfc0a038621a66b7c111c40f 100644 --- a/drivers/analog/adc.c +++ b/drivers/analog/adc.c @@ -1,5 +1,5 @@ /**************************************************************************** - * drivers/adc/adc.c + * drivers/analog/adc.c * * Copyright (C) 2011 Li Zhuoyi. All rights reserved. * Author: Li Zhuoyi <lzyy.cn@gmail.com> diff --git a/drivers/analog/ads1255.c b/drivers/analog/ads1255.c index adc053a9353893508701a941fdd202bf6b116646..374decc54aa925cd87b79f532640ef84617dc8a2 100644 --- a/drivers/analog/ads1255.c +++ b/drivers/analog/ads1255.c @@ -1,9 +1,10 @@ /************************************************************************************ - * arch/drivers/adc/ads1255.c + * arch/drivers/analog/ads1255.c * * Copyright (C) 2011 Li Zhuoyi. All rights reserved. * Author: Li Zhuoyi <lzyy.cn@gmail.com> * History: 0.1 2011-08-05 initial version + * 0.2 2011-08-25 fix bug in g_adcdev (cd_ops -> ad_ops,cd_priv -> ad_priv) * * This file is a part of NuttX: * @@ -101,13 +102,13 @@ #endif /**************************************************************************** - * cd_private Types + * ad_private Types ****************************************************************************/ struct up_dev_s { uint8_t channel; - uint8_t sps; + uint32_t sps; uint8_t pga; uint8_t buf; const uint8_t *mux; @@ -117,7 +118,7 @@ struct up_dev_s }; /**************************************************************************** - * cd_private Function Prototypes + * ad_private Function Prototypes ****************************************************************************/ /* ADC methods */ @@ -130,16 +131,16 @@ static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg); static int adc_interrupt(int irq, void *context); /**************************************************************************** - * cd_private Data + * ad_private Data ****************************************************************************/ static const struct adc_ops_s g_adcops = { - adc_reset, /* ao_reset */ - adc_setup, /* ao_setup */ - adc_shutdown, /* ao_shutdown */ - adc_rxint, /* ao_rxint */ - adc_ioctl /* ao_read */ + .ao_reset = adc_reset, /* ao_reset */ + .ao_setup = adc_setup, /* ao_setup */ + .ao_shutdown = adc_shutdown, /* ao_shutdown */ + .ao_rxint = adc_rxint, /* ao_rxint */ + .ao_ioctl = adc_ioctl /* ao_read */ }; static struct up_dev_s g_adcpriv = @@ -155,8 +156,8 @@ static struct up_dev_s g_adcpriv = static struct adc_dev_s g_adcdev = { - .cd_ops = &g_adcops, - .cd_priv= &g_adcpriv, + .ad_ops = &g_adcops, + .ad_priv= &g_adcpriv, }; /**************************************************************************** @@ -183,7 +184,7 @@ static uint8_t getspsreg(uint16_t sps) } /**************************************************************************** - * cd_private Functions + * ad_private Functions ****************************************************************************/ /* Reset the ADC device. Called early to initialize the hardware. This * is called, before ao_setup() and on error conditions. @@ -191,7 +192,7 @@ static uint8_t getspsreg(uint16_t sps) static void adc_reset(FAR struct adc_dev_s *dev) { - FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->cd_priv; + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; FAR struct spi_dev_s *spi = priv->spi; SPI_SETMODE(spi, SPIDEV_MODE1); @@ -213,7 +214,7 @@ static void adc_reset(FAR struct adc_dev_s *dev) static int adc_setup(FAR struct adc_dev_s *dev) { - FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->cd_priv; + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; FAR struct spi_dev_s *spi = priv->spi; int ret = irq_attach(priv->irq, adc_interrupt); if (ret == OK) @@ -242,7 +243,7 @@ static int adc_setup(FAR struct adc_dev_s *dev) static void adc_shutdown(FAR struct adc_dev_s *dev) { - FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->cd_priv; + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; up_disable_irq(priv->irq); irq_detach(priv->irq); } @@ -251,7 +252,7 @@ static void adc_shutdown(FAR struct adc_dev_s *dev) static void adc_rxint(FAR struct adc_dev_s *dev, bool enable) { - FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->cd_priv; + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; if (enable) up_enable_irq(priv->irq); else @@ -269,7 +270,7 @@ static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) static int adc_interrupt(int irq, void *context) { uint32_t regval; - FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.cd_priv; + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.ad_priv; FAR struct spi_dev_s *spi = priv->spi; unsigned char buf[4]; unsigned char ch; @@ -322,7 +323,7 @@ static int adc_interrupt(int irq, void *context) FAR struct adc_dev_s *up_ads1255initialize(FAR struct spi_dev_s *spi, unsigned int devno) { - FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.cd_priv; + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.ad_priv; /* Driver state data */ diff --git a/drivers/analog/dac.c b/drivers/analog/dac.c new file mode 100644 index 0000000000000000000000000000000000000000..a5f4c1473f9292a042e69c47660f9fb585662b42 --- /dev/null +++ b/drivers/analog/dac.c @@ -0,0 +1,498 @@ +/**************************************************************************** + * drivers/analog/dac.c + * + * Copyright (C) 2011 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi <lzyy.cn@gmail.com> + * History: 0.1 2011-08-04 initial version + * + * Derived from drivers/can.c + * + * Copyright (C) 2008-2009Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <unistd.h> +#include <string.h> +#include <semaphore.h> +#include <fcntl.h> +#include <errno.h> +#include <debug.h> + +#include <nuttx/fs.h> +#include <nuttx/arch.h> +#include <nuttx/analog/dac.h> + +#include <arch/irq.h> + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define HALF_SECOND_MSEC 500 +#define HALF_SECOND_USEC 500000L + + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int dac_open(FAR struct file *filep); +static int dac_close(FAR struct file *filep); +static ssize_t dac_read(FAR struct file *, FAR char *, size_t); +static ssize_t dac_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); +static int dac_ioctl(FAR struct file *filep,int cmd,unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations dac_fops = +{ + dac_open, + dac_close, + dac_read, + dac_write, + 0, + dac_ioctl +#ifndef CONFIG_DISABLE_POLL + , 0 +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/************************************************************************************ + * Name: dac_open + * + * Description: + * This function is called whenever the DAC device is opened. + * + ************************************************************************************/ + +static int dac_open(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct dac_dev_s *dev = inode->i_private; + uint8_t tmp; + int ret = OK; + + /* If the port is the middle of closing, wait until the close is finished */ + + if (sem_wait(&dev->ad_closesem) != OK) + { + ret = -errno; + } + else + { + /* Increment the count of references to the device. If this the first + * time that the driver has been opened for this device, then initialize + * the device. + */ + + tmp = dev->ad_ocount + 1; + if (tmp == 0) + { + /* More than 255 opens; uint8_t overflows to zero */ + + ret = -EMFILE; + } + else + { + /* Check if this is the first time that the driver has been opened. */ + + if (tmp == 1) + { + /* Yes.. perform one time hardware initialization. */ + + irqstate_t flags = irqsave(); + ret = dev->ad_ops->ao_setup(dev); + if (ret == OK) + { + /* Mark the FIFOs empty */ + + dev->ad_xmit.af_head = 0; + dev->ad_xmit.af_tail = 0; + + /* Save the new open count on success */ + + dev->ad_ocount = tmp; + } + irqrestore(flags); + } + } + sem_post(&dev->ad_closesem); + } + return ret; +} + +/************************************************************************************ + * Name: dac_close + * + * Description: + * This routine is called when the DAC device is closed. + * It waits for the last remaining data to be sent. + * + ************************************************************************************/ + +static int dac_close(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct dac_dev_s *dev = inode->i_private; + irqstate_t flags; + int ret = OK; + + if (sem_wait(&dev->ad_closesem) != OK) + { + ret = -errno; + } + else + { + /* Decrement the references to the driver. If the reference count will + * decrement to 0, then uninitialize the driver. + */ + + if (dev->ad_ocount > 1) + { + dev->ad_ocount--; + sem_post(&dev->ad_closesem); + } + else + { + /* There are no more references to the port */ + + dev->ad_ocount = 0; + + /* Now we wait for the transmit FIFO to clear */ + + while (dev->ad_xmit.af_head != dev->ad_xmit.af_tail) + { +#ifndef CONFIG_DISABLE_SIGNALS + usleep(HALF_SECOND_USEC); +#else + up_mdelay(HALF_SECOND_MSEC); +#endif + } + + /* Free the IRQ and disable the DAC device */ + + flags = irqsave(); /* Disable interrupts */ + dev->ad_ops->ao_shutdown(dev); /* Disable the DAC */ + irqrestore(flags); + + sem_post(&dev->ad_closesem); + } + } + return ret; +} + +/**************************************************************************** + * Name: dac_read + ****************************************************************************/ + +static ssize_t dac_read(FAR struct file *filep, FAR char *buffer, size_t buflen) +{ + return 0; +} + +/************************************************************************************ + * Name: dac_xmit + * + * Description: + * Send the message at the head of the ad_xmit FIFO + * + * Assumptions: + * Called with interrupts disabled + * + ************************************************************************************/ + +static int dac_xmit(FAR struct dac_dev_s *dev) +{ + bool enable = false; + int ret = OK; + + /* Check if the xmit FIFO is empty */ + + if (dev->ad_xmit.af_head != dev->ad_xmit.af_tail) + { + /* Send the next message at the head of the FIFO */ + + ret = dev->ad_ops->ao_send(dev, &dev->ad_xmit.af_buffer[dev->ad_xmit.af_head]); + + /* Make sure the TX done interrupts are enabled */ + + enable = (ret == OK ? true : false); + } + dev->ad_ops->ao_txint(dev, enable); + return ret; +} + +/************************************************************************************ + * Name: dac_write + ************************************************************************************/ + +static ssize_t dac_write(FAR struct file *filep, FAR const char *buffer, size_t buflen) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct dac_dev_s *dev = inode->i_private; + FAR struct dac_fifo_s *fifo = &dev->ad_xmit; + FAR struct dac_msg_s *msg; + bool empty = false; + ssize_t nsent = 0; + irqstate_t flags; + int nexttail; + int msglen; + int ret = 0; + + /* Interrupts must disabled throughout the following */ + + flags = irqsave(); + + /* Check if the TX FIFO was empty when we started. That is a clue that we have + * to kick off a new TX sequence. + */ + + empty = (fifo->af_head == fifo->af_tail); + + /* Add the messages to the FIFO. Ignore any trailing messages that are + * shorter than the minimum. + */ + + if (buflen % 5 ==0 ) + msglen=5; + else if (buflen % 4 ==0 ) + msglen=4; + else if (buflen % 3 ==0 ) + msglen=3; + else if (buflen % 2 ==0 ) + msglen=2; + else if (buflen == 1) + msglen=1; + else + msglen=5; + + while ((buflen - nsent) >= msglen ) + { + /* Check if adding this new message would over-run the drivers ability to enqueue + * xmit data. + */ + + nexttail = fifo->af_tail + 1; + if (nexttail >= CONFIG_DAC_FIFOSIZE) + { + nexttail = 0; + } + + /* If the XMIT fifo becomes full, then wait for space to become available */ + + while (nexttail == fifo->af_head) + { + /* The transmit FIFO is full -- was non-blocking mode selected? */ + + if (filep->f_oflags & O_NONBLOCK) + { + if (nsent == 0) + { + ret = -EAGAIN; + } + else + { + ret = nsent; + } + goto return_with_irqdisabled; + } + + /* If the FIFO was empty when we started, then we will have + * start the XMIT sequence to clear the FIFO. + */ + + if (empty) + { + dac_xmit(dev); + } + + /* Wait for a message to be sent */ + + do + { + ret = sem_wait(&fifo->af_sem); + if (ret < 0 && errno != EINTR) + { + ret = -errno; + goto return_with_irqdisabled; + } + } + while (ret < 0); + + /* Re-check the FIFO state */ + + empty = (fifo->af_head == fifo->af_tail); + } + + /* We get here if there is space at the end of the FIFO. Add the new + * CAN message at the tail of the FIFO. + */ + if(msglen==5) + { + msg = (FAR struct dac_msg_s *)&buffer[nsent]; + memcpy(&fifo->af_buffer[fifo->af_tail], msg, msglen); + } + else if(msglen == 4) + { + fifo->af_buffer[fifo->af_tail].am_channel=buffer[nsent]; + fifo->af_buffer[fifo->af_tail].am_data=*(uint32_t *)&buffer[nsent]; + fifo->af_buffer[fifo->af_tail].am_data&=0xffffff00; + } + else if(msglen == 3) + { + fifo->af_buffer[fifo->af_tail].am_channel=buffer[nsent]; + fifo->af_buffer[fifo->af_tail].am_data=(*(uint16_t *)&buffer[nsent+1]); + fifo->af_buffer[fifo->af_tail].am_data<<=16; + } + else if(msglen == 2) + { + fifo->af_buffer[fifo->af_tail].am_channel=0; + fifo->af_buffer[fifo->af_tail].am_data=(*(uint16_t *)&buffer[nsent]); + fifo->af_buffer[fifo->af_tail].am_data<<=16; + } + else if(msglen == 1) + { + fifo->af_buffer[fifo->af_tail].am_channel=0; + fifo->af_buffer[fifo->af_tail].am_data=buffer[nsent]; + fifo->af_buffer[fifo->af_tail].am_data<<=24; + } + /* Increment the tail of the circular buffer */ + + fifo->af_tail = nexttail; + + /* Increment the number of bytes that were sent */ + + nsent += msglen; + } + + /* We get here after all messages have been added to the FIFO. Check if + * we need to kick of the XMIT sequence. + */ + + if (empty) + { + dac_xmit(dev); + } + + /* Return the number of bytes that were sent */ + + ret = nsent; + +return_with_irqdisabled: + irqrestore(flags); + return ret; +} + +/************************************************************************************ + * Name: dac_ioctl + ************************************************************************************/ + +static int dac_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct dac_dev_s *dev = inode->i_private; + int ret = OK; + + ret = dev->ad_ops->ao_ioctl(dev, cmd, arg); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/************************************************************************************ + * Name: dac_txdone + * + * Description: + * Called from the DAC interrupt handler at the completion of a send operation. + * + * Return: + * OK on success; a negated errno on failure. + * + ************************************************************************************/ + +int dac_txdone(FAR struct dac_dev_s *dev) +{ + int ret = -ENOENT; + + /* Verify that the xmit FIFO is not empty */ + + if (dev->ad_xmit.af_head != dev->ad_xmit.af_tail) + { + /* Remove the message at the head of the xmit FIFO */ + + if (++dev->ad_xmit.af_head >= CONFIG_DAC_FIFOSIZE) + { + dev->ad_xmit.af_head = 0; + } + + /* Send the next message in the FIFO */ + + ret = dac_xmit(dev); + if (ret == OK) + { + /* Inform any waiting threads that new xmit space is available */ + + ret = sem_post(&dev->ad_xmit.af_sem); + } + } + return ret; +} + +int dac_register(FAR const char *path, FAR struct dac_dev_s *dev) +{ + /* Initialize the DAC device structure */ + + dev->ad_ocount = 0; + + sem_init(&dev->ad_xmit.af_sem, 0, 0); + sem_init(&dev->ad_closesem, 0, 1); + + dev->ad_ops->ao_reset(dev); + + return register_driver(path, &dac_fops, 0555, dev); +} + diff --git a/include/nuttx/analog/adc.h b/include/nuttx/analog/adc.h index 1afb5926d413dcf773c83e0d6fdf7a886c1f9a58..c4c5eba460d37b229d334173485578908ac7310e 100644 --- a/include/nuttx/analog/adc.h +++ b/include/nuttx/analog/adc.h @@ -4,6 +4,7 @@ * Copyright (C) 2011 Li Zhuoyi. All rights reserved. * Author: Li Zhuoyi <lzyy.cn@gmail.com> * History: 0.1 2011-08-04 initial version + * 0.2 remove ao_read * * Derived from include/nuttx/can.h * Copyright (C) 2008, 2009 Gregory Nutt. All rights reserved. @@ -120,8 +121,6 @@ struct adc_ops_s CODE void (*ao_rxint)(FAR struct adc_dev_s *dev, bool enable); - CODE int (*ao_read)(FAR struct adc_dev_s *dev, char *buffer,int len); - /* All ioctl calls will be routed through this method */ CODE int (*ao_ioctl)(FAR struct adc_dev_s *dev, int cmd, unsigned long arg); @@ -182,6 +181,15 @@ int adc_receive(FAR struct adc_dev_s *dev, uint8_t ch, int32_t data); FAR struct adc_dev_s *up_ads1255initialize(FAR struct spi_dev_s *spi, unsigned int devno); +/************************************************************************************ + * Name: up_adcinitialize + * + * Description: + * Initialize the MCU internal adc driver + * + ************************************************************************************/ +FAR struct adc_dev_s *up_adcinitialize(); + #if defined(__cplusplus) } #endif diff --git a/include/nuttx/analog/dac.h b/include/nuttx/analog/dac.h new file mode 100644 index 0000000000000000000000000000000000000000..7359e6c3aacf8e715cf034c551e95fce2d95a873 --- /dev/null +++ b/include/nuttx/analog/dac.h @@ -0,0 +1,189 @@ +/************************************************************************************ + * include/nuttx/analog/dac.h + * + * Copyright (C) 2011 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi <lzyy.cn@gmail.com> + * History: 0.1 2011-08-04 initial version + * + * Derived from include/nuttx/can.h + * Copyright (C) 2008, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __NUTTX_DAC_H +#define __NUTTX_DAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <semaphore.h> +#include <nuttx/fs.h> +#include <nuttx/spi.h> + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Default configuration settings that may be overridden in the board configuration. + * file. The configured size is limited to 255 to fit into a uint8_t. + */ + +#if !defined(CONFIG_DAC_FIFOSIZE) +# define CONFIG_DAC_FIFOSIZE 8 +#elif CONFIG_DAC_FIFOSIZE > 255 +# undef CONFIG_DAC_FIFOSIZE +# define CONFIG_DAC_FIFOSIZE 255 +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ +struct dac_msg_s +{ + uint8_t am_channel; /* The 8-bit DAC Channel */ + int32_t am_data; /* DAC convert result (4 bytes) */ +}; + +struct dac_fifo_s +{ + sem_t af_sem; /* Counting semaphore */ + uint8_t af_head; /* Index to the head [IN] index in the circular buffer */ + uint8_t af_tail; /* Index to the tail [OUT] index in the circular buffer */ + /* Circular buffer of CAN messages */ + struct dac_msg_s af_buffer[CONFIG_DAC_FIFOSIZE]; +}; + +/* This structure defines all of the operations providd by the architecture specific + * logic. All fields must be provided with non-NULL function pointers by the + * caller of dac_register(). + */ + +struct dac_dev_s; +struct dac_ops_s +{ + /* Reset the DAC device. Called early to initialize the hardware. This + * is called, before ao_setup() and on error conditions. + */ + + CODE void (*ao_reset)(FAR struct dac_dev_s *dev); + + /* Configure the DAC. This method is called the first time that the DAC + * device is opened. This will occur when the port is first opened. + * This setup includes configuring and attaching DAC interrupts. Interrupts + * are all disabled upon return. + */ + + CODE int (*ao_setup)(FAR struct dac_dev_s *dev); + + /* Disable the DAC. This method is called when the DAC device is closed. + * This method reverses the operation the setup method. + */ + CODE void (*ao_shutdown)(FAR struct dac_dev_s *dev); + + /* Call to enable or disable TX interrupts */ + + CODE void (*ao_txint)(FAR struct dac_dev_s *dev, bool enable); + + /* This method will send one message on the DAC */ + + CODE int (*ao_send)(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg); + + /* All ioctl calls will be routed through this method */ + + CODE int (*ao_ioctl)(FAR struct dac_dev_s *dev, int cmd, unsigned long arg); + +}; + +/* This is the device structure used by the driver. The caller of + * dac_register() must allocate and initialize this structure. The + * calling logic need only set all fields to zero except: + * + * The elements of 'ad_ops', and 'ad_priv' + * + * The common logic will initialize all semaphores. + */ + +struct dac_dev_s +{ + uint8_t ad_ocount; /* The number of times the device has been opened */ + uint8_t ad_nchannel; /* Number of dac channel */ + sem_t ad_closesem; /* Locks out new opens while close is in progress */ + struct dac_fifo_s ad_xmit; /* Describes receive FIFO */ + const struct dac_ops_s *ad_ops; /* Arch-specific operations */ + void *ad_priv; /* Used by the arch-specific logic */ +}; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif +/************************************************************************************ + * Name: dac_register + * + * Description: + * Register a dac driver. + * + ************************************************************************************/ + +int dac_register(FAR const char *path, FAR struct dac_dev_s *dev); + +/************************************************************************************ + * Name: dac_txdone + * + * Description: + * Called from the DAC interrupt handler at the completion of a send operation. + * + * Return: + * OK on success; a negated errno on failure. + * + ************************************************************************************/ +int dac_txdone(FAR struct dac_dev_s *dev); + +FAR struct dac_dev_s *up_ad5410initialize(FAR struct spi_dev_s *spi, unsigned int devno); +FAR struct dac_dev_s *up_dacinitialize(); + +#if defined(__cplusplus) +} +#endif + +#endif /* __NUTTX_DAC_H */ diff --git a/syscall/README.txt b/syscall/README.txt index 7c45207f868901bcdcf10a6f6ad974ac9b6c4598..7797c5781f1ba2132dba46178ea088757dc1390d 100644 --- a/syscall/README.txt +++ b/syscall/README.txt @@ -17,7 +17,7 @@ The syscall layer provided in this directory serves as the communication layer from the user-mode application into the kernel-mode RTOS. The switch from user-mode to kernel-mode is accomplished using software interrupts (SWIs). SWIs are implemented differently and named differently -by different manufacters but all work essentially the same: A special +by different manufacturers but all work essentially the same: A special instruction is executed in user-mode that causes a software generated interrupt. The software generated interrrupt is caught within the kernel and handle in kernel-mode. @@ -84,7 +84,7 @@ implemented as a simple comma-separated-value file, syscall.csv. Most spreadsheets programs will accept this format and can be used to maintain the syscall database. -The format of the CVS file for each line is: +The format of the CSV file for each line is: Field 1: Function name Field 2: The header file that contains the function prototype @@ -104,7 +104,7 @@ Each type field has a format as follows: A similar situation exists for unions. For example, the formal parameter type union sigval -- You cannot cast a uintptr_t to a union sigval, but you can cast to the type of one of the union - member types when passing the actua paramter. Similarly, we + member types when passing the actual paramter. Similarly, we cannot cast a union sigval to a uinptr_t either. Rather, we need to cast a specific union member fieldname to uintptr_t. @@ -122,7 +122,7 @@ database. Here the following definition is used: Stub - Another tiny bit of code that executes within the NuttX kernel that is used to map a software interrupt received by the kernel to - a kernel function call. The stubs receive the marshalled system + a kernel function call. The stubs receive the marshaled system call data, and perform the actually kernel function call (in kernel-mode) on behalf of the proxy function. @@ -140,4 +140,4 @@ mksyscall stubs and proxies is maintained in a comma separated value (CSV) file in the syscall/ directory. The mksyscall program will accept this CVS file as input and generate all of the required proxy or stub files as - output. See tools/README.txt for additonal information. + output. See tools/README.txt for additional information.