I've been waiting about a year on this, er.
So I'm waiting as fast as I can?
So you just keep plugging along at it.
If you can make it work you will have created something very useful.
Basically it would be a SPIN compiler.
Like I said, something VERY useful.
I will keep plugging away, and all the feedback and testing that others are doing helps a lot.
While you're waiting, you could try converting your program to C and using PropGCC to compile it. That will actually produce better code than the PASM output of Spin Converter, and it's available now. The disadvantage is that it does require PropGCC, which is pretty big.
(The C and C++ conversion in Spin Converter is complete, as far as I know, so it should be able to handle any program.)
...(The C and C++ conversion in Spin Converter is complete, as far as I know, so it should be able to handle any program.)
Just wow. This basically opens LMM and CMM for spin?
So can I now write spin programs bigger then 32K, convert them to C or C++ and run thru PropGCC/SimpleIDE and use external memory like SPI-RAM for more space? Even with sub objects and PASM?
...(The C and C++ conversion in Spin Converter is complete, as far as I know, so it should be able to handle any program.)
Just wow. This basically opens LMM and CMM for spin?
So can I now write spin programs bigger then 32K, convert them to C or C++ and run thru PropGCC/SimpleIDE and use external memory like SPI-RAM for more space? Even with sub objects and PASM?
Yes.
The caveat is that the GUI is very new, and mostly oriented towards single file at a time operation. But the command line version of the program (spin2cpp) has been working for quite a while now, and has been used to do a lot of Spin to C/C++ conversions. It automatically converts subobjects, and has a PASM assembler built in. And yes, compiling to XMM is also possible.
I pulled all the foolishness out of the TFT driver and cleaned up some.
And coded some simple (minded) PASM to wiggle the control pins.
The TFT_2016.ZIP file only has TFT_CLS in the main program.
Can you use this as a (Way More Involved) test file?
That one already launches a COG (there's a coginit in the init function; see TFT_PASM_IMAGE). Also, having the CS_HIGH, CS_LOW and so on routines in the DAT section doesn't help anything (the spn compiler can't call functions in DAT; as it turns out those functions aren't used anyway in the version you posted).
Here's a TFT2.spin that has everything except the initialization cut out. The next preview release (that I'll be putting up shortly) can compile it. Whether it will work correctly is another question entirely! It probably won't work right, but I'd like to hear your experience.
I've uploaded a new preview release. This fixes a number of bugs, both in the GUI and in the compiler itself. The GUI Options menu now as a "Make Binary" option which if checked causes spin2cpp to be run twice, once to produce the PASM and then again to produce a .binary file. There are a few simple examples that can be run (hello world, blinking led, and some basic math functions).
In C/C++ mode all of Spin is supported. For PASM output we still only support one object (see the demos for a way to kind of get around this with #include). Many builtin functions like coginit/cognew, lockset/lockclr, longmove, etc. are not supported yet. DAT sections are supported now, but they're output as "binary blobs", which seems counterintuitive but is a consequence of the compiler implementation. (On the other hand if you already have PASM in a DAT section why do you need to make new PASM form it? )
I'd love to hear any feedback / suggestions. This release is still very limited, but it can produce executable programs, and I think we're getting close to the point where OBEX objects can be converted.
Any chance that you can modify the Makefile to allow building just the command line portions? Building on Mac OS X requires Tk/Tcl (I believe) and I'm not thrilled to have to install ports or homebrew in order to get Tk/Tcl (my app build system does not get along with changes that those package systems)...
Any chance that you can modify the Makefile to allow building just the command line portions? Building on Mac OS X requires Tk/Tcl (I believe) and I'm not thrilled to have to install ports or homebrew in order to get Tk/Tcl (my app build system does not get along with changes that those package systems)...
Actually the GUI isn't built by default -- the regular make just builds spin2cpp, the command line portion. To get the GUI requires "make spincvt.zip", and that's kind of specialized because it builds a Windows only GUI.
I'm on Linux and I usually use the command line version for testing and such. I don't build a GUI app on Linux; for testing the GUI I either run spinconvert.tcl "by hand" or else build the Windows GUI and run it with Wine.
OK, so then there are some errors that show up on make that appear to be related to Mac OS X's use of clang.
These are just two of the errors. The compiler shuts down after about 30 of these, stating "too many errors"...
backends/asm/outasm.c:280:18: error: implicit conversion from enumeration type 'Operandkind' (aka 'enum Operandkind') to different enumeration type 'enum IROpcode'
[-Werror,-Wenum-conversion]
IR *ir = NewIR(code);
~~~~~ ^~~~
backends/asm/outasm.c:290:16: error: implicit conversion from enumeration type 'enum IROpcode' to different enumeration type 'Operandkind' (aka 'enum Operandkind')
[-Werror,-Wenum-conversion]
EmitOp1(irl, OPC_LABEL, op);
~~~~~~~ ^~~~~~~~~
All displayed errors are based in "backends/asm/outasm.c". Can these enumeration errors be removed?
I pulled all the foolishness out of the TFT driver and cleaned up some.
And coded some simple (minded) PASM to wiggle the control pins.
The TFT_2016.ZIP file only has TFT_CLS in the main program.
Can you use this as a (Way More Involved) test file?
That one already launches a COG (there's a coginit in the init function; see TFT_PASM_IMAGE). Also, having the CS_HIGH, CS_LOW and so on routines in the DAT section doesn't help anything (the spn compiler can't call functions in DAT; as it turns out those functions aren't used anyway in the version you posted).
those bit-wigglers are only called by the PASM code in the DAT, so no har - no foul.
But not a speedup either.
Here's a TFT2.spin that has everything except the initialization cut out. The next preview release (that I'll be putting up shortly) can compile it. Whether it will work correctly is another question entirely! It probably won't work right, but I'd like to hear your experience.
I dropped it into RAM and it looks like it INITed.
At least it cleared the previous contents from the screen.
I confused myself again. I mistakenly thought the Propeller Tool had variable trace capability.
It has been most of a year since I played around with it.
I think I was mistaken.
So I tried to drop the rest of the (prior) SPIN code in place.
It compiled ok, but something didn't work right.
Never cleared the display.
Let me look at it more carefully.
See i f I can get the terminal thingie working and see if I can see InitTime.
Don't have any more time tonight...
I've fixed at least some of the enumeration errors, although gcc is not too concerned about enumeration conversions in C mode (only in C++) so it's hard to track them all down.
I also changed the Makefile to remove -Werror, so at least you should be getting warnings instead of errors.
I do get a crash when I run "spin2cpp --asm hello.spin" (in: "spinconvert/examples/") where the code includes: "#include "serial.def"...
Building a more simple example (led.spin) completes without segmentation fault. Removing that #include and reference to ser_str provides a completion. So, something about the #include (I think).
It appears that PrintOperandAsValue is receiving a null 'reg' argument in this example... (This takes place on the 17th execution of PrintOperandAsValue).
Thanks for the bug report, @dgately. I haven't been able to reproduce exactly the bug you described, but I did fix some other bugs in the DAT section output that perhaps might be causing issues, so it's probably worth updating to the latest sources and trying again. Also, I've made a few build system changes lately and it's possible that some dependencies aren't being caught correctly by the Makefile, so I'd recommend doing a "make clean" before the make after you update this time.
I've published a new preview release (number 6). This one considerably expands support for PASM output; it can now handle VAR and OBJ sections. Most builtin functions are supported now. The mechanism for doing that was kind of elegant (if I do say so myself): I've added support for inline assembly, and so the builtins are actually written in Spin. For example, the waitcnt function is just:
I've published a new preview release (number 6). This one considerably expands support for PASM output; it can now handle VAR and OBJ sections. Most builtin functions are supported now. The mechanism for doing that was kind of elegant (if I do say so myself): I've added support for inline assembly, and so the builtins are actually written in Spin. For example, the waitcnt function is just:
The spin to PASM converter supports recursive functions now, and has more of Spin implemented (to the point that it can compile FullDuplexSerial.spin). So we can now run many small benchmarks and tests, including the famous fibonacci demo. Here's how spincvt (i.e. spin2cpp --asm --binary) stacks up on fibo(8), based on results from an old benchmark thread:
Time is cycles for fibo(8), size is size in bytes of the fibo function itself, ignoring all support and library functions.
The size is nothing to write home about, but it's in the same range as other PASM compiled solutions. The speed is nice: a 15x speed up over interpreted spin. GCC does better in COG mode, but I never expected to match the GCC optimizer. All in all I think things are coming along well.
I've published a new preview release (number 6). This one considerably expands support for PASM output; it can now handle VAR and OBJ sections. Most builtin functions are supported now. The mechanism for doing that was kind of elegant (if I do say so myself): I've added support for inline assembly, and so the builtins are actually written in Spin. For example, the waitcnt function is just:
pri waitcnt(x)
asm
waitcnt x, #0
endasm
That's nice - is there a limit to what can go between asm..endasm ?
you mention builtin functions, but general expectation is asm..endasm is linline-asm.
I've published a new preview release (number 6). This one considerably expands support for PASM output; it can now handle VAR and OBJ sections. Most builtin functions are supported now. The mechanism for doing that was kind of elegant (if I do say so myself): I've added support for inline assembly, and so the builtins are actually written in Spin. For example, the waitcnt function is just:
pri waitcnt(x)
asm
waitcnt x, #0
endasm
That's nice - is there a limit to what can go between asm..endasm ?
you mention builtin functions, but general expectation is asm..endasm is linline-asm.
Almost anything can go between asm...endasm. I mentioned builtins because this is *how* the builtins are implemented; most of the standard Spin functions like lockclr, lockset, waitcnt, and so on are implemented as ordinary functions that happen to use inline assembly. The compiler always includes a special "global" object that has definitions for all of these. But you can also write other functions that way too. The limitation is that only local variables and immediate constants can be operands in the inline assembly; you can't directly access anything else. So to increment an object variable you could write:
var
long value
pub incvalue(x) | ptr, tmp
ptr := @value '' want to access object variable in inline asm
asm
rdlong tmp, ptr ' read value
add tmp, x ' add x to it; that's OK, x is a local variable
wrlong tmp, ptr ' update value
endasm
This is a contrived example, of course, since it's a lot simpler to just write "value += 1", but it illustrates the principle: the inline asm cannot directly access "value" but it can access the variables of the function it is within.
Preview 8 is out, with LMM support. Lots of programs work now. @Cavelamb, I think TFT.spin should work for you as long as you select "LMM Mode" under the Options menu. I get the following timing results on SS_TFT.spin:
openspin:
Initialization time: 20095 ms
Text print time: 1591 ms
spincvt (LMM mode):
Initialization time: 1349 ms
Text print time: 75 ms
(Beware: I don't actually have hardware to test whether the TFT is working correctly!)
@Heater, you'll be pleased to hear that fft_bench works now:
openspin:
1024 point bit-reversal and butterfly run time = 1465 ms
spincvt (LMM mode):
1024 point bit-reversal and butterfly run time = 270 ms
For those of you using the command line, LMM mode is activated by the switch "--code=hub", so to produce a binary from a .spin file you do something like:
I'll try it this weekend, er.
Will let you know how it goes.
Where on earth are you?
Might want to ship the run-time machine to you for test, if you'd be interested.
Might be with the trouble to test your project - and get mine advanced.
I'll try it this weekend, er.
Will let you know how it goes.
Please do. I've uploaded a new preview (version 9). I think it's feature complete now; all of my regular Spin tests work for it, including launching a new COG with a Spin method. There are still a few rough edges (e.g. I'd like to implement a suggestion from @jmg that the original source code be added as comments) and I guess it would be nice to integrate the compiler with a proper IDE like PropellerIDE. But the basic functionality should all be there.
Where on earth are you?
Might want to ship the run-time machine to you for test, if you'd be interested.
Might be with the trouble to test your project - and get mine advanced.
I'm in Nova Scotia, Canada... but I don't have a lot of spare time, I'm afraid (this project has already eaten up more of what little I have than it should have!). But I'd be happy to help out here on the forums.
Here is the latest version, which I've labeled a "beta" release. It's now feature complete; it's able to compile all the Spin I've thrown at it, although admittedly that is a small set so far. I've implemented @jmg's suggestion to include the original source as comments in the output PASM.
I'll probably focus on adding P2 support next, unless there's some P1 features that aren't working and that someone needs.
Not sure of this is actually a bug or more a case of an incorrect but very common usage issue... These are showing up as I run spinconvert.rcl & test as much spin code as possible).
Trying to build a number of .spin files that I've either written or downloaded, results in a syntax error on the following code (when a preceding 'CON' is missing):
content of dubious.spin:
{{ Dubious Spin program example }}
_clkmode = xtal1 + pll16x ' Setting Clock Mode to Crystal 1 with 16 multiplier
_xinfreq = 5_000_000 ' Propeller set to run at 80MHz
PUB main
repeat
build of dubious.spin:
$spin2cpp --asm dubious.spin
dubious.spin:3: error: syntax error
Of course this code works:
{{ Correct Spin code example }}
CON
_clkmode = xtal1 + pll16x ' Setting Clock Mode to Crystal 1 with 16 multiplier
_xinfreq = 5_000_000 ' Propeller set to run at 80MHz
PUB main
repeat
The first example is probably NOT correct Spin syntax but compiles with openspin (as used by: SimpleIDE and PropellerIDE). It could be that openspin assumes declarations preceding VAR or PUB are always CON declarations.
Should spin2cpp follow openspin's allowance of this syntax or is openspin in error?
Since I'm actually finding issues/exceptions that concern spin2cpp more than spinconveri.tcl, should I just write these up as issues in git on the master branch of spin2cpp? Looks like spin2cpp still does not know to handle the 'abort' expression, yet:
spinconveri Compiler Output:
spin2cpp --noheader -g --asm --code=cog --data=hub -o /Users/altergator/PropSpinCode/ADXL345ObjectDemo/ADXL345ObjectDemo.pasm
/Users/altergator/PropSpinCode/ADXL345ObjectDemo/ADXL345ObjectDemo.spin
/Users/altergator/PropSpinCode/ADXL345ObjectDemo/ADXL345ObjectDemo.spin:98: error: Cannot handle expression yet
/Users/altergator/PropSpinCode/ADXL345ObjectDemo/ADXL345ObjectDemo.spin:202: error: Cannot handle expression yet
child process exited abnormally
code in question (ADXL345ObjectDemo.spin:):
lines 96-98:
if adxl.ReadDeviceID <> -1
debug.str(string(16, "ADXL345 Chip Not Present...Aborting!"))
abort
lines 195-202:
temp := adxl.ReadDataFormat
case temp & %0000_0011
0: debug.str(string(13, "2g format initiated!"))
1: debug.str(string(13, "4g format initiated!"))
2: debug.str(string(13, "8g format initiated!"))
3: debug.str(string(13, "16g format initiated!"))
OTHER: debug.str(string(13, "Unknown format initiated...Aborting!"))
abort
Not sure of this is actually a bug or more a case of an incorrect but very common usage issue... These are showing up as I run spinconvert.rcl & test as much spin code as possible).
Trying to build a number of .spin files that I've either written or downloaded, results in a syntax error on the following code (when a preceding 'CON' is missing):
Ah, interesting... I hadn't seen that missing 'CON' before, but if openspin accepts it then spin2cpp should too. I've changed the grammar to accept it; fortunately it was pretty easy. The fix is checked in to the master branch now (which has been merged with spin2pasm).
Thanks for trying out so many spin files, and reporting the problems. That's really helpful!
Eric
Comments
I will keep plugging away, and all the feedback and testing that others are doing helps a lot.
While you're waiting, you could try converting your program to C and using PropGCC to compile it. That will actually produce better code than the PASM output of Spin Converter, and it's available now. The disadvantage is that it does require PropGCC, which is pretty big.
(The C and C++ conversion in Spin Converter is complete, as far as I know, so it should be able to handle any program.)
This is a karma payback?
Just wow. This basically opens LMM and CMM for spin?
So can I now write spin programs bigger then 32K, convert them to C or C++ and run thru PropGCC/SimpleIDE and use external memory like SPI-RAM for more space? Even with sub objects and PASM?
If so this is very cool.
Mike
Yes.
The caveat is that the GUI is very new, and mostly oriented towards single file at a time operation. But the command line version of the program (spin2cpp) has been working for quite a while now, and has been used to do a lot of Spin to C/C++ conversions. It automatically converts subobjects, and has a PASM assembler built in. And yes, compiling to XMM is also possible.
And coded some simple (minded) PASM to wiggle the control pins.
The TFT_2016.ZIP file only has TFT_CLS in the main program.
Can you use this as a (Way More Involved) test file?
Here's a TFT2.spin that has everything except the initialization cut out. The next preview release (that I'll be putting up shortly) can compile it. Whether it will work correctly is another question entirely! It probably won't work right, but I'd like to hear your experience.
In C/C++ mode all of Spin is supported. For PASM output we still only support one object (see the demos for a way to kind of get around this with #include). Many builtin functions like coginit/cognew, lockset/lockclr, longmove, etc. are not supported yet. DAT sections are supported now, but they're output as "binary blobs", which seems counterintuitive but is a consequence of the compiler implementation. (On the other hand if you already have PASM in a DAT section why do you need to make new PASM form it? )
I'd love to hear any feedback / suggestions. This release is still very limited, but it can produce executable programs, and I think we're getting close to the point where OBEX objects can be converted.
Any chance that you can modify the Makefile to allow building just the command line portions? Building on Mac OS X requires Tk/Tcl (I believe) and I'm not thrilled to have to install ports or homebrew in order to get Tk/Tcl (my app build system does not get along with changes that those package systems)...
dgately
Actually the GUI isn't built by default -- the regular make just builds spin2cpp, the command line portion. To get the GUI requires "make spincvt.zip", and that's kind of specialized because it builds a Windows only GUI.
I'm on Linux and I usually use the command line version for testing and such. I don't build a GUI app on Linux; for testing the GUI I either run spinconvert.tcl "by hand" or else build the Windows GUI and run it with Wine.
These are just two of the errors. The compiler shuts down after about 30 of these, stating "too many errors"...
All displayed errors are based in "backends/asm/outasm.c". Can these enumeration errors be removed?
Thank you for your consideration,
dgately
But not a speedup either.
I dropped it into RAM and it looks like it INITed.
At least it cleared the previous contents from the screen.
I confused myself again. I mistakenly thought the Propeller Tool had variable trace capability.
It has been most of a year since I played around with it.
I think I was mistaken.
So I tried to drop the rest of the (prior) SPIN code in place.
It compiled ok, but something didn't work right.
Never cleared the display.
Let me look at it more carefully.
See i f I can get the terminal thingie working and see if I can see InitTime.
Don't have any more time tonight...
I've fixed at least some of the enumeration errors, although gcc is not too concerned about enumeration conversions in C mode (only in C++) so it's hard to track them all down.
I also changed the Makefile to remove -Werror, so at least you should be getting warnings instead of errors.
I do get a crash when I run "spin2cpp --asm hello.spin" (in: "spinconvert/examples/") where the code includes: "#include "serial.def"...
Building a more simple example (led.spin) completes without segmentation fault. Removing that #include and reference to ser_str provides a completion. So, something about the #include (I think).
Crash dump info:
dgately
I hope this helps...
dgately
I hope these changes help!
Very cool!
Time is cycles for fibo(8), size is size in bytes of the fibo function itself, ignoring all support and library functions.
The size is nothing to write home about, but it's in the same range as other PASM compiled solutions. The speed is nice: a 15x speed up over interpreted spin. GCC does better in COG mode, but I never expected to match the GCC optimizer. All in all I think things are coming along well.
It's really coming together now.
That's nice - is there a limit to what can go between asm..endasm ?
you mention builtin functions, but general expectation is asm..endasm is linline-asm.
Almost anything can go between asm...endasm. I mentioned builtins because this is *how* the builtins are implemented; most of the standard Spin functions like lockclr, lockset, waitcnt, and so on are implemented as ordinary functions that happen to use inline assembly. The compiler always includes a special "global" object that has definitions for all of these. But you can also write other functions that way too. The limitation is that only local variables and immediate constants can be operands in the inline assembly; you can't directly access anything else. So to increment an object variable you could write: This is a contrived example, of course, since it's a lot simpler to just write "value += 1", but it illustrates the principle: the inline asm cannot directly access "value" but it can access the variables of the function it is within.
@Heater, you'll be pleased to hear that fft_bench works now:
For those of you using the command line, LMM mode is activated by the switch "--code=hub", so to produce a binary from a .spin file you do something like:
Eric
Will let you know how it goes.
Where on earth are you?
Might want to ship the run-time machine to you for test, if you'd be interested.
Might be with the trouble to test your project - and get mine advanced.
Please do. I've uploaded a new preview (version 9). I think it's feature complete now; all of my regular Spin tests work for it, including launching a new COG with a Spin method. There are still a few rough edges (e.g. I'd like to implement a suggestion from @jmg that the original source code be added as comments) and I guess it would be nice to integrate the compiler with a proper IDE like PropellerIDE. But the basic functionality should all be there.
I'm in Nova Scotia, Canada... but I don't have a lot of spare time, I'm afraid (this project has already eaten up more of what little I have than it should have!). But I'd be happy to help out here on the forums.
Thanks,
Eric
I'll probably focus on adding P2 support next, unless there's some P1 features that aren't working and that someone needs.
Any/all feedback is welcome.
Eric
Thanks. I will not get around to checking it out just yet. Working on USB.
Trying to build a number of .spin files that I've either written or downloaded, results in a syntax error on the following code (when a preceding 'CON' is missing):
Of course this code works:
The first example is probably NOT correct Spin syntax but compiles with openspin (as used by: SimpleIDE and PropellerIDE). It could be that openspin assumes declarations preceding VAR or PUB are always CON declarations.
Should spin2cpp follow openspin's allowance of this syntax or is openspin in error?
dgately
Since I'm actually finding issues/exceptions that concern spin2cpp more than spinconveri.tcl, should I just write these up as issues in git on the master branch of spin2cpp? Looks like spin2cpp still does not know to handle the 'abort' expression, yet:
dgately
Ah, interesting... I hadn't seen that missing 'CON' before, but if openspin accepts it then spin2cpp should too. I've changed the grammar to accept it; fortunately it was pretty easy. The fix is checked in to the master branch now (which has been merged with spin2pasm).
Thanks for trying out so many spin files, and reporting the problems. That's really helpful!
Eric