From aadc76f41e39f84dbdcd6987ce89f6d8bcb87252 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 8 Jan 2015 13:44:10 -0600 Subject: Tiva Timer: Partial support for 16- and 32-bit, oneshot and periodic timer configurations --- nuttx/arch/arm/src/tiva/chip/tiva_timer.h | 119 ++++++++++-------------------- nuttx/arch/arm/src/tiva/tiva_timer.c | 56 +++++++++++++- nuttx/arch/arm/src/tiva/tiva_timer.h | 48 ++++++++++++ 3 files changed, 140 insertions(+), 83 deletions(-) diff --git a/nuttx/arch/arm/src/tiva/chip/tiva_timer.h b/nuttx/arch/arm/src/tiva/chip/tiva_timer.h index c2efdb2c7..f810d6fdd 100644 --- a/nuttx/arch/arm/src/tiva/chip/tiva_timer.h +++ b/nuttx/arch/arm/src/tiva/chip/tiva_timer.h @@ -477,86 +477,45 @@ # define TIMER_CFG_CFG_RTC (1 << TIMER_CFG_CFG_SHIFT) /* 32-bit real-time clock (RTC) counter configuration */ # define TIMER_CFG_CFG_16 (4 << TIMER_CFG_CFG_SHIFT) /* 16-bit timer configuration */ -/* GPTM Timer A Mode (TAMR) */ - -#define TIMER_TAMR_TAMR_SHIFT 0 /* Bits 1-0: Timer A Mode */ -#define TIMER_TAMR_TAMR_MASK (3 << TIMER_TAMR_TAMR_SHIFT) -# define TIMER_TAMR_TAMR_ONESHOT (1 << TIMER_TAMR_TAMR_SHIFT) /* One-Shot Timer mode */ -# define TIMER_TAMR_TAMR_PERIODIC (2 << TIMER_TAMR_TAMR_SHIFT) /* Periodic Timer mode */ -# define TIMER_TAMR_TAMR_CAPTURE (3 << TIMER_TAMR_TAMR_SHIFT) /* Capture mode */ -#define TIMER_TAMR_TACMR (1 << 2) /* Bit 2: Timer A Capture Mode */ -# define TIMER_TAMR_TACMR_EDGECOUNT (0 << TIMER_TAMR_TACMR_SHIFT) /* Edge-Count mode */ -# define TIMER_TAMR_TACMR_EDGETIME (1 << TIMER_TAMR_TACMR_SHIFT) /* Edge-Time mode */ -#define TIMER_TAMR_TAAMS (1 << 3) /* Bit 3: Timer A Alternate Mode Select */ -# define TIMER_TAMR_TAAMS_CAPTURE (0 << TIMER_TAMR_TAAMS_SHIFT) /* Capture mode is enabled */ -# define TIMER_TAMR_TAAMS_PWM (1 << TIMER_TAMR_TAAMS_SHIFT) /* PWM mode is enabled */ - -#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) -# define TIMER_TAMR_TACDIR (1 << 4) /* Bit 4: Timer A Count Direction */ -# define TIMER_TAMR_TACDIR_DOWN (0 << TIMER_TAMR_TACDIR_SHIFT) /* The timer counts down */ -# define TIMER_TAMR_TACDIR_UP (1 << TIMER_TAMR_TACDIR_SHIFT) /* When in one-shot or periodic mode, the timer counts up */ -# define TIMER_TAMR_TAMIE (1 << 5) /* Bit 5: Timer A Match Interrupt Enable */ -# define TIMER_TAMR_TAWOT (1 << 6) /* Bit 6: GPTM Timer A Wait-on-Trigger */ -# define TIMER_TAMR_TASNAPS (1 << 7) /* Bit 7: GPTM Timer A Snap-Shot Mode */ -# define TIMER_TAMR_TAILD (1 << 8) /* Bit 8: GPTM Timer A Interval Load Write */ -# define TIMER_TAMR_TAPWMIE (1 << 9) /* Bit 9: GPTM Timer A PWM Interrupt Enable */ -# define TIMER_TAMR_TAMRSU (1 << 10) /* Bit 10: GPTM Timer A Match Register Update */ -# define TIMER_TAMR_TAPLO (1 << 11) /* Bit 11: GPTM Timer A PWM Legacy Operation */ -#endif - -#if defined(CONFIG_ARCH_CHIP_TM4C129) -# define TIMER_TAMR_TACINTD (1 << 12) /* Bit 12: One-shot/Periodic Interrupt Disable */ -# define TIMER_TAMR_TCACT_SHIFT (13) /* Bits 13-15: Timer Compare Action Select */ -# define TIMER_TAMR_TCACT_MASK (7 << TIMER_TAMR_TCACT_SHIFT) -# define TIMER_TAMR_TCACT_NONE (0 << TIMER_TAMR_TCACT_SHIFT) /* Disable compare operations */ -# define TIMER_TAMR_TCACT_TOGGLE (1 << TIMER_TAMR_TCACT_SHIFT) /* Toggle state on timeout */ -# define TIMER_TAMR_TCACT_CLRTO (2 << TIMER_TAMR_TCACT_SHIFT) /* Clear CCP on timeout */ -# define TIMER_TAMR_TCACT_SETTO (3 << TIMER_TAMR_TCACT_SHIFT) /* Set CCP on timeout */ -# define TIMER_TAMR_TCACT_SETTOGTO (4 << TIMER_TAMR_TCACT_SHIFT) /* Set CCP and toggle on TimeOut */ -# define TIMER_TAMR_TCACT_CLRTOGTO (5 << TIMER_TAMR_TCACT_SHIFT) /* Clear CCP and toggle on TimeOut */ -# define TIMER_TAMR_TCACT_SETCLRTO (6 << TIMER_TAMR_TCACT_SHIFT) /* Set CCP and clear on timeout */ -# define TIMER_TAMR_TCACT_CLRSETTO (7 << TIMER_TAMR_TCACT_SHIFT) /* Clear CCP and set on timeout */ -#endif - -/* GPTM Timer B Mode (TBMR) */ - -#define TIMER_TBMR_TBMR_SHIFT 0 /* Bits 1-0: Timer B Mode */ -#define TIMER_TBMR_TBMR_MASK (3 << TIMER_TBMR_TBMR_SHIFT) -# define TIMER_TBMR_TBMR_ONESHOT (1 << TIMER_TBMR_TBMR_SHIFT) /* One-Shot Timer mode */ -# define TIMER_TBMR_TBMR_PERIODIC (2 << TIMER_TBMR_TBMR_SHIFT) /* Periodic Timer mode */ -# define TIMER_TBMR_TBMR_CAPTURE (3 << TIMER_TBMR_TBMR_SHIFT) /* Capture mode */ -#define TIMER_TBMR_TBCMR (1 << 2) /* Bit 2: Timer B Capture Mode */ -# define TIMER_TBMR_TBCMR_EDGECOUNT (0 << TIMER_TBMR_TBCMR_SHIFT) /* Edge-Count mode */ -# define TIMER_TBMR_TBCMR_EDGETIME (1 << TIMER_TBMR_TBCMR_SHIFT) /* Edge-Time mode */ -#define TIMER_TBMR_TBAMS (1 << 3) /* Bit 3: Timer B Alternate Mode Select */ -# define TIMER_TBMR_TBAMS_CAPTURE (0 << TIMER_TBMR_TBAMS_SHIFT) /* Capture mode is enabled */ -# define TIMER_TBMR_TBAMS_PWM (1 << TIMER_TBMR_TBAMS_SHIFT) /* PWM mode is enabled */ - -#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) -# define TIMER_TBMR_TBCDIR (1 << 4) /* Bit 4: Timer B Count Direction */ -# define TIMER_TBMR_TBCDIR_DOWN (0 << TIMER_TBMR_TBCDIR_SHIFT) /* The timer counts down */ -# define TIMER_TBMR_TBCDIR_UP (1 << TIMER_TBMR_TBCDIR_SHIFT) /* When in one-shot or periodic mode, the timer counts up */ -# define TIMER_TBMR_TBMIE (1 << 5) /* Bit 5: Timer B Match Interrupt Enable */ -# define TIMER_TBMR_TBWOT (1 << 6) /* Bit 6: GPTM Timer B Wait-on-Trigger */ -# define TIMER_TBMR_TBSNAPS (1 << 7) /* Bit 7: GPTM Timer B Snap-Shot Mode */ -# define TIMER_TBMR_TBILD (1 << 8) /* Bit 8: GPTM Timer B Interval Load Write */ -# define TIMER_TBMR_TBPWMIE (1 << 9) /* Bit 9: GPTM Timer B PWM Interrupt Enable */ -# define TIMER_TBMR_TBMRSU (1 << 10) /* Bit 10: GPTM Timer B Match Register Update */ -# define TIMER_TBMR_TBPLO (1 << 11) /* Bit 11: GPTM Timer B PWM Legacy Operation */ -#endif - -#if defined(CONFIG_ARCH_CHIP_TM4C129) -# define TIMER_TBMR_TBCINTD (1 << 12) /* Bit 12: One-shot/Periodic Interrupt Disable */ -# define TIMER_TBMR_TCACT_SHIFT (13) /* Bits 13-15: Timer Compare Action Select */ -# define TIMER_TBMR_TCACT_MASK (7 << TIMER_TBMR_TCACT_SHIFT) -# define TIMER_TBMR_TCACT_NONE (0 << TIMER_TBMR_TCACT_SHIFT) /* Disable compare operations */ -# define TIMER_TBMR_TCACT_TOGGLE (1 << TIMER_TBMR_TCACT_SHIFT) /* Toggle state on timeout */ -# define TIMER_TBMR_TCACT_CLRTO (2 << TIMER_TBMR_TCACT_SHIFT) /* Clear CCP on timeout */ -# define TIMER_TBMR_TCACT_SETTO (3 << TIMER_TBMR_TCACT_SHIFT) /* Set CCP on timeout */ -# define TIMER_TBMR_TCACT_SETTOGTO (4 << TIMER_TBMR_TCACT_SHIFT) /* Set CCP and toggle on TimeOut */ -# define TIMER_TBMR_TCACT_CLRTOGTO (5 << TIMER_TBMR_TCACT_SHIFT) /* Clear CCP and toggle on TimeOut */ -# define TIMER_TBMR_TCACT_SETCLRTO (6 << TIMER_TBMR_TCACT_SHIFT) /* Set CCP and clear on timeout */ -# define TIMER_TBMR_TCACT_CLRSETTO (7 << TIMER_TBMR_TCACT_SHIFT) /* Clear CCP and set on timeout */ +/* GPTM Timer A/B Mode (TAMR and TBMR) */ + +#define TIMER_TnMR_TnMR_SHIFT 0 /* Bits 1-0: Timer A Mode */ +#define TIMER_TnMR_TnMR_MASK (3 << TIMER_TnMR_TnMR_SHIFT) +# define TIMER_TnMR_TnMR_ONESHOT (1 << TIMER_TnMR_TnMR_SHIFT) /* One-Shot Timer mode */ +# define TIMER_TnMR_TnMR_PERIODIC (2 << TIMER_TnMR_TnMR_SHIFT) /* Periodic Timer mode */ +# define TIMER_TnMR_TnMR_CAPTURE (3 << TIMER_TnMR_TnMR_SHIFT) /* Capture mode */ +#define TIMER_TnMR_TACMR (1 << 2) /* Bit 2: Timer A Capture Mode */ +# define TIMER_TnMR_TACMR_EDGECOUNT (0 << TIMER_TnMR_TACMR_SHIFT) /* Edge-Count mode */ +# define TIMER_TnMR_TACMR_EDGETIME (1 << TIMER_TnMR_TACMR_SHIFT) /* Edge-Time mode */ +#define TIMER_TnMR_TAAMS (1 << 3) /* Bit 3: Timer A Alternate Mode Select */ +# define TIMER_TnMR_TAAMS_CAPTURE (0 << TIMER_TnMR_TAAMS_SHIFT) /* Capture mode is enabled */ +# define TIMER_TnMR_TAAMS_PWM (1 << TIMER_TnMR_TAAMS_SHIFT) /* PWM mode is enabled */ + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIMER_TnMR_TACDIR (1 << 4) /* Bit 4: Timer A Count Direction */ +# define TIMER_TnMR_TACDIR_DOWN (0 << TIMER_TnMR_TACDIR_SHIFT) /* The timer counts down */ +# define TIMER_TnMR_TACDIR_UP (1 << TIMER_TnMR_TACDIR_SHIFT) /* When in one-shot or periodic mode, the timer counts up */ +# define TIMER_TnMR_TAMIE (1 << 5) /* Bit 5: Timer A Match Interrupt Enable */ +# define TIMER_TnMR_TAWOT (1 << 6) /* Bit 6: GPTM Timer A Wait-on-Trigger */ +# define TIMER_TnMR_TASNAPS (1 << 7) /* Bit 7: GPTM Timer A Snap-Shot Mode */ +# define TIMER_TnMR_TAILD (1 << 8) /* Bit 8: GPTM Timer A Interval Load Write */ +# define TIMER_TnMR_TAPWMIE (1 << 9) /* Bit 9: GPTM Timer A PWM Interrupt Enable */ +# define TIMER_TnMR_TnMRSU (1 << 10) /* Bit 10: GPTM Timer A Match Register Update */ +# define TIMER_TnMR_TAPLO (1 << 11) /* Bit 11: GPTM Timer A PWM Legacy Operation */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIMER_TnMR_TACINTD (1 << 12) /* Bit 12: One-shot/Periodic Interrupt Disable */ +# define TIMER_TnMR_TCACT_SHIFT (13) /* Bits 13-15: Timer Compare Action Select */ +# define TIMER_TnMR_TCACT_MASK (7 << TIMER_TnMR_TCACT_SHIFT) +# define TIMER_TnMR_TCACT_NONE (0 << TIMER_TnMR_TCACT_SHIFT) /* Disable compare operations */ +# define TIMER_TnMR_TCACT_TOGGLE (1 << TIMER_TnMR_TCACT_SHIFT) /* Toggle state on timeout */ +# define TIMER_TnMR_TCACT_CLRTO (2 << TIMER_TnMR_TCACT_SHIFT) /* Clear CCP on timeout */ +# define TIMER_TnMR_TCACT_SETTO (3 << TIMER_TnMR_TCACT_SHIFT) /* Set CCP on timeout */ +# define TIMER_TnMR_TCACT_SETTOGTO (4 << TIMER_TnMR_TCACT_SHIFT) /* Set CCP and toggle on TimeOut */ +# define TIMER_TnMR_TCACT_CLRTOGTO (5 << TIMER_TnMR_TCACT_SHIFT) /* Clear CCP and toggle on TimeOut */ +# define TIMER_TnMR_TCACT_SETCLRTO (6 << TIMER_TnMR_TCACT_SHIFT) /* Set CCP and clear on timeout */ +# define TIMER_TnMR_TCACT_CLRSETTO (7 << TIMER_TnMR_TCACT_SHIFT) /* Clear CCP and set on timeout */ #endif /* GPTM Control (CTL) */ diff --git a/nuttx/arch/arm/src/tiva/tiva_timer.c b/nuttx/arch/arm/src/tiva/tiva_timer.c index 4f15c93e0..70feab6b5 100644 --- a/nuttx/arch/arm/src/tiva/tiva_timer.c +++ b/nuttx/arch/arm/src/tiva/tiva_timer.c @@ -290,6 +290,8 @@ static void tiva_putreg(struct tiva_gptmstate_s *priv, unsigned int offset, static int tiva_oneshot_periodic_mode32(struct tiva_gptmstate_s *priv, const struct tiva_timer32config_s *timer) { + uint32_t regval; + /* The GPTM is configured for One-Shot and Periodic modes by the following * sequence: * @@ -305,12 +307,30 @@ static int tiva_oneshot_periodic_mode32(struct tiva_gptmstate_s *priv, tiva_putreg(priv, TIVA_TIMER_CFG_OFFSET, TIMER_CFG_CFG_32); - /* 3. Configure the TnMR field in the GPTM Timer n Mode Register - * (GPTMTnMR): + /* 3. Configure the TAMR field in the GPTM Timer n Mode Register + * (GPTMTAMR): + * * a. Write a value of 0x1 for One-Shot mode. * b. Write a value of 0x2 for Periodic mode. + * + * When Timer A and TimerB are concatenated, the GPTMTBMR register is + * ignored and GPTMTAMR controls the modes for both Timer A and Timer B */ + regval = tiva_getreg(priv, TIVA_TIMER_TAMR_OFFSET); + regval &= ~TIMER_TnMR_TnMR_MASK; + + if (priv->config->mode == TIMER32_MODE_ONESHOT) + { + regval |= TIMER_TnMR_TnMR_ONESHOT; + } + else /* if (priv->config->mode == TIMER32_MODE_PERIODIC) */ + { + regval |= TIMER_TnMR_TnMR_PERIODIC; + } + + tiva_putreg(priv, TIVA_TIMER_TAMR_OFFSET, regval); + /* 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 @@ -318,11 +338,19 @@ static int tiva_oneshot_periodic_mode32(struct tiva_gptmstate_s *priv, * or down. In addition, if using CCP pins, the TCACT field can be * programmed to configure the compare action. */ +#warning Missing logic /* 5. Load the start value into the GPTM Timer n Interval Load Register - * (GPTMTnILR). + * (GPTMTAILR). + * + * When a GPTM is configured to one of the 32-bit modes, GPTMTAILR + * appears as a 32-bit register; the upper 16-bits correspond to bits + * 15:0 of the GPTM Timer B Interval Load (GPTMTBILR) register. + * Writes to GPTMTBILR are ignored. */ + tiva_putreg(priv, TIVA_TIMER_TAILR_OFFSET, timer->u.periodic.interval); + /* 6. If interrupts are required, set the appropriate bits in the GPTM * Interrupt Mask Register (GPTMIMR). */ @@ -353,6 +381,9 @@ static int tiva_oneshot_periodic_mode16(struct tiva_gptmstate_s *priv, const struct tiva_timer16config_s *timer, int tmndx) { + unsigned int regoffset; + uint32_t regval; + /* The GPTM is configured for One-Shot and Periodic modes by the following * sequence: * @@ -374,6 +405,21 @@ static int tiva_oneshot_periodic_mode16(struct tiva_gptmstate_s *priv, * b. Write a value of 0x2 for Periodic mode. */ + regoffset = tmndx ? TIVA_TIMER_TBMR_OFFSET : TIVA_TIMER_TAMR_OFFSET; + regval = tiva_getreg(priv, regoffset); + regval &= ~TIMER_TnMR_TnMR_MASK; + + if (timer->mode == TIMER16_MODE_ONESHOT) + { + regval |= TIMER_TnMR_TnMR_ONESHOT; + } + else /* if (timer->mode == TIMER16_MODE_PERIODIC) */ + { + regval |= TIMER_TnMR_TnMR_PERIODIC; + } + + tiva_putreg(priv, regoffset, regval); + /* 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 @@ -381,11 +427,15 @@ static int tiva_oneshot_periodic_mode16(struct tiva_gptmstate_s *priv, * or down. In addition, if using CCP pins, the TCACT field can be * programmed to configure the compare action. */ +#warning Missing logic /* 5. Load the start value into the GPTM Timer n Interval Load Register * (GPTMTnILR). */ + regoffset = tmndx ? TIVA_TIMER_TBILR_OFFSET : TIVA_TIMER_TAILR_OFFSET; + tiva_putreg(priv, regoffset, timer->u.periodic.interval); + /* 6. If interrupts are required, set the appropriate bits in the GPTM * Interrupt Mask Register (GPTMIMR). */ diff --git a/nuttx/arch/arm/src/tiva/tiva_timer.h b/nuttx/arch/arm/src/tiva/tiva_timer.h index 5ccd8b834..d2d270f9d 100644 --- a/nuttx/arch/arm/src/tiva/tiva_timer.h +++ b/nuttx/arch/arm/src/tiva/tiva_timer.h @@ -123,6 +123,24 @@ struct tiva_timer32config_s { bool down; /* False: Count up; True: Count down */ /* TODO: Add fields to support ADC trigger events */ + + /* Mode-specific parameters */ + + union + { + /* 32-bit programmable one-shot or periodic timer */ + + struct + { + uint32_t interval; /* Value for interval load register */ + } periodic; + + /* 32-bit RTC with external 32.768-KHz input */ + + struct + { + } rtc; + } u; }; /* This structure describes the configuration of one 16-bit timer A/B */ @@ -132,6 +150,36 @@ struct tiva_timer16config_s uint8_t mode; /* See enum tiva_timermode_e */ bool down; /* False: Count up; True: Count down */ /* TODO: Add fields to support ADC trigger events */ + + /* Mode-specific parameters */ + + union + { + /* 16-bit programmable one-shot or periodic timer */ + + struct + { + uint16_t interval; /* Value for interval load register */ + } periodic; + + /* 16-bit input edge-count capture mode w/8-bit prescaler */ + + struct + { + } count; + + /* 16-bit input time capture mode w/8-bit prescaler */ + + struct + { + } time; + + /* 16-bit PWM output mode w/8-bit prescaler */ + + struct + { + } pwm; + } u; }; /* This structure describes usage of both timers on a GPTIM module */ -- cgit v1.2.3