I will hook up the scope and have a look at the timing as I can simulate a download from another Prop so that I can control the timing a little better. It may be that I need to optimize the receive post-processing to make sure it's ready for the next character. But truly, under Linux Mint (Ubuntu base) and using FT232Rs and Minicom and i7 I am not experiencing any of these problems though obviously they exist.
With the latest kernel I'm having problems with minicom and the Prop Professional Dev Board, the BOE and QuickStart boards work just dandy. Earlier version of the FTDI chip?
The symptom is no I in I/O, the banner appears but no Input to the device is possible. Not even das blinken lits on the FTDI chip during keystrokes?
The PPDB works okay in TeraTerm and ZTerm but both of these can't compare to compile speeds (uploads) I get with Minicomm. Only using 230400 8N1
One other thing is that the PPDB will only boot the kernel if the usb is plugged in to a computer. And yes I do have pwr to the PPDB via a 7.5V supply. I must be missing something here, again. doh
and realized I had never seen an TF words for accessing the Prop's sine table.
So I dug into my PDF of the Hydra book (it is a great resource!) and found it on page 212.
I cobbled this together:
: Sin ( angle -- sine )
DUP 1 SHL $FFE AND DUP
OVER $800 AND
IF $F000 - ELSE $E000 + THEN
@ $FFFF AND
;
: SIN Sin #10000 * $FFFF / ." ==> ." $040A .NUM CR ;
"Sin" is the fetch word. "SIN" takes the actual sine off the stack and prints it out as a decimal.
One shortcoming of the sine table is that 2049 entries divided by 90 degrees when done by integer math dropping the remainder gets you 22 entries per degree, whereas floating point gets you 22.76666... a not inconsiderable error.
and realized I had never seen an TF words for accessing the Prop's sine table.
So I dug into my PDF of the Hydra book (it is a great resource!) and found it on page 212.
I cobbled this together:
: Sin ( angle -- sine )
DUP 1 SHL $FFE AND DUP
OVER $800 AND
IF $F000 - ELSE $E000 + THEN
@ $FFFF AND
;
: SIN Sin #10000 * $FFFF / ." ==> ." $040A .NUM CR ;
"Sin" is the fetch word. "SIN" takes the actual sine off the stack and prints it out as a decimal.
One shortcoming of the sine table is that 2049 entries divided by 90 degrees when done by integer math dropping the remainder gets you 22 entries per degree, whereas floating point gets you 22.76666... a not inconsiderable error.
If anyone can tighten this up ... please do!
... enjoy ... BBR
Thanks for bringing this up Brian, to tell the truth I've never looked into it. There are a few errors in your code but this is what I have found will work though it's not the final version. The Spin version looked weird so I found a PASM version which I used as the basis.
[FONT=courier new]pub SIN ( angle -- sine )
DUP $800 AND IF NEGATE THEN
$7000 OR 2* W@
;
\ This version takes the angle scaled to 2 decimal places and converts it to the 13-bit sine
pub SIN2 ( angle.00 -- sine )
#45 * #200 / SIN
;
pub .SIN
SIN2 #10,000 * 16 SHR ." = " .DEC
;
pub SINES #9000 0 DO CR I .DEC SPACE I .SIN #100 +LOOP ;
[/FONT]
You forgot a # on the 16 . I added a decimal point on the display
pub .SIN
SIN2 #10,000 * #16 SHR ." = ." .DEC
;
Yes, normally you would need a # to force it to decimal but I added a 16 as a fast constant instruction so this compiles as one byte rather than a 2 byte literal since it gets used often enough I felt.
I was also thinking that I would put a "0." in front of the result but of course it is only a demo anyway. I did have a chance to look at some threads discussing the use of the sine table and see that Phil has refined the method a little so I may look at coding that too. The 16 SHR is not the same as a 65535 / but close enough for now. Perhaps while I am into this I may even write a maths library although I favor scaled integer operations normally. Are there any opinions on the most suitable method and representation and the precision required? Do I go all the way or is there a minimal requirement? It may be that I might create a floating point stack in hub ram so I am not limited by memory with what can be achieved.
It turns out that while working on this I had some kind of a RAM failure in my DIP--40 Prop ... just few bytes and when it loaded it scrambled things rendering a half dozen or so commands useless or "???" like "MY" an your fast constant 16. Things were degenerating, culmination in I could load EEPROM and sort of run, but if I loaded RAM only SimpleIDE would verify the RAM load and it would always fail.
I pulled the chip, replaced it. rebuilt my kernel and extensions, tested your sine stuff ... since it was all back to working, I took the bad Prop, bent up its legs and threw it into File 13
It turns out that while working on this I had some kind of a RAM failure in my DIP--40 Prop ... just few bytes and when it loaded it scrambled things rendering a half dozen or so commands useless or "???" like "MY" an your fast constant 16. Things were degenerating, culmination in I could load EEPROM and sort of run, but if I loaded RAM only SimpleIDE would verify the RAM load and it would always fail.
I pulled the chip, replaced it. rebuilt my kernel and extensions, tested your sine stuff ... since it was all back to working, I took the bad Prop, bent up its legs and threw it into File 13
cheers ... BBR
File 13 is for the embarrassing stuff but weird stuff like "RAM failure" needs to be investigated and should be pushed to the TOS. Any chance of rebending this and finding out what happened? Could it be that it's RC oscillator is a little on the fast side and the EEPROM too slow, perhaps only because of a weak SDA pullup resistor? What value are you using because I know that you have multiple EEPROMs in your system and 10K is enough for most but 2K2 would be far better.
BTW, this is basically the same code I posted previously but I have overlaid it with the PASM example so those unfamiliar with Forth can follow the code.
[
[B][COLOR=#000000][FONT=Ubuntu Mono]( TACHYON Forth COS/SIN lookup method as per PASM method - Hydra Manual p212 )[/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono]\ getcos add sin,sin_90 'for cosine, add 90°[/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono]pub COS ( angle -- cosine )[/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono]$800 +[/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono]\ getsin test sin,sin_90 wc 'get quadrant 2|4 into c[/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono]\ test sin_sin_180 wz 'get quadrant 3|4 into nz[/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono]\ negc sin,sin 'if quadrant 2|4, negate offset[/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono]pub SIN ( angle -- sine )[/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono] DUP $1000 AND SWAP \ test quadrant 3|4 [/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono] DUP $800 AND IF NEGATE THEN \ test quadrant 2|4 and negate if true [/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono]\ or sin,sin_table 'or in sin table address >> 1[/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono]\ shl sin,#1 'shift left to get final word address[/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono]\ rdword sin,sin 'read word sample from $E000 to $F000[/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono] $7000 OR 2* W@ \ lookup word from sin table [/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono]\ negnz sin,sin 'if quadrant 3|4, negate sample[/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono]\ getsin_ret[/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono]\ getcos_ret ret '39..54 clock (variance is due to Hub sync on RDWORD)[/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono] SWAP IF NEGATE THEN \ if quadrant 3|4, negate sample[/FONT][/COLOR]
[COLOR=#000000][FONT=Ubuntu Mono] ;[/FONT][/COLOR]
[/B]
Here is a quick look at the output by graphing it onto the terminal.
I retract my earlier comments about what went wrong. The more I thought about the more I was convinced it was something else.
The one repeatable symptom of was the dictionary no longer knowing "MY" I narrowed it down to the BACKUP/RESTORE. I checked after each BACKUP and "MY QWORDS" worked.. But as soon as I did a RESTORE all I got was "MY ??? QWORDS" and my secondary marker the 'fast constant' 16 was no longer evaluated as 16d but as $16. I rebuilt my kernel (130605) and EXTEND (130607) three times and three more times it did the same thing upon invoking the RESTORE word.
I retract my earlier comments about what went wrong. The more I thought about the more I was convinced it was something else.
The one repeatable symptom of was the dictionary no longer knowing "MY" I narrowed it down to the BACKUP/RESTORE. I checked after each BACKUP and "MY QWORDS" worked.. But as soon as I did a RESTORE all I got was "MY ??? QWORDS" and my secondary marker the 'fast constant' 16 was no longer evaluated as 16d but as $16. I rebuilt my kernel (130605) and EXTEND (130607) three times and three more times it did the same thing upon invoking the RESTORE word.
Now what???
Oh yeah, I remember now that I have been having a little problem lately with COLD then reloading applications because it's not releasing all the used vectors but that may be tied with BACKUP itself. I will have a look.
Oh yeah, I remember now that I have been having a little problem lately with COLD then reloading applications because it's not releasing all the used vectors but that may be tied with BACKUP itself. I will have a look.
So use REBOOT for now? (Please excuse if this sounds like a noob question: it is!)
Also, can BACKUP be used without issue? Edit: I see it is an issue.
So use REBOOT for now? (Please excuse if this sounds like a noob question: it is!)
Also, can BACKUP be used without issue? Edit: I see it is an issue.
RickInTexas
Not really, BACKUP has been working fine since day one and RESTORE is only used if you have a larger EEPROM and a BACKUP also backups up the previous image although I have disabled this automatic feature (Brian?). Normally all you need to do is a BACKUP which updates the EEPROM with the current RAM image minus the parts that should not be overwritten etc. I think the problem I'm seeing is more to do with this rather large application which messes with the EEPROM but I will investigate further.
So Rick what's your current status? Are you still having serial problems? Seeing that you still had problems even with 1ms character delay seemed totally improbably that it had anything to do with the Prop or Tachyon. I will see if I can write a couple of lines of code to help debug this.
I found "my problem" with my large application and it turned out that COLD was not clearing all the vectors which meant that after a few COLDs and reloading my apps I would find that Tachyon exhausted it's vector table. As a note there would never really be a problem with not having enough vectors as the real limit is the amount of RAM for code and data anyway. Even with my app and drivers etc I still have 357 vectors free.
V3 will allow more memory to be free because it will maintain most of the names in EEPROM/Flash but when it comes to creating a "build" during which time the system is not normally running an app it will use another cog to cache from EEPROM/Flash and search the dictionary etc. This way the runtime Tachyon cog(s) can have a few more goodies loaded as there are 24 longs taken just by the CMPSTR instruction and it's really only needed for fast loads. V3 will also introduce some other enhancements including compile-time-only headers and code (discarded at the end of a build). Seeing that serial Flash is so cheap and small it makes sense to allow source modules to be loaded from serial Flash or SD so that a build would only need user code loaded through the console and it could just ask to "include L6470.fth" for instance. If Flash or SD exists it makes sense to save new source code to that first and then compile which should be a far more efficient way of doing things. I've got some 8M byte SPI chips as well as the 1M byte ones ready for P2 and many of my systems include serial Flash as well as SD memory. To add SPI Flash to existing systems only requires 2 I/O as I frequently safely double-duty the I2C bus lines for SCK and MOSI. Then there's the P2 version which is not so restricted.....
So Rick what's your current status? Are you still having serial problems? Seeing that you still had problems even with 1ms character delay seemed totally improbably that it had anything to do with the Prop or Tachyon. I will see if I can write a couple of lines of code to help debug this.
Truthfully, I have been enjoying the new version that's working quite nicely, also working through the Tachyon and EXTEND.fth modules so I can get a good grasp on what the functionality of the core system without introducing additional elements to complicate my learning.
I will get into extending the core code base in the next day or two, as obviously that's
requisite to moving to custom extensions to make it useful to do real work.
I will keep you apprised. Now that I have the right (current) tterm, that should help a lot.
As some of you know the boards I primarily use for TF have 2 Atmel Megabit EEPROMs. This gives 256 KBytes of program storage..
I look at this as 8 32K Prop image slots. Slot 0 is the main boot position, slot 1 is reserve for Peter's currently troublesome RESTORE command, leaving 6 slots for more storage if you wish.
Below are three words I wrote for handling large EEPROM I think some of you may find them useful even in a single 64K
As some of you know the boards I primarily use for TF have 2 Atmel Megabit EEPROMs. This gives 256 KBytes of program storage..
I look at this as 8 32K Prop image slots. Slot 0 is the main boot position, slot 1 is reserve for Peter's currently troublesome RESTORE command, leaving 6 slots for more storage if you wish.
Below are three words I wrote for handling large EEPROM I think some of you may find them useful even in a single 64K
So Rick what's your current status? Are you still having serial problems?
With Tera Term 4.78 and your settings, I am able to right-mouse click and upload code successfully. This terminal program is the first and only one that shows me the "spinner" while it is in progress. Joy at last.
Please review, I'm just a little confused by the first BIT transfer, seems it's always present.
\
\ ADC0381
\ Routines based on SPIN Example
\
\
#P20 |< CONSTANT CS '' chip select
#P21 |< CONSTANT CLK '' clock
#P22 |< CONSTANT DOUT '' chip data out
: ADC@
DOUT INPUTS '' set pin as input
CLK OUTCLR '' set pin ouput and clr
CS OUTSET '' set to output and set high /CS active low
#100 ms
CS OUTCLR '' set to low /CS active low
#25 us '' conversion time
CLK OUTSET '' Initial clock ?
#10 us
CLK OUTCLR
#10 us
DOUT 0 '' setup input mask and data for SHRINP
#8 FOR '' get data bits
SHRINP '' read and shift in next data bit
CLK OUTSET '' clock it, scope says 19Kz (10 - 40Kz)
#10 us
CLK OUTCLR
#10 us
NEXT
CS OUTCLR '' deselect
NIP '' discard input mask
#24 SHR '' right justify data
. '' show the output
;
Please review, I'm just a little confused by the first BIT transfer, seems it's always present.
\
\ ADC0381
\ Routines based on SPIN Example
\
\
#P20 |< CONSTANT CS '' chip select
#P21 |< CONSTANT CLK '' clock
#P22 |< CONSTANT DOUT '' chip data out
: ADC@
DOUT INPUTS '' set pin as input
CLK OUTCLR '' set pin ouput and clr
CS OUTSET '' set to output and set high /CS active low
#100 ms
CS OUTCLR '' set to low /CS active low
#25 us '' conversion time
CLK OUTSET '' Initial clock ?
#10 us
CLK OUTCLR
#10 us
DOUT 0 '' setup input mask and data for SHRINP
#8 FOR '' get data bits
SHRINP '' read and shift in next data bit
CLK OUTSET '' clock it, scope says 19Kz (10 - 40Kz)
#10 us
CLK OUTCLR
#10 us
NEXT
CS OUTCLR '' deselect
NIP '' discard input mask
#24 SHR '' right justify data
. '' show the output
;
This is a very very old chip and I guess you meant the ADC0831. The datsheet says "easy interface to the COPS family of processors" which is definitely 70's vintage!
I would have just used the [SPIOD] word which accepts a delay word, that way you just call it and then adjust the output.
However, looking at the chip itself the clock is required for the successive approximation and the ADC can't do a conversion without it, that's why the first bit
is to clock it so it can work out if the voltage is higher or lower than it's first "guess" (half). On the next clock it will refine the guess and of course output
the bit from the previous guess. After the last data bit is clocked out you don't need to clock it anymore and those extra cycles are just there to show you it doesn't
matter if you do or don't.
Putting aside the more efficient SPIOD method and looking at your code then this is what I would change.
\
\ ADC0381
\ Routines based on SPIN Example
\
\
#P20 |< CONSTANT CS '' chip select
#P21 |< CONSTANT CLK '' clock
#P22 |< CONSTANT DOUT '' chip data out
: ADC@ ( -- data )
'' just a little initialization although it is only needed first time
CS OUTSET '' set to output and set high /CS active low
CLK OUTCLR '' set pin ouput and clr
DOUT INPUTS '' set pin as input
CS OUTCLR '' set to low /CS active low - 250ns min before clock so don't wait
DOUT 0 '' setup input mask and data for SHRINP
9 FOR '' get data bits + start bit Note: On the initial SAR clock - first guess - data (MSB) won't be availble yet
CLK OUTSET '' Clock it
NOP NOP '' dpn't go too fast - the chip has a 400kHz max clock
CLK OUTCLR '' The output now comes out of tristate if it's the first clock otherwise next data is available
SHRINP '' ( iomask data ) read and shift in next data bit ( iomask data+ )
NEXT
CS OUTSET '' deselect (was using an OUTCLR)
NIP '' discard input mask
#24 SHR '' right justify data but it's still MSB first because of the SAR method
#24 REV '' flip it the right way around
;
This is a very very old chip and I guess you meant the ADC0831. The datsheet says "easy interface to the COPS family of processors" which is definitely 70's vintage!
.
.
.
.
Thanks for the clarification and the nice pattern.
I've noticd the DS1302.fth file posted on the Tachyon dropbox is not functional.
Seems the bits masks for read and write were opposite for the r / w bit 0.
Also without the chip enable CE line being asserted I could not get any action from the chip.
One more thing is that the halt bit (bit 7 in the wrtsecreg) needs to be cleared as does the write disable bit in the wrtctrlreg since both are undefined at startup per the datasheet.
Below is a modified version of the file with an INIT word and my attempt to get the seconds to output from BCD per the datasheet.
Also the GET_SECONDS routine is now SHR and REV to put the bits in the right order.
The routine needs someone with more FORTH / TACHYON experience to "fix" logic errors. I will finish out the file once I see the pattern to resolve the seconds correctly.
EDIT [ going over the datasheet again I've figured out the #24 REV was un-necessary. The below code now gets seconds out correctly after unpacking with the BCD word! ] Use the INIT word to get the chip running. TACHYON is really causing me to work hard but it is worth the effort, thanks peter et al for all the help I've received.
\
\ DS1302 on PPDB
\ Routines based on SPIN Example
\
\
\ DS1302 Command codes
%10000001 CONSTANT rdsecreg
%10000000 CONSTANT wrtsecreg
%10000011 CONSTANT rdminreg
%10000010 CONSTANT wrtminreg
%10000101 CONSTANT rdhrsreg
%10000100 CONSTANT wrthrsreg
%10000111 CONSTANT rddatereg
%10000110 CONSTANT wrtdatereg
%10001001 CONSTANT rdmonreg
%10001000 CONSTANT wrtmonreg
%10001101 CONSTANT rdyrreg
%10001100 CONSTANT wrtyrreg
%10001111 CONSTANT rdctrlreg
%10001110 CONSTANT wrtctrlreg
%10010001 CONSTANT rdtrklreg
%10010000 CONSTANT wrttrklreg
%10111111 CONSTANT rdbrstreg
%10111110 CONSTANT wrtbrstreg
#P23 |< CONSTANT CE
#P24 |< CONSTANT I/O
#P25 |< CONSTANT CLK
DECIMAL
: DS1302! ( data -- )
I/O OUTPUTS \ set I/O PIN to OUTPUT (redundant)
I/O SWAP \ set up the I/O pin on DS1302 (pinmask data -- )
CLK OUTCLR \ force CLK lo
8 FOR SHROUT
CLK OUTSET
NOP
CLK OUTCLR
NEXT
2DROP \ drop the iomask and data, clean stack
;
: DS1302@ ( -- data )
I/O DUP INPUTS \ set I/O PIN to INPUT
0 ( mask data -- )
8 FOR SHRINP
CLK OUTSET
NOP
CLK OUTCLR
NEXT
NIP
;
: SET_SECONDS ( packed -- )
CE OUTSET
wrtsecreg DS1302!
DS1302!
CE OUTCLR
;
: GET_SECONDS ( -- packed )
CE OUTSET
rdsecreg DS1302!
DS1302@
CE OUTCLR
#24 SHR \ right justify
\ #24 REV \ not necessary
;
: INIT
CLK OUTCLR
CE OUTCLR
#100 ms
\ Clear write-protect bit, undefined at start up
CE OUTSET
wrtctrlreg DS1302!
0 DS1302!
CE OUTCLR
\ Clear halt bit, undefined on startup
CE OUTSET
wrtsecreg DS1302!
0 DS1302!
CE OUTCLR
\ Clear trickle charger settings
CE OUTSET
wrttrklreg DS1302!
0 DS1302!
CE OUTCLR
;
: B2D DUP %01110000 AND 4 SHR #10 * SWAP %00001111 AND + ;
Peter,
Can you give us a rough road map and time table of 2.1 and 3 ??? Does 3 exist yet? and will 2.1 be further developed? Or will 2.1 languish while 3 is made useful?
When coding what word or words will display to me how much room I have left? what numbers are we looking for and what do they mean?
Peter,
Can you give us a rough road map and time table of 2.1 and 3 ??? Does 3 exist yet? and will 2.1 be further developed? Or will 2.1 languish while 3 is made useful?
When coding what word or words will display to me how much room I have left? what numbers are we looking for and what do they mean?
TNX ... bbr
Hi Brian,
This is a compatible upgrade which will make V3 work just like V2 for non-enhanced systems so there is no reason to stick with V2 and all V2 apps should be compatible with V3 if they are operated in a non-enhanced system. Got that? Basically you will see no difference normally and although V2 will not continue to be maintained there is no reason not to use V3 which be compatible with V2 apps as they are now.
Since V2.1 is stable I'd rather not enhance that too much in case we run into stability problems. Once V3 has proven to be stable and the kinks knocked out of it then you can switch over to it as the default kernel. Any compatible improvements made to V3 in the meantime can be applied to a V2.2 leaving V2.1 intact. V2,2 and V3 will be accessed only as Google docs mostly with the Dropbox folder updated occasionally.
The whole idea of moving to V3 is to allow for more efficient memory usage for systems that have serial Flash or SD memory while still working with basic systems. Tachyon aims at providing a fast and compact Forth in a minimal system rather than supporting far more esoteric systems that have multiple Props or external O/S capable processors. The minimal system with maybe SD memory is fairly typical of how many actual embedded (not on the fun bench) "products" are implemented by Prop users.
If you want a detailed byte by byte but compact look at memory you could do a wide ASCII dump using this definition:
[FONT=courier new]: ADUMP ( src cnt -- )
ADO CR I .WORD ." : " I #128 ADO I C@ DUP BL $7E WITHIN 0= IF DROP "." THEN EMIT LOOP #128 +LOOP
;
[/FONT]
I've been down with a virus for the past week and my head feels like a gyro, I move it one way but it continues where it was but I will see what I can do with fixing up the reporting words. BTW, typing END won't hurt anything but does report the memory used (albeit incorrectly).
1 - does 3 actually exist yet, or is it still being sketched out ????
2 - quick rundown on CASE after the various alterations
3 - a short demo sketch for making use of the timers to control event lasting many minutes and even hours
tnx ... bbr
Only three short questions but here’s my lengthy reply.........
The V3 document was created at the start of the month and some of the optimizations were directly applied to V2.1. At present the main aim is to decouple the dictionary from the runtime cog and hand over these functions to the APC instead. So the APC has to handle the serial Flash or SD at some basic level enough to store the dictionary and search it efficiently. So it's not in a state at present for testing applications, only for testing the dictionary functions.
CASE The use of the CASE statement has been simplified and basically works by saving the target value in a variable and implementing a transparent "fetch target, compare with compare value on stack, compile an IF .... EXIT THEN structure to handle the vector.
[COLOR=#000000][FONT=Courier New]pub TC ( ch -- )[/FONT][/COLOR]
[COLOR=#000000][FONT=Courier New] CASE[/FONT][/COLOR]
[COLOR=#000000][FONT=Courier New] "4" =[ ." Knock on the door, it's a 4" ]=[/FONT][/COLOR]
[COLOR=#000000][FONT=Courier New] "5" =[ ." Let's jive, it's a 5" ]=[/FONT][/COLOR]
[COLOR=#000000][FONT=Courier New] "2" CASE@ = "6" CASE@ = OR IF ." six or two, don’t mind a brew" ]=[/FONT][/COLOR]
[COLOR=#000000][FONT=Courier New] "7" "9" ..[ ." Pick up sticks, it's more than six" ]=[/FONT][/COLOR]
[COLOR=#000000][FONT=Courier New] “@” CASE@ < IF .” Alpha test “ ]=[/FONT][/COLOR]
[COLOR=#000000][FONT=Courier New];[/FONT][/COLOR]
In the above example the word CASE simply saves the target as a variable “case”. Next the =[ is an attempt at simplifying the comparison operation that resolves as “case C@ = IF”. Next comes the user code and then the closing bracket ]= which performs an EXIT and a THEN operation. To handle OR operations as well as general comparisons I’ve now added the CASE= to compare the parameter with “case” and leave a flag on the stack. This flag can be used directly by an IF in place of the =[ word. For testing above or below it becomes just as easy to fetch the case variable to compare against so I have added CASE@ for that purpose. So perhaps =[ could be called CASEOF (traditional) and ]= becomes ENDCASE.
[COLOR=#000000][FONT=Courier New]pub TC ( ch -- )[/FONT][/COLOR]
[COLOR=#000000][FONT=Courier New] CASE[/FONT][/COLOR]
[COLOR=#000000][FONT=Courier New] "4" CASEOF ." Knock on the door, it's a 4" ENDCASE[/FONT][/COLOR]
[COLOR=#000000][FONT=Courier New] "5" CASEOF ." Let's jive, it's a 5" ENDCASE[/FONT][/COLOR]
[COLOR=#000000][FONT=Courier New] "2" CASE@ = “6” CASE@ = OR IF .” six or two, don’t mind a brew” ENDCASE[/FONT][/COLOR]
[COLOR=#000000][FONT=Courier New] "7" "9" CASEIN ." Pick up sticks, it's more than six" ENDCASE[/FONT][/COLOR]
[COLOR=#000000][FONT=Courier New] "@" CASE@ < IF .” Alpha test “ ENDCASE[/FONT][/COLOR]
[COLOR=#000000][FONT=Courier New];[/FONT][/COLOR]
The ENDCASE executes an EXIT so it will not return back to the statements to be processed any further. Anything that hasn’t been filtered out by the CASE statements can be added in normally after the statements and if you need the target value again just use CASE@ to place it on the stack.
TIMERS Since there is already a background cog which maintains timers this makes it easier to keep track of realtime events. I mostly use these as timeouts which have a timer loaded say for 500ms so that if my application checks the timer all it wants to know is if it has timed out like this:
The code that loads or retriggers the timer #500 #mytimer TIMEOUT In this case #mytimer is simply a constant from 0 to 7 that indexes a timer. Stack operands ( time index -- ) are time in milliseconds and timer index 0..7.
Then the code that checks the timer #mytimer TIMEOUT? IF <timeout code> THEN
It is also possible to have the timer function execute code automatically upon a timeout like this:
Load the run address of MYALARM into #mytimer ‘ MYALARM #mytimer ALARM To disable the alarm simply specify zero as the run address 0 #mytimer ALARM
then the timer would be loaded #500 #mytimer TIMEOUT
After 500ms the timer would expire and MYALARM will be executed. For the action to be repeatable it is necessary for MYALARM to reload the timer itself as this is the most flexible approach. Bear in mind the MYALARM should not do too much processing as it will affect timing operations and also MYALARM is running in a separate cog from the application so output pins should not normally be shared.
Since the timers use longs and the countdown clock is 1ms it would take over 49 days before the maximum value would expire which I think is more than long enough for most events.
To set a timer for 5 hours you could do it this way: #18,000,000 #mytimer TIMEOUT But you might let Forth calculate the value for you: #60,000 #60 * 5 * #mytimer TIMEOUT So that 60,000 represented 60 seconds or a minute then multiply this by 60 to get hours then finally by 5. Notice too that the 5 like values 0..9 will never need to be forced to a number base as they will always resolve correctly if you are in hex or decimal. Besides these get compiled as fast constants if used this way.
Alternatively you could have some constants predefined so you could do it this way: #hour 5 * #mytimer TIMEOUT This is a little cleaner but still does not optimize the constant for runtime operation although it really doesn’t matter. V3 might allow compile time optimization so that constants such as we have seen would be evaluated and reduced to the minimum, in this case a single long. Mind you that that is not the way Forth does things but a little preprocessing couldn’t hurt and it might even be controlled by preprocessor operators. [ #hour 5 * ] #mytimer TIMEOUT In true Forth fashion however you could define a word called “hours” that is set as an immediate word and would evaluate the 5, calculate the constant and compile it. 5 hours #mytimer TIMEOUT
Hope that answers your questions and that you can understand it too!
Since talking about CASE statements I have had a rethink and looked at some of my apps to see what works best, is flexible, and is not too arcane. Surprisingly I decided to skip the normal Forth convention and adopt the C convention simply because it refers to a SWITCH, that is the actual target value, and it uses CASE and BREAK for normal operations which seem perfectly sensible to me. BREAK has been seen as a weakness in C because otherwise it falls through to the next line but I prefer the flexibility and these three words are very familiar to many programmers. Of course they are handled in Forth fashion and since Forth compiles exactly what you enter I have added a couple of extra words to allow for ranges and multiple values to be tested. Demo code is included. Feedback is appreciated.
{ TACHYON CASE STRUCTURES This implementation follows the C method to some degree. Each CASE statement simply compares the supplied value with the SWITCH and executes an IF To prevent the IF statement from falling through a BREAK is used (also acts as a THEN at CT) The SWITCH can be tested directly and a manual CASE can be constructed with IF <code> BREAK
SWITCH ( switch -- ) \ Save switch value used in CASE structure CASE ( val -- ) \ compare val with switch and perform an IF. Equivalent to SWITCH= IF BREAK \ EXIT (return) but also completes IF structure at CT. Equivalent to EXIT THEN
\ extra functions to allow the switch to be manipulated etc SWITCH@ ( -- switch ) \ Fetch last saved switch value SWITCH= ( val -- flg ) \ Compare val with switch. Equivalent to SWITCH@ = SWITCH>< ( from to -- flg ) \ Compare switch within range. Equivalent to SWITCH@ROT ROTWITHIN
Usage:
[FONT=courier new][COLOR=#000000]pub [B]CASEDEMO[/B] [/COLOR]( val -- )[/FONT]
[FONT=courier new][COLOR=#000000]SWITCH \ use the key value as a switch in the case statement[/COLOR][/FONT]
[FONT=courier new][COLOR=#000000]"A" CASE CR ." A is for APPLE " BREAK[/COLOR][/FONT]
[FONT=courier new][COLOR=#000000]"H" CASE CR ." H is for HAPPY " BREAK[/COLOR][/FONT]
[FONT=courier new][COLOR=#000000]"Z" CASE CR ." Z is for ZEBRA " BREAK[/COLOR][/FONT]
[FONT=courier new][COLOR=#000000]$08 CASE 4 REG ~ BREAK[/COLOR][/FONT]
[FONT=courier new][COLOR=#020FC0]\ Now accept 0 to 9 and build a number calculator style[/COLOR][/FONT]
[FONT=courier new][COLOR=#000000]"0" "9" SWITCH>< IF SWITCH@ $30 - 4 REG @ #10 * + 4 REG ! ." *" BREAK[/COLOR][/FONT]
[FONT=courier new][COLOR=#020FC0]\ On enter just display the accumulated number[/COLOR][/FONT]
[FONT=courier new][COLOR=#000000]$0D CASE CR ." and our lucky number is " 4 REG @ .DEC BREAK[/COLOR][/FONT]
[FONT=courier new][COLOR=#020FC0]\ show how we can test more than one value[/COLOR][/FONT]
[FONT=courier new][COLOR=#000000]"Q" SWITCH= "X" SWITCH= OR IF CR ." So you're a quitter hey?" CR CONSOLE BREAK[/COLOR][/FONT]
[FONT=courier new][COLOR=#000000]CR ." I don't know what " SWITCH@ EMIT ." is"[/COLOR][/FONT]
[FONT=courier new][COLOR=#000000]; [/COLOR][/FONT]
[FONT=courier new][COLOR=#000000]pub [B]DEMO[/B][/COLOR][/FONT]
[FONT=courier new][COLOR=#000000]BEGIN KEY UPPER CASEDEMO AGAIN[/COLOR][/FONT]
[FONT=courier new][COLOR=#000000];[/COLOR][/FONT]
[FONT=courier new]Running DEMO and here's a screen dump:
DEMO
A is for APPLE
I don't know what B is
I don't know what C is
H is for HAPPY
Z is for ZEBRA ****
and our lucky number is 8032***
and our lucky number is 8032001
So you're a quitter hey?
----------------------------------------------------------------
[/FONT]
The compiled code for this demo is revealed here:
[FONT=courier new]SEEALL CASEDEMO ...:
2A11: SWITCH
2A13: $41
2A15: SWITCH=
2A17: IF
2A19: CR
2A1B: ." A is for APPLE "
2A2D: EXIT
2A2E: THEN
2A2E: $48
2A30: SWITCH=
2A32: IF
2A34: CR
2A36: ." H is for HAPPY "
2A48: EXIT
2A49: THEN
2A49: $5A
2A4B: SWITCH=
2A4D: IF
2A4F: CR
2A51: ." Z is for ZEBRA "
2A63: EXIT
2A64: THEN
2A64: $08
2A66: SWITCH=
2A68: IF
2A6A: 4
2A6B: REG
2A6C: ~
2A6E: EXIT
2A6F: THEN
2A6F: $30
2A71: $39
2A73: SWITCH><
2A75: IF
2A77: SWITCH@
2A79: $30
2A7B: -
2A7C: 4
2A7D: REG
2A7E: @
2A7F: $0A
2A81: UM*
2A82: DROP
2A83: +
2A84: 4
2A85: REG
2A86: !
2A87: ." *"
2A8B: EXIT
2A8C: THEN
2A8C: $0D
2A8E: SWITCH=
2A90: IF
2A92: CR
2A94: ." and our lucky number is "
2AAF: 4
2AB0: REG
2AB1: @
2AB2: .DEC
2AB4: EXIT
2AB5: THEN
2AB5: $51
2AB7: SWITCH=
2AB9: $58
2ABB: SWITCH=
2ABD: OR
2ABE: IF
2AC0: CR
2AC2: ." So you're a quitter hey?"
2ADD: CR
2ADF: CONSOLE
2AE1: EXIT
2AE2: THEN
2AE2: CR
2AE4: ." I don't know what "
2AF9: SWITCH@
2AFB: EMIT
2AFD: ." is"
2B03: EXIT
=0242 bytes ok
[/FONT]
Hi,
I am still looking forward to exploring Tackyon Forth on the Propeller2. After all, what better use for a sizzling fast Forth than the best of Propellers.
In the meantime, I am still a lowly student of Forth and am finding my learning requires ANS Forth background material.
Since talking about CASE statements I have had a rethink and looked at some of my apps to see what works best, is flexible ,... Demo code is included. Feedback is appreciated.
{ TACHYON CASE STRUCTURES ...
Hi Peter,
I've had very little time for TC lately. My Son is racing Velodrome this weekend, so I'll be time constrained in the next few days too.
r.e. CASE:
I've uploaded the latest binary(with ext.):
Propeller .:.:--TACHYON--:.:. Forth V21130611.0000 with Primary extensions to TACHYON kernel - 130607.1600
In a WORD listing, sorted in Excel I show these two entries for:
NFA PFA EXT ATRS NAME
7271
1A63
...:
CASE
6E92
1208
XAC
...:
CASE
Why two? In any case, I tried to run the "CASE" test/demo code in your post, but it chokes on the "SWITCH" word; not too shocking as it's not been defined anywhere that I can find.
Am I missing something obvious?
Looking forward to your continued efforts as usual.
I've had very little time for TC lately. My Son is racing Velodrome this weekend, so I'll be time constrained in the next few days too.
r.e. CASE:
I've uploaded the latest binary(with ext.):
Propeller .:.:--TACHYON--:.:. Forth V21130611.0000 with Primary extensions to TACHYON kernel - 130607.1600
In a WORD listing, sorted in Excel I show these two entries for:
NFA PFA EXT ATRS NAME
7271
1A63
...:
CASE
6E92
1208
XAC
...:
CASE
Why two? In any case, I tried to run the "CASE" test/demo code in your post, but it chokes on the "SWITCH" word; not too shocking as it's not been defined anywhere that I can find.
Am I missing something obvious?
Looking forward to your continued efforts as usual.
Rick In Sunny Hot Texas USA
Sorry, I haven't updated the Dropbox version but just remember that all the bleeding edge stuff can be had direct from the Goggle document. Any changes I make to it are immediately reflected in any copies of the document that may have been opened by anyone. Sometimes this is a disadvantage as I am in the middle of some changes but nonetheless everyone has access to what I'm working on at that very moment. So I will just update the Dropbox file now although I am trying just to stick to V3 and carry through small improvements to V2.2 (to be published).
Sorry, I haven't updated the Dropbox version but just remember that all the bleeding edge stuff can be had direct from the Goggle document. Any changes I make to it are immediately reflected in any copies of the document that may have been opened by anyone. Sometimes this is a disadvantage as I am in the middle of some changes but nonetheless everyone has access to what I'm working on at that very moment. So I will just update the Dropbox file now although I am trying just to stick to V3 and carry through small improvements to V2.2 (to be published).
Comments
With the latest kernel I'm having problems with minicom and the Prop Professional Dev Board, the BOE and QuickStart boards work just dandy. Earlier version of the FTDI chip?
The symptom is no I in I/O, the banner appears but no Input to the device is possible. Not even das blinken lits on the FTDI chip during keystrokes?
The PPDB works okay in TeraTerm and ZTerm but both of these can't compare to compile speeds (uploads) I get with Minicomm. Only using 230400 8N1
One other thing is that the PPDB will only boot the kernel if the usb is plugged in to a computer. And yes I do have pwr to the PPDB via a 7.5V supply. I must be missing something here, again. doh
mac osx 10.8.2
I was reading this thread
http://forums.parallax.com/showthread.php/148448-Sine-lookup-table-question
and realized I had never seen an TF words for accessing the Prop's sine table.
So I dug into my PDF of the Hydra book (it is a great resource!) and found it on page 212.
I cobbled this together:
"Sin" is the fetch word. "SIN" takes the actual sine off the stack and prints it out as a decimal.
One shortcoming of the sine table is that 2049 entries divided by 90 degrees when done by integer math dropping the remainder gets you 22 entries per degree, whereas floating point gets you 22.76666... a not inconsiderable error.
If anyone can tighten this up ... please do!
... enjoy ... BBR
Thanks for bringing this up Brian, to tell the truth I've never looked into it. There are a few errors in your code but this is what I have found will work though it's not the final version. The Spin version looked weird so I found a PASM version which I used as the basis.
I was also thinking that I would put a "0." in front of the result but of course it is only a demo anyway. I did have a chance to look at some threads discussing the use of the sine table and see that Phil has refined the method a little so I may look at coding that too. The 16 SHR is not the same as a 65535 / but close enough for now. Perhaps while I am into this I may even write a maths library although I favor scaled integer operations normally. Are there any opinions on the most suitable method and representation and the precision required? Do I go all the way or is there a minimal requirement? It may be that I might create a floating point stack in hub ram so I am not limited by memory with what can be achieved.
I pulled the chip, replaced it. rebuilt my kernel and extensions, tested your sine stuff ... since it was all back to working, I took the bad Prop, bent up its legs and threw it into File 13
cheers ... BBR
[
Here is a quick look at the output by graphing it onto the terminal.
The one repeatable symptom of was the dictionary no longer knowing "MY" I narrowed it down to the BACKUP/RESTORE. I checked after each BACKUP and "MY QWORDS" worked.. But as soon as I did a RESTORE all I got was "MY ??? QWORDS" and my secondary marker the 'fast constant' 16 was no longer evaluated as 16d but as $16. I rebuilt my kernel (130605) and EXTEND (130607) three times and three more times it did the same thing upon invoking the RESTORE word.
Now what???
So use REBOOT for now? (Please excuse if this sounds like a noob question: it is!)
Also, can BACKUP be used without issue? Edit: I see it is an issue.
RickInTexas
So Rick what's your current status? Are you still having serial problems? Seeing that you still had problems even with 1ms character delay seemed totally improbably that it had anything to do with the Prop or Tachyon. I will see if I can write a couple of lines of code to help debug this.
V3 will allow more memory to be free because it will maintain most of the names in EEPROM/Flash but when it comes to creating a "build" during which time the system is not normally running an app it will use another cog to cache from EEPROM/Flash and search the dictionary etc. This way the runtime Tachyon cog(s) can have a few more goodies loaded as there are 24 longs taken just by the CMPSTR instruction and it's really only needed for fast loads. V3 will also introduce some other enhancements including compile-time-only headers and code (discarded at the end of a build). Seeing that serial Flash is so cheap and small it makes sense to allow source modules to be loaded from serial Flash or SD so that a build would only need user code loaded through the console and it could just ask to "include L6470.fth" for instance. If Flash or SD exists it makes sense to save new source code to that first and then compile which should be a far more efficient way of doing things. I've got some 8M byte SPI chips as well as the 1M byte ones ready for P2 and many of my systems include serial Flash as well as SD memory. To add SPI Flash to existing systems only requires 2 I/O as I frequently safely double-duty the I2C bus lines for SCK and MOSI. Then there's the P2 version which is not so restricted.....
Great. That helps a lot.
Truthfully, I have been enjoying the new version that's working quite nicely, also working through the Tachyon and EXTEND.fth modules so I can get a good grasp on what the functionality of the core system without introducing additional elements to complicate my learning.
I will get into extending the core code base in the next day or two, as obviously that's
requisite to moving to custom extensions to make it useful to do real work.
I will keep you apprised. Now that I have the right (current) tterm, that should help a lot.
RickInTexas
I look at this as 8 32K Prop image slots. Slot 0 is the main boot position, slot 1 is reserve for Peter's currently troublesome RESTORE command, leaving 6 slots for more storage if you wish.
Below are three words I wrote for handling large EEPROM I think some of you may find them useful even in a single 64K
I was going to make a Mouser order this week and that big eeprom is EOL and stock is 0.
Can you suggest a suitable replacement? SOIC is ok.
Better yet, what do I need in terms of memory organization?
I like the idea of having 32k banks for image management.
RickInTexas
With Tera Term 4.78 and your settings, I am able to right-mouse click and upload code successfully. This terminal program is the first and only one that shows me the "spinner" while it is in progress. Joy at last.
Thanks Peter!
RickInTexas
Please review, I'm just a little confused by the first BIT transfer, seems it's always present.
This is a very very old chip and I guess you meant the ADC0831. The datsheet says "easy interface to the COPS family of processors" which is definitely 70's vintage!
I would have just used the [SPIOD] word which accepts a delay word, that way you just call it and then adjust the output.
However, looking at the chip itself the clock is required for the successive approximation and the ADC can't do a conversion without it, that's why the first bit
is to clock it so it can work out if the voltage is higher or lower than it's first "guess" (half). On the next clock it will refine the guess and of course output
the bit from the previous guess. After the last data bit is clocked out you don't need to clock it anymore and those extra cycles are just there to show you it doesn't
matter if you do or don't.
Putting aside the more efficient SPIOD method and looking at your code then this is what I would change.
Thanks for the clarification and the nice pattern.
ADC0381.tiff
Seems the bits masks for read and write were opposite for the r / w bit 0.
Also without the chip enable CE line being asserted I could not get any action from the chip.
One more thing is that the halt bit (bit 7 in the wrtsecreg) needs to be cleared as does the write disable bit in the wrtctrlreg since both are undefined at startup per the datasheet.
Below is a modified version of the file with an INIT word and my attempt to get the seconds to output from BCD per the datasheet.
Also the GET_SECONDS routine is now SHR and REV to put the bits in the right order.
The routine needs someone with more FORTH / TACHYON experience to "fix" logic errors. I will finish out the file once I see the pattern to resolve the seconds correctly.
EDIT [ going over the datasheet again I've figured out the #24 REV was un-necessary. The below code now gets seconds out correctly after unpacking with the BCD word! ] Use the INIT word to get the chip running. TACHYON is really causing me to work hard but it is worth the effort, thanks peter et al for all the help I've received.
Can you give us a rough road map and time table of 2.1 and 3 ??? Does 3 exist yet? and will 2.1 be further developed? Or will 2.1 languish while 3 is made useful?
When coding what word or words will display to me how much room I have left? what numbers are we looking for and what do they mean?
TNX ... bbr
This is a compatible upgrade which will make V3 work just like V2 for non-enhanced systems so there is no reason to stick with V2 and all V2 apps should be compatible with V3 if they are operated in a non-enhanced system. Got that? Basically you will see no difference normally and although V2 will not continue to be maintained there is no reason not to use V3 which be compatible with V2 apps as they are now.
Since V2.1 is stable I'd rather not enhance that too much in case we run into stability problems. Once V3 has proven to be stable and the kinks knocked out of it then you can switch over to it as the default kernel. Any compatible improvements made to V3 in the meantime can be applied to a V2.2 leaving V2.1 intact. V2,2 and V3 will be accessed only as Google docs mostly with the Dropbox folder updated occasionally.
The whole idea of moving to V3 is to allow for more efficient memory usage for systems that have serial Flash or SD memory while still working with basic systems. Tachyon aims at providing a fast and compact Forth in a minimal system rather than supporting far more esoteric systems that have multiple Props or external O/S capable processors. The minimal system with maybe SD memory is fairly typical of how many actual embedded (not on the fun bench) "products" are implemented by Prop users.
As for finding out how much memory is left is a little bit harder and the current reporting words need some updating. Mostly I just type in RMAP just to see what's happening with memory:
RMAP
0000: 25 05 05 2D 0E 28 54 46 59 4B 3B 3C 47 6D 3E 4A
0400: 4B 58 10 .. .. .. .. .. .. .. .. .. .. .. .. ..
0800: .. .. .. .. .. 1B 59 65 5D 50 48 52 45 83 82 81
0C00: 89 7B 76 77 69 63 56 6D 3C 53 62 59 6A 5F 54 57
1000: 57 64 65 62 65 69 7C 60 6E 43 6A 7D 7E 74 64 7D
1400: 7A 4C 57 65 60 4A 5F 57 70 67 71 7A 62 7B 7C 6A
1800: 31 .. 4D 60 5A 4E 3A 17 56 36 54 59 65 59 51 47
1C00: 37 55 66 5D 52 45 64 5E 55 5E 63 6F 6D 62 7B 70
2000: 6E 46 66 5A 51 5D 4A 5E 64 3F 7C 6D 4F 77 69 6B
2400: 77 7C 6B 79 71 6F 71 10 71 69 6A 6C 84 75 5D 5B
2800: 63 67 5C 6B 6B 5F 15 3B .. .. .. .. .. .. .. ..
2C00: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
3000: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
3400: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
3800: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
3C00: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
4000: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
4400: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
4800: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
4C00: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
5000: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
5400: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
5800: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
5C00: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
6000: .. .. .. .. .. .. .. .. 36 64 60 5E 71 5D 64 5B
6400: 59 61 6C 5A 6D 5F 5F 5A 5C 57 57 5C 60 55 5C 50
6800: 53 4F 4F 4E 53 51 52 3A 41 40 44 3A 36 3F 46 4B
6C00: 3C 46 50 49 46 42 63 60 57 66 60 53 53 58 55 48
7000: 50 50 54 4F 54 54 58 58 5A 70 74 6F 5E 5C 59 5D
7400: 5E 08 .. .. 75 70 62 56 6B 58 6A 62 6E 6D 65 6E
7800: 63 86 71 7C 69 54 6E 70 7D 9E 9F 8F 6D 23 05 ..
7C00: .. .. 1C 58 4C 6C 68 6C 74 86 54 5F 8C 09 .. .. ok
If you want a detailed byte by byte but compact look at memory you could do a wide ASCII dump using this definition:
I've been down with a virus for the past week and my head feels like a gyro, I move it one way but it continues where it was but I will see what I can do with fixing up the reporting words. BTW, typing END won't hurt anything but does report the memory used (albeit incorrectly).
1 - does 3 actually exist yet, or is it still being sketched out ????
2 - quick rundown on CASE after the various alterations
3 - a short demo sketch for making use of the timers to control event lasting many minutes and even hours
tnx ... bbr
Only three short questions but here’s my lengthy reply.........
The V3 document was created at the start of the month and some of the optimizations were directly applied to V2.1. At present the main aim is to decouple the dictionary from the runtime cog and hand over these functions to the APC instead. So the APC has to handle the serial Flash or SD at some basic level enough to store the dictionary and search it efficiently. So it's not in a state at present for testing applications, only for testing the dictionary functions.
CASE
The use of the CASE statement has been simplified and basically works by saving the target value in a variable and implementing a transparent "fetch target, compare with compare value on stack, compile an IF .... EXIT THEN structure to handle the vector. In the above example the word CASE simply saves the target as a variable “case”. Next the =[ is an attempt at simplifying the comparison operation that resolves as “case C@ = IF”. Next comes the user code and then the closing bracket ]= which performs an EXIT and a THEN operation.
To handle OR operations as well as general comparisons I’ve now added the CASE= to compare the parameter with “case” and leave a flag on the stack. This flag can be used directly by an IF in place of the =[ word. For testing above or below it becomes just as easy to fetch the case variable to compare against so I have added CASE@ for that purpose. So perhaps =[ could be called CASEOF (traditional) and ]= becomes ENDCASE.
The ENDCASE executes an EXIT so it will not return back to the statements to be processed any further.
Anything that hasn’t been filtered out by the CASE statements can be added in normally after the statements and if you need the target value again just use CASE@ to place it on the stack.
TIMERS
Since there is already a background cog which maintains timers this makes it easier to keep track of realtime events. I mostly use these as timeouts which have a timer loaded say for 500ms so that if my application checks the timer all it wants to know is if it has timed out like this:
The code that loads or retriggers the timer
#500 #mytimer TIMEOUT
In this case #mytimer is simply a constant from 0 to 7 that indexes a timer. Stack operands ( time index -- ) are time in milliseconds and timer index 0..7.
Then the code that checks the timer
#mytimer TIMEOUT? IF <timeout code> THEN
It is also possible to have the timer function execute code automatically upon a timeout like this:
Load the run address of MYALARM into #mytimer
‘ MYALARM #mytimer ALARM
To disable the alarm simply specify zero as the run address
0 #mytimer ALARM
then the timer would be loaded
#500 #mytimer TIMEOUT
After 500ms the timer would expire and MYALARM will be executed. For the action to be repeatable it is necessary for MYALARM to reload the timer itself as this is the most flexible approach. Bear in mind the MYALARM should not do too much processing as it will affect timing operations and also MYALARM is running in a separate cog from the application so output pins should not normally be shared.
Since the timers use longs and the countdown clock is 1ms it would take over 49 days before the maximum value would expire which I think is more than long enough for most events.
To set a timer for 5 hours you could do it this way:
#18,000,000 #mytimer TIMEOUT
But you might let Forth calculate the value for you:
#60,000 #60 * 5 * #mytimer TIMEOUT
So that 60,000 represented 60 seconds or a minute then multiply this by 60 to get hours then finally by 5. Notice too that the 5 like values 0..9 will never need to be forced to a number base as they will always resolve correctly if you are in hex or decimal. Besides these get compiled as fast constants if used this way.
Alternatively you could have some constants predefined so you could do it this way:
#hour 5 * #mytimer TIMEOUT
This is a little cleaner but still does not optimize the constant for runtime operation although it really doesn’t matter. V3 might allow compile time optimization so that constants such as we have seen would be evaluated and reduced to the minimum, in this case a single long. Mind you that that is not the way Forth does things but a little preprocessing couldn’t hurt and it might even be controlled by preprocessor operators.
[ #hour 5 * ] #mytimer TIMEOUT
In true Forth fashion however you could define a word called “hours” that is set as an immediate word and would evaluate the 5, calculate the constant and compile it.
5 hours #mytimer TIMEOUT
Hope that answers your questions and that you can understand it too!
{ TACHYON CASE STRUCTURES
This implementation follows the C method to some degree.
Each CASE statement simply compares the supplied value with the SWITCH and executes an IF
To prevent the IF statement from falling through a BREAK is used (also acts as a THEN at CT)
The SWITCH can be tested directly and a manual CASE can be constructed with IF <code> BREAK
SWITCH ( switch -- ) \ Save switch value used in CASE structure
CASE ( val -- ) \ compare val with switch and perform an IF. Equivalent to SWITCH= IF
BREAK \ EXIT (return) but also completes IF structure at CT. Equivalent to EXIT THEN
\ extra functions to allow the switch to be manipulated etc
SWITCH@ ( -- switch ) \ Fetch last saved switch value
SWITCH= ( val -- flg ) \ Compare val with switch. Equivalent to SWITCH@ =
SWITCH>< ( from to -- flg ) \ Compare switch within range. Equivalent to SWITCH@ ROT ROT WITHIN
Usage:
The compiled code for this demo is revealed here:
I am still looking forward to exploring Tackyon Forth on the Propeller2. After all, what better use for a sizzling fast Forth than the best of Propellers.
In the meantime, I am still a lowly student of Forth and am finding my learning requires ANS Forth background material.
Hi Peter,
I've had very little time for TC lately. My Son is racing Velodrome this weekend, so I'll be time constrained in the next few days too.
r.e. CASE:
I've uploaded the latest binary(with ext.):
Propeller .:.:--TACHYON--:.:. Forth V21130611.0000 with Primary extensions to TACHYON kernel - 130607.1600
In a WORD listing, sorted in Excel I show these two entries for:
NFA PFA EXT ATRS NAME
7271
1A63
...:
CASE
6E92
1208
XAC
...:
CASE
Why two? In any case, I tried to run the "CASE" test/demo code in your post, but it chokes on the "SWITCH" word; not too shocking as it's not been defined anywhere that I can find.
Am I missing something obvious?
Looking forward to your continued efforts as usual.
Rick In Sunny Hot Texas USA
Sorry, I haven't updated the Dropbox version but just remember that all the bleeding edge stuff can be had direct from the Goggle document. Any changes I make to it are immediately reflected in any copies of the document that may have been opened by anyone. Sometimes this is a disadvantage as I am in the middle of some changes but nonetheless everyone has access to what I'm working on at that very moment. So I will just update the Dropbox file now although I am trying just to stick to V3 and carry through small improvements to V2.2 (to be published).
I must be missing something with timers
Running blink should blink the light (it does) and reload the timer to blink the light every #1000 ms ?
I get the first blink and then one blink 1 second later and no more blinks?
Trying to start the timer with #1000 #mt TIMEOUT does nothing subsequently?