arch/arm/src/sam34/sam4cm_oneshot.c
/****************************************************************************
 * Name: sam_oneshot_cancel
 *
 * Description:
 *   Cancel the oneshot timer and return the time remaining on the timer.
 *
 *   NOTE: This function may execute at a high rate with no timer running (as
 *   when pre-emption is enabled and disabled).
 *
 * Input Parameters:
 *   oneshot Caller allocated instance of the oneshot state structure.  This
 *           structure must have been previously initialized via a call to
 *           sam_oneshot_initialize();
 *   ts      The location in which to return the time remaining on the
 *           oneshot timer.  A time of zero is returned if the timer is
 *           not running.  ts may be zero in which case the time remaining
 *           is not returned.
 *
 * Returned Value:
 *   Zero (OK) is returned on success.  A call to up_timer_cancel() when
 *   the timer is not active should also return success; a negated errno
 *   value is returned on any failure.
 *
 ****************************************************************************/
sam_oneshot_cancel
Description:
Cancel the oneshot timer and return the time remaining on the timer.

This function may execute at a high rate with no timer running (as
when pre-emption is enabled and disabled).

Input Parameters:
oneshot Caller allocated instance of the oneshot state structure.  This
structure must have been previously initialized via a call to
sam_oneshot_initialize();
ts      The location in which to return the time remaining on the
oneshot timer.  A time of zero is returned if the timer is
not running.  ts may be zero in which case the time remaining
is not returned.

Returned Value:
Zero (OK) is returned on success.  A call to up_timer_cancel() when
the timer is not active should also return success; a negated errno
value is returned on any failure.
sam_oneshot_cancel Description : Cancel the oneshot timer and return the time remaining on the timer . This function may execute at a high rate with no timer running ( as when pre - emption is enabled and disabled ) . Input Parameters : oneshot Caller allocated instance of the oneshot state structure . This structure must have been previously initialized via a call to sam_oneshot_initialize () ; ts The location in which to return the time remaining on the oneshot timer . A time of zero is returned if the timer is not running . ts may be zero in which case the time remaining is not returned . Returned Value : Zero ( OK ) is returned on success . A call to up_timer_cancel () when the timer is not active should also return success ; a negated errno value is returned on any failure .
int sam_oneshot_cancel(struct sam_oneshot_s *oneshot, struct timespec *ts)
{
  irqstate_t flags;
  uint64_t usec;
  uint64_t sec;
  uint64_t nsec;
  uint32_t count;
  uint32_t rc;
  flags = irqsave();
  if (!oneshot->running)
    {
      ts->tv_sec  = 0;
      ts->tv_nsec = 0;
      irqrestore(flags);
      return OK;
    }
  tcvdbg("Cancelling...\n");
  count = sam_tc_getcounter(oneshot->tch);
  rc    = sam_tc_getregister(oneshot->tch, TC_REGC);
  sam_tc_attach(oneshot->tch, NULL, NULL, 0);
  sam_tc_stop(oneshot->tch);
  oneshot->running = false;
  oneshot->handler = NULL;
  oneshot->arg     = NULL;
  irqrestore(flags);
  if (ts)
    {
      tcvdbg("rc=%lu count=%lu usec=%lu\n",
             (unsigned long)rc, (unsigned long)count, (unsigned long)usec);
      if (count >= rc)
        {
          ts->tv_sec  = 0;
          ts->tv_nsec = 0;
        }
      else
        {
          usec        = (((uint64_t)(rc - count)) * USEC_PER_SEC) /
                        sam_tc_divfreq(oneshot->tch);
          sec         = usec / USEC_PER_SEC;
          nsec        = ((usec) - (sec * USEC_PER_SEC)) * NSEC_PER_USEC;
          ts->tv_sec  = (time_t)sec;
          ts->tv_nsec = (unsigned long)nsec;
        }
      tcvdbg("remaining (%lu, %lu)\n",
             (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
    }
  return OK;
}
int sam_oneshot_cancel ( struct sam_oneshot_s * oneshot , struct timespec * ts ) { irqstate_t flags ; uint64_t usec ; uint64_t sec ; uint64_t nsec ; uint32_t count ; uint32_t rc ; flags = irqsave ( ) ; if ( ! oneshot -> running ) { ts -> tv_sec = 0 ; ts -> tv_nsec = 0 ; irqrestore ( flags ) ; return OK ; } tcvdbg ( " \n " ) ; count = sam_tc_getcounter ( oneshot -> tch ) ; rc = sam_tc_getregister ( oneshot -> tch , TC_REGC ) ; sam_tc_attach ( oneshot -> tch , NULL , NULL , 0 ) ; sam_tc_stop ( oneshot -> tch ) ; oneshot -> running = false ; oneshot -> handler = NULL ; oneshot -> arg = NULL ; irqrestore ( flags ) ; if ( ts ) { tcvdbg ( " \n " , ( unsigned long ) rc , ( unsigned long ) count , ( unsigned long ) usec ) ; if ( count >= rc ) { ts -> tv_sec = 0 ; ts -> tv_nsec = 0 ; } else { usec = ( ( ( uint64_t ) ( rc - count ) ) * USEC_PER_SEC ) / sam_tc_divfreq ( oneshot -> tch ) ; sec = usec / USEC_PER_SEC ; nsec = ( ( usec ) - ( sec * USEC_PER_SEC ) ) * NSEC_PER_USEC ; ts -> tv_sec = ( time_t ) sec ; ts -> tv_nsec = ( unsigned long ) nsec ; } tcvdbg ( " \n " , ( unsigned long ) ts -> tv_sec , ( unsigned long ) ts -> tv_nsec ) ; } return OK ; }
Name: sam_oneshot_cancel
 Description:
   Cancel the oneshot timer and return the time remaining on the timer.
Name : sam_oneshot_cancel Description : Cancel the oneshot timer and return the time remaining on the timer .
/* Was the timer running? */ /* No.. Just return zero timer remaining and successful cancellation.
       * This function may execute at a high rate with no timer running
       * (as when pre-emption is enabled and disabled).
       */ /* Yes.. Get the timer counter and rc registers and stop the counter.  If
   * the counter expires while we are doing this, the counter clock will be
   * stopped, but the clock will not be disabled.
   *
   * The expected behavior is that the the counter register will freezes at
   * a value equal to the RC register when the timer expires.  The counter
   * should have values between 0 and RC in all other cased.
   *
   * REVISIT:  This does not appear to be the case.
   */ /* Now we can disable the interrupt and stop the timer. */ /* Did the caller provide us with a location to return the time
   * remaining?
   */ /* Yes.. then calculate and return the time remaining on the
       * oneshot timer.
       */ /* REVISIT: I am not certain why the timer counter value sometimes
       * exceeds RC.  Might be a bug, or perhaps the counter does not stop
       * in all cases.
       */ /* No time remaining (?) */ /* The total time remaining is the difference.  Convert the that
           * to units of microseconds.
           *
           *   frequency = ticks / second
           *   seconds   = ticks * frequency
           *   usecs     = (ticks * USEC_PER_SEC) / frequency;
           */ /* Return the time remaining in the correct form */