Read an input fast (Atmel Cortex M0: D11/D10/D09/D21/etc)

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

Simple. How do I read a pin in the most efficient way? I don't want to use a mask. 

 

This question is similar to https://www.avrfreaks.net/forum/s....

 

I know, this question is ridiculous! But I did not find any answers. If there is some other way to find such info, I'm all ears.

 

The LED toggle examples in Studio 7 supposedly use a button to toggle the LED, the descriptions say so. But in actuality they toggle the LED from SysTick.

 

There must be some other example that reads a pin, but Atmel does not like Google (nor any of its users).

This topic has a solution.

Last Edited: Thu. Nov 19, 2015 - 05:19 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

The usual way is to read the gpio pin register then mask for the bit of interest. If this is not fast enough, how fast do you want it?

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

You must be right. The special pin registers are restricted to Set/Reset/Toggle, with bits representing pins. So that makes it obvious for an input to need bit masking. So this was the wrong question. Thanks Kartman.

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

One of the "interesting" things about ARM CM0 is that the usual bitmask operations are missing or slow.  (No "and immediate" instruction, no "bit test" instruction, no "skip if bit in register set" instructions.   There is a regular AND instruction, but that requires moving the mask into a register first - at least one extra instruction and register.

However... CM0 *does* have a barrel shifter, and can shift a register up to 32bits in a single instruction.   So for single bit tests, what you apparently want to do is read the port, shift the bit-to-be-tested up into the sign bit, and use the "branch if minus" (BM) to go where you want.  (gcc does this for you give a typical "if (d&mask)" statement.   Or I wouldn't have noticed...)

 

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

Interesting. All in all 3 instructions (3 cycles) for a single pin (or bit) test (regardless of its origin, memory or register). If I remember correctly an AVR does the same (just for a pin) in one cycle (skip instruction on pin). So an AVR is actually a tad faster!

 

But given the choice I too would prefer the barrel shifter.

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

I dunno.  The single-instruction AVR skip instruction isn't very general, and it takes from one to three cycles.  Let's say two instructions (4 bytes) and 2-3 cycles for

   sbis port, bit  ;; two cycles if it skips
     rjmp nottrue  ;; two cycles always
     ;;; code to execute if bit is set
nottrue:

The similar code for CM0 would be 4 instructions (12 bytes) (4 to 6 cycles, not counting possible multi-cycle access to IO bus.):

    ld r1,PORTADDRESS   ;; pc-relative load of 32bit constant (6 bytes!)
    ld r2, [r1]         ;; port contents
    lsl r2, #(32-bit)   ;; shift
    bm nottrue
      ;;; code to execute if bit is set
nottrue: