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

16061626466

Comments

  • I think u are right...
    I added in 64 sets of braces and seems to be working...
  • Is ftell() something that FatFs should be providing?
  • Rayman wrote: »
    I just dug up a jpeg decoder that worked under GCC on P1...

    It seems to choke on initializing the 2D int array in the attached...

    Gives this error: >fft.c:3: error: wrong kind of initializer for array type

    Should one be able to declare a 2D array like this:
    int fft[64][64]={
    
       +8192,   +8192, ...  (lots of more integers here)
    

    Yes, that is still legal C (although I think it's deprecated in favor of grouping the numbers into the appropriate sub-arrays). As it happens I'm working on the initializer code now to support C99 designators like ".x = 2" or "[1] = 99" to initialize specific struct or array elements, and I've fix that as well.
    Rayman wrote: »
    Is ftell() something that FatFs should be providing?

    Not fatfs per se, but rather the higher level code: stdio is currently missing fseek() and ftell(). These should be easy to implement in terms of the lower level lseek() function.

    I've attached an updated fastspin with these changes. fseek() and ftell() are in include/libc/stdio/fseek.c, and are completely untested. Caveat emptor!

  • Great! I'll try it. I think I got that jpeg decoder to work. But, it doesn't have a license, so might switch to picojpeg...

    These codes both seem to use fseek and ftell... the later just to get the filesize, which seems like a roundabout way of doing that...
  • picojpeg works! I don't know why, but I find it amazing when big C code works with P2 so easily...
  • Rayman wrote: »
    picojpeg works! I don't know why, but I find it amazing when big C code works with P2 so easily...

    Great news! I'm glad you got it to work. fastspin C is getting a little more usable every day, thanks for your bug reports.
  • Wonder if I could do:
    #define printf debug
    
    In order to automagically turn off serial output when debug isn't on...
  • ersmithersmith Posts: 4,394
    edited 2020-09-12 - 01:15:06
    Rayman wrote: »
    Wonder if I could do:
    #define printf debug
    
    In order to automagically turn off serial output when debug isn't on...

    Not in C; "debug" is a Spin only feature.

    The usual approach in C is to do something like:
    #ifdef USE_DEBUG
    #define debug(_x) printf _x
    #else
    #define debug(_x)
    #endif
    
    and then insert statements like:
       debug(("the value of x is %d", x));
    
    which will be turned on/off by defining USE_DEBUG on the command line or in a header file.

    Note the double parens to make the whole contents of the macro into one symbol. You could make this cleaner by using a varargs macro, but I can never remember the syntax for those.
  • Ok, sounds like you can't redefine printf, but you can redefine debug.
  • Possible bug in fastspin, compiling code with secondary object that contains inline assembly...

    Although I'm able to compile JonnyMac's "jm_time_200.spin2" file on its own, I get compile errors when that file is used as an object from another spin2 file such as: "jm_rgbx_pixel_demo.spin2". Sources from GIT OBEX are attached:

    jm_time_200.spin2 compiled on its own:
    "flexgui/bin/fastspin" -2 -l -D_BAUD=230400 -O1   -I "flexgui/include" -I "flexgui/include/spin" -I "source/propeller/libraries/community/p2/All/jm_serial" -I "source/propeller/libraries/community/p2/All/jm_full_duplex_serial" -I "source/spin2cpp/include"  "Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2"
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2020 Total Spectrum Software Inc.
    Version 4.3.1 Compiled on: Aug 26 2020
    jm_time_200.spin2
    jm_time_200.p2asm
    Done.
    Program size is 1336 bytes
    Finished at Sat Sep 12 05:42:40 2020
    

    jm_time_200.spin2 compiled as an object from jm_rgbx_pixel_demo.spin2:
    "flexgui/bin/fastspin" -2 -l -D_BAUD=230400 -O1   -I "flexgui/include" -I "flexgui/include/spin" -I "source/propeller/libraries/community/p2/All/jm_serial" -I "source/propeller/libraries/community/p2/All/jm_full_duplex_serial" -I "source/spin2cpp/include"  "Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_rgbx_pixel_demo.spin2"
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2020 Total Spectrum Software Inc.
    Version 4.3.1 Compiled on: Aug 26 2020
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:113: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:114: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:116: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:116: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:117: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:117: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:118: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:118: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:119: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:119: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:120: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:121: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:122: error: Variable ms must be placed in memory (probably due to an @ expression) and hence cannot be accessed in inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:124: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:125: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:126: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:129: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:129: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:130: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:130: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:131: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:131: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:132: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:132: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:133: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:134: error: Operand too complex for inline assembly
    Desktop/jm_rgbx_pixel/jm_rgbx_pixel_demo/jm_time_200.spin2:135: error: Operand too complex for inline assembly
    jm_rgbx_pixel_demo.spin2
    |-jm_time_200.spin2
    |-jm_rgbx_pixel.spin2
    |-|-jm_gamma8.spin2
    child process exited abnormally
    Finished at Sat Sep 12 05:43:28 2020
    
    This code builds completely in PNut.v34z

    dgately
  • Is wordfill() supposed to change the value of the provided address argument?
    I have this:
    wordfill(pBuff,$FFFF,640*350)
    

    It appears to be modifying the value of pBuff after use... That's not right, is it?
  • Setting the clock to 250 MHz like this doesn't seem to work... Other values like 200, 240 work..
    #define P2_TARGET_MHZ 240
    #include "sys/p2es_clock.h"
    
    // -----------------------------------------------------------------------------
    int main()
    {
        //set the clock
        _clkset(_SETFREQ, _CLOCKFREQ);
    
  • @dgately : That inline assembly is using array references, and in fastspin arrays are placed in hub memory. It's going to be some time before I can correct it. The "submodule" issue is a red herring, the method using that inline assembly was being removed before.

    @Rayman : wordfill does not change its first argument. My guess is that it's overrunning the provided buffer and corrupting the stack or something like that.
  • RaymanRayman Posts: 11,282
    edited 2020-09-12 - 19:54:58
    There's something I don't understand going wrong with this 16bpp bmp example if I move the VGA.start() to before uSD mounting...

    If this section is moved first:
    [b    //Start up VGA
        int cf = _clockfreq();
        printf("clock freq= %d\n", cf);
        Vga.Start();  //Note:  cog# and basepin are currently set in VGA_16bpp.spin2 (also note that clock setting there must match what is here).[/b]
    

    The embedded bitmap file appears to have been moved in memory (but I think this is unlikely).

    Files are here: https://forums.parallax.com/plugins/FileUpload/images/file.png

    Update: It looks like Vga. just needs to be called before mounting uSD. I added this simple function to set the cog# for VGA and it works when I call it before mounting uSD.
        Vga.Config(1,0);//Config(cog,basepin)'
    
    4032 x 3024 - 4M
  • Also, I'm trying to figure out how to pass the clock frequency from C into Spin2 in order to calculate fset value...
    Currently doing it like this in CON section:
      fclk          = 200_000_000*1.0  'Note:  Make sure this matches FlexC
      fpix          = 25_000_000.0
      fset          = (fpix / fclk * 2.0) * float($4000_0000)
    

    I've tried a few ways of calculating fset in Spin2, but nothing seems to work...
    Maybe because it's floating point...

    I guess I can figure this out myself, but just thought you might already know how to do this...
  • Sorry, one other strange thing...
    I've made vsync an assembly register instead of a constant.
    Then, I set it to actual value before starting the assembly driver cog.

    This works like this:
    vsync           long     1
    

    but not like this:
    vsync           res     1
    

    Shouldn't it work either way?
  • Rayman wrote: »
    Also, I'm trying to figure out how to pass the clock frequency from C into Spin2 in order to calculate fset value...
    You can use #define and #include in both C and Spin2, so the easiest way is to make a header file "freq.h" like:
    #define RUNFREQ 200000000
    
    and then #include this in both your C and Spin2 code, and use RUNFREQ everywhere that you used to use the constant 200_000_000. NOTE: do not put any comments into the freq.h header file, C and Spin have different kinds of comments!


    Rayman wrote: »
    Sorry, one other strange thing...
    I've made vsync an assembly register instead of a constant.
    Then, I set it to actual value before starting the assembly driver cog.

    This works like this:
    vsync           long     1
    

    but not like this:
    vsync           res     1
    

    Shouldn't it work either way?

    No, because if you're setting it before starting the cog then you need to have storage for it. Basically anything defined with "res" is only valid *inside the cog code where it is defined*; outside of it it's undefined.
  • RaymanRayman Posts: 11,282
    edited 2020-09-12 - 22:00:30
    Thanks, i should have known about res...

    What do you make of the order of calling sd code and vga code making a difference?

    Seems to mess up address of bmp file include...
  • Rayman wrote: »
    Thanks, i should have known about res...

    What do you make of the order of calling sd code and vga code making a difference?

    I have no idea what's going on there, and haven't really had time to look at it. Maybe there's a timing dependence? Or one is accidentally writing into memory that the other one is using?
  • I’m wondering if it’s something with the file directive and the label I put there to tell where it is getting messed up
  • @Rayman : I can't see your code, the link you posted just points at a picture (.png).

    @dgately : I've updated github with some fixes to inline assembly which may help with your object. At least, it compiles now, although I don't have hardware to test it.
  • @Rayman: It looks like there's a race condition in your VGA COG code, which you start up with:
    PUB Start()|pBuff
        pBuff:=@BmpBits+70
        coginit(vga_cog,@VgaOrigin, @pBuff) 
    
    pBuff is a local variable, so as soon as the Start() function returns it's no longer valid (other things could be written on the stack). That means the VGA cog might get the wrong data for it. To avoid this, either put a short delay after the coginit(), or use a variable in the VAR section to pass the information to the COG. I also see the COG reads two longs from ptra, but only the first one is actually valid (there's only one piece of data located at address @pBuff, namely the value "@BmpBits+70".
  • Interesting... thanks for figuring it out.
  • I figured out how to calculate the pixel transfer frequency in FlexC:
        //Configure VGA driver cog and pins 
        float fpix = 25000000;
        float fclk = _clockfreq();
        float fset = (fpix / fclk * 2.0) * ((float)(0x40000000));  //pixel transfer frequency
        int iset = (int)fset;
        int VgaCog = 1;
        int VgaBasePin = 0;
        Vga.Config(VgaCog, VgaBasePin, iset);//Config(cog, basepin, xfreq)'
    

    Thinking it's better this way...
  • ersmith wrote: »
    @dgately : I've updated github with some fixes to inline assembly which may help with your object. At least, it compiles now, although I don't have hardware to test it.
    That change appears to work!
    NeoPixelLEDsP2.png

    Thx!
    793 x 595 - 1008K
  • Are variables declared in order in FlexC guaranteed to be contiguous in memory?

    Or, do I need to make a structure for that?
  • Any chance of one day getting something like GDB working with FlexC?

    If not, maybe some kind of interactive thing in the terminal?
  • The picojpeg code I'm working in does include on a C file like this:
    #include "stb_image.c"
    

    I've never seen this before... Web seems to say it's not so good. But, from my understanding I don't see anything wrong with it and it seems to work...

    I'm a bit tempted to do more of that to clean up my main C file to just have main() in it...
    How bad is this?
  • Rayman wrote: »
    Are variables declared in order in FlexC guaranteed to be contiguous in memory?

    Or, do I need to make a structure for that?

    You need to make a structure.
    Rayman wrote: »
    Any chance of one day getting something like GDB working with FlexC?

    If not, maybe some kind of interactive thing in the terminal?

    I really hope Parallax (i.e. Chip I guess) makes a real debugger for the P2. The Spin2 DEBUG() statement is nice, but it's really just a fancy form of printf debugging. If that happens then I'll try to support it in fastspin.
    Rayman wrote: »
    The picojpeg code I'm working in does include on a C file like this:
    #include "stb_image.c"
    

    I've never seen this before... Web seems to say it's not so good. But, from my understanding I don't see anything wrong with it and it seems to work...

    I'm a bit tempted to do more of that to clean up my main C file to just have main() in it...
    How bad is this?

    It's legal and it will work, but it seems to be considered poor style. OTOH for your code you should do what you want.
Sign In or Register to comment.