Shop OBEX P1 Docs P2 Docs Learn Events
Smart Pins Across Cogs? [SOLVED] — Parallax Forums

Smart Pins Across Cogs? [SOLVED]

JonnyMacJonnyMac Posts: 8,955
edited 2020-08-09 18:03 in Propeller 2
Based on the documentation we have, it seems like one cog can setup a smart pin which can be accessed by another. Right? That being the case, I'm having trouble with my jm_fullduplexserial.spin2 object (a WIP that *should* have been easy). If you have a minute and can review, maybe you'll see something silly I missed/screwed up. Thanks in advance.

Here's the var block:
var                                                               
                                                                  
  long  cog                                                     ' cog flag/id

  long  rxp    {ptra}                                           ' rx smart pin
  long  txp                                                     ' tx smart pin
  long  rxhub                                                   ' hub address of rxbuf
  long  txhub                                                   ' hub address of txbuf  
  
  long  rxhead {ptra[4]}                                        ' rx head index
  long  rxtail {ptra[5]}                                        ' rx tail index
  long  txhead {ptra[6]}                                        ' tx head index
  long  txtail {ptra[7]}                                        ' tx tail index

  long  txdelay                                                 ' ticks in one byte

  byte  rxbuf[BUF_SIZE]                                         ' buffers
  byte  txbuf[BUF_SIZE]

This code gets it going:
pub startx(rxpin, txpin, baud) : result | bitmode

'' Start simple serial coms on rxpin and txpin at baud
'' -- rxpin... recieve pin (-1 if not used)
'' -- txpin... transmit pin (-1 if not used)

  stop()

  longmove(@rxp, @rxpin, 2)                                     ' save pins
  rxhub := @rxbuf                                               ' point to buffers
  txhub := @txbuf

  txdelay := clkfreq / baud * 11                                ' tix to transmit one byte

  bitmode := muldiv64(clkfreq, $1_0000, baud) & $FFFFFC00       ' set bit timing
  bitmode |= (8-1)                                              ' set bits (8)

  pinstart(rxp, P_ASYNC_RX, bitmode, 0)                         ' configure rx smart pin     
  pinstart(txp, P_ASYNC_TX | P_OE, bitmode, 0)                  ' configure tx smart pin

  cog := coginit(COGEXEC_NEW, @uart_mgr, @rxp) + 1              ' start uart manager cog

  return cog
I know that the bitmode calculation works because I'm using it in my unbuffered serial object.

Finally, here's the PASM2 block that is simply managing the smartpin UARTS.
-- corrected tx busy check; seems to work now.
dat

                org

uart_mgr        setq      #4-1                                  ' get 4 parameters from hub
                rdlong    rxd, ptra


rx_serial       testb     rxd, #31                      wc      ' rx not used?
    if_c        jmp       #tx_serial                            ' if negative, no rx pin

                testp     rxd                           wc      ' anything waiting?
    if_nc       jmp       #tx_serial                            ' no, check transmit

                rdpin     t3, rxd                               ' read new byte
                shr       t3, #24                               ' align lsb

                mov       t1, p_rxbuf
                rdlong    t2, ptra[4]                           ' t2 := rxhead
                add       t1, t2
                wrbyte    t3, t1                                ' rxbuf[rxhead] := t1
                incmod    t2, ##(BUF_SIZE-1)                    ' update head index
                wrlong    t2, ptra[4]                           ' write head index back to hub


tx_serial       testb     txd, #31                      wc      ' tx not used?
    if_c        jmp       #rx_serial                            ' if negative, no tx pin

                rdpin     t1, txd                       wc      ' check busy flag
    if_c        jmp       #rx_serial

                rdlong    t1, ptra[6]                           ' t1 = txhead  
                rdlong    t2, ptra[7]                           ' t2 = txtail
                cmp       t1, t2                        wz      ' byte(s) to tx?
    if_e        jmp       #rx_serial

                mov       t1, p_txbuf                           ' start of tx buffer
                add       t1, t2                                ' add tail index 
                rdbyte    t3, t1                                ' t3 := txbuf[txtail]      
                wypin     t3, txd                               ' load into sp uart
                incmod    t2, ##(BUF_SIZE-1)                    ' update tail index
                wrlong    t2, ptra[7]                           ' write tail index back to hub

                jmp       #rx_serial  

' --------------------------------------------------------------------------------------------------

rxd             res       1                                     ' receive pin  
txd             res       1                                     ' transmit pin    
p_rxbuf         res       1                                     ' pointer to rxbuf     
p_txbuf         res       1                                     ' pointer to txbuf

t1              res       1                                     ' work vars
t2              res       1
t3              res       1

                fit       496

At the moment I'm getting nothing out to the terminal using a simple test program that does work with my unbuffered version.

Comments

  • JonnyMacJonnyMac Posts: 8,955
    edited 2020-08-09 18:02
    When in doubt... read further into the docs. Found that I was incorrectly checking the TX busy flag.
  • JonnyMacJonnyMac Posts: 8,955
    edited 2020-08-10 02:44
    I updated the code a bit -- seems like this style would simplify adding more ports.
    dat
    
                    org
    
    uart_mgr        setq      #4-1                                  ' get 4 parameters from hub
                    rdlong    rxd, ptra
    
                    
    uart_main       testb     rxd, #31                      wc      ' rx in use?
        if_nc       call      #rx_serial
    
                    testb     txd, #31                      wc      ' tx in use? 
        if_nc       call      #tx_serial
    
                    jmp       #uart_main
    
    
    rx_serial       testp     rxd                           wc      ' anything waiting?
        if_nc       ret
    
                    rdpin     t3, rxd                               ' read new byte
                    shr       t3, #24                               ' align lsb
                    mov       t1, p_rxbuf
                    rdlong    t2, ptra[4]                           ' t2 := rxhead
                    add       t1, t2
                    wrbyte    t3, t1                                ' rxbuf[rxhead] := t1
                    incmod    t2, #(BUF_SIZE-1)                     ' update head index
                    wrlong    t2, ptra[4]                           ' write head index back to hub
                    ret
    
    
    tx_serial       rdpin     t1, txd                       wc      ' check busy flag
        if_c        ret
        
                    rdlong    t1, ptra[6]                           ' t1 = txhead  
                    rdlong    t2, ptra[7]                           ' t2 = txtail
                    cmp       t1, t2                        wz      ' byte(s) to tx?
        if_e        ret
    
                    mov       t1, p_txbuf                           ' start of tx buffer
                    add       t1, t2                                ' add tail index 
                    rdbyte    t3, t1                                ' t3 := txbuf[txtail]      
                    wypin     t3, txd                               ' load into sp uart
                    incmod    t2, #(BUF_SIZE-1)                     ' update tail index
                    wrlong    t2, ptra[7]                           ' write tail index back to hub
                    ret 
    
    ' --------------------------------------------------------------------------------------------------
    
    rxd             res       1                                     ' receive pin  
    txd             res       1                                     ' transmit pin    
    p_rxbuf         res       1                                     ' pointer to rxbuf     
    p_txbuf         res       1                                     ' pointer to txbuf
    
    t1              res       1                                     ' work vars
    t2              res       1
    t3              res       1
    
                    fit       496
    
  • Hi Jon,

    Sorry, didn't catch what the code was before... just curious, was the C flag just not getting written/checked on the line with rdpin?

    Cheers
  • JonnyMacJonnyMac Posts: 8,955
    edited 2020-08-09 20:02
    I was using testp (looking for IN to be high) instead of rdpin -- error on my part. Rereading deeper into the docs made the difference (I was translating from working Spin2 code and did it incorrectly).
  • WhitWhit Posts: 4,191
    JonnyMac wrote: »
    I was using testp (looking for IN to be high) instead of rdpin -- error on my part. Rereading deeper into the docs made the difference (I was translating from working Spin2 code and did it incorrectly).

    Failing privately teaches to one who failed and is less embarrassing.

    Failing publicly and providing an explanation, is more humble, and teaches everyone!

    Thanks, JonnyMac!
  • Well, I do a lot of failing privately! As I had asked for help, I thought it appropriate to share the solution -- which was correcting a mistake of my own doing.
Sign In or Register to comment.