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

14041434546109

Comments

  • D.PD.P Posts: 790
    edited 2014-03-02 - 11:05:57
    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

    No comment on the speed 13-6, I'm laying low and avoiding the radar, but the last pillar just fell, did it make any noise? Gonna build the new kernel and fire up teraterm now, seeing how I usually use minicom.
  • David BetzDavid Betz Posts: 14,068
    edited 2014-03-02 - 11:23:26
    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
    This speed is quite impressive but I'm not sure how useful it is as a benchmark when it uses the iterative algorithm. Maybe we should find some other function/word calling benchmark that won't overflow Tachyon's COG-based stack for a better comparison. How many programs really do nothing but sit in a small loop?
  • D.PD.P Posts: 790
    edited 2014-03-02 - 11:34:01
    David Betz wrote: »
    This speed is quite impressive but I'm not sure how useful it is as a benchmark when it uses the iterative algorithm. Maybe we should find some other function/word calling benchmark that won't overflow Tachyon's COG-based stack for a better comparison. How many programs really do nothing but sit in a small loop?
    The GCC test program referred to was iterative as well. Let's just leave the speed stuff alone okay. Now how about executing this fibo via a telnet session, writing the results to SD, reading the results back from SD and transmitting them back via telnet, in one cog. That's the real benchmark for usefulness I think.
  • David BetzDavid Betz Posts: 14,068
    edited 2014-03-02 - 11:36:13
    D.P wrote: »
    The GCC test program referred to was iterative as well. Let's just leave the speed stuff alone okay. Now how about executing this fibo via a telnet session, writing the results to SD, reading the results back from SD and transmitting them back via telnet, in one cog. That's the real benchmark for usefulness I think.
    Yes, I know the GCC program was also iterative. I'm not sure that the GCC version is a very useful benchmark either. For evaluating Tachyon, I think something other than fibo is required.
  • D.PD.P Posts: 790
    edited 2014-03-02 - 11:42:14
    Getting a compile error here:
    TABLE fred $09B0 ALLOT
    
    fred HEXLOAD
    
    :100000001B5B34306D1B5B324A1B5B3134431B5B23        \ <---- first line throws an error
    .
    .
    .
    .
    
    
    Something is whack in this syntax, no space after colon operator not sure what you mean. HEXLOAD is a new word for me.
  • D.PD.P Posts: 790
    edited 2014-03-02 - 11:57:26
    David Betz wrote: »
    Yes, I know the GCC program was also iterative. I'm not sure that the GCC version is a very useful benchmark either. For evaluating Tachyon, I think something other than fibo is required.

    Well then how about the functional program just described? Telnet session, program a fibo routine, execute it, have it save its results to SD, read the results back from SD and transmit them via Telnet back in one cog. You may say that's not fair and you are right, FORTH is not fair, it's a lean and mean threaded interpretive language and should not be compared with anything else. It has been expertly ported onto the Prop architecture via the Tachyon VM. Use the tools that make you most productive no matter what they are! I sure don't care what tools people use, Tachyon is just an option.

    Save us all now that Kuroneko is casting his gaze upon the assembler with Peter and F32 is about to be cast into the VM.
  • David BetzDavid Betz Posts: 14,068
    edited 2014-03-02 - 13:20:27
    D.P wrote: »
    Well then how about the functional program just described? Telnet session, program a fibo routine, execute it, have it save its results to SD, read the results back from SD and transmit them via Telnet back in one cog. You may say that's not fair and you are right, FORTH is not fair, it's a lean and mean threaded interpretive language and should not be compared with anything else. It has been expertly ported onto the Prop architecture via the Tachyon VM. Use the tools that make you most productive no matter what they are! I sure don't care what tools people use, Tachyon is just an option.

    Save us all now that Kuroneko is casting his gaze upon the assembler with Peter and F32 is about to be cast into the VM.
    You win that benchmark because there is currently no way to do Telnet with PropGCC. Congratulations.
  • David BetzDavid Betz Posts: 14,068
    edited 2014-03-02 - 13:27:49
    Actually, since you mention Telnet, FTP, and web server, I was wondering if that network support would work with the Xbee Wi-Fi module that Parallax now sells? I assume Tachyon currently uses a WizNet chip?
  • D.PD.P Posts: 790
    edited 2014-03-02 - 14:15:23
    David Betz wrote: »
    Actually, since you mention Telnet, FTP, and web server, I was wondering if that network support would work with the Xbee Wi-Fi module that Parallax now sells? I assume Tachyon currently uses a WizNet chip?

    The wiznet 5500 is a hardware/ethernet based IP stack with 8 sockets. The Xbee 802.11n wi-if and has at max 2 sockets:

    "API mode
    When the UART is configured for API mode using the ATAP command the module will open two listening sockets,
    one for each IP type (UDP and TCP) "

    So while not as robust as the Wiznet socket wise, it is 802.11n and does have security! (WPA-PSK,WPA2-PSK and WEP) Cool chip.

    [url]ftp://ftp1.digi.com/support/temp/XBee Wi-Fi Beta/XBee Wi-Fi Documentation_BETA.pdf[/url]

    It has a 6Mb SPI and 1Mb UART interface. I'm sure a driver for Tachyon could be made and if I needed wi-fi I would begin one and post it here for Peter et al to help me structure correctly, being more of an art than engineering it seems sometimes with my limited experience in Tachyon/FORTH.

    The Tachyon Wiznet stuff is in exactly two small-ish FORTH files. W5200.fth and NETWORK.fth, serious idea compression inside, fair warning.
  • David BetzDavid Betz Posts: 14,068
    edited 2014-03-02 - 15:10:33
    D.P wrote: »
    The wiznet 5500 is a hardware/ethernet based IP stack with 8 sockets. The Xbee 802.11n wi-if and has at max 2 sockets:

    "API mode
    When the UART is configured for API mode using the ATAP command the module will open two listening sockets,
    one for each IP type (UDP and TCP) "

    So while not as robust as the Wiznet socket wise, it is 802.11n and does have security! (WPA-PSK,WPA2-PSK and WEP) Cool chip.

    [url]ftp://ftp1.digi.com/support/temp/XBee Wi-Fi Beta/XBee Wi-Fi Documentation_BETA.pdf[/url]

    It has a 6Mb SPI and 1Mb UART interface. I'm sure a driver for Tachyon could be made and if I needed wi-fi I would begin one and post it here for Peter et al to help me structure correctly, being more of an art than engineering it seems sometimes with my limited experience in Tachyon/FORTH.

    The Tachyon Wiznet stuff is in exactly two small-ish FORTH files. W5200.fth and NETWORK.fth, serious idea compression inside, fair warning.
    Thanks! I've played with the Xbee Wi-Fi module some and it doesn't seem to handle TCP/IP flow control well. You have to pace data being sent to it or it gets thrown away if the internal buffer overflows. Does the WizNet chip have this problem? I think the buffer size on the Xbee is < 2K bytes.
  • Peter JakackiPeter Jakacki Posts: 9,383
    edited 2014-03-02 - 15:52:02
    David Betz wrote: »
    This speed is quite impressive but I'm not sure how useful it is as a benchmark when it uses the iterative algorithm. Maybe we should find some other function/word calling benchmark that won't overflow Tachyon's COG-based stack for a better comparison. How many programs really do nothing but sit in a small loop?

    Exactly how I feel too, but I am using the benchmark as a way of comparing and improving TF against itself. But of course as DP pointed out, it can do it inside a TF Telnet session while writing to a file! So it's not just a benchmark which btw also means when a compiler uses a recursive algorithm it doesn't prove whether it can do the job either.

    One of the improvements I made was with looping, this is already fast and has the loop address held in a cog stack so that it doesn't have to read a displacement from hub ram each loop (conventional Forth) which slows things down. However in addition I created a REPS instruction from the extra longs that kuroneko gleaned so that it caches the instruction we want repeated, so each loop runs a cached instruction and in the case of the iterative fibo that takes IIRC 200ns/loop. So the REPS instruction even at this stage has also come in handy for instructions such as SPIWRB instruction etc in cutting down the low overhead even further.

    The other thing I changed was putting in a check on the data stack to see if it really needed to access the hub or not so that when the stack depth is less than 5 it is not being slowed down by hub accesses. But these are techniques made possible by all these extra longs that kuroneko manages to squeeze out and in the process I've learned some neat tricks like unconventional jmpret's and even just sumc has proved useful. Even jumping via the address field of a return rather than jumping to the return instruction itself saves cycles.

    Internally I have changed the hard coded jmp #doNEXT with a jmp unext so that I can make the VM instructions return where I want as in the case of REPS but also good for debugging purposes.

    I had a 32 channel 8-bit PWM module that ran up to 5kHz or so and kuroneko wrote a version that runs up to 7.6kHz and still fitted in the module limits of 18 longs.

    Next step is having modules and cogs loaded from an object repository in upper 64kB EEPROM at runtime, just select the objects you want and run, this also includes the F32 floating point object.

    So yeah, having a challenge is a good thing if it leads to not a cause for boasting but to self-improvement (code-wise) that benefits many while having fun.
  • D.PD.P Posts: 790
    edited 2014-03-02 - 15:56:24
    David Betz wrote: »
    Thanks! I've played with the Xbee Wi-Fi module some and it doesn't seem to handle TCP/IP flow control well. You have to pace data being sent to it or it gets thrown away if the internal buffer overflows. Does the WizNet chip have this problem? I think the buffer size on the Xbee is < 2K bytes.

    I have not had any issues using either the spin/pasm drivers or Tachyon with the W5200 chips.
  • David BetzDavid Betz Posts: 14,068
    edited 2014-03-02 - 16:06:23
    D.P wrote: »
    I have not had any issues using either the spin/pasm drivers or Tachyon with the W5200 chips.
    That's good to know. Maybe I should try that chip but I'd kind of like to have Wi-Fi capability.
  • D.PD.P Posts: 790
    edited 2014-03-02 - 16:17:48
    Try and only write to the buffer when it's empty then. I know you're very talented but I bet it's your implementation, xbee is a solid little gadget but may not be very fast.
  • David BetzDavid Betz Posts: 14,068
    edited 2014-03-02 - 16:25:17
    D.P wrote: »
    Try and only write to the buffer when it's empty then. I know you're very talented but I bet it's your implementation, xbee is a solid little gadget but may not be very fast.
    Okay, I'll stop trying to have a reasonable conversation. Not possible on these forums I guess.
  • Peter JakackiPeter Jakacki Posts: 9,383
    edited 2014-03-02 - 16:42:47
    David Betz wrote: »
    Okay, I'll stop trying to have a reasonable conversation. Not possible on these forums I guess.
    Hi Dave, we respect your opinions and I didn't read DPs post as having a dig at you, he just simply acknowledged your considerable talent but also acknowledged that the xbee is not very fast. Now that DP is an expert on WIZnet then maybe we can get him to do some debugging :)
  • D.PD.P Posts: 790
    edited 2014-03-02 - 17:01:37
    Hey David I meant what I said!!! I think you are really talented, I've followed your work here! No dig at all just saying it's probably the code that's all!
  • artkennedyartkennedy Posts: 164
    edited 2014-03-09 - 22:02:34
    I am back from some time off for a trip and another urgent task.

    I have researched BBCode now that I know what it is and will be trying it out.

    The use of a defining word within another word was not too bright. I am recently back to Forth after about 35 years off. Thanks for straightening me out on that.

    In combing the source I found .STR and decided to try it out. So I clipped the example code:
    $20 " This is a string." STRING A$  ok
    A$ 20 DUMP
    0000_33D8:   00 00 53 20  08 08 08 08   08 54 68 69  73 20 69 73   ..S .....This is
    0000_33E8:   20 61 20 73  74 72 69 6E   67 2E 00 06  06 20 00 06    a string.... .. ok
    A$ 9 + .STR This is a string. ok
    

    I'm wondering why the string is offset 9 bytes from its address.

    I'm also wondering if the BBcode above will work the way I intend. 'nyuk nyuk - I guess it did.
  • Peter JakackiPeter Jakacki Posts: 9,383
    edited 2014-03-10 - 00:21:44
    artkennedy wrote: »
    I am back from some time off for a trip and another urgent task.

    I have researched BBCode now that I know what it is and will be trying it out.

    The use of a defining word within another word was not too bright. I am recently back to Forth after about 35 years off. Thanks for straightening me out on that.

    In combing the source I found .STR and decided to try it out. So I clipped the example code:
    $20 " This is a string." STRING A$  ok
    A$ 20 DUMP
    0000_33D8:   00 00 53 20  08 08 08 08   08 54 68 69  73 20 69 73   ..S .....This is
    0000_33E8:   20 61 20 73  74 72 69 6E   67 2E 00 06  06 20 00 06    a string.... .. ok
    A$ 9 + .STR This is a string. ok
    

    I'm wondering why the string is offset 9 bytes from its address.

    I'm also wondering if the BBcode above will work the way I intend. 'nyuk nyuk - I guess it did.

    Oh, is that where you've been, I thought that all that tackling dialects of Forth had sent you off into cuckoo land! Now that you've been released you are coming back for some more punishment!

    Okay, to make it easy for you the STRING word takes a string and a maximum size as arguments but it's in this format:
    " MY STRING" 0 STRING A$
    So it's string,count, not count,string and the 0 just sets the maximum size to the current string length. Specify another size if this string is meant to be rewritten and it may need more room.
  • artkennedyartkennedy Posts: 164
    edited 2014-03-10 - 01:09:31
    Okaaay, I was thinking that the Useage note that I copied from EXTEND.FTH seemed to disagree with the parameter field above. Should have tried that. Thanks.
  • Peter JakackiPeter Jakacki Posts: 9,383
    edited 2014-03-10 - 01:53:32
    artkennedy wrote: »
    Okaaay, I was thinking that the Useage note that I copied from EXTEND.FTH seemed to disagree with the parameter field above. Should have tried that. Thanks.

    BTW, there are several aliases for certain dot words where I find the dot is not very distinct as a character in formatted source code so I have used the word PRINT instead. So therefore .STR is also PRINT$ and the dot itself is also PRINT etc and this is what you will see in many source code documents.

    I will check my usage notes to make sure they are correct.
  • artkennedyartkennedy Posts: 164
    edited 2014-03-11 - 15:35:44
    What I do wrong daddy?

    dmmbuf 10 DUMP 0000_3364: 44 43 20 31 32 33 2E 34 00 75 41 00 00 00 00 00 DC 123.4.uA..... dmmbuf 3 + NUMBER . 0 ok dmmbuf 3 + PRINT$ 123.4 ok;[\code] Also what wrong with BBcode?? . . . sigh . . .[code]dmmbuf 10 DUMP
    0000_3364: 44 43 20 31 32 33 2E 34 00 75 41 00 00 00 00 00 DC 123.4.uA.....
    dmmbuf 3 + NUMBER . 0 ok
    dmmbuf 3 + PRINT$ 123.4 ok;[\code]

    Also what wrong with BBcode??

    . . . sigh . . .
  • Peter JakackiPeter Jakacki Posts: 9,383
    edited 2014-03-11 - 17:19:58
    nglordi wrote: »
    I have posted a TACHYON based robot control language in the Robotics forum. I include the RCL Core here for comment.

    pub  BOEPAB.fth   ." TACHYON Robot Control for BOE Platform & Prop Activity Board "   ;
    
    {
     Motor drivers and utilities.
    }
    
    #P12 2 MASKS  ==  pwmpins
    
    #1495 #80 * == ld0  \ sets zero position of left servo
    
    #1504 #80 * == rd0  \ sets zero position of right servo
    
    LONG lduty, rduty
    
    pub .duty ( -- ) \ displays current right & left duties
        lduty @ . SPACE rduty @ . CR ;
    
    pub M1 ( duty -- ) \ sets left servo duty: -1000 - 1000
      #10 * ld0 + lduty !  ;
        
    pub M2 ( duty -- ) \ sets right servo duty: -1000 - 1000
      NEGATE #10 * rd0 + rduty !  ;
    
    pub S ( -- ) \ abruptly stops bot motion 
        0 M1  0 M2  ;
    
    pub D1 ( -- )  \ toggles left wheel direction
        lduty @ ld0 - NEGATE ld0 + lduty ! ;
    
    pub D2 ( -- )  \ toggles right wheel direction
        rduty @ rd0 - NEGATE rd0 + rduty ! ;
    
    pri rc_motors ( -- ) \ left and right servo pwm drivers
        pwmpins OUTCLR  S
        A NCO #P12 APIN  1 FRQ 0 PHSA COG!
        B NCO #P13 APIN  1 FRQ 0 PHSB COG!    
        BEGIN
          lduty @ NEGATE PHSA COG!
          rduty @ NEGATE PHSB COG!
    
          20 ms
        0 UNTIL  ;
    
    pub MSTART  ( -- ) \ executes servo drivers in a cog
        ' rc_motors TASK? RUN  50 ms  ;
    
     
          
    {
      Encoders record current total counts per wheel. 
    }
    
    #P14  2 MASKS  ==  encpins
    
    LONG lenc, renc, xl, xr
    
    pub .enc ( -- ) \ lists current  encoder counter values
        lenc @  . SPACE  renc @ . CR ;
    
    pub zenc ( -- ) \ set left and right encoder counters to 0
        0 lenc !  0 renc !  ;
    
    pri rc_enc ( -- ) \ simple encoder drivers based on basic stamp boebot program
        TRUE xl ! TRUE xr !  encpins INPUTS  zenc 
        BEGIN
          #P14 PIN@ DUP xl @ = IF DROP ELSE xl ! lenc ++  THEN
          #P15 PIN@ DUP xr @ = IF DROP ELSE xr ! renc ++  THEN
        0 UNTIL ; 
     
    pub ESTART  ( -- ) \ executes encoder drivers in a cog
         ' rc_enc TASK? RUN 50 ms ; 
    
    {
     Ping ultrasonic distance measurement (inches).
    }
    
    #1400 == p0   \ sets standard servo 0 position
    #8 == dist?   \ sets ping stop condition in inches
    
    LONG (dist), pos
    
    pub !pos  ( angle -- ) \ where angle is -90 - 90 degrees (right to left)
       #10 * p0 + #80 * pos !  ;
    
    pub dist ( -- value ) \ places current ping value (inches) on stack
        (dist) @ ;
    
    pub .dist ( -- ) \ displaces current ping value (inches)
        dist . CR  ;
    
    BYTE (stp)  \ stores stop flag
    
    pub restp ( -- ) \ resets stop flag to TRUE
        TRUE (stp) C!  ;
    
    pub stp ( -- flag ) \ places stop flag on stack
        (stp) C@  ;
    
    pri rc_ping ( -- ) \ ping driver - automatic stop condition 
       #P17 PINCLR 0 !pos
       B #P17 APIN  NCO  1 FRQ
       A 1 FRQ
       BEGIN
         #P16 PINCLR
         A #P16 APIN NCO #400 NEGATE PHSA COG!
           #1000 CTRMODE 0 PHSA COG! #P16 PININP
         pos @ NEGATE PHSB COG!
         50 ms
         PHSA COG@ #11800 / DUP (dist) !
         dist? < stp  AND IF
            FALSE (stp) C! S THEN 
       0 UNTIL  ;
      
    
    : PSTART  ( -- ) \ executes ping driver in a cog
       restp ' rc_ping TASK? RUN 50 ms ;
    
    {
      User parameters.
    }
    
    
    \ user constants - 2.625 inch wheel diameter  4.312 inch between wheels
    
       #8   ==   wcirc   \ wheel circumference in inches
     
      #64   ==   counts  \ number of counts per wheel rotation
    
       #8   ==   ctin    \ counts per inch
     
     #136   ==   rcirc  \ rotation circumfirence in 0.1 inch units
    
     #271   ==   tcirc  \ turn circumfirence in 0.1 inches
    
    pub R  ( -- )  \ hardware reset - execute START to continue
        #P9 PINCLR  ;
    
    pub START
        MSTART  ESTART  PSTART  DECIMAL ;
    
    
    
    {
    ********************************************************************************
    This completes the RCL Core.    
    
    Simple (indefinite) motion commands, which use indexed tables to select duties.
    }
    


    NickL

    Hi Nick, I must have missed a few posts there back in January, I've just come across a couple of yours including the helpful tip for the Forfiter terminal too, thanks.

    I'm wondering whether the 32 channel PWM can be adapted to RC servo control simply by introducing a 20ms frame WAITCNT after every 256 cycles and adding in a 1ms minimum pulse. That would mean the PWM module could be used for either then.

    Your coding style looks good but I noticed in your code that you are using a 0 UNTIL rather than simply saying AGAIN. Also you have a delay of 50ms after each RUN which btw does not require a coginit as it's ready and waiting for a task to execute, but I guess you might be waiting for other things to settle.

    There are also many Spin-like shortcuts like ~ and ~~ to clear and set a variable rather then 0 variable ! you would just say variable ~

    Look forward to seeing more code from you. If you like I can include you modules on the links page.
  • Peter JakackiPeter Jakacki Posts: 9,383
    edited 2014-03-11 - 17:22:53
    artkennedy wrote: »
    What I do wrong daddy?
    dmmbuf 10 DUMP
    0000_3364:   44 43 20 31  32 33 2E 34   00 75 41 00  00 00 00 00   DC 123.4.uA.....
    dmmbuf 3 + NUMBER . 0 ok
    dmmbuf 3 + PRINT$ 123.4 ok;[\code]
    
    Also what wrong with BBcode??
    
    . . . sigh . . .[/QUOTE]
    
    I thought we[URL="http://forums.parallax.com/showthread.php/141061-TACHYON-A-very-fast-and-compact-Forth-SD-file-handling-TELNET-FTP-WEB-servers?p=1244617&viewfull=1#post1244617"] answered that question a few weeks ago[/URL] but it's due to NUMBER expecting a string with a preceding count as in the case of GETWORD. However as I mentioned I may change NUMBER to handle a normal string but there is a workaround that involves copying the string to another string and inserting a count.
    
    If you click the "Go Advanced" button you can select a block of text and click the # symbol enclose it in code tags or you can do it manually but you need to use forward slash /, not back slash \.
    
    [code]some sample code
    
  • artkennedyartkennedy Posts: 164
    edited 2014-03-11 - 22:14:49
    I was going by this from the Introduction to Tachyon:
    "Typically strings are terminated with a null character which is universally accepted as a $00.
    Tachyon follows this method for terminating strings rather than the normal Forth method of preceding it with a count byte."

    But I now see from your reply and the source that is not the case for the NUMBER word:
    _NUMBER    ' ( cstr -- value digits | false )
    


    I followed the link you provided to the suggested NUMBER workaround.
    I include it here with comments I have added as I understand the way it works.
    \ 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+ $!            \ input string copied to num$ beginning at second byte
        num$ 1+ LEN$ num$ C!  \ length of string stored in first byte of num$
        num$ 1+ NUMBER        \ string submitted to NUMBER
        ;
    
    Did I get that right?


    It does not seem to work:
    FORGET num$  ok
    " 1234" #40 STRING num$  ok
    pub STR>NUM
        num$ 1+ $!
        num$ 1+ LEN$ num$ C!
        num$ 1+ NUMBER
        ;  ok
    " 399.9" STR>NUM . 4 ok
    num$ $10 DUMP
    0000_3390:   05 33 39 39  2E 39 00 20   63 74 17 B8  C7 06 74 16   .399.9. ct....t. ok
    


    Am I doing something wrong again?
    I'm working hard on this and not just firing off questions.
  • Peter JakackiPeter Jakacki Posts: 9,383
    edited 2014-03-11 - 22:30:28
    artkennedy wrote: »
    Am I doing something wrong again?
    I'm working hard on this and not just firing off questions.

    Number has to return a flag as well and this flag also happens to be the number of digits that it managed to convert, zero meaning it's not a number.
    In your case it said it had 4 digits.

    num$ 1+ NUMBER ok
    .S Data Stack (02)
    $0000.0004 - 4
    $0000.0F9F - 3999 ok

    BTW, NUMBER will be modified to handle normal strings but even the GETWORD string is still a normal null terminated string, it's just that it also happens to have the count preceding the address of the string, just as we faked with num$ 1+ NUMBER
  • artkennedyartkennedy Posts: 164
    edited 2014-03-11 - 23:36:33
    Got it. Thanks again.
    Number has to return a flag as well and this flag also happens to be the number of digits that it managed to convert, zero meaning it's not a number.
    In your case it said it had 4 digits.

    num$ 1+ NUMBER ok
    .S Data Stack (02)
    $0000.0004 - 4
    $0000.0F9F - 3999 ok

    BTW, NUMBER will be modified to handle normal strings but even the GETWORD string is still a normal null terminated string, it's just that it also happens to have the count preceding the address of the string, just as we faked with num$ 1+ NUMBER
  • D.PD.P Posts: 790
    edited 2014-03-16 - 11:19:01
    Tachyon has many ways to communicate to peripherals, what would be a good approach to modify the kernel to support Tachyon as a I2C slave device? Timmoore and Hippy have done alot of work in this area, my idea is to map the Tachyon Slave as a set of I2C Read/Write Registers into a Tachyon TABLE. This approach allows the Tachyon/Prop/Forth to just update the TABLE leaving the display to update all the graphics. One TASK for the console, one as the i2c slave to send recieve data from the TABLE/Registers, one TASK for the timmers, the rest used as the Target project requires.

    More.

    Holding the "state machine" as a series of bytes in upper eeprom allows the machine to recover from power downs into a known state. Upon reboot the state machine would be written to the TABLE, when the display reads the TABLE/REGISTERS upon its reboot it will know what to do instead the prop telling it to go to this page, clear yourself, update these widgets like this.... This logic can/should be part of these "intelligent" displays, the 4DSystem's displays are getting less expensive and more powerful all the time and with the soon to come full hd video diablo processor the 32PTUs will drop in price again.

    I've attached the pasm version of timmoore's I2C code from obex for mutual reference if any one else is interested in this idea.


    Update:
    I found this Peter, has this been done to Tachyon? Heck with I2C if so.
    I can tweak my SPI module in Tachyon Forth to handle slave mode. That way you get the speed, the interactivity, without delving into PASM.

    http://forums.parallax.com/showthread.php/144039-Propeller-as-SPI-SSP-Slave?p=1144225&viewfull=1#post1144225
  • artkennedyartkennedy Posts: 164
    edited 2014-03-16 - 23:07:13
    I was about to give and ask for help again ( gawd, makes me feel like such a beggar ) when something clicked and I went a little bit crazy. After 3 or 4 days this popped out. Voila:

    I am trying to get three serial ports working with the Propeller on this beautiful (to me) kludgey project.

    Right now the goal is to read the output of a DMM connected to AD590 temperature sensors. These sensors operate with voltage as low as 3 volts and source current at 1 microamp per degree Kelvin. My Protek 506 DMM has a range for up to 399.9 uA. Which translates to 125C or 260F - enough for direct readings without need for op amps etc. I have successfully connected this DMM to my XP Netbook and to my hp48g calculators - not yet to the Prop. Meanwhile I have written a program on an hp48 to simulate the output from the meter 'FAKEDMM' and connected at 1200 BAUD like the meter. The format is 7 bits with 2 stop bits which can be read by 8 and no stop bits by stripping the high bit from incoming data. I have written a word that receives this data and stores it in a buffer, dmmbuf.

    The meter sends data as a string with a prefix and suffix to indicate scales and type of reading. The format for the scale I want to read is "DC 399.9 uA<cr>". Next is to turn this string into a number in the Prop. I would never hook up the system with negative polarity (adding another character for the minus ) so for my purposes I could just pluck characters 4 through 8 and send the string to NUMBER, after adding a char count to the front. However, I have the crazy idea that someone else might get interested in using this in another way using a different scale with a different format and I would like to make this useful in such a case. Fortunately the scales all delimit the number with spaces. So, use the spaces to extract the number. And so began my introduction to Tachyon strings.

    I was pretty clueless at first but as I say, something finally clicked and here is what I came up with.
    This code is rather extravagantly commented. That is me trying to keep track of what I am doing.

    First this to load the buffer from the DMM:
    FORGET dmmbuf
    TABLE dmmbuf 30 ALLOT
    dmmbuf 30 0 FILL
    dmmbuf 30 DUMP
    
    #1200 SERBAUD
    
    : OUT2DMM #23 SEROUT ;
    
    : INfmDMM #22 SERIN ;
    
    : DMMIO
        ' OUT2DMM uemit W!   \  redirects I/O to OUT2DMM
        ' INfmDMM ukey W!    \  redirects I/O to INfmDMM
    ;
    
    : GETDMM         \ get reading from DMM, sends CR to trigger response, gets bytes until CR
       DMMIO                \ redirect I/O to DMM
       #13 EMIT             \ send request for data
       dmmbuf 1 -           \ init store address
       BEGIN                \ get bytes
          1 +               \    increment store address
          KEY #128 -        \    get byte, clear hi bit
          DUP 3RD           \    save copy for exit testing, pick address to top leaving a copy
          C!                \    store key
          #13 =             \    check for CR ( #141 was sent by DMM, it was converted to #13 above )
       UNTIL                \ finished
       0 SWAP C!            \ end string with a null
       CON                  \ return I/O to console
    ;
    

    Then string words to select parts of strings based on the position of characters in the strings - in this case spaces.
    : AFTER$      \  ( str ch -- str \points to portion of input string to the right of first instance of ch )
       OVER LEN$     \ ( str ch -- str ch len ) length of input string
       SWAP 3RD      \ ( str ch len -- str len ch str )
       LOCATE$ 3RD   \ ( str len chr str -- str len chptr str ) chptr-address of target ch
       - - 1-        \ ( str len chptr str -- str lenrem ) chptr - str = choffset, len - choffset - 1 = length of remainder of string
       RIGHT$        \ ( str lenrem -- rtstr ) rtstr = address of remainder of string
    ;
    
    : BEFORE$     \ ( str ch -- str \portion of input string to the left of first instance of ch )
       OVER LOCATE$   \ ( str ch -- str chptr ) find the marker char
       OVER -         \ ( str chptr -- str len ) string and len of new string
       LEFT$          \ ( str len -- str ) there is now a <null> at the former address of the space
    ;
    
    : BETWEEN$        \ ( str ch -- str \portion of input string enclosed by first two instances of ch )
       SWAP OVER      \ ( str ch -- ch str ch )  save copy of enclosing ch
       AFTER$ SWAP    \ ( ch rtstr -- rtstr ch )
       BEFORE$        \ ( rtstr ch -- btwstr ) address of target string
    ;
    

    And finally the one to make an honest number out of it. The string needed to be shifted two cells to the right for NUMBER. One for the character count byte and one for the number base prefix character. Again I wanted the work to have the potential for general use so input to the word is ( str chb -- ) with chb being "#" in this case.
    "#"
    FORGET STR>NUM
    : STR>NUM             \ ( str chb -- num ) shift string 2 cells right, append len and base flag character
       SWAP DUP LEN$      \ ( str chb -- chb str len )
       SWAP OVER          \ ( chb str len -- chb len str len )
       1+                 \ ( chb len str len -- chb len str len1+ ) expand loop counter to include <null> at end of string
       2DUP +             \ ( chb len str len1+ -- chb len str len1+ endptr ) save copy of len and str
       SWAP 0             \ ( chb len str len1+ endptr -- chb len str endptr len1+ 0 )
       DO                 \ ( chb len str endptr len1+ 0 -- chb len str endptr )
          DUP I              \ ( chb len str endptr -- chb len str endptr endptr I )
          1+ - DUP           \ increase loop counter by one then subtract - pointing to source cell, save a copy
          C@                 \ ( -- chb len str endptr source sd ) fetch contents of source cell (sd)
          SWAP 2+            \ ( chb len str endptr source sd -- chb len str endptr sd dest ) increment pointer to destination cell
          C!                 \ ( chb len str endptr sd dest -- chb len str endptr ) store
       LOOP               \ next cell
       DROP               \ ( chb len str endptr -- chb len str ) drop endptr
       SWAP 1+ OVER C!    \ ( chb len str -- chb str ) incr len, copy str, store len at str ( in vacated first position )
       SWAP OVER 1+       \ ( chb str -- str chb str1+ ) copy str, point to second cell of string
       C!                 \ ( str chb str1+ -- str ) store base flag char there
       1+ NUMBER          \ ( str -- num flag ) flag = 0 if bad else ct of num chars, num = number to base of chb
    ;
    

    I was tired but happy when I got to bed today at 3:45 AM but I have a lot to learn so if you have anything helpful to say about strategy, technique, terminology etc. just let 'er rip.

    Also I am new to forums like this so if there is a more appropriate way to present such a long utterance please point me in that direction.
  • Peter JakackiPeter Jakacki Posts: 9,383
    edited 2014-03-17 - 14:43:07
    artkennedy wrote: »
    I was about to give and ask for help again ( gawd, makes me feel like such a beggar ) when something clicked and I went a little bit crazy. After 3 or 4 days this popped out. Voila:

    <snip>

    I was tired but happy when I got to bed today at 3:45 AM but I have a lot to learn so if you have anything helpful to say about strategy, technique, terminology etc. just let 'er rip.

    Also I am new to forums like this so if there is a more appropriate way to present such a long utterance please point me in that direction.

    Glad to see you having fun, I've been a bit time poor lately and haven't had enough time to look at it but the code looks very neatly written.

    A couple of things I noticed was that you have a special routine to input a string from the DMM but if you simply define INfmDMM to strip the 8th bit then you could just use GETWORD to read in the string and COPY$ to the dmmbuf after. Also the loop in STR>NUM looks like it's begging for the use of a <CMOVE which moves a block of memory just like CMOVE does but it calculates the end addresses and works backwards so it's safe to use for moving a block up a few bytes.
    BTW, the NUMBER routine in the kernel has been fixed so it just accepts any string now without expecting a count byte.

    Your use of BEFORE$ AFTER$ BETWEEN$ makes me think that these could be more general-purpose as they work similar to LEFT$ RIGHT$ MID$ except they use a character match rather than a count. So if I rename them to say CLEFT$ CRIGHT$ CMID$ then I might add them to EXTEND if you like.

    Although you can still use the TABLE expression for arrays as such:
    TABLE dmmbuf 30 ALLOT
    dmmbuf 30 0 FILL
    This has been upgraded to:
    30 BYTES dmmbuf
    which also initializes the array to zeros. There are also the corresponding WORDS and LONGS you can use to create an array whereas the TABLE word is good for building a table of constants.

    That's more than I had time for at the moment but well done, I will find some more time later.






Sign In or Register to comment.