diff --git a/arch/arm/src/tiva/Kconfig b/arch/arm/src/tiva/Kconfig index 12e8970121..c4cf4b57a6 100644 --- a/arch/arm/src/tiva/Kconfig +++ b/arch/arm/src/tiva/Kconfig @@ -91,6 +91,8 @@ config ARCH_CHIP_TM4C123GH6ZRB select TIVA_HAVE_GPIOQ_IRQS select TIVA_HAVE_I2C4 select TIVA_HAVE_I2C5 + select TIVA_HAVE_QEI0 + select TIVA_HAVE_QEI1 config ARCH_CHIP_TM4C123GH6PM bool "TM4C123GH6PM" @@ -105,6 +107,8 @@ config ARCH_CHIP_TM4C123GH6PM select TIVA_HAVE_GPIOF_IRQS select TIVA_HAVE_ADC0 select TIVA_HAVE_ADC1 + select TIVA_HAVE_QEI0 + select TIVA_HAVE_QEI1 config ARCH_CHIP_TM4C1294NCPDT bool "TM4C1294NCPDT" @@ -122,6 +126,7 @@ config ARCH_CHIP_TM4C1294NCPDT select TIVA_HAVE_GPION_IRQS select TIVA_HAVE_GPIOP_IRQS select TIVA_HAVE_GPIOQ_IRQS + select TIVA_HAVE_QEI0 config ARCH_CHIP_TM4C129XNC bool "TM4C129XNC" @@ -141,6 +146,7 @@ config ARCH_CHIP_TM4C129XNC select TIVA_HAVE_GPIOR_IRQS select TIVA_HAVE_GPIOS_IRQS select TIVA_HAVE_GPIOT_IRQS + select TIVA_HAVE_QEI0 config ARCH_CHIP_CC1310 bool "CC1310 SimpleLink" @@ -315,6 +321,18 @@ config TIVA_HAVE_ADC1 bool default n +config TIVA_QEI + bool + default n + +config TIVA_HAVE_QEI0 + bool + default n + +config TIVA_HAVE_QEI1 + bool + default n + config TIVA_I2C bool default n @@ -462,6 +480,18 @@ config TIVA_ADC1 depends on TIVA_HAVE_ADC0 select TIVA_ADC +config TIVA_QEI0 + bool "QEI0" + default n + depends on TIVA_HAVE_QEI0 + select TIVA_QEI + +config TIVA_QEI1 + bool "QEI1" + default n + depends on TIVA_HAVE_QEI1 + select TIVA_QEI + config TIVA_I2C0 bool "I2C0" default n diff --git a/arch/arm/src/tiva/common/tiva_qencoder.c b/arch/arm/src/tiva/common/tiva_qencoder.c index e80f83aebd..8088cdaf79 100644 --- a/arch/arm/src/tiva/common/tiva_qencoder.c +++ b/arch/arm/src/tiva/common/tiva_qencoder.c @@ -94,7 +94,9 @@ static int tiva_qe_ioctl(FAR struct qe_lowerhalf_s *lower, int cmd, static int tiva_qe_direction(struct tiva_qe_s *qe, unsigned long *dir); static int tiva_qe_velocity(struct tiva_qe_s *qe, unsigned long *vel); -static int tiva_qe_ppr(struct tiva_qe_s *qe, unsigned long ppr); +static int tiva_qe_resetatppr(struct tiva_qe_s *qe, unsigned long ppr); +static int tiva_qe_resetatmaxpos(FAR struct tiva_qe_s *qe, unsigned long offs); +static int tiva_qe_resetatindex(FAR struct tiva_qe_s *qe); /************************************************************************************ * Private Data @@ -216,23 +218,51 @@ static int tiva_qe_setup(FAR struct qe_lowerhalf_s *lower) return -1; } - /* Set reset mode (default as INDEX_PULSE) */ + /* Get initial value of register */ - ctlreg = RESMODE_BY_INDEX_PULSE << TIVA_QEI_CTL_RESMODE; - tiva_qe_putreg(qe, TIVA_QEI_CTL_OFFSET, ctlreg); + ctlreg = tiva_qe_getreg(qe, TIVA_QEI_CTL_OFFSET); + + /* Turn off the bits we're about to control */ + + ctlreg &= ~(uint32_t)((1 << TIVA_QEI_CTL_RESMODE) | + (1 << TIVA_QEI_CTL_CAPMODE) | + (1 << TIVA_QEI_CTL_VELEN) | + (1 << TIVA_QEI_CTL_SIGMODE) | + (1 << TIVA_QEI_CTL_SWAP)); + + /* Set reset mode (default as MAXPOS) */ + + ctlreg |= RESMODE_BY_MAXPOS << TIVA_QEI_CTL_RESMODE; /* Set capture mode (default as PHA_AND_PHB) */ - ctlreg = tiva_qe_getreg(qe, TIVA_QEI_CTL_OFFSET); ctlreg |= CAPMODE_PHA_AND_PHB << TIVA_QEI_CTL_CAPMODE; - tiva_qe_putreg(qe, TIVA_QEI_CTL_OFFSET, ctlreg); /* Enable velocity capture */ - ctlreg = tiva_qe_getreg(qe, TIVA_QEI_CTL_OFFSET); ctlreg |= VELEN_ENABLE << TIVA_QEI_CTL_VELEN; + + /* Set signal mode (default as quadrature) */ + + ctlreg |= SIGMODE_QUADRATURE << TIVA_QEI_CTL_SIGMODE; + + /* Set swap mode (default as no swap) */ + + ctlreg |= SWAP_NO_SWAP << TIVA_QEI_CTL_SWAP; + + /* Program the register */ + tiva_qe_putreg(qe, TIVA_QEI_CTL_OFFSET, ctlreg); + /* Set default maxpos value to entire uint32_t range */ + + qe->maxpos = UINT32_MAX; + tiva_qe_putreg(qe, TIVA_QEI_MAXPOS_OFFSET, qe->maxpos); + + /* Reset the position */ + + tiva_qe_putreg(qe, TIVA_QEI_POS_OFFSET, 0); + /* Set prediv (1) */ ctlreg = tiva_qe_getreg(qe, TIVA_QEI_CTL_OFFSET); @@ -365,8 +395,16 @@ static int tiva_qe_ioctl(FAR struct qe_lowerhalf_s *lower, int cmd, tiva_qe_velocity(qe, (unsigned long *)arg); break; - case QEIOC_PPR: - tiva_qe_ppr(qe, arg); + case QEIOC_RESETATPPR: + tiva_qe_resetatppr(qe, arg); + break; + + case QEIOC_RESETATMAXPOS: + tiva_qe_resetatmaxpos(qe, arg); + break; + + case QEIOC_RESETATINDEX: + tiva_qe_resetatindex(qe); break; default: @@ -432,10 +470,13 @@ static int tiva_qe_velocity(FAR struct tiva_qe_s *qe, unsigned long *vel) } /**************************************************************************** - * Name: tiva_qe_ppr + * Name: tiva_qe_resetatppr * * Description: - * Set reset mode as MAXPOS and also set maxpos value + * Set reset mode as MAXPOS and set maxpos value to number of pulses + * per round of encoder. Note that this function multiplies the given + * ppr by 4 because capture mode is PHA_AND_PHB, meaning we count 4 + * edges per "pulse." * * Input Parameters: * qe - A reference to the TIVA QEI structure @@ -446,7 +487,30 @@ static int tiva_qe_velocity(FAR struct tiva_qe_s *qe, unsigned long *vel) * ****************************************************************************/ -static int tiva_qe_ppr(FAR struct tiva_qe_s *qe, unsigned long ppr) +static int tiva_qe_resetatppr(FAR struct tiva_qe_s *qe, unsigned long ppr) +{ + /* maxpos is 4 times of ppr since we set capture mode as PHA_AND_PHB */ + + return tiva_qe_resetatmaxpos(qe, ppr * 4); +} + +/**************************************************************************** + * Name: tiva_qe_resetatmaxpos + * + * Description: + * Set reset mode as MAXPOS and set maxpos value as given. + * + * Input Parameters: + * qe - A reference to the TIVA QEI structure + * maxpos - Maximum position count at which QEI resets. To get the full + * range, give UINT32_MAX. + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int tiva_qe_resetatmaxpos(FAR struct tiva_qe_s *qe, unsigned long maxpos) { sninfo("set maxpos reset mode and maxpos value of QEI %d\n", qe->id); @@ -458,9 +522,7 @@ static int tiva_qe_ppr(FAR struct tiva_qe_s *qe, unsigned long ppr) lower = (FAR struct qe_lowerhalf_s *)qe; tiva_qe_shutdown(lower); - /* maxpos is 4 times of ppr since we set capture mode as PHA_AND_PHB */ - - qe->maxpos = ppr * 4; + qe->maxpos = maxpos; /* Set reset mode as MAXPOS */ @@ -482,6 +544,48 @@ static int tiva_qe_ppr(FAR struct tiva_qe_s *qe, unsigned long ppr) return OK; } +/**************************************************************************** + * Name: tiva_qe_resetatindex + * + * Description: + * Set reset mode as INDEX + * + * Input Parameters: + * qe - A reference to the TIVA QEI structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int tiva_qe_resetatindex(FAR struct tiva_qe_s *qe) +{ + sninfo("set index reset mode of QEI %d\n", qe->id); + + FAR struct qe_lowerhalf_s *lower; + uint32_t ctlreg = 0; + + /* Disable the QEI */ + + lower = (FAR struct qe_lowerhalf_s *)qe; + tiva_qe_shutdown(lower); + + /* Set reset mode as INDEX */ + + ctlreg = tiva_qe_getreg(qe, TIVA_QEI_CTL_OFFSET); + ctlreg &= ~(uint32_t)(1 << TIVA_QEI_CTL_RESMODE); + ctlreg |= RESMODE_BY_INDEX_PULSE << TIVA_QEI_CTL_RESMODE; + tiva_qe_putreg(qe, TIVA_QEI_CTL_OFFSET, ctlreg); + + /* Enable the QEI */ + + ctlreg = tiva_qe_getreg(qe, TIVA_QEI_CTL_OFFSET); + ctlreg |= QEI_ENABLE << TIVA_QEI_CTL_ENABLE; + tiva_qe_putreg(qe, TIVA_QEI_CTL_OFFSET, ctlreg); + + return OK; +} + /************************************************************************************ * Name: tiva_qei_initialize * diff --git a/arch/arm/src/tiva/hardware/tiva_qencoder.h b/arch/arm/src/tiva/hardware/tiva_qencoder.h index 030fe1c7a9..4a43f882f4 100644 --- a/arch/arm/src/tiva/hardware/tiva_qencoder.h +++ b/arch/arm/src/tiva/hardware/tiva_qencoder.h @@ -56,14 +56,14 @@ #define TIVA_QEI_RIS_OFFSET (0x24) /* QEI Raw Interrupt Status */ #define TIVA_QEI_ISC_OFFSET (0x28) /* QEI Interrupt Status and Clear */ +/* QEI_CTL register */ + #define TIVA_QEI_CTL_FILTCNT (16) /* (Bit) Input Filter Prescale Count */ #define TIVA_QEI_CTL_FILTEN (13) /* (Bit) Enable Input Filter */ #define TIVA_QEI_CTL_STALLEN (12) /* (Bit) Stall QEI */ #define TIVA_QEI_CTL_INVI (11) /* (Bit) Invert Index Pulse */ #define TIVA_QEI_CTL_INVB (10) /* (Bit) Invert PhB */ #define TIVA_QEI_CTL_INVA (9) /* (Bit) Invert PhA */ -#define TIVA_QEI_CTL_SIGMODE (2) /* (Bit) Signal Mode */ -#define TIVA_QEI_CTL_SWAP (1) /* (Bit) Swap Signals */ #define TIVA_QEI_CTL_VELDIV (6) /* (Bit) Predivide Velocity */ #define VELDIV_1 (0x0) /* (Value) Divided by 1 */ @@ -87,12 +87,23 @@ #define CAPMODE_ONLY_PHA (0) /* (Value) Count PhA both edges */ #define CAPMODE_PHA_AND_PHB (1) /* (Value) Count PhA and PhB both edges */ +#define TIVA_QEI_CTL_SIGMODE (2) /* (Bit) Signal Mode */ +#define SIGMODE_QUADRATURE (0) /* (Value) PhA and PhB are Quadrature signals */ +#define SIGMODE_CLK_AND_DIR (1) /* (Value) PhA is CLK, PhB is DIR */ + +#define TIVA_QEI_CTL_SWAP (1) /* (Bit) Swap PhA/PhB Signals */ +#define SWAP_NO_SWAP (0) /* (Value) No swapping */ +#define SWAP_PHA_PHB (1) /* (Value) Swap PhA and PhB */ + #define TIVA_QEI_CTL_ENABLE (0) /* (Bit) Enable QEI */ #define QEI_DISABLE (0) /* (Value) Disable QEI */ #define QEI_ENABLE (1) /* (Value) Enable QEI */ +/* QEI_STAT register */ + #define TIVA_QEI_STAT_DIRECTION (1) /* (Bit) Direction of Rotation */ #define DIRECTION_FORWARD (0) /* (Value) Forward */ #define DIRECTION_BACKWARD (1) /* (Value) Backward */ #endif /* __ARCH_ARM_SRC_TIVA_HARDWARE_TIVA_QENCODER_H */ + diff --git a/arch/arm/src/tiva/tiva_qencoder.h b/arch/arm/src/tiva/tiva_qencoder.h index 828eaba352..48eafc876d 100644 --- a/arch/arm/src/tiva/tiva_qencoder.h +++ b/arch/arm/src/tiva/tiva_qencoder.h @@ -1,44 +1,44 @@ /************************************************************************************ -* arch/arm/src/tiva/tiva_qencoder.h -* -* Copyright (C) 2016 Young Mu. All rights reserved. -* Author: Young Mu -* -* 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. -* -************************************************************************************/ + * arch/arm/src/tiva/tiva_qencoder.h + * + * Copyright (C) 2016 Young Mu. All rights reserved. + * Author: Young Mu + * + * 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 __ARCH_ARM_SRC_TIVA_TIVA_QENCODER_H #define __ARCH_ARM_SRC_TIVA_TIVA_QENCODER_H /************************************************************************************ -* Included Files -************************************************************************************/ + * Included Files + ************************************************************************************/ #include @@ -48,11 +48,13 @@ #define QEIOC_DIRECTION _QEIOC(QE_TIVA_FIRST) #define QEIOC_VELOCITY _QEIOC(QE_TIVA_FIRST+1) -#define QEIOC_PPR _QEIOC(QE_TIVA_FIRST+2) +#define QEIOC_RESETATPPR _QEIOC(QE_TIVA_FIRST+2) +#define QEIOC_RESETATMAXPOS _QEIOC(QE_TIVA_FIRST+3) +#define QEIOC_RESETATINDEX _QEIOC(QE_TIVA_FIRST+4) /**************************************************************************** -* Public Function Prototypes -****************************************************************************/ + * Public Function Prototypes + ****************************************************************************/ FAR struct qe_lowerhalf_s *tiva_qei_initialize(int id); diff --git a/include/nuttx/sensors/qencoder.h b/include/nuttx/sensors/qencoder.h index c9239f1d6a..72623ef3f3 100644 --- a/include/nuttx/sensors/qencoder.h +++ b/include/nuttx/sensors/qencoder.h @@ -48,11 +48,13 @@ /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ + /* Configuration ************************************************************ * CONFIG_SENSORS_QENCODER - Enables support for the quadrature encoder upper half */ /* IOCTL Commands ***********************************************************/ + /* The Quadrature Encode module uses a standard character driver framework. * However, since the driver is a device control interface rather than a * data transfer interface, the majority of the functionality is implemented @@ -80,7 +82,7 @@ /* See arch/arm/src/tiva/tiva_qencoder.h (Not usable at that location) */ #define QE_TIVA_FIRST (QE_FIRST + QE_NCMDS) -#define QE_TIVA_NCMDS 3 +#define QE_TIVA_NCMDS 5 /* See include/nuttx/sensors/as5048b.h */ @@ -90,6 +92,7 @@ /**************************************************************************** * Public Types ****************************************************************************/ + /* This is the vtable that is used to by the upper half quadrature encoder * to call back into the lower half quadrature encoder. */