TMS570: Add GIO drivrs and GIO interrupt support

This commit is contained in:
Gregory Nutt 2015-12-25 13:44:49 -06:00
parent ccc6913383
commit c58393cb4d
8 changed files with 702 additions and 58 deletions

View File

@ -58,14 +58,14 @@
/* Default request to channel assignments. Undefined requests are reserved */
#define TMS570_REQ_ESMHIGH 0 /* ESM High level interrupt (NMI) */
#define TMS570_REQ_RTICMP0 2 /* RTI compare interrupt 0 */
#define TMS570_REQ_RTICMP1 3 /* RTI compare interrupt 1 */
#define TMS570_REQ_RTICMP2 4 /* RTI compare interrupt 2 */
#define TMS570_REQ_RTICMP3 5 /* RTI compare interrupt 3 */
#define TMS570_REQ_RTIOVF0 6 /* RTI overflow interrupt 0 */
#define TMS570_REQ_RTIOVF1 7 /* RTI overflow interrupt 1 */
#define TMS570_REQ_GIOA 9 /* GIO interrupt A */
#define TMS570_REQ_ESMHIGH 0 /* ESM High level interrupt (NMI) */
#define TMS570_REQ_RTICMP0 2 /* RTI compare interrupt 0 */
#define TMS570_REQ_RTICMP1 3 /* RTI compare interrupt 1 */
#define TMS570_REQ_RTICMP2 4 /* RTI compare interrupt 2 */
#define TMS570_REQ_RTICMP3 5 /* RTI compare interrupt 3 */
#define TMS570_REQ_RTIOVF0 6 /* RTI overflow interrupt 0 */
#define TMS570_REQ_RTIOVF1 7 /* RTI overflow interrupt 1 */
#define TMS570_REQ_GIO_0 9 /* GIO level 0 interrupt */
#define TMS570_REQ_N2HET_0 10 /* N2HET level 0 interrupt */
#define TMS570_REQ_HTU_0 11 /* HTU level 0 interrupt */
#define TMS570_REQ_MIBSPI1_0 12 /* MIBSPI1 level 0 interrupt */
@ -77,7 +77,7 @@
#define TMS570_REQ_ESMLO 20 /* ESM Low level interrupt */
#define TMS570_REQ_SYSTEM 21 /* Software interrupt (SSI) */
#define TMS570_REQ_CPU 22 /* PMU interrupt */
#define TMS570_REQ_GIOB 23 /* GIO interrupt B */
#define TMS570_REQ_GIO_1 23 /* GIO level 1 interrupt */
#define TMS570_REQ_N2HET_1 24 /* N2HET level 1 interrupt */
#define TMS570_REQ_HTU_1 25 /* HTU level 1 interrupt */
#define TMS570_REQ_MIBSPI1_1 26 /* MIBSPI1 level 1 interrupt */

View File

@ -104,7 +104,7 @@ CHIP_ASRCS =
# SAMA5-specific C source files
CHIP_CSRCS = tms570_boot.c tms570_clockconfig.c tms570_irq.c
CHIP_CSRCS = tms570_boot.c tms570_clockconfig.c tms570_gio.c tms570_irq.c
CHIP_CSRCS += tms570_lowputc.c tms570_serial.c
# Configuration dependent C and assembly language files
@ -113,6 +113,10 @@ ifneq ($(CONFIG_SCHED_TICKLESS),y)
CHIP_CSRCS += tms570_timerisr.c
endif
ifneq ($(CONFIG_TMS570_SELFTEST),y)
ifeq ($(CONFIG_TMS570_SELFTEST),y)
CHIP_CSRCS += tms570_selftest.c
endif
ifeq ($(CONFIG_TMS570_GIO_IRQ),y)
CHIP_CSRCS += tms570_gioirq.c
endif

View File

@ -62,6 +62,9 @@
#define TMS570_GIOG 6
#define TMS570_GIOH 7
#define TMS570_NPORTS 8
#define TMS570_NIRQPORTS 4
/* Register Offsets *********************************************************************************/
#define TMS570_GIO_GCR0_OFFSET 0x0000 /* GIO Global Control Register */
@ -264,6 +267,10 @@
/* GIO Interrupt Detect Register */
#define GIO_INTDET_PORT_SHIFT(p) ((p) << 3)
#define GIO_INTDET_PORT_MASK(p) (0xff << GIO_INTDET_PORT_SHIFT(p))
# define GIO_INTDET_PORT_PIN(p,n) (1 << (GIO_INTDET_PORT_SHIFT(p) + (n)))
#define GIO_INTDET_GIOA_SHIFT (0) /* Bits 0-7: Interrupt detection select for pins GIOA[7:0] */
#define GIO_INTDET_GIOA_MASK (0xff << GIO_INTDET_GIOA_SHIFT)
# define GIO_INTDET_GIOA_PIN(n) (1 << (GIO_INTDET_GIOA_SHIFT + (n)))
@ -279,6 +286,10 @@
/* GIO Interrupt Polarity Register */
#define GIO_POL_PORT_SHIFT(p) ((p) << 3)
#define GIO_POL_PORT_MASK(p) (0xff << GIO_POL_PORT_SHIFT(p))
# define GIO_POL_PORT_PIN(p,n) (1 << (GIO_POL_PORT_SHIFT(p) + (n)))
#define GIO_POL_GIOA_SHIFT (0) /* Bits 0-7: Interrupt polarity select for pins GIOA[7:0] */
#define GIO_POL_GIOA_MASK (0xff << GIO_POL_GIOA_SHIFT)
# define GIO_POL_GIOA_PIN(n) (1 << (GIO_POL_GIOA_SHIFT + (n)))
@ -294,6 +305,10 @@
/* GIO Interrupt Enable Set Register */
#define GIO_ENASET_PORT_SHIFT(p) ((p) << 3)
#define GIO_ENASET_PORT_MASK(p) (0xff << GIO_ENASET_PORT_SHIFT(p))
# define GIO_ENASET_PORT_PIN(p,n) (1 << (GIO_ENASET_PORT_SHIFT(p) + (n)))
#define GIO_ENASET_GIOA_SHIFT (0) /* Bits 0-7: Interrupt enable for pins GIOA[7:0] */
#define GIO_ENASET_GIOA_MASK (0xff << GIO_ENASET_GIOA_SHIFT)
# define GIO_ENASET_GIOA_PIN(n) (1 << (GIO_ENASET_GIOA_SHIFT + (n)))
@ -309,6 +324,10 @@
/* GIO Interrupt Enable Clear Register */
#define GIO_ENACLR_PORT_SHIFT(p) ((p) << 3)
#define GIO_ENACLR_PORT_MASK(p) (0xff << GIO_ENACLR_PORT_SHIFT(p))
# define GIO_ENACLR_PORT_PIN(p,n) (1 << (GIO_ENACLR_PORT_SHIFT(p) + (n)))
#define GIO_ENACLR_GIOA_SHIFT (0) /* Bits 0-7: Interrupt disable for pins GIOA[7:0] */
#define GIO_ENACLR_GIOA_MASK (0xff << GIO_ENACLR_GIOA_SHIFT)
# define GIO_ENACLR_GIOA_PIN(n) (1 << (GIO_ENACLR_GIOA_SHIFT + (n)))
@ -324,6 +343,10 @@
/* GIO Interrupt Priority Set Register */
#define GIO_LVLSET_PORT_SHIFT(p) ((p) << 3)
#define GIO_LVLSET_PORT_MASK(p) (0xff << GIO_LVLSET_PORT_SHIFT(p))
# define GIO_LVLSET_PORT_PIN(p,n) (1 << (GIO_LVLSET_PORT_SHIFT(p) + (n)))
#define GIO_LVLSET_GIOA_SHIFT (0) /* Bits 0-7: Interrupt high level select for pins GIOA[7:0] */
#define GIO_LVLSET_GIOA_MASK (0xff << GIO_LVLSET_GIOA_SHIFT)
# define GIO_LVLSET_GIOA_PIN(n) (1 << (GIO_LVLSET_GIOA_SHIFT + (n)))
@ -339,6 +362,10 @@
/* GIO Interrupt Priority Clear Register */
#define GIO_LVLCLR_PORT_SHIFT(p) ((p) << 3)
#define GIO_LVLCLR_PORT_MASK(p) (0xff << GIO_LVLCLR_PORT_SHIFT(p))
# define GIO_LVLCLR_PORT_PIN(p,n) (1 << (GIO_LVLCLR_PORT_SHIFT(p) + (n)))
#define GIO_LVLCLR_GIOA_SHIFT (0) /* Bits 0-7: Interrupt low level select for pins GIOA[7:0] */
#define GIO_LVLCLR_GIOA_MASK (0xff << GIO_LVLCLR_GIOA_SHIFT)
# define GIO_LVLCLR_GIOA_PIN(n) (1 << (GIO_LVLCLR_GIOA_SHIFT + (n)))
@ -354,6 +381,10 @@
/* GIO Interrupt Flag Register */
#define GIO_FLG_PORT_SHIFT(p) ((p) << 3)
#define GIO_FLG_PORT_MASK(p) (0xff << GIO_FLG_PORT_SHIFT(p))
# define GIO_FLG_PORT_PIN(p,n) (1 << (GIO_FLG_PORT_SHIFT(p) + (n)))
#define GIO_FLG_GIOA_SHIFT (0) /* Bits 0-7: Interrupt flag for pins GIOA[7:0] */
#define GIO_FLG_GIOA_MASK (0xff << GIO_FLG_GIOA_SHIFT)
# define GIO_FLG_GIOA_PIN(n) (1 << (GIO_FLG_GIOA_SHIFT + (n)))
@ -369,46 +400,46 @@
/* GIO Offset 1/2 Register and GIO Emulation 1/2 Register */
#define GIO_OFF_MASK (0x3f) /* Bits 0-5: GIO offset */
# define GIO_OFF_NONE (0x00) /* No interrupt pending */
# define GIO_OFF_GIOA0 (0x01) /* GIOA0 interrupt pending */
# define GIO_OFF_GIOA1 (0x02) /* GIOA1 interrupt pending */
# define GIO_OFF_GIOA2 (0x03) /* GIOA2 interrupt pending */
# define GIO_OFF_GIOA3 (0x04) /* GIOA3 interrupt pending */
# define GIO_OFF_GIOA4 (0x05) /* GIOA4 interrupt pending */
# define GIO_OFF_GIOA5 (0x06) /* GIOA5 interrupt pending */
# define GIO_OFF_GIOA6 (0x07) /* GIOA6 interrupt pending */
# define GIO_OFF_GIOA7 (0x08) /* GIOA7 interrupt pending */
# define GIO_OFF_GIOB0 (0x09) /* GIOB0 interrupt pending */
# define GIO_OFF_GIOB1 (0x0a) /* GIOB1 interrupt pending */
# define GIO_OFF_GIOB2 (0x0b) /* GIOB2 interrupt pending */
# define GIO_OFF_GIOB3 (0x0c) /* GIOB3 interrupt pending */
# define GIO_OFF_GIOB4 (0x0d) /* GIOB4 interrupt pending */
# define GIO_OFF_GIOB5 (0x0e) /* GIOB5 interrupt pending */
# define GIO_OFF_GIOB6 (0x0f) /* GIOB6 interrupt pending */
# define GIO_OFF_GIOB7 (0x10) /* GIOB7 interrupt pending */
# define GIO_OFF_GIOC0 (0x11) /* GIOC0 interrupt pending */
# define GIO_OFF_GIOC1 (0x12) /* GIOC1 interrupt pending */
# define GIO_OFF_GIOC2 (0x13) /* GIOC2 interrupt pending */
# define GIO_OFF_GIOC3 (0x14) /* GIOC3 interrupt pending */
# define GIO_OFF_GIOC4 (0x15) /* GIOC4 interrupt pending */
# define GIO_OFF_GIOC5 (0x16) /* GIOC5 interrupt pending */
# define GIO_OFF_GIOC6 (0x17) /* GIOC6 interrupt pending */
# define GIO_OFF_GIOC7 (0x18) /* GIOC7 interrupt pending */
# define GIO_OFF_GIOD0 (0x19) /* GIOD0 interrupt pending */
# define GIO_OFF_GIOD1 (0x1a) /* GIOD1 interrupt pending */
# define GIO_OFF_GIOD2 (0x1b) /* GIOD2 interrupt pending */
# define GIO_OFF_GIOD3 (0x1c) /* GIOD3 interrupt pending */
# define GIO_OFF_GIOD4 (0x1d) /* GIOD4 interrupt pending */
# define GIO_OFF_GIOD5 (0x1e) /* GIOD5 interrupt pending */
# define GIO_OFF_GIOD6 (0x1f) /* GIOD6 interrupt pending */
# define GIO_OFF_GIOD7 (0x20) /* GIOD7 interrupt pending */
#define GIO_OFF_MASK (0x3f) /* Bits 0-5: GIO offset */
# define GIO_OFF_NONE (0x00) /* No interrupt pending */
# define GIO_OFF_GIOA0 (0x01) /* GIOA0 interrupt pending */
# define GIO_OFF_GIOA1 (0x02) /* GIOA1 interrupt pending */
# define GIO_OFF_GIOA2 (0x03) /* GIOA2 interrupt pending */
# define GIO_OFF_GIOA3 (0x04) /* GIOA3 interrupt pending */
# define GIO_OFF_GIOA4 (0x05) /* GIOA4 interrupt pending */
# define GIO_OFF_GIOA5 (0x06) /* GIOA5 interrupt pending */
# define GIO_OFF_GIOA6 (0x07) /* GIOA6 interrupt pending */
# define GIO_OFF_GIOA7 (0x08) /* GIOA7 interrupt pending */
# define GIO_OFF_GIOB0 (0x09) /* GIOB0 interrupt pending */
# define GIO_OFF_GIOB1 (0x0a) /* GIOB1 interrupt pending */
# define GIO_OFF_GIOB2 (0x0b) /* GIOB2 interrupt pending */
# define GIO_OFF_GIOB3 (0x0c) /* GIOB3 interrupt pending */
# define GIO_OFF_GIOB4 (0x0d) /* GIOB4 interrupt pending */
# define GIO_OFF_GIOB5 (0x0e) /* GIOB5 interrupt pending */
# define GIO_OFF_GIOB6 (0x0f) /* GIOB6 interrupt pending */
# define GIO_OFF_GIOB7 (0x10) /* GIOB7 interrupt pending */
# define GIO_OFF_GIOC0 (0x11) /* GIOC0 interrupt pending */
# define GIO_OFF_GIOC1 (0x12) /* GIOC1 interrupt pending */
# define GIO_OFF_GIOC2 (0x13) /* GIOC2 interrupt pending */
# define GIO_OFF_GIOC3 (0x14) /* GIOC3 interrupt pending */
# define GIO_OFF_GIOC4 (0x15) /* GIOC4 interrupt pending */
# define GIO_OFF_GIOC5 (0x16) /* GIOC5 interrupt pending */
# define GIO_OFF_GIOC6 (0x17) /* GIOC6 interrupt pending */
# define GIO_OFF_GIOC7 (0x18) /* GIOC7 interrupt pending */
# define GIO_OFF_GIOD0 (0x19) /* GIOD0 interrupt pending */
# define GIO_OFF_GIOD1 (0x1a) /* GIOD1 interrupt pending */
# define GIO_OFF_GIOD2 (0x1b) /* GIOD2 interrupt pending */
# define GIO_OFF_GIOD3 (0x1c) /* GIOD3 interrupt pending */
# define GIO_OFF_GIOD4 (0x1d) /* GIOD4 interrupt pending */
# define GIO_OFF_GIOD5 (0x1e) /* GIOD5 interrupt pending */
# define GIO_OFF_GIOD6 (0x1f) /* GIOD6 interrupt pending */
# define GIO_OFF_GIOD7 (0x20) /* GIOD7 interrupt pending */
/* GIO Data Direction Register, GIO Data Input Register, GIO Data Output Register,
* GIO Data Set Register, GIO Data Clear Register, GIO Open Drain Register,
* GIO Pull Disable Register, and GIO Pull Select Register
*/
#define GIO_PIN(n) (1 << (n)) /* Bit n: Corresponds to pin n */
#define GIO_PIN(n) (1 << (n)) /* Bit n: Corresponds to pin n */
#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_GIO_H */

View File

@ -63,6 +63,7 @@
#include "chip/tms570_sys.h"
#include "chip/tms570_esm.h"
#include "tms570_clockconfig.h"
#include "tms570_gio.h"
#include "tms570_boot.h"
/****************************************************************************
@ -316,6 +317,10 @@ void arm_boot(void)
arm_data_initialize();
#endif
/* Initialize GIO for use by board initialization logic */
tms570_gio_initialize();
/* Perform board-specific initialization, This must include:
*
* - Initialization of board-specific memory resources (e.g., SDRAM)

View File

@ -0,0 +1,330 @@
/****************************************************************************
* arch/arm/src/tms570/tms570_gio.c
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <stdint.h>
#include <time.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <arch/board/board.h>
#include "up_internal.h"
#include "up_arch.h"
#include "chip/tms570_gio.h"
#include "tms570_gio.h"
/****************************************************************************
* Private Data
****************************************************************************/
#ifdef CONFIG_DEBUG_GPIO
static const char g_portchar[TMS570_NPORTS] =
{
'A'
#if TMS570_NPORTS > 1
, 'B'
#endif
#if TMS570_NPORTS > 2
, 'C'
#endif
#if TMS570_NPORTS > 3
, 'D'
#endif
#if TMS570_NPORTS > 4
, 'E'
#endif
#if TMS570_NPORTS > 5
, 'F'
#endif
#if TMS570_NPORTS > 6
, 'G'
#endif
#if TMS570_NPORTS > 7
, 'H'
#endif
};
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: tms570_gio_initialize
*
* Description:
* Take the GIO block out of reset and assure that it is ready for use.
*
****************************************************************************/
int tms570_gio_initialize(void)
{
/* Take the GIO block out of reset */
putreg32(GIO_GCR0_RESET, TMS570_GIO_GCR0);
/* Disable all pin interrupts on the pin. Make sure they are all level 0. */
putreg32(0xffffffff, TMS570_GIO_ENACLR);
putreg32(0xffffffff, TMS570_GIO_LVLCLR);
return OK;
}
/****************************************************************************
* Name: tms570_configgio
*
* Description:
* Configure a GIO pin based on bit-encoded description of the pin.
*
****************************************************************************/
int tms570_configgio(gio_pinset_t cfgset)
{
uint32_t port = tms570_gio_port(cfgset);
uintptr_t base = tms570_gio_base(cfgset);
uint32_t pin = tms570_gio_pin(cfgset);
uint32_t pinmask = tms570_gio_pinmask(cfgset);
uint32_t regval;
irqstate_t flags;
/* Disable interrupts to prohibit re-entrance. */
flags = irqsave();
/* Force the pin to be an input for now */
regval = getreg32(base + TMS570_GIO_DIR_OFFSET);
regval &= ~pinmask;
putreg32(regval, base + TMS570_GIO_DIR_OFFSET);
/* Disable interrupts on the pin. Make sure this is a level 0 pin. */
putreg32(GIO_ENACLR_PORT_PIN(port, pin), TMS570_GIO_ENACLR);
putreg32(GIO_LVLCLR_PORT_PIN(port, pin), TMS570_GIO_LVLCLR);
/* Setup settings common to both input and output pins */
/* Enable/disable the pull-up/down as requested */
switch (cfgset & GIO_CFG_MASK)
{
case GIO_CFG_DEFAULT: /* Default, no attribute */
default:
{
/* Disable pull functionality */
regval = getreg32(base + TMS570_GIO_PULDIS_OFFSET);
regval &= ~pinmask;
putreg32(regval, base + TMS570_GIO_PULDIS_OFFSET);
}
break;
case GIO_CFG_PULLUP: /* Internal pull-up */
{
/* Select pull-up */
regval = getreg32(base + TMS570_GIO_PSL_OFFSET);
regval |= pinmask;
putreg32(regval, base + TMS570_GIO_PSL_OFFSET);
/* Enable pull functionality */
regval = getreg32(base + TMS570_GIO_PULDIS_OFFSET);
regval |= pinmask;
putreg32(regval, base + TMS570_GIO_PULDIS_OFFSET);
}
break;
case GIO_CFG_PULLDOWN: /* Internal pull-down */
{
/* Select pull-down */
regval = getreg32(base + TMS570_GIO_PSL_OFFSET);
regval |= pinmask;
putreg32(regval, base + TMS570_GIO_PSL_OFFSET);
/* Enable pull functionality */
regval = getreg32(base + TMS570_GIO_DIR_OFFSET);
regval |= pinmask;
putreg32(regval, base + TMS570_GIO_DIR_OFFSET);
}
break;
}
/* Then do unique operations for an output pin */
if ((cfgset & GIO_MODE_MASK) == GIO_OUTPUT)
{
/* Enable the open drain driver if requested */
regval = getreg32(base + TMS570_GIO_PDR_OFFSET);
if ((cfgset & GIO_OPENDRAIN) != 0)
{
regval |= pinmask;
}
else
{
regval &= ~pinmask;
}
putreg32(regval, base + TMS570_GIO_PDR_OFFSET);
/* Set default output value */
if ((cfgset & GIO_OUTPUT_SET) != 0)
{
putreg32(pinmask, base + TMS570_GIO_DSET_OFFSET);
}
else
{
putreg32(pinmask, base + TMS570_GIO_DCLR_OFFSET);
}
/* Finally, configure the pin as an output */
regval = getreg32(base + TMS570_GIO_DIR_OFFSET);
regval |= pinmask;
putreg32(regval, base + TMS570_GIO_DIR_OFFSET);
}
irqrestore(flags);
return OK;
}
/****************************************************************************
* Name: tms570_giowrite
*
* Description:
* Write one or zero to the selected GIO pin
*
****************************************************************************/
void tms570_giowrite(gio_pinset_t pinset, bool value)
{
uintptr_t base = tms570_gio_base(pinset);
uint32_t pinmask = tms570_gio_pinmask(pinset);
if (value)
{
putreg32(pinmask, base + TMS570_GIO_DSET_OFFSET);
}
else
{
putreg32(pinmask, base + TMS570_GIO_DCLR_OFFSET);
}
}
/****************************************************************************
* Name: tms570_gioread
*
* Description:
* Read one or zero from the selected GIO pin
*
****************************************************************************/
bool tms570_gioread(gio_pinset_t pinset)
{
uintptr_t base = tms570_gio_base(pinset);
uint32_t pinmask = tms570_gio_pinmask(pinset);
uint32_t regval;
if ((pinset & GIO_MODE_MASK) == GIO_OUTPUT)
{
regval = getreg32(base + TMS570_GIO_DOUT_OFFSET);
}
else
{
regval = getreg32(base + TMS570_GIO_DIN_OFFSET);
}
return (regval & pinmask) != 0;
}
/************************************************************************************
* Function: tms570_dumpgio
*
* Description:
* Dump all GIO registers associated with the base address of the provided pinset.
*
************************************************************************************/
#ifdef CONFIG_DEBUG_GPIO
int tms570_dumpgio(uint32_t pinset, const char *msg)
{
irqstate_t flags;
uintptr_t base;
unsigned int port;
lldbg("GIO%c pinset: %08x base: %08x -- %s\n",
g_portchar[port], pinset, base, msg);
/* Get the base address associated with the GIO port */
port = (pinset & GIO_PORT_MASK) >> GIO_PORT_SHIFT;
base = TMS570_GIO_PORTBASE(port);
/* The following requires exclusive access to the GIO registers */
flags = irqsave();
/* Show global GIO registers */
lldbg(" GCR0: %08x INTDET: %08x POL: %08x ENA: %08x\n",
getreg32(TMS570_GIO_GCR0), getreg32(TMS570_GIO_INTDET),
getreg32(TMS570_GIO_POL), getreg32(TMS570_GIO_ENASET));
lldbg(" LVL: %08x FLG: %08x EMU1: %08x EMU2: %08x\n",
getreg32(TMS570_GIO_LVLSET), getreg32(TMS570_GIO_FLG),
getreg32(TMS570_GIO_EMU1), getreg32(TMS570_GIO_EMU2));
/* Port specific registers */
lldbg(" DIR: %08x DIN: %08x DOUT: %08x PDR: %08x\n",
getreg32(base + TMS570_GIO_DIR_OFFSET), getreg32(base + TMS570_GIO_DIN_OFFSET),
getreg32(base + TMS570_GIO_DOUT_OFFSET), getreg32(base + TMS570_GIO_PDR_OFFSET));
lldbg(" PULDIS: %08x PSL: %08x\n",
getreg32(base + TMS570_GIO_PULDIS_OFFSET), getreg32(base + TMS570_GIO_PSL_OFFSET));
irqrestore(flags);
return OK;
}
#endif

View File

@ -46,6 +46,8 @@
#include <stdbool.h>
#include <assert.h>
#include "chip/tms570_gio.h"
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
@ -54,7 +56,7 @@
/* 32-bit Encoding:
*
* .... .... .... .... MCCC .IIV PPP. .BBB
* .... .... .... .... M.CC IIOV PPP. .BBB
*/
/* Input/Output mode:
@ -70,28 +72,34 @@
/* These bits set the configuration of the pin:
* NOTE: No definitions for parallel capture mode
*
* .... .... .... .... .CCC .... .... ....
* .... .... .... .... ..CC .... .... ....
*/
#define GIO_CFG_SHIFT (12) /* Bits 12-14: GIO configuration bits */
#define GIO_CFG_MASK (7 << GIO_CFG_SHIFT)
#define GIO_CFG_MASK (3 << GIO_CFG_SHIFT)
# define GIO_CFG_DEFAULT (0 << GIO_CFG_SHIFT) /* Default, no attribute */
# define GIO_CFG_PULLUP (1 << GIO_CFG_SHIFT) /* Bit 16: Internal pull-up */
# define GIO_CFG_PULLDOWN (2 << GIO_CFG_SHIFT) /* Bit 17: Internal pull-down */
# define GIO_CFG_OPENDRAIN (4 << GIO_CFG_SHIFT) /* Bit 19: Open drain */
/* Interrupt modes:
*
* .... .... .... .... .... .II. .... ....
* .... .... .... .... .... II.. .... ....
*/
#define GIO_INT_SHIFT (9) /* Bits 9-10: GIO interrupt bits */
#define GIO_INT_SHIFT (10) /* Bits 10-11: GIO interrupt bits */
#define GIO_INT_MASK (3 << GIO_INT_SHIFT)
# define GIO_INT_NONE (0 << GIO_INT_SHIFT)
# define GIO_INT_RISING (1 << GIO_INT_SHIFT)
# define GIO_INT_FALLING (2 << GIO_INT_SHIFT)
# define GIO_INT_BOTHEDGES (3 << GIO_INT_SHIFT)
/* If the pin is an GIO output, then this selects the open drain output
*
* .... .... .... .... .... ..O. .... ....
*/
#define GIO_OPENDRAIN (1 << 9) /* Bit 9: Open drain mode */
/* If the pin is an GIO output, then this identifies the initial output value:
*
* .... .... .... .... .... ...V .... ....
@ -170,7 +178,7 @@ extern "C"
static inline uintptr_t tms570_gio_base(gio_pinset_t cfgset)
{
int port = (cfgset & GIO_PORT_MASK) >> GIO_PORT_SHIFT;
return TMS570_GIO_PORTBASE(n);
return TMS570_GIO_PORTBASE(port);
}
/****************************************************************************
@ -216,8 +224,18 @@ static inline int tms570_gio_pinmask(gio_pinset_t cfgset)
* Public Function Prototypes
************************************************************************************/
/****************************************************************************
* Name: tms570_gio_initialize
*
* Description:
* Take the GIO block out of reset and assure that it is ready for use.
*
****************************************************************************/
int tms570_gio_initialize(void);
/************************************************************************************
* Name: tms570_gioirqinitialize
* Name: tms570_gioirq_initialize
*
* Description:
* Initialize logic to support a second level of interrupt decoding for GIO pins.
@ -225,9 +243,9 @@ static inline int tms570_gio_pinmask(gio_pinset_t cfgset)
************************************************************************************/
#ifdef CONFIG_TMS570_GIO_IRQ
void tms570_gioirqinitialize(void);
void tms570_gioirq_initialize(void);
#else
# define tms570_gioirqinitialize()
# define tms570_gioirq_initialize()
#endif
/************************************************************************************
@ -310,7 +328,7 @@ void tms570_gioirqdisable(int irq);
*
************************************************************************************/
#ifdef CONFIG_DEBUG_GIO
#ifdef CONFIG_DEBUG_GPIO
int tms570_dumpgio(uint32_t pinset, const char *msg);
#else
# define tms570_dumpgio(p,m)

View File

@ -0,0 +1,256 @@
/****************************************************************************
* arch/arm/src/tms570/tms570_gioirq.c
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <stdint.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/init.h>
#include <nuttx/arch.h>
#include <arch/irq.h>
#include <arch/board/board.h>
#include "up_arch.h"
#include "up_internal.h"
#include "tms570_gio.h"
#include "chip/tms570_gio.h"
#ifdef CONFIG_TMS570_GIO_IRQ
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: tms570_gio_interrupt
*
* Description:
* Receive GIO interrupts
*
****************************************************************************/
static int tms3570_gio_interrupt(int irq, void *context)
{
uint32_t off1;
int irq2;
/* Loop until all pending GIO interrupts have been processed */
while ((off1 = getreg32(TMS570_GIO_OFF1)) != GIO_OFF_NONE)
{
/* Convert the offset value to the second-level IRQ number */
irq2 = off1 + TMS570_IRQ_GIOA0 - 1;
/* And dispatch the second-level GIO IRQ */
irq_dispatch(irq2, context);
}
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: tms570_gioirqinitialize
*
* Description:
* Initialize logic to support a second level of interrupt decoding for
* GIO pins.
*
****************************************************************************/
void tms570_gioirqinitialize(void)
{
/* Disable all pin interrupts on the pin. Make sure they are all level 0. */
putreg32(0xffffffff, TMS570_GIO_ENACLR);
putreg32(0xffffffff, TMS570_GIO_LVLCLR);
/* Attach and enable the GIO level 0 interrupt */
DEBUGVERIFY(irq_attach(TMS570_REQ_GIO_0, tms3570_gio_interrupt));
up_enable_irq(TMS570_REQ_GIO_0);
}
/************************************************************************************
* Name: tms570_gioirq
*
* Description:
* Configure an interrupt for the specified GIO pin.
*
************************************************************************************/
void tms570_gioirq(gio_pinset_t pinset)
{
uint32_t port = tms570_gio_port(pinset);
uint32_t pin = tms570_gio_pin(pinset);
irqstate_t flags;
uint32_t regval;
/* Start with the pin interrupts disabled. Make sure that level 0 is selected. */
putreg32(GIO_ENACLR_PORT_PIN(port, pin), TMS570_GIO_ENACLR);
putreg32(GIO_LVLCLR_PORT_PIN(port, pin), TMS570_GIO_LVLCLR);
/* Make sure that the pin is configured as an input and that interrupts can e
* supported on this port.
*/
if ((pinset & GIO_MODE_MASK) == GIO_INPUT && port < TMS570_NIRQPORTS)
{
flags = irqsave();
switch (pinset & GIO_INT_MASK)
{
case GIO_INT_NONE:
default:
break;
case GIO_INT_RISING:
{
/* Enable rising edge detectioni */
regval = getreg32(TMS570_GIO_POL);
regval |= GIO_POL_PORT_PIN(port, pin);
putreg32(regval, TMS570_GIO_POL);
/* Disable both rising and falling edge detection */
regval = getreg32(TMS570_GIO_INTDET);
regval &= ~GIO_INTDET_PORT_PIN(port, pin);
putreg32(regval, TMS570_GIO_INTDET);
}
break;
case GIO_INT_FALLING:
{
/* Enable falling edge detectioni */
regval = getreg32(TMS570_GIO_POL);
regval &= ~GIO_POL_PORT_PIN(port, pin);
putreg32(regval, TMS570_GIO_POL);
/* Disable both rising and falling edge detection */
regval = getreg32(TMS570_GIO_INTDET);
regval &= ~GIO_INTDET_PORT_PIN(port, pin);
putreg32(regval, TMS570_GIO_INTDET);
}
break;
case GIO_INT_BOTHEDGES:
{
/* Enable both rising and falling edge detection */
regval = getreg32(TMS570_GIO_INTDET);
regval |= GIO_INTDET_PORT_PIN(port, pin);
putreg32(regval, TMS570_GIO_INTDET);
}
break;
}
irqrestore(flags);
}
}
/************************************************************************************
* Name: tms570_gioirqenable
*
* Description:
* Enable the interrupt for specified GIO IRQ
*
************************************************************************************/
void tms570_gioirqenable(int irq)
{
int offset;
int port;
int pin;
offset = irq - TMS570_IRQ_GIOA0;
if (offset < TMS570_NGIO_IRQS)
{
/* Convert the offset IRQ number to a port and pin number */
pin = offset & 7;
port = offset >> 3;
/* Enable this pin interrupt */
putreg32(GIO_ENACLR_PORT_PIN(port, pin), TMS570_GIO_ENASET);
}
}
/************************************************************************************
* Name: tms570_gioirqdisable
*
* Description:
* Disable the interrupt for specified GIO IRQ
*
************************************************************************************/
void tms570_gioirqdisable(int irq)
{
int offset;
int port;
int pin;
offset = irq - TMS570_IRQ_GIOA0;
if (offset < TMS570_NGIO_IRQS)
{
/* Convert the offset IRQ number to a port and pin number */
pin = offset & 7;
port = offset >> 3;
/* Enable this pin interrupt */
putreg32(GIO_ENACLR_PORT_PIN(port, pin), TMS570_GIO_ENACLR);
}
}
#endif /* CONFIG_TMS570_GIO_IRQ */

View File

@ -178,7 +178,7 @@ void up_irqinitialize(void)
* GIO pins.
*/
tms570_gioirqinitialize();
tms570_gioirq_initialize();
#endif
/* And finally, enable interrupts */