Example #1
0
void up_timer_initialize(void)
{
#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP
  uint64_t max_delay;
#endif
  int ret;

  /* Initialize the one-shot timer */

  ret = sam_oneshot_initialize(&g_tickless.oneshot,
                               CONFIG_SAM34_TICKLESS_ONESHOT,
                               CONFIG_USEC_PER_TICK);
  if (ret < 0)
    {
      tmrerr("ERROR: sam_oneshot_initialize failed\n");
      PANIC();
    }

  DEBUGASSERT(ONESHOT_INITIALIZED(&g_tickless.oneshot));

#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP
  /* Get the maximum delay of the one-shot timer in microseconds */

  ret = sam_oneshot_max_delay(&g_tickless.oneshot, &max_delay);
  if (ret < 0)
    {
      tmrerr("ERROR: sam_oneshot_max_delay failed\n");
      PANIC();
    }

  /* Convert this to configured clock ticks for use by the OS timer logic */

  max_delay /= CONFIG_USEC_PER_TICK;
  if (max_delay > UINT32_MAX)
    {
      g_oneshot_maxticks = UINT32_MAX;
    }
  else
    {
      g_oneshot_maxticks = max_delay;
    }
#endif

  /* Initialize the free-running timer */

  ret = sam_freerun_initialize(&g_tickless.freerun,
                               CONFIG_SAM34_TICKLESS_FREERUN,
                               CONFIG_USEC_PER_TICK);
  if (ret < 0)
    {
      tmrerr("ERROR: sam_freerun_initialize failed\n");
      PANIC();
    }

  DEBUGASSERT(FREERUN_INITIALIZED(&g_tickless.freerun));
}
Example #2
0
int stm32l4_oneshot_initialize(FAR struct stm32l4_oneshot_s *oneshot,
                               int chan, uint16_t resolution)
{
  uint32_t frequency;

  tmrinfo("chan=%d resolution=%d usec\n", chan, resolution);
  DEBUGASSERT(oneshot && resolution > 0);

  /* Get the TC frequency the corresponds to the requested resolution */

  frequency = USEC_PER_SEC / (uint32_t)resolution;
  oneshot->frequency = frequency;

  oneshot->tch = stm32l4_tim_init(chan);
  if (!oneshot->tch)
    {
      tmrerr("ERROR: Failed to allocate TIM%d\n", chan);
      return -EBUSY;
    }

  STM32L4_TIM_SETCLOCK(oneshot->tch, frequency);

  /* Initialize the remaining fields in the state structure. */

  oneshot->chan       = chan;
  oneshot->running    = false;
  oneshot->handler    = NULL;
  oneshot->arg        = NULL;

  /* Assign a callback handler to the oneshot */

  return stm32l4_allocate_handler(oneshot);
}
Example #3
0
int sam_freerun_initialize(struct sam_freerun_s *freerun, int chan,
                           uint16_t resolution)
{
  uint32_t frequency;
  uint32_t divisor;
  uint32_t cmr;
  int ret;

  tmrinfo("chan=%d resolution=%d usec\n", chan, resolution);
  DEBUGASSERT(freerun && resolution > 0);

  /* Get the TC frequency the corresponds to the requested resolution */

  frequency = USEC_PER_SEC / (uint32_t)resolution;

  /* The pre-calculate values to use when we start the timer */

  ret = sam_tc_divisor(frequency, &divisor, &cmr);
  if (ret < 0)
    {
      tmrerr("ERROR: sam_tc_divisor failed: %d\n", ret);
      return ret;
    }

  tmrinfo("frequency=%lu, divisor=%u, cmr=%08lx\n",
          (unsigned long)frequency, (unsigned long)divisor,
          (unsigned long)cmr);

  /* Allocate the timer/counter and select its mode of operation
   *
   *   CMR_TCCLKS          - Returned by sam_tc_divisor
   *   TC_CMR_CLKI=0       - Not inverted
   *   TC_CMR_BURST_NONE   - Not gated by an external signal
   *   TC_CMR_CPCSTOP=0    - Don't stop the clock on an RC compare event
   *   TC_CMR_CPCDIS=0     - Don't disable the clock on an RC compare event
   *   TC_CMR_EEVTEDG_NONE - No external events (and, hence, no edges
   *   TC_CMR_EEVT_TIOB    - ???? REVISIT
   *   TC_CMR_ENET=0       - External event trigger disabled
   *   TC_CMR_WAVSEL_UP    - TC_CV is incremented from 0 to 0xffffffff
   *   TC_CMR_WAVE         - Waveform mode
   *   TC_CMR_ACPA_NONE    - RA compare has no effect on TIOA
   *   TC_CMR_ACPC_NONE    - RC compare has no effect on TIOA
   *   TC_CMR_AEEVT_NONE   - No external event effect on TIOA
   *   TC_CMR_ASWTRG_NONE  - No software trigger effect on TIOA
   *   TC_CMR_BCPB_NONE    - RB compare has no effect on TIOB
   *   TC_CMR_BCPC_NONE    - RC compare has no effect on TIOB
   *   TC_CMR_BEEVT_NONE   - No external event effect on TIOB
   *   TC_CMR_BSWTRG_NONE  - No software trigger effect on TIOB
   */

  cmr |= (TC_CMR_BURST_NOTGATED | TC_CMR_EEVTEDG_NONE | TC_CMR_EEVT_TIOB   |
          TC_CMR_WAVSEL_UP      | TC_CMR_WAVE         | TC_CMR_ACPA_NONE   |
          TC_CMR_ACPC_NONE      | TC_CMR_AEEVT_NONE   | TC_CMR_ASWTRG_NONE |
          TC_CMR_BCPB_NONE      | TC_CMR_BCPC_NONE    | TC_CMR_BEEVT_NONE  |
          TC_CMR_BSWTRG_NONE);

  freerun->tch = sam_tc_allocate(chan, cmr);
  if (!freerun->tch)
    {
      tmrerr("ERROR: Failed to allocate timer channel %d\n", chan);
      return -EBUSY;
    }

  /* Initialize the remaining fields in the state structure and return
   * success.
   */

  freerun->chan     = chan;
  freerun->running  = false;
  freerun->overflow = 0;

  /* Set up to receive the callback when the counter overflow occurs */

  (void)sam_tc_attach(freerun->tch, sam_freerun_handler, freerun,
                      TC_INT_COVFS);

  /* Start the counter */

  sam_tc_start(freerun->tch);
  return OK;
}
Example #4
0
static int oneshot_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
  FAR struct inode *inode;
  FAR struct oneshot_dev_s *priv;
  int ret;

  tmrinfo("cmd=%d arg=%08lx\n", cmd, (unsigned long)arg);

  DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
  inode = filep->f_inode;
  priv  = (FAR struct oneshot_dev_s *)inode->i_private;
  DEBUGASSERT(priv != NULL);

  /* Get exclusive access to the device structures */

  ret = nxsem_wait(&priv->od_exclsem);
  if (ret < 0)
    {
      return ret;
    }

  /* Handle oneshot timer ioctl commands */

  switch (cmd)
    {
      /* OSIOC_MAXDELAY - Return the maximum delay that can be supported
       *                  by this timer.
       *                  Argument: A referenct to a struct timespec in
       *                  which the maximum time will be returned.
       */

      case OSIOC_MAXDELAY:
        {
          FAR struct timespec *ts = (FAR struct timespec *)((uintptr_t)arg);
          DEBUGASSERT(ts != NULL);

          ret = ONESHOT_MAX_DELAY(priv->od_lower, ts);
        }
        break;

      /* OSIOC_START - Start the oneshot timer
       *               Argument: A reference to struct oneshot_start_s
       */

      case OSIOC_START:
        {
          FAR struct oneshot_start_s *start;
          pid_t pid;

          start = (FAR struct oneshot_start_s *)((uintptr_t)arg);
          DEBUGASSERT(start != NULL);

          /* Save signalling information */

          priv->od_signo = start->signo;
          priv->od_arg   = start->arg;

          pid = start->pid;
          if (pid == 0)
            {
              pid = getpid();
            }

          priv->od_pid = pid;

          /* Start the oneshot timer */

          ret = ONESHOT_START(priv->od_lower, oneshot_callback, priv,
                              &start->ts);
        }
        break;

      /* OSIOC_CANCEL - Stop the timer
       *                Argument: A reference to a struct timespec in
       *                which the time remaining will be returned.
       */

      case OSIOC_CANCEL:
        {
          FAR struct timespec *ts = (FAR struct timespec *)((uintptr_t)arg);

          /* Cancel the oneshot timer */

          ret = ONESHOT_CANCEL(priv->od_lower, ts);
        }
        break;

      /* OSIOC_CURRENT - Get the current time
       *                 Argument: A reference to a struct timespec in
       *                 which the current time will be returned.
       */

      case OSIOC_CURRENT:
        {
          FAR struct timespec *ts = (FAR struct timespec *)((uintptr_t)arg);

          /* Get the current time */

          ret = ONESHOT_CURRENT(priv->od_lower, ts);
        }
        break;

      default:
        {
          tmrerr("ERROR: Unrecognized cmd: %d arg: %ld\n", cmd, arg);
          ret = -ENOTTY;
        }
        break;
    }

  nxsem_post(&priv->od_exclsem);
  return ret;
}
Example #5
0
int sam_oneshot_initialize(struct sam_oneshot_s *oneshot, int chan,
                           uint16_t resolution)
{
  uint32_t frequency;
  uint32_t actual;
  uint32_t cmr;
  int ret;

  tmrinfo("chan=%d resolution=%d usec\n", chan, resolution);
  DEBUGASSERT(oneshot && resolution > 0);

  /* Get the TC frequency the corresponds to the requested resolution */

  frequency = USEC_PER_SEC / (uint32_t)resolution;

  /* The pre-calculate values to use when we start the timer */

  ret = sam_tc_clockselect(frequency, &cmr, &actual);
  if (ret < 0)
    {
      tmrerr("ERROR: sam_tc_clockselect failed: %d\n", ret);
      return ret;
    }

  tmrinfo("frequency=%lu, actual=%lu, cmr=%08lx\n",
          (unsigned long)frequency, (unsigned long)actual,
          (unsigned long)cmr);

  /* Allocate the timer/counter and select its mode of operation
   *
   *   TC_CMR_TCCLKS       - Returned by sam_tc_clockselect
   *   TC_CMR_CLKI=0       - Not inverted
   *   TC_CMR_BURST_NONE   - Not gated by an external signal
   *   TC_CMR_CPCSTOP=1    - Stop the clock on an RC compare event
   *   TC_CMR_CPCDIS=0     - Don't disable the clock on an RC compare event
   *   TC_CMR_EEVTEDG_NONE - No external events (and, hence, no edges
   *   TC_CMR_EEVT_TIOB    - ???? REVISIT
   *   TC_CMR_ENET=0       - External event trigger disabled
   *   TC_CMR_WAVSEL_UPRC  - TC_CV is incremented from 0 to the value of RC,
   *                         then automatically reset on a RC Compare
   *   TC_CMR_WAVE         - Waveform mode
   *   TC_CMR_ACPA_NONE    - RA compare has no effect on TIOA
   *   TC_CMR_ACPC_NONE    - RC compare has no effect on TIOA
   *   TC_CMR_AEEVT_NONE   - No external event effect on TIOA
   *   TC_CMR_ASWTRG_NONE  - No software trigger effect on TIOA
   *   TC_CMR_BCPB_NONE    - RB compare has no effect on TIOB
   *   TC_CMR_BCPC_NONE    - RC compare has no effect on TIOB
   *   TC_CMR_BEEVT_NONE   - No external event effect on TIOB
   *   TC_CMR_BSWTRG_NONE  - No software trigger effect on TIOB
   */

  cmr |= (TC_CMR_BURST_NONE  | TC_CMR_CPCSTOP     | TC_CMR_EEVTEDG_NONE  |
          TC_CMR_EEVT_TIOB   | TC_CMR_WAVSEL_UPRC | TC_CMR_WAVE          |
          TC_CMR_ACPA_NONE   | TC_CMR_ACPC_NONE   | TC_CMR_AEEVT_NONE    |
          TC_CMR_ASWTRG_NONE | TC_CMR_BCPB_NONE   | TC_CMR_BCPC_NONE     |
          TC_CMR_BEEVT_NONE  | TC_CMR_BSWTRG_NONE);

  oneshot->tch = sam_tc_allocate(chan, cmr);
  if (!oneshot->tch)
    {
      tmrerr("ERROR: Failed to allocate timer channel %d\n", chan);
      return -EBUSY;
    }

  /* Initialize the remaining fields in the state structure and return
   * success.
   */

  oneshot->chan        = chan;
  oneshot->running     = false;
  oneshot->handler     = NULL;
  oneshot->arg         = NULL;
  oneshot->start_count = 0;
  return OK;
}