Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Simultaneous Outport Ports?


  • Please log in to reply
10 replies to this topic

#1 fluke

fluke

    New Member

  • Members
  • Pip
  • 9 posts

Posted 24 February 2011 - 04:03 PM

Is there a command that makes it possible to simultaneously access multiple output ports? I need to send a clock signal off 2 Output ports and I'd like for them to both go high and low at exactly the same time: ie: static OutputPort port1= new OutputPort(Pins.GPIO_PIN_A1, false); static OutputPort port2= new OutputPort(Pins.GPIO_PIN_A3, false); port1.Write(true); port2.Write(true); Thread.Sleep(1000); port1.Write(false); port2.Write(false); This currently results in a ~50us lag between pulses. Is there a way to eliminate/ reduce that difference?

#2 Fred

Fred

    Advanced Member

  • Members
  • PipPipPip
  • 302 posts
  • LocationUK

Posted 24 February 2011 - 04:16 PM

If you're after exact timing I'd be tempted to do this in hardware. I'm assuming that they aren't *always* exactly the same - otherwise you'd just use the same signal. Could you use something like an OR gate to combine the outputs? e.g. To use Pin A2 to force both outputs high: create a third OutputPort, add an OR gate to pins A1 and A2 and use this as one output, add an OR gate to pins A3 and A2 and use this as the second output.

#3 Luke Cummings

Luke Cummings

    Advanced Member

  • Members
  • PipPipPip
  • 38 posts
  • LocationCalgary, AB

Posted 24 February 2011 - 06:22 PM

Sounds like your problem is a hardware related issue, can you be more specific as to what you are trying to do? Currently your saying these two pins will always have the same value. If so just use one pin.
Cheap, Fast, Good... Pick two

#4 Dan Morphis

Dan Morphis

    Advanced Member

  • Members
  • PipPipPip
  • 188 posts

Posted 24 February 2011 - 07:58 PM

This currently results in a ~50us lag between pulses. Is there a way to eliminate/ reduce that difference?


What about using the Fluent Interop stuff? That can reduce the lag your seeing. I'm honestly not sure how much though.

-dan

#5 phantomtypist

phantomtypist

    Advanced Member

  • Members
  • PipPipPip
  • 142 posts
  • LocationNew York, NY

Posted 24 February 2011 - 08:58 PM

Honestly, if both pins are supposed to generate the same clock at the same time simultaneously, why do you need to pins? Just use one pin to generate the clock and have whatever items are using that clock read from the same pin/wire. Unless you provide more information about the project/setup like Luke Cummings said, I'm not sure we'd be able to accurately answer your question.

#6 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 25 February 2011 - 02:08 AM

Hi fluke, If you absolutely need two pins to raise/lower at the exact same time, the only way to do that (even in assembly code) is by using shift registers. Basically, you'd set the state of a whole set of 32 pins at once (all the port A pins or all the port B pins). You can probably do this with Corey's Fluent interop...or using native code. Or using an I2C/SPI GPIO extender which can write multiple pins simultaneously. Chris

#7 fluke

fluke

    New Member

  • Members
  • Pip
  • 9 posts

Posted 25 February 2011 - 02:27 PM

Thanks for all the help everyone. For those that are curious, I'm controlling two different camera shutters through a custom trigger card and need two separate outputs to allow for operation of one or the other or both. It's not absolutely critical for me to eliminate the 50us delay, but there's no harm in trying!

#8 Corey Kosak

Corey Kosak

    Advanced Member

  • Members
  • PipPipPip
  • 276 posts
  • LocationHoboken, NJ

Posted 26 February 2011 - 06:45 PM

It's not absolutely critical for me to eliminate the 50us delay, but there's no harm in trying!

I think I must reluctantly disagree with our esteemed moderator. Doing what you want is quite easy actually.

Inside a given bank, you can:
  • Simultaneously turn on any subset of the 32 pins, or
  • Simultaneously turn off any subset of the 32 pins
It's certainly not the case that you have to set the state of all 32 pins at once. The interpretation of the SODR register is "for each 1 bit in the bit mask, turn on the associated pin (and leave the others alone)". Likewise, the interpretation of the CODR register is "for each 1 bit in the bit mask, turn OFF the associated pin (and leave the others alone)"

I have written some sample code which:
  • turns on (D0,D1) simultaneously
  • turns on (D2,D3) simultaneously (leaving D0,D1 alone)
  • then turns (D2,D3) off
  • then turns (D2,D3) on again
  • and finally turns all four off simultaneously
By the way, it happens that digital pins 0-3 are in the same bank. The pins are in a kind of funny order so the ones you expect to be in the same bank may not be.

Here is the screenshot from Salae: Posted Image

And here is the code, written in Fluent style. It could also be compiled into the firmware, but this was more convenient for me:
using System;
using FluentInterop.CodeGeneration;
using FluentInterop.Expressions;
using FluentInterop.Fluent;
using SecretLabs.NETMF.Hardware.Netduino;

namespace FluentSandbox {
  public class Program {
    public static void Main() {
      var pins=new[] {
        Pins.GPIO_PIN_D0,
        Pins.GPIO_PIN_D1,
        Pins.GPIO_PIN_D2,
        Pins.GPIO_PIN_D3,
      };

      //sanity check
      var firstBank=(int)pins[0]/32;
      foreach(var pin in pins) {
        var thisBank=(int)pin/32;
        if(thisBank!=firstBank) {
          throw new Exception("all pins must be in same bank");
        }
      }

      var code=CodeGenerator.Compile(g=> {
        g.Declare.Function("main", f => {
          var firmware=f.StandardArgs.firmwareParam16;
          var d0=f.Declare.PIOReference("bank0");

          var mask0=f.Declare.Int("mask0");
          var mask1=f.Declare.Int("mask1");
          var mask2=f.Declare.Int("mask2");
          var mask3=f.Declare.Int("mask3");

          //wasteful to write d0 four times, since by definition it will be the same every time,
          //but this is just a demo
          firmware.GetPIOAndBitmask((int)pins[0], ref d0, ref mask0);
          firmware.GetPIOAndBitmask((int)pins[1], ref d0, ref mask1);
          firmware.GetPIOAndBitmask((int)pins[2], ref d0, ref mask2);
          firmware.GetPIOAndBitmask((int)pins[3], ref d0, ref mask3);

          var mask0And1=f.Declare.Int("mask0and1", mask0|mask1);
          var mask2And3=f.Declare.Int("mask2and3", mask2|mask3);
          var allMasks=f.Declare.Int("allMasks", mask0And1|mask2And3);

          d0.PER=allMasks; //enable all 4 pins at once
          d0.CODR=allMasks; //clear all 4 pins at once
          d0.OER=allMasks; //enable output on all 4 pins at once

          d0.SODR=mask0And1; //turn 0 and 1 on

          d0.SODR=mask2And3; //turn 2 and 3 on
          d0.CODR=mask2And3; //turn 2 and 3 off
          d0.SODR=mask2And3; //turn 2 and 3 back on again

          d0.CODR=allMasks; //turn all 4 off
        });
      });

      code.Invoke(0);
    }
  }
}


#9 Corey Kosak

Corey Kosak

    Advanced Member

  • Members
  • PipPipPip
  • 276 posts
  • LocationHoboken, NJ

Posted 26 February 2011 - 06:54 PM

By the way, this is the justification for why I claimed here that the Netduino has the potential for huge throughput if one is using a parallel communication protocol.

#10 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 27 February 2011 - 01:00 AM

Hey Corey, Thanks for clarifying that. You're exactly right. Shifting out all 32 bits on PORTA/PORTB at the same time--using bitmasks--is what I was meaning to say. Thank you for taking the time to say it so much clearer and more accurately :) Chris

#11 Luke Cummings

Luke Cummings

    Advanced Member

  • Members
  • PipPipPip
  • 38 posts
  • LocationCalgary, AB

Posted 27 February 2011 - 07:03 AM

Wow Corey, I just has a "Duh" moment there... I guess some of us hardware guys have been spending a little too much time in .Net! :) Great explaination!
Cheap, Fast, Good... Pick two




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.