Shop OBEX P1 Docs P2 Docs Learn Events
Independent inb and outb — Parallax Forums

Independent inb and outb

pik33pik33 Posts: 2,366
edited 2014-08-14 13:12 in Propeller 1
Maybe sometimes there is better to have input and output ports independent. Having Port B enabled I modified top like this:

---------
-- TOP --
---------

include "altpll.inc";        -- main clock pll, outputs 160MHz
include "tim.inc";            -- clock generator, outputs 80MHz..20KHz cog clock, plus 2x CTRA/CTRB PLL simulator clock
include "dig.inc";            -- digital core of P8X32A

subdesign prop
(
    clock_50        : input;        -- clock input

    inp_resn        : input;        -- reset pin
    
    io        [31..0]    : bidir;        -- i/o pins
    outb    [31..0]    : output;        -- i/o pins
    inb   [31..0]  : input;
    dirb  [31..0]  : output;

    ledg    [7..0]    : output;        -- cog leds
    
    clkpll : output;
    clkcog : output;
)

variable

    pll                : altpll with (
                        pll_type = "enhanced",
                        operation_mode = "normal",
                        inclk0_input_frequency = 20000,        -- 20000ps = 50MHz
                        clk0_multiply_by = 24,
                        clk0_divide_by = 5);

    clkgen            : tim;

    core            : dig;

    nres            : dffe;

    pin        [31..0]    : tri;

begin

    -- clocks

    pll.inclk[]        = (gnd, clock_50);

    clkgen.clk        = pll.clk[0];
    clkgen.res        = !inp_resn;
    clkgen.cfg[]    = core.cfg[6..0];

    core.clk_pll    = clkgen.clk_pll;
    core.clk_cog    = clkgen.clk_cog;
   clkpll = clkgen.clk_pll;
    clkcog = clkgen.clk_cog;

    -- reset

    nres.clk        = clkgen.clk_cog;
    nres.d            = inp_resn & !core.cfg[7];

    core.nres        = nres.q;


    -- pins

    core.pin_in[]    = io[];
    core.pin_inb[]    = inb[];

    pin[].in        = core.pin_out[];
    pin[].oe        = core.pin_dir[];
    outb[]        = core.pin_outb[];
    dirb[]        = core.pin_dirb[];

    io[]            = pin[].out;


    -- cog leds

    ledg[]            = core.cog_led[];

end;


Then I connected inb to SWs, outb to LEDRs and run this in spin:
pub start

dirb:=$FFFFFFFF
repeat
  outb:=inb


Then, when sw[x] is on, led[x] glows. Not possible with bidir pins.And still, if I want a bidir pin on port B I can have it by simply adding a tristate buffer using inb[x], outb[x] and dirb[x].

Comments

  • jmgjmg Posts: 15,173
    edited 2014-08-14 13:12
    pik33 wrote: »
    Maybe sometimes there is better to have input and output ports independent. Having Port B enabled I modified top like this:

    Interesting idea, and makes sense on FPGA targets which tend to have shiploads of unused pins.
    You could expand this some more, to avoid constraints of IP only.

    Some uC split the OUTB, so write goes to the pins, and simple read gets the pin state.
    This slight variance allows 32 io lines to map to one register.

    The same rule can apply to INB, a write to that, can go to another 32 op register..

    If you also want DataDir control of > 2 ports, then a double-write might be possible.
    It's a little clunky, but preserves register space - the rule is a second write to the same address, goes to another destination. To reach that second location requires always write of two longs, so those pins are the set-and-forget types.
    Using these expansion rules, a default part might have 64io, but an extended one can have 128io, or if they are not bi-dir, they can reach to 128o and 128i, which is getting up to the FPGA useful limits.
Sign In or Register to comment.