Shop OBEX P1 Docs P2 Docs Learn Events
Parallel pin read in PASM2 — Parallax Forums

Parallel pin read in PASM2

ke4pjwke4pjw Posts: 1,079
edited 2022-01-20 06:18 in PASM2/Spin2 (P2)

So, I am having a bit of "writer's block" / procrastination with writing my first block of inline PASM2. I am not sure if I want to use smart pins to manipulate a series of byte reads from the parallel bus on the W6100 or just do it the old fashioned way, with INA. I looked to some code I wrote 10 years ago, a modification of the FullDuplexSerial I called FullDuplexParallel.

' Receive
receive                 jmpret  rxcode,txcode         'run chunk of tx code, then return

                        test    rxmask,ina      wz     ' Is RXF# low? Set Z flag if it is
        if_nz           jmp     #receive               ' If Z not set, jump to receive label

                        xor     outa, rdmask          ' Set RD# low

                        mov     rxdata, ina           ' Read pins set for input
                        or      outa, rdmask          ' Set RD# high

                        shr     rxdata, datapin       ' Shift data so that the LSB corisponds with D0

                                                      ' Save received byte and inc head
                        rdlong  t2,par                ' Assign the value of rx_head to t2
                        add     t2,rxbuff             ' Increment t2 by the address location of rxbuff
                        wrbyte  rxdata,t2             ' Write byte from the rxdata into the address located at t2's value (rx_head + rxbuff)
                        sub     t2,rxbuff             ' Decrement t2 by the address location of rxbuff
                                                      ' Increment rx_head
                        add     t2,#1                 ' Increment t2 by 1 bit (same as rx_head + 1)
                        and     t2,#$FF               ' Perform AND operation on t2's value with $FF (if > $FF then rollerover)
                        wrlong  t2,par                ' Write long value of t2 in to the address location of par
                        jmp     #receive              ' byte done, receive next byte
'

How would you handle that when it is INB, 8 pins at pins 32+? Maybe have a value at setup that checks the pin mask and sets a variable with $01FE for P31..P0 or $01FE for P63..P32 and mov from the variable?

Or is the old way dumb, and I should use smart pins?

I am stuck and can't start :) I hate feeling like this, LOL.

Thanks,
Terry

Comments

  • evanhevanh Posts: 15,187

    Your existing code is certainly an option. It could probably be optimised but it'll go faster just by the higher internal clock frequency available.

    Smartpins won't help you with data over parallel pins. They are primarily for single pin functions.

    A streamer likes to do parallel data though. So that's an option if you're keen for some mental gymnastics. There is no hardware synchronising so it's up to the software to coordinate between bit-bashing, or maybe a smartpin, and triggering the DMA at the right time.

  • JonnyMacJonnyMac Posts: 8,923
    edited 2022-01-15 05:17

    How would you handle that when it is INB...

    Maybe something like this (based on interpreter pinread() code).

    pub read8(base) : bits
    
      org
                    testb     base, #5                      wc      ' read ina or inb
        if_nc       mov       bits, ina
        if_c        mov       bits, inb
                    and       base, #$1F                            ' remove bank bit
                    shr       bits, base                            ' align pin to lsb
                    and       bits, #$FF                            ' trim to 8 bits
      end
    

    This doesn't allow reading across the ina/inb boundary.

  • If your pins are always on a multiple of 8, you can use getbyte/altgb on the INA/INB ports.

    altgb pingroup,#ina
    getbyte data
    

    will move 8 pins worth of pins into data. Note that pingroup is the base pin divided by 8.

  • evanhevanh Posts: 15,187

    That's so begging to be a macro.

  • Thanks for your examples guys. I had a copy of the PASM2 manual printed and bound so I could thumb through it. I am going to use WRBYTE to get this data into the HUB. Hopefully there will be more documentation on the FIFO and streamer available to mere mortals soon!

    Time for me to just get to the business of making it happen. Hopefully I will see a speed increase!

    Thanks all!

    --Terry

  • ke4pjwke4pjw Posts: 1,079
    edited 2022-01-19 03:36

    @Wuerfel_21 said:
    If your pins are always on a multiple of 8, you can use getbyte/altgb on the INA/INB ports.

    altgb pingroup,#ina
    getbyte data
    

    will move 8 pins worth of pins into data. Note that pingroup is the base pin divided by 8.

    How is pingroup expressed? A 32 bit bitfield of the pins of interest or a value created with ADDPINS?

    Nevermind. Sometimes I am just thick. You already answered that.

  • So, swapping over to PASM made a big improvement for the read. So much so, that it was reading the pins was faster than valid data could arrive, so I had to add a waitx in there after pulling the RD line low. It requires 4 clocks at 100Mhz for the data to be valid, I calculate that as 40ns. So we are at super fast speeds!

    I know there are other places that need improvement in other objects, so I am going to tackle those as well.

    One odd thing that occurred, that I did not expect, was I had to assign a local variable for the pingroup in altgb. I could not use a constant, nor could I use a literal. I used constants for drvl and drvh, such as DRVL ##RDn where RDn was defined as a constant. Not sure if this is a bug or a design choice.

    Another question, is it possible to use altsn for a two bit nibble (a crumb)?

    Thanks!
    Terry

  • evanhevanh Posts: 15,187

    @ke4pjw said:
    One odd thing that occurred, that I did not expect, was I had to assign a local variable for the pingroup in altgb. I could not use a constant, nor could I use a literal. I used constants for drvl and drvh, such as DRVL ##RDn where RDn was defined as a constant. Not sure if this is a bug or a design choice.

    Design choice. Frees up a bit in the instruction encoding. There is very few instructions that have immediate mode D-operand instruction encodings. And the ones that do are either single operand instructions or sacrifice status flag control.

    Another question, is it possible to use altsn for a two bit nibble (a crumb)?

    Nope, there's no two-bit ops like that.

  • evanhevanh Posts: 15,187

    Err, actually, there is quite a lot of instructions that do provide immediate mode D-operand. The compromises are still correct though. Most of them sacrifice control of Z flag.

  • ke4pjwke4pjw Posts: 1,079
    edited 2022-01-20 06:17

    Is the write operation of

       altgb datapin,#ina
        getbyte tmpdata
    

    Like this?

      altsb datapin,#outa
      setbyte LADDRH
    

    Having weird results, as in it hoses video display cog.

  • evanhevanh Posts: 15,187

    A quick squiz at your opening post ... nitpicking I know but the name probably shouldn't be full-duplex, as that implies a dual channel with one going each way concurrently. Half-duplex is a single channel with turnaround for bidirectional comms. Simplex is unidirectional data flow.

  • evanhevanh Posts: 15,187
    edited 2022-01-20 05:01

    @ke4pjw said:
    Is the write operation of

        altgb datapin,#ina
        getbyte tmpdata
    

    this?

    That reads byte data from INA/INB and places it in tmpdata

    The value in datapin is a pin-group number, so a 0 for pins P0-P7, a 1 for P8-P15, and so on up to 7 for P56-P63.

  • @evanh said:
    A quick squiz at your opening post ... nitpicking I know but the name probably shouldn't be full-duplex, as that implies a dual channel with one going each way concurrently. Half-duplex is a single channel with turnaround for bidirectional comms. Simplex is unidirectional data flow.

    That was just a section of the library I wrote for the FT-245. It is full duplex communication to the FT-245 and a modification of FullDuplexSerial.

    https://github.com/parallaxinc/propeller/tree/master/libraries/community/p1/All/FullDuplexParallel

  • evanhevanh Posts: 15,187

    @ke4pjw said:

      altsb datapin,#outa
      setbyte LADDRH
    

    Having weird results, as in it hoses video display cog.

    That's certainly going to write data to OUTA or OUTB. What appears on the pins depends on DIRA/DIRB and datapin as well as the data in LADDRH

  • ke4pjwke4pjw Posts: 1,079
    edited 2022-01-20 06:15

    @evanh said:

    @ke4pjw said:
    Is the write operation of

        altgb datapin,#ina
        getbyte tmpdata
    

    this?

    That reads byte data from INA/INB and places it in tmpdata

    The value in datapin is a pin-group number, so a 0 for pins P0-P7, a 1 for P8-P15, and so on up to 7 for P56-P63.

    Something more like this is what we are looking for? In this case, I want the value in LADDRH written to the datapin group.

      altsb outa,#datapin
      setbyte LADDRH
    
  • ke4pjwke4pjw Posts: 1,079
    edited 2022-01-20 14:20

    Ah, I got it. Had to change the direction from input. Thank you @evanh !

      DIRNOT #DATA
    
      altsb datapin, #outa
    
      setbyte LADDRH
    
  • evanhevanh Posts: 15,187
    edited 2022-01-20 06:01

    Triple back-tick on separate line for posting code blocks. Single back-tick, ', for code strings in a sentence.

  • evanhevanh Posts: 15,187

    @ke4pjw said:

    @evanh said:
    A quick squiz at your opening post ... nitpicking I know but the name probably shouldn't be full-duplex, as that implies a dual channel with one going each way concurrently. Half-duplex is a single channel with turnaround for bidirectional comms. Simplex is unidirectional data flow.

    That was just a section of the library I wrote for the FT-245. It is full duplex communication to the FT-245 and a modification of FullDuplexSerial.

    https://github.com/parallaxinc/propeller/tree/master/libraries/community/p1/All/FullDuplexParallel

    /me goes checks ... "USB to parallel FIFO bidirectional" - Half-duplex then. Often just called a data bus.

  • @evanh said:
    Triple back-tick on separate line for posting code blocks. Single back-tick, ', for code strings in a sentence.

    Ah!!! I would have never figured that out! Kinda miss the old markup. Thank you!

  • @evanh said:

    @ke4pjw said:

    @evanh said:
    A quick squiz at your opening post ... nitpicking I know but the name probably shouldn't be full-duplex, as that implies a dual channel with one going each way concurrently. Half-duplex is a single channel with turnaround for bidirectional comms. Simplex is unidirectional data flow.

    That was just a section of the library I wrote for the FT-245. It is full duplex communication to the FT-245 and a modification of FullDuplexSerial.

    https://github.com/parallaxinc/propeller/tree/master/libraries/community/p1/All/FullDuplexParallel

    /me goes checks ... "USB to parallel FIFO bidirectional" - Half-duplex then. Often just called a data bus.

    You are technically correct. That's the best kind of correct :smiley:

  • evanhevanh Posts: 15,187

    I can't think of a better name now. Calling it HalfDuplexParallel doesn't help anyone. LOL,

Sign In or Register to comment.