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

14445474950109

Comments

  • MJBMJB Posts: 1,165
    edited 2014-05-25 - 06:56:31
    Hi Peter,

    I have a basic version of the 1-Wire ROM search procedure running.
    And while cleaning up I came across a point, that I come across every now and then.
    It is the missing namespaces in Tachyon, to make sure that I don't accidentally overwrite
    an existing word.
    Besides the effort of a technical solution, there would be a very simple
    organisational solution.
    Like prefixing all the words of the package with a code like '1W.'
    then it would be clear for everybody, and no name conflicts could occure.
    It would cost a few chars more in name space dictionary, but since most words already contain 1W in the name
    it would be only the '.'.

    so 1W.RESET instead of 1WRESET ...
    what do you think?
    Markus
  • D.PD.P Posts: 790
    edited 2014-05-25 - 15:49:21
    Here's a basic driver for the AdaFruit MAX31855 breakout Thermocouple board.

    Peter you can by all means cut and paste the code to place it in the Tachyon dropbox as you see fit.
    TACHYON
    
    FORGET MAX31855.fth  
    
    pub MAX31855.fth  ." MAX31855 DRIVER - 140525-15:00 " ;
    
    ( MAX31855 ThermoCouple DRIVER )
    [~
    
    BYTE sbit             \ sign bit
    #P5 |< == MCLK        \ clock mask	
    #P3 |< == MCS         \ chip select mask
    #P1 == MDO            \ data input pin
    
    MCS OUTSET            \ initialize these pins
    MCLK OUTSET
    MDO |< INPUTS
    
    pub maxtc@  ( -- 32bitsMSBFirst )    \ bit bang to read MAX31855
      MCLK OUTCLR     \ just following what worked on Arduino, no joy with SHRINP
      1 ms
      MCS OUTCLR
      1 ms
      0   \ data destination placeholder
      #32 FOR 
        MCLK OUTCLR
        1 ms
        1 SHL         \ bump it over
        MDO PIN@
        IF 1 OR THEN  \ set bit accordingly
        MCLK OUTSET
        1 ms
      NEXT
      MCLK OUTCLR
      MCS OUTSET
    ;
    
    pub inttemp@  ( -- degreeC )
     maxtc@
      4 SHR               \ drop 4 lsb bits
      DUP
      $800 AND
      sbit C!             \ save sign bit
      $7FF AND            \ get 11 bits
      #625 * #10000 /     \ convert the temp
      sbit C@             \ get the sign bit, could use stack 
      IF -1 * THEN        \ convert for sign bit
    ;
    
    pub tctemp@   ( -- degreeC )
      maxtc@
      #18 SHR       \ shift upper 14 bits right 
      DUP           \ two copies
      $2000 AND     \ get bit 14 the sign bit 
      sbit C!       \ save sign bit
      $1FFF AND     \ get other 13 bits
      #25 * #100 /  \ convert the temp
      sbit C@
      IF -1 * THEN  \ convert for sign bit
    ;
    
    
    pub .inttemp      \ display internal MAX31855 temp
      inttemp@
      DUP
      ." Cold Junc. Temp: " . ."  C " #40 + #9 * 5 / #40 - . ."  F" CR
    ;
    
    pub .tctemp      \ display tc temp
      tctemp@ 
      DUP
      CR ." TC Temp: " . ."  C  "  #40 + #9 * 5 / #40 - . ."  F  "
    ;
    
    pub .runtc       \ routine to display readings to console every 2 seconds until ESC key hit
      #10 >RADIX
      BEGIN
        #1000 ms
        .tctemp  
        .inttemp #1000 ms
      ESC? UNTIL
      RADIX>
    ;
    
    { .runtc
    TC Temp: 21 C  69 F  Cold Junc. Temp: 22 C 71 F
    .
    .
    .
    }
    ]~
    END
    
    
  • MJBMJB Posts: 1,165
    edited 2014-05-25 - 17:12:37
    little comments
    D.P wrote: »
    Here's a basic driver for the AdaFruit MAX31855 breakout Thermocouple board.

    Peter you can by all means cut and paste the code to place it in the Tachyon dropbox as you see fit.
    TACHYON
    
    FORGET MAX31855.fth  
    
    pub MAX31855.fth  ." MAX31855 DRIVER - 140525-15:00 " ;
    
    ( MAX31855 ThermoCouple DRIVER )
    [~
    
    BYTE sbit             \ sign bit
    #P5 |< == MCLK        \ clock mask    
    #P3 |< == MCS         \ chip select mask
    #P1 == MDO            \ data input pin
    
    MCS OUTSET            \ initialize these pins
    MCLK OUTSET
    MDO |< INPUTS
    
    pub maxtc@  ( -- 32bitsMSBFirst )    \ bit bang to read MAX31855
      MCLK OUTCLR     \ just following what worked on Arduino, no joy with SHRINP
      1 ms
      MCS OUTCLR
      1 ms
      0   \ data destination placeholder
      #32 FOR 
        MCLK OUTCLR
        1 ms
        1 SHL         \ bump it over
        MDO PIN@
        IF 1 OR THEN  \ set bit accordingly
        MCLK OUTSET
        1 ms
      NEXT
      MCLK OUTCLR
      MCS OUTSET
    ;
    
    pub inttemp@  ( -- degreeC )
     maxtc@
      4 SHR               \ drop 4 lsb bits
      DUP
      $800 AND
      sbit C!             \ save sign bit
      $7FF AND            \ get 11 bits
      #625 * #10000 /     \ convert the temp
      sbit C@             \ get the sign bit, [COLOR=#0000cd]could use stack [/COLOR]:-)
    \  [COLOR=#ff0000]IF -1 * THEN        \ convert for sign bit[/COLOR]
    [COLOR=#0000cd]   ?NEGATE   \ is faster[/COLOR]
    ;
    
    pub tctemp@   ( -- degreeC )
      maxtc@
      #18 SHR       \ shift upper 14 bits right 
      DUP           \ two copies
      $2000 AND     \ get bit 14 the sign bit 
      sbit C!       \ save sign bit
      $1FFF AND     \ get other 13 bits
      #25 * #100 /  \ convert the temp
      sbit C@
    \  IF -1 * THEN  \ convert for sign bit
    [COLOR=#0000cd]   ?NEGATE   \ is faster[/COLOR]
    ;
    
    
    pub .inttemp      \ display internal MAX31855 temp
      inttemp@
      DUP
      ." Cold Junc. Temp: " . ."  C " #40 + #9 * 5 / #40 - . ."  F" CR
    ;
    
    pub .tctemp      \ display tc temp
      tctemp@ 
      DUP
      CR ." TC Temp: " . ."  C  "  #40 + #9 * 5 / #40 - . ."  F  "
    [COLOR=#0000cd]\  : C>F   #40 + #9 * 5 / #40 - ; [/COLOR]
    ;
    
    pub .runtc       \ routine to display readings to console every 2 seconds until ESC key hit
      #10 >RADIX   [COLOR=#0000cd]\ instead of switching radix you can use   the .NUM formatting see EXTEND [/COLOR]
      BEGIN
    [COLOR=#ff0000]\    #1000 ms[/COLOR]
        .tctemp  
        .inttemp [COLOR=#ff0000]\ #1000 ms[/COLOR]
    [COLOR=#0000cd]    2 seconds[/COLOR]
      ESC? UNTIL
      RADIX>
    ;
    
    { .runtc
    TC Temp: 21 C  69 F  Cold Junc. Temp: 22 C 71 F
    .
    .
    .
    }
    ]~
    END
    
    
  • D.PD.P Posts: 790
    edited 2014-05-25 - 18:16:06
    MJB wrote: »
    little comments

    Thanks for the review, still learning.

    Updated:
    TACHYON
    
    FORGET MAX31855.fth  
    
    pub MAX31855.fth  ." MAX31855 DRIVER - 140525-16:00 " ;
     \  update after mjb comments 
    
    ( MAX31855 ThermoCouple DRIVER )
    [~
    
    BYTE sbit             \ sign bit
    #P5 |< == MCLK        \ clock mask    
    #P3 |< == MCS         \ chip select mask
    #P1 == MDO            \ data input pin
    
    MCS OUTSET            \ initialize these pins
    MCLK OUTSET
    MDO |< INPUTS
    
    pub maxtc@  ( -- 32bitsMSBFirst )    \ bit bang to read MAX31855
      MCLK OUTCLR     \ just following what worked on Arduino, no joy with SHRINP
      1 ms
      MCS OUTCLR
      1 ms
      0   \ data destination placeholder
      #32 FOR 
        MCLK OUTCLR
        1 ms
        1 SHL         \ bump it over
        MDO PIN@
        IF 1 OR THEN  \ set bit accordingly
        MCLK OUTSET
        1 ms
      NEXT
      MCLK OUTCLR
      MCS OUTSET
    ;
    
    pub inttemp@  ( -- degreeC )
     maxtc@
      4 SHR               \ drop 4 lsb bits
      DUP
      $800 AND
      sbit C!             \ save sign bit
      $7FF AND            \ get 11 bits
      #625 * #10000 /     \ convert the temp
      sbit C@             \ get the sign bit, could use stack :-)
      ?NEGATE             \ negate if sign bit
    ;
    
    pub tctemp@   ( -- degreeC )
      maxtc@
      #18 SHR       \ shift upper 14 bits right 
      DUP           \ two copies
      $2000 AND     \ get bit 14 the sign bit 
      sbit C!       \ save sign bit
      $1FFF AND     \ get other 13 bits
      #25 * #100 /  \ convert the temp
      sbit C@
      ?NEGATE       \ negate if sign bit
    ;
    
    pub C>F  ( C -- F )  \ convert C degrees to F
      #40 + #9 * 5 / #40 - 
    ; 
    
    pub .inttemp      \ display internal MAX31855 temp
      inttemp@
      DUP
      ." Cold Junc. Temp: " $240A .NUM ."  C  "  C>F $240A .NUM ."  F  " \ .NUM 4 digits, leading blanks base 10
    ;
    
    pub .tctemp      \ display tc temp
      tctemp@ 
      DUP
      CR ." TC Temp: "  $240A .NUM ."  C  "  C>F $240A .NUM ."  F  "
    ;
    
    pub .runtc       \ routine to display readings to console every 2 seconds until ESC key hit
      BEGIN
        2 seconds
        .tctemp  
        .inttemp 
      ESC? UNTIL
    ;
    
    { .runtc
    TC Temp: 21 C  69 F  Cold Junc. Temp: 22 C 71 F
    .
    .
    .
    }
    ]~
    END
    
    
  • MJBMJB Posts: 1,165
    edited 2014-05-26 - 03:38:09
    D.P wrote: »
    Thanks for the review, still learning.
    me too - we can review each others code if you like

    I have no SPI HW set up, so I can not test it here ATM
    D.P wrote: »
    Updated:
    TACHYON
    
    FORGET MAX31855.fth  
    
    pub MAX31855.fth  ." MAX31855 DRIVER - 140525-16:00 " ;
     \  update after mjb comments 
    
    ( MAX31855 ThermoCouple DRIVER )
    [~
    
    BYTE sbit             \ sign bit
    #P5 |< == MCLK        \ clock mask    
    #P3 |< == MCS         \ chip select mask
    #P1 == MDO            \ data input pin
    
    MCS OUTSET            \ initialize these pins
    MCLK OUTSET
    MDO |< INPUTS
    
    pub maxtc@  ( -- 32bitsMSBFirst )    \ bit bang to read MAX31855
    [COLOR=#0000ff]\ here the SPI words should help:
    \ I propose the kernel embedded SPI here, since it seems sufficient.
    \ for more complex SPI requirements, like bidirectional, the loadable RUNMOD modules can be used
    \ like
    {   \ Define COGREG constants for most SPI operations based on kernel code, usually not for RUNMODs
    -5 CONSTANT @SPISCK
    -2 CONSTANT @SPICE
    -1 CONSTANT @SPICNT
    }
    32 @SPICNT COGREG!              \ set SPI to 32 bits at once
    MCS  @SPICE  COGREG!          \ define CS mask
    MCLK   @SPISCK  COGREG!     \ define SCK mask
    -3 CONSTANT @SPIINP                     \  definition is missing in EXTEND ( I'll try to add it )
    MDO |<  @SPIINP   COGREG!      \ define input mask 
    [/COLOR]
    [COLOR=#0000ff]{  let Tachyon do the work ...      from Tachyon.spin
    ' Receive data and shift into existing stack parameter
    ' If MOSI needs to be in a certain state then this should be set beforehand
    ' Clock will simply pulse from it's starting state - normally low
    ' Useage:  0 SPIRX     'read 32-bits as one long
    ' SPIRD ( data -- data<<8 )        ' 11.2us for 32 bits ==   2.8 MHz  ( sensor is specified up to 5 MHz )
    }[/COLOR]
    [COLOR=#b22222]{ your code ...
       MCLK OUTCLR     \ just following what worked on Arduino, no joy with SHRINP
      1 ms
      MCS OUTCLR
      1 ms
      0   \ data destination placeholder
      #32 FOR 
        MCLK OUTCLR
        1 ms
        1 SHL         \ bump it over
        MDO PIN@
        IF 1 OR THEN  \ set bit accordingly
        MCLK OUTSET
        1 ms
      NEXT
      MCLK OUTCLR
      MCS OUTSET
    }[/COLOR]
    [COLOR=#0000ff]\ set defined start conditions
    MCLK OUTCLR
    MCS OUTCLR
    0 SPIRDX    \ inputs 32 bits at once  -- done
    \ not sure if those are needed
    MCLK OUTCLR
    MCS OUTSET[/COLOR]
    ;
    
    pub inttemp@  ( -- degreeC )
     maxtc@
      4 SHR               \ drop 4 lsb bits
      DUP
      $800 AND
      sbit C!             \ save sign bit
      $7FF AND            \ get 11 bits
      #625 * #10000 /     \ convert the temp
      sbit C@             \ get the sign bit, could use stack :-)
      ?NEGATE             \ negate if sign bit
    ;
    
    pub tctemp@   ( -- degreeC )
      maxtc@
      #18 SHR       \ shift upper 14 bits right 
      DUP           \ two copies
      $2000 AND     \ get bit 14 the sign bit 
      sbit C!       \ save sign bit
      $1FFF AND     \ get other 13 bits
      #25 * #100 /  \ convert the temp
      sbit C@
      ?NEGATE       \ negate if sign bit
    ;
    
    pub C>F  ( C -- F )  \ convert C degrees to F
      #40 + #9 * 5 / #40 - 
    ; 
    
    pub .inttemp      \ display internal MAX31855 temp
      inttemp@
      DUP
      ." Cold Junc. Temp: " $240A .NUM ."  C  "  C>F $240A .NUM ."  F  " \ .NUM 4 digits, leading blanks base 10
    ;
    
    pub .tctemp      \ display tc temp
      tctemp@ 
      DUP
      CR ." TC Temp: "  $240A .NUM ."  C  "  C>F $240A .NUM ."  F  "
    ;
    
    pub .runtc       \ routine to display readings to console every 2 seconds until ESC key hit
      BEGIN
        2 seconds
        .tctemp  
        .inttemp 
      ESC? UNTIL
    ;
    
    { .runtc
    TC Temp: 21 C  69 F  Cold Junc. Temp: 22 C 71 F
    .
    .
    .
    }
    ]~
    END
    
    

    p.s. I changed the title to s.th. meaningful
    ALL:
    unfortunately most writers just leave the previous post title, so the title says nothing about the new post itself - this is bad for searching later - so I'd like to encourage use of meaningful post titles !! thanks MJB
  • artkennedyartkennedy Posts: 164
    edited 2014-05-30 - 01:01:35
    Hell-o Tachy World,

    I've been away for a while taking care of non-code and chip kinds of things. Recently working real hard on learning to use my new AdaFruit TI-ADS1115 16 bit ADC breakout. Yep, I dumped the DMM idea. The points against started adding up too fast.

    The TI-ADS1115 is my first foray into the I2C world. Thanks to Peter and Tachyon the lowest level stuff was not hard.

    Here is the code I have done so far:
    FORGET ADC16@
    
    
    : ADC16@           \ read contents from a TI-1115 register ( rp --- msb lsb ) rp = TI-1115 register pointer
       I2CSTART        \ wakeup call
       $90 I2C!        \ send address $48 plus write bit
       I2C!            \ write rp to pointer register
       I2CSTART        \ not done yet
       $91 I2C!        \ send address $48 plus read bit
       ackI2C@         \ get MSB of target register
       ackI2C@         \ get LSB
       I2CSTOP         \ that's all for now
    ;
    
    
    : ADC16!           \ get write n to TI-1115 register rp ( n rp --- n )
       I2CSTART        \ wakeup call
       $90 I2C!        \ send address $48 plus write bit
       I2C!            \ write rp to pointer register
       DUP 8 SHR       \ get MSB
       I2C!            \ write to target register
       $FF AND I2C!    \ write LSB
       I2CSTOP         \ that's all for now
    ;
    
    
    $8BA3 CONSTANT ADcfg
    
    
    : ADC16cfg         \ ( 16b --- ) \ configure per 16bit input value
                       \    see table of values in C:\Users\Art\Documents\Tech\!Propeller\ADC Add On\ADC_Board.txt
       1 ADC16!        \ point to config register and write
    ;
    
    
    : ADC16ss          \ get Single-Shot reading from TI-1115  ( 16b --- MSBrd LSBrd ) configuration --- result
       ADcfg ADC16cfg  \ config and trigger conversion - temp, hard coded configuration
       BEGIN           \ repeat
          1 ADC16@     \    config register, bit 15
          DROP $80 AND \    returns HI indicating completion of conversion
       UNTIL           \ until
       0 ADC16@        \ read data register for conversion result
       SWAP            \ pop MSB
       8 SHL +         \ shift MSB and combine with LSB
    ;
    
    
    : 2s>R DUP #32767 > IF #65536 - THEN  \ convert 16 bit twos complement number to real decimal
    ;
    
    
    

    If anyone sees where it could be improved - have at it. If it is useful to anyone . . . enjoy.

    I have also written a Excel sheet to assist in compiling the configuration value . . . which I have just attempted to attach and get an "Invalid File" error. Does the Forum not allow *.xlsx files? It sure is useful to me.
  • artkennedyartkennedy Posts: 164
    edited 2014-05-30 - 15:00:07
    I changed 2s>R to allow designated bit lengths.
    I imagine this has been done before but I didn't find it so I did it again. Good practice.

    "2s>R" might not be the best name.
    Should it be called something else?
    FORGET ADC16@
    
    
    : ADC16@           \ read contents from a TI-1115 register ( rp --- msb lsb ) rp = TI-1115 register pointer
       I2CSTART        \ wakeup call
       $90 I2C!        \ send address $48 plus write bit
       I2C!            \ write rp to pointer register
       I2CSTART        \ not done yet
       $91 I2C!        \ send address $48 plus read bit
       ackI2C@         \ get MSB of target register
       ackI2C@         \ get LSB
       I2CSTOP         \ that's all for now
    ;
    
    
    : ADC16!           \ get write n to TI-1115 register rp ( n rp --- n )
       I2CSTART        \ wakeup call
       $90 I2C!        \ send address $48 plus write bit
       I2C!            \ write rp to pointer register
       DUP 8 SHR       \ get MSB
       I2C!            \ write to target register
       $FF AND I2C!    \ write LSB
       I2CSTOP         \ that's all for now
    ;
    
    
    $8BA3 CONSTANT ADcfg
    
    
    : ADC16cfg         \ ( 16b --- ) \ configure per 16bit input value
                       \    see table of values in C:\Users\Art\Documents\Tech\!Propeller\ADC Add On\ADC_Board.txt
       1 ADC16!        \ point to config register and write
    ;
    
    
    : ADC16ss          \ get Single-Shot reading from TI-1115  ( 16b --- MSBrd LSBrd ) configuration --- result
       ADcfg ADC16cfg  \ config and trigger conversion - temp, hard coded configuration
       BEGIN           \ repeat
          1 ADC16@     \    config register, bit 15
          DROP $80 AND \    returns HI indicating completion of conversion
       UNTIL           \ until
       0 ADC16@        \ read data register for conversion result
       SWAP            \ pop MSB
       8 SHL +         \ shift MSB and combine with LSB
    ;
    
    
    : 2s>R      \ ( n len --- n1 ) n = twos complement number, len = bit length, n1 = converted to signed decimal number
    1- 2 SWAP ^ \ compute 2 ^ (bitlen - 1)
    2DUP        \ copy for test
    => IF       \ if n greater it is negative
       2 * -    \    n - 2 ^ len
    ELSE        \ else n is positive
       DROP     \    no change necessary
    THEN        \ then
    ;
    
  • artkennedyartkennedy Posts: 164
    edited 2014-05-30 - 15:02:38
    My last two posts are not really replies to [h=2]Re: MAX31855 SPI ADC for Thermocouples DRIVER[/h]But to the ongoing Tachyon thread.

    Oops!
  • D.PD.P Posts: 790
    edited 2014-05-31 - 08:29:47
    artkennedy wrote: »
    My last two posts are not really replies to [h=2]Re: MAX31855 SPI ADC for Thermocouples DRIVER[/h]But to the ongoing Tachyon thread.

    Oops!

    Hi Art,

    I saw your post in the other thread with Tracy responding with the spin objects he wrote for the chip (ADS1111).

    Looking forward to see how you go about the "math" that Tracy provided.

    I'm sure as soon as Peter gets some more Tachyon cycles we will see F32 as a loadable module, I plan to just use this in an empty cog as a full time floating point math engine
    since I want to calculate saturation dew point temperatures and hence RH using standard saturation vapor point equations.
  • MJBMJB Posts: 1,165
    edited 2014-05-31 - 15:24:40
    artkennedy wrote: »
    My last two posts are not really replies to Re: MAX31855 SPI ADC for Thermocouples DRIVER

    But to the ongoing Tachyon thread.

    Oops!
    you can go back EDIT POST / Go ADVANCED and change the title
  • artkennedyartkennedy Posts: 164
    edited 2014-06-01 - 16:43:00
    Thanks. Did that.
    MJB wrote: »
    you can go back EDIT POST / Go ADVANCED and change the title
  • Peter JakackiPeter Jakacki Posts: 9,335
    edited 2014-06-01 - 18:27:35
    artkennedy wrote: »
    I changed 2s>R to allow designated bit lengths.
    I imagine this has been done before but I didn't find it so I did it again. Good practice.

    "2s>R" might not be the best name.
    Should it be called something else?
    FORGET ADC16@
    
    
    : ADC16@           \ read contents from a TI-1115 register ( rp --- msb lsb ) rp = TI-1115 register pointer
       I2CSTART        \ wakeup call
       $90 I2C!        \ send address $48 plus write bit
       I2C!            \ write rp to pointer register
       I2CSTART        \ not done yet
       $91 I2C!        \ send address $48 plus read bit
       ackI2C@         \ get MSB of target register
       ackI2C@         \ get LSB
       I2CSTOP         \ that's all for now
    ;
    
    
    : ADC16!           \ get write n to TI-1115 register rp ( n rp --- n )
       I2CSTART        \ wakeup call
       $90 I2C!        \ send address $48 plus write bit
       I2C!            \ write rp to pointer register
       DUP 8 SHR       \ get MSB
       I2C!            \ write to target register
       $FF AND I2C!    \ write LSB
       I2CSTOP         \ that's all for now
    ;
    
    
    $8BA3 CONSTANT ADcfg
    
    
    : ADC16cfg         \ ( 16b --- ) \ configure per 16bit input value
                       \    see table of values in C:\Users\Art\Documents\Tech\!Propeller\ADC Add On\ADC_Board.txt
       1 ADC16!        \ point to config register and write
    ;
    
    
    : ADC16ss          \ get Single-Shot reading from TI-1115  ( 16b --- MSBrd LSBrd ) configuration --- result
       ADcfg ADC16cfg  \ config and trigger conversion - temp, hard coded configuration
       BEGIN           \ repeat
          1 ADC16@     \    config register, bit 15
          DROP $80 AND \    returns HI indicating completion of conversion
       UNTIL           \ until
       0 ADC16@        \ read data register for conversion result
       SWAP            \ pop MSB
       8 SHL +         \ shift MSB and combine with LSB
    ;
    
    
    : 2s>R      \ ( n len --- n1 ) n = twos complement number, len = bit length, n1 = converted to signed decimal number
    1- 2 SWAP ^ \ compute 2 ^ (bitlen - 1)
    2DUP        \ copy for test
    => IF       \ if n greater it is negative
       2 * -    \    n - 2 ^ len
    ELSE        \ else n is positive
       DROP     \    no change necessary
    THEN        \ then
    ;
    

    Hi Art, I had a look at this code when you first posted it but I've been a bit busy since, as always. The code looks clean and tidy and the only real critique I would have is that you should always standardize the get and put method as you have ADC16! requiring a 16-bit word for the data yet ADC16@ returns with that same word split into two bytes. Here's my take on your original code.
    [FONT=courier new]FORGET ADC16@
    
    $90    == @ADC --- adc 8-bit I2C address
    
    : ADC16@ ( reg -- dat16 )           \ read contents from a TI-1115 register
       I2CSTART        \ wakeup call
       @ADC I2C!       \ send address $48 plus write bit
       I2C!            \ write rp to pointer register
       I2CSTART        \ not done yet
       @ADC 1+ I2C!    \ send address $48 plus read bit
       ackI2C@         \ get MSB of target register
       ackI2C@         \ get LSB
       SWAP B>W        \ combine bytes into a word
       I2CSTOP         \ that's all for now
    ;
    
    
    : ADC16! ( dat16 reg -- )           \ get write n to TI-1115 register rp ( n rp --- n )
       I2CSTART        \ wakeup call
       @ADC I2C!       \ send address $48 plus write bit
       I2C!            \ write rp to pointer register
       W>B             \ Split word into high and low bytes ( bytel byteh )
       I2C!            \ write MSB to target register
       I2C!            \ write LSB
       I2CSTOP         \ that's all for now
    ;
    
    
    $8BA3 CONSTANT ADcfg
    
    
    : ADC16ss ( config -- data16 ) \ get Single-Shot reading from TI-1115
       ADcfg 1 ADC16!  \ config and trigger conversion - temp, hard coded configuration
       BEGIN          \ repeat
          1 ADC16@     \    config register, bit 15
          $8000 AND    \    returns HI indicating completion of conversion
       UNTIL          \ until
       0 ADC16@        \ read data register for conversion result
    ;
    
    --- extend sign of 16-bit word into a long
    : EXT16 ( sign16 -- sign32 ) DUP $8000 AND IF $1.0000 - THEN  \ convert 16 bit twos complement number to real decimal
    ;
    
    [/FONT]
    
  • D.PD.P Posts: 790
    edited 2014-06-02 - 16:50:12
    Hi Art, I had a look at this code when you first posted it but I've been a bit busy since, as always. The code looks clean and tidy and the only real critique I would have is that you should always standardize the get and put method as you have ADC16! requiring a 16-bit word for the data yet ADC16@ returns with that same word split into two bytes. Here's my take on your original code.

    I see the beginnings of CREATE DOES in the comments section of tachyon 06/02, hmmm.
  • Peter JakackiPeter Jakacki Posts: 9,335
    edited 2014-06-02 - 18:39:35
    D.P wrote: »
    I see the beginnings of CREATE DOES in the comments section of tachyon 06/02, hmmm.

    My EPRINT routine which stores literal print strings to spare EEPROM instead of program memory is the reason I'm looking into it.

    TF is setup for compactness as well as speed and certain decisions were made at the time in this regard. I'm not quite sure why I ended up using bytecode rather than a pointer in the header field but this made sense since bytecodes are compiled, not pointers. Some bytecode are calls via a vector table which then points to the code, once again this keeps the actual code compact at 2 bytes rather than 3 but adds the overhead of a table. The advantage of the table is that addresses can be extended to beyond 64K and still compile no more than 2 bytes, something that makes the transition to P2 easier.

    So back to the CREATE DOES, I trying to think how best to implement this in TF given it's internal quirks. If you see a way that works, such as in EPRINT then by all means please suggest it! :)

    I've just trimmed the kernel again by removing some fast constants such as 5,6,7 and optimizing the code. I added >N and >B to perform quick nibble and byte masking ops as it is quite common to say $0F AND or $FF AND but this would take 3 bytes and 2.6us but now uses only a single byte and takes 400ns.

    EDIT: Just thought of another way to generate fast literals, so instead of adding to an accumulator I use the pasm MIN instead to load the literal accumulator ACC which is normally zeroed and then set the carry which is normally cleared on every bytecode. So this works a treat and lets me put in any value in any order.
    7704(0081) 21 4E CF 49 | BL        if_nc         min        ACC,#32+1 wc
    7708(0082) 11 4E CF 49 | _16       if_nc         min        ACC,#16+1 wc
    770C(0083) 09 4E CF 49 | _8        if_nc         min        ACC,#8+1 wc
    7710(0084) 04 4E CF 49 | _3        if_nc         min        ACC,#3+1 wc
    7714(0085) 05 4E CF 49 | _4        if_nc         min        ACC,#4+1 wc
    7718(0086) 03 4E CF 49 | _2        if_nc         min        ACC,#2+1 wc
    771C(0087) 02 4E CF 49 | _1        if_nc         min        ACC,#1+1 wc
    7720(0088)             | _TRUE
    7720(0088) 01 4E FF 84 | MINUS1                  sub        ACC,#1
    7724(0089)             | _FALSE
    7724(0089) 7F 00 7C 5C | _0                      jmp        #PUSHACC
    

  • D.PD.P Posts: 790
    edited 2014-06-03 - 11:49:18
    My EPRINT routine which stores literal print strings to spare EEPROM instead of program memory is the reason I'm looking into it.

    TF is setup for compactness as well as speed and certain decisions were made at the time in this regard. I'm not quite sure why I ended up using bytecode rather than a pointer in the header field but this made sense since bytecodes are compiled, not pointers. Some bytecode are calls via a vector table which then points to the code, once again this keeps the actual code compact at 2 bytes rather than 3 but adds the overhead of a table. The advantage of the table is that addresses can be extended to beyond 64K and still compile no more than 2 bytes, something that makes the transition to P2 easier.

    So back to the CREATE DOES, I trying to think how best to implement this in TF given it's internal quirks. If you see a way that works, such as in EPRINT then by all means please suggest it! :)

    I've just trimmed the kernel again by removing some fast constants such as 5,6,7 and optimizing the code. I added >N and >B to perform quick nibble and byte masking ops as it is quite common to say $0F AND or $FF AND but this would take 3 bytes and 2.6us but now uses only a single byte and takes 400ns.

    EDIT: Just thought of another way to generate fast literals, so instead of adding to an accumulator I use the pasm MIN instead to load the literal accumulator ACC which is normally zeroed and then set the carry which is normally cleared on every bytecode. So this works a treat and lets me put in any value in any order.
    7704(0081) 21 4E CF 49 | BL        if_nc         min        ACC,#32+1 wc
    7708(0082) 11 4E CF 49 | _16       if_nc         min        ACC,#16+1 wc
    770C(0083) 09 4E CF 49 | _8        if_nc         min        ACC,#8+1 wc
    7710(0084) 04 4E CF 49 | _3        if_nc         min        ACC,#3+1 wc
    7714(0085) 05 4E CF 49 | _4        if_nc         min        ACC,#4+1 wc
    7718(0086) 03 4E CF 49 | _2        if_nc         min        ACC,#2+1 wc
    771C(0087) 02 4E CF 49 | _1        if_nc         min        ACC,#1+1 wc
    7720(0088)             | _TRUE
    7720(0088) 01 4E FF 84 | MINUS1                  sub        ACC,#1
    7724(0089)             | _FALSE
    7724(0089) 7F 00 7C 5C | _0                      jmp        #PUSHACC
    

    Neat!

    I have a few spinnerettes that I would like to use. Do you have any backups of Tachyon V2.1 and W5100.fth that support UDP clients? I have tried links on the drop box but couldn't get any UDP client "action" to work. I have telnet, ftp working but no UDP client. My current build is:
    Propeller .:.:--TACHYON--:.:. Forth V21130620.0000
    
    NAMES:  $5D96...7444 for 5806 (19120 bytes added) with 21546 bytes free
    CODE:   $0000...2ECB for 6173 (0922 bytes added) with 20789 bytes free
    CALLS:  0511 vectors free
    
    AUTORUN BOOT
    MODULES LOADED:
    2B31: WIZNET.fth          WIZNET 5100/5200 driver 130216.1500
    1880: EXTEND.fth          Primary extensions to TACHYON kernel - 130722.0000
    ----------------------------------------------------------------
    

    I can't find what I did to get UDP clients working during this timeframe.

    UPDATE: oh snap, the version of W5100 driver doesn't have these two helper words to set destination and port
    pub DIP ( ip -- )  sDIP WIZ4! ;   \ destination IP
    pub DPORT ( port -- ) sDPORT WIZ2! ; \ destination PORT
    
    Got confused with the UIP and UPORT words. All better, it's funny how just posting a question to the forum help to resolve issues without any feedback!
  • MJBMJB Posts: 1,165
    edited 2014-06-04 - 00:10:51
    My EPRINT routine which stores literal print strings to spare EEPROM instead of program memory is the reason I'm looking into it.
    <snip>
    So back to the CREATE DOES, I trying to think how best to implement this in TF given it's internal quirks. If you see a way that works, such as in EPRINT then by all means please suggest it! :)
    <snip>
    My understanding:
    CREATE DOES> is used to create so called DEFINING WORDS like
    : VARIABLE CONSTANT and the like.
    from FORTH PRIMER:
    
    Michael Ham has called the word pair [B][COLOR=red]CREATE...DOES>[/COLOR][/B], the “pearl of Forth”. 
    [B][COLOR=red]CREATE[/COLOR][/B] is a component of the compiler, whose function is to make a new 
    dictionary entry with a given name (the next name in the input stream) 
    and nothing else. [B][COLOR=red]
    DOES>[/COLOR][/B] assigns a specific run-time action to a newly [B]CREATE[/B]d word.  
    a. [B]Defining “defining” words[/B]          [B]
    CREATE[/B] finds its most important use in extending the powerful class of         
    Forth words called “defining” words. The colon compiler  "[B][COLOR=red]:[/COLOR][/B]"  is such         
    a word, as are [B]VARIABLE[/B] and [B]CONSTANT[/B].          
    The definition of [B]VARIABLE[/B] in high-level Forth is simple              
    [COLOR=red]: VARIABLE  CREATE   1 CELLS  ALLOT ;[/COLOR]         
    We have already seen how [B]VARIABLE[/B] is used in a program. (An 
    alternative definition found in some Forths is             
    [COLOR=red]: VARIABLE  CREATE   0  ,  ;[/COLOR]         —these variables are initialized to 0.)         
    Forth lets us define words initialized to contain specific values: for        
    example, we might want to define the number 17 to be a word. [B]
    CREATE[/B]        and "[B][COLOR=red],[/COLOR][/B]" ("comma") can do this:             [COLOR=red]
    17 CREATE SEVENTEEN  ,[/COLOR]  <cr>  ok         
    Now test it via             [COLOR=red]
    SEVENTEEN @ .[/COLOR]  <cr>  17 ok .          
    Remarks:            
    > The word [B][COLOR=red],[/COLOR][/B] ("comma") puts TOS into the next cell of the dictionary
    and increments the dictionary pointer by that number of bytes.           
    > A word "[B][COLOR=red]C,[/COLOR][/B]" ("see-comma") exists also — it puts a character into            
    the next character-length slot of the dictionary and increments            
    the pointer by 1 such slot. (In the ASCII character representation            
    the slots are 1 byte long; Unicode characters require 2 bytes.)          
    
    b. [B]Run-time [I]vs.[/I] compile-time actions[/B]         
     In the preceding example, we were able to initialize the variable         [B]
    SEVENTEEN[/B] to 17 when we [B]CREATE[/B]d it, but we still have to fetch it to         
    the stack [I]via[/I] [B]SEVENTEEN  @[/B] whenever we want it. This is not quite what        
    we had in mind. We would like to find 17 in TOS when [B]SEVENTEEN[/B] is         
    named. The word [B]DOES>[/B] gives us the tool to do this.          
    The function of [B]DOES>[/B] is to specify a run-time action for the “child”         
    words of a defining word.  Consider the defining word [B]CONSTANT[/B] , 
    defined in high-level (of course [B]CONSTANT[/B] is usually defined in machine        
    code for speed) Forth by             [COLOR=red]
    : CONSTANT  CREATE  ,  DOES>  @  ; [/COLOR]         
    and used as              [COLOR=red]
    53 CONSTANT PRIME[/COLOR]  <cr> ok          
    Now test it:             
    [COLOR=red]PRIME .[/COLOR] <cr>  53  ok .           
    What is happening here?            
    > [B]CREATE[/B] (hidden in [B]CONSTANT[/B]) makes an entry named [B]PRIME[/B] 
    (the first word in the input stream following [B]CONSTANT[/B]). Then "[B][COLOR=red],[/COLOR][/B]"             
    places the TOS (the number 53) in the next cell of the dictionary.           
    > Then [B]DOES>[/B] (inside [B]CONSTANT[/B]) appends the actions of all words 
    between it and "[B][COLOR=red];[/COLOR][/B]" (the end of the definition) —in this case, "[B][COLOR=red]@[/COLOR][/B]"—             
    to the child word(s) defined by [B]CONSTANT[/B].
    

    in TACHYON there is CREATE ( precompiled kernel code )
    which creates the dictionary entry,
    reads the next word as a name for the newly created word
    and then assigns the default BEHAVIOR - which is the code of VARB - makes it a variable,
    means, it just puts it's address on the stack at runtime.
    ' CREATE <name> - Create a name in the dictionary and also a code entry 
    CREATE    byte    REG,createvec,WFETCH,QDUP,_IF,01,AJMP        ' execute extended or user CREATE?
         byte    XCALL,xCREATEWORD            ' 
        byte    _BYTE,VARB,XCALL,xBCOMP,_0        ' set default bytecode as a VARIABLE
    ' ALLOT ( bytes -- )
    ALLOT    byte    REG,codes,WPLUSST
    ALLOCATED
         byte    REG,codes,WFETCH,REG,here,WSTORE
         byte    EXIT
    

    so a DOES> could just create a dummy word, compile the code following DOES> to it
    AND then put the new byte code to the previous definitions PFA.

    But I do not see the relation to the new PRINT" word.

    I think PRINT" is not a normal defining word since it does not define a new word each time it is called,
    as compared to what VARIABLE or CONSTANT do.

    To me it belongs into the category of compiler extension words,
    like the IF DO LOOP etc. words.
    Those have a compile time behavior (like PRINT" copying the chars to EE) and leave BYTECODES
    in the compiled code (like PRINT" retrieving the chars from EE and printing them ).

    I don't feel having a solid grasp on CREATE DOES> so maybe discussing it here a little helps.
  • D.PD.P Posts: 790
    edited 2014-06-04 - 10:11:44
    MJB wrote: »
    My understanding:
    CREATE DOES> is used to create so called DEFINING WORDS like
    : VARIABLE CONSTANT and the like.
    from FORTH PRIMER:
    
    Michael Ham has called the word pair [B][COLOR=red]CREATE...DOES>[/COLOR][/B], the &#8220;pearl of Forth&#8221;. 
    [B][COLOR=red]CREATE[/COLOR][/B] is a component of the compiler, whose function is to make a new 
    dictionary entry with a given name (the next name in the input stream) 
    and nothing else. [B][COLOR=red]
    DOES>[/COLOR][/B] assigns a specific run-time action to a newly [B]CREATE[/B]d word.  
    a. [B]Defining &#8220;defining&#8221; words[/B]          [B]
    CREATE[/B] finds its most important use in extending the powerful class of         
    Forth words called &#8220;defining&#8221; words. The colon compiler  "[B][COLOR=red]:[/COLOR][/B]"  is such         
    a word, as are [B]VARIABLE[/B] and [B]CONSTANT[/B].          
    The definition of [B]VARIABLE[/B] in high-level Forth is simple              
    [COLOR=red]: VARIABLE  CREATE   1 CELLS  ALLOT ;[/COLOR]         
    We have already seen how [B]VARIABLE[/B] is used in a program. (An 
    alternative definition found in some Forths is             
    [COLOR=red]: VARIABLE  CREATE   0  ,  ;[/COLOR]         &#8212;these variables are initialized to 0.)         
    Forth lets us define words initialized to contain specific values: for        
    example, we might want to define the number 17 to be a word. [B]
    CREATE[/B]        and "[B][COLOR=red],[/COLOR][/B]" ("comma") can do this:             [COLOR=red]
    17 CREATE SEVENTEEN  ,[/COLOR]  <cr>  ok         
    Now test it via             [COLOR=red]
    SEVENTEEN @ .[/COLOR]  <cr>  17 ok .          
    Remarks:            
    > The word [B][COLOR=red],[/COLOR][/B] ("comma") puts TOS into the next cell of the dictionary
    and increments the dictionary pointer by that number of bytes.           
    > A word "[B][COLOR=red]C,[/COLOR][/B]" ("see-comma") exists also &#8212; it puts a character into            
    the next character-length slot of the dictionary and increments            
    the pointer by 1 such slot. (In the ASCII character representation            
    the slots are 1 byte long; Unicode characters require 2 bytes.)          
    
    b. [B]Run-time [I]vs.[/I] compile-time actions[/B]         
     In the preceding example, we were able to initialize the variable         [B]
    SEVENTEEN[/B] to 17 when we [B]CREATE[/B]d it, but we still have to fetch it to         
    the stack [I]via[/I] [B]SEVENTEEN  @[/B] whenever we want it. This is not quite what        
    we had in mind. We would like to find 17 in TOS when [B]SEVENTEEN[/B] is         
    named. The word [B]DOES>[/B] gives us the tool to do this.          
    The function of [B]DOES>[/B] is to specify a run-time action for the &#8220;child&#8221;         
    words of a defining word.  Consider the defining word [B]CONSTANT[/B] , 
    defined in high-level (of course [B]CONSTANT[/B] is usually defined in machine        
    code for speed) Forth by             [COLOR=red]
    : CONSTANT  CREATE  ,  DOES>  @  ; [/COLOR]         
    and used as              [COLOR=red]
    53 CONSTANT PRIME[/COLOR]  <cr> ok          
    Now test it:             
    [COLOR=red]PRIME .[/COLOR] <cr>  53  ok .           
    What is happening here?            
    > [B]CREATE[/B] (hidden in [B]CONSTANT[/B]) makes an entry named [B]PRIME[/B] 
    (the first word in the input stream following [B]CONSTANT[/B]). Then "[B][COLOR=red],[/COLOR][/B]"             
    places the TOS (the number 53) in the next cell of the dictionary.           
    > Then [B]DOES>[/B] (inside [B]CONSTANT[/B]) appends the actions of all words 
    between it and "[B][COLOR=red];[/COLOR][/B]" (the end of the definition) &#8212;in this case, "[B][COLOR=red]@[/COLOR][/B]"&#8212;             
    to the child word(s) defined by [B]CONSTANT[/B].
    

    in TACHYON there is CREATE ( precompiled kernel code )
    which creates the dictionary entry,
    reads the next word as a name for the newly created word
    and then assigns the default BEHAVIOR - which is the code of VARB - makes it a variable,
    means, it just puts it's address on the stack at runtime.
    ' CREATE <name> - Create a name in the dictionary and also a code entry 
    CREATE    byte    REG,createvec,WFETCH,QDUP,_IF,01,AJMP        ' execute extended or user CREATE?
         byte    XCALL,xCREATEWORD            ' 
        byte    _BYTE,VARB,XCALL,xBCOMP,_0        ' set default bytecode as a VARIABLE
    ' ALLOT ( bytes -- )
    ALLOT    byte    REG,codes,WPLUSST
    ALLOCATED
         byte    REG,codes,WFETCH,REG,here,WSTORE
         byte    EXIT
    

    so a DOES> could just create a dummy word, compile the code following DOES> to it
    AND then put the new byte code to the previous definitions PFA.

    But I do not see the relation to the new PRINT" word.

    I think PRINT" is not a normal defining word since it does not define a new word each time it is called,
    as compared to what VARIABLE or CONSTANT do.

    To me it belongs into the category of compiler extension words,
    like the IF DO LOOP etc. words.
    Those have a compile time behavior (like PRINT" copying the chars to EE) and leave BYTECODES
    in the compiled code (like PRINT" retrieving the chars from EE and printing them ).

    I don't feel having a solid grasp on CREATE DOES> so maybe discussing it here a little helps.

    I've been reading through material on CREATE DOES> as well. This is very powerful and I can see it as a way to create arrays that have indexing methods, create words that parse themselves etc.

    Also when I stumble upon syntax such as this I am humbled by its eligance and brevity although the mental gymnastics of pushing a few parameters around in headspace can be hard for the beginner it is getting easier all the time.

    So I am not qualified to give input on an approach for CREATE DOES> implementation in Tachyon, yet!
    --- revision 140602 - Added timeout loop counter to prevent hanging
    
    pub @EEWAIT ( adr --  )
    
              #50 BEGIN 1- OVER @EE 0= OVER 0= OR UNTIL 2DROP
    
            ;
    
  • D.PD.P Posts: 790
    edited 2014-06-04 - 11:13:55
    I have a version of Tachyon running on the spinneret with the appropriate Wiznet.fth module. The module works properly. I have a K30 CO2 senor connected to the I2C bus same as standard EEPROM.
    I have words that access the sensor correctly. I can redirect output via the Lan connection just fine, but as soon as I issue any I2C commands i.e. I2CSTART, the networking hangs completely. I don't see any conficts in the ESPIO section in the source or in the Wiznet.fth driver.

    ?

    Thanks
      Propeller .:.:--TACHYON--:.:. Forth V21130620.0000
    
    MODULES LOADED:
    2ED5: K30.fth             Air Sense C02 Sensor Driver 140602-11:00
    2B31: WIZNET.fth          WIZNET 5100/5200 driver 130216.1500
    1880: EXTEND.fth          Primary extensions to TACHYON kernel - 130722.0000
     ok
    

    Here's the code in question, you can see the debugging in BEGIN UNTIL loop. Commenting out the I2CSTART I2CSTOP line and the networking runs correctly.

    The rc2 word that reads the sensor works correctly as well.
    pub lanC
      #27 #26 I2CPINS              \ set i2c pins other than eeprom - conflict testing
      DECIMAL                      \ set us in decimal mode
      CR ." Setting up networking.... " CR
      !WIZIO                        \ initialize the wiznet SPI setup for spinnerette
      #20 ms
      &192.168.10.1 GATEWAY         \ set the gateway
      &255.255.255.0 SUBNET         \ subnet
      &192.168.10.80 SRCIP          \ source ip
      $00.08 $DC.01.02.03 SHAR      \ mac
      #50 ms
      0 SOCKET CLOSE		\ select socket 0 and force it into life with CLOSE
      #50 ms
      UDP		   	  \ enable socket MODE UDP
      #33333 PORT             \ source port
      #22222 DPORT		  \ destination  port  22222
      &192.168.10.10 DIP      \ destination  ip
      #50 ms
      OPEN                    \ open the socket
      #50 ms
      lEmit                   \ redirect output to lan
      BEGIN
         I2CSTART I2CSTOP
    \     rc2 DROP                         \ get a co2 reading
    \    0= IF CO2? W@ DUP #10000 <        \ if the ack flag from the IC2 write is zero make sure value < #10K
    \       IF  co2$ .STR  CO2? W@ . CR            \ then write the banner and the value
          co2$ .STR  CO2? W@ . CR            \ then write the banner and the value
    \
    \      ELSE DROP                       \ num > #10K drop the dup
    \      THEN
    \    THEN
      #1500 ms
      ESC? UNTIL                   \ esc key pressed ?
      CON                                 \ redirect back to console
      EEPROM                              \ set i2c pins back to eeprom
    ;
    
  • Dave HeinDave Hein Posts: 6,061
    edited 2014-06-04 - 12:50:07
    On the subject of DOES>, pfth includes a 16-bit address in the dictionary entry for each word that points to the DOES> code. This value is normally set to zero unless DOES> is specified. The variable kernel function will load the address of the word's body onto the stack, and then jump to the DOES> code if the pointer is non-zero. You may want to have two different variable kernel functions where one is used when DOES> is specified and the other is used when DOES> is not specified.
  • Peter JakackiPeter Jakacki Posts: 9,335
    edited 2014-06-04 - 15:45:54
    D.P wrote: »
    I have a version of Tachyon running on the spinneret with the appropriate Wiznet.fth module. The module works properly. I have a K30 CO2 senor connected to the I2C bus same as standard EEPROM.
    I have words that access the sensor correctly. I can redirect output via the Lan connection just fine, but as soon as I issue any I2C commands i.e. I2CSTART, the networking hangs completely. I don't see any conficts in the ESPIO section in the source or in the Wiznet.fth driver.

    I see that you are using an earlier kernel and I think that since I2C uses the CLOCK word which uses a mask in a COGREG to toggle the SCL line that this also overwrites one of the SPIO COGREGs. V2.3 uses a separate COGREG for CLOCK but maybe as a quick hack you could patch your I2C routines by replacing any reference to CLOCK sequences such as CLOCK NOP CLOCK with SCL PINSET SCL PINCLR just as a quick suggestion. The timing is a little slower but that shouldn't matter.
  • D.PD.P Posts: 790
    edited 2014-06-04 - 17:28:39
    I see that you are using an earlier kernel and I think that since I2C uses the CLOCK word which uses a mask in a COGREG to toggle the SCL line that this also overwrites one of the SPIO COGREGs. V2.3 uses a separate COGREG for CLOCK but maybe as a quick hack you could patch your I2C routines by replacing any reference to CLOCK sequences such as CLOCK NOP CLOCK with SCL PINSET SCL PINCLR just as a quick suggestion. The timing is a little slower but that shouldn't matter.

    You are correct, all is well in spinneret land, thanks.

    This comment made me not question any conflicts in the older kernel.
    130605        Modified the CLOCK instruction which is used by I2C routines to use COGREG 4 as the clock mask rather than 0 to prevent conflict with SPI routines which may be operating at the same time.
    
    
  • MJBMJB Posts: 1,165
    edited 2014-06-05 - 05:06:36
    \MJB thoughts about create does> for Tachyon
    {
     : CONSTANT  CREATE  ,  DOES>  @  ; 
    
           and used as 
    
               53 CONSTANT PRIME  <cr> ok 
    
           Now test it:
    
               PRIME . <cr>  53  ok . 
    }
    
    : ` [COMPILE] [COMPILE] ;
    
    : mjbCREATE  
    \ will be stored in the ucreate vector so can be used by new code ...
    \ not sure if this is good ... or need to use another name since create and CREATE are in use already ...
    \ maybe Create  ;-)
        ` CREATEWORD 
        \ insert CFA of NEXT definition - which will be created by does> 
        \ so either does> does the substitution and places it's newly created dummy word PFA here,
        \ or we start from this word and search at runtime for the next words PFA
        \ then continue compiling the create part of the create does> pair.
        
        \ DOES> first performs a ; to finish the definition, the CREATE is part of.
        \ then DOES> starts a new dummy definition  pri  dummyXYZ
        \ and stores the PFA into the previous definition, so at each execution of the creation of a new 
        \ child word, the child words PFA gets set correctly.
        \ can the dummy definitions NAME be removed from the dictionary already now, before it is completed ???
    
        \ now all code following DOES> gets compiled into the dummy definition
        \ which is automatically completed with the next  ;
    
  • MJBMJB Posts: 1,165
    edited 2014-06-05 - 05:16:24
    D.P wrote: »
    I have a version of Tachyon running on the spinneret with the appropriate Wiznet.fth module.
      Propeller .:.:--TACHYON--:.:. Forth V21130620.0000
    
    MODULES LOADED:
    2ED5: K30.fth             Air Sense C02 Sensor Driver 140602-11:00
    2B31: WIZNET.fth          WIZNET 5100/5200 driver 130216.1500
    1880: EXTEND.fth          Primary extensions to TACHYON kernel - 130722.0000
     ok
    
    <snip>
    hi D.P. I have an idle Spinneret sitting here waiting for Tachyon as well :-)
    I want to use it as the internet gateway to my sensor/actor network I am setting up here.

    The kernel, Extend and Wiznet versions are from DROPBOX ?
    Original or did you have to adapt things?

    As I understand the WIZNET.fth for W5100 does not run with Tachyon2.3 ??
    That's why I postponed my Spinneret experiments atm. ( busy with construction site, house in the mountains ..)
    Thanks MJB
  • Peter JakackiPeter Jakacki Posts: 9,335
    edited 2014-06-05 - 08:31:35
    MJB wrote: »
    hi D.P. I have an idle Spinneret sitting here waiting for Tachyon as well :-)
    I want to use it as the internet gateway to my sensor/actor network I am setting up here.

    The kernel, Extend and Wiznet versions are from DROPBOX ?
    Original or did you have to adapt things?

    As I understand the WIZNET.fth for W5100 does not run with Tachyon2.3 ??
    That's why I postponed my Spinneret experiments atm. ( busy with construction site, house in the mountains ..)
    Thanks MJB

    I will revisit the W5100 and see if I can modify W5200.fth to work with it. That way it will just fit in with all the new stuff, even the microSD.
  • Dave HeinDave Hein Posts: 6,061
    edited 2014-06-05 - 08:57:20
    I was going to try implementing DOES> in Tachyon, but I can't seem to find the Tachyon source code. I have been able to download it before, but I can't recall where I got it. Every link I click on sends me to web pages with lots of documentation on Tachyon, and I can't find a link for the source. The link is probably buried somewhere in the documentation. Does anybody know the direct link to the source code?
  • Peter JakackiPeter Jakacki Posts: 9,335
    edited 2014-06-05 - 09:35:01
    Dave Hein wrote: »
    I was going to try implementing DOES> in Tachyon, but I can't seem to find the Tachyon source code. I have been able to download it before, but I can't recall where I got it. Every link I click on sends me to web pages with lots of documentation on Tachyon, and I can't find a link for the source. The link is probably buried somewhere in the documentation. Does anybody know the direct link to the source code?
    Yes, the intro points to the links page and it's in there but here it is as well
  • Dave HeinDave Hein Posts: 6,061
    edited 2014-06-05 - 09:50:20
    Yes, I've run into that page a few times, but where's the link to the Spin files or a zip file?
  • Dave HeinDave Hein Posts: 6,061
    edited 2014-06-05 - 09:59:06
    Here are a few words that I use to implement DOES> in the Fast forth interpreter. The word DOES> is used only during compilation, and it inserts the word _DOES into the compiled word, which is a runtime word. _DOES is followed by EXIT, and then followed by the code defined after DOES>. The _DOES word will add a pointer to this code to the header of the last word defined.
    \ WORD HEADER ACCESSORS
    : >does 1+ ;
    : >body 4 + ;
    : link>does link>xt 1+ ;
    : link>body link>xt 4 + ;
    
    \ DEFINE DOES> WORDS
    : cc! over 8 rshift over c! 1+ c! ;
    : _does r> dup >r 1+ last @ link>does cc! ;
    : does> compile _does [compile] exit ; immediate
    
    \ WORDS THAT USE DOES>
    : marker create last @ , does> @ dup dp ! @ last ! ;
    : defer  create 0 , does> @ execute ;
    : value create , does> @ ;
    : 2constant create swap , , does> dup @ swap cellsize + @ ;
    
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-06-05 - 10:08:58
    Dave Hein wrote: »
    Yes, I've run into that page a few times, but where's the link to the Spin files or a zip file?

    There's a link to the Tachyon Dropbox in Peter's signature.
  • Dave HeinDave Hein Posts: 6,061
    edited 2014-06-05 - 10:10:33
    Here's the Fast Forth PASM code that implements the kernel code used for words that are created using CREATE. It loads the address of the body onto the stack, and then checks for a non-zero pointer. If the pointer is zero it just exits the word. Otherwise, it jumps to the DOES> code by setting the PC equal to the pointer. To prevent normal variables by being slowed down by the DOES> code you use a kernel word that does not support the pointer, and have another kernel word that is only used for words that do have a DOES> pointer. CREATE could default to the non-does kernel word, and the DOES> word could replace it with the other word that supports DOES>.
    _var                    wrlong  nos, dstackptr
                            mov     nos, tos
                            mov     tos, pc
                            rdbyte  temp1, pc
                            add     pc, #1
                            add     tos, #3
                            rdbyte  pc, pc
                            shl     temp1, #8
                            or      pc, temp1       wz
                            add     dstackptr, #4
          if_z              jmp     #exit
                            jmp     #innerloop
    
Sign In or Register to comment.