Shop OBEX P1 Docs P2 Docs Learn Events
New version of spin to C++ translator — Parallax Forums

New version of spin to C++ translator

ersmithersmith Posts: 6,095
edited 2012-09-11 01:59 in Propeller 1
I've posted a new version of spin2cpp at http://code.google.com/p/spin2cpp. New in this version (0.7) are:

- Ability to generate a binary .dat file (like bstc's -c option)
- Support for the ^^ operator, and changes to the ? operators to make their outputs exactly like spin's
- A number of bug fixes, especially in the handling of floating point constants and labels within PASM

spin2cpp is a translator from Spin to C++. The resulting C++ code may be compiled with PropGCC. It's an easy way to port objects (including PASM) from Spin to C++. However, it should be noted that spin2cpp is still alpha quality software (if that), and is not an officially supported Parallax product. I'd be happy to hear feedback or bug reports -- please send them via the Google Code page, or via email to me at ersmith AT totalspectrum.ca.

Eric
«1

Comments

  • Dave HeinDave Hein Posts: 6,347
    edited 2012-07-12 16:34
    Eric,

    I used version 0.6 a few days ago to convert the Graphics object in the OBEX at http://obex.parallax.com/objects/55/ . There were a few things I had to fix up to get the code to convert and compile. It encountered a problem with a couple of lookupz instructions. It also had problems with variables that were declared as scalar values in a sequential list, and then accessed as an array by the first variable in the list.

    Dave
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-13 04:55
    This looks just the ticket for the big move from spin to C.

    I thought I would try to break it - hope that is ok :)

    Attached is Kye's SD driver code.

    It is choking on the one line of code that is using the @@ symbol. This isn't something that I use much myself either but in Kye's code it is part of the abort message system so it probably is important.

    I commented that out and it did produce a .h and .c file, but flagged another 18 errors. Still, that is actually very impressive as Kye's code is very complex and uses all sorts of cunning tricks.

    I very much like the way the pasm code has ended up as an array in C.

    I'd very much like to get Kye's code working as it has the ability to "chain" programs (PUB bootpartition) and I am using that extensively when writing "apps" for a touch screen where each app is a precompiled binary and you run it by touching an icon on the screen. I don't entirely understand Kye's code and how it does this but your program did manage to translate it into C.

    Blue sky brainstorming here, but I see Jazzed has come up with a Spin IDE. How cool would it be to translate it to C with this code and compile/download/run with a single click?
  • jazzedjazzed Posts: 11,803
    edited 2012-07-13 09:39
    Dr_Acula wrote: »
    Blue sky brainstorming here, but I see Jazzed has come up with a Spin IDE. How cool would it be to translate it to C with this code and compile/download/run with a single click?
    Eric has already done this for me for SimpleIDE, but unfortunately I had already started the SpinSIDE changes and it will take lots of work to integrate. There is still more work to do before I can include anyone's changes in the repository. I had to turn down a request for access to the repository because of my current relatively stressful work schedule with the program.

    --Steve
  • ersmithersmith Posts: 6,095
    edited 2012-07-13 10:22
    Dave: Thanks for the graphics demo pointer. I've checked in changes to make it compile; I haven't had a chance to run it yet (no TV setup at the moment).

    Dr_Acula: Thank you for Kye's example code. That's an interesting example, and show a weakness in spin2cpp's handling of pointers. I'm going to work on that, and I hope to have it fixed soon.

    Please keep sending me examples of Spin objects that spin2cpp can't handle -- I hope to get it compiling everything that people throw at it one day soon!

    Eric
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-13 17:10
    Please keep sending me examples of Spin objects that spin2cpp can't handle -- I hope to get it compiling everything that people throw at it one day soon!

    Apart from Kye's code (which you are working on, thanks!), I've just tested about ten programs and they are all working fine. Just one error and that is the pasm "fit" command (either on its own or as something like 'fit 496").

    I know it doesn't mean anything in C, but it might be useful down the track. Right now, if you are programming in Spin the fit command would produce an error if the cog code were too big. However, there is coming a time very soon (possibly even now) where you might never run the spin code through a spin compiler. Instead, you might be converting straight to C and running it. In this scenario, it might be useful to produce an error message if the pasm part was too big.

    This program is a great way to learn C++. There is new syntax that is unfamiliar to C89 programmers and indeed to Spin programmers that is not easy to find such as the double colon :: A search on Google reveals; Your search - "::" - did not match any documents. But seeing this in action and comparing line by line with the Spin code and it immediately becomes obvious what this does.

    Another thing that is absolutely amazing to see in action - spin2c does all the objects as well. So it is just one command and all the objects and sub objects are all there as .h and .cpp files. This makes converting the Obex a breeze!

    And also, I think this might be "Big Spin". Specifically, write a huge Spin program that compiles to over 32kilobytes. It won't compile with any of the existing Spin compilers as it would never fit in the propeller. But run it through Spin2C, and then run it in XMM mode on any propeller board with an SD card and it should run just fine.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-13 20:01
    Ok, working through this. Off on a tangent for an hour with this thread http://forums.parallax.com/showthread.php?141214-SpinSIDE-Test-Preview/page2 and still a bit confused about this, but now using F4 a lot to completely reset a project.

    1) Start with this demo code
    CON
    
    
      _clkmode      = xtal1 + pll16x                        ' use crystal x 16
      _xinfreq      = 5_000_000
      ' serial port speeds
      _baudRateSpeed = 115200 ' don't use Teraterm at 115200 and possibly even 38400. Use Shamcom/hyperterminal or vb.net
      _receiverPin = 31
      _transmitterPin = 30  
    
    OBJ
     sio:           "pcFullDuplexSerial2FC"                 ' Tim Moore and Juergen  Buchmueller
    
    VAR
    
      
    PUB Main 
        sio.AddPort(0, _receiverPin, _transmitterPin, -1, -1, 0, 0, _baudRateSpeed) ' add a serial port for xmodem  
        sio.start                                           
        sio.rxflush(0)                                      ' make sure no data in the buffer
        sio.str(0,string("Hello World"))                     ' send to com port   
    

    This is using a different serial driver just to test Spin2C a bit more

    2) Run this through Spin2CPP and it produces two .cpp and two .h files as in the attachment.

    3) Copy these files to a working directory (I'm using c:\propgcc\myprograms\)

    4) Start SimpleIDE

    5) This next bit is a bit confusing. Starting SimpleIDE may start with the previous project, so the first thing is to try to delete this. The problem is that if you select "New Project" then it creates a .c program, not a .cpp program. So instead, I restarted SimpleIDE, deleted the text from the previous project, then selected "Open File" and opened "Spin2Cdemo.cpp". I needed to change the default to include .cpp as that extension is not in the list. Then I went to Project/Set Project which created the .side file in the working directory.

    6) Bottom left corner, change the compiler from C to C++, and also change to XMMC as this program is going to the SD card.

    7) This is the C program. I think there is something wrong with the line int32_t spin2Cdemo::Main(void)
    #include <propeller.h>
    #include "spin2Cdemo.h"
    
    int32_t spin2Cdemo::Main(void)
    {
      int32_t result = 0;
      Sio.Addport(0, 31, 30, (-1), (-1), 0, 0, 115200);
      Sio.Start();
      Sio.Rxflush(0);
      Sio.Str(0, (int32_t)"Hello World");
      return result;
    }
    

    8) Error message below
    Project Directory: C:/propgcc/Myprograms/SpinC/

    propeller-elf-c++ -o a.out -Os -mxmmc -I . -m32bit-doubles -fno-exceptions -fno-rtti spin2Cdemo.cpp
    c:/propgcc/bin/../lib/gcc/propeller-elf/4.6.1/xmmc/short-doubles/_crtbegin.o: In function `argc_cnt':

    (.init+0x3c): undefined reference to `_main'

    C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccC7PeWr.o: In function `spin2Cdemo::Main()':

    (.text+0x4c): undefined reference to `pcFullDuplexSerial2FC::Addport(int, int, int, int, int, int, int, int)'

    C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccC7PeWr.o: In function `spin2Cdemo::Main()':

    (.text+0x58): undefined reference to `pcFullDuplexSerial2FC::Start()'

    C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccC7PeWr.o: In function `spin2Cdemo::Main()':

    (.text+0x68): undefined reference to `pcFullDuplexSerial2FC::Rxflush(int)'

    C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccC7PeWr.o: In function `spin2Cdemo::Main()':

    (.text+0x80): undefined reference to `pcFullDuplexSerial2FC::Str(int, int)'

    collect2: ld returned 1 exit status

    propeller-load -x a.out
    error: failed to open 'a.out'

    error: load failed

    Could not make AUTORUN.PEX

    Done. Build Failed!

    Click error or warning messages above to debug.

    Check source for bad function call or global variable name `_main'

    C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccC7PeWr.o: In function `spin2Cdemo::Main()':

    (.text+0x4c):


    ADDIT

    More experiments. In the readme.txt it explains that the --main command is needed so added this. Using a batch file
    Spin2cpp --main spin2Cdemo.spin
    Pause
    

    and that is two minuses in front of main (the helpfile says one).

    Now produces this code
    #include <propeller.h>
    #include "spin2Cdemo.h"
    
    int32_t spin2Cdemo::Main(void)
    {
      int32_t result = 0;
      //Sio.Addport(0, 31, 30, (-1), (-1), 0, 0, 115200);
      //Sio.Start();
      //Sio.Rxflush(0);
      //Sio.Str(0, (int32_t)"Hello World");
      return result;
    }
    
    
    spin2Cdemo MainObj__;
    
    int main() {
      return MainObj__.Main();
    }
    

    and this compiles but uncommenting any of the sio. calls causes an error eg
    Sio.Addport(0, 31, 30, (-1), (-1), 0, 0, 115200);
    (.text+0x48): undefined reference to `pcFullDuplexSerial2FC::Addport(int, int, int, int, int, int, int, int)'
    
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-13 23:19
    Found another bug - compile error if the last line of a program is not blank. This gives an error
    PUB start(a) | b ' this program is 2 lines long
         a := b
    

    but this does not
    PUB start(a) | b ' this program is 3 lines long
         a := b
       
    

    Workaround at the moment putting a comment as the last line in a program

    I'm still getting errors with undefined objects. Code has been simplified as much as possible so this can be tested with Code::blocks running GCC as well as SimpleIDE.

    Original spin program called main.spin
    OBJ
     MyObj:           "MyObject"                 
      
    PUB Main
        MyObj.start(1)
    ' end file     
    

    and the object called MyObject.spin
    PUB start(a) | b
         a := b
    ' end file     
    

    Run this through Spin2Cpp with this batch program
    Spin2cpp --main main.spin
    Pause
    
    and it generates four files:
    main.cpp
    #include <propeller.h>
    #include "main.h"
    
    int32_t mainSpin::Main(void)
    {
      int32_t result = 0;
      Myobj.Start(1);
      return result;
    }
    
    
    mainSpin MainObj__;
    
    int main() {
      return MainObj__.Main();
    }
    

    main.h
    #ifndef mainSpin_Class_Defined__
    #define mainSpin_Class_Defined__
    
    #include <stdint.h>
    #include "MyObject.h"
    
    class mainSpin {
    public:
      MyObject	Myobj;
      int32_t	Main(void);
    private:
    };
    
    #endif
    
    MyObject.cpp
    #include <propeller.h>
    #include "MyObject.h"
    
    int32_t MyObject::Start(int32_t A)
    {
      int32_t result = 0;
      int32_t	B;
      A = B;
      return result;
    }
    
    and MyObject.h
    #ifndef MyObject_Class_Defined__
    #define MyObject_Class_Defined__
    
    #include <stdint.h>
    
    class MyObject {
    public:
      int32_t	Start(int32_t A);
    private:
    };
    
    #endif
    

    Go through and comment out the references to #include "propeller.h" and then compile and it gives one error
    C:\Propeller\spintoC\DemoVerySimple\main.o:main.cpp|| undefined reference to `MyObject::Start(int)'|
    ||=== Build finished: 1 errors, 0 warnings ===|

    Any C experts able to help here?
  • ersmithersmith Posts: 6,095
    edited 2012-07-13 23:27
    Dr_Acula wrote: »
    Apart from Kye's code (which you are working on, thanks!), I've just tested about ten programs and they are all working fine. Just one error and that is the pasm "fit" command (either on its own or as something like 'fit 496").
    What's the error message? As far as I know "fit" should be supported; I have a regression test for it, so it's at least partially supported. But perhaps I've missed some cases. If you could provide the failing sample that would be great, I'd like to fix that.

    Thanks,
    Eric
  • ersmithersmith Posts: 6,095
    edited 2012-07-13 23:30
    If you're getting errors about undefined symbols, most likely there are some .cpp files missing from your project. For now you have to manually add all the .cpp files that spin2cpp creates to any SIDE project you're making. So for example if main.spin includes an "sio" object, then your project should include both main.cpp and sio.cpp.
  • ersmithersmith Posts: 6,095
    edited 2012-07-13 23:35
    A few other notes:

    (1) Files have to end with a newline. There doesn't has to be a blank line at the end, but the CR+LF (or CR, on the Mac, or LF on Linux) has to appear at the end of the last line. I'll try to fix this in a future release (it's been a finicky issue that I haven't had time to dig into yet).
    (2) I've updated the google code project (code.google.com/p/spin2cpp) with version 0.8 of spin2cpp. This compiles one fixes the @@ operator and has proper support for lookup/lookdown, so the examples posted above by Dr_Acula and Dave Hein will compile.
    (3) Thanks for catching the documentation error. Unfortunately I let that slip by in 0.8 as well, but I'll fix it in the next release.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-14 02:01
    1) fit gives an error "syntax error at line 5" if I put it on line 5.
    2) Re files needing to end on a newline, I've sometimes cheated with this sort of error and added a blank line at the end as the very first thing. If it needs the line, problem solved, and if there is an extra blank line then the program would not care anyway.
    3) Thanks for doing the @@ - that will open up a lot more code.

    I'm still having trouble compiling the output from Spin2Cpp. I've stripped the spin program back to the bare essentials. It is now a massive 5 lines of code! I tried making the object name the same as the file name but no change there. So, this is the "main" program
    OBJ
     MyObject:           "MyObject"                 
    PUB Main
        MyObject.start(1)
    

    and this is the object
    PUB start(a)  
    

    Run this through Spin2Cpp and it generates the two .cpp and two .h files. There are no other includes. Comment out the propeller.h include (or put it in the directory, it does not matter), but it won't compile. The C++ code is in post #8. GCC gives this error
    C:\Propeller\spintoC\DemoVerySimple\main.o:main.cpp|| undefined reference to `MyObject::Start(int)'|
    ||=== Build finished: 1 errors, 0 warnings ===|
    

    And propeller-elf gives this error
    propeller-elf-c++ -o a.out -Os -mxmmc -I . -m32bit-doubles -fno-exceptions -fno-rtti spin2Cdemo.cpp
    C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cc6GB2a6.o: In function `mainSpin::Main()':
    
    (.text+0x10): undefined reference to `MyObject::Start(int)'
    

    which looks like the same error to me, so it looks like something is not right with the C code being generated.
  • Heater.Heater. Posts: 21,230
    edited 2012-07-14 03:19
    That command is compiling only a single C++ file, spin2Cdemo.cpp and expecting to create an executable a.out.
    So of course any functions/methods in other files are not compiled and linked hence the error.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-14 04:08
    Hi heater,

    Can you explain that in a bit more detail please?

    I thought it might be a matter of replacing #include directives with the text from the file but it is more complex than that. main.cpp includes an include for main.h. But main.h contains two things referencing the object - #include myobject.h and also MyObject Myobject; Hmm - that seems a bit confusing. This is main.h
    #ifndef mainSpin_Class_Defined__
    #define mainSpin_Class_Defined__
    
    #include <stdint.h>
    #include "MyObject.h"
    
    class mainSpin {
    public:
      MyObject	Myobject;
      int32_t	Main(void);
    private:
    };
    
    #endif
    

    And to me it is even more confusing because myobject.cpp has an #include for myobject.h So it seems that myobject.h is being referenced in two different ways.

    I know C doesn't mind if you include an object multiple times but it seems that one of these #includes is redundant.

    I guess this is a computer program producing these four files, so they may not appear the same way if written by hand.

    Bottom line is that I took a huge Spin file with multiple objects and ran it through Spin2Cpp and then tried to compile it with a C compiler (two actually) and the C compilers crashed with multiple errors and so by reducing the code I've got it down to 5 lines of Spin code and it is possible to replicate the error with those 5 lines. The C code that does not work is
    main.cpp
    //#include <propeller.h>
    #include "main.h"
    int32_t mainSpin::Main(void)
    {
      int32_t result = 0;
      Myobject.Start(1);
      return result;
    }
    mainSpin MainObj__;
    int main() {
      return MainObj__.Main();
    }
    
    main.h
    #ifndef mainSpin_Class_Defined__
    #define mainSpin_Class_Defined__
    #include <stdint.h>
    #include "MyObject.h"
    class mainSpin {
    public:
      MyObject	Myobject;
      int32_t	Main(void);
    private:
    };
    #endif
    
    myobject.cpp
    //#include <propeller.h>
    #include "MyObject.h"
    int32_t MyObject::Start(int32_t A)
    {
      int32_t result = 0;
      return result;
    }
    
    myobject.h
    #ifndef MyObject_Class_Defined__
    #define MyObject_Class_Defined__
    #include <stdint.h>
    class MyObject {
    public:
      int32_t	Start(int32_t A);
    private:
    };
    #endif
    

    Eric might have a demo of some simple code that will compile, and/or point out what is wrong with the syntax of the C++ code above.
  • ersmithersmith Posts: 6,095
    edited 2012-07-14 04:59
    Dr_Acula wrote: »
    1) fit gives an error "syntax error at line 5" if I put it on line 5.
    Is the "fit" directive inside a DAT block? That's the only place where it's valid, AFAIK. If I'm mistaken, could you post the file that actually contains it? Something about the context must be causing spin2cpp some trouble, because there are "fit" directives in some of the samples that spin2cpp does compile (for example F32.spin has a "fit 496", and the Test/test76.spin has a "fit 4").
    I'm still having trouble compiling the output from Spin2Cpp.

    You need to add all of the .cpp files to the project. Your command line just has the main one, it does not have the subordinate "MyObject.cpp". The c++ command line should read:
    propeller-elf-c++ -o a.out -Os -mxmmc -I . -m32bit-doubles -fno-exceptions -fno-rtti spin2Cdemo.cpp MyObject.cpp
    
    The command line you posted was missing the second "MyObject.cpp".

    Both the MyObject.h and MyObject.cpp files are necessary. MyObject.h has to be included with #include (which you've done), and MyObject.cpp has to be compiled explicitly (which seems to be missing).

    Eric
  • ersmithersmith Posts: 6,095
    edited 2012-07-14 05:06
    Dr_Acula wrote: »
    I thought it might be a matter of replacing #include directives with the text from the file but it is more complex than that. main.cpp includes an include for main.h. But main.h contains two things referencing the object - #include myobject.h and also MyObject::Myobject; Hmm - that seems a bit confusing.
    The .h file contains declarations telling the compiler about the object -- what methods and variables it provides.

    The .cpp file actually contains the definitions of the object -- how the methods are implemented, and what initial values to give to the variables.

    The two are related, but distinct. Both are necessary because of the way C and C++ work. The objects can be compiled separately, so for example you can compile MyObject.cpp into MyObject.o (the actual executable code), and then link MyObject.o with may different projects. You can see this most clearly with functions from the standard C library, where for example you #include <stdio.h> to tell the compiler about how printf works, but the actual code for printf is not found in that header (it's kept in the library).

    This is different from Spin, where both declarations and definitions are included in the same file. The Spin way of working is conceptually simpler, but requires that all of the source code be processsed every time an object is referred to. The C/C++ way only requires the declarations to be re-processed, and also (in principle) allows the referred to objects to be updated and replaced as long as their interfaces remain the same.

    Eric
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-14 06:48
    Ah, thanks. Need to list all the files. Ok, can do.

    Re "fit", it was the very last line on my program - perhaps it was because there was no crlf after that was causing the error, and not fit itself?
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-14 17:15
    Addit, yes I can confirm that the FIT error is because it was the last line and no crlf after that. So adding a crlf to files would solve the problem.

    Re
    propeller-elf-c++ -o a.out -Os -mxmmc -I . -m32bit-doubles -fno-exceptions -fno-rtti spin2Cdemo.cpp MyObject.cpp
    

    I'm thinking of ways of automating downloads, either with a batch file or a simple command line program that processes text. So - to compile you need a list of all the sub objects. Two options - either write a program to go through each spin program and look for OBJ and then create a list. Another alternative is that Spin2Cpp would already have that list so would it be possible to output this as a text file?
  • jazzedjazzed Posts: 11,803
    edited 2012-07-14 18:11
    Dr_Acula wrote: »
    So - to compile you need a list of all the sub objects. Two options - either write a program to go through each spin program and look for OBJ and then create a list.

    SimpleIDE 0-8-0+ in SPIN mode should give you a list of all files in the project manager pane.

    Dr_Acula wrote: »
    Another alternative is that Spin2Cpp would already have that list so would it be possible to output this as a text file?

    It is possible to have C++ code in header files. This is a less desirable style for many programmers though.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-14 18:28
    Good points there. I was thinking about a comment earlier by jazzed about difficulties integrating Spin2cpp with SimpleIDE. Thinking about batch files and simple command line text parser programs, if you gave a program the name of your main spin routine, and the name of the .side file, that should be enough to create all the files. Run Spin 2cpp. Parse the spin files and extract all the names of sub objects (or there are other ways, such as looking for any new .h and .cpp files that have been created). Use the information in the .side file and the names of the cpp files to create the propeller-elf command line and then run it.

    Obviously this is not as simple as clicking a blue arrow but it could be a half way step towards one-click compile/download/run for spin to C.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-15 04:38
    Hi Eric,

    Found another bug- the post set and post clear. Though cog~ seems to work ok. Anyway, this is the code that doesn't compile
    CON ' i2c driver
      SCL = 28          ' pins never change
      SDA = 29
    
    PUB i2c_Start                   ' SDA goes HIGH to LOW with SCL HIGH
       outa[SCL]~~                         ' Initially drive SCL HIGH
       dira[SCL]~~
       outa[SDA]~~                         ' Initially drive SDA HIGH
       dira[SDA]~~
       outa[SDA]~                          ' Now drive SDA LOW
       outa[SCL]~                          ' Leave SCL LOW
    

    A workaround is to convert all ~~ to :=1 and to convert all ~ into :=0

    Also another thing, how deep does the object nesting go? I've tried compiling my "main.spin" program which calls "myobject.spin" and that works but if I include "mynestedobject.spin" in "myobject.spin" it misses that. Workaround is to compile manually each file (without --main).


    Also - I've gone straight for a big program now. See attached zip. Compiled some of the files separately and hopefully that hasn't lost any glue between them. The nesting order is calc.spin is the main, sub object is touch.spin, and within touch.spin is the sd driver and i2c driver.

    Running the batch program CompileCpp.bat
    propeller-elf-c++ -o a.out -Os -mxmmc -I . -m32bit-doubles -fno-exceptions -fno-rtti calc.cpp touch.cpp SD-MMC_FATEngine.cpp SPI_ASM.cpp
    propeller-elf-objdump -h a.out
    propeller-load -x a.out
    propeller-load.exe -b TOUCH161 -p COM1 -r -z a.out
    pause
    

    gives the following errors (errors all from the first line propeller-elf so subsequent lines could be commented out for the moment)
    C:\propgcc\Myprograms\SpinCCalc>propeller-elf-c++ -o a.out -Os -mxmmc -I . -m32bit-doubles -fno-exceptions -fno-rtti cal
    c.cpp touch.cpp SD-MMC_FATEngine.cpp SPI_ASM.cpp
    SD-MMC_FATEngine.cpp:1077:57: warning: missing terminating ' character [enabled by default]
    SD-MMC_FATEngine.cpp:1077:3: error: missing terminating ' character
    SD-MMC_FATEngine.cpp: In member function 'int32_t SD_MMC_FATEngine::Findslash(int32_t)':
    SD-MMC_FATEngine.cpp:1078:1: error: expected primary-expression before '}' token
    SD-MMC_FATEngine.cpp:1078:1: error: expected ';' before '}' token
    SD-MMC_FATEngine.cpp: In member function 'int32_t SD_MMC_FATEngine::Evaluatepath(int32_t, int32_t)':
    SD-MMC_FATEngine.cpp:1103:29: error: incompatible types in assignment of 'char' to 'uint8_t [12] {aka unsigned char [12]
    }'
    SD-MMC_FATEngine.cpp:1145:34: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
    SD-MMC_FATEngine.cpp:1146:31: error: incompatible types in assignment of 'char' to 'uint8_t [12] {aka unsigned char [12]
    }'
    SD-MMC_FATEngine.cpp:1148:34: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
    SD-MMC_FATEngine.cpp:1149:31: error: incompatible types in assignment of 'int' to 'uint8_t [12] {aka unsigned char [12]}
    '
    
    C:\propgcc\Myprograms\SpinCCalc>propeller-elf-objdump -h a.out
    
    Demo.zip 239.2K
  • ersmithersmith Posts: 6,095
    edited 2012-07-15 17:21
    Thanks for the useful demo example! That's turned up a few bugs -- besides the ~ and ~~ one (which I have checked in a fix for) there are also the problems that were causing SD-MMC_FATEngine.cpp to go wrong:

    (1) Spin treats the following two lines as the same if foo is an array:
    foo := "x"
    foo[0] := "x"
    
    In C or C++ only the analog of the second form is legal. I'll add some code to translate.

    (2) Spin doesn't treat backslashes in strings as anything special, but in C they are an escape character to indicate something special is following. Again, I'll have to add some code to translate.

    (3) As you noticed, only one level of objects seems to be converted. I'm pretty sure multiple levels were working before, so I think I've broken this with some recent changes.

    Thanks for the bug reports!

    Eric
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-15 21:40
    Thanks++ for looking at this. I kind of feel bad trying to break your software! But on the other hand I think this is a very exciting development that is so close to working now. I look forward to the latest code update :)
  • ersmithersmith Posts: 6,095
    edited 2012-07-17 15:32
    Thanks for your patience and bug reports. I've uploaded a new version (as usual it's at http://code.google.com/p/spin2cpp). This one should fix all of the bugs mentioned so far in this thread. I've also added some new options. The --files option prints a list of the .cpp files that are produced. The --elf option automatically invokes propeller-elf-gcc, assuming it is on your PATH, to create an executable file (ELF) that can be loaded with propeller-elf. So for example to compile the Count.spin demo using XMMC mode and -Os optimization, do:
    spin2cpp --elf -Os -mxmmc Count.spin
    
    This produces an a.out file. Not all gcc options are passed through yet, but I think the common ones are.

    Eric
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-17 15:56
    Sounds great - I can't wait to get home from work and check this out :)
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-17 18:31
    I haven't had a chance to test on a real board yet, but great to see it all compiles. Just to double check, in the touch.cpp file that is created, in the data array for the pasm code
    uint8_t touchSpin::dat[] = {
    
    most of the data at the beginning seems to be 0x00. Is that correct?

    Update - testing on a real board - compiles and downloads but the program does not run. I'll need to put in a serial debugging routine and start debugging to see where it is going wrong (lots of things to test out, Kye's SD driver, cog loading etc etc).

    Addit - off on a tangent, can you please test the attached zip, getting a number of "stray" errors when compiling this.


    Meanwhile, I've discovered why the large program is not running - it hangs when it starts Kye's SD driver. I believe this would be because the C code is running in XMM cached mode which is also using an SD driver. So the options solving this would be i) rewrite all code to use the internal C SD driver rather than Kye's driver, or ii) think about a command of some sort to disable and renenable caching or iii) use techniques already discussed whereby entire blocks of code are loaded into hub and hence are protected from caching or iv) cache from external ram rather than SD.

    This is going to require some thinking. Some of the above problems will also apply if one uses other SD code like fsrw.
  • ersmithersmith Posts: 6,095
    edited 2012-07-18 05:01
    Dr_Acula wrote: »
    I haven't had a chance to test on a real board yet, but great to see it all compiles. Just to double check, in the touch.cpp file that is created, in the data array for the pasm code most of the data at the beginning seems to be 0x00. Is that correct?
    I think so. dat[] array is just the bytes in the DAT section of the object. The DAT section of Touch.spin starts off with:
        RamLocation         long $0[31]                  ' 32 file ram locatinos
        RamSize             long $0[31]                  ' File sizes in words - NOT bytes (divide byte by 2)
        sdbuffer            byte $0[1024] ' 1024 byte buffer for sd card interface and also for sending one row 320 x3 = 960 bytes max picture size 
        buffer2             byte $0[512]  ' 512 general purpose hub buffer 
    
    which is a lot of zeros.
    Addit - off on a tangent, can you please test the attached zip, getting a number of "stray" errors when compiling this.
    Thanks. spin2cpp is getting confused by:
    PUB getCogID : result
      return cog -1
    
    result is a reserved keyword for spin2cpp. Changing it to any other string works, as does removing the ": result" completely (since it is never used).

    I see that bstc handles this correctly, so explicitly declaring the return value to be named "result" (which is the default) needs to be supported. I'll fix this. Thanks for catching it!
    Meanwhile, I've discovered why the large program is not running - it hangs when it starts Kye's SD driver. I believe this would be because the C code is running in XMM cached mode which is also using an SD driver.
    Oh yes, that would be a problem! Caching from external ram rather than SD would probably be the easiest solution.

    Eric
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-18 07:15
    Caching is going to be a bit of a puzzle. Just for starters, it seems the cache drivers start off life as Spin post #2 here http://forums.parallax.com/showthread.php?141258-PropGCC-memory-model-page

    So it is the interfacing between being able to talk to an SD card and the cache talking to an SD card. Many solutions. Caching in either external ram or SD would still have the same problem - how do you know the underlying C code is not accessing the cache? Or - do you have handles that you can pass into C to access the SD card?

    Caching is more important than in Spin because even simple Spin programs are being compiled into C that is filling up most of the hub ram. I'll ponder this some more...
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-18 17:27
    Attached is some experimental code for Kye's SD driver. I've taken a spin file, converted it to C++, and then moved it into SimpleIDE. It references a board "hubc" which is my hardware. You will need to change this. To test this on any board with an SD card, change to your board, and also in the program testsd.c, change this line
      Fat.Fatenginestart(24, 25, 26, 27, -1, -1, -1, -1, -1);
    

    to the pin numbers of your SD card.

    I was not expecting it to run in XMMC mode as there will be a conflict with the cache. However, it does not run either in LMM mode and so I suspect there is some sort of error somewhere else.

    One thing about Kye's code is that it seems to open an SD card much faster than the code that is part of GCC. So I'm interested in getting Kye's code working for that reason. Also it has the ability to reboot and chain files quickly which is very useful for an operating system.

    But there is a fundamental problem here with SpintoC that needs sorting out. That demo Spin code attached here only uses about 8.4k of hub ram, leaving lots of room for actual code. However, compile it to C and it is reporting about 26k which does not leave much for your program. I think that means one is forced into using XMMC and caching.

    For caching there will be conflicts. Cache from SD and you get conflicts reading and writing to the SD card. But caching from external ram has the same problem if the C code is also accessing the same ram.

    A simple answer is to have different memory. But then you (well me, actually) run out of pins. Unless you cache from something on the i2c bus (which I need to explore a bit more).

    Locks are another option, but it is not quite so simple. If you run Kye's SD code you cache it in. Then open a file. Then read from a file. But what if the C code that read the file is in a different cache block? So you need to make sure that all the code for an SD driver is cached in before using that driver.

    Another option I'm vaguely thinking about is to replicate something like the BIOS and BDOS calls in DOS. If a C program sends a BDOS call to "open a file", and that goes into the "C interpreter" (I know that isn't the correct term) then the interpreter can sort out conflicts with caching.

    Another option is to abandon Kye's SD driver and use the (seemingly much slower) one in C. One can do that, but I have this idea of running "Big Spin" where you work mainly in Spin and never really look at the C code (targeted at Spin coders) and if you do that, then it is hard to think of an equivalent of C's "fopen" functions in Spin. The Spin2C translator would need to take such Spin PUB calls and convert directly to the equivalent C code. Which would be similar to what it is doing now but not exactly the same.

    It is complex. On the upside, I think it is only the SD driver code that is complex. All the other code seems to be working fine in Spin2C.

    So, thinking along those lines, one would need a bare minimum SD file access system which can be used by both Spin and C. In a way, it may be easier to think of it in C first and then translate it to Spin. I think the bare minimum functions might be:

    start
    mount
    filenew
    fileopen (read or write)
    read or write a block of 512 bytes to or from an array
    fileclose

    I still very much like the concept of having the cache on the SD card. All the other memory options might be faster, but the SD card is more universal across almost all propeller boards out there. Just change the pin numbers. Plus I think experiments already done show that the actually cache hardware speed hardly matters.

    Having said that, if you got two or three 64kilobyte eeproms and put them on the i2c bus and put the program in eeprom rather than on the SD card, it could greatly simplify a lot of things. But the programs would be more limited in size. Hmm - going round in circles here!

    These are hard problems to solve. Just for starters, if anyone can get the attached code to work in LMM mode I think that might be a first step :)
  • KodeDaemonKodeDaemon Posts: 4
    edited 2012-07-20 14:30
    I have just come across this and gave it a try. Though it seems to not support some things we do in our code. I am using version 0.9 .

    Here are some examples:

    In some of our spin objects we reference other spin objects as arrays.
    OBJ
      objects[MAX_OBJECTS] :  "SpinObject"
    

    The following code causes spin2cpp to complain about pin not being a constant. This happens when setting outa[pin] to any value. These situations come from Mike Green's I2C driver:
      outa[pin]~~
    

    Another example:
      outa[pin] := (data <-= 1) & 1
    
  • ersmithersmith Posts: 6,095
    edited 2012-07-21 06:17
    Dr_Acula wrote: »
    But there is a fundamental problem here with SpintoC that needs sorting out. That demo Spin code attached here only uses about 8.4k of hub ram, leaving lots of room for actual code. However, compile it to C and it is reporting about 26k which does not leave much for your program.
    Well, that is the trade-off: C code is much faster than Spin, but also much bigger. We're looking into a "compressed" mode which will be intermediate in both speed and size, but I'm not sure when that will be ready.
    For caching there will be conflicts. Cache from SD and you get conflicts reading and writing to the SD card. But caching from external ram has the same problem if the C code is also accessing the same ram.
    True. But even in XMMC mode it's possible to explicitly force code into HUB memory, by putting __attribute__((section(".hub"))) in front of the function that you want to place in HUB RAM. So depending on usage you may be able to put the low level C code that reads the SD into HUB and avoid the cache conflict. It'll take some work, though.

    Eric
Sign In or Register to comment.