flexspin compiler for P2: Assembly, Spin, BASIC, and C in one compiler

17172737577

Comments

  • evanhevanh Posts: 10,230
    edited 2021-01-11 06:49
    It could be the receiver not keeping up. Try a slower baud. If there is bit drops the receiver could even loose track of the start-stop framing bits. Without an idle break there is no way to re-identify the framing.

    EDIT: I just compiled that example as is. It seems to run fine for me. Loop count is over 4000 and still looks the same. eg:
    ...
    
    =================================================================================================
    =================================================================================================
    =================================================================================================
    =================================================================================================
    =================================================================================================
    Loop Count: 4868
    
    =================================================================================================
    =================================================================================================
    =================================================================================================
    =================================================================================================
    =================================================================================================
    Loop Count: 4869
    
    =================================================================================================
    =================================================================================================
    =================================================================================================
    =================================================================================================
    =================================================================================================
    Loop Count: 4870
    
    =================================================================================================
    =================================================================================================
    =================================================================================================
    =================================================================================================
    =================================================================================================
    Loop Count: 4871
    
    ...
    
  • evanhevanh Posts: 10,230
    edited 2021-01-11 07:16
    FlexSpin version string: Version 5.0.2-beta-v5.0.1-6-ge3b2ba02 Compiled on: Dec 7 2020
    Loadp2 version string: version 0.043 Dec 20 2020

    PS: Loadp2 user baud was set to Eric's preferred 230400. I'm guessing that's same for you given there's nothing changing the baud in the program.

  • ersmithersmith Posts: 4,590
    @JRoark: I can't seem to reproduce the corruption on my system either. I think @evanh is right, it's most likely a PC side issue (the PC is not keeping up with the data). What baud rate are you running at?
  • JRoarkJRoark Posts: 626
    edited 2021-01-11 06:03
    This is interesting, and I think @ersmith and @evanh are right. While playing with this, I noticed something: after a couple of minutes, when the program terminated normally, the blue usb activity LED stopped blinking about 5 seconds BEFORE the screen stopped scrolling. So the terminal program is slow and buffering, and I’ll bet you dollars to donuts its wrapping the buffer. As a test I scattered some delays in between the PRINT statements and sure enough, all of the “problems” disappeared.

    BTW: this is running on Win10 on a Dell laptop with the USB link speed set to 256k. The laptop isnt exactly slow, so I’ll keep poking at this. It would be nice to debug at full speed.

    Thank you both for your help!

    EDIT: There is definitely something happening on the PC side with buffering, and when this happens the PC apparently signals down the USB channel and kills the P2-EVAL. The effect is the same as if you'd closed the debug window in FlexGUI. With delays inserted in the code to allow the PC to catch up, it's a non-issue. As the baud rate increases, so must the value of any delay inserted between print statements. Things seem solid with a 15 mS delay between PRINT statements, regardless of baud rate. Where do I go from here?
  • RaymanRayman Posts: 11,690
    Might want to check the Advanced Settings in Device Manager for the USB Serial Port.
    there are buffer size settings and some other things there...
  • ersmithersmith Posts: 4,590
    @JRoark : Maybe we should step back a bit and figure out what you want to accomplish. If you're sending a large amount of data from the eval board to the PC, perhaps it makes sense to write it into a file using the 9p file system? There's some flow control built in to that so it shouldn't encounter the same problems as the regular terminal.
  • RaymanRayman Posts: 11,690
    I've been bitten a couple times now by the shift operators like << having the lowest precedence in C whereas they have about the highest precedence in Spin1&Spin2.

    Guess I'm biased, but I wish C gave shifts a high precedence like Spin2.
  • RaymanRayman Posts: 11,690
    Is there a C way to use the Spin2 GETRND() function?
  • JonnyMacJonnyMac Posts: 7,323
    edited 2021-01-11 09:47
    There is a PASM2 getrnd instruction -- couldn't you just inline it?
    int getrnd() 
    {
       int x;
       __asm {
          getrnd x
       };
       return x;
    }
    
  • RaymanRayman Posts: 11,690
    Guess I'll try that. Not clear to me that this is initialized to random ADC noise like the Spin2 version is, but maybe it is...
  • JonnyMacJonnyMac Posts: 7,323
    edited 2021-01-11 09:53
    If you've downloaded the PNut folder you should have the Spin2 interpreter source in it. I explore this a lot, trying to get a handle on how Chip does things. I think the little code snippet above will behave just as Spin2 based on what the interpreter is doing.

    getrnd.png
    1188 x 475 - 46K
  • RaymanRayman Posts: 11,690
    Ok, thanks. And I see in the P2 docs that it should work.
    Tried this and seems to work:
        int r;
        __asm {
            getrnd r
        }
        r &= 0x3fffffff;
    

    That last line is something that C's rand() does for you automatically.
    Found out the hard way that my code explodes if you don't do that.
    Probably something about negative numbers messing things up...

    Not sure why FlexSpin C RAND_MAX value is 0x3fffffff and not 0x7fffffff though...
  • JonnyMacJonnyMac Posts: 7,323
    I've run into problems with negative random numbers in Spin1, so I tended to do a right shift to force 0 into the sign bit to resolve them.
  • ersmith wrote: »
    @JRoark : Maybe we should step back a bit and figure out what you want to accomplish. If you're sending a large amount of data from the eval board to the PC, perhaps it makes sense to write it into a file using the 9p file system? There's some flow control built in to that so it shouldn't encounter the same problems as the regular terminal.

    Good point, Eric. The back story: this all started when I rewrote all the FlexBASIC string functions for speed. To flush out any memory leaks or misbehaviors I ran a test program in a continuous loop. Basically I was just banging the bejeepers out of the string libraries trying to break them. And I broke it spectacularly. And randomly. No real pattern. It felt like a memory problem, but after a deep inspection of my code, I started getting a feeling that my code was (mostly) ok. And then EvanH and you both twigged to the idea that this was really a PC comm issue. And indeed it was.

    So what I’m really trying to do is to break things in a way that lets me study the output so I can see what broke. For realtime use I’ve already changed to printing to the VGA driver Eric wrote. For unattended testing I may use 9p.

  • Rayman wrote: »
    Might want to check the Advanced Settings in Device Manager for the USB Serial Port.
    there are buffer size settings and some other things there...

    Your comment resulted in me following some interesting rabbit trails down in the bowels of Windows, but in the end nothing I did really made any difference. The USB latency timer seemed promising initially but ultimately made no real difference. Still, it was a useful exercise and I do appreciate the input.

  • ersmithersmith Posts: 4,590
    Rayman wrote: »
    Is there a C way to use the Spin2 GETRND() function?

    It's called _rnd() and is declared in <propeller2.h>. It should probably be renamed _getrnd(), but we (forum users) made the propeller2.h file definition back when the function was still RND() in Spin2.
  • RaymanRayman Posts: 11,690
    edited 2021-01-12 02:08
    Thanks @ersmith. Does this do the AND with RAND_MAX?

    If not, maybe _rnd() can add RAND_MAX and _getrnd() can be without that?

    Also, why is RAND_MAX not $7FFF_FFFF?
  • ersmithersmith Posts: 4,590
    Rayman wrote: »
    Thanks @ersmith. Does this do the AND with RAND_MAX?
    No, and in C (as opposed to Spin) it's not really so necessary, since C has unsigned integers.
    Also, why is RAND_MAX not $7FFF_FFFF?

    I think it's due to the pseudo-random number generator (in rand.c) making some of the bits very predictable e.g. it would always alternate positive / negative. Masking out the upper bits hides that. It's not an issue for _getrnd() or _rnd(), there's no need to mask those.

  • RaymanRayman Posts: 11,690
    Right, I didn't think about using unsigned type...
    Ok, I've replaced code above with this and seems all OK:
    uint32_t r = _rnd();
    
  • RaymanRayman Posts: 11,690
    Just thinking about Variadic functions...

    Can I use these as a poor man's polymorphism?
    I have a function that is currently in 3 different forms to accept 2, 3 or 4 integer arguments.

    Can I combine them into one using Variadic form?

    Might be more work that it's worth though, even if it possible...
  • ersmithersmith Posts: 4,590
    Yes, variadic functions are the standard way in C to have a function with different number of arguments.

    In C++ (and FlexC) there's another option, to declare default values for arguments, e.g.:
       int foo(int x, int y, int z=98, int w=99) { ... }
    
    can be called as "foo(1, 2)", "foo(1,2,3)" or "foo(1,2,3,4)". The first two expand to "foo(1, 2, 98, 99)" and "foo(1, 2, 3, 99)" respectively.
  • RaymanRayman Posts: 11,690
    @ersmith Thanks. This foo(...) way works, this is perfect. Think I tried a couple weeks ago and couldn't make it work, but must have done something wrong... Works now.
  • RaymanRayman Posts: 11,690
    Long filenames work! As @ersmith said, you just add -DFF_USE_LFN=1 to the command line.
    Finally free from 8.3 filenames... Now, we just need to be able to use different pins for the uSD...
  • ersmithersmith Posts: 4,590
    There's documentation on the SD card file system now in general.pdf:
    If you define the symbol `FF_USE_LFN` on the command line with an option like `-DFF_USE_LFN` then long file names will be enabled for the SD card.
    
    The pins to use for the SD card may be changed by changing the following defines on the command line:
    ```
    PIN_CLK  (default 61)
    PIN_SS   (default 60)
    PIN_MOSI (default 59)
    PIN_MISO (default 58)
    ```
    So for example to change to using pins 0-3 for these you would add `-DPIN_MISO=0 -DPIN_MOSI=1 -DPIN_SS=2 -DPIN_CLK=3` to the command line.
    
    The docs don't say, but should, that if you redefine any of the PIN_* symbols then you should redefine them all.
  • RaymanRayman Posts: 11,690
    Perfect! BTW: I just did a quick compile test and it looks like adding 8.3 uSD support adds about 20 kB to program size and adding long filenames adds about 10 kB on top of that.
  • Possible bug in flexprop spin2 compiler:

    This code runs as expected with the Prop tool, however only returns the pin status of the basepin for dpins, apins, cpins, all other pins return 0.
    Not sure if it is addpins , pinfloat, or readpin.

    In the code below, it never sees a value of 3 on the cpins. ie P25 high and P24 low. Only sees P24 go high. So it never exists the loop looking for that status.
    CON
      PINBASE = 48
    
      _clkfreq = 250_000_000
    
    
      dpins = 0 addpins 7  ' CoCo Databus pins
      apins = 8 addpins 15 ' CoCo Addressbus pins
      cpins = 24 addpins 1 ' CoCo Clock pins
    
    DAT
    
    abus word 0
    dbus byte 0
    cbus byte 0
    
    
    OBJ
       scrn: "ansi"
    
    
    
    PUB runtext() | n
    pinfloat(dpins)
    pinfloat(apins)
    pinfloat(cpins)
    
    scrn.start(PINBASE)
    scrn.str(string(27, "[1;1H"))
    scrn.str(string(27, "[0J"))
    scrn.hideCursor()
    
    repeat
        repeat until cbus == 3
          cbus := Pinread(cpins)
        abus := Pinread(apins)
        repeat until cbus == 2
          cbus := Pinread(cpins)
        dbus := Pinread(dpins)
    
    
        scrn.str(string(27, "[1;1H"))
    
        scrn.nl()
        scrn.str(string("Address bus:"))
        scrn.hex(abus,0)
        scrn.nl()
        scrn.str(string("Data bus:"))
        scrn.hex(dbus,0)
        scrn.nl()
        scrn.str(string("Clock:"))
        scrn.hex(cbus,0)
        scrn.nl()
    
    
  • AJLAJL Posts: 359
    P25 high with P24 low will read as cbus == 2 unless you have inverted P24 in the pin setup.

    You haven’t given us a full description of the output of your code, so I’m not sure how much help can be given.
  • AJL wrote: »
    P25 high with P24 low will read as cbus == 2 unless you have inverted P24 in the pin setup.

    You haven’t given us a full description of the output of your code, so I’m not sure how much help can be given.
    Correct. It never reads 2 or 3 just 0 or 1. Even bypassing that check, all of of the bus lines are 0 or 1, even if they are actually FFFF, FF, and 03.

  • ersmithersmith Posts: 4,590
    ke4pjw wrote: »
    Possible bug in flexprop spin2 compiler:

    This code runs as expected with the Prop tool, however only returns the pin status of the basepin for dpins, apins, cpins, all other pins return 0.
    Not sure if it is addpins , pinfloat, or readpin.

    It's readpin, unfortunately. It's only reading a single pin. There's an interesting story behind that: for both pinwrite and pinread, handling multiple pins is much more complicated than handling a single pin. One pin operation can be translated to a single assembly instruction (testp in the case of readpin) but multiple pins requires using the hardware registers and shifting and masking. I implemented the pinread code back when only one pin was supported in Spin2, and forgot to update it when Chip changed the language.

    It'll be fixed in the next release of the compiler, although alas this fix will come at a performance cost for the common case of reading a single pin.

    For now, you can use the replacement function below (it should work in PNut/PropTool as well):
    pub mypinread(x) : y
      y := (x & $20) ? outb : outa
      y >>= x       ' implicitly relies on only bottom 5 bits being used
      x >>= 6       ' now x has number of pins to use
      y := y ZEROX x
    

    It's interesting to compare the assembly generated by flexspin for this with the code for pinr_ in Chip's interpreter. The interpreter code reads:
    pinr_		testb	x,#5	wc	'read ina or inb
    	if_nc	mov	y,ina
    	if_c	mov	y,inb
    
    		ror	y,x		'lsb-justify
    
    		shr	x,#6		'trim
    		zerox	y,x
    
    	_ret_	mov	x,y		'result in stack top
    
    The flexspin compiled version looks like:
    _mypinread
            test    arg01, #32 wz
     if_ne  mov     _var01, outb
     if_e   mov     _var01, outa
            mov     result1, _var01
            shr     result1, arg01
            shr     arg01, #6
            zerox   result1, arg01
    _mypinread_ret
            ret
    
    Which would be the same number of instructions except for the "ret" at the end; one of these days I'll have to add an optimization pass to get rid of ret when possible.
  • ersmith wrote: »

    It'll be fixed in the next release of the compiler, although alas this fix will come at a performance cost for the common case of reading a single pin.

    Thanks for the quick fix with the spin code, I will give it a try later today!

    I wonder if there could be any optimization that could be done at compile time to determine if only one pin is being used or not.
Sign In or Register to comment.