First Tacyon code.
Cannot load at all.
What part is wrong?
V4.4 introduced DOFOR which replaces DO and also Tachyon's ADO to simplify loops while making them more predictable and flexible. So DOFOR takes a start index, a loop count, and an increment val that is added to the index every loop. So $20 $5F 1 DOFOR I EMIT LOOP will print all the printable ASCII characters but just to give you an idea of the flexibility $7E $5F -1 DOFOR I EMIT LOOP will print these in reverse.
Anyway, there are a lot more efficient ways of doing this shifting in Tachyon as it has built-in SPI operators that will shift out all 8-bits in 2us but just to give you an idea how to write this in high level code:
\ Send data to shift-register
\ ( n -- ) n:E(bit6) + LED_on(bit5) + RS(bit4) + lcd4bit(bit3-0)
: shift_out ( n -- )
24 REV \ flip 8-bits so msb will be first to shift right out
data MASK SWAP \ create an iomask + data combo for SHROUT
8 FOR SHROUT clk HIGH clk LOW NEXT \ no need to delay, just shift right to output and clock 8 times
2DROP \ discard i/o mask and data
;
SHROUT ( iomask dat -- iomask dat>>1 ) will shift the next bit out to the pin specified in the mask and shift the data right for the next SHROUT etc.
FOR NEXT is all that you require for a simple counted loop which is analogous to a djnz operation in PASM.
24 REV actually flips all 32-bits over so that the lsb becomes the msb etc and in the same operation it shifts that flip 24 bits to the right.
( 0036 $3610 MON ) $A2 24 REV .LONG
0000.0045
BTW, you had DO in lowercase which if V4.4 still had it would be acceptable for interactive console use but correct case is necessary during a TACHYON END block load (faster).
REV ( n1 bits -- n2 ) C Reverse LSBs of n1 and zero-extend
This mean that Reverse LSBs of upper bits(b31--) 0-masked n1 ?
$37 #24 REV -> $76
$37 #28 REV -> $E
REV is the same as the PASM instruction and the explanation for it can be a bit confusing but all it does is flip all the bits 31->0, 0->32 etc and the parameter is then used to shift that flip right. So 0 REV will not shift at all but simply flip all the bits over. However a 24 REV is useful for flipping a byte and putting it back in the first 8 lsbs where it originally was.
Stack garbage is just that, leftovers from playing around and is purposely not cleared automatically. Your ^S cleared it as will a reset or !SP or any application that executes !SP. If there is a value on the stack then it got there by some means and not randomly so I guess you backtrack to find the source of it.
caskaz - do you have line delay set for 5ms or more? Character delay should be zero. Not sure what those "christmas trees" are in the version number though. Comms parameters are 8N1 but I might have to try your file in TeraTerm to see if I can recreate the problem. Also, make sure you set your text document "line endings" setting to standard Windows with CRLF as some only use line feed characters.
I'm aware loading Module( CHARLCD.fth).
Module( CHARLCD.fth) is loaded although power-off-on.
Which word saved in eeprom?
How to erase module( CHARLCD.fth)?
BACKUP --- saves the current "state" of the system with all the modules...
FORGET CHARLCD.fth --- forget this module
Any modules loaded after CHARLCD.fth will also be forgotten. Remember you will have to BACKUP after a FORGET if you want to save this state of the system between reboots, else CHARLCD.fth will be back.
Glad you see you checking out Tachyon caskaz, I always read your posts.
EXTEND has all the utilities loaded into it along with I2C and EEPROM routines including BACKUP which is in fact what it uses to lock everything into EEPROM once EXTEND is loaded. Normally any Tachyon software that is loaded includes ?BACKUP at the very end which checks for compile errors first and if there are none it then continues to perform a BACKUP. What BACKUP does is copy almost everything in hub RAM to EEPROM excluding the data areas at the top of memory since these areas in EEPROM are where the binary images for the Tachyon and receive cog are held where normally in Spin these images are memory wasted but Tachyon uses them for receive buffers, SD card buffers, and general data that doesn't need to be backed up.
There are also other binary images that are automatically loaded into upper EEPROM when EXTEND is loaded and these are referred to as ROMS that can be loaded by name at runtime. In fact the floating point F32 ROM is loaded automatically into cog 3 but I haven't made use of it yet although I have left it to dangle as a plaything for anyone adventurous enough to write the interface for it! (there is some basic interface code in EXTEND).
COMPACT is an operation that is normally performed once you fill up your 32k memory so that the current dictionary is moved over to upper EEPROM but this results in slower searches though and is normally only necessary when you add EASYNET drivers and server code.
V4.4 and V4 in general have lots of nice features but there are some things that still need polishing up that I certainly am aware of, however all these little things will be addressed soon enough. V3 is the original bytecode version of Tachyon and although there is nothing wrong with it and it is quite stable, I am concentrating on the newer versions.
I've found that DO LOOPs are a little back to front when I go to use them and I many times I would use the BOUNDS DO combination so that I had a start index and a count. So in Tachyon without "much ado" I turned that BOUNDS DO into a single ADO as a more efficient operation. Then in V4.4 I finally got around to creating what I feel is a better structure for loops where I would work with a start index and a count just like ADO (or BOUNDS DO) but I would also specify a value to increment the index with rather than leaving it up to LOOP and +LOOP. The important thing about DOFOR is that I have a fixed loop count that does not change if the loop index increment value changes as in the case of +LOOP.
If I want to loop 64 times but specify that the index be incremented or decremented by some value, then I know it will loop 64 times no matter the increment value just as this code shows.
0 64 4 DOFOR CR I .WORD SPACE I @ .LONG LOOP
If now I change the increment value to 16 so that it picks up every 4th long (16 bytes) then it will still print 64 longs.
0 64 8 DOFOR CR I .WORD SPACE I @ .LONG LOOP
This way I have more control of a loop and the loops are also faster since they don't need a value pushed onto the stack for +LOOP which btw is not present in 4.4, only DOFOR LOOP or the simpler FOR NEXT.
The other thing about DOFOR is that the index I is on top of the loop stack rather than buried under the old limit value for a DO. This means that FOR NEXT also uses the index I since there is only one parameter on the stack, right on the top, the index I which counts down.
Anyway, to use DOFOR you have the starting index, how many times it needs to loop for, and then the index increment value which is normally 1.
I notice too that in your shift loops you are using some form of delay whereas that shouldn't be necessary unless the shift register is far away and the wire capacitance is high.
For readability indenting should help. You can also use { } brackets for multi-line comments with having to worry about back slash \ and there are other comment methods too. I tend to prefer my 3 dash one since it doesn't clutter and I can add it above the pub/pri/ppre <name> without clutter;
--- Write 8-bit data to 74164 type shift register
pub WR74164 ( 8b -- )
The routines to make clock and data go high or low are probably redundant as it is just as easy and more efficient to say "data LOW" or "clk HIGH clk LOW".
I'm not quite sure how you are using the 164 to send serial as on one hand you say that the LCD enable pin is connected to output 6 of the 164 and on another function you have a strange and very long millisecond pulse.
good, btw "dup 0 > IF" can simply be "?DUP IF" (doesn't DUP a zero) since IF accepts any non-zero value as a "true" . However PRINT$ will take the address of a string and print it to the output device and all you have to do is make the lcd an output device like this:
: LCD ' lcd_char uemit W! ;
So that you would simply say LCD PRINT" HELLO WORLD" CON with the CON returning the output back to the console. Of course this only handles characters but you can get it to process control characters and take appropriate action as in CHARLCD.fth
I cannot understand [: LCD ' lcd_char uemit W! ;] at all whenI read it in CHARLCD.fth.
I did it just now.
String print on LCD.
How does string pass to LCD?
This is Tachyon kernel's function?
What uemit? it is variable?
uemit is the vector to tachyon output so by assigning ' lcd_char to uemit vector everything output goes to lcd_char instead of the console, to get back to console output you use CON as Peter has stated
LCD ." Hello World" CON
This will redirect the output (Hello World) to lcd_char then change the output back to the CONsole, nice right?
Redirecting character input and output are the easier and preferred way of implementing character I/O rather than recreating special string and number handlers for each and every device. Once you have made your LCD a standard output driver which at leasts interprets the basic control characters you can then treat it as if it were a serial module. This means you don't have to directly access the internal methods such as clear or newline etc by name, just treat it much the same as you would a terminal with the exception of special control characters that may turn the display on and off etc.
Have a good look at LCDEMIT in LCDCHAR.fth and follow the path that characters and controls take to find out more. That is why I can bundle up the LCD as a separate serial module if I need to and place far away and yet I scarcely change the main program that talks to it, all I need to do is change the LCD word to point to a serial output routine instead. However the main strength of this approach is the flexibility and ease of use.
--- redirect emit output to serial on pin 5
pub LCD 5 SERIAL ;
@MJB - good news, and I will still get around to getting the old cards to work too. I'm thinking now it might be as simple as increasing a timeout since the old cards can take quite a while from when a read/write command is issued until the data is ready.
@MJB - good news, and I will still get around to getting the old cards to work too. I'm thinking now it might be as simple as increasing a timeout since the old cards can take quite a while from when a read/write command is issued until the data is ready.
( 0010 $348A ok ) 0 IF PRINT" TRUE" THEN
( 0011 $348A ok ) TRUE IF PRINT" TRUE" THEN
TRUE
( 0012 $348A ok ) 1 IF PRINT" TRUE" THEN
TRUE
( 0013 $348A ok ) 123456 IF PRINT" TRUE" THEN
TRUE
If the stack is empty and you type "1 2DUP" then 2DUP will do exactly what it has been told and duplicate the top two items off the "stack". In this case although you only pushed 1 you must have had a number already on the stack since you have ended up with a depth of 4.
For your test code you just remember that what you are doing is incorrect since there are obvious mistakes in the code such as pushing 1 onto the stack in the beginning and yet executing 2DUP on that single value etc. Just by stepping through the code in your head and making notes in the code you will see that the UNTIL is not receiving the correct value but I'm not even really sure what you are trying to test in test? 1 BEGIN 2DUP sequence does not make any sense.
If your Forth code module doesn't FORGET 2w_charLCD.fth then it will of course do exactly what you asked it to do and load another copy of the program. That is why if you use CHARLCD.fth as a model you can see it will check before it defines anything and proceed to FORGET. If you try now to forget after loading multiple copies of your code then you will still have old copies still sitting there that need to be forgotten too.
btw, if you think about it, if Forth gives you a warning about a simple operation then that must mean that there is a lot of overhead in there checking all the time. If I type in 2DUP on an empty stack in gforth it warns me:
2dup
:30: Stack underflow
>>>2dup<<<
Backtrace:
Wow! I can only imagine the overhead and waste of memory and cpu cycles. If we did a Forth like that for the Prop then we would never be able to do anything useful or quickly, it would just be a show pony
Propeller .:.:--TACHYON--:.:. Forth V4.4 DAWN 440170610.0600
Cold start - no user code - setting defaults
--------------------------------------------------------------------------------
( 0001 $1B00 ok ) TACHYON V4
Propeller .:.:--TACHYON--:.:. Forth V4.4 DAWN 440170610.0600
( 0026 $1B1E ok ) Structure mismatch! *error*
--------------------------------------------------------------------
( 0001 $1B1E ok )
What does this mean?
Downloaded from dropbox today, and loaded spin with 115200 baud. try'd to load EXTEND.FTH on a Propeller Platform with 32kb eeprom. I use'd GtkTerm with 10ms. delay line.
Comments
V4.4 introduced DOFOR which replaces DO and also Tachyon's ADO to simplify loops while making them more predictable and flexible. So DOFOR takes a start index, a loop count, and an increment val that is added to the index every loop. So $20 $5F 1 DOFOR I EMIT LOOP will print all the printable ASCII characters but just to give you an idea of the flexibility $7E $5F -1 DOFOR I EMIT LOOP will print these in reverse. Anyway, there are a lot more efficient ways of doing this shifting in Tachyon as it has built-in SPI operators that will shift out all 8-bits in 2us but just to give you an idea how to write this in high level code:
SHROUT ( iomask dat -- iomask dat>>1 ) will shift the next bit out to the pin specified in the mask and shift the data right for the next SHROUT etc.
FOR NEXT is all that you require for a simple counted loop which is analogous to a djnz operation in PASM.
24 REV actually flips all 32-bits over so that the lsb becomes the msb etc and in the same operation it shifts that flip 24 bits to the right.
BTW, you had DO in lowercase which if V4.4 still had it would be acceptable for interactive console use but correct case is necessary during a TACHYON END block load (faster).
There is no description about DOFOR on "Grossary of Tachyon word".
This is not newest?
I don't understand About REV.
Sometimes there is 30424 on stack after execution.
This cause only console input?
REV ( n1 bits -- n2 ) C Reverse LSBs of n1 and zero-extend
This mean that Reverse LSBs of upper bits(b31--) 0-masked n1 ?
$37 #24 REV -> $76
$37 #28 REV -> $E
This cause only console input?
Or my installed Tachyon is abnormal?
REV is the same as the PASM instruction and the explanation for it can be a bit confusing but all it does is flip all the bits 31->0, 0->32 etc and the parameter is then used to shift that flip right. So 0 REV will not shift at all but simply flip all the bits over. However a 24 REV is useful for flipping a byte and putting it back in the first 8 lsbs where it originally was.
Stack garbage is just that, leftovers from playing around and is purposely not cleared automatically. Your ^S cleared it as will a reset or !SP or any application that executes !SP. If there is a value on the stack then it got there by some means and not randomly so I guess you backtrack to find the source of it.
I think I understand about REV.
But cannot load yet.
Tachyon freeze at loading code.
I'm aware loading Module( CHARLCD.fth).
Module( CHARLCD.fth) is loaded although power-off-on.
Which word saved in eeprom?
How to erase module( CHARLCD.fth)?
Any modules loaded after CHARLCD.fth will also be forgotten. Remember you will have to BACKUP after a FORGET if you want to save this state of the system between reboots, else CHARLCD.fth will be back.
Glad you see you checking out Tachyon caskaz, I always read your posts.
Erased CHARLCD.fth.
ButThereis no statement'BACKUP' inloading file.
Changed filename from 2wire_charLCD.fth to wirecharLCD.fth
Filename length is max11?
Loading is ok although there are errors yet.
Okay, try lowercase: backup
I don't have V4 loaded up, still using V3 for some file IO needs, but I'll load V4 up and follow along so I can help.
dp
Where is BACKUP-V4R4.FTH?
Hi Peter.
TachyonV4.4 freeze when entered [LAP1 us LAP .LAP]
Now asserted:
BACKUP is inside of EXTEND.FTH
There are also other binary images that are automatically loaded into upper EEPROM when EXTEND is loaded and these are referred to as ROMS that can be loaded by name at runtime. In fact the floating point F32 ROM is loaded automatically into cog 3 but I haven't made use of it yet although I have left it to dangle as a plaything for anyone adventurous enough to write the interface for it!
COMPACT is an operation that is normally performed once you fill up your 32k memory so that the current dictionary is moved over to upper EEPROM but this results in slower searches though and is normally only necessary when you add EASYNET drivers and server code.
V4.4 and V4 in general have lots of nice features but there are some things that still need polishing up that I certainly am aware of, however all these little things will be addressed soon enough. V3 is the original bytecode version of Tachyon and although there is nothing wrong with it and it is quite stable, I am concentrating on the newer versions.
Initilize og characterLCD is successful.
character display well on LCD.
string[ABCDEFG] display but inifinity-loop.
Debug on console when executing lcd_str.
\ ( n1 -- ) n1:string sample:[ " ABC" ]
: lcd_str
DUP LEN$ \ ( address length )
DUP 0 >
IF
OVER + 1 \ ( start end cnt )
.S
DOFOR I C@ .S lcd_char LOOP \ Print string
ELSE
2DROP
ENDIF
;
Using of DOFOR-LOOP is wrong?
I've found that DO LOOPs are a little back to front when I go to use them and I many times I would use the BOUNDS DO combination so that I had a start index and a count. So in Tachyon without "much ado" I turned that BOUNDS DO into a single ADO as a more efficient operation. Then in V4.4 I finally got around to creating what I feel is a better structure for loops where I would work with a start index and a count just like ADO (or BOUNDS DO) but I would also specify a value to increment the index with rather than leaving it up to LOOP and +LOOP. The important thing about DOFOR is that I have a fixed loop count that does not change if the loop index increment value changes as in the case of +LOOP.
If I want to loop 64 times but specify that the index be incremented or decremented by some value, then I know it will loop 64 times no matter the increment value just as this code shows. If now I change the increment value to 16 so that it picks up every 4th long (16 bytes) then it will still print 64 longs. This way I have more control of a loop and the loops are also faster since they don't need a value pushed onto the stack for +LOOP which btw is not present in 4.4, only DOFOR LOOP or the simpler FOR NEXT.
The other thing about DOFOR is that the index I is on top of the loop stack rather than buried under the old limit value for a DO. This means that FOR NEXT also uses the index I since there is only one parameter on the stack, right on the top, the index I which counts down.
Anyway, to use DOFOR you have the starting index, how many times it needs to loop for, and then the index increment value which is normally 1.
I notice too that in your shift loops you are using some form of delay whereas that shouldn't be necessary unless the shift register is far away and the wire capacitance is high.
For readability indenting should help. You can also use { } brackets for multi-line comments with having to worry about back slash \ and there are other comment methods too. I tend to prefer my 3 dash one since it doesn't clutter and I can add it above the pub/pri/ppre <name> without clutter; The routines to make clock and data go high or low are probably redundant as it is just as easy and more efficient to say "data LOW" or "clk HIGH clk LOW".
I'm not quite sure how you are using the 164 to send serial as on one hand you say that the LCD enable pin is connected to output 6 of the 164 and on another function you have a strange and very long millisecond pulse.
I cannot understand [: LCD ' lcd_char uemit W! ;] at all whenI read it in CHARLCD.fth.
I did it just now.
String print on LCD.
How does string pass to LCD?
This is Tachyon kernel's function?
What uemit? it is variable?
uemit is the vector to tachyon output so by assigning ' lcd_char to uemit vector everything output goes to lcd_char instead of the console, to get back to console output you use CON as Peter has stated
This will redirect the output (Hello World) to lcd_char then change the output back to the CONsole, nice right?
beeing able to use my old small SD cards would be nice of course ...
for now I am fine
Have a good look at LCDEMIT in LCDCHAR.fth and follow the path that characters and controls take to find out more. That is why I can bundle up the LCD as a separate serial module if I need to and place far away and yet I scarcely change the main program that talks to it, all I need to do is change the LCD word to point to a serial output routine instead. However the main strength of this approach is the flexibility and ease of use.
@MJB - good news, and I will still get around to getting the old cards to work too. I'm thinking now it might be as simple as increasing a timeout since the old cards can take quite a while from when a read/write command is issued until the data is ready.
And APPEND too
Same file is loaded.
Sometimes input-miss from console occur.
Now serial-speed is 921600(default).
Slower speed is better?
infinity loop
What is wrong?
Looks like you loaded the module more than once?
for the infinite loop issue -1 is true in tachyon everything else is false so you are always returning false in your IF statement
If the stack is empty and you type "1 2DUP" then 2DUP will do exactly what it has been told and duplicate the top two items off the "stack". In this case although you only pushed 1 you must have had a number already on the stack since you have ended up with a depth of 4.
For your test code you just remember that what you are doing is incorrect since there are obvious mistakes in the code such as pushing 1 onto the stack in the beginning and yet executing 2DUP on that single value etc. Just by stepping through the code in your head and making notes in the code you will see that the UNTIL is not receiving the correct value but I'm not even really sure what you are trying to test in test? 1 BEGIN 2DUP sequence does not make any sense.
If your Forth code module doesn't FORGET 2w_charLCD.fth then it will of course do exactly what you asked it to do and load another copy of the program. That is why if you use CHARLCD.fth as a model you can see it will check before it defines anything and proceed to FORGET. If you try now to forget after loading multiple copies of your code then you will still have old copies still sitting there that need to be forgotten too.
btw, if you think about it, if Forth gives you a warning about a simple operation then that must mean that there is a lot of overhead in there checking all the time. If I type in 2DUP on an empty stack in gforth it warns me: Wow! I can only imagine the overhead and waste of memory and cpu cycles. If we did a Forth like that for the Prop then we would never be able to do anything useful or quickly, it would just be a show pony
Downloaded from dropbox today, and loaded spin with 115200 baud. try'd to load EXTEND.FTH on a Propeller Platform with 32kb eeprom. I use'd GtkTerm with 10ms. delay line.
I think cold-start is only Tahyon-kernel-body.
You shuld load EXTEND.FTH.
It seem you download different kernel to me.
Please check TACHYON FORTH web page.
Introduction to TACHYON Forth
I'm Tachyon new comer same as you.
Enjoy slowly Tachyon.