Shop OBEX P1 Docs P2 Docs Learn Events
TAQOZ ROM FORTH - Using Smartpins to transmit and receive asych serial data — Parallax Forums

TAQOZ ROM FORTH - Using Smartpins to transmit and receive asych serial data

I have been experimenting with TAQOZ ROM Forth to read serial data from SDI-12 sensors and now have a working bit-bashed serial data program for transmitting and receiving data. Developing the program has been great fun and has taught me a lot about the P2 and how to use TAQOZ.

I'd like to simplify the program using Smartpins in asynch serial mode. The transmit side is working thanks to Peter and Bob's examples in 'The Bit Bashers Guide to the Parallax P2', where there are examples of transmitting serial data, but I am struggling to work out how to receive serial data using Smartpins.

Does anyone have any experience of receiving and handling serial data with Smartpins using TAQOZ ROM FORTH?

Thanks, Pete

Comments

  • Hi Peter,
    I cannot help you directly. But I am trying to learn about Smartpins myself with Taqoz. At the moment I try to do this this way: Use Taqoz 2.8 from SD-card. It has got the inline assembler. So it should be possible to move PASM code from the other examples to Taqoz.
    In your case I would start from jm_fullduplexserial.spin2 , which is contained in the download of Propeller Tool.
    Good luck!
    Christof

  • Hi Christof,
    Many thanks, I appreciate your support. We are both thinking along the same lines: I have Taqoz 2.7 running on SD-card (haven't found 2.8) with TIA and have been trying snippets of PASM code (thanks to SuperBob's and John Titus's docs). I'm still learning TIA code/syntax and mostly my code crashes Taqoz ;)

    I initially used JonnyMac's jm_fullduplexserial object for a Spin2 version of my SDI-12 program, which works well (except not being able make the RX non blocking - due to lack of understanding of Spin2 on my part, not the serial library). However, the challenge is to get a version running in Taqoz FORTH using Smartpin TX and RX.

    I'll look again at the PASM RX code in jm_fullduplexserial.spin2, try it out with the TIA and report back...
    Thanks,
    Pete

  • Hi Pete, Taqoz 2.8 is in the ZIP from April here: https://sourceforge.net/projects/tachyon-forth/files/TAQOZ/binaries/

  • Hi Christof,
    Many thanks, I'll have a go with a new SD card.
    Making some progress with Smartpin Async RX. I've got a minimal TX/RX test program working just using the Smartpins.
    I found some useful routines in Peter J's PS2 keyboard code that helped me understand how to initialise Smartpin in async RX mode and how to retrieve characters.
    I'll post the code after a bit more experimenting.
    Pete

  • Peter_FPeter_F Posts: 16
    edited 2021-09-16 16:59

    Hi Christof,
    I worked out how to use a smartpin to receive serial data in Taqoz ROM FORTH (thanks to Jon Titus's smartpin document).
    Please see Taqoz words below to initialise/enable smartpin async mode and to receive a serial character.
    The CLKSET routine sets CLKHZ to the actual measured RCFAST frequency (~25.5 MHz) which then allows normal baud rate values to be used.
    e.g. If CLKSET is not used, the BRATE value would need to be about 1053 instead of 1200. To measure the P2 clock see 'The Bit Basher's Guide..' page 15.

    \  **NB Maximum P2 I/O pin input voltage is 3.3 volts i.e. NOT RS232 levels**
    \  **An RS232 to TTL  (3.3v) Converter Board needed to connect to actual RS232 devices**
    
    1200 := BRATE     \ ( Baud rate )
    18   := RXPIN     \ ( Inverted serial data input )
    
    : CLKSET ( -- )   \ ( reset CLKHZ to actual boot frequency so smartpin baud rates are correct )
        25_553_000 ' CLKHZ 2+ !   \ ( use the actual frequency of P2 ) ;
    
    : RXINIT ( -- )   \ ( initialise smartpin for ASYNC serial RX at BRATE baud rate )
        CLKSET
        RXPIN PIN MUTE
        RXPIN PIN BRATE RXD H   \ ( H - set pin high needed to enable smartpin operation? ) ;
    
    : SDRX ( -- char )   \ ( RX char from smart pin serial )
        WAITPIN
        RDPIN     \ ( receive smartpin char on RXPIN, right shift data from bits 31-24 to 7-0 )
        #24 >> ;
    
    

    Here is a demo program that generates a serial data message in the background (i.e. running on cog 1) which is received by a serial data routine running in the foreground.
    It's great how the P2 cogs can test itself! The RX serial routine to be tested can run on one cog and the TX routine can independently send serial data to the RX routine from another cog.

    Join the serial TX output pin on P16 to the RX input pin on P18 via 1K Ohm resistor. Type GO to start the demo and any key to stop it.

    TAQOZ
    
    \  **NB Maximum P2 I/O pin input voltage is 3.3 volts i.e. NOT RS232 levels**
    \  **An RS232 to TTL(3.3v) Converter Board needed to connect to actual RS232 devices**
    
    \ ( Peter Foden PRFSoft )
    \ ( 12 Sept 2021 Code to test Smartpin asynch serial mode TX and RX on Propeller P2 in Taqoz ROM FORTH )
    \ ( Cog demo - running RX program in foreground and TX program in the background on another cog )
    \ ( To test TX/RX routines connect P16 (TX) to P18 (RX) via a 1K resistor )
    \ ( NB run CLKSET before using Smartpin Async mode in Taqoz ROM FORTH, then baud is set using normal values )
    \
    \             P2 IO Pins view                              1K Ohm
    \     -------------------------------       TX(Pin 16) >---/\/\/\/---|
    \     |  G   17   19   21  23  V16  |       RX(Pin 18) <-------------|
    \     |                             |       
    \     |  G   16   18   20  22  +5v  |       V16 = 3.3v
    \     -------------------------------
    
    RCFAST
    
    1200 := BRATE     \ ( Smartpin async operation at this baudrate only works at 20 MHz clock rate ie RCFAST )
    16   := TXPIN     \ ( Serial data output - NB inverted output for use with TTL-RS232 interface )
    18   := RXPIN     \ ( Serial data input  - NB P2 IO input voltage must be no greater 3.3 volts )
    
    : CLKSET ( -- )   \ ( reset CLKHZ to actual boot frequency so smartpin baud rates are correct )
        25_553_000 ' CLKHZ 2+ ! \ ( use the actual frequency of P2 )
    ;
    
    : RXINIT ( -- )   \ ( initialise smartpin for ASYNC serial RX at BRATE baud rate )
        CLKSET
        RXPIN PIN MUTE
        RXPIN PIN BRATE RXD H  \ ( H - set pin high needed to enable smartpin operation? )
    ;
    
    : SDRX ( -- char )   \ ( RX char from smart pin serial - first attempt - seems to work )
        WAITPIN
        RDPIN            \ ( receive smartpin char on RXPIN, shift data from bits 31-24 to 7-0 )
        #24 >>
    ;
    
    : TXINIT ( -- )      \ ( initialise smart pin for ASYNC serial TX at BRATE baud rate )
        CLKSET
        TXPIN PIN MUTE
        TXPIN PIN BRATE TXD  \ ( no. of serial bits defaults to 8 if BIT or -bit not used )
    ;                    \ ( for SDI-12 we need 8 bits (7+1 even parity bit ) so default 8 is ok )
    
    : SDTX ( char -- )   \ ( send char via smart pin serial TX )
        WYPIN            \ ( send char TX )
        WAITPIN          \ ( wait for char to be sent )
    ;
    
    : TX_HELLO ( -- TX_string )  \ ( taken from Bit Basher's Guide Doc )
        TXPIN PIN " Hello World!" DUP LEN$ TXDAT
    ;
    
    : RUN
        DUP NEWCOG
        5000 WAITX
        TASK W!
    ;
    
    : TEST1 ( -- char )   \ ( receive serial n data chars in a foreground loop )
        RXINIT
        CRLF
      BEGIN      
        42 0 DO           \ ( RX 42 chars and print them )
          SDRX EMIT
        LOOP CRLF
      KEY UNTIL  
    ;
    
    : TEST2  ( -- )       \ ( send ASCII string test every second until a key is pressed )
       TXINIT
       BEGIN
         TX_HELLO         \ ( send 'Hello World!' message string )
         $0D SDTX         \ ( send CR char )
         $0A SDTX         \ ( send LF char )
         1000 ms
       AGAIN
    ;
    
    : START_TST ( -- )    \ ( start background loop going sending TXs every 1 sec )
        ' TEST2 1 RUN
    ;
    
    \ ( set CLKHZ to corrected frequency, start background TX loop in COG1, start foreground RX loop )
    : GO CLKSET START_TST TEST1 ;  
    
    END
    
    

    It's been great finding out how smartpins work, I've a long way to go yet but I hope these very basic serial routines may be of interest to others too.
    Thanks for the encouragement,
    Regards,
    Pete

  • Thanks for this @Peter_F , this plugs a big gap in serial comms - Bob

  • @Peter_F said:
    Hi Christof,
    I worked out how to use a smartpin to receive serial data in Taqoz ROM FORTH (thanks to Jon Titus's smartpin document).
    Please see Taqoz words below to initialise/enable smartpin async mode and to receive a serial character.
    The CLKSET routine sets CLKHZ to the actual measured RCFAST frequency (~25.5 MHz) which then allows normal baud rate values to be used.
    e.g. If CLKSET is not used, the BRATE value would need to be about 1053 instead of 1200. To measure the P2 clock see 'The Bit Basher's Guide..' page 15.

    \  **NB Maximum P2 I/O pin input voltage is 3.3 volts i.e. NOT RS232 levels**
    \  **An RS232 to TTL  (3.3v) Converter Board needed to connect to actual RS232 devices**
    
    1200 := BRATE     \ ( Baud rate )
    18   := RXPIN     \ ( Inverted serial data input )
    
    : CLKSET ( -- )   \ ( reset CLKHZ to actual boot frequency so smartpin baud rates are correct )
        25_553_000 ' CLKHZ 2+ !   \ ( use the actual frequency of P2 ) ;
    
    : RXINIT ( -- )   \ ( initialise smartpin for ASYNC serial RX at BRATE baud rate )
        CLKSET
        RXPIN PIN MUTE
        RXPIN PIN BRATE RXD H   \ ( H - set pin high needed to enable smartpin operation ) ;
    
    : SDRX ( -- char )   \ ( RX char from smart pin serial )
        WAITPIN
        RDPIN     \ ( receive smartpin char on RXPIN, right shift data from bits 31-24 to 7-0 )
        #24 >> ;
    
    

    Here is a demo program that generates a serial data message in the background (i.e. running on cog 1) which is received by a serial data routine running in the foreground.
    Join the serial TX output pin on P16 to the RX input pin on P18 via 1K Ohm resistor. Type GO to start the demo and any key to stop it.

    TAQOZ
    
    \  **NB Maximum P2 I/O pin input voltage is 3.3 volts i.e. NOT RS232 levels**
    \  **An RS232 to TTL(3.3v) Converter Board needed to connect to actual RS232 devices**
    
    \ ( Peter Foden PRFSoft )
    \ ( 12 Sept 2021 Code to test Smartpin asynch serial mode TX and RX on Propeller P2 in Taqoz ROM FORTH )
    \ ( Cog demo - running RX program in foreground and TX program in the background on another cog )
    \ ( To test TX/RX routines connect P16 (TX) to P18 (RX) via a 1K resistor )
    \ ( NB run CLKSET before using Smartpin Async mode in Taqoz ROM FORTH, then baud is set using normal values )
    \
    \             P2 IO Pins view                              1K Ohm
    \     -------------------------------       TX(Pin 16) >---/\/\/\/---|
    \     |  G   17   19   21  23  V16  |       RX(Pin 18) <-------------|
    \     |                             |       
    \     |  G   16   18   20  22  +5v  |       V16 = 3.3v
    \     -------------------------------
    
    RCFAST
    
    1200 := BRATE     \ ( Smartpin async operation at this baudrate only works at 20 MHz clock rate ie RCFAST )
    16   := TXPIN     \ ( Serial data output - NB inverted output for use with TTL-RS232 interface )
    18   := RXPIN     \ ( Serial data input  - NB P2 IO input voltage must be no greater 3.3 volts )
    
    : CLKSET ( -- )   \ ( reset CLKHZ to actual boot frequency so smartpin baud rates are correct )
        25_553_000 ' CLKHZ 2+ !   \ ( use the actual frequency of P2 )
    ;
    
    : RXINIT ( -- )   \ ( initialise smartpin for ASYNC serial RX at BRATE baud rate )
        CLKSET
        RXPIN PIN MUTE
        RXPIN PIN BRATE RXD H  \ ( H - set pin high needed to enable smartpin operation )
    ;
       
    : SDRX ( -- char )   \ ( RX char from smart pin serial - first attempt - seems to work )
        WAITPIN
        RDPIN            \ ( receive smartpin char on RXPIN, shift data from bits 31-24 to 7-0 )
        #24 >>
    ;
    
    : TXINIT ( -- )      \ ( initialise smart pin for ASYNC serial TX at BRATE baud rate )
        CLKSET
        TXPIN PIN MUTE
        TXPIN PIN BRATE TXD  \ ( no. of serial bits defaults to 8 if BIT or -bit not used )
    ;                    \ ( for SDI-12 we need 8 bits (7+1 even parity bit ) so default 8 is ok )
    
    : SDTX ( char -- )   \ ( send char via smart pin serial TX )
        WYPIN            \ ( send char TX )
        WAITPIN          \ ( wait for char to be sent )
    ;
    
    : TX_HELLO ( -- TX_string )  \ ( taken from Bit Basher's Guide Doc )
        TXPIN PIN " Hello World!" DUP LEN$ TXDAT
    ;
     
    : RUN
        DUP NEWCOG
        5000 WAITX
        TASK W!
    ;
    
    : TEST1 ( -- char )   \ ( receive serial n data chars in a foreground loop )
        RXINIT
        CRLF
      BEGIN      
        42 0 DO           \ ( RX 42 chars and print them )
          SDRX EMIT
        LOOP CRLF
      KEY UNTIL  
    ;
     
    : TEST2  ( -- )       \ ( send ASCII string test every second until a key is pressed )
       TXINIT
       BEGIN
         TX_HELLO         \ ( send 'Hello World!' message string )
         $0D SDTX         \ ( send CR char )
         $0A SDTX         \ ( send LF char )
         1000 ms
       AGAIN
    ;
    
    : START_TST ( -- )    \ ( start background loop going sending TXs every 1 sec )
        ' TEST2 1 RUN
    ;
    
    \ ( set CLKHZ to corrected frequency, start background TX loop in COG1, start foreground RX loop )
    : GO CLKSET START_TST TEST1 ;  
    
    END
    
    

    It's been great finding out how smartpins work, I've a long way to go yet but I hope these very basic serial routines may be of interest to others too.
    Thanks for the encouragement,
    Regards,
    Pete

    Great! Thanks for sharing!

  • @bob_g4bby said:
    Thanks for this @Peter_F , this plugs a big gap in serial comms - Bob

    Hi Bob,
    Thanks, I appreciate your help too, your Bit Basher's Guide is always open on my desk!
    Please use/edit the RX code if you think you might need another serial comms example.

    I have been using the TAQOZ ROM Forth, because it supports smartpin async serial at the low
    baud rates I want to use (ie 1200 baud for SDI-12 sensors) and is so easy to program using FlexProp.

    Cheers,
    Pete

  • bob_g4bbybob_g4bby Posts: 414
    edited 2022-04-24 10:43

    There is a potential flaw with the serial input code SDRX - if no chr is ever received (e.g. the connector is unplugged), the following code will never exit:-

    : SDRX ( -- char )  --- RX char from smart pin serial
        WAITPIN         --- wait until a char has been received
        RDPIN           --- receive smartpin char on RXPIN, shift data from bits 31-24 to 7-0
        #24 >>
    ;
    

    Better is to have a serial input word SDRX-TO that will eventually timeout if no chr is received (requires PASM loaded):-

    --- Serial Input with timeout Bob Edwards April 2022
    --- If a serial input word waits indefinitely for a character with no means of escape
    --- that may leave a product locked up, reset being the only way out
    --- This serial input only waits for a number of milliseconds to receive a char
    --- after which time it will indicate chr received or timeout
    
    921600 := BRATE \ Baud rate
    55   := RXPIN   \ Smartpin to be used as serial input 
    
    --- checks whether smartpin ack has occurred
    pub PIN?    ( -- flag=true if ack occurred )
        @PIN
        ASM:
            testp a wc
            nop
            mov a,#0
            if_c mov a,#-1
            ret
        end
    
    --- initialise smartpin for ASYNC serial RX at BRATE baud rate
    : RXINIT ( -- )
        RXPIN PIN MUTE
        RXPIN PIN BRATE RXD H   --- H - set pin high needed to enable smartpin operation?
    ;
    
    --- serial input timeout data
    8 bytes sdrxtimer
    
    --- RX char from smart pin serial with timeout in ms
    : SDRX-TO   ( timeout -- chr flag=FALSE | flag=TRUE )
        sdrxtimer TIMEOUT       --- start the timeout
        BEGIN                   --- leave this loop if
            PIN?                --- a chr arrived at the serial input
            sdrxtimer TIMEOUT?  --- or there's been no chr for 5s or more
            OR
        UNTIL
        sdrxtimer TIMEOUT?      --- has a chr been received
        IF
            TRUE                --- no, signal timeout occurred
        ELSE
            RDPIN               --- yes, read the chr
            #24 >>              --- adjust it to the LS byte
            FALSE               --- signal no timeout
        THEN
    ;
    
    --- test of SDRX-TO
    --- receive and display chrs on serial port until keypress
    --- display alarm if 5s timeout occurs
    --- requires serial data applying to smartpin 55
    --- 921600 baud, 8 bit, no parity, 1 stop bit
    
    : TEST
    RXINIT
    CRLF
    BEGIN
        5000 SDRX-TO
        IF
            ."  timeout! "
        ELSE
            EMIT
        THEN
    KEY UNTIL
    ;
    
    

    I had a need for a timeout, as a means of synchronising the receipt of a stream of longs from a windows p.c. When timeout occurs, taqoz will know that a new long is about to be received as four bytes.

    N.B. When testing serial input routines out, you may not have enough time to display debug results. e.g. If a serial input is running at full speed at 921600 baud, you will miss serial input data if you try to display stuff on the user terminal, because it also runs at 921600 baud! To fix that, you might:-
    1. Introduce a timed gap between serial input chars, assuming you have control of the source
    2. Change the serial input baud rate to something low like 9600 baud - that would give a little time for debug display at 921600 baud in between serial input chars
    3. Pass filtered data to another COG for display, via a queue (maybe)

Sign In or Register to comment.