Shop OBEX P1 Docs P2 Docs Learn Events
Using arrays in PASM2? — Parallax Forums

Using arrays in PASM2?

I decided to re-visit my previous attempt at designing a multi-port serial object. It is based on Jon's excellent FullDuplexSerial object (sorry Jon for butchering your code!) and my own ideas of how to implement multiple serial ports. To do this I decided to use several arrays to hold the variables.

  long  num_ports                                               ' total number of open ports (0-7)
  long  rxpins[MAX_PORT]                                        ' rx pin array
  long  txpins[MAX_PORT]                                        ' tx pin array 
  long  rxhub[MAX_PORT]                                         ' cog p_rxbuf - ptr to rxbuf hub address
  long  txhub[MAX_PORT]                                         ' cog p_txbuf - ptr to txbuf hub address
  long  p_rxhd[MAX_PORT]                                        ' cog ptr to rxhead[] hub address start
  long  p_txhd[MAX_PORT]                                        ' cog ptr to txhead[] hub address start
  long  p_txtl[MAX_PORT]                                        ' cog ptr to txtail[] hub address start

  long  rxhead[MAX_PORT]                                        ' rx/tx head and tail arrays
  long  rxtail[MAX_PORT]
  long  txhead[MAX_PORT]                                        '
  long  txtail[MAX_PORT]                                        '

The above are the arrays defined as global VARs in the spin code.

portnum         long      1                                     ' total # ports
rxpin           long      0[MAX_PORT]                                  ' rx pin array
txpin           long      0[MAX_PORT]                                  ' tx pin array
p_rxbuf         long      0[MAX_PORT]                                  ' ptr to rxhub
p_txbuf         long      0[MAX_PORT]                                  ' ptr to txhub
p_rxhead        long      0[MAX_PORT]                                  ' ptr to rxhead
p_txhead        long      0[MAX_PORT]                                  ' ptr to txhead
p_txtail        long      0[MAX_PORT]                                  ' prt to txtail

And above are the variables located in the DAT section of PASM2 (along with a few other working variables).

In the attached SPIN document the AddPort() method initializes the rx/tx smart pins and stores the number of open ports prior to running the start() method to initialize the cog

uart_mgr                                                        ' read hub arrays into cog, get # of open ports
                                                                ' to copy to cog ram
                rdlong    portnum, ptra++                       ' get # of open ports
                setq      #(MAX_PORT*7)                         ' block copy hub variables to cog
                rdlong    rxpin, ptra

uart_main                                                       ' loop through each port, get rx, tx pins
                mov       portctr, #0                           ' initialize portctr = 0

(I cut out the numerous DEBUG statements in the code for clarity - I attached the full code to this thread) Starting out I move the SPIN variables into PASM2, this appears to be working correctly. The portctr based on the number of open ports and used to loop through each port to see if there is anything to receive or transmit.

.loop                                                           ' get offsets for array values
                alts      portctr, #rxpin                       ' add portctr offset to rxpin - rxpin[portctr]
                mov       rxd, 0                                ' copy rxpin to rxd

                alts      portctr, #txpin                       ' add portctr offset to txpin - txpin[portctr]
                mov       txd, 0                                ' copy txpin to txd
                                                                ' rxpin available, jump to rx_serial or tx_serial
                testb     rxd,  #31                     wc      ' rx pin in use? -test for -1 when no pin saved
    if_nc       call      #rx_serial

                testb     txd, #31                      wc      ' tx in use? -test for -1
    if_nc       call      #tx_serial
                                                                ' increment counter to next port. if portctr =
                                                                ' open ports, reset portctr to 0 and loop
                incmod    portctr, portnum              wc      ' check if portctr = open ports
    if_nc       jmp       #.loop                                ' repeat loop for each open port

                jmp       #uart_main

The main loop here gets the rx, tx pins and sees if the smart pin has anything, then jumps to the tx or rx code. It loops through each open port. I am working on the tx_serial code at this point, haven't tested the rx_serial routine yet.

tx_serial       rdpin     t1, txd                       wc      ' check busy flag
    if_c        ret                                             '  abort if busy

                alts      portctr, #p_txhead                    ' get txhead value from hub
                mov       offset, 0                             ' offset = address of txhead[portctr]
                rdlong    t1, offset                            ' t1 = txhead[portctr] in hub memory

                alts      portctr, #p_txtail                    ' get txtail value from hub
                mov       offset1, 0                            ' offset1 = address of txtail[portctr]
                rdlong    t2, offset1                           ' t2 = txtail[portctr] in hub memory

                cmp       t1, t2                        wz      ' byte(s) to tx?
    if_e        ret

                alts      portctr, #p_txbuf                     ' get txbuf[portctr] in hub memory
                mov       t1, 0                                 ' t1 := txhub[portctr]
                add       t1, t2                                ' add tail index
                rdbyte    t3, t1                                ' t3 := txhub[txtail]
                wypin     t3, txd                               ' load into sp uart

                incmod    t2, #(BUF_SIZE-1)                     ' update tail index
    _ret_       wrlong    t2, offset1                           ' write tail index back to hub

Everything up to this point appears to be working right, the correct txpin is being used but I think I'm messing up in the way I'm using the p_txhead pointer array in the cog. I thought that this points back to the hub memory location for the txhead value but the DEBUG values are not what I'm expecting. Monitoring the txpin with a logic analyzer isn't giving me the expected output either. Obviously something is being sent to the tx pin so the tx_serial loop is triggered and I see the start bit on the analyzer but only '1's' are showing up after that.

I'm hoping some of the PASM gurus can see the error of my ways!

Comments

  • evanhevanh Posts: 15,192
    edited 2022-08-12 06:00
    • I doubt you need both VAR and DAT sections for the same globals.

    • ALTx prefixing instructions modify the subsequent instruction's S/D register fields. This primary is for performing variable indirection within cogRAM. The prefixing cannot convert an instruction that accesses cogRAM into one that accesses hubRAM.

    So, instead of this:

                    alts      portctr, #p_txtail                    ' get txtail value from hub
                    mov       offset1, 0                            ' offset1 = address of txtail[portctr]
                    rdlong    t2, offset1                           ' t2 = txtail[portctr] in hub memory
    

    maybe this:

                    loc       ptrb, #p_txtail                    ' get txtail value from hub
                    rdlong    t2, ptrb[portctr]                  ' t2 = txtail[portctr] in hub memory
    

    PS: I haven't actually used the hubRAM indexing feature myself. It requires using either PTRA or PTRB. It is limited to 32 positive indexes (0..31). Sadly there is also another negative 32 indexes that no-one is ever likely to use.

  • @evanh said:
    - I doubt you need both VAR and DAT sections for the same globals.

    • ALTx prefixing instructions modify the subsequent instruction's S/D register fields. This primary is for performing variable indirection within cogRAM. The prefixing cannot convert an instruction that accesses cogRAM into one that accesses hubRAM.

    So, instead of this:

                    alts      portctr, #p_txtail                    ' get txtail value from hub
                    mov       offset1, 0                            ' offset1 = address of txtail[portctr]
                    rdlong    t2, offset1                           ' t2 = txtail[portctr] in hub memory
    

    maybe this:

                    loc       ptrb, #p_txtail                    ' get txtail value from hub
                    rdlong    t2, ptrb[portctr]                  ' t2 = txtail[portctr] in hub memory
    

    PS: I haven't actually used the hubRAM indexing feature myself. It requires using either PTRA or PTRB. It is limited to 32 positive indexes (0..31). Sadly there is also another negative 32 indexes that no-one is ever likely to use.

    I’m not sure I really understand about not needing the VAR and DAT global? I understood that to use the SETQ and RDLONG for a block copy, the VAR and DAT variables had to be in the same order and size.

    I was using the ALTS command to add the portctr and p_txtail values and put the result in the offset1 variable. I wanted to read the hub array txtail[] value using the pointer. I’m not sure how using ptrb register accomplishes this?

    I didn’t use direct reference to the ptra register like it was used in the FullDuplexSerial.spin2 code because of limitations on reading ptra values which block transferring lots of values to the cog. I thought I might be able to get around that limitation using a series of arrays but haven’t been getting the hoped for results.

    I see that Chip just released the new version of DEBUG using Pnut, I will have to try that out and see if that can help pinpoint the problems I’m having. Just knowing the memory location and values for the arrays would be very helpful to figure out where I am accessing the wrong values.

  • evanhevanh Posts: 15,192
    edited 2022-08-13 02:32

    You're accessing the wrong memory altogether. The ALTS is incapable of referencing hubRAM. #p_txtail is invalid there.

    The VAR/DAT comment was just advise. It looks like double handling.

    EDIT: Actually, the fact you aren't getting a compile error says the value of #p_txtail is not correct. To be safe, we both should have used an @ to ensure it is a hubRAM address. eg:

                    loc       ptrb, #@p_txtail                   ' get txtail value from hub
                    rdlong    t2, ptrb[portctr]                  ' t2 = txtail[portctr] in hub memory
    

    EDIT2: Ah, Smile, even that won't work in Pnut/Proptool's Spin2. Compile time knowledge isn't there. Only can be passed in from runtime Spin2 knowledge. Immediate assignments for hubRAM addresses, like above, aren't an option.

    It's interesting, hubRAM tables with indexed references can be built at compile time because they use relative referencing between themselves. But to actually read such tables you still need a base runtime reference.

  • evanhevanh Posts: 15,192
    edited 2022-08-13 02:50

    [maybe I should read the full source up there :)]

  • Did not know ALTS can’t access hubRAM, I’ll go back and read the instruction description again. Also will check out the LOC instruction.

  • evanhevanh Posts: 15,192

    Okay, I got too excited there. Nothing wrong with the ALTS, it's correctly referencing the array of p_txtail pointers that have been copied into cogRAM by the earlier SETQ+RDLONG.

    I think where you may have gone wrong is those pointers are not to heads and tails of the actual buffers. They seem to be pointers to pointers of the buffers, ie: double indirection. That's a bug in the addport() Spin2 code elsewhere.

  • evanhevanh Posts: 15,192

    Oh, you don't need the offset1 variable at all in there. This should work:

                    alts      portctr, #p_txtail                    ' get txtail value from hub
                    rdlong    t2, 0-0                           ' t2 = txtail[portctr] in hub memory
    
  • @evanh said:
    Oh, you don't need the offset1 variable at all in there. This should work:

                    alts      portctr, #p_txtail                    ' get txtail value from hub
                    rdlong    t2, 0-0                           ' t2 = txtail[portctr] in hub memory
    

    Thanks, I’ll try out this and your other suggestions tomorrow. I tend to initially use a lot of variables just to help keep things straight until I get the code to work. Then I look at optimizing after that.

  • evanhevanh Posts: 15,192

    Um, I've just started compiling your code, removed a lot of the debug() clutter, and it seems to be working. The double indirection isn't what I thought.

    Cog0  INIT $0000_0000 $0000_0000 load
    Cog0  INIT $0000_0404 $0000_0000 load
    Cog0  -------addport--------
    Cog0  num_ports = 0
    Cog0  rxpins = 5
    Cog0  txpins = 6
    Cog0  (&rxbuf) = $112C
    Cog0  (&txbuf) = $122C
    Cog0  rxhub = $112C
    Cog0  txhub = $122C
    Cog0  p_rxhd = $1088
    Cog0  p_txhd = $10C8
    Cog0  p_txtl = $10E8
    Cog0  port_1 = 0
    Cog1  INIT $0000_0DF0 $0000_0FA4 load
    Cog1  txptr: $122C   txbuf[txtail]: 2
    Cog1  txptr: $122D   txbuf[txtail]: 3
    Cog1  txptr: $122E   txbuf[txtail]: 4
    Cog1  txptr: $122F   txbuf[txtail]: 5
    Cog1  txptr: $1230   txbuf[txtail]: 6
    Cog1  txptr: $1231   txbuf[txtail]: 7
    Cog1  txptr: $1232   txbuf[txtail]: 8
    Cog1  txptr: $1233   txbuf[txtail]: 9
    Cog1  txptr: $1234   txbuf[txtail]: 0
    Cog1  txptr: $1235   txbuf[txtail]: 1
    Cog1  txptr: $1236   txbuf[txtail]: 2
    Cog1  txptr: $1237   txbuf[txtail]: 3
    Cog1  txptr: $1238   txbuf[txtail]: 4
    Cog1  txptr: $1239   txbuf[txtail]: 5
    Cog1  txptr: $123A   txbuf[txtail]: 6
    ...
    

    I think the counting sequence starting from 2 is exactly what your tx() routine is sending.

  • evanhevanh Posts: 15,192
    edited 2022-08-14 05:46

    And I'm seeing valid serial data on the pin output too.

  • @evanh said:
    Um, I've just started compiling your code, removed a lot of the debug() clutter, and it seems to be working. The double indirection isn't what I thought.
    I think the counting sequence starting from 2 is exactly what your tx() routine is sending.

    I agree, I did put a lot of DEBUG statements in there during testing! Interesting that you are seeing the correct output and I’m not seeing it on the logic analyzer. Time for more troubleshooting, maybe try out Chip’s single step debugger. What changes did you make to the code so far?

  • evanhevanh Posts: 15,192
    edited 2022-08-14 14:22

    Just the debug()s. Other than the removals, I modified one for that print out:

                    debug("txptr: ", uhex_(t1), "   txbuf[txtail]: ", udec_(t3))
    

    EDIT: And I added a couple to addport()

    Maybe I used flexspin rather than pnut too. ;) I doubt that is the reason though. I'm suspicious you might not have used the analyser's trigger correctly. There is the relatively large pause between each character. That'll translate to lots of $FFs.

  • I ran the code using the new version of Pnut and checked the analyzer trigger. I removed the 100ms delay in the txtest() method to get faster responses on the analyzer. So now I see an output but not the expected values (should be simply outputting a count from 0-9), it seems the output value is all over the place. I'll try out the new single step debugging in Pnut and see where that takes me.

  • Finally got back to the serial code and working with the single step debugger. I really like the new functionality in Pnut, hope to see it in the PropTool soon!
    Troubleshooting the assembly code it appears to be working correctly and the test program (output values 1-9 on pin 6) show the incrementing values going to the output pin 6 but the logic analyzer is only showing an output value 63. I simplified the test program to only enable a single port (0) and testing the transmit code (will work on recieve side next). The transmit code appears to be working but I'm not seeing the expected values on the output pin. Hoping someone can see what I'm doing wrong.

    con
      ' serial specific constants
      BUF_SIZE       = 32                                           ' size of rx and tx buffers
      MAX_PORT       = 8                                            ' set to number of ports to be used (0-7)
    
    
    var
    
      long  num_ports                                               ' total number of open ports (0-7)
      long  rxpins[MAX_PORT]                                        ' rx pin array - cog rxbuff
      long  txpins[MAX_PORT]                                        ' tx pin array - cog txbuff
      long  rxhub[MAX_PORT]                                         ' cog p_rxbuf - ptr to rxbuf hub address
      long  txhub[MAX_PORT]                                         ' cog p_txbuf - ptr to txbuf hub address
      long  p_rxhd[MAX_PORT]                                        ' cog ptr to rxhead[] hub address start
      long  p_txhd[MAX_PORT]                                        ' cog ptr to txhead[] hub address start
      long  p_txtl[MAX_PORT]                                        ' cog ptr to txtail[] hub address start
    
      long  rxhead[MAX_PORT]                                        ' rx/tx head and tail arrays
      long  rxtail[MAX_PORT]
      long  txhead[MAX_PORT]                                        '
      long  txtail[MAX_PORT]                                        '
      long  txdelay[MAX_PORT]                                       ' port baud rate
      long  cog                                                     ' cog flag/id
    
      byte  rxbuf[BUF_SIZE * MAX_PORT]                              ' buffers - set MAX_PORT to actual open ports
      byte  txbuf[BUF_SIZE * MAX_PORT]
    
      byte  pbuf[80]                                                ' padded strings
    
      byte  port_1                                                  ' named ports
      byte  port_2
      byte  port_3
    
    pub main()| t
      ' testing setup only
      port_1 := addport(5, 6, %0000, BR_TERM)                            ' 1st open port
      debug(sdec(port_1))
      start()
      txtest()
    
    pub rxtest() | n
    ' test recieve
      n := rx(0)
    
    pub txtest() | i, s
      ' test transmit
      i := 1
      repeat
        tx(0, i)                                                    ' output port 0
    '    tx(1, i+10)                                                 ' output port 1
    '    tx(2, i+15)
        i++
        if i == 10
          i := 1
    
    
    pub null()
    '' This is not a top-level object
    
    
    pub addport(rxp, txp, mode, baud) : result | baudcfg, spmode, tdelay
    '' call method before start(). miniumum 1 port required
    '' load data arrays and setup smartpins
    '' does not check for port duplication
    '' run addport at least once before calling start method
    '' returns portid (0 to MAX_PORT-1), -1 on error
    '' -- rxp... receive pin (-1 if not used)
    '' -- txp... transmit pin (-1 if not used)
    '' -- mode.... %0xx1 = invert rx
    ''             %0x1x = invert tx
    ''             %01xx = open-drain/open-source tx
    
      if (rxp == txp)                                            ' pins must be unique
        result := -1
      ' check if pin used by any other ports
    
        num_ports++
    
      if num_ports > (MAX_PORT-1)                                    ' port in range
        result := -1                                                 ' error, initializing too many ports
        abort
      else
        result := num_ports                                          ' return port number (0-7), -1 if error
    
      txdelay[num_ports] := clkfreq / baud * 11                      ' tix to transmit one byte
    
      baudcfg := muldiv64(clkfreq, $1_0000, baud) & $FFFFFC00        ' set bit timing
      baudcfg |= (8-1)                                               ' set bits (8)
    
      rxpins[num_ports] := rxp                                     ' save rx pin
    
      if rxpins[num_ports] >= 0                                      ' configure rx pin if used
        spmode := P_ASYNC_RX
        if (mode.[0])
          spmode |= P_INVERT_IN
        pinstart(rxpins[num_ports], spmode, baudcfg, 0)
    
      txpins[num_ports] := txp                                     ' save tx pin
    
      if txpins[num_ports] >= 0                                      ' configure tx pin if used
        spmode := P_ASYNC_TX | P_OE
        case mode.[2..1]
          %01 : spmode |= P_INVERT_OUTPUT
          %10 : spmode |= P_HIGH_FLOAT                               ' requires external pull-up
          %11 : spmode |= P_INVERT_OUTPUT | P_LOW_FLOAT              ' requires external pull-down
        pinstart(txpins[num_ports], spmode, baudcfg, 0)
    
      rxhub[num_ports] := @rxbuf[num_ports * BUF_SIZE]               ' ptr to hub buffer address
      txhub[num_ports] := @txbuf[num_ports * BUF_SIZE]
    
      p_rxhd[num_ports] := @rxhead[num_ports]                        ' ptr to hub addresses
      p_txhd[num_ports] := @txhead[num_ports]
      p_txtl[num_ports] := @txtail[num_ports]
    
    {  debug("---------------")
      debug(udec(num_ports))
      debug(udec(rxpins[num_ports]))
      debug(udec(txpins[num_ports]))
      debug(udec(rxhub[num_ports]))
      debug(udec(txhub[num_ports]))
      debug(udec(p_rxhd[num_ports]))
      debug(udec(p_txhd[num_ports]))
      debug(udec(p_txtl[num_ports]))
    }
    
    
    pub start() : result
    '' Start new cog
    
      stop()
      cog := coginit(COGEXEC_NEW, @uart_mgr, @num_ports) + 1         ' start uart manager cog
      return cog
    
    pub tx(portval, b) | n
    '' Move byte into transmit buffer if room is available
    '' -- will wait if buffer is full
      repeat
        n := txhead[portval] - txtail[portval]                       ' bytes in buffer
    
        if (n < 0)                                                   ' fix for index wrap-around
          n += BUF_SIZE
        if (n < BUF_SIZE-1)
          quit
    
      txbuf[(portval * BUF_SIZE) + txhead[portval]] := b             ' move to buffer offset location
      if (++txhead[portval] == BUF_SIZE)                             ' update head pointer
        txhead[portval] := 0
    
    
    pub txn(portval, b, n)
    '' Emit byte n times
    
      repeat n
        tx(portval, b)
    
    
    pub str(portval, p_str)
    '' Emit z-string at p_str
    
      repeat (strsize(p_str))
        tx(portval, byte[p_str++])
        debug(sdec(p_str))
        debug(sdec(byte[p_str]))
    
    
    pub txflush(portval)
    '' Wait for transmit buffer to empty
    '' -- will delay one byte period after buffer is empty
    
      repeat until (txtail[portval] == txhead[portval])             ' let buffer empty
      waitct(getct() + txdelay[portval])                            ' delay for last byte
    
    
    dat { smart pin uart/buffer manager }
                    org
    uart_mgr                                                        ' read hub arrays into cog, get # of open ports
                                                                    ' to copy to cog ram
                    rdlong    portnum, ptra++                       ' get # of open ports
                    setq      #(MAX_PORT*7)                         ' block copy hub variables to cog
                    rdlong    rxpin, ptra
    
    uart_main                                                       ' loop through each port, get rx, tx pins
                    mov       portctr, #0                           ' initialize portctr = 0
    
    .loop                                                           ' get offsets for array values
                    debug("-----loop-------")
                    debug(uhex(portctr))
    
                    alts      portctr, #rxpin                       ' add portctr offset to rxpin - rxpin[portctr]
                    mov       rxd, 0                                ' copy rxpin to rxd
    
                    alts      portctr, #txpin                       ' add portctr offset to txpin - txpin[portctr]
                    mov       txd, 0                                ' copy txpin to txd
    
                                                                    ' rxpin available, jump to rx_serial or tx_serial
                    testb     rxd,  #31                     wc      ' rx pin in use? -test for -1 when no pin saved
        if_nc       call      #rx_serial
    
                    testb     txd, #31                      wc      ' tx in use? -test for -1
        if_nc       call      #tx_serial
                                                                    ' increment counter to next port. if portctr =
                                                                    ' open ports, reset portctr to 0 and loop
                    incmod    portctr, portnum              wc      ' check if portctr = open ports
        if_nc       jmp       #.loop                                ' repeat loop for each open port
    
                    jmp       #uart_main
    
    rx_serial       testp     rxd                           wc      ' anything waiting on smartpin?
        if_nc       ret
    '                debug("-----rxserial-------")
                    rdpin     t3, rxd                               ' read new byte from smartpin
                    shr       t3, #24                               ' align lsb
    
                    alts      portctr, #p_rxbuf                     ' get @rxhub[portctr] from hub
                    mov       t1, 0                                 ' t1 := @rxhub[portctr]
    
                    alts      portctr, #p_rxhead                    ' get rxhead[portctr] value from hub
                    mov       offset, 0                             ' offset = rxhead[portctr]
                    rdlong    t2, offset                            ' read rxhead[portctr] from hub
    
                    add       t1, t2
                    wrbyte    t3, t1                                ' rxbuf[rxhead] := t3
                    incmod    t2, #(BUF_SIZE-1)                     ' update rxhead index
        _ret_       wrlong    t2, offset                            ' write rxhead index back to hub
    
    tx_serial       debug
            rdpin     t1, txd                       wc      ' check busy flag
        if_c        ret                                             '  abort if busy
                    debug("-------txserial--------")
    
                    alts      portctr, #p_txhead                    ' get txhead value from hub
                    mov       offset, 0                             ' offset = address of txhead[portctr]
                    rdlong    t1, offset                            ' t1 = txhead[portctr] in hub memory
    
                    debug(uhex(p_txhead))
                    debug(uhex(#p_txhead))
                    debug(uhex(offset))
                    debug("txhead: ", uhex(t1))
    
                    alts      portctr, #p_txtail                    ' get txtail value from hub
                    mov       offset1, 0                            ' offset1 = address of txtail[portctr]
                    rdlong    t2, offset1                           ' t2 = txtail[portctr] in hub memory
    
                    debug(uhex(#p_txtail))
                    debug(uhex(offset1))
                    debug("txtail: ", uhex_(t2))
            debug()
    
                    cmp       t1, t2                        wz      ' byte(s) to tx?
        if_e        ret
    
                    alts      portctr, #p_txbuf                     ' get txbuf[portctr] in hub memory
                    mov       t1, 0                                 ' t1 := txhub[portctr]
                    add       t1, t2                                ' add tail index
                    rdbyte    t3, t1                                ' t3 := txhub[txtail] -- t3 debug shows the expected output value
                    wypin     t3, txd                               ' load into uart
    
                    debug("txhub: ", uhex_(t3))
            debug("txptr: ", uhex_(t1), "   txbuf[txtail]: ", udec_(t3))
    
                    incmod    t2, #(BUF_SIZE-1)                     ' update tail index
        _ret_       wrlong    t2, offset1                           ' write tail index back to hub
    
    ' --------------------------------------------------------------------------------------------------
    
    portnum         long      1                                     ' total # ports
    rxpin           long      0[MAX_PORT]                                  ' rx pin array
    txpin           long      0[MAX_PORT]                                  ' tx pin array
    p_rxbuf         long      0[MAX_PORT]                                  ' ptr to rxhub
    p_txbuf         long      0[MAX_PORT]                                  ' ptr to txhub
    p_rxhead        long      0[MAX_PORT]                                  ' ptr to rxhead
    p_txhead        long      0[MAX_PORT]                                  ' ptr to txhead
    p_txtail        long      0[MAX_PORT]                                  ' prt to txtail
    
    portctr         res       1                                     ' loop counter
    rxd             res       1                                     ' rx pin
    txd             res       1                                     ' tx pin
    offset          res       1
    offset1         res       1
    t1              res       1                                     ' work vars
    t2              res       1
    t3              res       1
    
                    fit       472
    
  • evanhevanh Posts: 15,192
    edited 2022-08-20 17:18

    I had to fix a few errors with the chopped down source but that one is working fine, the correct data is appearing on the pins, same as previously. Counting from 1 up to 9 and repeating. So far I've not had any issues with its transmit.

    Here's what I'm compiling right now. I've reinstated a 200 ms pause between bytes, so I can see each byte triggered one by one on the scope, and I'm using pins 8 and 9.

    PS: You'll probably need to remove the DEBUG_BAUD constant I've added. Pnut 35t (the latest) has a bug itself, that it can't handle anything other than default baud.

  • evanhevanh Posts: 15,192

    Using the scope's trigger means I'm not looking for each byte in one huge capture. Each byte is a separate capture.

  • Interesting, I only get a decimal value of 15 on the output running the copy you loaded on my analyzer. Maybe the problem is in my analyzer? I'll try out another analyzer software and my o-scope.

  • Using another software package for the analyzer I get the expected output values being transmitted! So the problem was at my end with reading the data.
    I enabled an additional port and saw some issues to work through, looks like the adddport() method isn't setting up the arrays correctly so back to troubleshooting

  • @evanh said:
    Oh, you don't need the offset1 variable at all in there. This should work:

                    alts      portctr, #p_txtail                    ' get txtail value from hub
                    rdlong    t2, 0-0                           ' t2 = txtail[portctr] in hub memory
    

    I tried this change which broke the code, it seems like it should work but I'm not seeing the problem yet. I put the offset1 back in and it worked again, I'll look into this again later.

    Started testing the txserial PASM code with more than a single port open. With 1 or 2 open ports the code works and I get good output on the analyzer. But when a 3rd port is added the code breaks, port 1 output no longer shows the count correctly, numbers are all over the place. Port 2 and 3 outputs are both empty. So far I haven't seen the cause but I suspect I'm over running/overwriting one of the arrays with the 3rd port. I've been single-stepping thought the code but not seeing where the problem originates.

  • evanhevanh Posts: 15,192
    edited 2022-08-23 01:13

    Ah, I later noticed value of offset1 was additionally used further down. It would've needed two such edits to eliminate its use. So, in that respect, it is best as is.

    Sorry, I'd made too many off-the-cuff remarks back there. Once I actually tried using your code, it worked well.

  • @evanh said:
    Ah, I later noticed value of offset1 was additionally used further down. It would've needed two such edits to eliminate its use. So, in that respect, it is best as is.

    Sorry, I'd made too many off-the-cuff remarks back there. Once I actually tried using your code, it worked well.

    I really appreciate your input, its caused me to investigate other PASM commands like LOC (doesn’t appear it will work with the size of the arrays I’m using but good to know about anyway).

  • evanhevanh Posts: 15,192
    edited 2022-08-23 02:57

    LOC doesn't work because Spin functions/data, at compile time, don't have a known address in hubRAM. They are only resolved at run-time. My lack of experience in doing arrays with inline Pasm caught me out there.

    LOC is great for pure Pasm programs. I think Eric's Flex suite can use them too but you lose Pnut/Proptool compatibility if you do.

Sign In or Register to comment.