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

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

15354565859109

Comments

  • mindrobotsmindrobots Posts: 6,506
    edited 2014-10-16 07:04
    Hi Peter,

    I broke my Tachyon!

    I just grabbed the latest (15 hours old) from Dropbox: Tachyon V2.4 and Extend.fth. I'm using a Propeller BOE on Win7 with TeraTerm 4.78 (all my usual suspects).

    I load Tachyon (F11 from source) to the board, start up Tera Term 230,400 (15ms line delay). When I paste EXTEND.fth into TeraTerm, I get this:
    [code]
    ok
    ( EXTEND.fth ) ok
    ok
    TACHYON
    Propeller .:.:--TACHYON--:.:. Forth V23140619.0000
    ok
    0000 ok
    0001 ok
    0002 ok
    0003 okND.fth ." Primary extensions to TACHYON kernel - 121122.1200 " ;
    0004 ok
    " !!!!!!!!!!!!!!!!!!!!! REQUIRES LATEST KERNEL V2.0 121012.2200 upwards !!!!!!!!0005 ok
    0006 ok
    0007 ok
    0008 ok
    0009 ok DUP $0A <> IF $100 OR 2* (EMIT) ELSE DROP THEN ;
    0010 ok
    \
    0011 ok
    \
    0012 ok
    0013 ok 1 flags CLR ' LEMIT uemit W! ;
    0014 ok
    \
    0015 ok
    0016 ok 1 flags SET 0 uemit W! ;
    0017 ok
    0018 @
  • KMyersKMyers Posts: 433
    edited 2014-10-16 08:41
    Same set up here except with an activity board. Load current binary works great, cut and paste the extend get to about line 17 and get a missing word, then about 20 minutes later I get several more then nothing. Let run all afternoon into late evening and it never finished with the log on and prompt. I know its something I am not doing but what?

    I used Notepad ++ to copy the file and terra term to paste into Tachyon. Also tried to reduce baud rate and left the delays set to original setting...:blank:
  • whiteoxewhiteoxe Posts: 794
    edited 2014-10-16 10:06
    Hey Peter, I tried to send you a private messagre but i got a message saying your message box was full and could not accept any more ?
  • KMyersKMyers Posts: 433
    edited 2014-10-16 10:22
    I am as usual confused today. This morning when I rebooted my Act brd the extension file showed up in the start up screen, Peter please ignore my mental issues. :lol: I assumed that when the extension completed it would automatic reboot. My bad...:innocent:
  • D.PD.P Posts: 790
    edited 2014-10-16 12:43
    Works just fine on my quickstart, wow V2.4x has some really neat stuff! Thanks Peter
    0035  ok
    0267      INCLUDING #9 PIN_I/O_OPERATIONS
    0436      INCLUDING #8 CHARACTER_OUTPUT
    0493      INCLUDING #7 LOCAL_VARIABLES 
    0515      INCLUDING #6 FIXED_POSITION_VARIABLES 
    0571      INCLUDING #5 MATHS_FUNCTIONS 
    0707      INCLUDING #12 NUMBER_PRINT_FORMATING 
    0822      INCLUDING #19 ANSI_TERMINAL
    0998      INCLUDING #24 INTERTASK_COMMUNICATIONS
    1027      INCLUDING #20 STRINGS
    1102      INCLUDING #21 SAN_FILTER
    1128      INCLUDING #22 MCP3208_8_channel_ADC
    1407      INCLUDING #13  PBASIC_STYLE_SERIAL_I/O
    1441      INCLUDING #14   EXAMINE_SPECIAL_PURPOSE_REGISTERS
    1486      INCLUDING #15   Memory Map Reporting
    1917      INCLUDING #17 Virtual RTC words 51 48 17 3B 
    2024      INCLUDING #10 PWM
    2084      INCLUDING #11 HEX FILE LOAD & DUMP
    2163      INCLUDING #18 COMPILER REPORTING
    2270  ok
    2271  ok
    2272 
    
    00:00:00  End of source code, 2273 lines processed and 0000 errors found 
    MODULES LOADED: 
    1900: EXTEND.fth          Primary extensions to TACHYON kernel - 140905-173O
    
    
      Propeller .:.:--TACHYON--:.:. Forth V24140928.1630
    Clock frequency = 80,000,000
    NAMES:  $5CB2...7471 for 6079 (3682 bytes added)
    CODE:   $0000...33CC for 7181 (6860 bytes added)
    CALLS:  0452 vectors free
    RAM:    10470 bytes free
     ok
    ?BACKUP  ok
      ok
    
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-10-16 12:47
    @DP, are you using Windows/TeraTerm or Linux/Minicom?

    I'll try it on a Quickstart to rule out a board issue.
  • D.PD.P Posts: 790
    edited 2014-10-16 12:55
    mindrobots wrote: »
    @DP, are you using Windows/TeraTerm or Linux/Minicom?

    I'll try it on a Quickstart to rule out a board issue.

    OSX, minicom, here's my alias to start minicom for this quickstart board
    alias mini5='minicom -D /dev/tty.usbserial-AH00OO83 -b 230400'
    
    I use 13 ms line delay no character delay
  • RickBRickB Posts: 395
    edited 2014-10-16 19:51
    Peter:

    Somewhat off topic. In searching for some Forth info, I ran across a question on Stack Overflow asking about a multicore forth back in 2011. The question remains open and is largely unanswered in terms of a practical implementation. There seems to be at least 3 on this forum. Care to contribute an answer?

    http://stackoverflow.com/questions/5618297/multicore-forth-is-there-one

    Rick
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-10-17 03:47
    RickB wrote: »
    Peter:

    Somewhat off topic. In searching for some Forth info, I ran across a question on Stack Overflow asking about a multicore forth back in 2011. The question remains open and is largely unanswered in terms of a practical implementation. There seems to be at least 3 on this forum. Care to contribute an answer?

    http://stackoverflow.com/questions/5618297/multicore-forth-is-there-one

    Rick

    Just keeping the reply to this forum but considering the reference it seems to be mainly academic in nature? Computer languages to many are a great source of debate, like Apple vs Android etc etc. Personally I find all the Forth forums very boring as this debate and also about features of the language are bounced back and forth (pun) ad nasuem. I can't say I would use Forth for everything, but for me there is a sweet spot between really low end and high end where Forth shines. But it's not about the language really, it's about productivity which increases in an environment that allows you to test out things interactively AND easily, not like interactive Basic peek and poke in decimal etc, but creating defintiions and structures that allow high level interaction at the bare metal layer at close to assembly speed, or at least fast enough.

    There's this joke about what's the differnce between a scientist and an engineer? The engineer gets his hands dirty. Yeah, I like to get into it rather than standing around all day talking about it and many times getting into it just proves that most don't know what they are talking about.

    Now back to that other forum and not really answering the question either but I don't really consider Tachyon a multicore Forh either, and I think that distinction for the Prop should go to PropForth as not only does it launch multiple Forth consoles one in each core but it also facilitates multi-chip processing too. However this approach seems to have traded off some of the very advantages of Forth that I at least need, one of which is speed, and also compactness too amongst other things. But each to his own and hopefully we have come to our own decision rather than relying upon popular opinions etc.
  • richaj45richaj45 Posts: 179
    edited 2014-10-17 09:19
    Along the line of multicore, i have a question.

    From the Tachyon code it looks to me the receive serial get left in COG 0 and the rest of the code goes into COG 1.

    If i am write how does one put special drivers and such into other COGs using Tachon?

    Forgive me if this is a stupid question, i only come around every so often.

    cheers,
    rich
  • MJBMJB Posts: 1,235
    edited 2014-10-17 12:06
    richaj45 wrote: »
    Along the line of multicore, i have a question.

    From the Tachyon code it looks to me the receive serial get left in COG 0 and the rest of the code goes into COG 1.

    If i am write how does one put special drivers and such into other COGs using Tachon?

    Forgive me if this is a stupid question, i only come around every so often.

    cheers,
    rich
    there are no stupid questions ... maybe ...

    if you look at the end of tachyon 2.4.spin you find this
    [COLOR=#000000][FONT=Ubuntu Mono]{ Boot-time Spin startup - launches Tachyon into all the remaining cogs and starts serial receive in this cog = 0 }[/FONT][/COLOR]
    
    [COLOR=#000000][FONT=Ubuntu Mono]PUB Start[/FONT][/COLOR]
    [COLOR=#000000][FONT=Ubuntu Mono]  rxticks := txticks := clkfreq / baudrate    [/FONT][/COLOR][COLOR=#000000][FONT=Ubuntu Mono]    [/FONT][/COLOR][COLOR=#000000][FONT=Ubuntu Mono]' Force VM transmit routine to correct baud[/FONT][/COLOR]
    [COLOR=#000000][FONT=Ubuntu Mono]  coginit(1,@HSSerialRx, @rxbuffers)[/FONT][/COLOR]
    [COLOR=#000000][FONT=Ubuntu Mono]  repeat 6[/FONT][/COLOR]
    [COLOR=#000000][FONT=Ubuntu Mono]    [/FONT][/COLOR][COLOR=#000000][FONT=Ubuntu Mono]cognew(@RESET, @IDLE_reset)[/FONT][/COLOR]
    [COLOR=#000000][FONT=Ubuntu Mono]  coginit(0,@RESET, @TERMINAL_reset)[/FONT][/COLOR]
    
    
    you see that the serial started is started in COG1 and COG0 is loaded with the Tachyon Terminal.
    The other 6 COGs get loaded with the Tachyon kernel as well, but put in IDLE state, waiting for a WORD / function to be loaded.

    see:
    ( COG TASK CONTROL )
    and
    ( INTERTASK COMMUNICATIONS ) in EXTEND.fth for how to start a Tachyon-Task in an other COG

    EXTEND also defines a TIMER task, that is started in COG 7
    see Timer and Keypoll examples here


    you can also write PASM drivers to be loaded in COGS, but this currently requires to put the code in Tachyon.spin
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-10-17 13:20
    MJB wrote: »
    there are no stupid questions ... maybe ...

    you can also write PASM drivers to be loaded in COGS, but this currently requires to put the code in Tachyon.spin

    There are easy ways to load directly into cogs form EEPROM or SD so I will update the files to do this which also includes assembling a PASM source from onboard file to a cog PASM object. Simply specify the file and cog to run when you want to run it during runtime, so you can change it on the fly. One moment it's an FFT, next moment it's handling high level communications etc.
  • richaj45richaj45 Posts: 179
    edited 2014-10-17 16:54
    Thanks for the education.

    rich
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-10-17 20:15
    Tachyon 2.4 & latest EXTEND.FTH from Dropbox is working fine now. In this message, I reported issues loading extend - after grabbing a fresh copy of extend.fth from Dropbox, it loaded fine onto a Prop BOE and also onto a QuickStart.

    Win7, Tera Term, 230400 with 15ms line delay.

    The ws2812 code with the MASK change also works just fine with my ws2811 LEDs.

    Fun stuff!!
  • ChameleonChameleon Posts: 14
    edited 2014-10-18 00:43
    Well it was a short and fast learning curve, looked at the timing, decided that it may be a bit tight for bytecode alone so I do what I do and create a module as there is room for 19 longs in the Tachyon cog to load in special purpose modules which are called with the RUNMOD instruction.

    To run this continually (optional of course) in the background of the console cog (why not) just type:
    KEYPOLL LEDS

    Or else you can run it from the timer cog with:
    TIMER ledtimer ( create a timer variable )
    ' LEDS ledtimer ALARM ( tell this timer what to do when it counts down to zero)
    #20 ledtimer TIMEOUT ( timeout in 20ms but need to insert this code in LEDS really to reload timer)

    To fill the array with RED you could try this:
    pub RED ( value -- ) rgbsz 1 DO DUP I C! 3 +LOOP DROP ;
    If you only wanted it updated when you changed something then add LEDS to the end of that code to do that.

    So you could type:
    20 % RED
    and the red bytes in the array should fill up with a value of 51. Well, it should work and the green and blue are similar but different offset (0 DO or 2 DO)
    Actually that would factor to:
    pub COLOR ( value offset -- ) rgbsz SWAP DO DUP I C! 3 +LOOP DROP ;
    pub RED ( value -- ) 1 COLOR ;
    pub GREEN ( value -- ) 0 COLOR ;
    pub BLUE ( value -- ) 2 COLOR ;

    COLOR crashes the prop! It looks to me like it starts stomping on the registers.

    Changing to
    pub COLOR ( value offset -- ) rgbleds + rgbsz ADO DUP I C! 3 +LOOP DROP ;
    
    works beautifully!
    I've got several projects where these will be outrageously useful, and will be attaching a bit of an update with some more capabilities. We need the ability to change the color on specific pixels, the ability to blank the strip without affecting the data in the array among other functions.
  • D.PD.P Posts: 790
    edited 2014-10-18 09:44
    Chameleon wrote: »
    COLOR crashes the prop! It looks to me like it starts stomping on the registers.

    Changing to
    pub COLOR ( value offset -- ) rgbleds + rgbsz ADO DUP I C! 3 +LOOP DROP ;
    
    works beautifully!
    I've got several projects where these will be outrageously useful, and will be attaching a bit of an update with some more capabilities. We need the ability to change the color on specific pixels, the ability to blank the strip without affecting the data in the array among other functions.

    I agree with Chameleon, just don't get your above COLOR word Peter. I do think you meant ADO instead of DO and need to adjust the initial address of the array with the proper byte offset before the loop?
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-10-18 14:00
    D.P wrote: »
    I agree with Chameleon, just don't get your above COLOR word Peter. I do think you meant ADO instead of DO and need to adjust the initial address of the array with the proper byte offset before the loop?

    Yeah, dumb things like that happen as I didn't get to test it out and "rgbleds" was in the original before I factored it out "quickly" :)

    But good to hear it works because when I get some leds I will be posting some videos of some fancy patterns which I will be able to tune interactively of course.
  • D.PD.P Posts: 790
    edited 2014-10-18 18:11
    Yeah, dumb things like that happen as I didn't get to test it out and "rgbleds" was in the original before I factored it out "quickly" :)

    But good to hear it works because when I get some leds I will be posting some videos of some fancy patterns which I will be able to tune interactively of course.

    What about using 7 strips and pushing the 5X7 font out for a basic scrolling marque :)

    In keypoll of course while running telnet, http, ftp and sending an email, okay maybe email is running in its own cog since it could block a bit.
  • MJBMJB Posts: 1,235
    edited 2014-10-19 02:51
    D.P wrote: »
    What about using 7 strips and pushing the 5X7 font out for a basic scrolling marque :)

    In keypoll of course while running telnet, http, ftp and sending an email, okay maybe email is running in its own cog since it could block a bit.
    If you want a controlled timing (like for running text) you might better put the redisplay routine into a timer task running in the timer COG.
    Or if need be even in it's own COG. All very easy with Tachyon. and since we have some spare COGs we can use them as well.
  • ChameleonChameleon Posts: 14
    edited 2014-10-22 16:13
    Chameleon wrote: »
    COLOR crashes the prop! It looks to me like it starts stomping on the registers.

    Changing to
    pub COLOR ( value offset -- ) rgbleds + rgbsz ADO DUP I C! 3 +LOOP DROP ;
    
    works beautifully!
    I've got several projects where these will be outrageously useful, and will be attaching a bit of an update with some more capabilities. We need the ability to change the color on specific pixels, the ability to blank the strip without affecting the data in the array among other functions.

    I've had some good success, but am still fighting some bugs. I'm running into some seemingly random reboots, but wanted to toss out the general idea I had. Being a noob, I'm still trying to understand why one solved bug (creating tempgrn, tempred and tempblu after creating pxldata placed the temp colors within pxldata) actually happened...
    ( WS2812.fth )
    
    TACHYON
    
    [~
    FORGET WS2812.fth
    pub WS2812.fth         PRINT" WS2812 Intelligent RGB LED driver V1.0 1410221430.0000 " ;
    IFNDEF [WS2812]                        --- use newer name for module in case this had the old name
    ALIAS [TXRGB] [WS2812]
    }
    
    {  configure for the strip in use  }
    #P0   MASK     == WSTXD   --- define our transmit pin
    --- three bytes for storing temporary color values, used for writing to/reading from the pixel array
    #1    BYTE tempgrn
    #1    BYTE tempred
    #1    BYTE tempblu
    #3    BYTE tempcolors
    --- configure the pixel array itself
    #32   == pxlcount         --- number of LEDS in the array
    #96   == pxlbytes         --- MUST BE 3x pxcount
    #96   BYTE pxldata        --- pxlbytes
    
    {  read/write tempcolor array  }
        {  read colors from tempcolor to stack }
    pub GRN@ ( -- value ) tempgrn C@ ;
    pub RED@ ( -- value ) tempred C@ ;
    pub BLU@ ( -- value ) tempblu C@ ;
    
        {  "additive" color setting...leaves other color bytes unaffected  }
    pub GRN+ ( value -- ) tempgrn C! ;
    pub RED+ ( value -- ) tempred C! ;
    pub BLU+ ( value -- ) tempblu C! ;
    
        {  "exclusive" color setting...blanks out (zeroes) the other color bytes  }
    pub COLOR ( blu red grn -- )  tempgrn C! tempred C! tempblu C! ;    
    pub BLACK ( -- ) 0 tempgrn C! 0 tempred C! 0 tempblu C! ;
    pub MAGENTA ( value -- ) BLACK DUP 0 COLOR ;
    pub CYAN ( value -- ) BLACK DUP 2/ SWAP 0 SWAP COLOR ;
    
    pub GRN! ( value -- ) BLACK tempgrn C! ;
    pub RED! ( value -- ) BLACK tempred C! ;
    pub BLU! ( value -- ) BLACK tempblu C! ;
    
    {  pixel setting  }
    --- CMOVE (src dest num -- )  --- evaluate for byte savings (PXRD, PXWR, etc)
    
    --- use two vectors, but saves a few bytes
    pub PXRD ( src dest -- )
        SWAP 
        pub PXWR ( dest src -- )
            C@ SWAP C!
            ;
        ;
    
    --- very likely unneeded...(PXCOLORADDR, not PXADDR) 
    pub PXCOLORADDR ( grb pixelid --- coloraddress ) --- used for each read/write to the pixel data array
        pub PXADDR ( pixelid -- grnaddr ) 
            3 * pxldata + 
            ;
        +
        ;
    
    pub PX@ ( pixelid -- )    --- read the color setting for a single pixel to tempcolor
        PXADDR DUP
        tempgrn PXRD
        1+ DUP tempred PXRD
        1+ tempblu PXRD
        ;
        
    pub PX! ( pixelid -- )    --- write tempcolor values to a single pixel
        PXADDR DUP            
        tempgrn PXWR          
        1+ DUP tempred PXWR
        1+ tempblu PXWR
        ;
    
    
    --- work in progress...figure out why fails after #28 pixels
    --- remove numleds after it works for the entire array
    pub PXFILL ( numleds -- )         --- write tempcolor to entire pixel array
        --- pxlcount 0 DO    --- planned function
        0 DO                 --- remove once it works for all leds, regardless of pixel count
          I PX!
        LOOP
        ;
    
    
    {  communicate with the led strip  }
    pub LEDCONFIG ( -- )  --- needs to be separated for blankleds..."configure" cog, then send three bytes at a time to strip
        WSTXD OUTCLR              --- Start a RET to synch the chips
        WSTXD 4 COGREG!           --- setup the I/O pin for the RUNMOD to use
        [WS2812]                   --- select the WS2812 module for RUNMOD
        #10 us                    --- still need a bit of extra delay for a minimum RET op while txd is low
        ;
    
    pub LEDS ( -- )  --- Replacement for Peter's LEDS...same code, just split into two words
        LEDCONFIG 
        pxldata pxlbytes RUNMOD      --- pass the address of the array and the byte count to the RUNMOD
        ;
    
    --- Is this an easier task for the kernel addition?
    pub BLANKLEDS ( -- ) --- Turns off all LEDS (0G 0R 0B) without affecting the color data in pxldata
        --- PLACE HOLDER...Figure out crashes with current code first...I have no idea if the strip timing chokes doing this
        {
        set tempcolors to $000000...easier way?
        LEDCONFIG                --- set up cog for sending the data to the strip
        pxlcount 0 DO            --- do once per pixel
            tempcolors 3 RUNMOD  --- send the temp data to the strip
        LOOP
        }
        
    {  debug code  }
    pub DUMPTEMP ( -- )       --- dumps the contents of tempcolor
        CR 
        CR PRINT" ============================================="
        CR PRINT" LED TEMP COLORS (" tempgrn . PRINT" , " tempred . PRINT" , " tempblu . PRINT" , " tempcolors . PRINT" )"
        CR 
        PRINT" GREEN: " tempgrn C@ . 
        PRINT"   RED: " tempred C@ . 
        PRINT"   BLUE: " BLU@ .    
        PRINT"   TEMPCOLORS: " tempcolors @ .
        ;
            
    pub DUMPB  ( -- )    --- 3 byte data element array pretty dumper (thanks, D.P.)
        DUMPTEMP 
        CR 
        CR PRINT" ============================================="
        CR PRINT" LED STORED COLORS "
        CR 
        pxldata pxlbytes       --- push this onto the stack: arrayaddr arraysize
        CR                                --- Carrriage return to start
        ADO  I C@ . "-" EMIT              --- fetch each first byte show it
          I pxldata - 1+ 3 MOD 0=        --- test for third byte
            IF PRINT" --" pxldata I - 1+ 3 /  . PRINT"  (" I 2 - . PRINT" )" CR THEN    --- pretty print it
        LOOP                 --- around we go
     ;
    
    ]~
    
    END
    

    #28 PXFILL works without issue, but #29 PXFILL reboots the prop...

    I'm continuing to work on this, but if anyone has any thoughts as to why I'm getting the reboots, I'd be happy to hear it.
  • D.PD.P Posts: 790
    edited 2014-10-22 16:26
    Chameleon wrote: »
    I've had some good success, but am still fighting some bugs. I'm running into some seemingly random reboots, but wanted to toss out the general idea I had. Being a noob, I'm still trying to understand why one solved bug (creating tempgrn, tempred and tempblu after creating pxldata placed the temp colors within pxldata) actually happened...
    ( WS2812.fth )
    
    TACHYON
    
    [~
    FORGET WS2812.fth
    pub WS2812.fth         PRINT" WS2812 Intelligent RGB LED driver V1.0 1410221430.0000 " ;
    IFNDEF [WS2812]                        --- use newer name for module in case this had the old name
    ALIAS [TXRGB] [WS2812]
    }
    
    {  configure for the strip in use  }
    #P0   MASK     == WSTXD   --- define our transmit pin
    --- three bytes for storing temporary color values, used for writing to/reading from the pixel array
    #1    BYTE tempgrn
    #1    BYTE tempred
    #1    BYTE tempblu
    #3    BYTE tempcolors
    --- configure the pixel array itself
    #32   == pxlcount         --- number of LEDS in the array
    #96   == pxlbytes         --- MUST BE 3x pxcount
    #96   BYTE pxldata        --- pxlbytes
    
    {  read/write tempcolor array  }
        {  read colors from tempcolor to stack }
    pub GRN@ ( -- value ) tempgrn C@ ;
    pub RED@ ( -- value ) tempred C@ ;
    pub BLU@ ( -- value ) tempblu C@ ;
    
        {  "additive" color setting...leaves other color bytes unaffected  }
    pub GRN+ ( value -- ) tempgrn C! ;
    pub RED+ ( value -- ) tempred C! ;
    pub BLU+ ( value -- ) tempblu C! ;
    
        {  "exclusive" color setting...blanks out (zeroes) the other color bytes  }
    pub COLOR ( blu red grn -- )  tempgrn C! tempred C! tempblu C! ;    
    pub BLACK ( -- ) 0 tempgrn C! 0 tempred C! 0 tempblu C! ;
    pub MAGENTA ( value -- ) BLACK DUP 0 COLOR ;
    pub CYAN ( value -- ) BLACK DUP 2/ SWAP 0 SWAP COLOR ;
    
    pub GRN! ( value -- ) BLACK tempgrn C! ;
    pub RED! ( value -- ) BLACK tempred C! ;
    pub BLU! ( value -- ) BLACK tempblu C! ;
    
    {  pixel setting  }
    --- CMOVE (src dest num -- )  --- evaluate for byte savings (PXRD, PXWR, etc)
    
    --- use two vectors, but saves a few bytes
    pub PXRD ( src dest -- )
        SWAP 
        pub PXWR ( dest src -- )
            C@ SWAP C!
            ;
        ;
    
    --- very likely unneeded...(PXCOLORADDR, not PXADDR) 
    pub PXCOLORADDR ( grb pixelid --- coloraddress ) --- used for each read/write to the pixel data array
        pub PXADDR ( pixelid -- grnaddr ) 
            3 * pxldata + 
            ;
        +
        ;
    
    pub PX@ ( pixelid -- )    --- read the color setting for a single pixel to tempcolor
        PXADDR DUP
        tempgrn PXRD
        1+ DUP tempred PXRD
        1+ tempblu PXRD
        ;
        
    pub PX! ( pixelid -- )    --- write tempcolor values to a single pixel
        PXADDR DUP            
        tempgrn PXWR          
        1+ DUP tempred PXWR
        1+ tempblu PXWR
        ;
    
    
    --- work in progress...figure out why fails after #28 pixels
    --- remove numleds after it works for the entire array
    pub PXFILL ( numleds -- )         --- write tempcolor to entire pixel array
        --- pxlcount 0 DO    --- planned function
        0 DO                 --- remove once it works for all leds, regardless of pixel count
          I PX!
        LOOP
        ;
    
    
    {  communicate with the led strip  }
    pub LEDCONFIG ( -- )  --- needs to be separated for blankleds..."configure" cog, then send three bytes at a time to strip
        WSTXD OUTCLR              --- Start a RET to synch the chips
        WSTXD 4 COGREG!           --- setup the I/O pin for the RUNMOD to use
        [WS2812]                   --- select the WS2812 module for RUNMOD
        #10 us                    --- still need a bit of extra delay for a minimum RET op while txd is low
        ;
    
    pub LEDS ( -- )  --- Replacement for Peter's LEDS...same code, just split into two words
        LEDCONFIG 
        pxldata pxlbytes RUNMOD      --- pass the address of the array and the byte count to the RUNMOD
        ;
    
    --- Is this an easier task for the kernel addition?
    pub BLANKLEDS ( -- ) --- Turns off all LEDS (0G 0R 0B) without affecting the color data in pxldata
        --- PLACE HOLDER...Figure out crashes with current code first...I have no idea if the strip timing chokes doing this
        {
        set tempcolors to $000000...easier way?
        LEDCONFIG                --- set up cog for sending the data to the strip
        pxlcount 0 DO            --- do once per pixel
            tempcolors 3 RUNMOD  --- send the temp data to the strip
        LOOP
        }
        
    {  debug code  }
    pub DUMPTEMP ( -- )       --- dumps the contents of tempcolor
        CR 
        CR PRINT" ============================================="
        CR PRINT" LED TEMP COLORS (" tempgrn . PRINT" , " tempred . PRINT" , " tempblu . PRINT" , " tempcolors . PRINT" )"
        CR 
        PRINT" GREEN: " tempgrn C@ . 
        PRINT"   RED: " tempred C@ . 
        PRINT"   BLUE: " BLU@ .    
        PRINT"   TEMPCOLORS: " tempcolors @ .
        ;
            
    pub DUMPB  ( -- )    --- 3 byte data element array pretty dumper (thanks, D.P.)
        DUMPTEMP 
        CR 
        CR PRINT" ============================================="
        CR PRINT" LED STORED COLORS "
        CR 
        pxldata pxlbytes       --- push this onto the stack: arrayaddr arraysize
        CR                                --- Carrriage return to start
        ADO  I C@ . "-" EMIT              --- fetch each first byte show it
          I pxldata - 1+ 3 MOD 0=        --- test for third byte
            IF PRINT" --" pxldata I - 1+ 3 /  . PRINT"  (" I 2 - . PRINT" )" CR THEN    --- pretty print it
        LOOP                 --- around we go
     ;
    
    ]~
    
    END
    

    #28 PXFILL works without issue, but #29 PXFILL reboots the prop...

    I'm continuing to work on this, but if anyone has any thoughts as to why I'm getting the reboots, I'd be happy to hear it.

    replace every 1+ with 1 + and if it works Peter can explain
  • ChameleonChameleon Posts: 14
    edited 2014-10-22 18:08
    D.P wrote: »
    replace every 1+ with 1 + and if it works Peter can explain

    Nope...I believe I changed from 1 + to 1+ as a possible solution (straw grab)...tried this recommendation with precisely the same outcome.

    I'd like to hear any limitations of 1+ vs 1 +, because I can't see any, and using 1+ rather than 1 + saves one byte per call. While I'm learning, I'd like to ingrain as many byte-efficient strategies as possible, like word nesting and 1+ vs 1 +. Using 1+, I have 9044 bytes free, where 1 + leaves me with 9038 (Tachyon + EXTEND + another module I wrote)

    I'll move Forth and (hopefully) succeed!
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-10-22 18:15
    D.P wrote: »
    replace every 1+ with 1 + and if it works Peter can explain

    Absolutely no difference using 1 + instead of 1+ except that 1+ is a Tachyon opcode and only takes 400ns to execute.
    4 LAP 1 + LAP .LAP   2. 200us ok
    . 5 ok
    4 LAP 1+ LAP .LAP   400ns ok
    . 5 ok
    



    But here's your problem, look at this code and also your original and besides using defined constants as parameters for other constants, notice BYTE vs BYTES (doh!)
    #32   == pxlcount         --- number of LEDS in the array
    pxlcount 3 *   == pxlbytes
    pxlbytes   [B]BYTES[/B] pxldata        --- pxlbytes
    


    vs the original:
    --- configure the pixel array itself
    #32   == pxlcount         --- number of LEDS in the array
    #96   == pxlbytes         --- MUST BE 3x pxcount
    #96   BYTE pxldata        --- pxlbytes
    

    pxlcount should also really be ledcount as each led has 3 pixels.

    EDIT: looking at the other BYTE defs they might need to be changed too as BYTE will only create byte sized variables without requiring any extra parameters and BYTES needs to know how many bytes in an array as such:
    BYTE onebyte
    BYTE x,y,z
    8 BYTES mybuf

    So the purality of BYTE(S) WORD(S) LONG(S) indicates that you need to tell it how many. There are no error messages if you say 20 BYTE as 20 is just another stack parameter that may have a purpose only you know of but as you know Forth does not enforce syntax "you must do it this way" which while fine for students with training wheels is IMO too restictive if you know what you are doing.

    BTW, if you mostly deal with decimal numbers you can just change your base to DECIMAL and skip the # tags. Perhaps I may just make decimal the default as I find that I normally prefix all my hex numbers with $ anyway.
  • D.PD.P Posts: 790
    edited 2014-10-22 19:38
    Absolutely no difference using 1 + instead of 1+ except that 1+ is a Tachyon opcode and only takes 400ns to execute.
    4 LAP 1 + LAP .LAP   2. 200us ok
    . 5 ok
    4 LAP 1+ LAP .LAP   400ns ok
    . 5 ok
    
    .
    .
    .
    Yep the version I wrote worked and I missed the BYTE/S mixup, thus just throwing hay into the wind with wild hope. Thanks for the explanation/s, always.
  • ChameleonChameleon Posts: 14
    edited 2014-10-23 00:13
    Absolutely no difference using 1 + instead of 1+ except that 1+ is a Tachyon opcode and only takes 400ns to execute.
    4 LAP 1 + LAP .LAP   2. 200us ok
    . 5 ok
    4 LAP 1+ LAP .LAP   400ns ok
    . 5 ok
    
    ...AND that it only requires one byte in the code as opposed to two bytes (my original reason for trying it, to start as byte-efficient as possible as early as possible)
    But here's your problem, look at this code and also your original and besides using defined constants as parameters for other constants, notice BYTE vs BYTES (doh!)
    #32   == pxlcount         --- number of LEDS in the array
    pxlcount 3 *   == pxlbytes
    pxlbytes   [B]BYTES[/B] pxldata        --- pxlbytes
    


    vs the original:
    --- configure the pixel array itself
    #32   == pxlcount         --- number of LEDS in the array
    #96   == pxlbytes         --- MUST BE 3x pxcount
    #96   BYTE pxldata        --- pxlbytes
    

    Doh! is right. The simple stuff can kill...can you tell me why it worked well for the first 28 LEDs, but not 29 plus?

    I started calculating the byte count, but crashed because I started manipulating the array only (no attention to calling [WS2812]), and pxlcount 3 * BYTES pxldata failed (or something else at the same time during development)...I started with the right intent, just missed a step.
    pxlcount should also really be ledcount as each led has 3 pixels.

    EDIT: looking at the other BYTE defs they might need to be changed too as BYTE will only create byte sized variables without requiring any extra parameters and BYTES needs to know how many bytes in an array as such:
    BYTE onebyte
    BYTE x,y,z
    8 BYTES mybuf

    So the purality of BYTE(S) WORD(S) LONG(S) indicates that you need to tell it how many. There are no error messages if you say 20 BYTE as 20 is just another stack parameter that may have a purpose only you know of but as you know Forth does not enforce syntax "you must do it this way" which while fine for students with training wheels is IMO too restictive if you know what you are doing.

    BTW, if you mostly deal with decimal numbers you can just change your base to DECIMAL and skip the # tags. Perhaps I may just make decimal the default as I find that I normally prefix all my hex numbers with $ anyway.

    pxlcount vs. ledcount is (human) semantics. I chose pixels since the WS2812s I bought from Adafruit are "Neopixels."

    What are your thoughts about adding an led clear to the kernel like the runmod? I see this being essential in a lot of applications, where we'll want to turn off all LEDS without affecting the color data already in the array (such as flashing a pattern on and off). I'm worried that we'll run into timing issues, where the strip will see my approach as an intentional reset...I haven't tested it yet since I've just seen your helpful smack on the forehead for a braindead flub.

    While I'm at it, does anyone else have suggestions for additional functions? I'm kinda enjoying this, and this makes a good post "Hello World" project. I've already been thinking about scrolling marquees, so will be looking into multi-strip support.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-10-23 01:15
    Chameleon wrote: »
    ...AND that it only requires one byte in the code as opposed to two bytes (my original reason for trying it, to start as byte-efficient as possible as early as possible)



    Doh! is right. The simple stuff can kill...can you tell me why it worked well for the first 28 LEDs, but not 29 plus?

    I started calculating the byte count, but crashed because I started manipulating the array only (no attention to calling [WS2812]), and pxlcount 3 * BYTES pxldata failed (or something else at the same time during development)...I started with the right intent, just missed a step.



    pxlcount vs. ledcount is (human) semantics. I chose pixels since the WS2812s I bought from Adafruit are "Neopixels."

    What are your thoughts about adding an led clear to the kernel like the runmod? I see this being essential in a lot of applications, where we'll want to turn off all LEDS without affecting the color data already in the array (such as flashing a pattern on and off). I'm worried that we'll run into timing issues, where the strip will see my approach as an intentional reset...I haven't tested it yet since I've just seen your helpful smack on the forehead for a braindead flub.

    While I'm at it, does anyone else have suggestions for additional functions? I'm kinda enjoying this, and this makes a good post "Hello World" project. I've already been thinking about scrolling marquees, so will be looking into multi-strip support.

    Since the RUNMOD function only requires the start address and count it is easy enough to have a blank area or any other area for that matter such as the tables in ROM but otherwise just feel free to use the BUFFERS area or part thereof.
    Initially you could: BUFFERS $800 ERASE BUFFERS pxlbytes + pxlbytes $FF FILL

    To blank all the LEDs: BUFFERS pxlbytes RUNMOD
    To light em up: BUFFERS pxlbytes + pxlbytes RUNMOD

    In fact rather than calling RUNMOD directly you should really have this:
    pub SHOW ( address -- ) pxlbytes RUNMOD #50 us ;

    So BLANK becomes pub BLANK BUFFERS SHOW ;

    Anyway there are all kinds of optimizations possible although I normally worry about "functionality first, features second". The scrolling marquee was one I was going to demo as soon as I get some LEDs but don't let me stop you, keep up the fun work.

    EDIT: the crash is simply because you are using a byte array in code space, not normally a problem but it was overwriting the GRN@ to BLU+ words which weren't noticed until it overran COLOR.
    pxldata $80 DUMP
    0000_3557: 00 C0 1F 62 0F BF 1F 62 0F C0 20 62 0F C0 1F 6A ...b...b.. b...j
    0000_3567: 0F BF 1F 6A 0F C0 20 6A 0F C0 1F 6A BF 1F 6A C0 ...j.. j...j..j.
    0000_3577: 20 6A 0F 87 C0 1F 6A 87 BF 1F 6A 87 C0 20 6A 0F j....j...j.. j.
    0000_3587: C0 26 17 87 BF 25 0F C0 26 17 4A 21 87 21 BF 25 .&...%..&.J!.!.%
    0000_3597: 0F C0 26 C0 1F 6A 0F C0 26 BF 1F 6A 0F C0 26 C0 ..&..j..&..j..&.
    0000_35A7: 20 6A 0F 21 62 21 6A 0F 0F 85 F5 14 C0 22 29 0F j.!b!j......").
    0000_35B7: 0F C0 2A 17 C0 1F C0 29 2C 17 BF 1F C0 29 2C C0 ..*....),....),.
    0000_35C7: 20 C0 29 0F C0 2A 17 C0 1F BF 29 2C 17 BF 1F BF .)..*....),.... ok
    ' COLOR . 3570 ok
    ' GRN+ . 3564 ok
    pxldata #29 + . 3574 ok

    You can also define storage areas as constants with ORG such as:
    BUFFERS ORG
    pxlbytes DS pxldata
    1 DS tempgrn
    and so on to keep it all together without worrying about slamming into code.
  • ChameleonChameleon Posts: 14
    edited 2014-10-25 01:46
    Since the RUNMOD function only requires the start address and count it is easy enough to have a blank area or any other area for that matter such as the tables in ROM but otherwise just feel free to use the BUFFERS area or part thereof.
    Initially you could: BUFFERS $800 ERASE BUFFERS pxlbytes + pxlbytes $FF FILL

    To blank all the LEDs: BUFFERS pxlbytes RUNMOD
    To light em up: BUFFERS pxlbytes + pxlbytes RUNMOD

    In fact rather than calling RUNMOD directly you should really have this:
    pub SHOW ( address -- ) pxlbytes RUNMOD #50 us ;

    So BLANK becomes pub BLANK BUFFERS SHOW ;

    Anyway there are all kinds of optimizations possible although I normally worry about "functionality first, features second". The scrolling marquee was one I was going to demo as soon as I get some LEDs but don't let me stop you, keep up the fun work.
    Awesome! Once again, I'm thinking about added code, and it was already there...seems to be a recurring theme for me...so many paradigms to overcome, but fun to try. I always keep features in mind, since I need them in order to know when it is functional.

    EDIT: the crash is simply because you are using a byte array in code space, not normally a problem but it was overwriting the GRN@ to BLU+ words which weren't noticed until it overran COLOR.
    pxldata $80 DUMP
    0000_3557: 00 C0 1F 62 0F BF 1F 62 0F C0 20 62 0F C0 1F 6A ...b...b.. b...j
    0000_3567: 0F BF 1F 6A 0F C0 20 6A 0F C0 1F 6A BF 1F 6A C0 ...j.. j...j..j.
    0000_3577: 20 6A 0F 87 C0 1F 6A 87 BF 1F 6A 87 C0 20 6A 0F j....j...j.. j.
    0000_3587: C0 26 17 87 BF 25 0F C0 26 17 4A 21 87 21 BF 25 .&...%..&.J!.!.%
    0000_3597: 0F C0 26 C0 1F 6A 0F C0 26 BF 1F 6A 0F C0 26 C0 ..&..j..&..j..&.
    0000_35A7: 20 6A 0F 21 62 21 6A 0F 0F 85 F5 14 C0 22 29 0F j.!b!j......").
    0000_35B7: 0F C0 2A 17 C0 1F C0 29 2C 17 BF 1F C0 29 2C C0 ..*....),....),.
    0000_35C7: 20 C0 29 0F C0 2A 17 C0 1F BF 29 2C 17 BF 1F BF .)..*....),.... ok
    ' COLOR . 3570 ok
    ' GRN+ . 3564 ok
    pxldata #29 + . 3574 ok

    You can also define storage areas as constants with ORG such as:
    BUFFERS ORG
    pxlbytes DS pxldata
    1 DS tempgrn
    and so on to keep it all together without worrying about slamming into code.

    I ran into precisely the same issue on a different section of the project I'm working on...That's why I had DUMPTEMP and DUMPB spit out the relevant addresses. I was blind, since I looked for precisely that and looked right over it. The noob is humbled. I just haven't had the time to fully understand ORG and the pros and cons (if there are any), but definately see an advantage.

    It now works even better than I hoped. I was expecting it to have more of a delay than it actually had, which is always a good thing when you're looking for as fast as friggin' possible. I'm adding some features, and will re-post the whole (functional and with the features I need) module.

    When I grow up, I wanna be like Peter. Most coders tell MCUs what to do. He convinces them that they want to do what he wants them to do.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-10-25 07:02
    Chameleon wrote: »
    Awesome! Once again, I'm thinking about added code, and it was already there...seems to be a recurring theme for me...so many paradigms to overcome, but fun to try. I always keep features in mind, since I need them in order to know when it is functional.



    I ran into precisely the same issue on a different section of the project I'm working on...That's why I had DUMPTEMP and DUMPB spit out the relevant addresses. I was blind, since I looked for precisely that and looked right over it. The noob is humbled. I just haven't had the time to fully understand ORG and the pros and cons (if there are any), but definately see an advantage.

    It now works even better than I hoped. I was expecting it to have more of a delay than it actually had, which is always a good thing when you're looking for as fast as friggin' possible. I'm adding some features, and will re-post the whole (functional and with the features I need) module.

    When I grow up, I wanna be like Peter. Most coders tell MCUs what to do. He convinces them that they want to do what he wants them to do.


    ORG just sets a pointer somewhere into memory that you would like to use for pure storage as opposed to variables which all feature at least a bytecode to say that the following memory is a variable or a constant etc. So when you use ORG you can then use DS (Data Storage) to specify how many bytes you would like at the current storage address and the symbol for it. Unlike an assembler that this concept is taken from the symbol lives on in the Forth dictionary as a constant that supplies the address of that storage area which could be used for anything at all, totally untyped and unchecked.

    So for instance we set up some buffers for these LEDs we go like this:
    [FONT=courier new]32            == ledcnt
    ledcnt 3 *    == pxlbytes
    
    BUFFERS       ORG              --- use BUFFERS for data storage
    pxlbytes      DS pxldata       --- pxldata begins at BUFFERS and ORG is advanced to BUFFERS+96
    1             DS tempgrn       --- tempgrn becomes a constant set as BUFFERS+96 and ORG is incremented
    1             DS tempred
    1             DS tempblu
    3             DS tempcolors[/FONT]
    

    What's different about this compared to using variables although they both return an address to a storage area is that there are no code bytes mixed in as the code is in code space as a constant whose value is the address of this storage area over here. So you can wipe the whole memory in this data storage area for instance and it won't affect the code but write a long to a byte variable will cause it to zap the code that follows that byte. How we use this DS then is sometimes to keep all our data in one place to allow it to be accessed as a structure such as file system tables and entries etc which are comprised of variable sized records. Have a look at SDCARD.fth and EASYFILE.fth for example.

    Now having grown up I wouldn't call myself a coder or perhaps even a programmer plus I've made too many mistakes around too many talented people such as we have on this forum to ever worry about getting a big head and thinking I can get stuff to do what I want it to do, mostly I just coax it along and get lucky sometimes. The thing is with this stuff, more important than important is having fun and learning and sharing. That's something any of us can do and who gets tired of having fun?
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-10-26 22:07
    With a full filesystem and networking loaded (+app) this 32K RAM bottleneck has been bothering me for ages and the logical thing to do is to move the dictionary to external memory but EEPROM is way too slow and SD seems to be the choice, but how to actually manage and search it efficiently then? A dictionary can grow to 10K and even with SD it takes around 3ms per sector so that 60ms is still way too long to search for each word if we are compiling. So I have looked at hashing schemes and hybrid hashing schemes but they also introduce complexities without saving that much RAM.

    Now, finally now I have come up with a scheme which keeps the dictionary in SDFS but can find any word from the console within 3ms, the time it takes to read a sector. This means that I "sacrifice" 2MB of SD but of course that's nothing as I convert 5 bits of the count and 7-bits of the first character as a 1 of 4,096 sector index into a dictionary file. So the sector gets read into a fixed buffer (there are 4 of them for 4 open files) and Tachyon just searches that RAM the same as it would when all the dictionary was in RAM, but now only the possible matches are presented, the ones with the same string length and same first character. Everything from there on works the same.

    When a new word is created it goes into the "current" dictionary except of course there's that little step that makes sure it has read in the matching sector. Then the sector gets written and everything continues as normal. From Tachyon's text interpreter point of view the dictionary is a tiny 512 byte sector buffer, except that buffer gets magically loaded and saved as needed.

    A dictionary can be converted to SDFS once the SDFS is in place as I am adding a simple SDWORDS which writes all the dictionary to the WORDS.DCT file, reclaims RAM, and then wires itself in to handle the SDFS as necessary.

    I needed this has my application that sits on top of all the network layer needed around >2K and I was constantly running out of room. Expect to see a lot more added functionality now and even VGA with a full blown system too.

    The slight problem now is that a full system image is comprised of 32K Prop EEPROM, + optional print strings in upper EEPROM + the 2MB WORDS.DCT file to make it complete. So don't expect the Spin tool to load it all with just a 32K binary although it may be that simple plus copy the WORDS.DCT to your SD card.
  • D.PD.P Posts: 790
    edited 2014-10-26 22:39
    With a full filesystem and networking loaded (+app) this 32K RAM bottleneck has been bothering me for ages and the logical thing to do is to move the dictionary to external memory but EEPROM is way too slow and SD seems to be the choice, but how to actually manage and search it efficiently then? A dictionary can grow to 10K and even with SD it takes around 3ms per sector so that 60ms is still way too long to search for each word if we are compiling. So I have looked at hashing schemes and hybrid hashing schemes but they also introduce complexities without saving that much RAM.

    Now, finally now I have come up with a scheme which keeps the dictionary in SDFS but can find any word from the console within 3ms, the time it takes to read a sector. This means that I "sacrifice" 2MB of SD but of course that's nothing as I convert 5 bits of the count and 7-bits of the first character as a 1 of 4,096 sector index into a dictionary file. So the sector gets read into a fixed buffer (there are 4 of them for 4 open files) and Tachyon just searches that RAM the same as it would when all the dictionary was in RAM, but now only the possible matches are presented, the ones with the same string length and same first character. Everything from there on works the same.

    When a new word is created it goes into the "current" dictionary except of course there's that little step that makes sure it has read in the matching sector. Then the sector gets written and everything continues as normal. From Tachyon's text interpreter point of view the dictionary is a tiny 512 byte sector buffer, except that buffer gets magically loaded and saved as needed.

    A dictionary can be converted to SDFS once the SDFS is in place as I am adding a simple SDWORDS which writes all the dictionary to the WORDS.DCT file, reclaims RAM, and then wires itself in to handle the SDFS as necessary.

    I needed this has my application that sits on top of all the network layer needed around >2K and I was constantly running out of room. Expect to see a lot more added functionality now and even VGA with a full blown system too.

    The slight problem now is that a full system image is comprised of 32K Prop EEPROM, + optional print strings in upper EEPROM + the 2MB WORDS.DCT file to make it complete. So don't expect the Spin tool to load it all with just a 32K binary although it may be that simple plus copy the WORDS.DCT to your SD card.

    Great news!!! I've been running into the dreading "dictionary is full" error after loading all the networking goodies and wondering what I need/can chop out. Look forward to testing this new functionality when ready.
Sign In or Register to comment.