@ersmith Issue #1: There seems to be some mischief compiling without optimization in FlexBASIC 5-9-1-Beta. This code:
FUNCTION BCDToDec(BCD as ulong) as ulong
' BCD to Decimal
' Converts a BCD number into decimal
dim tmp as ulong
dim i as long
tmp = 0
i = 7
do
tmp = tmp + ((BCD AND &HF000_0000) >> 28) * (10 ^ i)
BCD = BCD << 4
i -= 1
loop until i = -1
return tmp
END FUNCTION
produces these errors from the first line after the DO statement:
D:/Flex2Gui/flexgui/P2 Libs/CommonLibP2.p2asm:183: error: Unknown symbol __system____builtin_powf
D:/Flex2Gui/flexgui/P2 Libs/CommonLibP2.p2asm:187: error: Unknown symbol __system___float_mul
D:/Flex2Gui/flexgui/P2 Libs/CommonLibP2.p2asm:191: error: Unknown symbol __system___float_add
Similar errors get thrown in other functions when dividing:
D:/Flex2Gui/flexgui/P2 Libs/CommonLibP2.p2asm:692: error: Unknown symbol __system___float_div
This behavior seems to be of recent origin and only occurs with optimization turned off. Any other level of optimization compiles fine.
Issue #2: Comparisons of 64-bit numbers gets wonky in DO/LOOPs if left-most argument is a function call returning 64-bits.
This code works fine: (Note: the function GetCnt64() just returns the 64-bit system counter as a ulongint. Works fine)
SUB PauseMS64(count as ulongint)
' Pauses until COUNT milliseconds has elapsed then returns to caller
dim bailOutCnt as ulongint
bailOutCnt = GetCnt64() + (count * (CLKFREQ / 1_000))
do
'do nothing
loop until bailOutCnt <= GetCnt64()
END SUB
This code below differs by one line and throws the error: Bad number of parameters in call to _int64_cmpu: expected 4 found 3
SUB PauseMS64(count as ulongint)
' Pauses until COUNT milliseconds has elapsed then returns to caller
dim bailOutCnt as ulongint
bailOutCnt = GetCnt64() + (count * (CLKFREQ / 1_000))
do
'do nothing
loop until GetCnt64() > bailOutCount ‘ <~~~ reversed argument position
END SUB
The only difference between these two is the order of the vars/func for the comparison test in the LOOP closure.
@JRoark said:
@ersmith Is there any way in FlexBASIC to define a string constant that does not contain "typeable" characters? What I'm looking for is a constant for a CR (or LF, or a BS, etc), but this doesn't work:
CONST cr = chr$(13)
or
CONST cr$ = 13
In the first case, the compiler doesn't know about CHR$() as it relates to making a constant, and in the other it just assigns the value of 13. If the text was "typeable", then it would be easy:
CONST greeting = "How ya doin?"
I'm confuzzified.
No, unfortunately there is no way to insert non-printable characters in a literal string, and a BASIC CONST string can only be a literal.
What are you trying to accomplish? Could you use a VAR or a DIM SHARED instead?
@ersmith said:
No, unfortunately there is no way to insert non-printable characters in a literal string, and a BASIC CONST string can only be a literal.
What are you trying to accomplish? Could you use a VAR or a DIM SHARED instead?
I got myself wrapped-up in thinking the "clean" way of doing it would be to use CONST for consistency, but as you suggested I finally settled on using a DIM SHARED at the module level. Works a treat.
There's a new release of FlexProp, version 5.9.2, available on Patreon (it's been there for a while now actually!) and now on github. This version is a kind of preview of the 6.0.0 release, which is still some way away. There are some notable new features, including:
P1 ROM bytecode support exposed in the GUI now (the compiler has supported it for a little while, thanks to @Wuerfel_21 's contribution). The P1 ROM bytecode works very well for Spin1, and fairly well for Spin2 on P1, C, and BASIC. Due to the nature of the interpreter there are a few features missing, notably inline assembly support.
Support for BRK debugging on P2 (allowing debug of PASM code); this was also contributed by @Wuerfel_21 , she's been very busy!
A new kind of bytecode for P2 (not the same as the "official" P2 bytecode). Called "nu" code, this has an interpreter that's custom built for each application. The Nu compiler and interpreter are still under active development, and should not be used in production code yet -- the final version will be smaller and faster than what's there now.
A smaller and simpler runtime library is used for many cases (e.g. simple serial prints). This is detected automatically, no command line options are required.
Automatic locking of access to the serial port for PRINT and printf, so C and BASIC programs running on multiple COGs will (generally) work better.
BASIC improvments: multiple items in CASE, and _SameTypes() and _HasMethod() builtins for doing generic programming.
Also, there's a major change to the Mac OS GUI: it's now built as a complete binary application (similar to the Windows one) and comes with Tcl/Tk 8.6, instead of relying on the system one. This fixes a number of annoying bugs in the (obsolete) Tcl/Tk distributed with MacOS, but probably introduces new bugs .
@ersmith I just now installed the latest Windows version of Flex 5.9.2 obtained from the Patreon page. After compiling I get a TCL error. "APPLICATION ERROR: Version conflict for package "TCL" Have 8..."
Here is the logfile it generated:
version conflict for package "Tcl": have 8.6.11, need 8.7-
version conflict for package "Tcl": have 8.6.11, need 8.7-
while executing
"package require Tcl 8.7-"
(file "D:/Flex2Gui/flexgui/tcl_library/tcl9.0/msgcat/msgcat.tcl" line 15)
invoked from within
"source D:/Flex2Gui/flexgui/tcl_library/tcl9.0/msgcat/msgcat.tcl"
("package ifneeded msgcat 1.7.0" script)
invoked from within
"package require msgcat 1.6"
("uplevel" body line 2)
invoked from within
"uplevel \#0 {
package require msgcat 1.6
if { $::tcl_platform(platform) eq {windows} } {
if { [catch { package require registry 1.1 }] } {
..."
(file "D:/Flex2Gui/flexgui/tcl_library/tcl8.6/clock.tcl" line 21)
invoked from within
"source -encoding utf-8 [file join $TclLibDir clock.tcl]"
(procedure "::tcl::clock::format" line 3)
invoked from within
"clock format $now -format %c"
(procedure "doCompile" line 20)
invoked from within
"doCompile"
invoked from within
".toolbar.compile invoke "
invoked from within
".toolbar.compile instate !disabled { .toolbar.compile invoke } "
invoked from within
".toolbar.compile instate pressed { .toolbar.compile state !pressed; .toolbar.compile instate !disabled { .toolbar.compile invoke } } "
(command bound to event)
This error does not seem to hinder the compiler from working. It seems to get thrown when the compiler has already finished and control is being returned to TCL.
@JRoark : I think you've somehow mixed up two installations of FlexProp. The new one (flexprop 5.9.2) doesn't even have a tcl9.0 subdirectory inside tcl_library. I'd suggest re-installing; if you can't start fresh, then rename (at least) the "src", "bin", and "tcl_library" directories to something else before unpacking 5.9.2 over them.
@ersmith said:
@JRoark : I think you've somehow mixed up two installations of FlexProp. The new one (flexprop 5.9.2) doesn't even have a tcl9.0 subdirectory inside tcl_library. I'd suggest re-installing; if you can't start fresh, then rename (at least) the "src", "bin", and "tcl_library" directories to something else before unpacking 5.9.2 over them.
Roger that! I havent done a fresh install-from-scratch in about two years, so its probably way past time. Thanks for the help.
@bigtreeman said:
Hi, I'm using github compiled Flexprop v5.9.2
I have found the flexprop clock initialisation
seems to only use mmmmmmmmmm pll multiplier
and not dddddd xtal divider
I don't think this is correct. I'm using the algorithm that Chip gave in the forums, and it uses both the pll multiplier and xtal divider. I don't have a 25 MHz system to test with, but you can see the generated values in the .p2asm file. They're given as comments near the beginning of the file, e.g.:
con
_xtlfreq = 25000000
_clkfreq = 120000000
dat
nop
cogid pa
coginit pa,##$404
orgh $10
long 0 'reserved
long 0 ' clock frequency: will default to 120000000
long 0 ' clock mode: will default to $11017fb
Were you using TAQOZ to print the clock modes? Perhaps the forth runtime changes something in the calculated values?
Oh, for that matter it may not be using the calculated values at all -- my test program was in Spin2, but TAQOZ is pure assembly, so it won't (generally) have the clock set for it automatically. How are you getting flexspin's calculated clock frequencies into the TAQOZ code?
I've posted FlexProp version 5.9.3 binaries on the usual sites (github and Patreon). This version supports the new Spin2 floating point operators, and a few miscellaneous bug fixes.
@ersmith said:
I've posted FlexProp version 5.9.3 binaries on the usual sites (github and Patreon). This version supports the new Spin2 floating point operators, and a few miscellaneous bug fixes.
Eric
There seems to be something wrong with the floating point implementation.
I get always one of these errors:
error: applying round to a non float expression
error: Cannot handle expression yet
The following minimal Spin2 code produces both errors:
CON
_clkfreq = 160_000_000
PUB go(): i,f
f := 1.0e+6
i := round(f /. 10.0)
Yes, round() seems to be broken. I'll get a fix in soon, but for now you can work around this by adding -Dround=_float_round on the command line. You may get some warnings about round being redefined in some header files, but you can ignore those.
round(), trunc() and float() are all fixed in github (source code) now. The workaround for older flexspin versions is to always use the all-caps versions (ROUND, TRUNC, FLOAT) and to add the following defines to the command line:
I try to register a timer ISR because I don't want to waste a full COG on letting a few LEDs blink. This works if I run the PASM2 method into an endless loop. But the moment I remove that & return, the ISR is not executed anymore.
con
SD_STATUS_PIN = 25
SYSTEM_STATUS_PIN = 24
pub main()
setup_timer()
repeat
pinhigh(SD_STATUS_PIN)
waitms(100)
pinlow(SD_STATUS_PIN)
waitms(100)
pri setup_timer()
org
drvl #SYSTEM_STATUS_PIN
mov ijmp1, #int1
getct t1
addct1 t1, period
setint1 #1
.loop jmp #.loop ' comment this out
ret
int1 addct1 t1, period
drvnot #SYSTEM_STATUS_PIN
reti1
period long clkfreq_/10
t1 long 0
end
Addct1 sets only a single value for the timer. Only a single event is generated when the system clock counter reaches that value. You have to update the timer in your int1 ISR by executing another addct1.
BTW, you can blink LEDs without any cog resources by setting the pin to PWM smart pin mode. By using large values for the base period you can set PWM frequencies in the second range.
@ManAtWork I do update the timer, it does work when the main “thread” loops endlessly.
Thanks for the PWM hint, I’d obviously prefer that. I did in fact try that based off an example but the period was too small. I only managed 200us or so. Do you have an example?
I suspect that a repeat construct without any further parameters, and followed by an indented-code-section will get assembled as an infinite Pasm2-REP-loop, and can't be interrupted in any way.
There resides the problem; if you substitute the endless-repeat construct by a jmp/loop-one, it'll work, as expected.
@deets said:
@ManAtWork I do update the timer, it does work when the main “thread” loops endlessly.
Oh, I see. I've overlooked that because the indentication gets messed up when quoting code. Then it must have something to do with the spin interpreter's implementation of waitms(). It probably also uses addct1. That's the danger of mixing spin and assembler in the same cog.
Thanks for the PWM hint, I’d obviously prefer that. I did in fact try that based off an example but the period was too small. I only managed 200us or so. Do you have an example?
sets the base period to 100µs and the frame period to 5000 which should mean 500ms total cycle time. 2500 is half of the frame period and means 50% duty cycle.
PS: BTW, wrong thread/off topic. If you like to discuss more smart pin related stuff please start a new thread.
Flexspin's generated code isn't supposed(tm) to be interrupt-safe. So, ye, it may take arbitrary time for an interrupt to actually fire. Though adding an option to disable REP optimization is probably easy and would solve the biggest issue.
Also, you really really really really really really don't want to define your interrupt handler in inline ASM, it WILL get overwritten with whatever gets loaded into FCACHE next.
@ManAtWork : Unfortunately as @Wuerfel_21 says Flexspin's generated code is not interrupt-safe, and using interrupts in the same COG as compiled code is not supported.
I appreciate the insights. I read somewhere that spin is IRQ friendly - I guess that’s PNut then. Is there a way to safely store PASM and state somewhere? Or should I just declare spin state & it will be accessible?
@deets
have a look to Chip's sample ... he is reading the ADC with PASM in the spin program, in the background, using interrupts IIRC.
I can't remember exactly where the sample is, perhaps also included in the pnut archive.
Comments
@ersmith
Issue #1: There seems to be some mischief compiling without optimization in FlexBASIC 5-9-1-Beta. This code:
produces these errors from the first line after the DO statement:
Similar errors get thrown in other functions when dividing:
This behavior seems to be of recent origin and only occurs with optimization turned off. Any other level of optimization compiles fine.
Issue #2: Comparisons of 64-bit numbers gets wonky in DO/LOOPs if left-most argument is a function call returning 64-bits.
This code works fine: (Note: the function GetCnt64() just returns the 64-bit system counter as a ulongint. Works fine)
This code below differs by one line and throws the error: Bad number of parameters in call to _int64_cmpu: expected 4 found 3
The only difference between these two is the order of the vars/func for the comparison test in the LOOP closure.
No, unfortunately there is no way to insert non-printable characters in a literal string, and a BASIC CONST string can only be a literal.
What are you trying to accomplish? Could you use a VAR or a DIM SHARED instead?
I got myself wrapped-up in thinking the "clean" way of doing it would be to use CONST for consistency, but as you suggested I finally settled on using a DIM SHARED at the module level. Works a treat.
There's a new release of FlexProp, version 5.9.2, available on Patreon (it's been there for a while now actually!) and now on github. This version is a kind of preview of the 6.0.0 release, which is still some way away. There are some notable new features, including:
Also, there's a major change to the Mac OS GUI: it's now built as a complete binary application (similar to the Windows one) and comes with Tcl/Tk 8.6, instead of relying on the system one. This fixes a number of annoying bugs in the (obsolete) Tcl/Tk distributed with MacOS, but probably introduces new bugs .
@ersmith I just now installed the latest Windows version of Flex 5.9.2 obtained from the Patreon page. After compiling I get a TCL error. "APPLICATION ERROR: Version conflict for package "TCL" Have 8..."
Here is the logfile it generated:
This error does not seem to hinder the compiler from working. It seems to get thrown when the compiler has already finished and control is being returned to TCL.
@JRoark : I think you've somehow mixed up two installations of FlexProp. The new one (flexprop 5.9.2) doesn't even have a tcl9.0 subdirectory inside tcl_library. I'd suggest re-installing; if you can't start fresh, then rename (at least) the "src", "bin", and "tcl_library" directories to something else before unpacking 5.9.2 over them.
Roger that! I havent done a fresh install-from-scratch in about two years, so its probably way past time. Thanks for the help.
Hi, I'm using github compiled Flexprop v5.9.2
I have found the flexprop clock initialisation
seems to only use mmmmmmmmmm pll multiplier
and not dddddd xtal divider
I've written a one liner bit of test code to get it accurate to the 1Mhz
using both the ddd divider and mmm multiplier
changing the clkfreq
CON
_xtlfreq = 25_000_000
_clkfreq = 120_000_000 -> 250_000_000
' rdmode ( -- m )
rdmode rdlong x,#@clkmode
jmp #pushx
120 Mhz -> rdmode .bin --- %000000010000000000000011_11111000 * 4 = 100
130 Mhz -> rdmode .bin --- %000000010000000000000100_11111000 * 5 = 125
140 Mhz -> rdmode .bin --- %000000010000000000000100_11111000 * 5 = 125
150 Mhz -> rdmode .bin --- %000000010000000000000101_11111000 * 6 = 150
160 Mhz -> rdmode .bin --- %000000010000000000000101_11111000 * 6 = 150
170 Mhz -> rdmode .bin --- %000000010000000000000101_11111000 * 6 = 150
180 Mhz -> rdmode .bin --- %000000010000000000000110_11111000 * 7 = 175
190 Mhz -> rdmode .bin --- %000000010000000000000110_11111000 * 7 = 175
200 Mhz -> rdmode .bin --- %000000010000000000000111_11111000 * 8 = 200
210 Mhz -> rdmode .bin --- %000000010000000000000111_11111000 * 8 = 200
220 Mhz -> rdmode .bin --- %000000010000000000000111_11111000 * 8 = 200
230 Mhz -> rdmode .bin --- %000000010000000000001000_11111000 * 9 = 225
240 Mhz -> rdmode .bin --- %000000010000000000001000_11111000 * 9 = 225
250 Mhz -> rdmode .bin --- %000000010000000000001001_11111000 * 10 = 250
I don't think this is correct. I'm using the algorithm that Chip gave in the forums, and it uses both the pll multiplier and xtal divider. I don't have a 25 MHz system to test with, but you can see the generated values in the .p2asm file. They're given as comments near the beginning of the file, e.g.:
What I get for some of the values you tried are:
Were you using TAQOZ to print the clock modes? Perhaps the forth runtime changes something in the calculated values?
Oh, for that matter it may not be using the calculated values at all -- my test program was in Spin2, but TAQOZ is pure assembly, so it won't (generally) have the clock set for it automatically. How are you getting flexspin's calculated clock frequencies into the TAQOZ code?
Just found the nasty bit of stuff which mucks up the clock,
it's getting the flick
I'm sorry, I don't understand this comment... did you miss posting some of the text, perhaps?
I've posted FlexProp version 5.9.3 binaries on the usual sites (github and Patreon). This version supports the new Spin2 floating point operators, and a few miscellaneous bug fixes.
the Taqoz compile time changes things,
I've read so much code lately to find how the P2 works,
Eric
There seems to be something wrong with the floating point implementation.
I get always one of these errors:
The following minimal Spin2 code produces both errors:
Andy
I experimented with this code and it is round() not compiling as expected.
i:=round (10.2) compiles
i:=round(j) doesn't compile and causes these 2 error comments
i:= f/. 10.0 compiles
Yes, round() seems to be broken. I'll get a fix in soon, but for now you can work around this by adding -Dround=_float_round on the command line. You may get some warnings about round being redefined in some header files, but you can ignore those.
It's not only round(), also trunc() and float() don't like expressions inside parentheses.
Andy
round(), trunc() and float() are all fixed in github (source code) now. The workaround for older flexspin versions is to always use the all-caps versions (ROUND, TRUNC, FLOAT) and to add the following defines to the command line:
Thank you, Eric
I will try that workaround.
I try to register a timer ISR because I don't want to waste a full COG on letting a few LEDs blink. This works if I run the PASM2 method into an endless loop. But the moment I remove that & return, the ISR is not executed anymore.
Any pointers?
Addct1 sets only a single value for the timer. Only a single event is generated when the system clock counter reaches that value. You have to update the timer in your int1 ISR by executing another addct1.
BTW, you can blink LEDs without any cog resources by setting the pin to PWM smart pin mode. By using large values for the base period you can set PWM frequencies in the second range.
@ManAtWork I do update the timer, it does work when the main “thread” loops endlessly.
Thanks for the PWM hint, I’d obviously prefer that. I did in fact try that based off an example but the period was too small. I only managed 200us or so. Do you have an example?
I suspect that a repeat construct without any further parameters, and followed by an indented-code-section will get assembled as an infinite Pasm2-REP-loop, and can't be interrupted in any way.
There resides the problem; if you substitute the endless-repeat construct by a jmp/loop-one, it'll work, as expected.
Hope it helps
Henrique
Oh, I see. I've overlooked that because the indentication gets messed up when quoting code. Then it must have something to do with the spin interpreter's implementation of waitms(). It probably also uses addct1. That's the danger of mixing spin and assembler in the same cog.
sets the base period to 100µs and the frame period to 5000 which should mean 500ms total cycle time. 2500 is half of the frame period and means 50% duty cycle.
PS: BTW, wrong thread/off topic. If you like to discuss more smart pin related stuff please start a new thread.
The Parallax Propeller 2 documentation states that one of the conditions for an interrupt to be processed is that REP can’t be active.
So, I think @Yanomani has probably identified the problem. If you can examine the executable code for a REP instruction you should be able to confirm.
Flexspin's generated code isn't supposed(tm) to be interrupt-safe. So, ye, it may take arbitrary time for an interrupt to actually fire. Though adding an option to disable REP optimization is probably easy and would solve the biggest issue.
Also, you really really really really really really don't want to define your interrupt handler in inline ASM, it WILL get overwritten with whatever gets loaded into FCACHE next.
@ManAtWork : Unfortunately as @Wuerfel_21 says Flexspin's generated code is not interrupt-safe, and using interrupts in the same COG as compiled code is not supported.
I appreciate the insights. I read somewhere that spin is IRQ friendly - I guess that’s PNut then. Is there a way to safely store PASM and state somewhere? Or should I just declare spin state & it will be accessible?
@deets
have a look to Chip's sample ... he is reading the ADC with PASM in the spin program, in the background, using interrupts IIRC.
I can't remember exactly where the sample is, perhaps also included in the pnut archive.