diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-05-05 14:35:37 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-05-05 14:35:37 -0600 |
commit | 5bc7fcd3ffc062169be8562afc4d2feaa6425cb0 (patch) | |
tree | ae955b30b00e95103c89d5db2d57b8b08c99d21d /nuttx/arch/arm/src/sam34/sam_tc.c | |
parent | 28817e379f7a93e4c62df2c3f7e06c3729709015 (diff) | |
download | px4-nuttx-5bc7fcd3ffc062169be8562afc4d2feaa6425cb0.tar.gz px4-nuttx-5bc7fcd3ffc062169be8562afc4d2feaa6425cb0.tar.bz2 px4-nuttx-5bc7fcd3ffc062169be8562afc4d2feaa6425cb0.zip |
Add SAM3/4 RTT driver. From Bob Doiron
Diffstat (limited to 'nuttx/arch/arm/src/sam34/sam_tc.c')
-rw-r--r-- | nuttx/arch/arm/src/sam34/sam_tc.c | 47 |
1 files changed, 23 insertions, 24 deletions
diff --git a/nuttx/arch/arm/src/sam34/sam_tc.c b/nuttx/arch/arm/src/sam34/sam_tc.c index 27dbd1642..b955d6bb0 100644 --- a/nuttx/arch/arm/src/sam34/sam_tc.c +++ b/nuttx/arch/arm/src/sam34/sam_tc.c @@ -106,7 +106,6 @@ struct sam34_lowerhalf_s uint32_t clkticks; /* actual clock ticks for current interval */ bool started; /* The timer has been started */ uint16_t periphid; /* peripheral id */ - uint16_t debug; }; /**************************************************************************** @@ -134,7 +133,7 @@ static int sam34_getstatus(FAR struct timer_lowerhalf_s *lower, FAR struct timer_status_s *status); static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower, uint32_t timeout); -static tccb_t sam34_capture(FAR struct timer_lowerhalf_s *lower, +static tccb_t sam34_sethandler(FAR struct timer_lowerhalf_s *lower, tccb_t handler); static int sam34_ioctl(FAR struct timer_lowerhalf_s *lower, int cmd, unsigned long arg); @@ -150,7 +149,7 @@ static const struct timer_ops_s g_tcops = .stop = sam34_stop, .getstatus = sam34_getstatus, .settimeout = sam34_settimeout, - .capture = sam34_capture, + .sethandler = sam34_sethandler, .ioctl = sam34_ioctl, }; @@ -267,15 +266,13 @@ static void sam34_putreg(uint32_t val, uint32_t addr) static int sam34_interrupt(int irq, FAR void *context) { FAR struct sam34_lowerhalf_s *priv = &g_tcdevs[irq-SAM_IRQ_TC0]; - uint16_t regval; tcvdbg("Entry\n"); DEBUGASSERT((irq >= SAM_IRQ_TC0) && (irq <= SAM_IRQ_TC5)); /* Check if the interrupt is really pending */ - regval = sam34_getreg(priv->base + SAM_TC_SR_OFFSET); - if ((regval & TC_INT_CPCS) != 0) + if ((sam34_getreg(priv->base + SAM_TC_SR_OFFSET) & TC_INT_CPCS) != 0) { uint32_t timeout; @@ -283,7 +280,7 @@ static int sam34_interrupt(int irq, FAR void *context) if (priv->handler && priv->handler(&priv->timeout)) { - /* Calculate new ticks */ + /* Calculate new ticks / dither adjustment */ priv->clkticks = ((uint64_t)(priv->adjustment + priv->timeout))*TC_FCLK / 1000000; @@ -323,7 +320,7 @@ static int sam34_interrupt(int irq, FAR void *context) static int sam34_start(FAR struct timer_lowerhalf_s *lower) { FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; - uint32_t mr_val = 0; + uint32_t mr_val; tcvdbg("Entry\n"); DEBUGASSERT(priv); @@ -335,13 +332,14 @@ static int sam34_start(FAR struct timer_lowerhalf_s *lower) sam_enableperiph0(priv->periphid); /* Enable peripheral clock */ sam34_putreg(TC_CCR_CLKDIS, priv->base + SAM_TC_CCR_OFFSET); /* Disable counter */ + sam34_putreg(0, priv->base + SAM_TC_CV_OFFSET); /* clear counter */ /* TC_CMR_WAVE - waveform mode * TC_CMR_WAVSEL_UPAUTO - reset on RC compare (interval timer) * TC_CMR_TCCLKS_TIMERCLOCK5 = SCLK */ - mr_val |= (TC_CMR_WAVE + TC_CMR_WAVSEL_UPAUTO + TC_CMR_TCCLKS_TIMERCLOCK5); + mr_val = (TC_CMR_WAVE + TC_CMR_WAVSEL_UPAUTO + TC_CMR_TCCLKS_TIMERCLOCK5); sam34_putreg(mr_val, priv->base + SAM_TC_CMR_OFFSET); sam34_putreg(priv->clkticks, priv->base + SAM_TC_RC_OFFSET); /* Set interval */ @@ -381,7 +379,7 @@ static int sam34_stop(FAR struct timer_lowerhalf_s *lower) tcvdbg("Entry\n"); DEBUGASSERT(priv); - if(!priv->started) + if (!priv->started) { return -EINVAL; } @@ -430,7 +428,7 @@ static int sam34_getstatus(FAR struct timer_lowerhalf_s *lower, if (priv->handler) { - status->flags |= TCFLAGS_CAPTURE; + status->flags |= TCFLAGS_HANDLER; } /* Return the actual timeout is milliseconds */ @@ -440,7 +438,7 @@ static int sam34_getstatus(FAR struct timer_lowerhalf_s *lower, /* Get the time remaining until the timer expires (in microseconds) */ elapsed = sam34_getreg(priv->base + SAM_TC_CV_OFFSET); - status->timeleft = (priv->timeout * elapsed) / (priv->clkticks + 1); /* TODO - check on this +1 */ + status->timeleft = ((uint64_t)priv->timeout * elapsed) / (priv->clkticks + 1); /* TODO - check on this +1 */ tcvdbg(" flags : %08x\n", status->flags); tcvdbg(" timeout : %d\n", status->timeout); @@ -470,6 +468,12 @@ static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower, FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; DEBUGASSERT(priv); + + if (priv->started) + { + return -EPERM; + } + tcvdbg("Entry: timeout=%d\n", timeout); /* Can this timeout be represented? */ @@ -486,21 +490,17 @@ static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower, timeout = (1000000ULL * priv->clkticks) / TC_FCLK; /* Truncated timeout */ priv->adjustment = priv->timeout - timeout; /* Truncated time to be added to next interval (dither) */ - tcvdbg("fwdt=%d reload=%d timout=%d, adjustment=%d\n", - TC_FCLK, reload, priv->timeout, priv->adjustment); - - /* Don't commit to MR register until started! */ + tcvdbg("fclk=%d clkticks=%d timout=%d, adjustment=%d\n", + TC_FCLK, priv->clkticks, priv->timeout, priv->adjustment); return OK; } /**************************************************************************** - * Name: sam34_capture + * Name: sam34_sethandler * * Description: - * Don't reset on timer timeout; instead, call this user provider - * timeout handler. NOTE: Providing handler==NULL will restore the reset - * behavior. + * Call this user provided timeout handler. * * Input Parameters: * lower - A pointer the publicly visible representation of the "lower-half" @@ -511,13 +511,12 @@ static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower, * * Returned Values: * The previous timer expiration function pointer or NULL is there was - * no previous function pointer, i.e., if the previous behavior was - * reset-on-expiration (NULL is also returned if an error occurs). + * no previous function pointer. * ****************************************************************************/ -static tccb_t sam34_capture(FAR struct timer_lowerhalf_s *lower, - tccb_t handler) +static tccb_t sam34_sethandler(FAR struct timer_lowerhalf_s *lower, + tccb_t handler) { FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; irqstate_t flags; |