Shop OBEX P1 Docs P2 Docs Learn Events
I/O Pins and Indexing — Parallax Forums

I/O Pins and Indexing

PJAllenPJAllen BannedPosts: 5,065
edited 2009-02-10 12:55 in General Discussion
COUNT, PULSIN, and the like require the specification of a Pin (e.g. RB.4, RC.0).· Can I base that on a VARiable?·

Hz·VAR RB.4 isn't what I'm after.

More like --

FOR idx = 0 TO 3
··PULSIN RB.idx,...·· ' RB.0, RB.1, RB.2, RB.3
· NEXT idx

Comments

  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-02-07 06:16
    No, you can't use a variable pin in SX/B functions -- you'd have to create a custom function.
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-02-07 06:36
    Here's a function (off the top of my head) that approximates the BS2 PULSIN fucntion for a high-going pulse. If you look at the list file for the SX/B PULSIN function you'll see that it's quite involved.

    ' Use: result = PULSE_IN pin
    ' -- pin is 0 (RB.0) to 15 (RC.7)
    ' -- measures in 10us units
    
    FUNC PULSE_IN
      piPin         VAR     tmpB1
      piMask        VAR     tmpW1
      piWork        VAR     tmpW2
      piResult      VAR     tmpW3
    
      piPin = __PARAM1
      piMask = %1 << piPin
    
    Wait_Clear:
      piResult = 0
      DO
        INC piResult
        IF piResult = 0 THEN PI_Exit                ' overflow
        piWork = RBC & piMask                       ' scan pin
        IF piWork = 0 THEN EXIT
        DELAY_US 2
      LOOP
    
    Wait_For_High:
      piResult = 0
      DO
        INC piResult
        IF piResult = 0 THEN PI_Exit
        piWork = RBC & piMask
        IF piWork > 0 THEN EXIT
        DELAY_US 2
      LOOP
    
    Measure_Pulse:
      piResult = 0
      DO
        INC piResult
        IF piResult = 0 THEN PI_Exit
        piWork = RBC & piMask
        IF piWork = 0 THEN EXIT
        DELAY_US 2
      LOOP
    
    PI_Exit:
      RETURN piResult
      ENDFUNC
    
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2009-02-07 14:19
    OK.
    I was figuring there must be a way to rifle through the hardware pins as part of a FOR...NEXT, instead of writing a line for each which takes up a lot of program space.· Not just for PULSIN, but for COUNT and others requiring a Pin.

    It's not like I was planning on "Plan B", but, on to "Plan B" (custom functions.)
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-02-07 18:51
    PJ Allen,

    Attached is my library PortPins that is part of my Dynamic Virtual Peripheral library suite
    that I am currently writing. Ports are encoded in bytes, portpins are encoded in words,
    which allows to perform functions on multiple pins per port (eg. set 3 pins of RB high).
    The routines use assembly to save code and increase speed.
    No variables or locals are required by this library.

    This can be useful if you want to write sxb functions that take custom ports and pins.
    The actual subroutines and functions are in the INC file.
    The Demo file shows how to import the library.

    regards peter
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2009-02-08 01:38
    PV,

    Thanks for your Reply.·
    I shall study the material.
    (Looks like others have been interested, too.)
    -- PJA --
  • David BaylissDavid Bayliss Posts: 58
    edited 2009-02-10 00:10
    Peter V,

    I've had a look at your library; I think this is an excellent idea. I like having the ports enumerated with the pins.

    I was wondering though - have you considered using the @ capability in SX/B2 to alias the ports? ie

    ports var byte(3) @$05

    then you can access using variable indexing ...

    David
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-02-10 01:10
    Hi David,

    That is another possibility. But to find the specific port you then must compare bytes
    or use the IND and FSR register. That requires cycles. The definitions for the
    ports as used are the easiest way to find a specific port without altering fsr and
    using ind. (in assembly: snb dvpPort.0 if not portA). As said, that library is
    part of a suite. I am close to completing the VP library. I can already reveal that it
    acts as the javelin in that you can start and stop virtual peripherals. Each VP
    is split into states that·take exactly 21 cycles. With 6 VP's running
    and including the overhead, the isr takes 196 cycles every time. Lower
    the number of VP's and you gain 21 cycles per dropped VP. This allows
    to combine VP's with TASKS.

    regards peter
  • David BaylissDavid Bayliss Posts: 58
    edited 2009-02-10 02:25
    Well, obviously you understand this way better than I. But purely in terms of cycles I think the index comes out one ahead on the port read for SX28 (doesn't the skip still cost you the cycle of the skipped instruction?). It would win by more on the SX48. However, as you point out, it does clobber FSR.
    Actually SX/B2 is missing a trick with the @·on the var instruction (this array doesn't require the bank-reset) - without that the lead would be a little greater

    ReadPort:······················· ;FUNC ReadPort
    · MOV W,#ports·················· ;· return Ports(__PARAM1)
    · ADD W,__PARAM1···············
    · MOV FSR,W····················
    · MOV __PARAM1,IND·············
    · BANK $00·····················
    · RETP·························
    ································ ;· endfunc

    dvpPortRead:···················· ;FUNC dvpPortRead
    · ; ASM························· ;· asm
    ·snb·__param1.0················
    ·mov·w,ra······················
    ·snb·__param1.1················
    ·mov·w,rb······················
    ·snb·__param1.2················
    ·mov·w,rc······················
    · ; ENDASM······················ ;· endasm
    · MOV __PARAM1,W················ ;· __param1 = w
    · RETP·························· ;· return __param1
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-02-10 12:55
    David,

    You are right it takes less cycles, but only if fsr may be destroyed.
    In my interrupt code, the code can run for more than 1 bank so I
    would need to save fsr in a global register. For the sx48 with STACK in use,
    there are ZERO free global ram bytes, so using a global ram means first
    saving it (and restoring afterwards) which adds even more cycles.
    The isr code I have now does not use any global ram byte.

    You can easily convert an index based value

    for portindex=0 to 4
    · __param1 = 1 << portindex
    · dvpPinWrite __param1,$FF,$00 'make all pin latches low
    next


    regards peter
    ·
Sign In or Register to comment.