Merged in young-mu/nuttx (pull request #135)
Add QEI lower-half driver impl. for Tiva series chip
This commit is contained in:
commit
28b4082020
@ -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)
|
||||
|
98
arch/arm/src/tiva/chip/tiva_qencoder.h
Normal file
98
arch/arm/src/tiva/chip/tiva_qencoder.h
Normal file
@ -0,0 +1,98 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/tiva/chip/tiva_qencoder.h
|
||||
*
|
||||
* Copyright (C) 2016 Young Mu. All rights reserved.
|
||||
* Author: Young Mu <young.mu@aliyun.com>
|
||||
*
|
||||
* 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 */
|
@ -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 */
|
||||
|
||||
|
500
arch/arm/src/tiva/tiva_qencoder.c
Normal file
500
arch/arm/src/tiva/tiva_qencoder.c
Normal file
@ -0,0 +1,500 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/tiva/tiva_qencoder.c
|
||||
*
|
||||
* Copyright (C) 2016 Young Mu. All rights reserved.
|
||||
* Author: Young Mu <young.mu@aliyun.com>
|
||||
*
|
||||
* 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 <gnutt@nuttx.org>
|
||||
* Diego Sanchez <dsanchez@nx-engineering.com>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/sensors/qencoder.h>
|
||||
|
||||
#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;
|
||||
}
|
58
arch/arm/src/tiva/tiva_qencoder.h
Normal file
58
arch/arm/src/tiva/tiva_qencoder.h
Normal file
@ -0,0 +1,58 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/tiva/tiva_qencoder.h
|
||||
*
|
||||
* Copyright (C) 2016 Young Mu. All rights reserved.
|
||||
* Author: Young Mu <young.mu@aliyun.com>
|
||||
*
|
||||
* 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 <nuttx/sensors/qencoder.h>
|
||||
|
||||
/************************************************************************************
|
||||
* 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 */
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user