summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-01-10 12:22:37 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-01-10 12:22:37 -0600
commitfa8521ee2c6e3ade23e07308fe917c111b4c3e95 (patch)
treedd8ff895a500226c30ca80daddcbc950cd2be89c
parentcac39a0e7995a1eb23ba2b5e0109ea85110bf55c (diff)
downloadnuttx-fa8521ee2c6e3ade23e07308fe917c111b4c3e95.tar.gz
nuttx-fa8521ee2c6e3ade23e07308fe917c111b4c3e95.tar.bz2
nuttx-fa8521ee2c6e3ade23e07308fe917c111b4c3e95.zip
Tiva Timer: Add support for RTC match interrupts
-rw-r--r--nuttx/arch/arm/src/tiva/tiva_timer.c105
-rw-r--r--nuttx/arch/arm/src/tiva/tiva_timer.h73
2 files changed, 163 insertions, 15 deletions
diff --git a/nuttx/arch/arm/src/tiva/tiva_timer.c b/nuttx/arch/arm/src/tiva/tiva_timer.c
index 1a375f89a..cee1d5564 100644
--- a/nuttx/arch/arm/src/tiva/tiva_timer.c
+++ b/nuttx/arch/arm/src/tiva/tiva_timer.c
@@ -457,13 +457,13 @@ static int tiva_timer32_interrupt(struct tiva_gptmstate_s *priv)
{
tiva_putreg(priv, TIVA_TIMER_ICR_OFFSET, status);
- /* If this was a match interrupt, then disable further match
- * interrupts.
+ /* If this was a match (or RTC match) interrupt, then disable further
+ * match interrupts.
*/
- if ((status & TIMER_INT_TAM) != 0)
+ if ((status & (TIMER_INT_TAM | TIMER_INT_RTC)) != 0)
{
- priv->imr &= ~TIMER_INT_TAM;
+ status &= ~(TIMER_INT_TAM | TIMER_INT_RTC);
tiva_putreg(priv, TIVA_TIMER_IMR_OFFSET, priv->imr);
}
@@ -839,7 +839,6 @@ static int tiva_oneshot_periodic_mode32(struct tiva_gptmstate_s *priv,
regval &= ~TIMER_TnMR_TnCINTD;
}
-
/* Enable count down? */
if (TIMER_ISCOUNTUP(timer))
@@ -876,6 +875,8 @@ static int tiva_oneshot_periodic_mode32(struct tiva_gptmstate_s *priv,
*/
#warning Missing Logic
+ /* TODO: Enable and configure uDMA trigger outputs */
+
/* 5. Load the start value into the GPTM Timer n Interval Load Register
* (GPTMTAILR).
*
@@ -1087,6 +1088,8 @@ static int tiva_oneshot_periodic_mode16(struct tiva_gptmstate_s *priv,
}
}
+ /* TODO: Enable and configure uDMA trigger outputs */
+
/* In addition, if using CCP pins, the TCACT field can be programmed to
* configure the compare action.
*/
@@ -1152,6 +1155,10 @@ static int tiva_oneshot_periodic_mode16(struct tiva_gptmstate_s *priv,
* Description:
* Configure a 32-bit timer to operate in RTC mode
*
+ * The input clock on a CCP0 input is required to be 32.768 KHz in RTC
+ * mode. The clock signal is then divided down to a 1-Hz rate and is
+ * passed along to the input of the counter.
+ *
****************************************************************************/
static int tiva_rtc_mode32(struct tiva_gptmstate_s *priv,
@@ -1932,6 +1939,94 @@ void tiva_timer16_stop(TIMER_HANDLE handle, int tmndx)
}
/****************************************************************************
+ * Name: tiva_rtc_alarm
+ *
+ * Description:
+ * Setup to receive an interrupt when the RTC counter equals a match time
+ * value. This function sets the match register to the current timer
+ * counter register value PLUS the relative value provided. The relative
+ * value then is an offset in seconds from the current time.
+ *
+ * NOTE: Use of this function is only meaningful for a a 32-bit RTC time.
+ *
+ * Input Parameters:
+ * handle - The handle value returned by tiva_gptm_configure()
+ * delay - A relative time in the future (seconds)
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+void tiva_rtc_alarm(TIMER_HANDLE handle, uint32_t delay)
+{
+ struct tiva_gptmstate_s *priv = (struct tiva_gptmstate_s *)handle;
+ const struct tiva_timer32config_s *config;
+ irqstate_t flags;
+ uintptr_t base;
+ uint32_t counter;
+ uint32_t match;
+ uint32_t adcev;
+ uint32_t adcbits;
+
+ DEBUGASSERT(priv && priv->attr && priv->config &&
+ priv->config->mode == TIMER32_MODE_RTC);
+
+ /* Update the saved IMR if an interrupt will be needed */
+
+ config = (const struct tiva_timer32config_s *)priv->config;
+ if (config->handler)
+ {
+ /* Update the saved IMR to enable the RTC match interrupt */
+
+ priv->imr |= TIMER_INT_RTC;
+ }
+
+ /* This must be done without interrupt or context switches to minimize
+ * race conditions with the free-running timer. Note that we also
+ * by-pass the normal register accesses to keep the latency to a
+ * minimum.
+ */
+
+ base = priv->attr->base;
+ adcbits = TIMER_ISADCRTCM(config) ? TIMER_ADCEV_RTCADCEN : 0;
+
+ flags = irqsave();
+
+ /* Set the match register to the current value of the timer counter plus
+ * the provided relative delay value.
+ */
+
+ counter = getreg32(base + TIVA_TIMER_TAR_OFFSET);
+ match = counter + delay;
+ 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);
+
+ /* TODO: Set uDMA trigger in the same manner */
+
+ /* Enable interrupts as necessary */
+
+ putreg32(priv->imr, base + TIVA_TIMER_IMR_OFFSET);
+ irqrestore(flags);
+
+#ifdef CONFIG_TIVA_TIMER_REGDEBUG
+ /* Generate low-level debug output outside of the critical section */
+
+ 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
+}
+
+/****************************************************************************
* Name: tiva_timer32_relmatch
*
* Description:
diff --git a/nuttx/arch/arm/src/tiva/tiva_timer.h b/nuttx/arch/arm/src/tiva/tiva_timer.h
index 89e8fa740..a0b9fab30 100644
--- a/nuttx/arch/arm/src/tiva/tiva_timer.h
+++ b/nuttx/arch/arm/src/tiva/tiva_timer.h
@@ -94,21 +94,47 @@
#define TIMER16B 1
/* Flags bit definitions in configuration structures. NOTE: not all flags
- * apply in all timer modes.
+ * apply in all timer modes. Applicable modes noted with:
+ *
+ * a. 32-bit one shot timer
+ * b. 32-bit periodic timer
+ * c. 32-bit one shot timer
+ * d. 32-bit periodic timer
+ * e. 32-bit RTC timer
*/
-#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_FLAG_COUNTUP (1 << 0) /* Bit 0: Count up (abcd) */
+#define TIMER_FLAG_ADCTIMEOUT (1 << 1) /* Bit 1: Generate ADC trigger on
+ * timeout (abcd) */
+#define TIMER_FLAG_ADCRTCM (1 << 2) /* Bit 2: Generate ADC trigger on
+ * RTC match (e) */
+#define TIMER_FLAG_ADCMATCH (1 << 3) /* Bit 3: Generate ADC trigger on
+ * match (abcd) */
+#define TIMER_FLAG_DMATIMEOUT (1 << 4) /* Bit 4: Generate uDMA trigger on
+ * timeout (abcd) */
+#define TIMER_FLAG_DMARTCM (1 << 5) /* Bit 5: Generate uDMA trigger on
+ * RTC match (e) */
+#define TIMER_FLAG_DMAMATCH (1 << 6) /* Bit 6: Generate uDMA trigger on
+ * match (abcd) */
#define TIMER_ISCOUNTUP(c) ((((c)->flags) & TIMER_FLAG_COUNTUP) != 0)
#define TIMER_ISADCTIMEOUT(c) ((((c)->flags) & TIMER_FLAG_ADCTIMEOUT) != 0)
+#define TIMER_ISADCRTCM(c) ((((c)->flags) & TIMER_FLAG_ADCRTCM) != 0)
#define TIMER_ISADCMATCH(c) ((((c)->flags) & TIMER_FLAG_ADCMATCH) != 0)
+#define TIMER_ISDMATIMEOUT(c) ((((c)->flags) & TIMER_FLAG_DMATIMEOUT) != 0)
+#define TIMER_ISDMARTCM(c) ((((c)->flags) & TIMER_FLAG_DMARTCM) != 0)
+#define TIMER_ISDMAMATCH(c) ((((c)->flags) & TIMER_FLAG_DMAMATCH) != 0)
/****************************************************************************
* Public Types
****************************************************************************/
-/* This enumeration identifies all supported 32-bit timer modes of operation */
+/* This enumeration identifies all supported 32-bit timer modes of operation
+ *
+ * NOTES:
+ * - TIMER32_MODE_RTC: The input clock on a CCP0 input is required to be
+ * 32.768 KHz in RTC mode. The clock signal is then divided down to a 1-Hz
+ * rate and is passed along to the input of the counter.
+ */
enum tiva_timer32mode_e
{
@@ -118,7 +144,7 @@ enum tiva_timer32mode_e
TIMER32_MODE_RTC /* 32-bit RTC with external 32.768-KHz input */
};
-/* This enumeration identifies all supported 16-bit timer A/Bmodes of
+/* This enumeration identifies all supported 16-bit timer A/B modes of
* operation.
*/
@@ -546,6 +572,33 @@ static inline void tiva_timer16b_absmatch(TIMER_HANDLE handle, uint16_t absmatch
}
/****************************************************************************
+ * Name: tiva_rtc_alarm
+ *
+ * Description:
+ * Setup to receive an interrupt when the RTC counter equals a match time
+ * value. This function sets the match register to the current timer
+ * counter register value PLUS the relative value provided. The relative
+ * value then is an offset in seconds from the current time.
+ *
+ * If an interrupt handler is provided, then the RTC match interrupt will
+ * be enabled. A single RTC match interrupt will be generated; further
+ * RTC match interrupts will be disabled.
+ *
+ * NOTE: Use of this function is only meaningful for a a 32-bit RTC time.
+ * NOTE: An interrupt handler address must provided in the configuration.
+ *
+ * Input Parameters:
+ * handle - The handle value returned by tiva_gptm_configure()
+ * delay - A relative time in the future (seconds)
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+void tiva_rtc_alarm(TIMER_HANDLE handle, uint32_t delay);
+
+/****************************************************************************
* Name: tiva_timer32_relmatch
*
* Description:
@@ -559,8 +612,8 @@ static inline void tiva_timer16b_absmatch(TIMER_HANDLE handle, uint16_t absmatch
* be enabled. A single match interrupt will be generated; further match
* interrupts will be disabled.
*
- * NOTE: Use of this function is only meaningful for a free-runnning,
- * periodic timer.
+ * NOTE: Use of this function is only meaningful for a 32-bit free-
+ * runnning, periodic timer.
*
* WARNING: For free-running timers, the relative match value should be
* sufficiently far in the future to avoid race conditions.
@@ -590,8 +643,8 @@ void tiva_timer32_relmatch(TIMER_HANDLE handle, uint32_t relmatch);
* be enabled. A single match interrupt will be generated; further match
* interrupts will be disabled.
*
- * NOTE: Use of this function is only meaningful for a free-runnning,
- * periodic timer.
+ * NOTE: Use of this function is only meaningful for a 16-bit free-
+ * runnning, periodic timer.
*
* NOTE: The relmatch input is a really a 24-bit value; it is the 16-bit
* match counter match value AND the 8-bit prescaler value. From the