Tiva GPTM timers: Implement 16-bit PWM mode

arch/arm/src/tiva/Kconfig:
    Remove EXPERIMENTAL dependency on TIVA_TIMER16_PWM.

arch/arm/src/tiva/common/tiva_timerlib.c:
    Fix wrong 32/16-bit ifdef checks.
    Add tiva_pwm16_sel_event() to choose GPTMCTL.TnEVENT value.
    Implement tiva_pwm_mode16().
    tiva_timer16_setinterval(): Fix wrong check for TIMER16_MODE_ONESHOT
        and TIMER16_MODE_PERIODIC. Was comparing to config->cmn.mode
        which can never have those values. This prevented interrupts being
        enabled. Compare to timer->mode instead.
    Add tiva_timer16pwm_setperiodduty() to set initial period, duty cycle,
        and enable interrupts if requested in GPTM peripheral. Interrupts
        are not enabled in NVIC until tiva_timer16_start() is called.
    Add tiva_timer16pwm_setduty() to update duty cycle at any time.

arch/arm/src/tiva/hardware/lm/lm3s_timer.h,
arch/arm/src/tiva/hardware/lm/lm4f_timer.h,
arch/arm/src/tiva/hardware/tm4c/tm4c123_timer.h,
arch/arm/src/tiva/hardware/tm4c/tm4c129_timer.h:
    Add missing defines; make surrounding defines consistent.

arch/arm/src/tiva/tiva_timer.h:
    Add new TIMER_FLAG_* configuration flags to enable configuring the
    16-bit PWM feature. Extend type of "flags" in tiva_timer32config_s
    and tiva_timer16config_s from 8- to 32-bits to allow more flags.
This commit is contained in:
Nathan Hartman 2019-08-09 11:03:44 -06:00 committed by Gregory Nutt
parent 545cfada38
commit b417ed4b40
7 changed files with 441 additions and 69 deletions

View File

@ -1327,7 +1327,11 @@ config TIVA_TIMER16_TIMECAP
config TIVA_TIMER16_PWM
bool "16-bit PWM output support"
default n
depends on EXPERIMENTAL
---help---
Enables 24-bit PWM mode using a 16-bit half-timer of a
Tiva 16/32-bit General Purpose Timer Module (GPTM) block.
The 24-bit resolution is achieved by using the prescaler
as the high 8 bits.
endif # TIVA_TIMER_16BIT

View File

@ -211,6 +211,11 @@ static int tiva_input_time_mode16(struct tiva_gptmstate_s *priv,
const struct tiva_timer16config_s *timer, int tmndx);
#endif
#ifdef CONFIG_TIVA_TIMER16_PWM
static uint32_t tiva_pwm16_sel_event(struct tiva_gptmstate_s *priv,
const struct tiva_timer16config_s *timer,
int tmndx);
#endif
#ifdef CONFIG_TIVA_TIMER16_PWM
static int tiva_pwm_mode16(struct tiva_gptmstate_s *priv,
const struct tiva_timer16config_s *timer, int tmndx);
@ -1444,6 +1449,79 @@ static int tiva_input_time_mode16(struct tiva_gptmstate_s *priv,
}
#endif
/****************************************************************************
* Name: tiva_pwm16_sel_event
*
* Description:
* Select which event to program into the TnEVENT field in the GPTMCTL
* register based on configured flags. Note that the caller must first
* clear the bit field (using either TIMER_CTL_TAEVENT_MASK or
* TIMER_CTL_TBEVENT_MASK depending on whether Timer A or Timer B is
* used) before writing the value returned by this function.
*
* Input Parameters:
* handle - The handle value returned by tiva_gptm_configure()
* timer - The timer A or B configuration structure. This is located
* within the configuration passed to tiva_gptm_configure().
* tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer
*
* Returned Value:
* Value to be programmed into the TnEVENT field in the GPTMCTL register
* after clearing the bit field as described above.
*
****************************************************************************/
#ifdef CONFIG_TIVA_TIMER16_PWM
static uint32_t tiva_pwm16_sel_event(struct tiva_gptmstate_s *priv,
const struct tiva_timer16config_s *timer,
int tmndx)
{
/* For PWM interrupt edge selection, we can interrupt on positive edge
* (TIMER_CTL_TnEVENT_POS), negative edge (TIMER_CTL_TnEVENT_NEG), or both
* edges (TIMER_CTL_TnEVENT_BOTH). If PWM output is inverted, then edge
* detect interrupt behavior is reversed by the hardware. We will normalize
* this so that higher level logic won't have to.
*/
if (TIMER_ISPWMINTBOTH(timer))
{
/* When interrupting on both edges, it doesn't matter if PWM output
* is inverted.
*/
return tmndx ? TIMER_CTL_TBEVENT_BOTH : TIMER_CTL_TAEVENT_BOTH;
}
if (TIMER_ISPWMINTPOS(timer))
{
if (TIMER_ISPWMINVERT(timer))
{
return tmndx ? TIMER_CTL_TBEVENT_NEG : TIMER_CTL_TAEVENT_NEG;
}
else
{
return tmndx ? TIMER_CTL_TBEVENT_POS : TIMER_CTL_TAEVENT_POS;
}
}
if (TIMER_ISPWMINTNEG(timer))
{
if (TIMER_ISPWMINVERT(timer))
{
return tmndx ? TIMER_CTL_TBEVENT_POS : TIMER_CTL_TAEVENT_POS;
}
else
{
return tmndx ? TIMER_CTL_TBEVENT_NEG : TIMER_CTL_TAEVENT_NEG;
}
}
/* Not interrupting on any edge
*/
return 0;
}
#endif
/****************************************************************************
* Name: tiva_pwm_mode16
*
@ -1468,6 +1546,11 @@ static int tiva_pwm_mode16(struct tiva_gptmstate_s *priv,
const struct tiva_timer16config_s *timer,
int tmndx)
{
unsigned int regoffset;
uint32_t regval;
uint32_t clrbits;
uint32_t setbits;
/* A timer is configured to PWM mode using the following sequence:
*
* 1. Ensure the timer is disabled (the TnEN bit is cleared) before making
@ -1483,26 +1566,60 @@ static int tiva_pwm_mode16(struct tiva_gptmstate_s *priv,
* tiva_gptm_configure() before this function was called.
*
* 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.
* 0x1 (enables PWM), the TnCMR bit to 0x0 (edge count mode), and the
* TnMR field to 0x2 (periodic timer mode).
*/
regoffset = tmndx ? TIVA_TIMER_TBMR_OFFSET : TIVA_TIMER_TAMR_OFFSET;
clrbits = TIMER_TnMR_TnMR_MASK | TIMER_TnMR_TnCMR | TIMER_TnMR_TnAMS;
setbits = TIMER_TnMR_TnMR_PERIODIC | TIMER_TnMR_TnCMR_EDGECOUNT | TIMER_TnMR_TnAMS_PWM;
tiva_modifyreg(priv, regoffset, clrbits, setbits);
/* 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).
regval = tmndx ? TIMER_CTL_TBPWML : TIMER_CTL_TAPWML;
if (TIMER_ISPWMINVERT(timer))
{
tiva_modifyreg(priv, TIVA_TIMER_CTL_OFFSET, 0, regval);
}
else
{
tiva_modifyreg(priv, TIVA_TIMER_CTL_OFFSET, regval, 0);
}
/* 5. If PWM interrupts are used, configure which signal edge(s) trigger
* the interrupt by setting the TnEVENT field in the GPTMCTL register.
* This can be the positive edge (TIMER_CTL_TnEVENT_POS), the negative
* edge (TIMER_CTL_TnEVENT_NEG), or both edges (TIMER_CTL_TnEVENT_BOTH).
* Note that if the PWM output is inverted (see above), then edge detect
* interrupt behavior is reversed. We will normalize this so that higher
* level logic won't have to.
*
* 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.
*/
/* 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.
*/
clrbits = tmndx ? TIMER_CTL_TBEVENT_MASK : TIMER_CTL_TAEVENT_MASK;
setbits = tiva_pwm16_sel_event(priv, timer, tmndx);
tiva_modifyreg(priv, TIVA_TIMER_CTL_OFFSET, clrbits, setbits);
/* 7. Load the timer start value into the GPTM Timer n Interval Load
* (GPTMTnILR) register.
regoffset = tmndx ? TIVA_TIMER_TBMR_OFFSET : TIVA_TIMER_TAMR_OFFSET;
tiva_modifyreg(priv, regoffset, 0, TIMER_TnMR_TnPWMIE);
/* 6. Set PWM period: This is a 24-bit value. Put the high byte (bits 16
* thru 23) in the prescaler register (TIVA_TIMER_TnPR_OFFSET). Put the
* low word (bits 0 through 15) in the interval load register
* (TIVA_TIMER_TnILR_OFFSET).
*
* NOTE: This is done when tiva_timer16pwm_setperiodduty() is called.
* That must be done by other logic, prior to starting the clock running.
*
* The following note was here before implementation of this function
* was written:
*
* REVISIT: When the ALTCLK bit is set in the GPTMCC register to enable
* using the alternate clock source, the synchronization imposes
@ -1521,23 +1638,29 @@ static int tiva_pwm_mode16(struct tiva_gptmstate_s *priv,
* interrupt enabled are: GPTMTAMATCHR = 0x23 GPTMTAILR = 0x46"
*/
/* 8. Load the GPTM Timer n Match (GPTMTnMATCHR) register with the match
* value.
/* 7. Set PWM duty cycle: This is a 24-bit value. Put the high byte (bits
* 16 thru 23) in the prescale match register (TIVA_TIMER_TnPMR_OFFSET).
* Put the low word (bits 0 thru 16) in the match register
* (TIVA_TIMER_TnMATCHR_OFFSET).
*
* NOTE: This is done when tiva_timer16pwm_setperiodduty() is called.
* That must be done by other logic, prior to starting the clock running.
* Once the period and initial duty cycle are set, the duty cycle can
* be changed at any time by calling tiva_timer16pwm_setduty().
*/
#warning Missing Logic
/* 9. Set the TnEN bit in the GPTM Control (GPTMCTL) register to enable
/* 8. 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.
* This is done when tiva_timer16_start() is called.
*
* NOTE: This timer is not started until tiva_gptm_enableclk() is called.
* 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.
*/
return -ENOSYS;
return OK;
}
#endif
@ -1613,8 +1736,8 @@ static int tiva_timer16_configure(struct tiva_gptmstate_s *priv,
#endif
#ifdef CONFIG_TIVA_TIMER16_PWM
case TIMER16_MODE_PWM: /* 16-bit PWM output mode w/8-bit
* prescaler */
case TIMER16_MODE_PWM: /* 24-bit PWM output mode with upper
* 8-bits in prescaler register */
return tiva_pwm_mode16(priv, timer, tmndx);
#endif
@ -1762,7 +1885,7 @@ TIMER_HANDLE tiva_gptm_configure(const struct tiva_gptmconfig_s *config)
/* Wait for the reset to complete */
while (!tiva_gptm_periphrdy());
while (!tiva_gptm_periphrdy(config->gptm));
up_udelay(250);
/* Select the alternate timer clock source is so requested. The general
@ -1921,7 +2044,7 @@ void tiva_gptm_release(TIMER_HANDLE handle)
/* Wait for the reset to complete */
while (!tiva_gptm_periphrdy());
while (!tiva_gptm_periphrdy(config->gptm));
up_udelay(250);
/* Disable power and clocking to the GPTM module */
@ -2497,8 +2620,8 @@ void tiva_timer16_setinterval(TIMER_HANDLE handle, uint16_t interval, int tmndx)
toints = false;
if (timer->handler &&
(config->cmn.mode == TIMER16_MODE_ONESHOT ||
config->cmn.mode == TIMER16_MODE_PERIODIC))
(timer->mode == TIMER16_MODE_ONESHOT ||
timer->mode == TIMER16_MODE_PERIODIC))
{
toints = true;
}
@ -3068,3 +3191,173 @@ void tiva_timer16_relmatch(TIMER_HANDLE handle, uint32_t relmatch, int tmndx)
#endif
}
#endif
/****************************************************************************
* Name: tiva_timer16pwm_setperiodduty
*
* Description:
* Set the period and initial duty cycle for a 16-bit timer operating in
* PWM mode. Also, enable interrupts if a handler is provided. The timer
* is not started until tiva_timer16_start() is called.
*
* Input Parameters:
* handle - The handle value returned by tiva_gptm_configure()
* period - The PWM period, a 24-bit value.
* duty - The initial PWM duty cycle, a 24-bit value.
* tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer
*
* Returned Value:
* None.
*
****************************************************************************/
#ifdef CONFIG_TIVA_TIMER16_PWM
void tiva_timer16pwm_setperiodduty(TIMER_HANDLE handle, uint32_t period,
uint32_t duty, int tmndx)
{
struct tiva_gptmstate_s *priv = (struct tiva_gptmstate_s *)handle;
const struct tiva_gptm16config_s *config;
const struct tiva_timer16config_s *timer;
irqstate_t flags;
uintptr_t base;
bool toints;
uint32_t imr;
uint32_t periodhi;
uint32_t dutyhi;
DEBUGASSERT(priv && priv->attr && priv->config &&
priv->config->mode == TIMER16_MODE &&
(period & 0x00ffffff) && (duty & 0x00ffffff) &&
(unsigned)tmndx < 2);
config = (const struct tiva_gptm16config_s *)priv->config;
timer = &config->config[tmndx];
base = priv->attr->base;
/* Do we need to enable timeout interrupts? Interrupts are only enabled
* if (1) the user has provided a handler, and (2) the timer is
* configured for PWM.
*/
toints = false;
imr = 0;
if (timer->handler && timer->mode == TIMER16_MODE_PWM)
{
toints = true;
}
/* To set PWM period:
* Put high byte (8 bits) in prescaler register.
* Put low word (16 bits) in interval load register.
*
* To set PWM duty cycle:
* Put high byte (8 bits) in prescale match register.
* Put low word (16 bits) in match register.
*/
periodhi = (period >> 16) & 0xff;
period &= 0xffff;
dutyhi = (duty >> 16) & 0xff;
duty &= 0xffff;
/* Make the following atomic */
flags = enter_critical_section();
if (tmndx)
{
putreg32(periodhi, base + TIVA_TIMER_TBPR_OFFSET);
putreg32(period, base + TIVA_TIMER_TBILR_OFFSET);
putreg32(dutyhi, base + TIVA_TIMER_TBPMR_OFFSET);
putreg32(duty, base + TIVA_TIMER_TBMATCHR_OFFSET);
imr |= TIMER_INT_CBE;
}
else
{
putreg32(periodhi, base + TIVA_TIMER_TAPR_OFFSET);
putreg32(period, base + TIVA_TIMER_TAILR_OFFSET);
putreg32(dutyhi, base + TIVA_TIMER_TAPMR_OFFSET);
putreg32(duty, base + TIVA_TIMER_TAMATCHR_OFFSET);
imr |= TIMER_INT_CAE;
}
/* Enable the capture mode event interrupt at the timer peripheral.
* The interrupt will not fire until enabled at the NVIC. That will be
* done when tiva_timer16_start() is called. */
if (toints)
{
priv->imr = imr;
putreg32(priv->imr, base + TIVA_TIMER_IMR_OFFSET);
}
leave_critical_section(flags);
}
#endif
/****************************************************************************
* Name: tiva_timer16pwm_setduty
*
* Description:
* Update the duty cycle for a 16-bit timer operating in PWM mode.
*
* Input Parameters:
* handle - The handle value returned by tiva_gptm_configure()
* duty - The initial PWM duty cycle, a 24-bit value.
* tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer
*
* Returned Value:
* None.
*
****************************************************************************/
#ifdef CONFIG_TIVA_TIMER16_PWM
void tiva_timer16pwm_setduty(TIMER_HANDLE handle, uint32_t duty, int tmndx)
{
struct tiva_gptmstate_s *priv = (struct tiva_gptmstate_s *)handle;
irqstate_t flags;
uintptr_t base;
uintptr_t tnpmr;
uintptr_t tnmatchr;
uint32_t dutyhi;
DEBUGASSERT(priv && priv->attr && priv->config &&
priv->config->mode == TIMER16_MODE &&
(duty & 0x00ffffff) && (unsigned)tmndx < 2);
base = priv->attr->base;
/* To set PWM duty cycle:
* Put high byte (8 bits) in prescale match register.
* Put low word (16 bits) in match register.
*/
if (tmndx)
{
tnpmr = base + TIVA_TIMER_TBPMR_OFFSET;
tnmatchr = base + TIVA_TIMER_TBMATCHR_OFFSET;
}
else
{
tnpmr = base + TIVA_TIMER_TAPMR_OFFSET;
tnmatchr = base + TIVA_TIMER_TAMATCHR_OFFSET;
}
dutyhi = (duty >> 16) & 0xff;
duty &= 0xffff;
/* Make the following atomic */
flags = enter_critical_section();
putreg32(dutyhi, tnpmr);
putreg32(duty, tnmatchr);
leave_critical_section(flags);
}
#endif

View File

@ -262,15 +262,17 @@
/* GPTM Timer A/B Mode (TAMR and TBMR) */
#define TIMER_TnMR_TnMR_SHIFT 0 /* Bits 1-0: Timer A/B Mode */
#define TIMER_TnMR_TnMR_MASK (3 << TIMER_TnMR_TnMR_SHIFT)
#define TIMER_TnMR_TnMR_SHIFT (0) /* Bits 1-0: Timer A/B Mode */
#define TIMER_TnMR_TnMR_MASK (3 << TIMER_TnMR_TnMR_SHIFT) /* Bits 1-0: Timer A/B Mode */
# 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_TnCMR (1 << 2) /* Bit 2: Timer A/B Capture Mode */
#define TIMER_TnMR_TnCMR_SHIFT (2) /* Bit 2: Timer A/B Capture Mode */
#define TIMER_TnMR_TnCMR (1 << TIMER_TnMR_TnCMR_SHIFT) /* Bit 2: Timer A/B Capture Mode */
# define TIMER_TnMR_TnCMR_EDGECOUNT (0 << TIMER_TnMR_TnCMR_SHIFT) /* Edge-Count mode */
# define TIMER_TnMR_TnCMR_EDGETIME (1 << TIMER_TnMR_TnCMR_SHIFT) /* Edge-Time mode */
#define TIMER_TnMR_TnAMS (1 << 3) /* Bit 3: Timer A/B Alternate Mode Select */
#define TIMER_TnMR_TnAMS_SHIFT (3) /* Bit 3: Timer A/B Alternate Mode Select */
#define TIMER_TnMR_TnAMS (1 << TIMER_TnMR_TnAMS_SHIFT) /* Bit 3: Timer A/B Alternate Mode Select */
# define TIMER_TnMR_TnAMS_CAPTURE (0 << TIMER_TnMR_TnAMS_SHIFT) /* Capture mode is enabled */
# define TIMER_TnMR_TnAMS_PWM (1 << TIMER_TnMR_TnAMS_SHIFT) /* PWM mode is enabled */

View File

@ -336,20 +336,23 @@
/* GPTM Timer A/B Mode (TAMR and TBMR) */
#define TIMER_TnMR_TnMR_SHIFT 0 /* Bits 1-0: Timer A/B Mode */
#define TIMER_TnMR_TnMR_SHIFT (0) /* Bits 1-0: Timer A/B 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_TnCMR (1 << 2) /* Bit 2: Timer A/B Capture Mode */
#define TIMER_TnMR_TnCMR_SHIFT (2) /* Bit 2: Timer A/B Capture Mode */
#define TIMER_TnMR_TnCMR (1 << TIMER_TnMR_TnCMR_SHIFT) /* Bit 2: Timer A/B Capture Mode */
# define TIMER_TnMR_TnCMR_EDGECOUNT (0 << TIMER_TnMR_TnCMR_SHIFT) /* Edge-Count mode */
# define TIMER_TnMR_TnCMR_EDGETIME (1 << TIMER_TnMR_TnCMR_SHIFT) /* Edge-Time mode */
#define TIMER_TnMR_TnAMS (1 << 3) /* Bit 3: Timer A/B Alternate Mode Select */
#define TIMER_TnMR_TnAMS_SHIFT (3) /* Bit 3: Timer A/B Alternate Mode Select */
#define TIMER_TnMR_TnAMS (1 << TIMER_TnMR_TnAMS_SHIFT) /* Bit 3: Timer A/B Alternate Mode Select */
# define TIMER_TnMR_TnAMS_CAPTURE (0 << TIMER_TnMR_TnAMS_SHIFT) /* Capture mode is enabled */
# define TIMER_TnMR_TnAMS_PWM (1 << TIMER_TnMR_TnAMS_SHIFT) /* PWM mode is enabled */
#define TIMER_TnMR_TnCDIR (1 << 4) /* Bit 4: Timer A/B Count Direction */
# define TIMER_TnMR_TnCDIR_DOWN (0) /* Timer counts down */
# define TIMER_TnMR_TnCDIR_UP TIMER_TnMR_TnCDIR /* Timer counts up (one-shot/periodic modes) */
#define TIMER_TnMR_TnCDIR_SHIFT (4) /* Bit 4: Timer A/B Count Direction */
#define TIMER_TnMR_TnCDIR (1 << TIMER_TnMR_TnCDIR_SHIFT) /* Bit 4: Timer A/B Count Direction */
# define TIMER_TnMR_TnCDIR_DOWN (0 << TIMER_TnMR_TnCDIR_SHIFT) /* Timer counts down */
# define TIMER_TnMR_TnCDIR_UP (1 << TIMER_TnMR_TnCDIR_SHIFT) /* Timer counts up (one-shot/periodic modes) */
#define TIMER_TnMR_TnMIE (1 << 5) /* Bit 5: Timer A/B Match Interrupt Enable */
#define TIMER_TnMR_TnWOT (1 << 6) /* Bit 6: GPTM Timer A/B Wait-on-Trigger */
#define TIMER_TnMR_TnSNAPS (1 << 7) /* Bit 7: GPTM Timer A/B Snap-Shot Mode */

View File

@ -336,20 +336,23 @@
/* GPTM Timer A/B Mode (TAMR and TBMR) */
#define TIMER_TnMR_TnMR_SHIFT 0 /* Bits 1-0: Timer A/B Mode */
#define TIMER_TnMR_TnMR_SHIFT (0) /* Bits 1-0: Timer A/B 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_TnCMR (1 << 2) /* Bit 2: Timer A/B Capture Mode */
#define TIMER_TnMR_TnCMR_SHIFT (2) /* Bit 2: Timer A/B Capture Mode */
#define TIMER_TnMR_TnCMR (1 << TIMER_TnMR_TnCMR_SHIFT) /* Bit 2: Timer A/B Capture Mode */
# define TIMER_TnMR_TnCMR_EDGECOUNT (0 << TIMER_TnMR_TnCMR_SHIFT) /* Edge-Count mode */
# define TIMER_TnMR_TnCMR_EDGETIME (1 << TIMER_TnMR_TnCMR_SHIFT) /* Edge-Time mode */
#define TIMER_TnMR_TnAMS (1 << 3) /* Bit 3: Timer A/B Alternate Mode Select */
#define TIMER_TnMR_TnAMS_SHIFT (3) /* Bit 3: Timer A/B Alternate Mode Select */
#define TIMER_TnMR_TnAMS (1 << TIMER_TnMR_TnAMS_SHIFT) /* Bit 3: Timer A/B Alternate Mode Select */
# define TIMER_TnMR_TnAMS_CAPTURE (0 << TIMER_TnMR_TnAMS_SHIFT) /* Capture mode is enabled */
# define TIMER_TnMR_TnAMS_PWM (1 << TIMER_TnMR_TnAMS_SHIFT) /* PWM mode is enabled */
#define TIMER_TnMR_TnCDIR (1 << 4) /* Bit 4: Timer A/B Count Direction */
# define TIMER_TnMR_TnCDIR_DOWN (0) /* Timer counts down */
# define TIMER_TnMR_TnCDIR_UP TIMER_TnMR_TnCDIR /* Timer counts up (one-shot/periodic modes) */
#define TIMER_TnMR_TnCDIR_SHIFT (4) /* Bit 4: Timer A/B Count Direction */
#define TIMER_TnMR_TnCDIR (1 << TIMER_TnMR_TnCDIR_SHIFT) /* Bit 4: Timer A/B Count Direction */
# define TIMER_TnMR_TnCDIR_DOWN (0 << TIMER_TnMR_TnCDIR_SHIFT) /* Timer counts down */
# define TIMER_TnMR_TnCDIR_UP (1 << TIMER_TnMR_TnCDIR_SHIFT) /* Timer counts up (one-shot/periodic modes) */
#define TIMER_TnMR_TnMIE (1 << 5) /* Bit 5: Timer A/B Match Interrupt Enable */
#define TIMER_TnMR_TnWOT (1 << 6) /* Bit 6: GPTM Timer A/B Wait-on-Trigger */
#define TIMER_TnMR_TnSNAPS (1 << 7) /* Bit 7: GPTM Timer A/B Snap-Shot Mode */

View File

@ -363,20 +363,23 @@
/* GPTM Timer A/B Mode (TAMR and TBMR) */
#define TIMER_TnMR_TnMR_SHIFT 0 /* Bits 1-0: Timer A/B Mode */
#define TIMER_TnMR_TnMR_SHIFT (0) /* Bits 1-0: Timer A/B 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_TnCMR (1 << 2) /* Bit 2: Timer A/B Capture Mode */
#define TIMER_TnMR_TnCMR_SHIFT (2) /* Bit 2: Timer A/B Capture Mode */
#define TIMER_TnMR_TnCMR (1 << TIMER_TnMR_TnCMR_SHIFT) /* Bit 2: Timer A/B Capture Mode */
# define TIMER_TnMR_TnCMR_EDGECOUNT (0 << TIMER_TnMR_TnCMR_SHIFT) /* Edge-Count mode */
# define TIMER_TnMR_TnCMR_EDGETIME (1 << TIMER_TnMR_TnCMR_SHIFT) /* Edge-Time mode */
#define TIMER_TnMR_TnAMS (1 << 3) /* Bit 3: Timer A/B Alternate Mode Select */
#define TIMER_TnMR_TnAMS_SHIFT (3) /* Bit 3: Timer A/B Alternate Mode Select */
#define TIMER_TnMR_TnAMS (1 << TIMER_TnMR_TnAMS_SHIFT) /* Bit 3: Timer A/B Alternate Mode Select */
# define TIMER_TnMR_TnAMS_CAPTURE (0 << TIMER_TnMR_TnAMS_SHIFT) /* Capture mode is enabled */
# define TIMER_TnMR_TnAMS_PWM (1 << TIMER_TnMR_TnAMS_SHIFT) /* PWM mode is enabled */
#define TIMER_TnMR_TnCDIR (1 << 4) /* Bit 4: Timer A/B Count Direction */
# define TIMER_TnMR_TnCDIR_DOWN (0) /* Timer counts down */
# define TIMER_TnMR_TnCDIR_UP TIMER_TnMR_TnCDIR /* Timer counts up (one-shot/periodic modes) */
#define TIMER_TnMR_TnCDIR_SHIFT (4) /* Bit 4: Timer A/B Count Direction */
#define TIMER_TnMR_TnCDIR (1 << TIMER_TnMR_TnCDIR_SHIFT) /* Bit 4: Timer A/B Count Direction */
# define TIMER_TnMR_TnCDIR_DOWN (0 << TIMER_TnMR_TnCDIR_SHIFT) /* Timer counts down */
# define TIMER_TnMR_TnCDIR_UP (1 << TIMER_TnMR_TnCDIR_SHIFT) /* Timer counts up (one-shot/periodic modes) */
#define TIMER_TnMR_TnMIE (1 << 5) /* Bit 5: Timer A/B Match Interrupt Enable */
#define TIMER_TnMR_TnWOT (1 << 6) /* Bit 6: GPTM Timer A/B Wait-on-Trigger */
#define TIMER_TnMR_TnSNAPS (1 << 7) /* Bit 7: GPTM Timer A/B Snap-Shot Mode */
@ -407,7 +410,7 @@
# define TIMER_CTL_TAEVENT_BOTH (3 << TIMER_CTL_TAEVENT_SHIFT) /* Both edges */
#define TIMER_CTL_RTCEN (1 << 4) /* Bit 4: GPTM RTC Stall Enable */
#define TIMER_CTL_TAOTE (1 << 5) /* Bit 5: GPTM Timer A Output Trigger Enable */
#define TIMER_CTL_TAPWML (1 << 6) /* Bit 6: GPTM Timer A PWM Output Level */
#define TIMER_CTL_TAPWML (1 << 6) /* Bit 6: GPTM Timer A PWM Output Level Inverted */
#define TIMER_CTL_TBEN (1 << 8) /* Bit 8: GPTM Timer B Enable */
#define TIMER_CTL_TBSTALL (1 << 9) /* Bit 9: GPTM Timer B Stall Enable */
#define TIMER_CTL_TBEVENT_SHFIT (10) /* Bits 10-11: GPTM Timer B Event Mode */
@ -416,7 +419,7 @@
# define TIMER_CTL_TBEVENT_NEG (1 << TIMER_CTL_TBEVENT_SHFIT) /* Negative edge */
# define TIMER_CTL_TBEVENT_BOTH (3 << TIMER_CTL_TBEVENT_SHFIT) /* Both edges */
#define TIMER_CTL_TBOTE (1 << 13) /* Bit 13: GPTM Timer B Output Trigger Enable */
#define TIMER_CTL_TBPWML (1 << 14) /* Bit 14: GPTM Timer B PWM Output Level */
#define TIMER_CTL_TBPWML (1 << 14) /* Bit 14: GPTM Timer B PWM Output Level Inverted */
/* GPTM Synchronize (GPTM0 only) */

View File

@ -103,21 +103,29 @@
* c. 32-bit one shot timer
* d. 32-bit periodic timer
* e. 32-bit RTC timer
* f. 16-bit PWM timer
*/
#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_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_FLAG_PWMINVERT (1 << 7) /* Bit 7: Invert PWM signal (f) */
#define TIMER_FLAG_PWMINTPOS (1 << 8) /* Bit 8: Interrupt on PWM positive
* edge (f) */
#define TIMER_FLAG_PWMINTNEG (1 << 9) /* Bit 9: Interrupt on PWM negative
* edge (f) */
#define TIMER_FLAG_STALL (1 << 10) /* Bit 10: Stall timer when CPU paused
* in debug breakpoint (abcdef) */
#define TIMER_ISCOUNTUP(c) ((((c)->flags) & TIMER_FLAG_COUNTUP) != 0)
#define TIMER_ISADCTIMEOUT(c) ((((c)->flags) & TIMER_FLAG_ADCTIMEOUT) != 0)
@ -126,6 +134,12 @@
#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)
#define TIMER_ISPWMINVERT(c) ((((c)->flags) & TIMER_FLAG_PWMINVERT) != 0)
#define TIMER_ISPWMINTPOS(c) ((((c)->flags) & TIMER_FLAG_PWMINTPOS) != 0)
#define TIMER_ISPWMINTNEG(c) ((((c)->flags) & TIMER_FLAG_PWMINTNEG) != 0)
#define TIMER_ISSTALL ((((c)->flags) & TIMER_FLAG_STALL) != 0)
#define TIMER_ISPWMINTBOTH(c) (TIMER_ISPWMINTPOS(c) && TIMER_ISPWMINTNEG(c))
/****************************************************************************
* Public Types
@ -182,7 +196,7 @@ typedef void (*timer32_handler_t)(TIMER_HANDLE handle, void *arg,
struct tiva_timer32config_s
{
uint8_t flags; /* See TIMER_FLAG_* definitions */
uint32_t flags; /* See TIMER_FLAG_* definitions */
timer32_handler_t handler; /* Non-NULL: Interrupts will be enabled
* and forwarded to this function */
void *arg; /* Argument that accompanies the handler
@ -213,8 +227,8 @@ typedef void (*timer16_handler_t)(TIMER_HANDLE handle, void *arg,
struct tiva_timer16config_s
{
uint8_t mode; /* See enum tiva_timermode_e */
uint8_t flags; /* See TIMER_FLAG_* definitions */
uint8_t mode; /* See enum tiva_timer16mode_e */
uint32_t flags; /* See TIMER_FLAG_* definitions */
timer16_handler_t handler; /* Non-NULL: Interrupts will be enabled
* and forwarded to this function */
void *arg; /* Argument that accompanies the handler
@ -247,7 +261,7 @@ struct tiva_gptm32config_s
#endif
/* This structure is cast compatible with struct tiva_gptmconfig_s and
* describes usage of both bit-bit timers A/B on a GPTM module.
* describes usage of both 16-bit half-timers A/B on a GPTM module.
*/
#ifdef CONFIG_TIVA_TIMER_16BIT
@ -794,6 +808,56 @@ void tiva_timer16_relmatch(TIMER_HANDLE handle, uint32_t relmatch, int tmndx);
# define tiva_timer16b_relmatch(h,r) tiva_timer16_relmatch(h,r,TIMER16B)
#endif
/****************************************************************************
* Name: tiva_timer16pwm_setperiodduty
*
* Description:
* Set the period and initial duty cycle for a 16-bit timer operating in
* PWM mode. Also, enable interrupts if a handler is provided. The timer
* is not started until tiva_timer16_start() is called.
*
* Input Parameters:
* handle - The handle value returned by tiva_gptm_configure()
* period - The PWM period, a 24-bit value.
* duty - The initial PWM duty cycle, a 24-bit value.
* tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer
*
* Returned Value:
* None.
*
****************************************************************************/
#ifdef CONFIG_TIVA_TIMER16_PWM
void tiva_timer16pwm_setperiodduty(TIMER_HANDLE handle, uint32_t period,
uint32_t duty, int tmndx);
# define tiva_timer16apwm_setperiodduty(h,p,d) tiva_timer16pwm_setperiodduty(h,p,d,TIMER16A)
# define tiva_timer16bpwm_setperiodduty(h,p,d) tiva_timer16pwm_setperiodduty(h,p,d,TIMER16B)
#endif
/****************************************************************************
* Name: tiva_timer16pwm_setduty
*
* Description:
* Update the duty cycle for a 16-bit timer operating in PWM mode.
*
* Input Parameters:
* handle - The handle value returned by tiva_gptm_configure()
* duty - The initial PWM duty cycle, a 24-bit value.
* tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer
*
* Returned Value:
* None.
*
****************************************************************************/
#ifdef CONFIG_TIVA_TIMER16_PWM
void tiva_timer16pwm_setduty(TIMER_HANDLE handle, uint32_t duty, int tmndx);
# define tiva_timer16apwm_setduty(h,d) tiva_timer16pwm_setduty(h,d,TIMER16A)
# define tiva_timer16bpwm_setduty(h,d) tiva_timer16pwm_setduty(h,d,TIMER16B)
#endif
/****************************************************************************
* Name: tiva_gptm0_synchronize
*