Shop OBEX P1 Docs P2 Docs Learn Events
Serial (and debug) PASM Object — Parallax Forums

Serial (and debug) PASM Object

As an extension to the Serial/Debug routines in hub ROM, I've been thinking about making this a cog standalone object.

In my programs I make extensive use of the ROM routines to output as well as debug the code.

I was thinking of using the following hub mailbox for communication between pasm and/or spin programs. Any cog (ie multiple cogs) can access the routines but beware as there is no contention between multiple users.

Here is the proposed hub mailbox interface.
'' +--------------------------------------------------------------------------+
'' | HUB Interface:                                                           |
'' +--------------------------------------------------------------------------+
'' |  +0:  _ser_x  long  data                                                 |
'' |  +4:  _ser_f  long  function parameter                                   |
'' |  +8:  _ser_p  long  address  parameter                                   |
'' | +12:  _ser_p2 long  address2 parameter                                   |
'' +--------------------------------------------------------------------------+
'' | _ser_f = "f" function parameter                                          |
'' | function   | 8 7 6 5 | 4 3 2 1 0 | comment                               |
'' |------------|---------|-----------|---------------------------------------|
'' | idle       | 0 0 0 0 | 0 0 0 0 0 | waiting for command                   |
'' | initialise | 0 0 0 0 | 1 0 0 0 0 | initialise serial...                  |
'' |            |         |           |   _ser_x  = bitper (calc from baud)   |
'' |            |         |           |   _ser_p  = bufad in hub (for Rx buf) |
'' |            |         |           |   _ser_p2 = rxpin<<8 + txpin          |
'' | TxRepeat   | 0 0 0 0 | 1 1 1 1 1 | repeat last Tx command (no params)    |
'' |------------|---------|-----------|---------------------------------------|
'' | TxString   | 0 0 0 1 | 0 0 0 0 0 | display nul-terminated string         |
'' |            |         |           |   _ser_p  = address of string in hub  |
'' |------------|---------|-----------|---------------------------------------|
'' | TxHex      | 0 0 1 0 | 1 . . . . | reverse byte order                    |
'' |            |         | . 1 . . . | space between hex pairs               |
'' |            |         | . . n n n | nnn = digits 1-7, 0 = 8 digits        |
'' |            |         |           | _ser_x = hex (long) to display        |
'' |------------|---------|-----------|---------------------------------------|
'' | TxList     | 0 0 1 1 | 1 . . . . | _ser_p2 = address2                    |
'' |            |         | . 1 . . . |                                       |
'' |            |         | . . 1 . . |                                       |
'' |            |         | . . . 1 . | display as longs                      |
'' |            |         | . . . . 1 |                                       |
'' |------------|---------|-----------|---------------------------------------|
'' | TxBinary   | 0 1 0 0 | n n n n n | nnnnn = no.of digits 1-31, 0 = 32     |
'' |            |         |           | _ser_x = binary (long) to display     |
'' |------------|---------|-----------|---------------------------------------|
'' | TxDecimal  | 0 1 0 1 | 0 n n n n | nnnn = no.of digits 1-10              |
'' | ?          | 0 1 0 1 | 1 x x x x |                                       |
'' |------------|---------|-----------|---------------------------------------|
'' | ?          | 0 1 1 0 | x x x x x |                                       |
'' |------------|---------|-----------|---------------------------------------|
'' | RxString   | 0 1 1 1 | 1 . . . . | echo                                  |
'' |            |         | . 1 . . . | _ser_x  = display prompt              |
'' |            |         | . . 1 . . | _ser_p  = address for recv buffer     |
'' |            |         | . . . 1 . | strip <lf>                            |
'' | RxChar     | 0 1 1 1 | . . . . 1 | single char only (returned in _ser_x) |
'' |------------|---------|-----------|---------------------------------------|

Note: A VGA/USB-Keyboard alternative object would be easy to substitute, without the using programs needing to know if serial or video was being used.
Your thoughts please?

Comments

  • roglohrogloh Posts: 5,787
    edited 2020-07-23 03:38
    Cluso99 wrote: »

    Note: A VGA/USB-Keyboard alternative object would be easy to substitute, without the using programs needing to know if serial or video was being used.
    Your thoughts please?

    What we sort of need (or at least I sort of need), is some type of easy IO redirection flexibility. Chip has put this rather useful SEND function in SPIN2 which can take a variable number of arguments, but unlike "printf" it doesn't take a format string which I find can limit it for printing arbitrary things of interest in a nice way. If there was some layer that could make good use of this SEND and allow more formatting as well as redirection to serial/VGA etc that would be especially useful. Whether that also includes serial from multiple COGs/mailboxes etc, I'm not sure, though it may also be handy for logging/debugging purposed from multiple COGs.
  • Cluso99Cluso99 Posts: 18,069
    edited 2020-07-23 03:53
    rogloh wrote: »
    Cluso99 wrote: »

    Note: A VGA/USB-Keyboard alternative object would be easy to substitute, without the using programs needing to know if serial or video was being used.
    Your thoughts please?

    What we sort of need (or at least I sort of need), is some type of easy IO redirection flexibility. Chip has put this rather useful SEND function in SPIN2 which can take a variable number of arguments, but unlike "printf" it doesn't take a format string which I find can limit it for printing arbitrary things of interest in a nice way. If there was some layer that could make good use of this SEND and allow more formatting as well as redirection to serial/VGA etc that would be especially useful. Whether that also includes serial from multiple COGs/mailboxes etc, I'm not sure, though it may also be handy for logging purposed from multiple COGs.
    On P1 I found it very annoying that there were inconsistencies for calling objects to output.
    eg: fdx.tx(char) vs vga.out(char) etc.

    So we need a consistent interface.

    Next, fdx could be called from spin but not from pasm.

    So this is why we need a hub mailbox. A mailbox should be exposed the same from all languages which is why I asked if micropython can access hub.

    Some of these calls eg TxHex requires more parameters. TxList requires even more.
    BTW TxList does a memory dump in the format shown below. For this, you need to specify a hub address (we're not going to get cog/lut here because it will be from the objects' cog/lut not from the callers' cog/lut), plus an optional 2nd address when more that one line is required.
    01AE0: 70 05 00 00  EC 7C BB B9  0A E0 A4 2D  8A 3A FA A1   'p....|.....-.:..'
    01AF0: 07 95 34 04  09 3E 02 0E  53 CA 27 FC  F4 D2 72 FE   '..4..>..S.'...r.'
    
    I find that I use this call a lot to debug programs.

    So I have aimed for a calling method of providing a list of parameters (up to 4) being passed as longs, and the first parameter being the command, followed by a data long, then optional address1 and optional address2.

    This doesn't do any formatting like a python, C, etc statements do. I am not sure that it wouldn't be best to let the respective languages do the formatting and just pass the characters or string to the object/cog via the mailbox. What do you think?
  • Cluso99 wrote: »
    This doesn't do any formatting like a python, C, etc statements do. I am not sure that it wouldn't be best to let the respective languages do the formatting and just pass the characters or string to the object/cog via the mailbox. What do you think?

    Yeah it's sort of several problems to figure out (and they are coupled):
    1) SPIN2 doesn't support multiple variable arguments in its API except for SEND
    2) SEND potentially allows redirection of output which is very handy
    3) SEND has limited formatting capabilities on it's own, its more for raw strings, chars and numbers.

    We have also no input redirection as there's no corresponding "RECV" for SEND. Something needs to be built for that too.

  • I think JDserial had the nicest mailbox interface,
    write something into the mailbox long <256 it's a character. Everything larger is a zero terminated string address.

    Mike

  • msrobots wrote: »
    I think JDserial had the nicest mailbox interface,
    write something into the mailbox long <256 it's a character. Everything larger is a zero terminated string address.

    Mike

    Ok, yeah that sounds interesting. Maybe jm_serial can be patched to make use of SEND for it's tx redirection. I should take a look at that. One (perhaps minor) issue with a SPIN2 wrapper layer on top of send is that the callers will need to call different named API methods based on their number of arguments. That can be tedious to change each time you need to add new arguments to print etc, and there's probably a limit to the number implemented.
  • Cluso99Cluso99 Posts: 18,069
    edited 2020-07-23 07:11
    msrobots wrote: »
    I think JDserial had the nicest mailbox interface,
    write something into the mailbox long <256 it's a character. Everything larger is a zero terminated string address.

    Mike
    Mike,
    Strings are the easiest to handle after characters.

    What I find I need most often are the hex and list displays. Both of these also have reversal requirements too. So we have a number of parameters that come with them that make them versatile, and it's those features we don't want to have to code every time - just a call with a couple of parameters is all that is necessary.

    So this would be a HEX display call from pasm...
            ...
            mov     f,      #_HEX+_REV+_SP+0        ' TxHex + Reversed + spaces between hex pairs + 0=8 digits
            mov     x,      somevalue               ' hex value to be displayed
            call    #tx
            ...
    '' +--------------------------------------------------------------------------+
    tx      rdlong  tmp,    ##mailbox_f    wz       ' mailbox empty?
      if_z  jmp     #tx                             ' wait for mailbox
            setq    #4-1                            '\ copy parameters (4 longs)
            wrlong  f,      ##mailbox_f
            ret                            wcz
    '' +--------------------------------------------------------------------------+
                            '\ internal mailbox copy...
    f       long    0       '| command
    x       long    0       '| data
    p       long    0       '| hub address pointer
    p2      long    0       '/ hub address2 pointer
    
    and this would be a HEX display call from spin...
    VAR
            long    f, x, p, p2
     
     pub    ...
            f := #_HEX+_REV+_SP+0           ' TxHex + Reversed + spaces between hex pairs + 0=8 digits
            x := somevalue                  ' hex value to be displayed
            print(f, x, 0, 0)               ' print "x" as hex reversed with spaces, 8 digits
            ...
    ..or..
            print(#_HEX+_REV+_SP+0, someval, 0, 0)    ' print "x" as hex reversed with spaces, 8 digits
    
     
     PRI print(f, x, p, p2)
            repeat 
              while LONG[@mailbox_f] <> 0
            longmove(@mailbox_f, @f, 4)     ' copy f,x,p,p2 to mailbox
    
Sign In or Register to comment.