summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-01-10 10:07:56 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-01-10 10:07:56 -0600
commitcac39a0e7995a1eb23ba2b5e0109ea85110bf55c (patch)
treeb62cb39c3d4f288fedfdb10af8cb27e03f850116
parent505e80785192ef62ea1cf0ac6c09bce40994b073 (diff)
downloadnuttx-cac39a0e7995a1eb23ba2b5e0109ea85110bf55c.tar.gz
nuttx-cac39a0e7995a1eb23ba2b5e0109ea85110bf55c.tar.bz2
nuttx-cac39a0e7995a1eb23ba2b5e0109ea85110bf55c.zip
Tive Timer: Add support for ADC trigger generation from one-shot and periodic timers for timeout and match evetns
-rw-r--r--nuttx/arch/arm/src/tiva/tiva_timer.c92
-rw-r--r--nuttx/arch/arm/src/tiva/tiva_timer.h18
2 files changed, 100 insertions, 10 deletions
diff --git a/nuttx/arch/arm/src/tiva/tiva_timer.c b/nuttx/arch/arm/src/tiva/tiva_timer.c
index 32845a296..1a375f89a 100644
--- a/nuttx/arch/arm/src/tiva/tiva_timer.c
+++ b/nuttx/arch/arm/src/tiva/tiva_timer.c
@@ -839,15 +839,38 @@ static int tiva_oneshot_periodic_mode32(struct tiva_gptmstate_s *priv,
regval &= ~TIMER_TnMR_TnCINTD;
}
+
/* Enable count down? */
- if (timer->countup)
+ if (TIMER_ISCOUNTUP(timer))
{
regval |= TIMER_TnMR_TnCDIR_UP;
}
tiva_putreg(priv, TIVA_TIMER_TAMR_OFFSET, regval);
+ /* Enable and configure ADC trigger outputs */
+
+ if (TIMER_ISADCTIMEOUT(timer) || TIMER_ISADCMATCH(timer))
+ {
+ /* Enable ADC trigger outputs by setting the TAOTE bit in the
+ * control register.
+ */
+
+ regval = tiva_getreg(priv, TIVA_TIMER_CTL_OFFSET);
+ regval |= TIMER_CTL_TAOTE;
+ tiva_putreg(priv, TIVA_TIMER_CTL_OFFSET, regval);
+
+ /* Enable timeout triggers now (match triggers will be
+ * enabled when the first match value is set).
+ */
+
+ if (TIMER_ISADCTIMEOUT(timer))
+ {
+ tiva_putreg(priv, TIVA_TIMER_ADCEV_OFFSET, TIMER_ADCEV_TATOADCEN);
+ }
+ }
+
/* In addition, if using CCP pins, the TCACT field can be programmed to
* configure the compare action.
*/
@@ -870,7 +893,7 @@ static int tiva_oneshot_periodic_mode32(struct tiva_gptmstate_s *priv,
* next clock cycle.
*/
- if (timer->countup)
+ if (TIMER_ISCOUNTUP(timer))
{
/* Count up from zero */
@@ -1034,13 +1057,36 @@ static int tiva_oneshot_periodic_mode16(struct tiva_gptmstate_s *priv,
/* Enable count down? */
- if (timer->countup)
+ if (TIMER_ISCOUNTUP(timer))
{
regval |= TIMER_TnMR_TnCDIR_UP;
}
tiva_putreg(priv, regoffset, regval);
+ /* Enable and configure ADC trigger outputs */
+
+ if (TIMER_ISADCTIMEOUT(timer) || TIMER_ISADCMATCH(timer))
+ {
+ /* Enable ADC trigger outputs by setting the TnOTE bit in the
+ * control register.
+ */
+
+ regval = tiva_getreg(priv, TIVA_TIMER_CTL_OFFSET);
+ regval |= tmndx ? TIMER_CTL_TBOTE : TIMER_CTL_TAOTE;
+ tiva_putreg(priv, TIVA_TIMER_CTL_OFFSET, regval);
+
+ /* Enable timeout triggers now (match triggers will be
+ * enabled when the first match value is set).
+ */
+
+ if (TIMER_ISADCTIMEOUT(timer))
+ {
+ regval = tmndx ? TIMER_ADCEV_TBTOADCEN : TIMER_ADCEV_TATOADCEN;
+ tiva_putreg(priv, TIVA_TIMER_ADCEV_OFFSET, regval);
+ }
+ }
+
/* In addition, if using CCP pins, the TCACT field can be programmed to
* configure the compare action.
*/
@@ -1065,7 +1111,7 @@ static int tiva_oneshot_periodic_mode16(struct tiva_gptmstate_s *priv,
*/
regoffset = tmndx ? TIVA_TIMER_TBV_OFFSET : TIVA_TIMER_TAV_OFFSET;
- if (timer->countup)
+ if (TIMER_ISCOUNTUP(timer))
{
/* Count up from zero */
@@ -1922,6 +1968,8 @@ void tiva_timer32_relmatch(TIMER_HANDLE handle, uint32_t relmatch)
irqstate_t flags;
uint32_t counter;
uint32_t match;
+ uint32_t adcev;
+ uint32_t adcbits;
DEBUGASSERT(priv && priv->attr && priv->config &&
priv->config->mode != TIMER16_MODE);
@@ -1942,7 +1990,9 @@ void tiva_timer32_relmatch(TIMER_HANDLE handle, uint32_t relmatch)
* minimum.
*/
- base = priv->attr->base;
+ base = priv->attr->base;
+ adcbits = TIMER_ISADCMATCH(config) ? TIMER_ADCEV_CAMADCEN : 0;
+
flags = irqsave();
/* Set the match register to the current value of the timer counter plus
@@ -1955,6 +2005,13 @@ void tiva_timer32_relmatch(TIMER_HANDLE handle, uint32_t relmatch)
match = counter + relmatch;
putreg32(match, base + TIVA_TIMER_TAMATCHR_OFFSET);
+ /* Enable ADC trigger (if selected). NOTE the TAOTE bit was already
+ * selected in the GPTMCTL register when the timer was configured.
+ */
+
+ adcev = getreg32(base + TIVA_TIMER_ADCEV_OFFSET);
+ putreg32(adcev | adcbits, base + TIVA_TIMER_ADCEV_OFFSET);
+
/* Enable interrupts as necessary */
putreg32(priv->imr, base + TIVA_TIMER_IMR_OFFSET);
@@ -1965,6 +2022,8 @@ void tiva_timer32_relmatch(TIMER_HANDLE handle, uint32_t relmatch)
lldbg("%08x->%08x\n", base + TIVA_TIMER_TAR_OFFSET, counter);
lldbg("%08x<-%08x\n", base + TIVA_TIMER_TAMATCHR_OFFSET, match);
+ lldbg("%08x->%08x\n", base + TIVA_TIMER_ADCEV_OFFSET, adcev);
+ lldbg("%08x<-%08x\n", base + TIVA_TIMER_ADCEV_OFFSET, adcev | adcbits);
lldbg("%08x<-%08x\n", base + TIVA_TIMER_IMR_OFFSET, priv->imr);
#endif
}
@@ -2020,12 +2079,15 @@ void tiva_timer16_relmatch(TIMER_HANDLE handle, uint32_t relmatch, int tmndx)
uintptr_t prescr;
uintptr_t matchr;
uintptr_t prematchr;
+ uintptr_t adcevr;
uintptr_t imr;
uint32_t timerv;
uint32_t prescv;
uint32_t matchv;
uint32_t prematchv;
+ uint32_t adcevv;
uint32_t counter;
+ uint32_t adcbits;
bool countup;
DEBUGASSERT(priv && priv->attr && priv->config &&
@@ -2055,6 +2117,10 @@ void tiva_timer16_relmatch(TIMER_HANDLE handle, uint32_t relmatch, int tmndx)
prescr = base + TIVA_TIMER_TBPR_OFFSET;
matchr = base + TIVA_TIMER_TBMATCHR_OFFSET;
prematchr = base + TIVA_TIMER_TBPMR_OFFSET;
+
+ /* Do we need to enable ADC trigger on the match? */
+
+ adcbits = TIMER_ISADCMATCH(config) ? TIMER_ADCEV_CBMADCEN : 0;
}
else
{
@@ -2074,10 +2140,15 @@ void tiva_timer16_relmatch(TIMER_HANDLE handle, uint32_t relmatch, int tmndx)
prescr = base + TIVA_TIMER_TAPR_OFFSET;
matchr = base + TIVA_TIMER_TAMATCHR_OFFSET;
prematchr = base + TIVA_TIMER_TAPMR_OFFSET;
+
+ /* Do we need to enable ADC trigger on the match? */
+
+ adcbits = TIMER_ISADCMATCH(config) ? TIMER_ADCEV_CAMADCEN : 0;
}
+ adcevr = base + TIVA_TIMER_ADCEV_OFFSET;
imr = base + TIVA_TIMER_IMR_OFFSET;
- countup = config->countup;
+ countup = TIMER_ISCOUNTUP(config);
/* This must be done without interrupt or context switches to minimize
* race conditions with the free-running timer. Note that we also
@@ -2121,6 +2192,13 @@ void tiva_timer16_relmatch(TIMER_HANDLE handle, uint32_t relmatch, int tmndx)
putreg32(matchv, matchr);
putreg32(prematchv, prematchr);
+ /* Enable ADC trigger (if selected). NOTE the TnOTE bit was already
+ * selected in the GPTMCTL register when the timer was configured.
+ */
+
+ adcevv = getreg32(adcevr);
+ putreg32(adcevv | adcbits, adcevr);
+
/* Enable interrupts as necessary */
putreg32(priv->imr, imr);
@@ -2133,6 +2211,8 @@ void tiva_timer16_relmatch(TIMER_HANDLE handle, uint32_t relmatch, int tmndx)
lldbg("%08x->%08x\n", prescr, prescv);
lldbg("%08x<-%08x\n", matchr, matchv);
lldbg("%08x<-%08x\n", prematchr, prematchv);
+ lldbg("%08x->%08x\n", adcevr, adcevv);
+ lldbg("%08x<-%08x\n", adcevr, adcevv | adcbits);
lldbg("%08x<-%08x\n", imr, priv->imr);
#endif
}
diff --git a/nuttx/arch/arm/src/tiva/tiva_timer.h b/nuttx/arch/arm/src/tiva/tiva_timer.h
index e367d542f..89e8fa740 100644
--- a/nuttx/arch/arm/src/tiva/tiva_timer.h
+++ b/nuttx/arch/arm/src/tiva/tiva_timer.h
@@ -93,6 +93,18 @@
#define TIMER16A 0
#define TIMER16B 1
+/* Flags bit definitions in configuration structures. NOTE: not all flags
+ * apply in all timer modes.
+ */
+
+#define TIMER_FLAG_COUNTUP (1 << 0) /* Bit 0: Count up */
+#define TIMER_FLAG_ADCTIMEOUT (1 << 1) /* Bit 1: Generate ADC trigger on timeout */
+#define TIMER_FLAG_ADCMATCH (1 << 2) /* Bit 2: Generate ADC trigger on match */
+
+#define TIMER_ISCOUNTUP(c) ((((c)->flags) & TIMER_FLAG_COUNTUP) != 0)
+#define TIMER_ISADCTIMEOUT(c) ((((c)->flags) & TIMER_FLAG_ADCTIMEOUT) != 0)
+#define TIMER_ISADCMATCH(c) ((((c)->flags) & TIMER_FLAG_ADCMATCH) != 0)
+
/****************************************************************************
* Public Types
****************************************************************************/
@@ -142,10 +154,9 @@ typedef void (*timer32_handler_t)(TIMER_HANDLE handle,
struct tiva_timer32config_s
{
- bool countup; /* True: Count up; False: Count down */
+ uint8_t flags; /* See TIMER_FLAG_* definitions */
timer32_handler_t handler; /* Non-NULL: Interrupts will be enabled
* and forwarded to this function */
- /* TODO: Add fields to support ADC trigger events */
/* Mode-specific parameters */
@@ -187,10 +198,9 @@ typedef void (*timer16_handler_t)(TIMER_HANDLE handle,
struct tiva_timer16config_s
{
uint8_t mode; /* See enum tiva_timermode_e */
- bool countup; /* True: Count up; False: Count down */
+ uint8_t flags; /* See TIMER_FLAG_* definitions */
timer16_handler_t handler; /* Non-NULL: Interrupts will be enabled
* and forwarded to this function */
- /* TODO: Add fields to support ADC trigger events */
/* Mode-specific parameters */