I was so used to having only one or two characters to indicate comments that I hadn't noticed that ( would do it. I was using a \ before the ( . I can see now that seeing ( and not \ ( was confusing me. That's cleared up.
Here's another.
From the kernel:
{ quick test
pub TC ( ch -- )
CASE
"4" =[ ." Knock on the door, it's a 4" ]=
"5" =[ ." Let's jive, it's a 5" ]=
"7" "9" ..[ ." Pick up sticks, it's more than six" ]=
;
}
Can't determine what =[ and ]= do. Also ..[
I know the whole clip is a comment but I don't what's going on there. Help?
looks like an old version of CASE now changed to more C-like
SWITCH CASE -> see pub CASEDEMO
I have the whole TACHYON files - Kernel + EXTEND + ... all extensions in NOTEPAD++ and then just do a search-all-files ...
this reveals immediately what's going on ... and =[ are only in this single place
I was so used to having only one or two characters to indicate comments that I hadn't noticed that ( would do it. I was using a \ before the ( . I can see now that seeing ( and not \ ( was confusing me. That's cleared up.
Here's another.
From the kernel:
{ quick test
pub TC ( ch -- )
CASE
"4" =[ ." Knock on the door, it's a 4" ]=
"5" =[ ." Let's jive, it's a 5" ]=
"7" "9" ..[ ." Pick up sticks, it's more than six" ]=
;
}
Can't determine what =[ and ]= do. Also ..[
I know the whole clip is a comment but I don't what's going on there. Help?
I will have to track those outdated examples and bring them up-to-date. As MJB mentioned the newer method is more C like using SWITCH and CASE BREAK statements etc. I will look at updating that in the document but I'm also happy to provide examples of use as well, just let me know.
I did not know about NOTEPAD++. I have just downloaded and will check it out. I have used The Semware Editor ( tsepro ) *forever* and love it. I have been keeping copies of the kernel and EXTEND loaded and switching to search. Sounds like combining for searching might be worth trying.
I was trying to get a handle on the CASE structure and got flummoxed by the old example. Think I've got it now. Just had to realize that the structure does not need an explicit closing term.
looks like an old version of CASE now changed to more C-like
SWITCH CASE -> see pub CASEDEMO
I have the whole TACHYON files - Kernel + EXTEND + ... all extensions in NOTEPAD++ and then just do a search-all-files ...
this reveals immediately what's going on ... and =[ are only in this single place
But you missed some too
I use the --- a lot since it allows me to space out a comment --- --- --- --- out to where I want it --- just so forum BB code doesn't gobble up whitespace plus --- does not clutter or confuse reading code like 1405 7 / \ is confusing
There's also \\\ and *** but I use that mainly to disable lines of code and to distinguish this from a real comment although they work the same way.
I was thinking I had the CASE structure whipped. Wrong!
Why does this work:
FORGET TEST
: TEST \ press keys 1-9 to trigger sensor n repeated reading.
\ when reading in progress press <esc> to return to sensor selection
\ when in selection press <esc> to quit
SWITCH
"1" "9" SWITCH>< IF SWITCH@ CR EMIT BREAK
$1B CASE CR BREAK
;
: DOTEST
BEGIN
KEY UPPER TEST
SWITCH@ $1B =
UNTIL
;
SC DOTEST
And this does not:
FORGET TEST
: TEST \ press keys 1-9 to trigger sensor n repeated reading.
\ when reading in progress press <esc> to return to sensor selection
\ when in selection press <esc> to quit
BEGIN
KEY UPPER
SWITCH
"1" "9" SWITCH>< IF SWITCH@ CR EMIT BREAK
$1B CASE CR BREAK
SWITCH@ $1B =
UNTIL
;
SC TEST
I think it has something to do with what BREAK does to the stack but I can't scope it.
I was thinking I had the CASE structure whipped. Wrong!
Why does this work:
FORGET TEST
: TEST \ press keys 1-9 to trigger sensor n repeated reading.
\ when reading in progress press <esc> to return to sensor selection
\ when in selection press <esc> to quit
SWITCH
"1" "9" SWITCH>< IF SWITCH@ CR EMIT BREAK
$1B CASE CR BREAK
;
: DOTEST
BEGIN
KEY UPPER TEST
SWITCH@ $1B =
UNTIL
;
SC DOTEST
And this does not:
FORGET TEST
: TEST \ press keys 1-9 to trigger sensor n repeated reading.
\ when reading in progress press <esc> to return to sensor selection
\ when in selection press <esc> to quit
BEGIN
KEY UPPER
SWITCH
"1" "9" SWITCH>< IF SWITCH@ CR EMIT BREAK
$1B CASE CR BREAK
SWITCH@ $1B =
UNTIL
;
SC TEST
I think it has something to do with what BREAK does to the stack but I can't scope it.
Good work, yYou are doing well in playing with it to see what it does and doesn't do. If you have a look at the source code you will find that BREAK compiles an EXIT THEN because CASE compiles an = IF so that makes sense. The limitation with this method is of course that when a CASE is taken is that it will EXIT the definition on BREAK so it won't execute any more code in the definition after that, your loop will be broken. This is not normally a problem but it pays to know the limitation.
I suppose that I could define an OTHERWISE ..... ENDCASE where all the BREAKs could know where to jump to but that seems an unnecessary complication as I like to keep the structure open and flexible.
Thanks. Okay, thought it was something like that. I was getting what I could from the source. Wasn't sure what an EXIT does. Yeah, I like to wring the juice out of things that are new to me so I know what to expect.
in working on the webserver -
the lastest EASYNET is not working any more with the W5100 / Spinneret
I spottet the new virtual memory functions as the problem and try to adapt
the W5100.FTH - but I seem to miss s.th.
the request comes in - but no result page back
you surely see quickly, what's missing
thanks,
Markus
still struggling
I traced the problem down to DIR works, but cat <filename> gives 'not found'
with spinneret and latest google doc files up to EASYFILE
I had this SD card working before but made changes to content, so decided to reformat to have clean unfragmented image.
I did this with windows format ...
D.P. reminded me of your post to use the SDFORMATTER tool.
so I did this, copied the files back - looks ok from windows ...
but on spinneret I get this very strange behavior
this explains, why the webserver and FTP do not show the file contents ...
what can I do?
thanks, Markus
here the output
Media mounted as 5957.3321 NO NAME FAT32 Cluster size = 2,768 Sectors = 3,600
not found
ok
Cluster size and Sectors look very strange for a 4GB card
still struggling
I traced the problem down to DIR works, but cat <filename> gives 'not found'
with spinneret and latest google doc files up to EASYFILE
I had this SD card working before but made changes to content, so decided to reformat to have clean unfragmented image.
I did this with windows format ...
D.P. reminded me of your post to use the SDFORMATTER tool.
so I did this, copied the files back - looks ok from windows ...
but on spinneret I get this very strange behavior
this explains, why the webserver and FTP do not show the file contents ...
what can I do?
thanks, Markus
here the output
Media mounted as 5957.3321 NO NAME FAT32 Cluster size = 2,768 Sectors = 3,600
not found
ok
Cluster size and Sectors look very strange for a 4GB card
I meant to have a look at it a while ago but just tried it now and it did the same thing. What I noticed was that it was remounting each time and basically wiping the request. Turned out to be a single line in MOUNT that have been \\\ commented out for some memory optimization but still had to set the mount flag. Fixed it up and it's fine now.
BTW, if you load EPRINT.fth before SDCARD then it will save at least 2K of hub RAM by storing all the print strings in upper EEPROM.
I meant to have a look at it a while ago but just tried it now and it did the same thing. What I noticed was that it was remounting each time and basically wiping the request. Turned out to be a single line in MOUNT that have been \\\ commented out for some memory optimization but still had to set the mount flag. Fixed it up and it's fine now.
BTW, if you load EPRINT.fth before SDCARD then it will save at least 2K of hub RAM by storing all the print strings in upper EEPROM.
how little optimizations can have strange side effects ;-)
OK works again - back to webserver development
I had a look to see if EPRINT could be loaded earlier in sequence to also save part of the strings in EXTEND.
This will be possible with my proposed restructuring of EXTEND.
Just a quick line to say thank you.
I have a MMA845x accelerometer and I decided to test it with Tachyon.
That was easy!!
At the moment I'll revert to spin for trig calculations (I already have all the trig calculations in spin..), but the interactive mode is extremely easy.
It takes a little bit to get acquainted to it, but the sheer power of Tachyon is terrific.
Thanks again,
Massimo
Just a quick line to say thank you.
I have a MMA845x accelerometer and I decided to test it with Tachyon.
That was easy!!
At the moment I'll revert to spin for trig calculations (I already have all the trig calculations in spin..), but the interactive mode is extremely easy.
It takes a little bit to get acquainted to it, but the sheer power of Tachyon is terrific.
Thanks again,
Massimo
Thanks, but is that a little hint to graft in the FPU package?
BTW, do you have that section of Spin code I could look at to make sure it's covered? (when I do integrate it that is
:-)
Not really..
I realised I can do with neithe FPU or trig/cordic.. :-)
That was just a post to say unconditionally thank you.. with no extra requests ;-)
I'm using also the nokia LCD, and the code available is a nice help.
I would like to convert my current relevant spin code to Tachyon... the data come in 2's complement so that would offer me the possibility to learn more.. :-)
I'm using the accelerometer to get the height of a tree. I "look" at it at known distance, and I get back an approximate height.
:-)
Not really..
I realised I can do with neithe FPU or trig/cordic.. :-)
That was just a post to say unconditionally thank you.. with no extra requests ;-)
I'm using also the nokia LCD, and the code available is a nice help.
I would like to convert my current relevant spin code to Tachyon... the data come in 2's complement so that would offer me the possibility to learn more.. :-)
I'm using the accelerometer to get the height of a tree. I "look" at it at known distance, and I get back an approximate height.
Here is your code transposed with Forth for a nice side by side comparison and then at the end how you can code it. I noticed that I did not have the equivalent of a arithmetic right shift ~> and so I combined all those shifts and absolute ops into one definition and here is how it looks:
[FONT=courier new] repeat BEGIN
i2c.i2cstart I2CSTART
k:=i2c.i2cwrite(accel_w) @accel I2C! @accel is the 8-bit i2c address
k:=i2c.i2cwrite(1) 1 I2C!
i2c.i2cstart I2CSTART
k:=i2c.i2cwrite(accel_r) @accel 1+ I2C! read address is always write address+1
accel_x:=i2c.i2cread(0) 0 I2C@
accel_x:=accel_x<<8 8 SHL
accel_x:=accel_x+i2c.i2cread(0) 0 I2C@ +
accel_x:=accel_x<<16 16 SHL #14 ~> ABS x - justify and sign extend then convert to abs
accel_y:=i2c.i2cread(0) 0 I2C@
accel_y:=accel_y<<8 8 SHL
accel_y:=accel_y+i2c.i2cread(0) 0 I2C@ +
accel_y:=accel_y<<16 16 SHL #14 ~> ABS y
accel_z:=i2c.i2cread(0) 0 I2C@
accel_z:=accel_z<<8 8 SHL
accel_z:=accel_z+i2c.i2cread(1) 1 I2C@ +
accel_z:=accel_z<<16 16 SHL #14 ~> ABS z
i2c.i2cstop I2CSTOP
accel_x:=accel_x~>14 combined in previous ops
accel_y:=accel_y~>14
accel_z:=accel_z~>14
||accel_z
||accel_y
||accel_x
pst.char(13) CR
pst.dec(accel_x) ROT .DEC
pst.char(" ") SPACE
2DUP keep a copy of y and z
pst.dec(accel_y) SWAP .DEC
pst.char(" ") SPACE
pst.dec(accel_z) .DEC
pst.char(" ") SPACE
pst.str(string(" -> ")) PRINT" -> "
var1:=dist*accel_y/accel_z / dist @ * divide x by y on stack then multiply by dist variable
pst.dec(var1) .DEC
AGAIN
\ Need to define an arithmetic shift right and though I am loathe to use a hint of PASM it happens to be the most efficient way
\ However in this case we combine all the shifting and ABS in one operation
: AFIX ( hb lb -- result ) SWAP B>W 16 SHL $38FF680E PASM DROP ABS ;
\ Now we define the loop anew
: DOIT
BEGIN
I2CSTART @accel I2C! 1 I2C!
I2CSTART @accel 1+ I2C!
ackI2C@ ackI2C@ AFIX \ x adjusted
ackI2C@ ackI2C@ AFIX \ y adjusted
ackI2C@ 1 I2C@ AFIX \ z adjusted
I2CSTOP
<CR> ROT .DEC SPACE 2DUP SWAP .DEC SPACE .DEC SPACE
PRINT" -> " / dist @ * .DEC
AGAIN
;
[/FONT]
Thanks Peter!
I'll give it a run tonight, and I'll try to digest it all :-)
Just a question:
I was thinking about combining the two bytes and testing bit 16 for the sign. Would it works too?
After all I need to combine the two bytes, get the sign, ABS it, and have it less than say 16-18 bits.
Maybe it's the right occasion to do some experiments :-)
Thanks Peter!
I'll give it a run tonight, and I'll try to digest it all :-)
Just a question:
I was thinking about combining the two bytes and testing bit 16 for the sign. Would it works too?
After all I need to combine the two bytes, get the sign, ABS it, and have it less than say 16-18 bits.
Maybe it's the right occasion to do some experiments :-)
Massimo
I'm not quite sure what result you are looking for but I just had a look at the datasheet and the raw data is 14-bit signed left justified so that the 2 lsbs are zeros. Why are you converting these to an absolute value? Surely you would want it signed?
If raw value = $7FFC then this is the maximum positive value of 8191
$FFFC = -1
So just get the raw 16-bit word and shift it right 2 bits then test bit 13 to see if it's set and if it is then just subtract $4000 from it like this (assuming signed result though):
: AFIX ( hb lb -- result ) SWAP B>W 2 SHR DUP $2000 AND IF $4000 - THEN ;
\ test data by supplying max+ -1 max-
$7F $FC AFIX . 8191 ok
$FF $FC AFIX . -1 ok
$80 $00 AFIX . -8192 ok
An alternative AFIX using the signed shift right operator (implemented as a PASM opcode)
: AFIX ( hb lb -- result ) SWAP B>W 16 SHL $38FF6812 PASM DROP ;
Thanks Peter!
I'll give it a run tonight, and I'll try to digest it all :-)
Just a question:
I was thinking about combining the two bytes and testing bit 16 for the sign. Would it works too?
After all I need to combine the two bytes, get the sign, ABS it, and have it less than say 16-18 bits.
Maybe it's the right occasion to do some experiments :-)
Massimo
: AFIX ( hb lb -- result ) SWAP B>W 16 SHL $28FF680E PASM DROP ABS ;
: AFIX ( hb lb -- result ) SWAP B>W 16 SHL $28FF680E PASM DROP ABS ;
Here they be dragons!
Actually that should have been a $38FF680E hex dragon in this example!
I'm actually allocating a new opcode called MYOP which can be user set easily. By default I use it for fast cropping (<mask> AND) but in this example I would init MYOP with $38FF680E ' MYOP COG! after which I just run AFIX like this:
: AFIX ( hb lb -- result ) --- SWAP B>W 16 SHL MYOP ABS ;
Of course the final example used:
: AFIX ( hb lb -- result ) SWAP B>W 16 SHL $38FF6812 PASM DROP ;
So that would convert to:
: AFIX ( hb lb -- result ) SWAP B>W 16 SHL MYOP ;
In this case MYOP is preset to perform a ~>18 or SAR tos,#18
Thanks Peter.
In fact my original code was a rather primitive test.
I had the two bytes composing the acceleration, and the result from the datasheet is in 2's complement. So I simply shifted left until the acceleration sign bit reached the bit 32, and let spin handle the rest...
Seeing how you code things is a great learning opportunity. The final result is so elegant and effective..
Thanks again.
Massimo
I've been working on V2.4 of the kernel which removes the CMPSTR memory hog from the cog kernel to save memory for other things but it can still run as a RUNMOD during a block mode compiling. I've also added an OPCODE construct that works just like CONSTANT in that you can create an OPCODE word which when invoke is executed as that PASM operation.
\ Example of creating an OPCODE that runs as a PASM instruction when invoked.
$80FF6204 OPCODE ADD4 --- ADD tos,#4
Testing this:
1200 ADD4 . 1204 ok
While playing with the OPCODE word I wondered how much trouble it would be to have a simple inline assembler so I wouldn't have to work out the machine code but could type it in as normal assembly code. Yes, normal assembly code, pretty much. Here's a quick little assembler I have just been playing with and the results of a few quick test codes reveals works quick well. This may be used for assembling OBEX code for my runtime OBEX in EEPROM or SD but rather than take up code memory for something that only gets used during devlelopment I may store the mnemonics and opcodes on an SD file or EEPROM instead.
[FONT=courier new]( Demo assembler for Tachyon Forth )
\ this assembler is being tested but generates code interactively from the console
\ define some conditional execution words
BYTE ce
: CE ce C! ;
: if_z 1010b CE ;
: if_nz 0101b CE ;
: if_c 1100b CE ;
: if_nc 0011b CE ;
\ define some PASM instructions
LONG op
: OP op ! ;
: add 100000_0010b OP ;
: and 011000_0010b OP ;
: rdbyte 000000_0010b OP ;
\ alias for top-of-stack
STACKS == tos
\ define some results modifiers
BYTE sr
: SR+ sr C@ OR sr C! ;
: SR- NOT sr C@ AND sr C! ;
( with results - zcri )
: wc 0100b SR+ ;
: wz 1000b SR+ ;
: nr 0010b SR- ;
: # 0001b SR+ ;
\ The assembler itself - console prompt is revectored to this so all final assembly is carried out on an end-of-line
: ASSEMBLE
BEGIN HERE 3 AND WHILE 1 ALLOT REPEAT
op @ IF
SWAP 9 SHL OR op @ #22 SHL OR sr C@ #22 SHL OR ce C@ #18 SHL OR
4 ALLOT ( just allot the memory for now, do not store )
"A" 1 VC SPACE HERE .WORD ." : " .LONG CR
THEN
$0F CE 0 OP 0 sr C!
;
: ASMCODE ' ASSEMBLE prompt W! "," delim C! "`" NFA' # 1+ C! ' CR prompt 2+ W! ;
\ Now let's try to assemble some code
ASMCODE
add tos,#,1
if_z add tos,#,1 wc
and tos,#,0111
if_c rdbyte tos,tos
add tos 1+,#,4
[/FONT]
The result when run and when compared against code generated by a Spin compiler
[FONT=courier new][COLOR=#0000cd]{ Results from test code
ASMCODE
3758: 80FF.6201 add tos,#,1
3768: 81EB.6201 if_z add tos,#,1 wc
3775: 60FF.6227 and tos,#,100111b
3784: 00B3.63B1 if_c rdbyte tos,tos
3791: 80FF.6404 add tos 1+,#,4
}
[/COLOR]
{ Results from Spin compiler
7E4C(0051) 01 62 FF 80 | ADD tos,#1
7E50(0052) 01 62 EB 81 | if_z ADD tos,#1 wc
7E54(0053) 27 62 FF 60 | AND tos,#100111b
7E58(0054) B1 63 B3 00 | if_c RDBYTE tos,tos ' same thing as a C@
}
[/FONT]
I've had a little time to play a bit more and expand and optimize the resident assembler and considering it's only taking 290 code bytes of storage so far I think I'm doing well. Here's what a listing looks like at the moment and remember that this is interactive on the Prop through the serial terminal but what I want to do is add forward referencing and try to standardize the assembler format closer to how PASM is written in Spin.
EDIT: updated the listing again, I can see that I can remove the :: for labels if I allow the "not found" error handler to create a label, simple. Getting closer.
This inline assembler is just about complete although I still have to resolve how to handle CALL and possibly forward references (in one pass). With all PASM opcodes defined the assembler takes up around 1400 bytes including headers and code. The interesting thing with this assembler is that it just uses the normal Forth parsing technique but TF has a few flexible hooks whereby I can tell it what to do at the start and at the end of a line as well as what to do when it comes across a word that is not in the dictionary nor is it a number. So labels are unknown when Forth first parses them but the "unum" vector which optionally processes unresolvable words points to code that creates a constant using the current origin truncated to 9-bits.
So far so good, I will soon embark on allowing PASM code to be loaded in the same way as source code but have the code saved in a EEPROM or SD file for the runtime OBEX. I've kept it simple with the "corg" directive so it assembles to the BUFFERS area for instance and the lower 9-bits of the address are the same as the assembled cogs address. The object code would then be saved in a file to free up the storage and remove the label constants.The code would include an OBEX name such as "UART4" and at runtime we could load a cog simply by saying " UART4" 2 LOADCOG or " FPU" 5 LOADCOG for instance. With any existing PASM code there is very little modification required to make this work, mostly I just include a space after an immediate # for instance. Normal Forth operations and calculations can be intermixed with PASM even on the same line, this is a macro-macro-assembler!
The implications for P2 are somewhat obvious too, it also means the system can be standalone and even metacompile it's own kernel.
This inline assembler is just about complete although I still have to resolve how to handle CALL and possibly forward references (in one pass). With all PASM opcodes defined the assembler takes up around 1400 bytes including headers and code. The interesting thing with this assembler is that it just uses the normal Forth parsing technique but TF has a few flexible hooks whereby I can tell it what to do at the start and at the end of a line as well as what to do when it comes across a word that is not in the dictionary nor is it a number. So labels are unknown when Forth first parses them but the "unum" vector which optionally processes unresolvable words points to code that creates a constant using the current origin truncated to 9-bits.
So far so good, I will soon embark on allowing PASM code to be loaded in the same way as source code but have the code saved in a EEPROM or SD file for the runtime OBEX. I've kept it simple with the "corg" directive so it assembles to the BUFFERS area for instance and the lower 9-bits of the address are the same as the assembled cogs address. The object code would then be saved in a file to free up the storage and remove the label constants.The code would include an OBEX name such as "UART4" and at runtime we could load a cog simply by saying " UART4" 2 LOADCOG or " FPU" 5 LOADCOG for instance. With any existing PASM code there is very little modification required to make this work, mostly I just include a space after an immediate # for instance. Normal Forth operations and calculations can be intermixed with PASM even on the same line, this is a macro-macro-assembler!
The implications for P2 are somewhat obvious too, it also means the system can be standalone and even metacompile it's own kernel.
Wow, 1400 bytes, access to obex pasm objects, P2 Tachyon being able to "self host". And all "we" did was make a little nudge for FPU pasm access. Uh looks like you are having fun so I'll just shut up and keep studying the code. Thanks Peter
I am missing something basic trying to use the I2C bus from another cog.
I have my allocated space for stack and regs, I am using the standard I2C bus pins which are initialized in I2CSTART,
the routine works as expected when not in a task, then in the task I get zero output as seen by my logic analyzer?
I am missing something basic trying to use the I2C bus from another cog.
I have my allocated space for stack and regs, I am using the standard I2C bus pins which are initialized in I2CSTART,
the routine works as expected when not in a task, then in the task I get zero output as seen by my logic analyzer?
Same ol, same ol, this is the OR'd port pin from the main cog still driven high so you need to release the I2C lines before passing control to another cog. Remember, any cog can set a pin high but another cog cannot pull it down. Either keep the output low in the unused cog or release the DIRA bits. Actually it probably wouldn't really hurt leaving these lines low after an I2CSTOP so I might look at doing that instead.
\ I2C STOP CONDITION also releases I2C lines
pub I2CSTOP
SDA OUTCLR SCL OUTSET 0 DROP SDA OUTSET \ Patch 140319 - leave SDA as a high output (in case it's shared)
0 DROP \ short delay
;
\ I2C STOP CONDITION also releases I2C lines
pub I2CSTOP
SDA OUTCLR SCL OUTSET 0 DROP SDA OUTSET \ Patch 140319 - leave SDA as a high output (in case it's shared)
0 DROP \ short delay
;
So I'll add
pub I2CCLR
SDA OUTCLR SCL OUTCLR
;
Yes, but perhaps this could just be added to I2CSTOP after a few microseconds, but what if we let it float, so:
pub I2CSTOP
SDA OUTCLR SCLR OUTSET 0 DROP SDA OUTSET 1 us SCL INPUTS SDA INPUTS
;
Note: 1 us is actually around 10 us (overhead)
Comments
looks like an old version of CASE now changed to more C-like
SWITCH CASE -> see pub CASEDEMO
I have the whole TACHYON files - Kernel + EXTEND + ... all extensions in NOTEPAD++ and then just do a search-all-files ...
this reveals immediately what's going on ... and =[ are only in this single place
I will have to track those outdated examples and bring them up-to-date. As MJB mentioned the newer method is more C like using SWITCH and CASE BREAK statements etc. I will look at updating that in the document but I'm also happy to provide examples of use as well, just let me know.
I was trying to get a handle on the CASE structure and got flummoxed by the old example. Think I've got it now. Just had to realize that the structure does not need an explicit closing term.
Why does this work: And this does not: I think it has something to do with what BREAK does to the stack but I can't scope it.
Good work, yYou are doing well in playing with it to see what it does and doesn't do. If you have a look at the source code you will find that BREAK compiles an EXIT THEN because CASE compiles an = IF so that makes sense. The limitation with this method is of course that when a CASE is taken is that it will EXIT the definition on BREAK so it won't execute any more code in the definition after that, your loop will be broken. This is not normally a problem but it pays to know the limitation.
I suppose that I could define an OTHERWISE ..... ENDCASE where all the BREAKs could know where to jump to but that seems an unnecessary complication as I like to keep the structure open and flexible.
in working on the webserver -
the lastest EASYNET is not working any more with the W5100 / Spinneret
I spottet the new virtual memory functions as the problem and try to adapt
the W5100.FTH - but I seem to miss s.th.
the request comes in - but no result page back
you surely see quickly, what's missing
thanks,
Markus
still struggling
I traced the problem down to DIR works, but cat <filename> gives 'not found'
with spinneret and latest google doc files up to EASYFILE
I had this SD card working before but made changes to content, so decided to reformat to have clean unfragmented image.
I did this with windows format ...
D.P. reminded me of your post to use the SDFORMATTER tool.
so I did this, copied the files back - looks ok from windows ...
but on spinneret I get this very strange behavior
this explains, why the webserver and FTP do not show the file contents ...
what can I do?
thanks, Markus
here the output Cluster size and Sectors look very strange for a 4GB card
I meant to have a look at it a while ago but just tried it now and it did the same thing. What I noticed was that it was remounting each time and basically wiping the request. Turned out to be a single line in MOUNT that have been \\\ commented out for some memory optimization but still had to set the mount flag. Fixed it up and it's fine now.
BTW, if you load EPRINT.fth before SDCARD then it will save at least 2K of hub RAM by storing all the print strings in upper EEPROM.
how little optimizations can have strange side effects ;-)
OK works again - back to webserver development
I had a look to see if EPRINT could be loaded earlier in sequence to also save part of the strings in EXTEND.
This will be possible with my proposed restructuring of EXTEND.
Thanks Peter, Markus
I have a MMA845x accelerometer and I decided to test it with Tachyon.
That was easy!!
At the moment I'll revert to spin for trig calculations (I already have all the trig calculations in spin..), but the interactive mode is extremely easy.
It takes a little bit to get acquainted to it, but the sheer power of Tachyon is terrific.
Thanks again,
Massimo
Thanks, but is that a little hint to graft in the FPU package?
BTW, do you have that section of Spin code I could look at to make sure it's covered? (when I do integrate it that is
Yes that is a hint, I swear I see a hint in there
:-)
Not really..
I realised I can do with neithe FPU or trig/cordic.. :-)
That was just a post to say unconditionally thank you.. with no extra requests ;-)
I'm using also the nokia LCD, and the code available is a nice help.
I would like to convert my current relevant spin code to Tachyon... the data come in 2's complement so that would offer me the possibility to learn more.. :-)
I'm using the accelerometer to get the height of a tree. I "look" at it at known distance, and I get back an approximate height.
The key code is the following:
Okay, I won't take the hint then
Here is your code transposed with Forth for a nice side by side comparison and then at the end how you can code it. I noticed that I did not have the equivalent of a arithmetic right shift ~> and so I combined all those shifts and absolute ops into one definition and here is how it looks:
I'll give it a run tonight, and I'll try to digest it all :-)
Just a question:
I was thinking about combining the two bytes and testing bit 16 for the sign. Would it works too?
After all I need to combine the two bytes, get the sign, ABS it, and have it less than say 16-18 bits.
Maybe it's the right occasion to do some experiments :-)
Massimo
I'm not quite sure what result you are looking for but I just had a look at the datasheet and the raw data is 14-bit signed left justified so that the 2 lsbs are zeros. Why are you converting these to an absolute value? Surely you would want it signed?
If raw value = $7FFC then this is the maximum positive value of 8191
$FFFC = -1
So just get the raw 16-bit word and shift it right 2 bits then test bit 13 to see if it's set and if it is then just subtract $4000 from it like this (assuming signed result though):
: AFIX ( hb lb -- result ) SWAP B>W 2 SHR DUP $2000 AND IF $4000 - THEN ;
\ test data by supplying max+ -1 max-
$7F $FC AFIX . 8191 ok
$FF $FC AFIX . -1 ok
$80 $00 AFIX . -8192 ok
An alternative AFIX using the signed shift right operator (implemented as a PASM opcode)
: AFIX ( hb lb -- result ) SWAP B>W 16 SHL $38FF6812 PASM DROP ;
Actually that should have been a $38FF680E hex dragon in this example!
I'm actually allocating a new opcode called MYOP which can be user set easily. By default I use it for fast cropping (<mask> AND) but in this example I would init MYOP with $38FF680E ' MYOP COG! after which I just run AFIX like this:
: AFIX ( hb lb -- result ) --- SWAP B>W 16 SHL MYOP ABS ;
Of course the final example used:
: AFIX ( hb lb -- result ) SWAP B>W 16 SHL $38FF6812 PASM DROP ;
So that would convert to:
: AFIX ( hb lb -- result ) SWAP B>W 16 SHL MYOP ;
In this case MYOP is preset to perform a ~>18 or SAR tos,#18
In fact my original code was a rather primitive test.
I had the two bytes composing the acceleration, and the result from the datasheet is in 2's complement. So I simply shifted left until the acceleration sign bit reached the bit 32, and let spin handle the rest...
Seeing how you code things is a great learning opportunity. The final result is so elegant and effective..
Thanks again.
Massimo
\ Example of creating an OPCODE that runs as a PASM instruction when invoked.
$80FF6204 OPCODE ADD4 --- ADD tos,#4
Testing this:
1200 ADD4 . 1204 ok
While playing with the OPCODE word I wondered how much trouble it would be to have a simple inline assembler so I wouldn't have to work out the machine code but could type it in as normal assembly code. Yes, normal assembly code, pretty much. Here's a quick little assembler I have just been playing with and the results of a few quick test codes reveals works quick well. This may be used for assembling OBEX code for my runtime OBEX in EEPROM or SD but rather than take up code memory for something that only gets used during devlelopment I may store the mnemonics and opcodes on an SD file or EEPROM instead.
The result when run and when compared against code generated by a Spin compiler
EDIT: updated the listing again, I can see that I can remove the :: for labels if I allow the "not found" error handler to create a label, simple. Getting closer.
So far so good, I will soon embark on allowing PASM code to be loaded in the same way as source code but have the code saved in a EEPROM or SD file for the runtime OBEX. I've kept it simple with the "corg" directive so it assembles to the BUFFERS area for instance and the lower 9-bits of the address are the same as the assembled cogs address. The object code would then be saved in a file to free up the storage and remove the label constants.The code would include an OBEX name such as "UART4" and at runtime we could load a cog simply by saying " UART4" 2 LOADCOG or " FPU" 5 LOADCOG for instance. With any existing PASM code there is very little modification required to make this work, mostly I just include a space after an immediate # for instance. Normal Forth operations and calculations can be intermixed with PASM even on the same line, this is a macro-macro-assembler!
The implications for P2 are somewhat obvious too, it also means the system can be standalone and even metacompile it's own kernel.
Wow, 1400 bytes, access to obex pasm objects, P2 Tachyon being able to "self host". And all "we" did was make a little nudge for FPU pasm access. Uh looks like you are having fun so I'll just shut up and keep studying the code. Thanks Peter
I have my allocated space for stack and regs, I am using the standard I2C bus pins which are initialized in I2CSTART,
the routine works as expected when not in a task, then in the task I get zero output as seen by my logic analyzer?
Same ol, same ol, this is the OR'd port pin from the main cog still driven high so you need to release the I2C lines before passing control to another cog. Remember, any cog can set a pin high but another cog cannot pull it down. Either keep the output low in the unused cog or release the DIRA bits. Actually it probably wouldn't really hurt leaving these lines low after an I2CSTOP so I might look at doing that instead.
So I'll add
Yes, but perhaps this could just be added to I2CSTOP after a few microseconds, but what if we let it float, so:
pub I2CSTOP
SDA OUTCLR SCLR OUTSET 0 DROP SDA OUTSET 1 us SCL INPUTS SDA INPUTS
;
Note: 1 us is actually around 10 us (overhead)