Shop OBEX P1 Docs P2 Docs Learn Events
Tachyon V4 "DAWN" - exploring new worlds - Page 16 — Parallax Forums

Tachyon V4 "DAWN" - exploring new worlds

1131416181930

Comments

  • caskazcaskaz Posts: 957
    edited 2017-06-16 13:38
    Thank you Peter.

    I modified code.
    Wave takes 1.805sec
  • Hi Peter.
    I try to translate Wii-nunchuk to Tachyon.
    Wii-nunchuk is for 100kHz.

    This operate well on PropForth.
    But Not operating on Tachyon.
    Wii-nunchuk's slave-address had checked by lsi2c.

    I attached PropForth-file and Tachyon's test code.
    Please teach me wrong part in test code.
  • caskaz - I added a I2C clock delay feature to the kernel so I will check it out now and calibrate it for slow 100kHz devices, 400khz, and 1MHz. Check back in about 30 minutes.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-06-16 14:17
    caskaz - compile the latest kernel and EXTEND and you can select I2C bus speeds between 100kHz, 400kHz, or fast.

    I happened to have a lot of these older SAA1064 LED driver chips that only work at 100kHz. Here you can see it being detected on the 100kHz setting but not at 400kHz.
    ( 0003 $344E  ok )   I2C400 lsi2c
    
    *** I2C ***
    A0 EEPROM
    ( 0004 $344E  ok )   I2C100 lsi2c
    
    *** I2C ***
    70 DISPLAY I/O
    A0 EEPROM
    ( 0005 $344E  ok )
    
  • caskaz - compile the latest kernel and EXTEND and you can select I2C bus speeds between 100kHz, 400kHz, or fast.

    I happened to have a lot of these older SAA1064 LED driver chips that only work at 100kHz. Here you can see it being detected on the 100kHz setting but not at 400kHz.
    ( 0003 $344E  ok )   I2C400 lsi2c
    
    *** I2C ***
    A0 EEPROM
    ( 0004 $344E  ok )   I2C100 lsi2c
    
    *** I2C ***
    70 DISPLAY I/O
    A0 EEPROM
    ( 0005 $344E  ok )
    

    Now that is really handy, I'll APPEND my notes :)
  • caskazcaskaz Posts: 957
    edited 2017-06-17 02:45
    Hi Peter.
    I reloaded TachyonV4.4.spin and EXTEND.fth.
    But it is strange.
    There are WORD(I2C400 and I2C100).
    It seems to not operate.
      Propeller .:.:--TACHYON--:.:. Forth V4.4 DAWN 440170616.2330
    
    MODULES LOADED:
    1AC0: EXTEND.fth          Primary extensions to TACHYON V4.4 kernel  - 170612-0130
    
    AUTORUN BOOT
    FREQ = 80.0MHz
    *** INITS ***
    NO ROMS
    *** I2C ***
    40 I/O EXPANDER
    A0 EEPROM
    A4 EEPROM
    
    PPNET: &00.00.00.00 @2,000,000
     CODE:$344E =12878 bytes   NAME:$5AB0 =6480 bytes   DATA:$76E8 =216 bytes    =9826 bytes f     ree    Data Stack (1)
    $0000.76D8 - 30424
    
    
    --------------------------------------------------------------------------------
    ( 0001 $344E  ok )   lsi2c
    
    *** I2C ***
    40 I/O EXPANDER
    A0 EEPROM
    A4 EEPROM
    ( 0002 $344E  ok )   I2C400 lsi2c
    
    *** I2C ***
    40 I/O EXPANDER
    A0 EEPROM
    A4 EEPROM
    ( 0003 $344E  ok )   I2C100 lsi2c
    
    *** I2C ***
    40 I/O EXPANDER   <-- PCF8574
    A0 EEPROM              <--  EEPROM
    A4 EEPROM              <--  Wiinunchuk
    ( 0004 $344E  ok )
    

    After start-up Tachyon, I load i2c_charLCD.fth.
    Executing demo, it operate well. WAVE takes 1.998sec.
    Executing demo after I2C100, only WAVE operate(3.690sec).
    Font-display don't oparete. BarGraph is strange.
  • @D.P - I finally just had a look at APPEND and it seemed to be working but there were two things I fixed:
    1 - Change absolute SD memory address to relative FS address
    2 - set file read pointer as well as file write pointer (APPEND is normally a write operation)

    Now bear in mind that APPEND returns with the file read/write pointer which is a relative offset from the start of the file and so it is also the length of the text file itself.
    ( 0003 $44A2  ok )   FOPEN CHARLCD.FTH
    ...opened at 0000.4840 for 65536
    
    ( 0004 $44A2  ok )   0 $40 FS DUMP
    
    0000.0000:   54 41 43 48  59 4F 4E 20  56 34 0D 0D  49 46 44 45    TACHYON V4..IFDE
    0000.0010:   46 20 43 48  41 52 4C 43  44 2E 66 74  68 0D 40 72    F CHARLCD.fth.@r
    0000.0020:   65 73 74 09  6F 72 67 0D  46 4F 52 47  45 54 20 43    est.org.FORGET C
    0000.0030:   48 41 52 4C  43 44 2E 66  74 68 0D 7D  0D 0D 70 75    HARLCD.fth.}..pu
    ( 0005 $44A2  ok )   0 APPEND .  
    11010
    ( 0006 $44A2  ok )   -$100 fread +! (cat)
     (HUBLCD)               BEGIN lcdch W@ 0= UNTIL $100 OR lcdch W! ;
    pub LCD                 lcdtask C@ IF ' (HUBLCD) ELSE ' LCDEMIT THEN uemit W! ;
    
    
    pub LCD.TASK
         !RP !SP
        lcdtask C~~
         BEGIN
           lcdch W@ ?DUP IF LCDEMIT lcdch W~ THEN
         AGAIN
         ;
    }
    
    END
    
    ?BACKUP
    
    ( 0007 $44A2  ok )
    
  • @Peter - as you maybe remember I'm working on Linux with a Makefile to build Tachyon. Therefore I appreciate that you "back"-moved the xxx-4r4.FTH naming convention to xxx.FTH and separate different versions into versioned folder names.

    There are two more things which in your filename convention do "makefiling" harder than they have to:

    1. remove whitespaces in filenames
    2. move "Tachyon Vx.x.spin" to "tachyon.spin"

    this would ease up things and reduce makefile complexity a lot.

    Thanks in advance - proplem
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-06-17 12:17
    proplem wrote: »
    @Peter - as you maybe remember I'm working on Linux with a Makefile to build Tachyon. Therefore I appreciate that you "back"-moved the xxx-4r4.FTH naming convention to xxx.FTH and separate different versions into versioned folder names.

    There are two more things which in your filename convention do "makefiling" harder than they have to:

    1. remove whitespaces in filenames
    2. move "Tachyon Vx.x.spin" to "tachyon.spin"

    this would ease up things and reduce makefile complexity a lot.

    Thanks in advance - proplem

    Funny thing, just a few moments ago I was looking at FAT32 file directory structures and what are considered valid characters for 8.3 names and space is one of them, but not for lead or trailing characters. Anyway I prefer not to use them but some files still have them in long file names although they are being updated to conform to 8.3. Not that I'm a fan of such short file names but I abhor the kludge of a kludge, that abomination that is called LFN. I suppose I could change the kernel name to TACHYON.SPIN which unfortunately is not 8.3 and the whole reason I want 8.3 is for clean, quick and simple embedded use.

  • caskazcaskaz Posts: 957
    edited 2017-06-17 14:14
    Hi.

    Translated encoder to Tachyon.
    It need eliminate-chattering although not needing in PropForth.

    count operate well.

    But ' count TASK? RUN don't operate.
    What is wrong?
    TACHYON V4
                  
    IFDEF encoder.fth
    @rest	org
    FORGET encoder.fth
    }
    
    pub encoder        ." encoder  2017/06/17 23:02:16 " ;
    
    @org W@	== @rest	--- remember
    
    {
    2017/06/17 23:00:17
    Translated Wii_nunchuk to Tachyon
    Inserted chattring-procedure
             3V3
              |
            10kohm
              |     A -----------
    P0 --------------| Rotary    |
             GND ----|  Encorder |
    P1 --------------|           |
              |     B -----------
            10kohm
              |
             3V3
             
         prev  current status
           0     0      stop           0
           0     1      CW             1
           0     2      CCW           -1
           0     3      invalid(=stop) 0
           4     0      CCW           -1
           4     1      stop           0
           4     2      invalid(=stop) 0
           4     3      CW             1
           8     0      CW             1
           8     1      invalid(=stop) 0
           8     2      stop           0
           8     3      CCW           -1
           C     0      invalid(=stop) 0
           C     1      CCW           -1
           C     2      CW             1
           C     3      stop           0
             
    }
    
    \ =========================================================================== 
    \ Constants 
    \ =========================================================================== 
    #P2 == phaseA
    TABLE encoder_tbl
    0 , 1 , -1 , 0 , 
    -1 , 0 , 0 , 1 , 
    1 , 0 , 0 , -1 , 
    0 , -1 , 1 , 0 , 
    #800000        == 10msec
    
    \ =========================================================================== 
    \ Variables 
    \ =========================================================================== 
    long lastDebounceTime
    long pos
    word prev
    byte debounce
    
    \ =========================================================================== 
    \ Main 
    \ =========================================================================== 
    \ Get current encoder status(b1:b0)
    \ ( -- n1 ) n1:encoder status
    : status INA COG@ phaseA SHR 3 AND ;
    
    \ Get encorder's position
    \ ( -- )
    : count
    0 lastDebounceTime !
    0 debounce C!
    status pos !
    0 prev W!
    BEGIN   
         \ Eliminate chattering   
         BEGIN
              status DUP                              ( 2bit 2bit ) 
              prev W@ phaseA SHR <>                   ( 2bit  1/0 ) 
              IF
                   \ If encoder is under debouncong
                   debounce C@ 0=
                   IF
                        CNT@ lastDebounceTime ! 1 debounce C!                         
                   ENDIF
              ELSE
                   0 debounce C!
              ENDIF     
              debounce C@                             ( 2bit 1/0 )
              IF
                   CNT@ lastDebounceTime @ - 10msec >    
                   IF
                        \ Update current swState and lastswState
                        DUP 1                         ( 2bit 2bit 1 )                  
                   ELSE
                        DROP 0                        ( 0 )
                   ENDIF
              ELSE
                   DROP 0                             ( 0 )
              ENDIF   
         UNTIL
         \ Update encoder position
         prev W@ OR 4 * encoder_tbl + @
         pos @ + pos !                           \ Update pos
         phaseA SHL prev W!
    \              SPACE pos @ . CR    
    \     KEY 
     
    UNTIL
    ;
    
    : test 
    ' count TASK? RUN
    BEGIN pos @ . CR KEY UNTIL ;
    ;
    
    END
    
    \ ?BACKUP
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-06-17 15:22
    caskaz - most of your problems seem to be related to sloppy stack use. In this instance you have commented out KEY in a BEGIN UNTIL and it is probably reading garbage off the stack and exiting the routine. Of course you need a BEGIN AGAIN for the task or alternatively you could just as easily use a timer task with a 10ms timeout. Once you have a routine that is only called every 10ms or so then much of your debounce is taken care of and you don't have to keep track of the time either.

    To use a timer task you must create a TIMER variable, have your routine reload that timer each time it is called, set an ALARM vector for that timer pointing to your routine, and finally you need to kick it off to get it started:
    TIMER mytimer ( create a TIMER variable )
    
    : MYROUTINE    
    YADA YADA 
    10 mytimer TIMEOUT ( reload the timer )
    ;
    
    : MYINIT  
    YADA YADA BLAH BLAH  ( do what you do )
     ' MYROUTINE mytimer ALARM ( point to your code )
    10 mytimer TIMEOUT ( kick it off  - plus this links the mytimer variable into the timer task list )
    

    btw, a timer routine is called every time from the timer task so you don't need any BEGIN AGAIN plus it's also important that your routine execute and return in well under 1ms so that it doesn't block other timer functions.
  • Funny thing, just a few moments ago I was looking at FAT32 file directory structures and what are considered valid characters for 8.3 names and space is one of them, but not for lead or trailing characters. Anyway I prefer not to use them but some files still have them in long file names although they are being updated to conform to 8.3. Not that I'm a fan of such short file names but I abhor the kludge of a kludge, that abomination that is called LFN. I suppose I could change the kernel name to TACHYON.SPIN which unfortunately is not 8.3 and the whole reason I want 8.3 is for clean, quick and simple embedded use.
    Peter - thinking of Chuck Moore who had to reduce FOURTH to FORTH which has become a great name and according to the rule that (white) space is a delimiter between words i think of a file name as one word in forthish manner. Think also of "ifdef file name.FTH" - oops.

    It lasted a bit until I acknowledged - ".SPIN" is not .3 . This is an issue. I saw you experimented already with .spn but one is not used to it. Ugly isn't it?

    As long as we don't write a spin interpreter on top of tachyon which could load spin files from sdcard we can accept the .spin inconvenience - do we?

    Thank you very much for applying this. As the new naming has settled I will refactor my Makefile and publish it.

    Best regards,
    proplem
  • Hi Peter.

    I can't understand TIMER at all.
    But I want to think about it lator.

    I try to do code below.
    \ =========================================================================== 
    \ Constants 
    \ =========================================================================== 
    #P2 == phaseA
    TABLE encoder_tbl
    0 , 1 , -1 , 0 , 
    -1 , 0 , 0 , 1 , 
    1 , 0 , 0 , -1 , 
    0 , -1 , 1 , 0 , 
    #800000        == 10msec
    
    \ =========================================================================== 
    \ Variables 
    \ =========================================================================== 
    long lastDebounceTime
    long pos
    word prev
    byte debounce
    
    \ =========================================================================== 
    \ Main 
    \ =========================================================================== 
    \ Get current encoder status(b1:b0)
    \ ( -- n1 ) n1:encoder status
    : status INA COG@ phaseA SHR 3 AND ;
    
    \ Get encorder's position
    \ ( -- )
    : count
    0 lastDebounceTime !
    0 debounce C!
    0 pos !
    0 prev W!
    BEGIN   
         \ Eliminate chattering   
         status DUP                              ( 2bit 2bit ) 
         prev W@ phaseA SHR <>                   ( 2bit  1/0 ) 
         IF
              \ If encoder is under debouncong
              debounce C@ 0=
              IF
                   CNT@ lastDebounceTime ! 1 debounce C!                         
              ENDIF
         ELSE
              0 debounce C!
         ENDIF     
         debounce C@                             ( 2bit 1/0 )
         IF
              CNT@ lastDebounceTime @ - 10msec >    
              IF
                   DUP 1                         ( 2bit 2bit 1 )      
                             
              ELSE
                   DROP 0                        ( 0 )
            
              ENDIF
         ELSE
              DROP 0                             ( 0 )
                   
         ENDIF   
         \ Update encoder position
         IF
              prev W@ OR 4 * encoder_tbl + @
              pos @ + pos !                           \ Update pos
              phaseA SHL prev W!
         ENDIF
         0
     \ pos @ . SPACE
     \ KEY
    UNTIL
    ;
    
    : test
    ' count TASK? RUN             \ Run countr on anothrt cog
    #10 ms
    BEGIN pos @ . SPACE #100 ms KEY UNTIL 
    ;
    

    There are 2 problem.
    1. After executing it, count should be 0. But it is 3 or -2.
    2. Executing it, sometimes [Error - cog out of range] occur.
    But count-up/down operate when rotating encoder.
    Stack should be no data . But there are data on stack.

    What is wrong?
    ( 0125 $3578  ok )   test
    0 2 2 2 2 2 2 2 2 2 2 2
    ( 0126 $3578  ok )   test
    0 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 5 5 5 5 5 3 -7 -15 -22 -36 -51 -65 -85 -94 -94 -96 -101 -101 -103 -111 -102 -87 -96 -96 -96 -102 -102 -102 -107 -107 -111 -111 -115 -115 -115 -115 -115 -120 -116 -116 -116 -120 -120 -123 -123 -124 -125 -125 -129 -129 -131 -133 -133 -135 -139 -139 -139 -150 -172 -189 -203 -218 -223 -223 -223 -231 -231 -233 -233 -237 -237 -237 -245 -245 -245 -251 -253 -253 -255 -261 -265 -278 -278 -280 -280 -280 -287 -289 -289 -289 -293 -293 -293 -303 -307 -307 -307 -309 -309 -309 -311 -311 -311 -311 -317 -317 -319 -325 -325 -325 -331 -331 -331 -335 -335 -335 -335 -344 -344 -344 -348 -348 -348 -355 -355 -355 -358 -358 -358 -363 -363 -363 -366 -375 -375 -375 -377 -377 -377 -379 -381 -381 -381 -387 -387 -387 -393 -393 -393 -393 -399 -399 -399 -399 -405 -413 -417 -435 -450 -459 -464 -474 -482 -493 -502 -504 -504 -504 -504 -510 -525 -537 -556 -567 -581 -581 -581 -583 -586 -605 -608 -608 -608 -608 -608 -612 -626 -643 -661 -675 -685 -691 -691 -691 -693 -698 -704 -717 -717 -717 -717 -717 -717 -719 -728 -751 -754 -762 -762 -762 -762 -765 -771 -784 -788 -792 -792 -792 -792 -792 -798 -814 -818 -829 -829 -829 -834 -838 -853 -861 -863 -863 -871 -871 -871 -871 -871 -878 -894 -908 -922 -924 -924 -935 -938 -938 -940 -951 -951 -951 -951 -951 -954 -967 -973 -973 -973 -973 -975 -975 -977 -978 -987 -987 -987 -987 -987 -987 -988 -991 -1001 -1005 -1005 -1005 -1011 -1020 -1021 -1027 -1027 -1041 -1052 -1052 -1052 -1052 -1052 -1052 -1065 -1083 -1083 -1089 -1104 -1130 -1156 -1181 -1187 -1189 -1189 -1191 -1195 -1195 -1195 -1195 -1196 -1199 -1211 -1217 -1224 -1233 -1241 -1248 -1256 -1266 -1278 -1278 -1278 -1278 -1278 -1278 -1278 -1278
    ( 0127 $3578  ok )   test
    0 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2
    ( 0128 $3578  ok )   test
    
    Error - cog out of range -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 5 9 10 11 11 10 10 10 10 10 10 10
    ( 0129 $3578  ok )
    ( 0129 $3578  ok )   test
    
    Error - cog out of range 11 11 11 11 11 11 11 11 11 11 11
    ( 0130 $3578  ok )   test
    
    Error - cog out of range 11 11 11 11 11 11 11 11 11 11 11 11 11 12 16 22 29 38 48 58 67 75 79 87 98 106 113 120 126 132 135 126 126 126 126 102 96 87 87 87 76 54 33 15 -4 -18 -30 -30 -30 -30 -36 -39 -39 -39 -35 -27 -17 -7 -3 1 6 13 18 20 20 20 20 20 20 20 20
    ( 0131 $3578  ok )   test
    
    Error - cog out of range 20 20 20 20 20 20 20
    ( 0132 $3578  ok )
    

  • caskazcaskaz Posts: 957
    edited 2017-06-18 03:30
    Hi.

    I load i2c_charLCD.fth.
    Executing "demo", no operating and no error.
    After 'I2C400', demo operate well.
    After 'I2C100', only WAVE operate well.
    Font and BarGrapf is NG. But no error.

    This is abnormal?
  • D.PD.P Posts: 790
    edited 2017-06-18 06:05
    caskaz wrote: »
    Hi Peter.

    I can't understand TIMER at all.
    But I want to think about it lator.

    I try to do code below.
    \ =========================================================================== 
    \ Constants 
    \ =========================================================================== 
    #P2 == phaseA
    TABLE encoder_tbl
    0 , 1 , -1 , 0 , 
    -1 , 0 , 0 , 1 , 
    1 , 0 , 0 , -1 , 
    0 , -1 , 1 , 0 , 
    #800000        == 10msec
    
    \ =========================================================================== 
    \ Variables 
    \ =========================================================================== 
    long lastDebounceTime
    long pos
    word prev
    byte debounce
    
    \ =========================================================================== 
    \ Main 
    \ =========================================================================== 
    \ Get current encoder status(b1:b0)
    \ ( -- n1 ) n1:encoder status
    : status INA COG@ phaseA SHR 3 AND ;
    
    \ Get encorder's position
    \ ( -- )
    : count
    0 lastDebounceTime !
    0 debounce C!
    0 pos !
    0 prev W!
    BEGIN   
         \ Eliminate chattering   
         status DUP                              ( 2bit 2bit ) 
         prev W@ phaseA SHR <>                   ( 2bit  1/0 ) 
         IF
              \ If encoder is under debouncong
              debounce C@ 0=
              IF
                   CNT@ lastDebounceTime ! 1 debounce C!                         
              ENDIF
         ELSE
              0 debounce C!
         ENDIF     
         debounce C@                             ( 2bit 1/0 )
         IF
              CNT@ lastDebounceTime @ - 10msec >    
              IF
                   DUP 1                         ( 2bit 2bit 1 )      
                             
              ELSE
                   DROP 0                        ( 0 )
            
              ENDIF
         ELSE
              DROP 0                             ( 0 )
                   
         ENDIF   
         \ Update encoder position
         IF
              prev W@ OR 4 * encoder_tbl + @
              pos @ + pos !                           \ Update pos
              phaseA SHL prev W!
         ENDIF
         0
     \ pos @ . SPACE
     \ KEY
    UNTIL
    ;
    
    : test
    ' count TASK? RUN             \ Run countr on anothrt cog
    #10 ms
    BEGIN pos @ . SPACE #100 ms KEY UNTIL 
    ;
    

    There are 2 problem.
    1. After executing it, count should be 0. But it is 3 or -2.
    2. Executing it, sometimes [Error - cog out of range] occur.
    But count-up/down operate when rotating encoder.
    Stack should be no data . But there are data on stack.

    What is wrong?
    ( 0125 $3578  ok )   test
    0 2 2 2 2 2 2 2 2 2 2 2
    ( 0126 $3578  ok )   test
    0 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 5 5 5 5 5 3 -7 -15 -22 -36 -51 -65 -85 -94 -94 -96 -101 -101 -103 -111 -102 -87 -96 -96 -96 -102 -102 -102 -107 -107 -111 -111 -115 -115 -115 -115 -115 -120 -116 -116 -116 -120 -120 -123 -123 -124 -125 -125 -129 -129 -131 -133 -133 -135 -139 -139 -139 -150 -172 -189 -203 -218 -223 -223 -223 -231 -231 -233 -233 -237 -237 -237 -245 -245 -245 -251 -253 -253 -255 -261 -265 -278 -278 -280 -280 -280 -287 -289 -289 -289 -293 -293 -293 -303 -307 -307 -307 -309 -309 -309 -311 -311 -311 -311 -317 -317 -319 -325 -325 -325 -331 -331 -331 -335 -335 -335 -335 -344 -344 -344 -348 -348 -348 -355 -355 -355 -358 -358 -358 -363 -363 -363 -366 -375 -375 -375 -377 -377 -377 -379 -381 -381 -381 -387 -387 -387 -393 -393 -393 -393 -399 -399 -399 -399 -405 -413 -417 -435 -450 -459 -464 -474 -482 -493 -502 -504 -504 -504 -504 -510 -525 -537 -556 -567 -581 -581 -581 -583 -586 -605 -608 -608 -608 -608 -608 -612 -626 -643 -661 -675 -685 -691 -691 -691 -693 -698 -704 -717 -717 -717 -717 -717 -717 -719 -728 -751 -754 -762 -762 -762 -762 -765 -771 -784 -788 -792 -792 -792 -792 -792 -798 -814 -818 -829 -829 -829 -834 -838 -853 -861 -863 -863 -871 -871 -871 -871 -871 -878 -894 -908 -922 -924 -924 -935 -938 -938 -940 -951 -951 -951 -951 -951 -954 -967 -973 -973 -973 -973 -975 -975 -977 -978 -987 -987 -987 -987 -987 -987 -988 -991 -1001 -1005 -1005 -1005 -1011 -1020 -1021 -1027 -1027 -1041 -1052 -1052 -1052 -1052 -1052 -1052 -1065 -1083 -1083 -1089 -1104 -1130 -1156 -1181 -1187 -1189 -1189 -1191 -1195 -1195 -1195 -1195 -1196 -1199 -1211 -1217 -1224 -1233 -1241 -1248 -1256 -1266 -1278 -1278 -1278 -1278 -1278 -1278 -1278 -1278
    ( 0127 $3578  ok )   test
    0 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2
    ( 0128 $3578  ok )   test
    
    Error - cog out of range -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 5 9 10 11 11 10 10 10 10 10 10 10
    ( 0129 $3578  ok )
    ( 0129 $3578  ok )   test
    
    Error - cog out of range 11 11 11 11 11 11 11 11 11 11 11
    ( 0130 $3578  ok )   test
    
    Error - cog out of range 11 11 11 11 11 11 11 11 11 11 11 11 11 12 16 22 29 38 48 58 67 75 79 87 98 106 113 120 126 132 135 126 126 126 126 102 96 87 87 87 76 54 33 15 -4 -18 -30 -30 -30 -30 -36 -39 -39 -39 -35 -27 -17 -7 -3 1 6 13 18 20 20 20 20 20 20 20 20
    ( 0131 $3578  ok )   test
    
    Error - cog out of range 20 20 20 20 20 20 20
    ( 0132 $3578  ok )
    


    Hi caskaz,

    Fix this code up to suit your exact need. It currently compiles and returns 0 ever 10 ms, stops with pressing any key.

    I don't have any hardware to attach so only 0s. This is timer based code as Peter suggested.
    Remember to make your count word as fast as possible, < 1ms else you can hammer the other timers. Timers are very powerful in Tachyon and look how simple the code becomes, nice!
    
    TACHYON V4
                  
    IFDEF encoder.fth
    @rest	org
    FORGET encoder.fth
    }
    
    pub encoder        ." encoder  2017/06/17 23:02:16 " ;
    
    @org W@	== @rest	--- remember
    
    {
    2017/06/17 23:00:17
    Translated Wii_nunchuk to Tachyon
    Inserted chattring-procedure
             3V3
              |
            10kohm
              |     A -----------
    P0 --------------| Rotary    |
             GND ----|  Encorder |
    P1 --------------|           |
              |     B -----------
            10kohm
              |
             3V3
             
         prev  current status
           0     0      stop           0
           0     1      CW             1
           0     2      CCW           -1
           0     3      invalid(=stop) 0
           4     0      CCW           -1
           4     1      stop           0
           4     2      invalid(=stop) 0
           4     3      CW             1
           8     0      CW             1
           8     1      invalid(=stop) 0
           8     2      stop           0
           8     3      CCW           -1
           C     0      invalid(=stop) 0
           C     1      CCW           -1
           C     2      CW             1
           C     3      stop           0
             
    }
    
    \ =========================================================================== 
    \ Constants 
    \ =========================================================================== 
    #P2 == phaseA
    TABLE encoder_tbl
    0 , 1 , -1 , 0 , 
    -1 , 0 , 0 , 1 , 
    1 , 0 , 0 , -1 , 
    0 , -1 , 1 , 0 , 
    #800000        == 10msec
    
    \ =========================================================================== 
    \ Variables 
    \ =========================================================================== 
    long pos
    word prev
    TIMER enc_timer  ( create a timer variable )
    \ =========================================================================== 
    \ Main 
    \ =========================================================================== 
    \ Get current encoder status(b1:b0)
    \ ( -- n1 ) n1:encoder status
    : status INA COG@ phaseA SHR 3 AND ;
    
    \ Get encorder's position
    \ ( -- )
    : count
      status pos !
      0 prev W!
    
      status DUP                              ( 2bit 2bit ) 
      prev W@ phaseA SHR <>                   ( 2bit  1/0 ) 
     
      \ Update encoder position
      prev W@ OR 4 * encoder_tbl + @
      pos @ + pos !                           \ Update pos
      phaseA SHL prev W!
    
      10 enc_timer TIMEOUT   ( reload the timer to fire in 10 ms again )
    ;
    
    : test 
      ' count enc_timer ALARM ( point enc_timer to your code )
      15 enc_timer TIMEOUT ( initial start up after 15 ms  - links the enc_timer variable into the timer task list )
      BEGIN pos @ . CR 100 ms KEY UNTIL 
    ;
    
    \ ?BACKUP
    
    END
    
    



  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-06-18 06:01
    re @D.P - yes, I actually tidied up a version too, there were far too many IF ELSE THENs for my liking that only end up passing more flags rather than doing anything, all it needs is some actual logic and called every 10ms from the timer to handle the debounce easily. Here's one little thing I did in that you were using longs in the table to read out -1, 0, or 1 but you only need byte values 0,1,2 from which you subtract one.
    TABLE encoder_tbl
    1 | 2 | 0 | 1 |
    0 | 1 | 1 | 2 |
    2 | 1 | 1 | 0 |
    1 | 0 | 2 | 1 |
    

    Your code then reads it very simply:
    prev W@ OR encoder_tbl + C@ 1-	( -1 0 or 1 )
    
  • @D.P - I finally just had a look at APPEND and it seemed to be working but there were two things I fixed:
    1 - Change absolute SD memory address to relative FS address
    2 - set file read pointer as well as file write pointer (APPEND is normally a write operation)

    Now bear in mind that APPEND returns with the file read/write pointer which is a relative offset from the start of the file and so it is also the length of the text file itself.


    Hi Peter,

    I was able to repeat these results thanks. I tried to fix up V3 also but no joy, no worries. Gotta port to V4 at some point.
  • D.P wrote: »
    Hi Peter,

    I was able to repeat these results thanks. I tried to fix up V3 also but no joy, no worries. Gotta port to V4 at some point.

    V4 EASYFILE has a lot of enhancements and there are more coming. I'm even looking at implementing features that enhance embedded FAT32 operation yet are not incompatible with FAT32 itself. For instance I like to preallocate clusters so even an 11k file might have 64KB or 1MB allocated since memory is so plentiful yet an APPEND on a text reveals that it is 11k but has plenty of room to grow. In fact the cluster size of 32k in FAT32 means that even a 0 byte file will take 32kB anyway, so that is a form of preallocation. But if I update the file size to 11k I still want to know what the maximum size of the file is without scanning the cluster chain so to this end I am retasking some of the directory entry fields to indicate the max size and then I am also grabbing the last sector of the last cluster of a file and using that simply for file properties. Anyway, there are quite a few things I'm looking at doing, maybe even using the SD card to augment VGA memory seeing that I could read in 16kB every frame.

  • caskazcaskaz Posts: 957
    edited 2017-06-18 07:01
    Hi.

    This don't operate . Encoder-count is still 0.

    BTW,
    I cannot understand TIMER.
    Although there is not BEGIN-UNTIL, pos update?
    [#10 enc_timer TIMEOUT] update pos?
    \ =========================================================================== 
    \ Constants 
    \ =========================================================================== 
    #P2 == phaseA
    {
    TABLE encoder_tbl
    0 , 1 , -1 , 0 , 
    -1 , 0 , 0 , 1 , 
    1 , 0 , 0 , -1 , 
    0 , -1 , 1 , 0 , 
    }
    TABLE encoder_tbl
    1 | 2 | 0 | 1 |  
    0 | 1 | 1 | 2 | 
    2 | 1 | 1 | 0 | 
    1 | 0 | 2 | 1 | 
    
    #800000        == 10msec
    
    \ =========================================================================== 
    \ Variables 
    \ =========================================================================== 
    long lastDebounceTime
    long pos
    word prev
    byte debounce
    TIMER enc_timer
    \ =========================================================================== 
    \ Main 
    \ =========================================================================== 
    \ Get current encoder status(b1:b0)
    \ ( -- n1 ) n1:encoder status
    : status INA COG@ phaseA SHR 3 AND ;
    
    \ Get encorder's position
    \ ( -- )
    : count
    status pos !
    0 prev W!
    status DUP
    prev W@ phaseA SHR <>
    \ prev W@ OR 4 * encoder_tbl + @
    prev W@ OR encoder_tbl + C@ 1-
    pos @ + pos !                           \ Update pos
    phaseA SHL prev W!
    #10 enc_timer TIMEOUT
    ;
    
    : test
    #15 enc_timer TIMEOUT
    BEGIN pos @ . SPACE #100 ms KEY UNTIL 
    ;
    
    
    END
    
    \ ?BACKUP
    
  • caskaz wrote: »
    Hi.

    This don't operate . Encoder-count is still 0.

    BTW,
    I cannot understand TIMER.
    Although there is not BEGIN-UNTIL, pos update?
    [#10 enc_timer TIMEOUT] update pos?
    \ =========================================================================== 
    \ Constants 
    \ =========================================================================== 
    #P2 == phaseA
    {
    TABLE encoder_tbl
    0 , 1 , -1 , 0 , 
    -1 , 0 , 0 , 1 , 
    1 , 0 , 0 , -1 , 
    0 , -1 , 1 , 0 , 
    }
    TABLE encoder_tbl
    1 | 2 | 0 | 1 |  
    0 | 1 | 1 | 2 | 
    2 | 1 | 1 | 0 | 
    1 | 0 | 2 | 1 | 
    
    #800000        == 10msec
    
    \ =========================================================================== 
    \ Variables 
    \ =========================================================================== 
    long lastDebounceTime
    long pos
    word prev
    byte debounce
    TIMER enc_timer
    \ =========================================================================== 
    \ Main 
    \ =========================================================================== 
    \ Get current encoder status(b1:b0)
    \ ( -- n1 ) n1:encoder status
    : status INA COG@ phaseA SHR 3 AND ;
    
    \ Get encorder's position
    \ ( -- )
    : count
    status pos !
    0 prev W!
    status DUP
    prev W@ phaseA SHR <>
    \ prev W@ OR 4 * encoder_tbl + @
    prev W@ OR encoder_tbl + C@ 1-
    pos @ + pos !                           \ Update pos
    phaseA SHL prev W!
    #10 enc_timer TIMEOUT
    ;
    
    : test
    #15 enc_timer TIMEOUT
    BEGIN pos @ . SPACE #100 ms KEY UNTIL 
    ;
    
    
    END
    
    \ ?BACKUP
    

    It's not that hard.
    your count word is being called every 10 ms
    inside of count this line resets the timer to fire again
    #10 enc_timer TIMEOUT
    
    in your test word the ALARM vector for this enc_timer is set to your count word
      ' count enc_timer ALARM ( point enc_timer to your code )
    

    then the
    #15 enc_timer TIMEOUT
    
    starts the timer initially after 15 ms
    Hey you are missing that ALARM line in your test word code, go paste it back in from my example else count will never be called
    : test 
      ' count enc_timer ALARM ( point enc_timer to your code )
      15 enc_timer TIMEOUT ( initial start up after 15 ms  - links the enc_timer variable into the timer task list )
      BEGIN pos @ . CR 100 ms KEY UNTIL 
    ;
    
  • D.P wrote: »
    Hi Peter,

    I was able to repeat these results thanks. I tried to fix up V3 also but no joy, no worries. Gotta port to V4 at some point.

    V4 EASYFILE has a lot of enhancements and there are more coming. I'm even looking at implementing features that enhance embedded FAT32 operation yet are not incompatible with FAT32 itself. For instance I like to preallocate clusters so even an 11k file might have 64KB or 1MB allocated since memory is so plentiful yet an APPEND on a text reveals that it is 11k but has plenty of room to grow. In fact the cluster size of 32k in FAT32 means that even a 0 byte file will take 32kB anyway, so that is a form of preallocation. But if I update the file size to 11k I still want to know what the maximum size of the file is without scanning the cluster chain so to this end I am retasking some of the directory entry fields to indicate the max size and then I am also grabbing the last sector of the last cluster of a file and using that simply for file properties. Anyway, there are quite a few things I'm looking at doing, maybe even using the SD card to augment VGA memory seeing that I could read in 16kB every frame.

    Got it, keep moving forward, I will port stuff forward. Now about that upper lower case thing during compile?



  • @D.P - During interactive mode there is no need for fast searching so everything gets converted to uppercase for searching but during TACHYON block load it will search without any conversion. In any case just say ON ANYCASE or OFF ANYCASE if you still want it to be case sensitive during interactive use.
  • caskazcaskaz Posts: 957
    edited 2017-06-18 07:36
    Hi.

    I Sorry D.P.
    I uinserted [' count enc_timer ALARM in test.
    But not operated.


    This is wrong? Original is D.P.
    Although executing BLINKEM, LED not blinking.

    How does LED operate?
    TACHYON V4
                  
    IFDEF timer.fth
    @rest	org
    FORGET encoder.fth
    }
    
    pub timer        ." timer  2017/06/17 11:49:45 " ;
    
    @org W@	== @rest	--- remember
    
    
     \ * SIMPLE ROUTINE TO EXERCISE ALL 8 LEDS WITH TACHYON TIMERS
    \ * AND ALARMS ON THE  PROP QUICKSTART BOARD
    \ * 
    \ * USE THE WORD "BLINKEM" TO START THE LIGHTS 
    \ * AND "STOPEM" TO STOP THE LIGHTS
    
    
    0 == #mt0
    1 == #mt1
    2 == #mt2
    3 == #mt3
    4 == #mt4
    5 == #mt5
    6 == #mt6
    7 == #mt7
    
    : blink0 #16 PIN@ IF #16 LOW #500 ELSE #16 HIGH #50 THEN #mt0 TIMEOUT ;
    : b0 ' blink0 #mt0  ALARM ;
    
    : blink1 #17 PIN@ IF #17 LOW #300 ELSE #17 HIGH #50 THEN #mt1 TIMEOUT ;
    : b1 ' blink1 #mt1  ALARM ;
    
    : blink2 #18 PIN@ IF #18 LOW #150 ELSE #18 HIGH #50 THEN #mt2 TIMEOUT ;
    : b2 ' blink2 #mt2  ALARM ;
    
    : blink3 #19 PIN@ IF #19 LOW #285 ELSE #19 HIGH #50 THEN #mt3 TIMEOUT ;
    : b3 ' blink3 #mt3  ALARM ;
    
    : blink4 #20 PIN@ IF #20 LOW #175 ELSE #20 HIGH #50 THEN #mt4 TIMEOUT ;
    : b4 ' blink4 #mt4  ALARM ;
    
    : blink5 #21 PIN@ IF #21 LOW #335 ELSE #21 HIGH #50 THEN #mt5 TIMEOUT ;
    : b5 ' blink5 #mt5  ALARM ;
    
    : blink6 #22 PIN@ IF #22 LOW #100 ELSE #22 HIGH #50 THEN #mt6 TIMEOUT ;
    : b6 ' blink6 #mt6  ALARM ;
    
    : blink7 #23 PIN@ IF #23 LOW #195 ELSE #23 HIGH #50 THEN #mt7 TIMEOUT ;
    : b7 ' blink7 #mt7  ALARM ;
    
    : clrpin $FF0000 OUTCLR ;
    
    : BLINKEM  b0 b1 b2 b3 b4 b5 b6 b7  8 FOR #25 I * 1 + I TIMEOUT NEXT ;
    
    : STOPEM    8 FOR ' clrpin I ALARM NEXT ;
    
     END
    
    \ ?BACKUP
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-06-18 07:37
    caskaz - IF ELSE THEN are good for deciding what to do rather than passing that decision on in the form of flags. The encoder can actually be reduced to a couple of lines or so of easy to read code if you think about how the encoder works. Translating from other languages or even other Forths is almost invariably inefficient and hard to read.

    The TIMER task runs in its own cog and besides maintaining runtime and soft RTC always scans a linked list of user timers every 1ms. All you need to do is to create a timer variable, an optional do something vector on ALARM. If you want your code to run repeatedly then all you do is simply reload the timer.

    Create a timer variable
    TIMER mytimer
    

    Load that timer with a large enough value
    1000000 mytimer TIMEOUT
    
    and you can watch it count down
    mytimer @ .
    

    When it counts down to zero it will stop but if an ALARM vector is set it will execute that. Also, when TIMEOUT is first executed the timer variable is added to the linked list so you can have as many timers as you like, even ones that count up etc. Have a look at that section in EXTEND.

  • Hi there - I tried to "translate" EASYNET.FTH to the new v4r4 DOFOR loop syntax.

    There is a syntax issue with IX in BLKSEND maybe someone has some minutes to fix or explain what has to be done?

    Thanks, proplem
  • proplemproplem Posts: 233
    edited 2017-06-18 11:54
    Can anybody generally explain how error messages (generally or especially in v4r4) have to be understood?
    When I paste EASYNET-4r4.FTH, I get:
    ( 0001 $4648  ok )   ( Please define +FTP to IFDEF compile FTP and HTTP servers )
    ( 0002 $4648  ok )   TACHYON V4
      Propeller .:.:--TACHYON--:.:. Forth V4.4 DAWN 440170616.2330
    ( 0547 $4F46  ++ )    ??? in BLKSEND at >L 
    ( 0548 $4F46  ?? )    ??? in BLKSEND at IX 
    ( 0551 $4F46  ?? )    ??? in BLKSEND at IX 
                                                ??? in BLKSEND at L> 
    ( 1417 $5356  ok )   
    
       End of source code, 0004  errors found  Load time = 1343124720 cycles at 96MHz = 13c
    Code bytes used = 3342
     CODE:$5356 =20822 bytes   NAME:$686A =2966 bytes   DATA:$79EA =986 bytes    =5396 byt)
    
    ( 1418 $5356  ok )   
    ( 1419 $5356  ok )   ' EASYNET +INIT
    ( 1420 $5356  ok )   
    ( 1421 $5356  ok )   ?BACKUP
    
    The first number in the prompt (for example)
    ( 0547 $4F46  ++ )    ??? in BLKSEND at >L
    
    isn't the line number where the error occurs. I tried removing all empty lines but that isn't getting better maybe also comment lines have to be removed?!?

    edit: Maybe an explanation could be inserted into the google docs Tachyon + V4 "Dawn" ?
  • I wrote code for encoder.
    This don't use TIMER because I don't understand it.
    I try to re-write it after understanding TIMER.


    Sometimes error occur(Error - cog out of range).
      Propeller .:.:--TACHYON--:.:. Forth V4.4 DAWN 440170616.2330
    --------------------------------------------------------------------------------
    ( 0001 $344E  ok )   TACHYON V4
      Propeller .:.:--TACHYON--:.:. Forth V4.4 DAWN 440170616.2330
    ( 0373 $3848  ok )                  -- Loading i2c_charLCD.fth --
    
       End of source code, 0000  errors found  Load time = 475698544 cycles at 80MHz = 5.946sec
    Code bytes used = 1018
     CODE:$3848 =13896 bytes   NAME:$5942 =6846 bytes   DATA:$7702 =242 bytes    =8442 bytes free    Data Stack (0)
    
    ( 0374 $3848  ok )
    ( 0375 $3848  ok )   \
    ( 0376 $3848  ok )
    ( 0377 $3848  ok )   TACHYON V4
      Propeller .:.:--TACHYON--:.:. Forth V4.4 DAWN 440170616.2330
    ( 0130 $39A4  ok )                -- Loading encoder.fth --
    
       End of source code, 0000  errors found  Load time = 167187520 cycles at 80MHz = 2.089sec
    Code bytes used = 348
     CODE:$39A4 =14244 bytes   NAME:$58AE =6994 bytes   DATA:$770F =255 bytes    =7946 bytes free    Data Stack (0)
    
    ( 0131 $39A4  ok )
    ( 0132 $39A4  ok )   \
    ( 0133 $39A4  ok )   I2C400      <--- If not executing I2C400, i2c_charLCD don't display any.
    ( 0134 $39A4  ok )   prtEncoder
    

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-06-18 12:34
    proplem - I have updated a version of EASYNET for V4r4.

    In V4r4 the top of the loop stack is the index both for DOFOR and FOR so there is no longer any need for IX as I is the same for both as it is also for anything pushed onto the top of the stack too.

    EDIT: I just realized that I removed >L and L> so I have made the change to EASYNET as well.

    The trouble with line numbers is that they aren't counted during block comments so the error reports a different line number. If I can I will see if I can fix it.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-06-18 12:47
    caskaz - thanks for your persistence and demonstration of the practical applications of Tachyon.

    If you use TASK? it will find the next cog that is free, however, if you the TASK? again for the same code it will find find the next cog that is free other than the one it is already running in. I normally just specify a cog to use.

    Here is a list of ones that are used
    0 = Tachyon console
    1 = Console serial receive
    2 = Tachyon TIMER task
    3 = F32
    4 = free
    5 = free
    6 = free
    7 = free

    F32 isn't really being used at the moment but it might be fully utilized in the near future and become an integral part of Tachyon.

    When you get a free moment, try those simple things I last mentioned concerning timers. I'm sure you will see how they can be very useful. Even without ALARM vectors you can easily setup a timer for 10ms for instance and test for timeout like this:
    TIMER mytimer
    10 mytimer TIMEOUT
    ( snippet to test for timeout )
    mytimer TIMEOUT? IF <do stuff> THEN
    

    The timer task also maintains a soft RTC which can also be used with a hardware RTC for faster "cached" access to the current time rather than the delay required to read the real RTC.
  • caskazcaskaz Posts: 957
    edited 2017-06-18 13:52
    Hi Peter.

    Code below don't operate.
    What is wrong?
    TIMER mytimer
    
    : test
    #3000  mytimer TIMEOUT
    mytimer TIMEOUT? IF #P16 HIGH THEN
    ;
    
Sign In or Register to comment.