Shop OBEX P1 Docs P2 Docs Learn Events
Debug coexisting with serial output? — Parallax Forums

Debug coexisting with serial output?

RaymanRayman Posts: 14,557
edited 2023-12-02 15:52 in Propeller 2

I was thinking that it'd be convenient to have the newish P2 debug window and regular smart serial output working together.

It seems can use debug window as serial terminal if set baud to 2_000_000.
But, in this little test here, if I add a debug statement then P2 seems to hang.
Or, serial output stops anyway.
Is there a solution for this?

Also: It'd be convenient if the Prop Tool did not require a debug statement to be present in order to launch the debug window...

Comments

  • evanhevanh Posts: 15,848

    Hehe, you'll be throwing a curve ball with that. I think the Debug handler always re-init's the serial smartpins on every call. Any partial transfer will be cut short, which will likely mess with the debug framing as well as lose user data. And of course the user code will also lose the smartpin IN state.

    Flexspin can handle it though. Where using compile option -g instead of -gbrk then it'll handle using both user terminal and debug terminal together. It's a legacy hangover that's still supported.

  • roglohrogloh Posts: 5,752
    edited 2023-12-03 00:03

    I haven't used DEBUG much lately and don't really know its current feature set but if there was a way to use the debug mechanism to identify regular "non-debug" serial data to the PC and then demux it accordingly, then a serial object could be coded to choose to use a suitable transmit path (assuming it knew when DEBUG was active vs not compiled in). There well may need to be a special debug format symbol (the "CHR" format below) or other named tag to identify this case. Sort of like the following pseudocode.

    PUB tx(val)
    #ifdef DEBUG ' run this when DEBUG is enabled
       DEBUG(CHR(val)) ' use the debug path send a character to the regular output terminal in order to sync it with any other serial debug activity
    #else ' directly access smartpin
      wypin(tx_pin, val)
      txflush() 'rja
    #endif
    

    Is there a good way for the compiled code to know when DEBUG is active or not and let it alter its behaviour like this? It might not need to be a conditional compilation approach.

    Note that this idea is only for transmit. The serial receive case still assumes it can access the smartpin hardware directly from a COG taking input from it.

  • RaymanRayman Posts: 14,557

    Hmm didn’t realize debug reset smart pin on every use…

    Maybe it also resets it after use ?
    That might explain what I’m seeing…

    I seem to recall Chip saying this would work, but I’m definitely missing something…

  • Is the DEBUG multiplexing scheme documented anywhere? I wonder if the non-debug data in the serial stream is already being identified via the absence of some given debug "escape" sequence already. If you have to tag each and every non-debug character explicitly as being non-debug and intended for the usual console/terminal it could potentially increase the serial transfer requirements by at least 2x or possibly more depending on the actual scheme, which is not ideal.

  • evanhevanh Posts: 15,848
    edited 2023-12-03 04:36

    There was a change a year or so back to provide settable baud. One or both smartpins now alternate between repository and async-serial mode. So that'll ensure there is no remaining user comms activity. So the debug code now computes the X register clock divider each time as well.

  • RaymanRayman Posts: 14,557

    Ok, seems all I have to do is restart serial like this before using regular serial after a debug call:

    PUB Loop(n) 'Loop Routine
    
      Testing(n)
      waitms(1000)
      ser.start(2_000_000)'115200*2)
      ser.str(@"This is a string for loop #")
      ser.dec(n)  'This causes P2 to hang?
      ser.tx(13) 'carriage return
    

    This might become my new favorite way to use prop tool with serial...
    Don't have to deal with PST... PST is OK for the most part with F12, but doesn't always work like I'd want.
    Plus, can use debug, if needed.
    Think I'll add a fake debug statement to serial driver so don't need one in main code.

  • RaymanRayman Posts: 14,557

    Actually, maybe can make a MyDebug() routine that restart serial after use....

  • RaymanRayman Posts: 14,557

    Above seems to also work in FlexProp using internal PST terminal and "print debug" and baud set to 2MEG.
    But, FlexProp doesn't require restarting serial to work...

  • RaymanRayman Posts: 14,557

    This might be a solution:

    obj   'Objects
      ser : "SimplerSerialDebug"  'For serial diagnostics
    
    
    PUB Main()|nLoop   'Main Routine
      Setup()
    
      repeat
        Loop(nLoop++)
    
    
    PUB Setup()|i   'Setup Routine
    
    
      'Start serial and do countdown
      ser.start(2_000_000)'115200*2)
    
    
    
    PUB Loop(n) 'Loop Routine
    
      ser.dudec(n) 'debug unsigned decimal
      waitms(1000)
      ser.str(@"This is a string for loop #")
      ser.dec(n)  'This causes P2 to hang?
      ser.tx(13) 'carriage return
    

    This some things added to SimplerSerial to make SimplerSerialDebug version:

    DAT  'pins fixed to the usual
      rx_pin long 63
      tx_pin long 62
      baud   long 2_000_000
    
    
    PUB Start(baudrate) | bitperiod, bit_mode  'start using user defined pins
      'Note:  The "mode" parameter, used by fullduplexserial, has been removed
    
      ' calculate delay between bits
      bitperiod := (CLKFREQ / baudrate)
    
    
      ' calculate smartpin mode for 8 bits per character
      bit_mode := 7 + (bitperiod << 16)
    
      ' set up the transmit pin
      pinf(tx_pin)
      wrpin(tx_pin, _txmode)
      wxpin(tx_pin, bit_mode)
      pinl(tx_pin)   ' turn smartpin on by making the pin an output
    
      ' set up the receive pin
      pinf(rx_pin)
      wrpin(rx_pin, _rxmode)
      wxpin(rx_pin, bit_mode)
      pinl(rx_pin)  ' turn smartpin on
    
      baud:=baudrate
    
    
    PUB dUDEC(x)  'Debug an unsigned decimal number
      debug(udec(x))
      start(baud)
    
    PUB dUHEX(x,n)  'Debug an unsigned hexidecimal number
      debug(uhex(x,n))
      start(baud)
    
    
  • RaymanRayman Posts: 14,557
    edited 2023-12-07 22:26
  • RaymanRayman Posts: 14,557

    But, this gets away from Spin2 documentation and makes it hard to explain...
    So, probably just say to use ser.start() after every debug...
    Or, before every serial output.

    Or, maybe can add faster version of ser.start() where smartpin setting have been saved and add that to start of every serial operation. That might break consecutive serial outputs though...

    Wishing there was an easier solution here...

  • Flexspin's built in serial routines for C and BASIC are written to act very much like the debug serial routines, and as a result they are (usually) compatible with debug. For example:

    obj
      c: "libc"
    
    pub main() | a
     a := 1
     c.printf(@"using printf: a = %d ...", a)
     debug("using debug: ", sdec(a))
     c.puts(@"using puts")
     debug(sdec(a+1))
     c.puts(@"done")
    

    outputs:

    Cog0  INIT $0000_0000 $0000_0000 load
    Cog0  INIT $0000_0404 $0000_0000 load
    using printf: a = 1 ...Cog0  using debug: a = 1
    using puts
    Cog0  (a + 1) = 2
    done
    
  • evanhevanh Posts: 15,848

    Good to know. I guess I never tested -gbrk like that.

  • RaymanRayman Posts: 14,557
    edited 2023-12-20 16:52

    Think that maybe this is working and can also work with Spin Tools IDE and FlexProp.
    Looking like the most portable way is to send both CR and LF.

    Added these functions to help:

    PUB crlf() 'send CR and LF
      tx(13) 'CR
      tx(10) 'LF
    
    
    PUB  println(p) 'print a string and then do CRLF
      str(p)
      crlf()
    

    But, do need to turn off the line feed handling in PST if want to use that instead of Prop Tool debug.
    Also, need to switch back to ANSI terminal option in FlexProp.

  • RaymanRayman Posts: 14,557
    edited 2023-12-24 18:20

    Guess feeling moderately happy with SimplestSerial. At least for new users of Prop Tool, makes serial output easy.
    Was going to post this in OBEX, but that is locked?

    Added this to my "Getting started with SimpleP2 and Spin2 guide". Going to see if my kids can follow it..

  • RaymanRayman Posts: 14,557

    Was just testing this out some more with Prop Tool debug window and appears the only real issue is using Spin2 debug statements.
    The program can freeze if you don't call ser.Begin() after a Spin2 debug statement.

    Assembly debug statements don't seem to be an issue.
    Coginit and cogspin both emit some serial output that can get jumbled if a delay is not added after these, but it stays on the rails without it.

    Attached are some more demo/tests.

  • RaymanRayman Posts: 14,557

    Posted it to OBEX. See now there's a 24 delay before you can do that...

Sign In or Register to comment.