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 26 — Parallax Forums

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

12324262829109

Comments

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2013-07-09 01:36
    Iamretired wrote: »
    Everyone has been very helpful, but I am still left with the same questions.
    Given the stack contents after a reset (an initial condition) and after loading stack with 12 11 10 .....3 2 1 , why the unexpected result?

    I have a problem understanding the Data Stack. The Introduction to TACHYON FORTH has a table that seems to say the stack is limited to 12 elements;
    At initial startup I get
    ^D DEBUG
    DATA STACK
    01A6: 000001A6 00000004
    01A8: FFFFF9FF 00000000 00000000 00000000
    01AC: 00000000 00000000 00000000 00000000
    01B0: 00000000 00000000
    What is FFFFF9FF at address 01A8?

    I put on the stack 12 11 ........ 2 1 and did a ^D DEBUG.
    12 11 10 9 8 7 6 5 4 3 2 1 ok
    ^D DEBUG
    DATA STACK
    01A6: 000001A6 00000004
    01A8: 00000001 00000002 00000003 00000004
    01AC: 00000005 00000005 00000005 00000005
    01B0: 00000005 00000005
    I don't fully understand what I see. The 12 elements are evident and the first column appear to be addresses with the first element containing its own address. I don't know why 01A7 contains 00000004 or why my TOS is 01A8, and 01AC to 01B1 contains 00000005 ( where is 00000006 and 7 thru 12? ) .

    I am not questioning why it was designed this way. I want to know if there is a bug causing my unexpected result or as the questions above indicate 'what can I infer from the DEBUG listing?

    Thank you,
    Johnmb


    I think D.P. did well by way of reply and what he says is correct. Sometimes one can get so focused on some perceived eccentricity which is not a bad thing in itself but if that same energy were instead utilized in the direction you want to go in then you would certainly progress despite these eccentricities and anomalies. The difference is that energy is being expended on the study of the implementation of the platform rather than on implementing onto that platform. The first one will get you steamed up whereas the second approach will get the steam up (D.P.’s project)

    However I will provide an answer to your question although it is academic and has no real bearing on development itself.

    The stack is 12 longs deep and you push 12 numbers onto it:
    12 11 10 9 8 7 6 5 4 3 2 1 ok

    Then type a ^D for DEBUG (BTW, your stack address indicates you have a slightly earlier version of Tachyon)

    DATA STACK
    01A8: 000001A8 00000001 00000002 00000003
    01AC: 00000004 00000005 00000006 00000006
    01B0: 00000006 00000006 00000006 00000006

    Just to check the stack manually we could also print each item out:
    12 11 10 9 8 7 6 5 4 3 2 1 ok
    . 1 ok
    . 2 ok
    . 3 ok
    . 4 ok
    . 5 ok
    . 6 ok
    . 6 ok
    . 6 ok
    . 6 ok
    . 6 ok
    . 6 ok
    . 6 ok

    Notice the difference immediately as the 01A8 (sames as the TOS address) only exists in the DEBUG version and you will find that this is DEBUG itself using the same stack that you are trying to test, you need to take this into consideration. However the second version also shows that the stack must have had up to six levels of parameters pushed onto it forcing the 12 11 10 9 8 7 to “fall off” and then afterwards as the stack is progressively popped again while the bottom most item 6 is simply copied but not written (from where?). So at some point the same stack was being used and looked a bit like this:
    (TOP OF STACK)
    temp working value
    temp working value
    temp working value
    temp working value
    temp working value
    temp working value
    1
    2
    3
    4
    5
    6
    (BOTTOM OF STACK)

    12 to 7 were simply overwritten one by one on the bottom of the stack as more items were added.
    After a pop it would look like this:
    (TOP OF STACK)
    temp working value
    temp working value
    temp working value
    temp working value
    temp working value
    1
    2
    3
    4
    5
    6
    6 ← the bottom value does not get changed during a pop
    (BOTTOM OF STACK)

    Then by the end we end up with what we did.

    Have you ever tried to test your multimeter by getting it to measure it’s own battery? Well it won’t work the way you expect for very good reason but that does not mean the meter is faulty, just your reasoning.

    BTW, My very first version of Tachyon had DEBUG and all the hex dump stuff written in PASM to help debug the nascent kernel and so DEBUG would not consume any stack resources as it used it’s own cog registers (and cog memory for code) and so you would see the stack just as it really was. But once the kernel started to grow the debug routines were hogging precious cog resources that were required for....you know...actual runtime operations. There would be no problem with a Forth written on an ARM processor having a really deep stack and a non-intrusive DEBUG but that’s another kettle of fish, well actually only one fish whereas the Prop is a kettle of fish.

    So as D.P. says don’t get stuck on the details of the crumbs, just start using it as it is meant to be used.

  • IamretiredIamretired Posts: 56
    edited 2013-07-09 11:58
    I greatly appreciate the comments from D.P. and Peter: I understand them. I first saw what I thought was an anomaly while examining the stack using .S and .. Thank you for you patience, comments and advice.

    John
  • Brian RileyBrian Riley Posts: 626
    edited 2013-07-10 12:28
    I was working today on some 1-Wire stuff. It turned out that I had several unused pins and life would be simpler with two different 1W busses ... so I put my new found knowledge from the other day to work and came up with these mods to the 1-Wire I/O Defs. They work perfectly and required no changes to anything else.

    ... Peter ... are there any hidden land mines in what I've done here????
    ( I/O DEFINITIONS )
    
    { OLD CODE
    LONG dq
    pri DQ@                dq @ ;
    pub DQ!                dq ! ;
    #P16 |< DQ!                        \ set the default
    }
    
    \ ----- I/O Defs & redirection words (new code) -----
    
    #P16 |< CONSTANT DQ		\ set default 
    
    pri DQ@	( -- )			' DQ 1+ @ ;
    pub DQ!	( 1wpin -- )	MASK ' DQ 1+ ! ;
    
    : @1W_ID	( -- )	#P16 DQ! ;
    : @1W_TEMP	( -- )	#P17 DQ! ;
    
    \ ---------------------------------------
    
    
  • MJBMJB Posts: 1,235
    edited 2013-07-10 14:19
    ( I/O DEFINITIONS )
    
    { OLD CODE
    LONG dq
    pri DQ@                dq @ ;
    pub DQ!                dq ! ;
    #P16 |< DQ!                        \ set the default
    }
    
    \ ----- I/O Defs & redirection words (new code) -----
    
    #P16 |< CONSTANT DQ        \ set default 
    
    pri DQ@    ( -- )            ' DQ 1+ @ ;
    pub DQ!    ( 1wpin -- )    MASK ' DQ 1+ ! ;
    
    : @1W_ID    ( -- )    #P16 DQ! ;
    : @1W_TEMP    ( -- )    #P17 DQ! ;
    
    \ ---------------------------------------
    
    
    hi Brian,
    where do you see the benefit of using CONSTANT vs. the following?
    ( I/O DEFINITIONS )
    LONG dq
    pri DQ@   ( -- 1wmask )            dq @ ;
    pub DQ!    ( 1wpin -- )    MASK   dq ! ;
    #P16  DQ!                        \ set the default
    
    : @1W_ID          ( -- )   #P16 DQ! ;
    : @1W_TEMP    ( -- )   #P17 DQ! ;
    
    \ ---------------------------------------
    
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2013-07-10 18:10
    I was working today on some 1-Wire stuff. It turned out that I had several unused pins and life would be simpler with two different 1W busses ... so I put my new found knowledge from the other day to work and came up with these mods to the 1-Wire I/O Defs. They work perfectly and required no changes to anything else.

    ... Peter ... are there any hidden land mines in what I've done here????
    ( I/O DEFINITIONS )
    
    { OLD CODE
    LONG dq
    pri DQ@                dq @ ;
    pub DQ!                dq ! ;
    #P16 |< DQ!                        \ set the default
    }
    
    \ ----- I/O Defs & redirection words (new code) -----
    
    #P16 |< CONSTANT DQ        \ set default 
    
    pri DQ@    ( -- )            ' DQ 1+ @ ;
    pub DQ!    ( 1wpin -- )    MASK ' DQ 1+ ! ;
    
    : @1W_ID    ( -- )    #P16 DQ! ;
    : @1W_TEMP    ( -- )    #P17 DQ! ;
    
    \ ---------------------------------------
    
    

    One of the reasons I used constants in place of variables is that without redirection we just use constants in the first place and they are much more readable both in the pin definition and in their reference. So therefore it made sense to use rewritable constants to make it clear what was happening and what the default pins were. Alternate pins should also be defined as constants for readability too and the constant name used in the redefinition function. Of course in some applications I just use an encoded long to specify up to 4 pins and any constant definitions would be redundant but that doesn't mean you can't include them, at least as comments in your code.

    So Brian you obviously missed the point of using constants as you have this defintion:
    [FONT=courier new]pri DQ@    ( -- )            ' DQ 1+ @ ;[/FONT]
    
    Now the constant DQ if you run it will return the value of the constant whereas DQ@ tries to manually manipulate the constant and just ends up with what DQ if run would do anyway. So DQ@ is absolutely redundant and you only need to say DQ. Also to add to the confusion you were probably better off leaving it the way you had it although I would still recommend defining the pins as constants first simply for readability: However following faithfully using the constant method this is what I would do:
    [FONT=courier new]\ ----- I/O Defs & redirection words (new code) -----
    
    #P16 |< == DQID    
    #P17 |< == DQTEMP
    
    pub @1W_TEMP    ( -- )    DQTEMP ( falls through to DQ! )
    [/FONT][FONT=courier new]pub DQ!    ( 1wmask -- )    ' DQ 1+ ! ;[/FONT][FONT=courier new]
    pub @1W_ID    ( -- )    DQID DQ! ;
    [/FONT]
    
  • D.PD.P Posts: 790
    edited 2013-07-10 21:08
    I have a word that uses SEROUT and one that uses SERINW ( a routine I made with SERIN using WAITLOW instead of WAITPNE) to update and query an LCD serial device.

    When I try to launch SDMSG (using SEROUT) in a task and all it does it run once and complete (no loops) my system becomes unstable and I loose comms to the serial device.

    What are the "rules" using SEROUT in another TASK if any. I have modified the SDMSG to first set #9600 SERBAUD reading that separate cogs can have separate SERBAUD settings.

    The words run just dandy from the console cog, in loops, keypoll etc.

    Maybe I'm not understanding how variables, constants et al are scoped in Tachyon.


    Seems I'm corrupting more than I realize, time to look at the code again.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2013-07-10 21:34
    D.P wrote: »
    I have a word that uses SEROUT and one that uses SERINW ( a routine I made with SERIN using WAITLOW instead of WAITPNE) to update and query an LCD serial device.

    When I try to launch SDMSG (using SEROUT) in a task and all it does it run once and complete (no loops) my system becomes unstable and I loose comms to the serial device.

    What are the "rules" using SEROUT in another TASK if any. I have modified the SDMSG to first set #9600 SERBAUD reading that separate cogs can have separate SERBAUD settings.

    The words run just dandy from the console cog, in loops, keypoll etc.

    Maybe I'm not understanding how variables, constants et al are scoped in Tachyon.


    Seems I'm corrupting more than I realize, time to look at the code again.

    The trouble with SEROUT is that it's just a very basic function that's handy but could do with a tiny bit of tweaking to make it work with multiple instances. The on offender is "baudcnt" which is effectively a global variable even though it isn't. It's possible just to copy&paste a new version with it's own variable or if you give your cog it's own set of task registers and then baudcnt will be independant from the other cogs. Just allocate an area of memory for this and pass the address to that cog (from within the task). Here are two comments from the source codes
    ' Task registers can be switched easily by setting "regptr" ( 7 COGREG! )

    \ baudcnt is a task register so each cog can have it's own baudrate (if used)

    So do this:
    TABLE task1 #32 ALLOT
    then from within your task startup code do this:
    task1 7 COGREG!
    XXXX SERBAUD

    So try this and see how it goes. Of course I could add a word called TASKREGS which just does the same as 7 COGREG! but I will look at any improvements I can make.

    BTW, I'm scratching my head wondering why you need to input from a serial LCD? These are always output devices and the only requirement for reading back that I have when I design them is because of a keypad or something other than the display itself.
  • MJBMJB Posts: 1,235
    edited 2013-07-11 02:43
    what I would do:
    [FONT=courier new]\ ----- I/O Defs & redirection words (new code) -----
    
    #P16 |< == DQID    
    #P17 |< == DQTEMP
    
    pub @1W_TEMP    ( -- )    DQTEMP ( falls through to DQ! )
    [/FONT][FONT=courier new]pub DQ!    ( 1wmask -- )    ' DQ 1+ ! ;[/FONT][FONT=courier new]
    pub @1W_ID    ( -- )    DQID DQ! ;
    [/FONT]
    
    Peter, to make it really clear DQ needs to be defined as a const as well
    [FONT=courier new]\ ----- I/O Defs & redirection words (new code) -----
    
    #P16 |< == DQID    
    #P17 |< == DQTEMP
    [/FONT]
    [FONT=courier new][B][COLOR=#020FC0]DQID  == DQ  \ define the DQ const and set default value[/COLOR][/B]
    [/FONT][FONT=courier new]
    pub @1W_TEMP    ( -- )    DQTEMP ( falls through to DQ! )
    [/FONT][FONT=courier new]pub DQ!    ( 1wmask -- )    ' DQ 1+ ! ;[/FONT][FONT=courier new]
    pub @1W_ID    ( -- )    DQID DQ! ;[/FONT]
    
    \ now DQ can be used in the code just like a normal constant
    \ and it can be reassigned with DQ! to whatever you want, even other consts
  • MJBMJB Posts: 1,235
    edited 2013-07-11 02:53
    here my work in progress
    https://docs.google.com/document/d/1HHymqkUEEFFATqiF4GXQnR2If_3Yd_lw03UVOJczcgM/edit
    still some weeks until the modules arrive.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2013-07-11 05:17
    MJB wrote: »
    here my work in progress
    https://docs.google.com/document/d/1HHymqkUEEFFATqiF4GXQnR2If_3Yd_lw03UVOJczcgM/edit
    still some weeks until the modules arrive.

    I will see what I can do in the meantime as I do have boards that will accept the 24L01 modules directly. I noticed that you started to use the stack to pass multiple parameters to writecmd and although this would work I see you chose this because the manual buffer write method looked clumsy, which it was. How about this method instead:
    [FONT=courier new][COLOR=#000000]BYTE ix[/COLOR]
    [/FONT]
    [FONT=courier new][COLOR=#000000]pub !! ( data -- ) \ add data to buffer[/COLOR][/FONT]
    
    [FONT=courier new][COLOR=#000000]    ix C@ data24 + C![/COLOR][/FONT]
    [FONT=courier new][COLOR=#000000]    ix C++[/COLOR][/FONT]
    [FONT=courier new][COLOR=#000000]    ;[/COLOR][/FONT]
    [FONT=courier new][COLOR=#000000]pub Setup_rx ( )[/COLOR][/FONT]
    
    [FONT=courier new][COLOR=#000000]\    buffer variant[/COLOR][/FONT]
    [FONT=courier new][COLOR=#000000]    ix C~             \ reset buffer index[/COLOR][/FONT]
    [FONT=courier new][COLOR=#000000]    $34 !! $43 !! $10 !! $10 !! $01 !![/COLOR][/FONT]
    [FONT=courier new][COLOR=#000000]    5 Write_reg  Rx_addr_p0 OR WriteCmd24 [/COLOR][COLOR=#000000][B] [/B][/COLOR][COLOR=#000000]( cnt cmd )[/COLOR][/FONT]
    
    
    As you can see the stack usage is kept to a minimum and it's also possible to further improve this so that you could pass a long instead of 4 bytes etc. Since the data packing
    routine would need to know the count then it automatically also knows when to stop and send the command as well. In which case we only need a combo WriteDat an WriteCmd that would be invoked like this:
    $10104334 $01 5 Write_reg Rx_addr_p0 OR WriteDatCmd24
    The Rx_addr_p0 style always looks very verbose and although German has a tendency toward very long concatenated names it seems to clutter the code. How about something as simple as nonunderscored names and simply rely on camelcase like this: RxAddr0
    You can also use + instead of OR which further increases readability (IMO). Going a bit further and redefine Write24 this is probably how I would make it look:
    $10104334 $01 5 Rwr RxAddr0 + Write24
  • MJBMJB Posts: 1,235
    edited 2013-07-11 12:46
    @Peter
    Interesting how much effort you are spending - in thought and in implementation - to keep the stack use low.
    My approach is getting it to run as soon as possible and then see, where is need for improvement and optimization.
    But maybe it is your experience with Forth and Tachyon and your coding speed that let you do the additional effort
    while I am still thinking along ...

    pushing 5 values on the stack and then immediately sending them out didn't appear a big deal to me.
    So you think using 5 stack elements here will cause trouble later?
    I was also thinking the stack variant would be much faster.
    Just pushing the values into the COG and sending them out from there without HUB memory access.

    When I see your last code line it is not immediately clear to me what the bytes mean.
    is it bytes 4..1 and then byte 5 - or do we better 1..4 5 ?
    without some extensive comments it is not easily visible what byte means what.
    Whereas my approach was very straight forward, just push 5 .. 1 on the stack and then in a tiny loop
    write them to SPI 1 .. 5 with RUNMOD where they get automatic and 'free' pops.

    on the + vs. OR I agree it is visually more distinct to have the +,
    but from a logic way to me an OR indicates a bitwise combination, whereas + implies s.th. different,
    even when given the correct arguments as here the outcome is the same.
    so this 'readability' is a matter of personal style.

    nevertheless, thanks very much for your input.
    it is of very great value to me and surely to others following as well
    Markus
  • MJBMJB Posts: 1,235
    edited 2013-07-11 14:20
    reconsidering the line:
    $01 $10 $10 $43 $34 5 Write_reg Rx_addr_p0 OR WriteCmd24S
    
    this uses 8 stack entries ...
    and we have a max of 12 ....
    this can be critical very soon ..

    so I consider
    $34 $43101001 5 Write_reg Rx_addr_p0 OR WriteCmd24S
    $34 1 Write_reg Rx_addr_p0 OR WriteCmd24S
    
    
    with the bytes right justified in 2 longs.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2013-07-11 15:25
    MJB wrote: »
    @Peter
    Interesting how much effort you are spending - in thought and in implementation - to keep the stack use low.
    My approach is getting it to run as soon as possible and then see, where is need for improvement and optimization.
    But maybe it is your experience with Forth and Tachyon and your coding speed that let you do the additional effort
    while I am still thinking along ...

    pushing 5 values on the stack and then immediately sending them out didn't appear a big deal to me.
    So you think using 5 stack elements here will cause trouble later?
    I was also thinking the stack variant would be much faster.
    Just pushing the values into the COG and sending them out from there without HUB memory access.

    When I see your last code line it is not immediately clear to me what the bytes mean.
    is it bytes 4..1 and then byte 5 - or do we better 1..4 5 ?
    without some extensive comments it is not easily visible what byte means what.
    Whereas my approach was very straight forward, just push 5 .. 1 on the stack and then in a tiny loop
    write them to SPI 1 .. 5 with RUNMOD where they get automatic and 'free' pops.

    on the + vs. OR I agree it is visually more distinct to have the +,
    but from a logic way to me an OR indicates a bitwise combination, whereas + implies s.th. different,
    even when given the correct arguments as here the outcome is the same.
    so this 'readability' is a matter of personal style.

    nevertheless, thanks very much for your input.
    it is of very great value to me and surely to others following as well
    Markus

    The stack approach was using 7 items (5 data + count + command) on a stack that's only 12 deep and that alarmed me because this is a lower layer of an application that is going to have have many items on the stack? Plus the actual WriteCmd24S needs stack space too before it even touches the parameters that have been passed.

    As for + vs OR as I mentioned it's about readability and it is perfectly correct to add bit fields such as b7 + b5 + b1 + b0 and it's perfectly understandable too.

    If bytes are packed into longs it's good to treat the long as a little-endian array, the LSB is the first byte.


    EDIT: just picked up on your last post
  • MJBMJB Posts: 1,235
    edited 2013-07-11 15:45
    If bytes are packed into longs it's good to treat the long as a little-endian array, the LSB is the first byte.
    first byte - would mean the first byte sent via SPI? so we can loop upwards ?
    the nRF24L01 expects the LSByte first with bit MSBit first.

    would it make sense to arrange the bytes in a way so
    ESPIO could be used 32bits and then 8bits? for the 5 bytes
    or would 5 times ESPIO RUNMOD be comparable in speed?
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2013-07-11 21:49
    MJB wrote: »
    first byte - would mean the first byte sent via SPI? so we can loop upwards ?
    the nRF24L01 expects the LSByte first with bit MSBit first.

    would it make sense to arrange the bytes in a way so
    ESPIO could be used 32bits and then 8bits? for the 5 bytes
    or would 5 times ESPIO RUNMOD be comparable in speed?
    There's no great advantage in speed but it can be done and if we did then the long would be byte packed big-endian style as you mentioned. What Tachyon needs is a string and byte string operation where you could pass multiple bytes as a string in suitable notation such as: $" 3443101001" and the address of the counted string would be stored on the stack. I will look into this with some interest as that seems the best way of handling a long length of parameters. Normally I prefer null terminated strings but binary strings would have to have a count which I might make compatible with null terminated strings by storing the count at stringaddress-1 and still null terminate anyway. Then I could have an SPI function for TxString, now wouldn't that be good? Bundle that into WriteStr24 ( str cmd -- ):

    $" 3443101001" Rwr RxAddr0 + WriteStr24
  • D.PD.P Posts: 790
    edited 2013-07-11 22:39
    The trouble with SEROUT is that it's just a very basic function that's handy but could do with a tiny bit of tweaking to make it work with multiple instances. The on offender is "baudcnt" which is effectively a global variable even though it isn't. It's possible just to copy&paste a new version with it's own variable or if you give your cog it's own set of task registers and then baudcnt will be independant from the other cogs. Just allocate an area of memory for this and pass the address to that cog (from within the task). Here are two comments from the source codes
    ' Task registers can be switched easily by setting "regptr" ( 7 COGREG! )

    \ baudcnt is a task register so each cog can have it's own baudrate (if used)

    So do this:
    TABLE task1 #32 ALLOT
    then from within your task startup code do this:
    task1 7 COGREG!
    XXXX SERBAUD

    So try this and see how it goes. Of course I could add a word called TASKREGS which just does the same as 7 COGREG! but I will look at any improvements I can make.

    BTW, I'm scratching my head wondering why you need to input from a serial LCD? These are always output devices and the only requirement for reading back that I have when I design them is because of a keypad or something other than the display itself.

    The device in question is a 4DSystems LCD32-PTU touch screen running async TTL serial, read it for touch input/messages, write to it to update the graphics/send commands.

    The above worked correctly. Could you explain the issues of using modules such as the PFC RTC library in other tasks, seems I'm still steeping on myself trying to read from the RTC in a separate TASK.

    Here are the very un-optimized routines I use to read and write to this display with lots of debug info still in place. And a few test words to see how to write to the controls.
    pub SERINW ( pin -- data )
            MASK DUP INPUTS DUP
            #200000 SWAP WAITLOW  0 > IF              \ 15 ms delay
              baudcnt @ 2/ DELTA
              baudcnt @ DELTA                        \ delay to sample 1 bit later in 1st data bit
                0 8 FOR SHRINP WAITCNT NEXT
              NIP #24 SHR                            \ right justify 8-bit data
          \    DUP CR .                    \ got data
            THEN
    ;
    
    pub RD_MSG
      0 flag !
      #ptx SERINW
      1+ ?DUP  IF            \ add one to return value from serinw dup if not zero now we need to remove the 1 to get
        1-                   \    original return value back
        DUP
        mcmd C!              \ store 1st byte in mcmd byte
        #rp_evt = IF         \ is this byte = to our Report Object evt?
          #ptx SERIN         \ next byte 2 bytes for object
          mobjh C!           \ move into mobjh MSB
          #ptx SERIN         \ next byte
          mobjl C!           \ move byte into mobjl LSB
          #ptx SERIN         \ next byte 2 bytes for value
          mvalh C!           \ move into mval MSB
          #ptx SERIN         \ next byte
          mvall C!           \ move into mval LSB
          #ptx SERIN
          mchks C!
          mcmd C@ mobjh C@ XOR mobjl C@ XOR
          mvalh C@ XOR mvall C@ XOR
          mchks C@ = IF
           CR CR ." Good Data "
             -1 flag !         \ got good data set flag true
          THEN
          mobjh C@ 8 SHL mobjl C@ OR mobj W!
          CR ." chks:  " mchks C@ .
          CR ." mcmd: " mcmd C@ .
          CR ." obj: H: " mobjh C@ . ."   L: " mobjl C@ .
          CR ." val: H: " mvalh C@ . ."   L: " mvall C@ .
        THEN
      THEN
    
    
    : SDMSG ( val obj -- ack/nak )
    
        #wr_obj mchksum !
        #wr_obj #prx SEROUT     \ send write obj cmd
        W>B                     \ move obj into 2 byte msb top of stack
        DUP mchksum @ XOR mchksum !       \ add byte to checksum
        SWAP
        DUP mchksum @ XOR mchksum !       \ add other byte to checksum
        SWAP                    \ align bytes again in proper order
        #prx SEROUT             \ send first byte
        NOP
        #prx SEROUT             \ send second byte
        NOP
        W>B                     \ move val into 2 bytes
        DUP mchksum @ XOR mchksum !       \ add byte to checksum
        SWAP
        DUP mchksum @ XOR mchksum !       \ add byte to checksum
        SWAP                    \ align bytes again in proper order
        #prx SEROUT             \ send msb of val
        NOP
        #prx SEROUT             \ send lsb of val
    
        mchksum @ #prx SEROUT   \ send checksum
    ;
    
    : RST
      $0000 $0400 SDMSG  \ GRN SLIDER
      $0000 $0401 SDMSG  \ RED
      $0000 $0800 SDMSG  \ PSI
      $0000 $1200 SDMSG  \ THERM
      $0000 $0F00 SDMSG  \ HOURS MINS
      $0000 $0F01 SDMSG  \ SECS
    ;
    : FUL
      $00FF $0400 SDMSG  \ GRN SLIDER
      $00FF $0401 SDMSG  \ RED
      $0023 $0800 SDMSG  \ PSI
      $0078 $1200 SDMSG  \ THERM
      $0937 $0F00 SDMSG  \ HOURS MINS
      $003B $0F01 SDMSG  \ SECS
    ;
    
    : GA #ptx SERINW ;
    
    : TL
      $003B $0F01 SDMSG   \ SET SECONDS:  59
      $0423 $0F00 SDMSG   \ SET HOURS MINUTES: 1059
      $0011 $0800 SDMSG   \ SET PSI GUAGE: 17 0-35
      $0061 $1200 SDMSG   \ SET THERM: 180,  0-120 = 120-240
      $00A0 $0400 SDMSG   \ SET GRN SLIDER: 160  0-255
      $0050 $0401 SDMSG   \ SET GRN SLIDER: 80  0-255
    ;
    
    : RSTLCD #P21 PINCLR 10 us #P21 PINSET ;
    
    
  • MJBMJB Posts: 1,235
    edited 2013-07-12 02:23
    What Tachyon needs is a string and byte string operation where you could pass multiple bytes as a string in suitable notation such as: $" 3443101001" and the address of the counted string would be stored on the stack. I will look into this with some interest as that seems the best way of handling a long length of parameters. Normally I prefer null terminated strings but binary strings would have to have a count which I might make compatible with null terminated strings by storing the count at stringaddress-1 and still null terminate anyway. Then I could have an SPI function for TxString, now wouldn't that be good? Bundle that into WriteStr24 ( str cmd -- ):

    $" 3443101001" Rwr RxAddr0 + WriteStr24

    like this

    AND since we not only want to write predefined constant bytestrings we need some ByteString manipulation words as well.
    STRING name n     \ allocates a string with n bytes, ALLOC is done internally, not after, since we want to store the allocated length
    
    if string length in byte stringaddress-1 is 0 then treat as null terminated
    if string length in byte stringaddress-1 is >0 then treat as binary string of this size
    maybe we let the programmer decide how to use instead of forcing s.th.

    access is straight forward
    name x + C@ 
    byte name x + C!
    
    or
    : "! ( byte stringName index -- ) + C! ;
    : "@ ( stringName index -- byte ) + C@ ;
    byte name x "!
    name x "@ 
    
    Manually update length:
    newlen  name 1- C!
    

    of course we can search the string for a first 0 to match with null terminated,
    but this would not really be needed, since writing a 0 len field would imply this.
    Now the user can decide how to use the string functions.
    see stringFunctions.fth ;-)

    unfortunately the allocated length is not accessible easily.
    From the dictionary we can find the next word address,
    but maybe we could store the allocated length in
    alloclen  name 2- C!
    

    this would allow for 255 byte strings - big enough for a micro

    ... and now we are back to the original question accumulating bytes to a buffer
    so now the string is the buffer, and it's length field is the buffer fill counter
    after creation this is 0

    we define a "!++ which stores and increments count ... and leaves the string address in the stack,
    like the C@++
    : "!++ ( stringAddress byte -- stringAddress ) ... ;
    
    myString $34 "!++ $43 "!++ ...   DROP
    

    kind of ...
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2013-07-12 05:18
    Yes, and I was thinking about the allocation size as well, so strings could also simply be buffers or memory arrays where we have more than 255 bytes which would make it much more versatile, why not?
    SIZE[2] LEN[2] STRING NULL
    The null is redundant for binary strings but useful for text strings. The address that is passed is the address of the string which is also long aligned to allow for word and long elements. So the length is the word just before the string address and the allocated size is just before that. It's basically up to user code to interpret the string the way it wants but I will see if we need to do more but for the moment KISS.
  • bmentinkbmentink Posts: 107
    edited 2013-07-13 18:40
    Hi Peter and all,

    I have not been on this forum for awhile, but was tempted back when I noticed your excellent Forth for the Prop. (.. by the way, I am the author of GraspForth ..)

    I am trying to get started on my Linux box and am having a couple of issues.
    I did get BST going so I have a IDE that will compile SPIN for Linux ..... well it appears to at least.
    As instructed I copy/pasted the code from the web page (deleting 1st and last lines) and it compiles ok and installs on the Prop.
    I launch cKermit at 230400 and I get the "ok" Forth prompt ok, but have the following issues ..

    1. The Forth word "WORDS" does not exist, however I can put stuff on the stack and print them off ok ... so that is working.
    2. Backspace does the wrong thing but ^H works ... guess that is a kermit thing. So I next tried minicom as you suggest, set it to the correct baud rate 230400, but I do not get the "ok" prompt.
    I think characters are getting to the Prop as the blue light blinks when I press a key. I tried different baud rates to no avail.
    3. Copy/paste of forth code to the kermit console causes a garbled mess and a hung Forth. Really must get miniterm working ..

    Peter do you have a miniterm config file posted somewhere that has all the parameters set correctly ... especially for 3M baud rate?

    I look forward to playing with this and contributing where I can ...

    Cheers,
    Bernie
  • D.PD.P Posts: 790
    edited 2013-07-13 18:44
    pri RDRTC ( -- )
    
            0 @RTC
    
            I2CSTART $A3 I2C!
    
            0 #16 ADO 0 I2C@ I rtcmasks + C@ AND I rtc + C! LOOP 1 I2C@ DROP
    
            I2CSTOP
    ;
    

    This WORD is part of the PCF8563RTC module.
    I can use the below WORD just fine in a separate task
    pri WRRTC ( -- ) \ Write the rtc buffer to the RTC chip
    
            0 0 RTC!
    
            0 @RTC rtc #16 ADO I C@ I2C! LOOP I2CSTOP
    ;
    
     \ as in this word 
    
    pub 1khz  ( -- )  \ set clockout to 1khz
    
            $81 $0D RTC!  WRRTC
    ;
    

    Stumped, I've got the LCD, ADC reads and RTC writes all working fine from the separate task, just when I call the RDRTC WORD I loose stability?
  • D.PD.P Posts: 790
    edited 2013-07-13 18:55
    bmentink wrote: »
    Hi Peter and all,

    I have not been on this forum for awhile, but was tempted back when I noticed your excellent Forth for the Prop. (.. by the way, I am the author of GraspForth ..)

    I am trying to get started on my Linux box and am having a couple of issues.
    I did get BST going so I have a IDE that will compile SPIN for Linux ..... well it appears to at least.
    As instructed I copy/pasted the code from the web page (deleting 1st and last lines) and it compiles ok and installs on the Prop.
    I launch cKermit at 230400 and I get the "ok" Forth prompt ok, but have the following issues ..

    1. The Forth word "WORDS" does not exist, however I can put stuff on the stack and print them off ok ... so that is working.
    2. Backspace does the wrong thing but ^H works ... guess that is a kermit thing. So I next tried minicom as you suggest, set it to the correct baud rate 230400, but I do not get the "ok" prompt.
    I think characters are getting to the Prop as the blue light blinks when I press a key. I tried different baud rates to no avail.
    3. Copy/paste of forth code to the kermit console causes a garbled mess and a hung Forth. Really must get miniterm working ..

    Peter do you have a miniterm config file posted somewhere that has all the parameters set correctly ... especially for 3M baud rate?

    I look forward to playing with this and contributing where I can ...

    Cheers,
    Bernie

    You need to get EXTEND.fth and paste this into the terminal, make sure you set a little Line delay (4ms) and you may need t set a 1ms per char delay worst case.

    The WORDS you are looking for are in EXTEND.fth, and a whole bunch more, welcome back.

    Extend.fth https://docs.google.com/document/pub?id=19t8NRAKQOdUNgcCKb6D3jGS3Y41l2IIxCUVjmWXqSCU
  • bmentinkbmentink Posts: 107
    edited 2013-07-13 19:08
    Thanks D.P ..

    Yes, finally got minicom working ... needed to reset the Prop for some reason.
    I was following the "Getting started guide" and it stated that WORDS was in the kernel code ... hence the confusion. On further investigation I did notice that it was commented out of the kernel for some reason.
    Anyway I am up and running now .. thanks.

    Do you know how to make the line delays stick in minicom? I save my configuration but next boot the line delays are gone ..

    Cheers,
    Bernie
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2013-07-13 19:34
    bmentink wrote: »
    Thanks D.P ..

    Yes, finally got minicom working ... needed to reset the Prop for some reason.
    I was following the "Getting started guide" and it stated that WORDS was in the kernel code ... hence the confusion. On further investigation I did notice that it was commented out of the kernel for some reason.
    Anyway I am up and running now .. thanks.

    Do you know how to make the line delays stick in minicom? I save my configuration but next boot the line delays are gone ..

    Cheers,
    Bernie

    You have to make sure that the user is part of the serial/dialout etc groups otherwise you are stuck with invoking minicom with "minicom -s" setup each time. If you did happen to run minicom with -s then you obviously do not have permissions and any setup you save won't work. Once you have enabled permissions then you can save your minicom config as USB0 and then simply invoke "minicom USB0" next time. I find that I need around 10 to 12 ms line delay but never any character delay. Turn off hardware and software handshakes. I will look at providing a simple minicom guide shortly.

    BTW, "WORDS" was part of the kernel earlier but it is easier to write and enhance these higher level functions as pure Forth source code which is why it's moved to EXTEND.fth. There are probably a lot of things in EXTEND.fth that aren't totally necessary but then again they don't take up a lot of room either so just consider this file as a necessary part of the kernel which compiled by the PC compiled kernel.
  • D.PD.P Posts: 790
    edited 2013-07-13 19:37
    bmentink wrote: »
    Thanks D.P ..

    Yes, finally got minicom working ... needed to reset the Prop for some reason.
    I was following the "Getting started guide" and it stated that WORDS was in the kernel code ... hence the confusion. On further investigation I did notice that it was commented out of the kernel for some reason.
    Anyway I am up and running now .. thanks.

    Do you know how to make the line delays stick in minicom? I save my configuration but next boot the line delays are gone ..

    Cheers,
    Bernie

    I'm on Mac OSX and I can't get the delays to stick either! I've tried the usual stuff just no luck, let me know if you figure it out.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2013-07-13 19:38
    You have to make sure that the user is part of the serial/dialout etc groups otherwise you are stuck with invoking minicom with "minicom -s" setup each time. If you did happen to run minicom with -s then you obviously do not have permissions and any setup you save won't work. Once you have enabled permissions then you can save your minicom config as USB0 and then simply invoke "minicom USB0" next time. I find that I need around 10 to 12 ms line delay but never any character delay. Turn off hardware and software handshakes. I will look at providing a simple minicom guide shortly.

    BTW, "WORDS" was part of the kernel earlier but it is easier to write and enhance these higher level functions as pure Forth source code which is why it's moved to EXTEND.fth. There are probably a lot of things in EXTEND.fth that aren't totally necessary but then again they don't take up a lot of room either so just consider this file as a necessary part of the kernel which compiled by the PC compiled kernel.

    P.S. I was so busy answering your query that I forgot my manners so welcome back to the Prop forum Bernie and especially the Tachyon thread :)
    BTW, I wrote IVOS for the ARM7 which I entered into the Philips Circuit Cellar ARM design competition back in 2005 amongst many other things of course. Bit-bashing color VGA under interrupts while processing Forth apps, sound, SD, keyboards etc was a little bit harder with a single core compared to the Prop.

    @D.P. Yes, the delays don't stick do they but I might look into that because it must be possible to set that surely.

    EDIT: I remember you now Bernie from the H8 days, you're a Kiwi hey. Good to see you still around.
  • D.PD.P Posts: 790
    edited 2013-07-13 19:55
    P.S. I was so busy answering your query that I forgot my manners so welcome back to the Prop forum Bernie and especially the Tachyon thread :)
    BTW, I wrote IVOS for the ARM7 which I entered into the Philips Circuit Cellar ARM design competition back in 2005 amongst many other things of course. Bit-bashing color VGA under interrupts while processing Forth apps, sound, SD, keyboards etc was a little bit harder with a single core compared to the Prop.

    @D.P. Yes, the delays don't stick do they but I might look into that because it must be possible to set that surely.

    Write (couldn't help that) you are. Post 771, don't mean to nag but I'm stumped, when you got a few cycles?

    Oh and thanks for the 12ms delay in Minicomm, that works without any char delay, joy.

    UPDATE

    The delay works on my user code but when I rebuild the world not even 15ms delay works for EXTEND.fth?
  • bmentinkbmentink Posts: 107
    edited 2013-07-13 20:28
    Hi Peter,

    Thanks for the welcome back, and things are cold here in Christchurch at the mo .. :-) Yes, you are right, I had forgotten all about the H8 days, that was even before GraspForth ..... I'm getting old and forgetful ;-)

    Regarding the line delays .. I found that 4ms was fine at 1M baud (I can't seem to get as high as 3M, maybe because I have a 5Mhz crystal?).
    So I have an old Propeller Proto Board, is there any advantage on using a 10Mhz crystal? Will it let me go to 3M baud?

    My .minirc.dfl looks like this:

    # Machine-generated file - use setup menu in minicom to change parameters.
    pu port /dev/ttyUSB0
    pu baudrate 1000000
    pu rtscts No
    pu addlinefeed No

    Can you maybe post yours Peter?

    Cheers,
    Bernie
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2013-07-13 20:50
    bmentink wrote: »
    Hi Peter,

    Thanks for the welcome back, and things are cold here in Christchurch at the mo .. :-) Yes, you are right, I had forgotten all about the H8 days, that was even before GraspForth ..... I'm getting old and forgetful ;-)

    Regarding the line delays .. I found that 4ms was fine at 1M baud (I can't seem to get as high as 3M, maybe because I have a 5Mhz crystal?).
    So I have an old Propeller Proto Board, is there any advantage on using a 10Mhz crystal? Will it let me go to 3M baud?

    My .minirc.dfl looks like this:

    # Machine-generated file - use setup menu in minicom to change parameters.
    pu port /dev/ttyUSB0
    pu baudrate 1000000
    pu rtscts No
    pu addlinefeed No

    Can you maybe post yours Peter?

    Cheers,
    Bernie
    Hi Bernie, I just changed the thread title to "Minicom setup". The crystal makes no difference it's just that 10MHz are much easier to get in smaller packages such as cylindrical and very small SMD. I detest those HC49/4 SMD crystals because they are large and have legs that spread out like antennas plus they really mess up routing to pins because of this large footprint that they occupy. Through-hole HC49 are better in this respect but why bother when there are much better solutions available.

    The limitation with 3M baud is not with Tachyon or the Prop but to do with the FT232R USB-serial chip so your limitation will be tied in with the hardware. As I mentioned earlier I will do up a minicom setup guide.

    EDIT: I'm looking at recompiling a version of minicom from source. There's the variable vt_nl_delay which needs to be set.
  • D.PD.P Posts: 790
    edited 2013-07-14 15:55
    D.P wrote: »
    Write (couldn't help that) you are. Post 771, don't mean to nag but I'm stumped, when you got a few cycles?

    Oh and thanks for the 12ms delay in Minicomm, that works without any char delay, joy.

    UPDATE

    The delay works on my user code but when I rebuild the world not even 15ms delay works for EXTEND.fth?

    This was a logic error on my part ( imagine that). All is working as advertised. The 4DSystems LCD's are really touchy regarding serial, easy (for me at least) to lockup.

    They do include a way to read and write to a FAT 32 file system via serial to the onboard SD. Once I have the rest of the boundary conditions identified I'll post my code

    Thanks to all for the patience and help.

    @Peter, I can't seem to find any info on the settings that we would use for Line rx Delay or Char rx Delay to manually configure the .minicom.dfl file, and since my install doesn't seem to want to write a .minicom.dfl file anywhere I can find with these settings (cd / sudo fgrep -R ) I can't see what they would be. Not on the MAN page, no joy with google so far.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2013-07-14 16:11
    D.P wrote: »
    This was a logic error on my part ( imagine that). All is working as advertised. The 4DSystems LCD's are really touchy regarding serial, easy (for me at least) to lockup.

    They do include a way to read and write to a FAT 32 file system via serial to the onboard SD. Once I have the rest of the boundary conditions identified I'll post my code

    Thanks to all for the patience and help.

    @Peter, I can't seem to find any info on the settings that we would use for Line rx Delay or Char rx Delay to manually configure the .minicom.dfl file, and since my install doesn't seem to want to write a .minicom.dfl file anywhere I can find with these settings (cd / sudo fgrep -R ) I can't see what they would be. Not on the MAN page, no joy with google so far.

    Just check for the hidden .minirc.df1 etc files in your home directory but minicom does not store or load any tx or line delays here, it's just not built into the code. I will probably enhance and rebuild the source for minicom just to add these features.
Sign In or Register to comment.