SAMB11 delay

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does anybody know how to implement delay function for SAMB11?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

pretty much the same way you'd implement it on any other processor.

 

eg, http://asf.atmel.com/docs/latest/samd11/html/group__group__common__services__delay.html

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yeah.. great, but there is no ASF clock component for SAMB11

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SamB11 has Systick.  Maybe you can use it like the Getting Started Application for the SamD21.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jstampfl wrote:
SamB11 has Systick

That's a standard feature of all Cortex-M !

And, as the name suggests, it is specifically intended for providing a System timing Tick ...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've been playing with this.  A square wave from an Arduino Due isn't quite as rock-solid as I'd like, but I'm not sure whether that's a bug somewhere, or just expected glitchyness due to other interrupts; needs more testing, and more documentation...

#define debug(a)
#define GET_SYSTICK SysTick->VAL;
/*
 * Delay for N cycles, using sysTick Timer.
 * Systick must be running.  count should be significantly less than the LOAD value,
 * so this is probably good for 100 cycles < delay < 100us (or less) with a 1ms systick interrupt.

 * (likewise, obviously not accurate to 1 cycle.  Probably accurate to within ~20 cycles, except for interrupts.)

 *   eeeeeE--------SeeeeeeeeeeeeeeeeeeR   (no wrap)
 *   --SeeeeeeeeeeeeeeeeeeeeeeeeeE----R   (wrap - end time E > start time S)
 */
void sysTickDelay (uint32_t count)
{
  uint32_t reload = SysTick->LOAD;
  int32_t start, end, now;

  debug("get start >");
  start = GET_SYSTICK;
  end = start - count;
  if (end > 0) {
    while (1) {
      now = GET_SYSTICK;
      if ((now <= end) || (now > start))
        return;
    }
  } else {
    end += reload;  // wrap the end time
    while (1) {
      now = GET_SYSTICK;
      if ((now <= end) && (now > start))
        return;
    }
  }
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've been playing with this. [code followed]

In retrospect, that seems more obscure than is worthwhile.  The following bit of code is more straightforward and significantly smaller, even though the inner loops is a bit slower, and it ends up using more registers.  It seems to take about 500ns with 0 as the delay count, on an 84MHz SAM3X8E (Arduino Due clone.)  That's a bit depressing; I guess the flash lookahead doesn't work so well for such tiny loops, and ... all those wait states.

 

void sysTickDelay2 (uint32_t count)
{
  int32_t start, elapsed, reload;

  start = GET_SYSTICK;
  reload = SysTick->LOAD;
  while (1) {
    elapsed = start - SysTick->VAL;
    if (elapsed < 0)
      elapsed += reload;  // Handle wrap.
    if (elapsed >= count)
      return;
  }
}

 

In theory, this should work on any ARM Cortex that has Systick running, and Systick is an ARM-defined part of the chip, rather than a vendor-dependent peripheral...

 

Last Edited: Fri. Nov 10, 2017 - 05:38 AM