Tiva Timer: Partial support for 16- and 32-bit, oneshot and periodic timer configurations

This commit is contained in:
Gregory Nutt 2015-01-08 13:44:10 -06:00
parent 58818e1afd
commit 09bd382697
3 changed files with 134 additions and 77 deletions

View File

@ -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) */
/* GPTM Timer A/B Mode (TAMR and TBMR) */
#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 */
#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_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 */
# 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_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 */
# 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) */

View File

@ -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).
*/

View File

@ -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 */