Shop OBEX P1 Docs P2 Docs Learn Events
Smarter than a P2 Smart Pin? — Parallax Forums

Smarter than a P2 Smart Pin?

I have been trying to understand the smart pins on the P2. I was trying to get pins 62 and 63 to talk to the propeller output window that comes up when using flexgui. I attached the file below. I am hoping someone can help me learn what I am not seeing.

Comments

  • JonnyMacJonnyMac Posts: 9,102
    edited 2021-04-03 02:17

    Your file is not attached.

    I've included my P2 template file that uses jm_fullduplexserial.spin2 for terminal IO coms (this object uses smart pins for async io). Since you're running in FlexGUI, you'll want to change the terminal type to T_ANSI at the top of the program.

  • Steve_HatchSteve_Hatch Posts: 19
    edited 2021-04-03 16:55
    con
    
      freq = 160_000_000
      mode = $010007f8
    
    
    dat
        org
    
        ' set up clock
        hubset #0
        hubset ##mode  ' initialize oscillator
        waitx ##20_000_000/100 ' wait for it to settle down
        hubset ##mode + %11   ' enable it
    
    
            mov bitperiod, ##$2B60007   ' Setup baud to 230400 w 8 bits     
            mov txmode, ##$0000_0000_000_0000000000000_01_11110_0
            mov tx, #62 
            mov rx, #63     
            wrpin txmode, #tx
            wxpin bitperiod, #tx        
            dirh #tx
            waitx ##1000
            mov rxmode, ##$0000_0000_000_0000000000000_00_11110_0
            wrpin rxmode, #rx
            wxpin bitperiod, #rx
            dirh #rx
            waitx ##1000
    
    rcvr        testp #rx wc        ' Test to see if there is a char
        if_c    jmp #test1      ' Wait till a char
            jmp #test2
    
    
    
    test1       mov x, #56      ' Set x to blink 1st pin  Blink if carry is set
            drvnot x        ' Toggle pin 56
            shl x, #18
            waitx x
            jmp #rcvr
    
    test2       mov x, #57      ' Set pin 57  Blink if carry is not set
            drvnot x
            shl x, #18  
            waitx x
            jmp #rcvr
    
    
    
    tx      res 1       ' Tx pin
    rx      res 1       ' Rx pin
    bitperiod   res 1       ' Setup baud rate
    txmode      res 1       ' Transmit mode
    x       res 1       ' Temp register
    y       res 1       ' Temp register
    rxmode      res 1       ' Receive mode
    rdata       res 1       ' buffer to read a char
    
  • For some reason, the file that was attached was the binary file, not the text. So, I posted the full text in the next comment, hoping someone would see that the text was by the same author as the first. I used jm_fullduplexserial.spin2 as my template when designing my little program. I don't know how to change the terminal to an ANSI terminal. I still don't understand why my program won't work. What I wanted to do was use the LED's on my evaluation board to indicate what was happening until I got the program to respond to the keyboard. On the first attempt, I had P56 blinking, since I thought that using testp instruction I could read the status tof the receiver. Then when I hit any key, the blinking LED would change to P57. Then I could expand the program to shift all the bits in and read the whole character which I would send back to the terminal completing the loopback test. Instead what I am getting is both LED's taking turn randomly flashing and unable to see that a key has been pressed. It is pretty frustrating to not be able to figure out the smart pins. When they were just responding as regular IO pins it was easier to troubleshoot. The smart pins seem to hide what is going on and make troubleshooting harder. Very frustrated at the moment. Hoping to be able to figure out what is happening. My full program is an assembly level program, so I have no spin infrastructure at the top.

  • you need to remover the # before

    wrpin txmode, #tx
    wxpin bitperiod, #tx        
    

    Enjoy!

    Mike

  • evanhevanh Posts: 15,912
    edited 2021-04-03 23:53

    Yes, the # means the value gets directly encoded into the assembled instruction and acts as "immediate" data. Also called immediate addressing. Use #value or #label when the value is defined as a constant.

    But when the value is stored in a variable (cog general register) then what gets encoded is the register number that holds that value. This doesn't have the #.

  • Well guys, thanks for your response, but that did not make it work. There is something missing that I can't see or understand, hence my statement that I am not smarter than a smart pin. This is my first experience with smart pins and so far I am not being successful.

  • evanhevanh Posts: 15,912
    edited 2021-04-05 21:29

    Fixed up all the #'s ... testing it ... assembles fine ...

    • As a rule, for reliable reconfiguration of a smartpin, it should be surrounded with a DIRL/DIRH pair.
    • rx smartpin is incorrectly a transmit mode. Needs 11110_0 -> 11111_0
    • TESTP won't clear the receive buffer full flag. Requires a partnered RDPIN.
    • HUBSET mode and bitperiod are both too obfuscated. I haven't tried to decode them.
  • JonnyMacJonnyMac Posts: 9,102
    edited 2021-04-07 01:48

    I sometimes have a hard time finding things on my desk because it is (clears throat)... untidy. I looked at your code and a couple of Chip's PASM-only demos and came up with this. It will echo what comes in on P63 out P62, and blip the LED on P56. If you open PST it's easy to test; what you type into the entry field is echoed to the output field

    Suggestions:
    -- be kind to yourself and others by formatting your code neatly
    -- use Spin's built-in constants to make code easier to read and less error prone

    con { timing }
    
      CLK_FREQ = 160_000_000
    
      _clkfreq = CLK_FREQ
    
    
    con { fixed io pins }
    
      PGM_RX   = 63  { I }                                          ' programming / debug
      PGM_TX   = 62  { O }
    
      LED      = 56  { O }                                          ' LED on Eval/Edge
    
    
    con { serial }
    
      BAUD = 230_400
    
      BAUD_CFG = ((CLK_FREQ / BAUD) << 16) | (8 - 1)
    
    
    dat
    
                    org
    
    entry           asmclk                                          ' setup clock
                    drvh      #LED                                  ' Eval p56 off
    
    cfg_serial      fltl      #PGM_RX
                    wrpin     #P_ASYNC_RX, #PGM_RX
                    wxpin     ##BAUD_CFG, #PGM_RX
                    wypin     #0, PGM_RX
                    drvh      #PGM_RX
    
                    fltl      #PGM_TX
                    wrpin     #(P_ASYNC_TX | P_OE), #PGM_TX
                    wxpin     ##BAUD_CFG, #PGM_TX
                    wypin     #0, PGM_TX
                    drvh      #PGM_TX
    
    echo_loop       testp     #PGM_RX                       wc      ' anything in sp buffer?
        if_nc       jmp       #$-1                                  ' no, keep waiting
    
                    rdpin     t1, #PGM_RX                           ' yes, grab it
                    shr       t1, #24                               ' fix up
    
                    rdpin     t2, #PGM_TX                   wc      ' check tx busy flag
        if_c        jmp       #$-1                                  ' wait until not busy
    
                    wypin     t1, #PGM_TX                           ' echo back to terminal
    
                    drvl      #LED                                  ' led on
                    waitx     ##(CLK_FREQ / 20)                     ' 50ms blip
                    drvh      #LED
    
                    jmp       #echo_loop
    
    
    t1              res       1
    t2              res       1
    
                    fit       496
    
    

    Edit: Changed ## to # where appropriate.

  • evanhevanh Posts: 15,912
    edited 2021-04-05 22:57

    Lol, took some testing but I found a real typo illusion. The pin modes for the two smartpins is set using $ when they should be %. eg: ##$0000_0000_000_0000000000000_01_11110_0 should be ##%0000_0000_000_0000000000000_01_11110_0
    Amusingly, the assemblers didn't complain because the hexadecimal value was still within 32-bit bounds.

    PS: As Jon mentioned, using the built-in predefines would avoid some mistakes like this.

  • Thank you for your help. I will have to continue to work on this. The program I am writing is going to be a compete assembler program. Once it loads it will loop within itself, so no Spin is my goal. I wrote a software UART that is working fine for me and I am going to move on without the smart pins and maybe come back to it at a later date, when I get the program working. I do appreciate your time. Without help from friends, this would be overwhelming.

    Steve

  • evanhevanh Posts: 15,912
    edited 2021-04-07 01:07

    Steve,
    Try this. I've hacked your code around over a couple of sessions of experimenting. It's not all intentional.

    Main thing is it's making use of a convenience in the assemblers where you get free assemble-time calculation and setting of the system clock frequency. Without it, specifying the components is a little messy. Also makes a reliable relationship with other frequency calculations like for baud setting.

    con
    
    '  mode = $0100_07f8              ' 160 MHz
    
      _clkfreq = 160_000_000
      txpin = 62
      rxpin = 63
      baud = 230_400
    
    
    dat
        org
    {
        ' set up clock
        hubset ##mode  ' initialize oscillator
        waitx ##25_000_000/100 ' wait for it to settle down
        hubset ##mode + %11   ' enable it
    }
        asmclk
        wrpin   #0, #56|(7<<6)  'set all LEDs OFF
        drvh    #56|(7<<6)  'set all LEDs OFF
        waitx ##_clkfreq    'wait for terminal startup
    
            dirl #rxpin
            wrpin #%00_11111_0, #rxpin
            wxpin bitperiod, #rxpin
            dirh #rxpin
    
            dirl #txpin
            wrpin #%01_11110_0, #txpin
            wxpin bitperiod, #txpin
            dirh #txpin
    
            waitx ##1000
        wypin #"F", #txpin
    
    
    rcvr
            testp #rxpin wc        ' Test to see if there is a char
        if_c    rdpin rdata, #rxpin
        if_c    shr rdata, #32-8
        if_c    jmp #test1      ' Wait till a char
            jmp #test2
    
    
    test1
        wypin rdata, #txpin
            mov x, #56      ' Set x to blink 1st pin  Blink if carry is set
            drvnot x        ' Toggle pin 56
            shl x, #18
            waitx x
            jmp #rcvr
    
    test2
            mov x, #57      ' Set pin 57  Blink if carry is not set
            drvnot x
            shl x, #18  
            waitx x
            jmp #rcvr
    
    
    
    bitperiod   long    round(float(_clkfreq) / float(baud) * 65536.0) & $ffff_fc00 | 7   ' config of baud with 8N1 framing
    x       res 1       ' Temp register
    y       res 1       ' Temp register
    rdata       res 1       ' buffer to read a char
    
    

    EDIT: Updated to include reading in the byte and echoing back, like Jon did.

  • evanhevanh Posts: 15,912
    edited 2021-04-07 01:21

    On the build your own assembler side of things, there is quite a lot of early hints from before the days of the predefines here - https://forums.parallax.com/discussion/169542/p2-links-for-where-to-obtain-tools-sample-test-code-reference-only/p1
    and here - https://forums.parallax.com/discussion/169069/p2-tricks-traps-differences-between-p1-reference-material-only/p1

    Back then, Cluso made a handy set of component constants for using to set sysclock frequency - https://forums.parallax.com/discussion/comment/1452025/#Comment_1452025
    I still use that method in fact. That way I know what values the multiplier and dividers are set to when testing timings.

    For a quick leg up and to keep compatibility with the constants used in Pnut/Proptool/Flexspin, Eric likely has a complete list in his sources - https://github.com/totalspectrum/spin2cpp/releases

  • JonnyMacJonnyMac Posts: 9,102
    edited 2021-04-07 01:49

    so no Spin is my goal.

    There is no Spin in the program I uploaded yesterday. The constant expressions are evaluated by the compiler, and Spin2 constants apply to PASM2. As Evan pointed out, your code style made it tricky to spot a subtle error. To be honest, I didn't look that hard because I favor using named constants, especially when they're built into the compiler.

  • JonnyMacJonnyMac Posts: 9,102
    edited 2021-04-07 01:42

    @evanh Are you sure you don't want that first drvl, #rxpin to be fltl?

            dirl #rxpin                                       ' <-- shouldn't this be fltl?
            wrpin #%00_11111_0, #rxpin        
            wxpin bitperiod, #rxpin
            dirh #rxpin
    
  • evanhevanh Posts: 15,912
    edited 2021-04-07 01:54

    DIRL is not DRVL. Another one of those little illusions. DIRL was more commonly used over FLTL early on and I actually prefer it for more specifically actioning the need.

    That said, FLTL is fine and can save an instruction. And may be a good idea here since I do set OUT high beforehand.

  • Another one of those little illusions.

    Indeed. Thanks for the explanation.

  • Cluso99Cluso99 Posts: 18,069

    FWIW Spin2 was not available when the first P2 chips became available. So initially, all code was only pasm.

  • Fair point, but the ability to create named constants -- which I content can be helpful to all -- has always been available.

Sign In or Register to comment.