diff --git a/arch/arm/src/tiva/Make.defs b/arch/arm/src/tiva/Make.defs index f3eb92fadc..98aed8cc65 100644 --- a/arch/arm/src/tiva/Make.defs +++ b/arch/arm/src/tiva/Make.defs @@ -105,6 +105,10 @@ ifeq ($(CONFIG_TIVA_PWM),y) CHIP_CSRCS += tiva_pwm.c endif +ifeq ($(CONFIG_TIVA_QEI),y) +CHIP_CSRCS += tiva_qencoder.c +endif + ifeq ($(CONFIG_TIVA_TIMER),y) CHIP_CSRCS += tiva_timerlib.c ifeq ($(CONFIG_TIVA_TIMER32_PERIODIC),y) diff --git a/arch/arm/src/tiva/chip/tiva_qencoder.h b/arch/arm/src/tiva/chip/tiva_qencoder.h new file mode 100644 index 0000000000..4352d2fa8d --- /dev/null +++ b/arch/arm/src/tiva/chip/tiva_qencoder.h @@ -0,0 +1,98 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/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_CHIP_TIVA_QENCODER_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TIVA_QENCODER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define TIVA_QEI_CTL_OFFSET (0x0) /* QEI Control */ +#define TIVA_QEI_STAT_OFFSET (0x4) /* QEI Status */ +#define TIVA_QEI_POS_OFFSET (0x8) /* QEI Position */ +#define TIVA_QEI_MAXPOS_OFFSET (0xc) /* QEI Maximum Position */ +#define TIVA_QEI_LOAD_OFFSET (0x10) /* QEI Timer Load */ +#define TIVA_QEI_TIME_OFFSET (0x14) /* QEI Timer */ +#define TIVA_QEI_COUNT_OFFSET (0x18) /* QEI Velocity Counter */ +#define TIVA_QEI_SPEED_OFFSET (0x1c) /* QEI Velocity */ +#define TIVA_QEI_INTEN_OFFSET (0x20) /* QEI Interrupt Enable */ +#define TIVA_QEI_RIS_OFFSET (0x24) /* QEI Raw Interrupt Status */ +#define TIVA_QEI_ISC_OFFSET (0x28) /* QEI Interrupt Status and Clear */ + +#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 */ +#define VELDIV_2 (0x1) /* (Value) Divided by 2 */ +#define VELDIV_4 (0x2) /* (Value) Divided by 4 */ +#define VELDIV_8 (0x3) /* (Value) Divided by 8 */ +#define VELDIV_16 (0x4) /* (Value) Divided by 16 */ +#define VELDIV_32 (0x5) /* (Value) Divided by 32 */ +#define VELDIV_64 (0x6) /* (Value) Divided by 64 */ +#define VELDIV_128 (0x7) /* (Value) Divided by 128 */ + +#define TIVA_QEI_CTL_VELEN (5) /* (Bit) Capture Velocity */ +#define VELEN_DISABLE (0) /* (value) Disable Velocity Capture */ +#define VELEN_ENABLE (1) /* (value) Enable Velocity Capture */ + +#define TIVA_QEI_CTL_RESMODE (4) /* (Bit) Reset Mode */ +#define RESMODE_BY_MAXPOS (0) /* (Value) Reset by MAXPOS */ +#define RESMODE_BY_INDEX_PULSE (1) /* (Value) Reset by Index Pulse */ + +#define TIVA_QEI_CTL_CAPMODE (3) /* (Bit) Capture Mode */ +#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_ENABLE (0) /* (Bit) Enable QEI */ +#define QEI_DISABLE (0) /* (Value) Disable QEI */ +#define QEI_ENABLE (1) /* (Value) Enable QEI */ + +#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_CHIP_TIVA_QENCODER_H */ diff --git a/arch/arm/src/tiva/chip/tm4c129_syscontrol.h b/arch/arm/src/tiva/chip/tm4c129_syscontrol.h index 9578313b86..59ab38f169 100644 --- a/arch/arm/src/tiva/chip/tm4c129_syscontrol.h +++ b/arch/arm/src/tiva/chip/tm4c129_syscontrol.h @@ -1901,7 +1901,9 @@ /* QE Interface Power Control */ -#define SYSCON_PCQEI_P0 (1 << 0) /* Bit 0: QEI Module 0 Power Control */ +#define SYSCON_PCQEI(n) (1 << (n)) /* Bit n: QEI module n Power Control */ +# define SYSCON_PCQEI_P0 (1 << 0) /* Bit 0: QEI Module 0 Power Control */ +# define SYSCON_PCQEI_P1 (1 << 1) /* Bit 1: QEI Module 1 Power Control */ /* EEPROM Power Control */ diff --git a/arch/arm/src/tiva/tiva_qencoder.c b/arch/arm/src/tiva/tiva_qencoder.c new file mode 100644 index 0000000000..eeba3628d8 --- /dev/null +++ b/arch/arm/src/tiva/tiva_qencoder.c @@ -0,0 +1,500 @@ +/************************************************************************************ + * arch/arm/src/tiva/tiva_qencoder.c + * + * Copyright (C) 2016 Young Mu. All rights reserved. + * Author: Young Mu + * + * The basic structure of this driver derives in spirit (if nothing more) + * from the NuttX STM32 QEI driver which has: + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Diego Sanchez + * + * 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 +#include +#include + +#include + +#include "up_arch.h" +#include "tiva_gpio.h" +#include "tiva_qencoder.h" +#include "tiva_enablepwr.h" +#include "tiva_enableclks.h" + +#include "chip/tiva_qencoder.h" +#include "chip/tiva_pinmap.h" +#include "chip/tm4c_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define qeierr(fmt, args...) printf("%s(%d): " fmt, __FUNCTION__, __LINE__, ##args); + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_QE +#endif + +#ifdef CONFIG_DEBUG_QEI +# define qeidbg dbg +# ifdef CONFIG_DEBUG_VERBOSE +# define qeivdbg vdbg +# else +# define qeivdbg(x...) +# endif +#else +# define qeidbg(x...) +# define qeivdbg(x...) +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +struct tiva_qe_s +{ + const struct qe_ops_s *ops; + uint8_t id; + uintptr_t base; + uint32_t idx; + uint32_t pha; + uint32_t phb; + uint32_t pulses; +}; + +/************************************************************************************ + * Private Function Prototypes + ************************************************************************************/ + +static inline void tiva_qe_putreg(struct tiva_qe_s *qe, unsigned int offset, uint32_t regval); +static inline uint32_t tiva_qe_getreg(struct tiva_qe_s *qe, unsigned int offset); + +static int tiva_qe_setup(FAR struct qe_lowerhalf_s *lower); +static int tiva_qe_shutdown(FAR struct qe_lowerhalf_s *lower); +static int tiva_qe_position(FAR struct qe_lowerhalf_s *lower, FAR int32_t *pos); +static int tiva_qe_reset(FAR struct qe_lowerhalf_s *lower); +static int tiva_qe_ioctl(FAR struct qe_lowerhalf_s *lower, int cmd, unsigned long arg); + +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); + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +static const struct qe_ops_s g_qe_ops = +{ + .setup = tiva_qe_setup, + .shutdown = tiva_qe_shutdown, + .position = tiva_qe_position, + .reset = tiva_qe_reset, + .ioctl = tiva_qe_ioctl, +}; + +#ifdef CONFIG_TIVA_QEI0 +static struct tiva_qe_s g_qe0 = +{ + .ops = &g_qe_ops, + .id = 0, + .base = TIVA_QEI0_BASE, + .idx = GPIO_QEI0_IDX, + .pha = GPIO_QEI0_PHA, + .phb = GPIO_QEI0_PHB, +# ifdef CONFIG_TIVA_QEI0_PULSES + .pulses = CONFIG_TIVA_QEI0_PULSES, +# else + .pulses = 0, +# endif +}; +#endif + +#ifdef CONFIG_TIVA_QEI1 +static struct tiva_qe_s g_qe1 = +{ + .ops = &g_qe_ops, + .id = 1, + .base = TIVA_QEI1_BASE, + .idx = GPIO_QEI1_IDX, + .pha = GPIO_QEI1_PHA, + .phb = GPIO_QEI1_PHB, +# ifdef CONFIG_TIVA_QEI1_PULSES + .pulses = CONFIG_TIVA_QEI1_PUSLSE, +# else + .pulses = 0, +# endif +}; +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: tiva_qe_getreg + * + * Description: + * Get a 32-bit register value by offset + * + ************************************************************************************/ + +static inline uint32_t tiva_qe_getreg(struct tiva_qe_s *qe, unsigned int offset) +{ + uintptr_t regaddr = qe->base + offset; + return getreg32(regaddr); +} + +/************************************************************************************ + * Name: tiva_qe_putreg + * + * Description: + * Put a 32-bit register value by offset + * + ************************************************************************************/ + +static inline void tiva_qe_putreg(struct tiva_qe_s *qe, unsigned int offset, uint32_t regval) +{ + uintptr_t regaddr = qe->base + offset; + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: qe_setup + * + * Description: + * This method is called when the driver is opened. The lower half driver + * will be configured and initialized the device so that it is ready for + * use. It will not, however, output pulses until the start method is + * called. + * + * Input parameters: + * lower - A reference to the lower half QEI driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int tiva_qe_setup(FAR struct qe_lowerhalf_s *lower) +{ + uint32_t ctlreg = 0; + FAR struct tiva_qe_s *qe = (FAR struct tiva_qe_s *)lower; + qeidbg("setup QEI %d\n", qe->id); + + /* Enable GPIO port, GPIO pin type and GPIO alternate function */ + /* (refer to TM4C1294NC 24.4.2-4) */ + int ret; + ret = tiva_configgpio(qe->idx); + if (ret < 0) + { + qeierr("tiva_configgpio failed (%x)\n", qe->idx); + return -1; + } + + ret = tiva_configgpio(qe->pha); + if (ret < 0) + { + qeierr("tiva_configgpio failed (%x)\n", qe->pha); + return -1; + } + + ret = tiva_configgpio(qe->phb); + if (ret < 0) + { + qeierr("tiva_configgpio failed (%x)\n", qe->phb); + return -1; + } + + /* Set reset mode */ + /* (refer to TM4C1294NC 24.4.5.1) */ + if (qe->pulses == 0) { + ctlreg = RESMODE_BY_INDEX_PULSE << TIVA_QEI_CTL_RESMODE; + } else { + ctlreg = RESMODE_BY_MAXPOS << TIVA_QEI_CTL_RESMODE; + } + tiva_qe_putreg(qe, TIVA_QEI_CTL_OFFSET, ctlreg); + + /* Set capture mode (PHA_AND_PHB) */ + /* (refer to TM4C1294NC 24.4.5.1) */ + 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); + + /* Set maxpos */ + /* (refer to TM4C1294NC 24.4.5.2) */ + tiva_qe_putreg(qe, TIVA_QEI_MAXPOS_OFFSET, qe->pulses * 4); + + /* Enable velocity capture */ + ctlreg = tiva_qe_getreg(qe, TIVA_QEI_CTL_OFFSET); + ctlreg |= VELEN_ENABLE << TIVA_QEI_CTL_VELEN; + tiva_qe_putreg(qe, TIVA_QEI_CTL_OFFSET, ctlreg); + + /* Set prediv (1) */ + ctlreg = tiva_qe_getreg(qe, TIVA_QEI_CTL_OFFSET); + ctlreg |= VELDIV_1 << TIVA_QEI_CTL_VELDIV; + tiva_qe_putreg(qe, TIVA_QEI_CTL_OFFSET, ctlreg); + + /* Set period load (1s for TM4C1294NC) */ + tiva_qe_putreg(qe, TIVA_QEI_LOAD_OFFSET, 120000000); + + /* Enable the QEI */ + /* (refer to TM4C1294NC 24.4.6) */ + 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: qe_shutdown + * + * Description: + * This method is called when the driver is closed. The lower half driver + * stop data collection, free any resources, disable the timer hardware, and + * put the system into the lowest possible power usage state + * + * Input parameters: + * lower - A reference to the lower half QEI driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int tiva_qe_shutdown(FAR struct qe_lowerhalf_s *lower) +{ + FAR struct tiva_qe_s *qe = (FAR struct tiva_qe_s *)lower; + qeidbg("shutdown QEI %d\n", qe->id); + + /* Disable the QEI */ + tiva_qe_putreg(qe, TIVA_SYSCON_SRQEI_OFFSET, SYSCON_SRQEI(qe->id)); + + return OK; +} + +/**************************************************************************** + * Name: tiva_qe_reset + * + * Description: + * Reset the position measurement to zero. + * + * Input parameters: + * lower - A reference to the lower half QEI driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int tiva_qe_reset(FAR struct qe_lowerhalf_s *lower) +{ + FAR struct tiva_qe_s *qe = (FAR struct tiva_qe_s *)lower; + qeidbg("reset QEI %d\n", qe->id); + + tiva_qe_putreg(qe, TIVA_QEI_POS_OFFSET, 0); + + return OK; +} + +/**************************************************************************** + * Name: tiva_qe_position + * + * Description: + * Return the position mesaured by QEI. + * + * Input parameters: + * lower - A reference to the lower half QEI driver state structure + * pos - pointer to the position returned + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int tiva_qe_position(FAR struct qe_lowerhalf_s *lower, FAR int32_t *pos) +{ + FAR struct tiva_qe_s *qe = (FAR struct tiva_qe_s *)lower; + qeidbg("get position of QEI %d\n", qe->id); + + /* (refer to TM4C1294NC 24.4.8) */ + *pos = (int32_t)tiva_qe_getreg(qe, TIVA_QEI_POS_OFFSET); + + return OK; +} + +/**************************************************************************** + * Name: tiva_qe_ioctl + * + * Description: + * Lower-half logic may support platform-specific ioctl commands + * + * Input parameters: + * lower - A reference to the lower half QEI driver state structure + * cmd - The ioctl command + * arg - The argument accompanying the ioctl command + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int tiva_qe_ioctl(FAR struct qe_lowerhalf_s *lower, int cmd, unsigned long arg) +{ + FAR struct tiva_qe_s *qe = (FAR struct tiva_qe_s *)lower; + qeidbg("ioctl QEI %d\n", qe->id); + + switch (cmd) + { + case QEIOC_DIRECTION: + tiva_qe_direction(qe, (unsigned long *)arg); + break; + case QEIOC_VELOCITY: + tiva_qe_velocity(qe, (unsigned long *)arg); + break; + default: + qeierr("invalid cmd %x\n", cmd); + break; + } + + return OK; +} + +/**************************************************************************** + * Name: tiva_qe_direction + * + * Description: + * Return the direction mesaured by QEI. + * + * Input parameters: + * qe - A reference to the TIVA QEI structure + * dir - pointer to the direction returned + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int tiva_qe_direction(FAR struct tiva_qe_s *qe, unsigned long *dir) +{ + qeidbg("get direction of QEI %d\n", qe->id); + + uint32_t statreg; + statreg = tiva_qe_getreg(qe, TIVA_QEI_STAT_OFFSET); + + int32_t dirbit; + dirbit = (statreg & (1 << TIVA_QEI_STAT_DIRECTION)) == DIRECTION_FORWARD ? 1 : -1; + + *dir = dirbit; + + return OK; +} + +/**************************************************************************** + * Name: tiva_qe_direction + * + * Description: + * Return the velocity mesaured by QEI. + * + * 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_velocity(FAR struct tiva_qe_s *qe, unsigned long *vel) +{ + qeidbg("get direction of QEI %d\n", qe->id); + + *vel = (int32_t)tiva_qe_getreg(qe, TIVA_QEI_SPEED_OFFSET); + + return OK; +} + +/************************************************************************************ + * Name: tiva_qei_initialize + * + * Description: + * Enable power and clock for quadrature encoder interface. This function + * must be called from board-specific logic. + * + * Input Parameters: + * id - A number identifying certain QEI. + * + * Returned Value: + * On success, a pointer to the SAMA5 lower half QEI driver is returned. + * NULL is returned on any failure. + * + ************************************************************************************/ + +FAR struct qe_lowerhalf_s *tiva_qei_initialize(int id) +{ + assert(id >= 0); + FAR struct tiva_qe_s *qe; + FAR struct qe_lowerhalf_s *lower; + + switch (id) + { +#ifdef CONFIG_TIVA_QEI0 + case 0: + qe = &g_qe0; + break; +#endif + +#ifdef CONFIG_TIVA_QEI1 + case 1: + qe = &g_qe1; + break; +#endif + + default: + qeierr("ERROR: invalid QEI %d\n", id); + return NULL; + } + + /* Enable QEI clock (refer to TM4C1294NC 24.4.1) */ + tiva_qei_enablepwr(qe->id); + tiva_qei_enableclk(qe->id); + + /* Make sure that the QEI enable bit has been cleared */ + lower = (FAR struct qe_lowerhalf_s *)qe; + tiva_qe_shutdown(lower); + + return lower; +} diff --git a/arch/arm/src/tiva/tiva_qencoder.h b/arch/arm/src/tiva/tiva_qencoder.h new file mode 100644 index 0000000000..b99e945bd8 --- /dev/null +++ b/arch/arm/src/tiva/tiva_qencoder.h @@ -0,0 +1,58 @@ +/************************************************************************************ +* 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 +************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define QEIOC_DIRECTION _QEIOC(QEIOC_USER) +#define QEIOC_VELOCITY _QEIOC(QEIOC_USER+1) + +/**************************************************************************** +* Public Function Prototypes +****************************************************************************/ + +FAR struct qe_lowerhalf_s *tiva_qei_initialize(int id); + +#endif /* __ARCH_ARM_SRC_TIVA_TIVA_QENCODER_H */ diff --git a/configs/tm4c1294-launchpad/src/tm4c_bringup.c b/configs/tm4c1294-launchpad/src/tm4c_bringup.c index 8031a8687d..b0b5eef54a 100644 --- a/configs/tm4c1294-launchpad/src/tm4c_bringup.c +++ b/configs/tm4c1294-launchpad/src/tm4c_bringup.c @@ -50,6 +50,7 @@ #include "tiva_i2c.h" #include "tiva_pwm.h" +#include "tiva_qencoder.h" #include "tm4c1294-launchpad.h" /**************************************************************************** @@ -64,9 +65,16 @@ # define HAVE_PWM #endif +#ifdef CONFIG_TM4C1294_LAUNCHPAD_QEI +# define HAVE_QEI +#endif + #define PWM_PATH_FMT "/dev/pwm%d" #define PWM_PATH_FMTLEN (10) +#define QEI_PATH_FMT "/dev/qei%d" +#define QEI_PATH_FMTLEN (10) + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -172,7 +180,7 @@ void tm4c_pwm_register(int channel) dev = tiva_pwm_initialize(channel); if (dev == NULL) { - pwmerr("ERROR: Failed to get PWM%d interface\n", channel); + _err("ERROR: Failed to get PWM%d interface\n", channel); } else { @@ -180,7 +188,7 @@ void tm4c_pwm_register(int channel) ret = pwm_register(pwm_path, dev); if (ret < 0) { - pwmerr("ERROR: Failed to register PWM%d driver: %d\n", + _err("ERROR: Failed to register PWM%d driver: %d\n", channel, ret); } } @@ -225,6 +233,62 @@ static void tm4c_pwm(void) } #endif +/**************************************************************************** + * Name: tm4c_qei_register + * + * Description: + * Register a QEI dev file with the upper_level QEI driver. + * + * Input Parameters: + * id - A number identifying the QEI. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void tm4c_qei_register(int id) +{ + FAR struct qe_lowerhalf_s *dev; + int ret; + char qe_path[QEI_PATH_FMTLEN]; + + dev = tiva_qei_initialize(id); + if (dev == NULL) + { + _err("ERROR: Failed to get QEI %d\n", id); + } + else + { + snprintf(qe_path, QEI_PATH_FMTLEN, QEI_PATH_FMT, id); + ret = qe_register(qe_path, dev); + if (ret < 0) + { + _err("ERROR: Failed to register QEI %d driver: %d\n", id, ret); + } + } +} + +/**************************************************************************** + * Name: tm4c_qei + * + * Description: + * Register QEI drivers for the QEI tool. + * + ****************************************************************************/ + +#ifdef HAVE_QEI +static void tm4c_qei(void) +{ +#ifdef CONFIG_TIVA_QEI0 + tm4c_qei_register(0); +#endif +#ifdef CONFIG_TIVA_QEI1 + tm4c_qei_register(1); +#endif +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -253,6 +317,12 @@ int tm4c_bringup(void) tm4c_pwm(); #endif +#ifdef HAVE_QEI + /* Register QEI drivers */ + + tm4c_qei(); +#endif + #ifdef HAVE_TIMER /* Initialize the timer driver */