summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/tiva/tiva_timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/arch/arm/src/tiva/tiva_timer.c')
-rw-r--r--nuttx/arch/arm/src/tiva/tiva_timer.c687
1 files changed, 687 insertions, 0 deletions
diff --git a/nuttx/arch/arm/src/tiva/tiva_timer.c b/nuttx/arch/arm/src/tiva/tiva_timer.c
new file mode 100644
index 000000000..4dfb65576
--- /dev/null
+++ b/nuttx/arch/arm/src/tiva/tiva_timer.c
@@ -0,0 +1,687 @@
+/****************************************************************************
+ * arch/arm/src/tiva/tiva_timer.h
+ *
+ * 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 <stdbool.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <nuttx/arch.h>
+#include <arch/irq.h>
+
+#include "up_arch.h"
+#include "chip/tiva_syscontrol.h"
+
+#include "tiva_enableclks.h"
+#include "tiva_enablepwr.h"
+#include "tiva_periphrdy.h"
+#include "tiva_timer.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+/* This structure retains the fixed, well-known attrutes of a GPTM module */
+
+struct tiva_gptmattr_s
+{
+ uintptr_t base; /* Register base address */
+ int irq[2]; /* Timer A/B interrupt numbers */
+};
+
+/* This structure represents the state of a GPTM module */
+
+struct tiva_gptmstate_s
+{
+ const struct tiva_gptmattr_s *attr;
+ const struct tiva_gptmconfig_s *config;
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#ifdef CONFIG_TIVA_TIMER0
+static const struct tiva_gptmattr_s g_gptm0_attr =
+{
+ .base = TIVA_TIMER0_BASE,
+ .irq = { TIVA_IRQ_TIMER0A, TIVA_IRQ_TIMER0B },
+};
+
+static struct tiva_gptmstate_s g_gptm0_state;
+#endif
+
+#ifdef CONFIG_TIVA_TIMER1
+static const struct tiva_gptmattr_s g_gptm1_attr =
+{
+ .base = TIVA_TIMER1_BASE,
+ .irq = { TIVA_IRQ_TIMER1A, TIVA_IRQ_TIMER1B },
+};
+
+static struct tiva_gptmstate_s g_gptm1_state;
+#endif
+
+#ifdef CONFIG_TIVA_TIMER2
+static const struct tiva_gptmattr_s g_gptm2_attr =
+{
+ .base = TIVA_TIMER2_BASE,
+ .irq = { TIVA_IRQ_TIMER2A, TIVA_IRQ_TIMER2B },
+};
+
+static struct tiva_gptmstate_s g_gptm2_state;
+#endif
+
+#ifdef CONFIG_TIVA_TIMER3
+static const struct tiva_gptmattr_s g_gptm3_attr =
+{
+ .base = TIVA_TIMER3_BASE,
+ .irq = { TIVA_IRQ_TIMER3A, TIVA_IRQ_TIMER3B },
+};
+
+static struct tiva_gptmstate_s g_gptm3_state;
+#endif
+
+#ifdef CONFIG_TIVA_TIMER4
+static const struct tiva_gptmattr_s g_gptm4_attr =
+{
+ .base = TIVA_TIMER4_BASE,
+ .irq = { TIVA_IRQ_TIMER4A, TIVA_IRQ_TIMER4B },
+};
+
+static struct tiva_gptmstate_s g_gptm4_state;
+#endif
+
+#ifdef CONFIG_TIVA_TIMER5
+static const struct tiva_gptmattr_s g_gptm5_attr =
+{
+ .base = TIVA_TIMER5_BASE,
+ .irq = { TIVA_IRQ_TIMER5A, TIVA_IRQ_TIMER5B },
+};
+
+static struct tiva_gptmstate_s g_gptm5_state;
+#endif
+
+#ifdef CONFIG_TIVA_TIMER6
+static const struct tiva_gptmattr_s g_gptm6_attr =
+{
+ .base = TIVA_TIMER6_BASE,
+ .irq = { TIVA_IRQ_TIMER6A, TIVA_IRQ_TIMER6B },
+};
+
+static struct tiva_gptmstate_s g_gptm6_state;
+#endif
+
+#ifdef CONFIG_TIVA_TIMER7
+static const struct tiva_gptmattr_s g_gptm7_attr =
+{
+ .base = TIVA_TIMER7_BASE,
+ .irq = { TIVA_IRQ_TIMER7A, TIVA_IRQ_TIMER7B },
+};
+
+static struct tiva_gptmstate_s g_gptm7_state;
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: tiva_getreg
+ *
+ * Description:
+ * Read one 32-bit GPTM register
+ *
+ ****************************************************************************/
+
+static uint32_t tiva_getreg(struct tiva_gptmstate_s *priv, unsigned int offset)
+{
+ uintptr_t regaddr = priv->attr->base + offset;
+ return getreg32(regaddr);
+}
+
+/****************************************************************************
+ * Name: tiva_putreg
+ *
+ * Description:
+ * Write one 32-bit GPTM register
+ *
+ ****************************************************************************/
+
+static void tiva_putreg(struct tiva_gptmstate_s *priv, unsigned int offset,
+ uint32_t regval)
+{
+ uintptr_t regaddr = priv->attr->base + offset;
+ putreg32(regval, regaddr);
+}
+
+/****************************************************************************
+ * Name: tiva_oneshot_periodic_mode32
+ *
+ * Description:
+ * Configure a 32-bit timer to operate in one-short or periodic mode
+ *
+ ****************************************************************************/
+
+static int tiva_oneshot_periodic_mode32(struct tiva_gptmstate_s *priv,
+ const struct tiva_timer32config_s *timer)
+{
+ /* The GPTM is configured for One-Shot and Periodic modes by the following
+ * sequence:
+ *
+ * 1. Ensure the timer is disabled (the TnEN bit in the GPTMCTL register
+ * is cleared) before making any changes.
+ * 2. Write the GPTM Configuration Register (GPTMCFG) with a value of
+ * 0x0000.0000.
+ * 3. Configure the TnMR field in the GPTM Timer n Mode Register
+ * (GPTMTnMR):
+ * a. Write a value of 0x1 for One-Shot mode.
+ * b. Write a value of 0x2 for Periodic mode.
+ * 4. Optionally configure the TnSNAPS, TnWOT, TnMTE, and TnCDIR bits in
+ * the GPTMTnMR register to select whether to capture the value of the
+ * free-running timer at time-out, use an external trigger to start
+ * counting, configure an additional trigger or interrupt, and count up
+ * or down. In addition, if using CCP pins, the TCACT field can be
+ * programmed to configure the compare action.
+ * 5. Load the start value into the GPTM Timer n Interval Load Register
+ * (GPTMTnILR).
+ * 6. If interrupts are required, set the appropriate bits in the GPTM
+ * Interrupt Mask Register (GPTMIMR).
+ * 7. Set the TnEN bit in the GPTMCTL register to enable the timer and
+ * start counting.
+ * 8. Poll the GPTMRIS register or wait for the interrupt to be generated
+ * (if enabled). In both cases, the status flags are cleared by writing
+ * a 1 to the appropriate bit of the GPTM Interrupt Clear Register
+ * (GPTMICR).
+ */
+#warning Missing Logic
+ return -ENOSYS;
+}
+
+/****************************************************************************
+ * Name: tiva_oneshot_periodic_mode16
+ *
+ * Description:
+ * Configure 16-bit timer A/B to operate in one-short or periodic mode
+ *
+ ****************************************************************************/
+
+static int tiva_oneshot_periodic_mode16(struct tiva_gptmstate_s *priv,
+ const struct tiva_timer16config_s *timer,
+ int tmndx)
+{
+ /* The GPTM is configured for One-Shot and Periodic modes by the following
+ * sequence:
+ *
+ * 1. Ensure the timer is disabled (the TnEN bit in the GPTMCTL register
+ * is cleared) before making any changes.
+ * 2. Write the GPTM Configuration Register (GPTMCFG) with a value of
+ * 0x0000.0000.
+ * 3. Configure the TnMR field in the GPTM Timer n Mode Register
+ * (GPTMTnMR):
+ * a. Write a value of 0x1 for One-Shot mode.
+ * b. Write a value of 0x2 for Periodic mode.
+ * 4. Optionally configure the TnSNAPS, TnWOT, TnMTE, and TnCDIR bits in
+ * the GPTMTnMR register to select whether to capture the value of the
+ * free-running timer at time-out, use an external trigger to start
+ * counting, configure an additional trigger or interrupt, and count up
+ * or down. In addition, if using CCP pins, the TCACT field can be
+ * programmed to configure the compare action.
+ * 5. Load the start value into the GPTM Timer n Interval Load Register
+ * (GPTMTnILR).
+ * 6. If interrupts are required, set the appropriate bits in the GPTM
+ * Interrupt Mask Register (GPTMIMR).
+ * 7. Set the TnEN bit in the GPTMCTL register to enable the timer and
+ * start counting.
+ * 8. Poll the GPTMRIS register or wait for the interrupt to be generated
+ * (if enabled). In both cases, the status flags are cleared by writing
+ * a 1 to the appropriate bit of the GPTM Interrupt Clear Register
+ * (GPTMICR).
+ */
+#warning Missing Logic
+ return -ENOSYS;
+}
+
+/****************************************************************************
+ * Name: tiva_rtc_mode32
+ *
+ * Description:
+ * Configure a 32-bit timer to operate in RTC mode
+ *
+ ****************************************************************************/
+
+static int tiva_rtc_mode32(struct tiva_gptmstate_s *priv,
+ const struct tiva_timer32config_s *timer)
+{
+ /* To use the RTC mode, the timer must have a 32.768-KHz input signal on
+ * an even CCP input. To enable the RTC feature, follow these steps:
+ *
+ * 1. Ensure the timer is disabled (the TAEN bit is cleared) before making
+ * any changes.
+ * 2. If the timer has been operating in a different mode prior to this,
+ * clear any residual set bits in the GPTM Timer n Mode (GPTMTnMR)
+ * register before reconfiguring.
+ * 3. Write the GPTM Configuration Register (GPTMCFG) with a value of
+ * 0x0000.0001.
+ * 4. Write the match value to the GPTM Timer n Match Register
+ * (GPTMTnMATCHR).
+ * 5. Set/clear the RTCEN and TnSTALL bit in the GPTM Control Register
+ * (GPTMCTL) as needed.
+ * 6. If interrupts are required, set the RTCIM bit in the GPTM Interrupt
+ * Mask Register (GPTMIMR).
+ * 7. Set the TAEN bit in the GPTMCTL register to enable the timer and
+ * start counting.
+ *
+ * When the timer count equals the value in the GPTMTnMATCHR register,
+ * the GPTM asserts the RTCRIS bit in the GPTMRIS register and continues
+ * counting until Timer A is disabled or a hardware reset. The interrupt
+ * is cleared by writing the RTCCINT bit in the GPTMICR register. Note
+ * that if the GPTMTnILR register is loaded with a new value, the timer
+ * begins counting at this new value and continues until it reaches
+ * 0xFFFF.FFFF, at which point it rolls over.
+ */
+#warning Missing Logic
+ return -ENOSYS;
+}
+
+/****************************************************************************
+ * Name: tiva_input_edgecount_mode16
+ *
+ * Description:
+ * Configure 16-bit timer A/B to operate in Input Edge-Count mode
+ *
+ ****************************************************************************/
+
+static int tiva_input_edgecount_mode16(struct tiva_gptmstate_s *priv,
+ const struct tiva_timer16config_s *timer,
+ int tmndx)
+{
+ /* A timer is configured to Input Edge-Count mode by the following sequence:
+ *
+ * 1. Ensure the timer is disabled (the TnEN bit is cleared) before making
+ * any changes.
+ * 2. Write the GPTM Configuration (GPTMCFG) register with a value of
+ * 0x0000.0004.
+ * 3. In the GPTM Timer Mode (GPTMTnMR) register, write the TnCMR field to
+ * 0x0 and the TnMR field to 0x3.
+ * 4. Configure the type of event(s) that the timer captures by writing
+ * the TnEVENT field of the GPTM Control (GPTMCTL) register.
+ * 5. Program registers according to count direction:
+ * - In down-count mode, the GPTMTnMATCHR and GPTMTnPMR registers are
+ * configured so that the difference between the value in the GPTMTnILR
+ * and GPTMTnPR registers and the GPTMTnMATCHR and GPTMTnPMR registers
+ * equals the number of edge events that must be counted.
+ * - In up-count mode, the timer counts from 0x0 to the value in the
+ * GPTMTnMATCHR and GPTMTnPMR registers. Note that when executing an
+ * up-count, the value of the GPTMTnPR and GPTMTnILR must be greater
+ * than the value of GPTMTnPMR and GPTMTnMATCHR.
+ * 6. If interrupts are required, set the CnMIM bit in the GPTM Interrupt
+ * Mask (GPTMIMR) register.
+ * 7. Set the TnEN bit in the GPTMCTL register to enable the timer and
+ * begin waiting for edge events.
+ * 8. Poll the CnMRIS bit in the GPTMRIS register or wait for the
+ * interrupt to be generated (if enabled). In both cases, the status
+ * flags are cleared by writing a 1 to the CnMCINT bit of the GPTM
+ * Interrupt Clear (GPTMICR) register.
+ *
+ * When counting down in Input Edge-Count Mode, the timer stops after the
+ * programmed number of edge events has been detected. To re-enable the
+ * timer, ensure that the TnEN bit is cleared and repeat steps 4 through 8.
+ */
+#warning Missing Logic
+ return -ENOSYS;
+}
+
+/****************************************************************************
+ * Name: tiva_input_time_mode16
+ *
+ * Description:
+ * Configure 16-bit timer A/B to operate in Input Time mode
+ *
+ ****************************************************************************/
+
+static int tiva_input_time_mode16(struct tiva_gptmstate_s *priv,
+ const struct tiva_timer16config_s *timer,
+ int tmndx)
+{
+ /* A timer is configured to Input Edge Time mode by the following sequence:
+ *
+ * 1. Ensure the timer is disabled (the TnEN bit is cleared) before making
+ * any changes.
+ * 2. Write the GPTM Configuration (GPTMCFG) register with a value of
+ * 0x0000.0004.
+ * 3. In the GPTM Timer Mode (GPTMTnMR) register, write the TnCMR field to
+ * 0x1 and the TnMR field to 0x3 and select a count direction by
+ * programming the TnCDIR bit.
+ * 4. Configure the type of event that the timer captures by writing the
+ * TnEVENT field of the GPTM Control (GPTMCTL) register.
+ * 5. If a prescaler is to be used, write the prescale value to the GPTM
+ * Timer n Prescale Register (GPTMTnPR).
+ * 6. Load the timer start value into the GPTM Timer n Interval Load
+ * (GPTMTnILR) register.
+ * 7. If interrupts are required, set the CnEIM bit in the GPTM Interrupt
+ * Mask (GPTMIMR) register.
+ * 8. Set the TnEN bit in the GPTM Control (GPTMCTL) register to enable the
+ * timer and start counting.
+ * 9. Poll the CnERIS bit in the GPTMRIS register or wait for the interrupt
+ * to be generated (if enabled). In both cases, the status flags are
+ * cleared by writing a 1 to the CnECINT bit of the GPTM Interrupt
+ * Clear (GPTMICR) register. The time at which the event happened can
+ * be obtained by reading the GPTM Timer n (GPTMTnR) register.
+ *
+ * In Input Edge Timing mode, the timer continues running after an edge
+ * event has been detected, but the timer interval can be changed at any
+ * time by writing the GPTMTnILR register and clearing the TnILD bit in
+ * the GPTMTnMR register. The change takes effect at the next cycle after
+ * the write.
+ */
+#warning Missing Logic
+ return -ENOSYS;
+}
+
+/****************************************************************************
+ * Name: tiva_pwm_mode16
+ *
+ * Description:
+ * Configure 16-bit timer A/B to operate in PWM mode
+ *
+ ****************************************************************************/
+
+static int tiva_pwm_mode16(struct tiva_gptmstate_s *priv,
+ const struct tiva_timer16config_s *timer,
+ int tmndx)
+{
+ /* A timer is configured to PWM mode using the following sequence:
+ *
+ * 1. Ensure the timer is disabled (the TnEN bit is cleared) before making
+ * any changes.
+ * 2. Write the GPTM Configuration (GPTMCFG) register with a value of
+ * 0x0000.0004.
+ * 3. In the GPTM Timer Mode (GPTMTnMR) register, set the TnAMS bit to
+ * 0x1, the TnCMR bit to 0x0, and the TnMR field to 0x2.
+ * 4. Configure the output state of the PWM signal (whether or not it is
+ * inverted) in the TnPWML field of the GPTM Control (GPTMCTL) register.
+ * 5. If a prescaler is to be used, write the prescale value to the GPTM
+ * Timer n Prescale Register (GPTMTnPR).
+ * 6. If PWM interrupts are used, configure the interrupt condition in the
+ * TnEVENT field in the GPTMCTL register and enable the interrupts by
+ * setting the TnPWMIE bit in the GPTMTnMR register. Note that edge
+ * detect interrupt behavior is reversed when the PWM output is
+ * inverted.
+ * 7. Load the timer start value into the GPTM Timer n Interval Load
+ * (GPTMTnILR) register.
+ * 8. Load the GPTM Timer n Match (GPTMTnMATCHR) register with the match
+ * value.
+ * 9. Set the TnEN bit in the GPTM Control (GPTMCTL) register to enable
+ * the timer and begin generation of the output PWM signal.
+ *
+ * In PWM Time mode, the timer continues running after the PWM signal has
+ * been generated. The PWM period can be adjusted at any time by writing
+ * the GPTMTnILR register, and the change takes effect at the next cycle
+ * after the write.
+ */
+#warning Missing Logic
+ return -ENOSYS;
+}
+
+/****************************************************************************
+ * Name: tiva_timer16_configure
+ *
+ * Description:
+ * Configure the 32-bit timer to operate in the provided mode.
+ *
+ ****************************************************************************/
+
+static int tiva_timer32_configure(struct tiva_gptmstate_s *priv,
+ const struct tiva_timer32config_s *timer)
+{
+ switch (priv->config->mode)
+ {
+ case TIMER32_MODE_ONESHOT: /* 32-bit programmable one-shot timer */
+ case TIMER32_MODE_PERIODIC: /* 32-bit programmable periodic timer */
+ return tiva_oneshot_periodic_mode32(priv, timer);
+
+ case TIMER32_MODE_RTC: /* 32-bit RTC with external 32.768-KHz
+ * input */
+ return tiva_rtc_mode32(priv, timer);
+
+ default:
+ return -EINVAL;
+ }
+}
+
+/****************************************************************************
+ * Name: tiva_timer16_configure
+ *
+ * Description:
+ * Configure 16-bit timer A or B to operate in the provided mode.
+ *
+ ****************************************************************************/
+
+static int tiva_timer16_configure(struct tiva_gptmstate_s *priv,
+ const struct tiva_timer16config_s *timer,
+ int tmndx)
+{
+ switch (timer->mode)
+ {
+ case TIMER16_MODE_NONE:
+ return OK;
+
+ case TIMER16_MODE_ONESHOT: /* 16-bit programmable one-shot timer */
+ case TIMER16_MODE_PERIODIC: /* 16-bit programmable periodic timer */
+ return tiva_oneshot_periodic_mode16(priv, timer, tmndx);
+
+ case TIMER16_MODE_COUNT_CAPTURE: /* 16-bit input-edge count-capture
+ * mode w/8-bit prescaler */
+ return tiva_input_edgecount_mode16(priv, timer, tmndx);
+
+ case TIMER16_MODE_TIME_CAPTURE: /* 16-bit input-edge time-capture
+ * mode w/8-bit prescaler */
+ return tiva_input_time_mode16(priv, timer, tmndx);
+
+ case TIMER16_MODE_PWM: /* 16-bit PWM output mode w/8-bit
+ * prescaler */
+ return tiva_pwm_mode16(priv, timer, tmndx);
+
+ default:
+ return -EINVAL;
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: tiva_gptm_configure
+ *
+ * Description:
+ * Configure a general purpose timer module to operate in the provided
+ * modes.
+ *
+ ****************************************************************************/
+
+TIMER_HANDLE tiva_gptm_configure(const struct tiva_gptmconfig_s *gptm)
+{
+ static const struct tiva_gptmattr_s *attr;
+ static struct tiva_gptmstate_s *priv;
+ uint32_t regval;
+ int ret;
+
+ DEBUGASSERT(gptm);
+
+ /* Select the GPTM module. */
+
+ switch (gptm->gptm)
+ {
+#ifdef CONFIG_TIVA_TIMER0
+ case 0:
+ /* Enable GPTM0 clocking and power */
+
+
+ attr = &g_gptm0_attr;
+ priv = &g_gptm0_state;
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_TIMER1
+ case 1:
+ attr = &g_gptm1_attr;
+ priv = &g_gptm1_state;
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_TIMER2
+ case 2:
+ attr = &g_gptm2_attr;
+ priv = &g_gptm2_state;
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_TIMER3
+ case 3:
+ attr = &g_gptm3_attr;
+ priv = &g_gptm3_state;
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_TIMER4
+ case 4:
+ attr = &g_gptm4_attr;
+ priv = &g_gptm4_state;
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_TIMER5
+ case 5:
+ attr = &g_gptm5_attr;
+ priv = &g_gptm5_state;
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_TIMER6
+ case 6:
+ attr = &g_gptm6_attr;
+ priv = &g_gptm6_state;
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_TIMER7
+ case 7:
+ attr = &g_gptm7_attr;
+ priv = &g_gptm7_state;
+ break;
+#endif
+
+ default:
+ return (TIMER_HANDLE)NULL;
+ }
+
+ /* Initialize the state structure */
+
+ memset(priv, 0, sizeof(struct tiva_gptmstate_s));
+ priv->attr = attr;
+ priv->config = gptm;
+
+ /* Enable power and clocking to the GPTM module
+ *
+ * - Enable Power (TM4C129 family only): Applies power (only) to the GPTM
+ * module. This is not an essential step since enabling clocking
+ * will also apply power. The only significance is that the GPTM state
+ * will be retained if the GPTM clocking is subsequently disabled.
+ * - Enable Clocking (All families): Applies both power and clocking to
+ * the GPTM module, bringing it a fully functional state.
+ */
+
+ tiva_gptm_enableclk(gptm->gptm);
+ tiva_gptm_enablepwr(gptm->gptm);
+
+ /* Wait for the gptm to become ready before modifying its registers */
+
+ while (!tiva_gpio_periphrdy(gptm->gptm));
+
+ /* Reset the time to be certain that it is in the disabled state */
+
+ regval = tiva_getreg(priv, TIVA_SYSCON_SRTIMER);
+ regval |= SYSCON_SRTIMER(gptm->gptm);
+ tiva_putreg(priv, TIVA_SYSCON_SRTIMER, regval);
+
+ regval &= ~SYSCON_SRTIMER(gptm->gptm);
+ tiva_putreg(priv, TIVA_SYSCON_SRTIMER, regval);
+
+ /* Wait for the reset to complete */
+
+ while (!tiva_emac_periphrdy());
+ up_udelay(250);
+
+ /* Then [re-]configure the timer into the new configuration */
+
+ if (gptm->mode != TIMER16_MODE)
+ {
+ const struct tiva_gptm32config_s *gptm32 =
+ (const struct tiva_gptm32config_s *)gptm;
+
+ /* Configure the 32-bit timer */
+
+ ret = tiva_timer32_configure(priv, &gptm32->config);
+ }
+ else
+ {
+ const struct tiva_gptm16config_s *gptm16 =
+ (const struct tiva_gptm16config_s *)gptm;
+
+ /* Configure both 16-bit timers */
+
+ ret = tiva_timer16_configure(priv, &gptm16->config[TIMER_A], TIMER_A);
+ if (ret == OK)
+ {
+ ret = tiva_timer16_configure(priv, &gptm16->config[TIMER_B],
+ TIMER_B);
+ }
+ }
+
+ /* Return the timer handler if successfully configured */
+
+ return ret < 0 ? (TIMER_HANDLE)NULL : (TIMER_HANDLE)priv;
+}