Shop OBEX P1 Docs P2 Docs Learn Events
TACHYON O/S V3.0 JUNO - Furiously Fast Forth, FAT32+LAN+VGA+RS485+OBEX ROMS+FP+LMM+++ - Page 42 — Parallax Forums

TACHYON O/S V3.0 JUNO - Furiously Fast Forth, FAT32+LAN+VGA+RS485+OBEX ROMS+FP+LMM+++

13940424445109

Comments

  • artkennedyartkennedy Posts: 174
    edited 2014-02-18 20:51
    I am really liking the way Tachyon parses as soon as you enter a space and reports "NOT FOUND" so that you can then press ESC and not even disturb the stack. *Slick*
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-18 21:43
    D.P wrote: »
    This has been elusive for me for some reason. I'm just now proceding from FORTH/Tachyon syntax to more "how it works" stuff.
    Getting past this hurdle has helped me greatly, I just couldn't glean what I needed from within the source.
    Now I have renewed motivation, thanks for the "thorn removal"

    UPDATE, while this has removed the keyboard issue the LCD is "no op", LCD checked with console testing? I've tried with $20,$30 ALLOT for regs1

    UPDATE2****** NEED TO HAVE A BLANK LINE BETWEEN EACH ALLOT STATEMENT, ARRG I BEEN BITTEN BY THIS BEFORE! BEWARE
    TABLE regs1         $20 ALLOT           \ some room for temp register + uemit and ukey
    TABLE stacktsk     $40 ALLOT
    
    \ shoud be 
    
    TABLE regs1         $20 ALLOT           \ some room for temp register + uemit and ukey
    
    TABLE stacktsk     $40 ALLOT
    

    I can fix the blank line thing, it's just that I keep forgetting about it but if you leave out the end-of-line comment it also works fine too. Just place the comment up above it. It has to do with termination of looking for more names although TABLE itself should never need to do this but it's based on AVARIABLE which does.

    As long as nothing has set the LCD serial data pin high such as during testing then your task should be able to run but I will hook-up one of my serial LCDs and try it out anyway.

    EDIT: you could also release the LCD serial data pin after transmit as the LCD should have a pullup.
    pub LCDEMIT 9 PINSET 9 SEROUT 9 PININP ;
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-18 21:52
    artkennedy wrote: »
    I am really liking the way Tachyon parses as soon as you enter a space and reports "NOT FOUND" so that you can then press ESC and not even disturb the stack. *Slick*

    I did have that changed to ??? during normal interactive mode but to make the error pop out a bit more during a source code load I did the --> badword <-- NOT FOUND message instead. So don't be surprised if it seems to revert back to ??? because that is less invasive when we are typing whereas the NOT FOUND is useful during a TACHYON ...... END type load.

    The parsing as you type is really compile as you type so you don't have to create a definition just to run "compile only" words as they work the same outside of a definition as they do inside, an example:
    $80 BL DO I EMIT LOOP
    Will execute immediately you hit the enter key without having to put this inside a definition.

    BTW, You don't even need to hit ESC as it is quite happy just to continue on. Clearing the stack on an error seems to be a standard Forth thing but I always found it to be more of a nuisance, type type doh, retype retype doh and so on.

    EDIT: The compile as you go approach also means I don't have to have a text input buffer large enough to accommodate the longest line, I only need a word buffer wide enough to accommodate the longest word (32 characters).
  • D.PD.P Posts: 790
    edited 2014-02-19 00:30
    I can fix the blank line thing, it's just that I keep forgetting about it but if you leave out the end-of-line comment it also works fine too. Just place the comment up above it. It has to do with termination of looking for more names although TABLE itself should never need to do this but it's based on AVARIABLE which does.

    As long as nothing has set the LCD serial data pin high such as during testing then your task should be able to run but I will hook-up one of my serial LCDs and try it out anyway.

    EDIT: you could also release the LCD serial data pin after transmit as the LCD should have a pullup.
    pub LCDEMIT 9 PINSET 9 SEROUT 9 PININP ;

    Everything works after the additional line between the TABLE definitions. I will remember/document about the comments and the release of the serial pin.
    Thanks
  • artkennedyartkennedy Posts: 174
    edited 2014-02-19 10:16
    I am working to interface a DMM to the Propeller. It communicates with 7 bits and 2 stop bits. I have tested it with an hp48 calculator at 8.1. Works fine if you clear the high bit of incoming data. For some reason PropForth would not cooperate with this although I did a successful test using the calculator to simulate the DMM by transmitting the same string with the high bits set. Maybe something I overlooked.

    Currently I am learning to use Tachyon and testing still with the calculator doing the FakeDMM thing. I have established communication and get the string in to the prop. The test string is "DC 4.321 V". I have written code to extract the numeric part of the string "4.321" or "-1.234", as the case may be, so I need to find the spaces. Of course I could just assume ;-) the result to always be positive and it would always be in the same place - easy. But I would rather make a more general method. And after I get the number as a string I will want to make it a number - don't know how yet - have ideas - surely been done before.

    Here is the code and the problems: [ how do I put code in one of those nice little windows? ]

    dmmbuf .STR DC 4.321 V ok

    : .DMM
    dmmbuf $20 STRING D$ \ assign DMM reading to D$
    BL D$ LOCATE$ 1+ $20 STRING N$ \ drop left side of string before number
    N$ DUP BL OVER LOCATE$ \ find trailing space
    SWAP - LEFT$ \ drop all after number
    N$ D$ COPY$
    FORGET N$
    ;

    Problems:

    Won't run. Can't FORGET it. It places the strings in the dictionary before it is even executed. Arrrrh!
  • D.PD.P Posts: 790
    edited 2014-02-19 13:37
    r
    artkennedy wrote: »
    I am working to interface a DMM to the Propeller. It communicates with 7 bits and 2 stop bits. I have tested it with an hp48 calculator at 8.1. Works fine if you clear the high bit of incoming data. For some reason PropForth would not cooperate with this although I did a successful test using the calculator to simulate the DMM by transmitting the same string with the high bits set. Maybe something I overlooked.

    Currently I am learning to use Tachyon and testing still with the calculator doing the FakeDMM thing. I have established communication and get the string in to the prop. The test string is "DC 4.321 V". I have written code to extract the numeric part of the string "4.321" or "-1.234", as the case may be, so I need to find the spaces. Of course I could just assume ;-) the result to always be positive and it would always be in the same place - easy. But I would rather make a more general method. And after I get the number as a string I will want to make it a number - don't know how yet - have ideas - surely been done before.

    Here is the code and the problems: [ how do I put code in one of those nice little windows? ]

    dmmbuf .STR DC 4.321 V ok

    : .DMM
    dmmbuf $20 STRING D$ \ assign DMM reading to D$
    BL D$ LOCATE$ 1+ $20 STRING N$ \ drop left side of string before number
    N$ DUP BL OVER LOCATE$ \ find trailing space
    SWAP - LEFT$ \ drop all after number
    N$ D$ COPY$
    FORGET N$
    ;

    Problems:

    Won't run. Can't FORGET it. It places the strings in the dictionary before it is even executed. Arrrrh!

    I can't declare a STRING in a definition so Peter will have the answer, but this does work so your logic is right :)
     " DC 4.321 V" $20 STRING dmmbuf  ok
     NULL$ $20 STRING D$  ok
     NULL$ $20 STRING N$    ok
    : DMM 
     dmmbuf D$ COPY$ 
     BL D$ LOCATE$ 1+ N$ COPY$  \ 
     N$ DUP BL OVER LOCATE$ \ 
     SWAP - LEFT$ \ 
     N$ D$ COPY$ 
    ;  ok
    DMM  ok
    N$ .STR 4.321 ok
    D$ .STR 4.321 ok
    

    Pretty sure you could refactor one string and use the temporary buffers if memory is of concern.
    "Add BUFFERS word which points to the 2K VM image (reusable as temporary buffers - do not backup as Tachyon will not be able to boot)"
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-19 14:14
    artkennedy wrote: »
    I am working to interface a DMM to the Propeller. It communicates with 7 bits and 2 stop bits. I have tested it with an hp48 calculator at 8.1. Works fine if you clear the high bit of incoming data. For some reason PropForth would not cooperate with this although I did a successful test using the calculator to simulate the DMM by transmitting the same string with the high bits set. Maybe something I overlooked.

    Currently I am learning to use Tachyon and testing still with the calculator doing the FakeDMM thing. I have established communication and get the string in to the prop. The test string is "DC 4.321 V". I have written code to extract the numeric part of the string "4.321" or "-1.234", as the case may be, so I need to find the spaces. Of course I could just assume ;-) the result to always be positive and it would always be in the same place - easy. But I would rather make a more general method. And after I get the number as a string I will want to make it a number - don't know how yet - have ideas - surely been done before.

    Here is the code and the problems: [ how do I put code in one of those nice little windows? ]

    dmmbuf .STR DC 4.321 V ok

    : .DMM
    dmmbuf $20 STRING D$ \ assign DMM reading to D$
    BL D$ LOCATE$ 1+ $20 STRING N$ \ drop left side of string before number
    N$ DUP BL OVER LOCATE$ \ find trailing space
    SWAP - LEFT$ \ drop all after number
    N$ D$ COPY$
    FORGET N$
    ;

    Problems:

    Won't run. Can't FORGET it. It places the strings in the dictionary before it is even executed. Arrrrh!

    About the forum formating, it uses BBCode and you can enter this directly or press the ADVANCED button down the bottom right of the edit window and you get a whole lot of other options. So when you paste code into the window then select that section and click the # button which will enclose the text in code tags.

    The STRING word is a defining word, that is it creates a new defintion and the rule is that you do not create new definitions inside another one, so logically these should be defined before .DMM . So STRING and FORGET etc are all defining words that execute immediately even during compile so no Forth ever expects to use them in the way that you have defined .DMM

    Anyway, you are doing it the hard way, all the parsing and conversion is built into TF, don't assemble the whole line into a buffer just parse it word by word (direct key input) and use GETWORD DECIMAL NUMBER when you are expecting data from the DMM. The AC/DC part of the message would also be handled by a preceding GETWORD and storing that result in a string like this GETWORD dmm$ COPY$ etc.

    I could write the code for you but it is simpler than you think so I will let you have a bit more of a play with TF. Of couse if you have to have it in a bufffer to parse just remember that NUMBER will parse a string but define that string just like any variable or constant, outside of another defintion.

    EDIT: You would never say in any Forth
    : MyTest 1234 CONSTANT mycon mycon . ;
    But of course you do it like this:
    1234 CONSTANT mycon
    : MyTest mycon . ;
    So STRING is similar to CONSTANT and VARIABLE and so on. Even if the first example compiled somehow what would happend each time you ran it is that it would create another new definition called mycon, after testing that ten times you would have 10 new "mycons" in the dictionary, clearly not what you would want to happen.

    BTW, any use of the BACKUP word is normally safe, it skips those areas it would never want to overwrite in EEPROM.
  • nglordinglordi Posts: 114
    edited 2014-02-19 19:46
    While searching for a pic32 forth, I came across the program FORFITER (Lubos Pekny www.forth.cz). It is a terminal program designed to use with FORTH. It combines a terminal with an editor. It effectively eliminates copy/paste as a tool to entend forth. I am now using forfiter instead of tera term.

    NickL
  • D.PD.P Posts: 790
    edited 2014-02-19 19:50
    About the forum formating, it uses BBCode and you can enter this directly or press the ADVANCED button down the bottom right of the edit window and you get a whole lot of other options. So when you paste code into the window then select that section and click the # button which will enclose the text in code tags.

    The STRING word is a defining word, that is it creates a new defintion and the rule is that you do not create new definitions inside another one, so logically these should be defined before .DMM . So STRING and FORGET etc are all defining words that execute immediately even during compile so no Forth ever expects to use them in the way that you have defined .DMM

    Anyway, you are doing it the hard way, all the parsing and conversion is built into TF, don't assemble the whole line into a buffer just parse it word by word (direct key input) and use GETWORD DECIMAL NUMBER when you are expecting data from the DMM. The AC/DC part of the message would also be handled by a preceding GETWORD and storing that result in a string like this GETWORD dmm$ COPY$ etc.

    I could write the code for you but it is simpler than you think so I will let you have a bit more of a play with TF. Of couse if you have to have it in a bufffer to parse just remember that NUMBER will parse a string but define that string just like any variable or constant, outside of another defintion.

    EDIT: You would never say in any Forth
    : MyTest 1234 CONSTANT mycon mycon . ;
    But of course you do it like this:
    1234 CONSTANT mycon
    : MyTest mycon . ;
    So STRING is similar to CONSTANT and VARIABLE and so on. Even if the first example compiled somehow what would happend each time you ran it is that it would create another new definition called mycon, after testing that ten times you would have 10 new "mycons" in the dictionary, clearly not what you would want to happen.

    BTW, any use of the BACKUP word is normally safe, it skips those areas it would never want to overwrite in EEPROM.

    NUMBER in my version doesn't seem to work according to the comments in the Tachyon V2.3 source regarding valid conversion forms. Else my syntax is wrong?
      Propeller .:.:--TACHYON--:.:. Forth V23140216.1600
    
    NAMES:  $5DC9...74EF for 5926 (3412 bytes added)
    CODE:   $0000...3352 for 7212 (6994 bytes added)
    CALLS:  0482 vectors free
    RAM:    10871 bytes free
    
    AUTORUN EXTEND.boot
    MODULES LOADED: 
    1800: EXTEND.fth          Primary extensions to TACHYON kernel - 140216-1400 
    ----------------------------------------------------------------
    " 1234d" $10 STRING D$  ok
    .S 
    STACK: 0000.0000 0000.0000 FFFF.F9FF 0000.0010  ok
    D$ TYPE$ 1234d ok
    .S 
    STACK: 0000.0000 0000.0000 FFFF.F9FF 0000.0010  ok
    D$ NUMBER  ok
    .S 
    STACK: 0000.0000 FFFF.F9FF 0000.0010 0000.0000  ok
    

    NUMBER ' ( str -- value digits | false )

    Acceptable forms are:
    $1000 hex number
    1000h

    #1000 decimal number
    1000d

    %1000 binary number
    1000b
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-20 14:34
    D.P wrote: »
    NUMBER in my version doesn't seem to work according to the comments in the Tachyon V2.3 source regarding valid conversion forms. Else my syntax is wrong?

    NUMBER ' ( str -- value digits | false )

    Acceptable forms are:
    $1000 hex number
    1000h

    #1000 decimal number
    1000d

    00 binary number
    1000b

    While it is true that NUMBER will take a string from GETWORD and convert it, it does not appear to work with strings in general and this is simply because NUMBER is expecting a string with a preceding count as is used in GETWORD. It stills looks like a string, it's that it just happens to have the count of the string in the byte preceding it.

    I may change the operation of NUMBER to work with strings in general but in the meantime this will work:
    [FONT=courier new]
    \ Create a string variable to hold the longest number (binary with separators)
    " 1234" #40 STRING num$
    pub STR>NUM ( str -- num digits | false )
        num$ 1+ $!
        num$ 1+ LEN$ num$ C!
        num$ 1+ NUMBER
        ;
    [/FONT]
    
  • D.PD.P Posts: 790
    edited 2014-02-21 09:28
    While it is true that NUMBER will take a string from GETWORD and convert it, it does not appear to work with strings in general and this is simply because NUMBER is expecting a string with a preceding count as is used in GETWORD. It stills looks like a string, it's that it just happens to have the count of the string in the byte preceding it.

    I may change the operation of NUMBER to work with strings in general but in the meantime this will work:
    [FONT=courier new]
    \ Create a string variable to hold the longest number (binary with separators)
    " 1234" #40 STRING num$
    pub STR>NUM ( str -- num digits | false )
        num$ 1+ $!
        num$ 1+ LEN$ num$ C!
        num$ 1+ NUMBER
        ;
    [/FONT]
    

    This is what works for me
    " "     #40 STRING buf$ 
    pub STR>NUM ( str -- num digits | false ) 
        buf$ ERASE$ 
        buf$ 1+ $! 
        buf$ 1+ LEN$ buf$ C! 
        buf$ 1+ NUMBER 
        ; 
    " $DEADBEEF" STR>NUM .S 
    STACK: 0000.0000 0000.0000 DEAD.BEEF 0000.0008  ok
    
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-24 16:06
    I'm integrating floating point into TF but if I do this at compile time it adds another 2K to the memory footprint that while acceptable during evaluation stage is really wasteful when you start cramming in other modules and your application. What I am thinking of doing is specifying that the image of the floating point module and other modules reside in the top 32k of a 64kB EEPROM so that main hub memory is not lost. Normally a Prop loads a cog from an image in hub memory and that 2K or so area is normally waster afterwards. In the case of TF the hub memory area that held the TF cog image is reused at runtime for buffers, as is also the smaller receive cog image as it is reused for serial buffers. This is fine as when I do a backup of the TF system it bypasses these areas as it doesn't need to backup buffers which of course it shouldn't anyway as it needs to have the TF and serial images available at boot-time.

    Anyhow, getting back to allowing TF to make efficient use of it's hub memory without imposing extra hardware on the system other than using a 64kB EEPROM instead of the normal 32kB, I need to have any additional cog images out of the way but readily accessible at boot time. The logical place for this is in the top 32kB of the 64kB EEPROM where a boot-time program can load the images that are required into cogs without messing with hub memory. Since coginit requires the image to be in hub ram I just load the EEPROM image into the 2K buffer area vacated by the TF image. This would allow me to be able to load the floating-point image as well as others such as VGA, serial, etc into cogs while TF is booting. Of course these images could also reside on SD instead but that may not be present while EEPROM always is.

    Does that scheme sound acceptable? Are there other cog objects that you would like? In the case of floating point I just use the PASM from F32 as would be the case with serial, VGA etc.

    BTW, the image is initially loaded into EEPROM in a similar manner to extending the kernel, except we load a hex file.

    EDIT: in the case of a VGA/TV text driver I could compile and load the module normally as I could reuse the image ram for the display buffer. But the EEPROM scheme is more flexible.

    EDIT: Rather than a pure hex file I could use the listing generated by BST and paste that into my TF module source, that's uncomplicated and readable, and TF could just filter out the code it needs to load into EEPROM. There's lot's of information in the listing, here's a sample:
    [FONT=courier new]|===========================================================================|
    Object DAT Blocks
    |===========================================================================|
    0018(0000)             |                         org
    0018(0000) F0 97 BF 0A | getCommand              rdlong  cmdPtr, par wz          ' wait for command
    001C(0001) 00 00 68 5C |           if_z          jmp     #getCommand
    0020(0002) CB 89 BF A1 |                         mov     t2, cmdPtr wc           ' load fnumA
    0024(0003) C4 9D BF 08 |                         rdlong  fnumA, t2
    0028(0004) 04 88 FF 80 |                         add     t2, #4[/FONT]
    

    Have a look at what the hybrid source code document will look like, here's one here, it's unfinished but might work out.
  • max72max72 Posts: 1,155
    edited 2014-02-25 05:09
    I think it is a great addition.
    The 4 serial ports is a good candidate too, but probably the best would be to have a small how to in order to implement our object or add an existing one.
    Tell me if I'm wrong, but after all the 2 main configurations are the coprocessor style (where the pasm cog waits for the arguments and executes one of the possible operations) and the silently running, where the pasm code is doing its work independently, and in case shares data in and out via a HUB array.
    If we were able to create the code we could be able to speed up the obex translation, and also adding our own pasm modules.
    Massimo
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-26 06:12
    I added a new instruction to the PASM kernel that takes just one extra long and now I run the Fibonacci benchmark with much faster results. I might never use the new instruction in anything else but then again I might. It just replaces the OVER + SWAP operation and since it only added one extra long in the kernel I thought why not.

    DECIMAL ok
    1 26 ADO CR ." fibo(" I . ." ) = " NEWCNT I fibo .LAP ." result =" . LOOP
    fibo(1) = 11us result =1
    fibo(2) = 12us result =1
    fibo(3) = 13us result =2
    fibo(4) = 14us result =3
    fibo(5) = 15us result =5
    fibo(6) = 16us result =8
    fibo(7) = 17us result =13
    fibo(8) = 18us result =21
    fibo(9) = 19us result =34
    fibo(10) = 20us result =55
    fibo(11) = 21us result =89
    fibo(12) = 22us result =144
    fibo(13) = 23us result =233
    fibo(14) = 24us result =377
    fibo(15) = 25us result =610
    fibo(16) = 26us result =987
    fibo(17) = 27us result =1597
    fibo(18) = 28us result =2584
    fibo(19) = 29us result =4181
    fibo(20) = 30us result =6765
    fibo(21) = 31us result =10946
    fibo(22) = 32us result =17711
    fibo(23) = 33us result =28657
    fibo(24) = 34us result =46368
    fibo(25) = 35us result =75025
    fibo(26) = 36us result =121393 ok

  • D.PD.P Posts: 790
    edited 2014-02-26 10:25
    I added a new instruction to the PASM kernel that takes just one extra long and now I run the Fibonacci benchmark with much faster results. I might never use the new instruction in anything else but then again I might. It just replaces the OVER + SWAP operation and since it only added one extra long in the kernel I thought why not.

    DECIMAL ok
    1 26 ADO CR ." fibo(" I . ." ) = " NEWCNT I fibo .LAP ." result =" . LOOP
    fibo(1) = 11us result =1
    fibo(2) = 12us result =1
    fibo(3) = 13us result =2
    fibo(4) = 14us result =3
    fibo(5) = 15us result =5
    fibo(6) = 16us result =8
    fibo(7) = 17us result =13
    fibo(8) = 18us result =21
    fibo(9) = 19us result =34
    fibo(10) = 20us result =55
    fibo(11) = 21us result =89
    fibo(12) = 22us result =144
    fibo(13) = 23us result =233
    fibo(14) = 24us result =377
    fibo(15) = 25us result =610
    fibo(16) = 26us result =987
    fibo(17) = 27us result =1597
    fibo(18) = 28us result =2584
    fibo(19) = 29us result =4181
    fibo(20) = 30us result =6765
    fibo(21) = 31us result =10946
    fibo(22) = 32us result =17711
    fibo(23) = 33us result =28657
    fibo(24) = 34us result =46368
    fibo(25) = 35us result =75025
    fibo(26) = 36us result =121393 ok


    Based on the previous results I would say 1 long went a long way. As far as the F32 "hack" (the optimal way to connect a rotary phone switch to cause the best track switching to occur with the least fuss, "tech model railroad club") I can't wait to start using it. I agree with max72 it would be nice to be able to push our own "mods" this way but not necessary. I think F32 now gives Tachyon just about everything one could need. Telnet, FTP, HTTP, Sockets, Floating Point, Strings, RTC provisions, SD access, partial FAT16/32, I2C, SPI, ASync and best of all a console to rule them all! I was gathering UI needs from co-workers the other day and even they said "hey wait don't you have to go rebuild the software or something before you show us again" as I worked directly on the console as the equipment was running! :) Thanks Peter.
    fibo(1) = 13us result =1                                                                                        
    fibo(2) = 16us result =1                                                                                        
    fibo(3) = 19us result =2                                                                                        
    fibo(4) = 22us result =3                                                                                        
    fibo(5) = 25us result =5                                                                                        
    fibo(6) = 28us result =8                                                                                        
    fibo(7) = 31us result =13                                                                                       
    fibo(8) = 34us result =21                                                                                       
    fibo(9) = 37us result =34                                                                                       
    fibo(10) = 40us result =55                                                                                      
    fibo(11) = 43us result =89                                                                                      
    fibo(12) = 46us result =144                                                                                     
    fibo(13) = 49us result =233                                                                                     
    fibo(14) = 52us result =377                                                                                     
    fibo(15) = 55us result =610                                                                                     
    fibo(16) = 58us result =987                                                                                     
    fibo(17) = 61us result =1597                                                                                    
    fibo(18) = 64us result =2584                                                                                    
    fibo(19) = 67us result =4181                                                                                    
    fibo(20) = 70us result =6765                                                                                    
    fibo(21) = 73us result =10946                                                                                   
    fibo(22) = 76us result =17711                                                                                   
    fibo(23) = 79us result =28657                                                                                   
    fibo(24) = 82us result =46368                                                                                   
    fibo(25) = 85us result =75025                                                                                   
    fibo(26) = 88us result =121393 ok  
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-27 07:21
    Kuroneko has been helping out today with tweaking some of the PASM code which has freed up a handful of longs, and also the 8 channel PWM. So that's prompted me to tidy up some other stuff too and also fully implement and test the 32 channel PWM. These outputs are jitter free as best as they can be measured, there is a scope trace in the kernel source document you can look at but what I did was zoom in to 25ns/div at 50 ms after the trigger and leave the scope on infinite persistence. There was no jitter at all even though you can see the hairy rise time etc and the only thing that crept in was about 10ns of drift over 10 minutes or more, but no jitter, just rock steady. The reason for 32 channels is so that you can make any and as many pins as you like a PWM output
    You need 256 longs for a table that can be used to store all the calculated duty cycles for 32 channels over 256 samples (8-bit). The init code looks like this:
    [FONT=courier new]TABLE pwms #1024 ALLOT    \ allocate a 256 longs table for the PWM map    
    
    #5000 PWMFREQ        \ Set the frequecy
        
    \ Start up PWM using from P0..7, P16..P23 for 16 channels    
    $FF00FF pwms RUNPWM32        
    
    #50 % 2 MASK PWM32!    \ set P2 to 50 % duty
    #25 % $0F0000 PWM32!    \ set P16..P19 to 25 % duty[/FONT]
    

    pwm-M.jpg



    The signed divide also runs faster from 47us down to 18us whereas the unsigned divide U/ takes 10us. The multiply ops take around 4 or 5 us.

    Don't forget there's the serial LCD rolling odometer demo too.
    1023 x 762 - 176K
  • D.PD.P Posts: 790
    edited 2014-02-27 14:42
    Kuroneko has been helping out today with tweaking some of the PASM code which has freed up a handful of longs, and also the 8 channel PWM. So that's prompted me to tidy up some other stuff too and also fully implement and test the 32 channel PWM. These outputs are jitter free as best as they can be measured, there is a scope trace in the kernel source document you can look at but what I did was zoom in to 25ns/div at 50 ms after the trigger and leave the scope on infinite persistence. There was no jitter at all even though you can see the hairy rise time etc and the only thing that crept in was about 10ns of drift over 10 minutes or more, but no jitter, just rock steady. The reason for 32 channels is so that you can make any and as many pins as you like a PWM output
    You need 256 longs for a table that can be used to store all the calculated duty cycles for 32 channels over 256 samples (8-bit). The init code looks like this:
    [FONT=courier new]TABLE pwms #1024 ALLOT    \ allocate a 256 longs table for the PWM map    
    
    #5000 PWMFREQ        \ Set the frequecy
        
    \ Start up PWM using from P0..7, P16..P23 for 16 channels    
    $FF00FF pwms RUNPWM32        
    
    #50 % 2 MASK PWM32!    \ set P2 to 50 % duty
    #25 % $0F0000 PWM32!    \ set P16..P19 to 25 % duty[/FONT]
    

    pwm-M.jpg



    The signed divide also runs faster from 47us down to 18us whereas the unsigned divide U/ takes 10us. The multiply ops take around 4 or 5 us.

    Don't forget there's the serial LCD rolling odometer demo too.
    uh WOW comes to mind,

    Notice the online kernel has 5 MHz crytal settings now.

    Looks good here.
    00:00:00  End of source code, 2926 lines processed and 0000 errors found 
    Load time = 5,841ms
    
     Propeller .:.:--TACHYON--:.:. Forth V23140228.0000
    
    NAMES:  $5D99...7488 for 5871 (3288 bytes added)
    CODE:   $0000...315D for 6766 (6429 bytes added)
    CALLS:  0497 vectors free
    RAM:    11324 bytes free
    
    AUTORUN EXTEND.boot
    MODULES LOADED: 
    1840: EXTEND.fth          Primary extensions to TACHYON kernel - 140227-1430 
    
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-27 22:23
    Just sorted through some problems on my side with kuroneko and then fired up his version of PWM32 and now that runs up to 6.940kHz. no make that 7.6kHz
    Controlling individual pins or groups of pins is easy and of course you can always create your methods like these
    75 % 2 SETPWM ( set P2 to 75% duty)
    or
    32 16 8 SETPWMS ( set P16..P23 to 32/256 duty cycle)
    or you might like to specify the range like Spin in which case we could modify SETPWMS
    32 16 23 SETPWMS
    etc
    These methods calculate the entries in a 1K byte table for all 256 samples of 32 channels which the PWM cog just reads from. So it's also possible to put arbitrary waveforms in the table too or even higher frequencies with less resolution, for instance if I set the channel bit in each alternate long I would have a 6.94kHz * 128 or 888.32kHz square wave on that pin (now 972.8kHz)

    As mentioned earlier these PWM outputs are table based and jitter free.

    7.6kHz 25% waveform
    PWM32-m2.jpg
    917 x 699 - 206K
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-28 08:01
    So just a few days ago I managed to get 36us for 26 iterations of the fibonacci sequence. Now I have added some more instructions and some bytecode magic.... the fibo routine takes just 7 code bytes and runs how fast?

    DECIMAL ok
    1 26 ADO CR ." fibo(" I . ." ) = " NEWCNT I fibo .LAP ." result =" . LOOP
    fibo(1) = 9us result =1
    fibo(2) = 10us result =1
    fibo(3) = 10us result =2
    fibo(4) = 10us result =3
    fibo(5) = 10us result =5
    fibo(6) = 11us result =8
    fibo(7) = 11us result =13
    fibo(8) = 11us result =21
    fibo(9) = 12us result =34
    fibo(10) = 12us result =55
    fibo(11) = 12us result =89
    fibo(12) = 13us result =144
    fibo(13) = 13us result =233
    fibo(14) = 13us result =377
    fibo(15) = 13us result =610
    fibo(16) = 14us result =987
    fibo(17) = 14us result =1597
    fibo(18) = 14us result =2584
    fibo(19) = 15us result =4181
    fibo(20) = 15us result =6765
    fibo(21) = 15us result =10946
    fibo(22) = 16us result =17711
    fibo(23) = 16us result =28657
    fibo(24) = 16us result =46368
    fibo(25) = 16us result =75025
    fibo(26) = 17us result =121393 ok

  • mindrobotsmindrobots Posts: 6,506
    edited 2014-02-28 10:05
    Gee, you only cut it in half?? :lol:

    Wow!!
  • D.PD.P Posts: 790
    edited 2014-02-28 12:46
    So just a few days ago I managed to get 36us for 26 iterations of the fibonacci sequence. Now I have added some more instructions and some bytecode magic.... the fibo routine takes just 7 code bytes and runs how fast?

    DECIMAL ok
    1 26 ADO CR ." fibo(" I . ." ) = " NEWCNT I fibo .LAP ." result =" . LOOP
    fibo(1) = 9us result =1
    fibo(2) = 10us result =1
    fibo(3) = 10us result =2
    fibo(4) = 10us result =3
    fibo(5) = 10us result =5
    fibo(6) = 11us result =8
    fibo(7) = 11us result =13
    fibo(8) = 11us result =21
    fibo(9) = 12us result =34
    fibo(10) = 12us result =55
    fibo(11) = 12us result =89
    fibo(12) = 13us result =144
    fibo(13) = 13us result =233
    fibo(14) = 13us result =377
    fibo(15) = 13us result =610
    fibo(16) = 14us result =987
    fibo(17) = 14us result =1597
    fibo(18) = 14us result =2584
    fibo(19) = 15us result =4181
    fibo(20) = 15us result =6765
    fibo(21) = 15us result =10946
    fibo(22) = 16us result =17711
    fibo(23) = 16us result =28657
    fibo(24) = 16us result =46368
    fibo(25) = 16us result =75025
    fibo(26) = 17us result =121393 ok

    Here's the iterative results from Heater's GCC LMM code.
    I'm happy to have this speed without the need for C. And so much more!
    fibo( 1) =      1 (  24 ticks) (0us)
    fibo( 2) =      1 (  20 ticks) (0us)
    fibo( 3) =      2 (  68 ticks) (0us)
    fibo( 4) =      3 (  84 ticks) (1us)
    fibo( 5) =      5 ( 116 ticks) (1us)
    fibo( 6) =      8 ( 148 ticks) (1us)
    fibo( 7) =     13 ( 180 ticks) (2us)
    fibo( 8) =     21 ( 196 ticks) (2us)
    fibo( 9) =     34 ( 228 ticks) (2us)
    fibo(10) =     55 ( 260 ticks) (3us)
    fibo(11) =     89 ( 292 ticks) (3us)
    fibo(12) =    144 ( 308 ticks) (3us)
    fibo(13) =    233 ( 340 ticks) (4us)
    fibo(14) =    377 ( 372 ticks) (4us)
    fibo(15) =    610 ( 404 ticks) (5us)
    fibo(16) =    987 ( 420 ticks) (5us)
    fibo(17) =   1597 ( 452 ticks) (5us)
    fibo(18) =   2584 ( 484 ticks) (6us)
    fibo(19) =   4181 ( 516 ticks) (6us)
    fibo(20) =   6765 ( 532 ticks) (6us)
    fibo(21) =  10946 ( 564 ticks) (7us)
    fibo(22) =  17711 ( 596 ticks) (7us)
    fibo(23) =  28657 ( 628 ticks) (7us)
    fibo(24) =  46368 ( 644 ticks) (8us)
    fibo(25) =  75025 ( 676 ticks) (8us)
    fibo(26) = 121393 ( 708 ticks) (8us)
    
  • msrobotsmsrobots Posts: 3,701
    edited 2014-02-28 14:50
    As generally I am impressed with TF. Even if reading Forth code is as useful for me as reading spin-binary's in HEX.

    But 7 code bytes IS impressive. What I am missing here is D.P.'s excitement over the speed. Heaters Fibo in compiled C finishes 26 iteration before TF does ONE?

    Enjoy!

    Mike
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-28 15:42
    msrobots wrote: »
    As generally I am impressed with TF. Even if reading Forth code is as useful for me as reading spin-binary's in HEX.

    But 7 code bytes IS impressive. What I am missing here is D.P.'s excitement over the speed. Heaters Fibo in compiled C finishes 26 iteration before TF does ONE?

    Enjoy!

    Mike

    What's also very interesting is the loop time, if we look at the difference in timing between 1 and 26 iterations it is 17-9 for TF which is of course 8us vs GCC's 8us, the same! So not having the cog dedicated to a benchmark means the other 9us is spent in TF coming from doing something useful, calling the function, stacking the parameters, unstacking, and returning back to something useful again up to 17us later. Oh well..... :)

    EDIT: just thinking about this abysmal 17us to run a fibo(26), I think Spin could almost run one and a half bytecode instructions in this same amount of time!
  • D.PD.P Posts: 790
    edited 2014-03-01 12:39
    msrobots wrote: »
    As generally I am impressed with TF. Even if reading Forth code is as useful for me as reading spin-binary's in HEX.

    But 7 code bytes IS impressive. What I am missing here is D.P.'s excitement over the speed. Heaters Fibo in compiled C finishes 26 iteration before TF does ONE?

    Enjoy!

    Mike

    One (GCC) is a compiled to benchmark one off program, does nothing more.
    The other is able to run along side FTP, HTTP, TELNET, SD CARD and console access in ONE cog! I thought that the TF fibo just being 9 us slower than the almighty GCC was fantastic, but now I understand it runs at the same speed. Do you understand?
  • msrobotsmsrobots Posts: 3,701
    edited 2014-03-01 13:22
    OK.

    17-9=8. Did not look at it this way. Sad that me and forth do not get along. Seems my brain is indoctrinated by non prefix languages. I tried but cant wrap my head around it.

    Enjoy!

    Mike
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-03-01 14:48
    msrobots wrote: »
    OK.

    17-9=8. Did not look at it this way. Sad that me and forth do not get along. Seems my brain is indoctrinated by non prefix languages. I tried but cant wrap my head around it.

    Enjoy!

    Mike

    Ah, I see Mike, you can't wrap your head around it, but I see from your avatar that perhaps your head's bin rappin' da PC C.
    It's so much more fun that way hey? :) Whereas my avatar (which btw is reproducible on the serial terminal -prop) is going yabba dabba doo!

    My first languages were "machine code", assembler, Basic, even Fortran, then C, with my introduction to Forth in there somewhere.
  • msrobotsmsrobots Posts: 3,701
    edited 2014-03-01 15:29
    Ah,... Whereas my avatar (which btw is reproducible on the serial terminal -prop) is going yabba dabba doo!

    You got me curious ... how to display your Avatar on a serial terminal? Or did you mean to display "yabba dabba doo"?

    I do use different languages also, my last fulltime Cobol Job was somewhere at the end of the last century. Over the years I needed usually to change the Language when changing the Job. But say switching from VB.net to C#.net is not a really big task, the framework stays the same, just the syntax varies a bit. Things like C might be no big thing either - I hadn't had the need for yet. Since a couple of weeks I use JavaScript since @Heater talked me into it, but all of those languages are very alike in the way they handle stuff. Forth is quite different.

    As to my Avatar ... that picture was probably taken while I was trying to understand FORTH.

    Enjoy!

    Mike
  • D.PD.P Posts: 790
    edited 2014-03-01 16:15
    msrobots wrote: »
    You got me curious ... how to display your Avatar on a serial terminal? Or did you mean to display "yabba dabba doo"?

    I do use different languages also, my last fulltime Cobol Job was somewhere at the end of the last century. Over the years I needed usually to change the Language when changing the Job. But say switching from VB.net to C#.net is not a really big task, the framework stays the same, just the syntax varies a bit. Things like C might be no big thing either - I hadn't had the need for yet. Since a couple of weeks I use JavaScript since @Heater talked me into it, but all of those languages are very alike in the way they handle stuff. Forth is quite different.

    As to my Avatar ... that picture was probably taken while I was trying to understand FORTH.

    Enjoy!

    Mike

    It was incredibly hard for me at first. Now it's fun. Hairless monkeys hate "to change", confirmation bias and peer packing can ruin the mind.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-03-01 19:44
    msrobots wrote: »
    You got me curious ... how to display your Avatar on a serial terminal? Or did you mean to display "yabba dabba doo"?

    I do use different languages also, my last fulltime Cobol Job was somewhere at the end of the last century. Over the years I needed usually to change the Language when changing the Job. But say switching from VB.net to C#.net is not a really big task, the framework stays the same, just the syntax varies a bit. Things like C might be no big thing either - I hadn't had the need for yet. Since a couple of weeks I use JavaScript since @Heater talked me into it, but all of those languages are very alike in the way they handle stuff. Forth is quite different.

    As to my Avatar ... that picture was probably taken while I was trying to understand FORTH.

    Enjoy!

    Mike

    Good come back Mike, hi5!

    My avatar was taken from an ANSI graphics that I would display on compatible terminals, such as TeraTerm, even Hyperterminal. I will post a special edition of EXTEND.fth which will test to see if the terminal is compatible and then display my avatar on boot. In fact I can even test the terminal's baud rate settings etc to automatically adapt.

    EDIT: Didn't want to make a new post but I shaved a few more microseconds from my fibo, still going for more:
    fibo(22) = 12us result =17711
    fibo(23) = 12us result =28657
    fibo(24) = 13us result =46368
    fibo(25) = 13us result =75025
    fibo(26) = 13us result =121393
    and
    fibo(46) = 19us result =1836311903 ok

    kuroneko has written fibo in PASM and gets 3.6us for fibo(46)
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-03-02 07:39
    Good come back Mike, hi5!

    My avatar was taken from an ANSI graphics that I would display on compatible terminals, such as TeraTerm, even Hyperterminal. I will post a special edition of EXTEND.fth which will test to see if the terminal is compatible and then display my avatar on boot. In fact I can even test the terminal's baud rate settings etc to automatically adapt.

    Anyone who is using TeraTerm or Hyperterminal can compile the latest kernel and EXTEND.fth and my avatar should appear on boot. My minicom doesn't handle these characters properly but I still need to fully activate the automatic terminal test software so that it only displays on compatible terminals.

    Here are some of the latest fibonacci results:

    fibo(2) = 6us result =1
    fibo(3) = 6us result =2

    fibo(23) = 12us result =28657
    fibo(24) = 13us result =46368
    fibo(25) = 13us result =75025
    fibo(26) = 13us result =121393

    fibo(46) = 19us result =1836311903 ok
Sign In or Register to comment.