Shop OBEX P1 Docs P2 Docs Learn Events
TACHYON O/S V3.0 JUNO - Furiously Fast Forth, FAT32+LAN+VGA+RS485+OBEX ROMS+FP+LMM+++ - Page 74 — Parallax Forums

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

17172747677109

Comments

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-11-08 01:06
    Seems the device itself is not I2C compliant then :) SDA is allowed to do whatever it likes while the clock is low as transitions on SDA while clock is high have the START/STOP condition meanings.

    However if you change this second line in I2C! (also I2C!?) from:
    SDA DUP OUTSET SWAP					\ data masks
    
    to
    SDA DUP OUTCLR SWAP					\ data masks
    

    it should keep that non-compliant chip happy.
  • Thanks Peter that did the trick. Sensor is responsive now. It's an AllSensors DLVR-L30D 14bit pressure sensor.
  • I need a little help with SWITCH CASE BREAK.
    I am probably thinking about this incorrectly but it seems to me there needs to be CASE ELSE and CASE END structure.
    Maybe there is a way to do CASE ELSE with the existing words . . .
    Also it seems instructions in the same block after the last CASE BREAK are ignored.

    What am I missing?
  • FORGET FROB
    : FROB
      SWITCH
      "A" CASE ." AYE" BREAK
      "S" CASE ." SIR" BREAK
      ." FLOGGING"
    ;
    
    Well . . . that works as expected . . . so where is my issue? It seems to arise in some more complicated code.
    Standby -
  • Okay, I can see now that the code after the last BREAK functions as CASE ELSE but how do I do CASE END?
  • MJBMJB Posts: 1,235
    artkennedy wrote: »
    Okay, I can see now that the code after the last BREAK functions as CASE ELSE but how do I do CASE END?

    Hi Art,
    The Tachyon Select/Case structure is similar, but also different from C.
    - there is no END CASE - so SELECTS can not be nested directly.
    It works very simple.
    SELECT stores a value into the compare variable.
    CASE compares a given value with the stored compare variable value
    and then performs an IF. BREAK defines the end of the IF.
    A new SELECT just stores a new value into the compare variable.
    
    { TACHYON CASE STRUCTURES
    This implementation follows the C method to some degree.
    Each CASE statement simply compares the supplied value with the SWITCH and executes an IF
    To prevent the IF statement from falling through a BREAK is used (also acts as a THEN at CT)
    The SWITCH can be tested directly and a manual CASE can be constructed with IF <code> BREAK
    
    SWITCH ( switch -- )             \ Save switch value used in CASE structure
    CASE ( val -- )                  \ compare val with switch and perform an IF. Equivalent to SWITCH= IF
    BREAK                            \ EXIT (return) but also completes IF structure at CT. Equivalent to EXIT THEN
    \ extra functions to allow the switch to be manipulated etc
    SWITCH@ ( -- switch )            \ Fetch last saved switch value
    SWITCH= ( val -- flg )           \ Compare val with switch. Equivalent to SWITCH@ =
    SWITCH>< ( from to -- flg )    \ Compare switch within range. Equivalent to SWITCH@ ROT ROT WITHIN
    
    Usage:
    
    pub CASEDEMO  ( val -- )
       SWITCH                \ use the key value as a switch in the case statement
       "A" CASE CR ." A is for APPLE " BREAK
       "H" CASE CR ." H is for HAPPY " BREAK
       "Z" CASE CR ." Z is for ZEBRA " BREAK
       $08 CASE 4 REG ~ BREAK
       \ Now accept 0 to 9 and build a number calculator style
       "0" "9" SWITCH>< IF SWITCH@ $30 - 4 REG @ #10 * + 4 REG ! ." *" BREAK
       \ On enter just display the accumulated number
       $0D CASE CR ." and our lucky number is " 4 REG @ .DEC BREAK
       \ show how we can test more than one value
       "Q" SWITCH= "X" SWITCH= OR IF CR ." So you're a quitter hey?" CR CONSOLE BREAK
       CR ." I don't know what " SWITCH@ EMIT ."  is"
        ;
    pub DEMO
       BEGIN WKEY UPPER CASEDEMO AGAIN
     ;
    
    

  • Thanks, MJB. I am not C literate so I am not familiar with the SELECT word you mention. I suppose you are referring to the conditions tested by the CASE words. My problem is that code after I am finished testing for the SWITCH is treated as a CASE ELSE in that it is only processed if none of the cases are true. If one of the cases is true the code following the last BREAK is skipped. I don't understand how to work with that. The rest is indeed simple and I have previously studied the source and can't find an answer. Maybe the Forth word has to end after the last BREAK. . . ?
  • There is one thing to watch with this switch case break in that since the break is compiled as a "exit then" then it won't try to execute anything else as if you could tell it to jump to an end case and continue. This keeps it simple and efficient and so you should factor the case statements together in their own routine rather than one big long routine that continues on and on long after.
  • Hi,
    I've uploaded the Tachyon explorer and got the follwing boot screen:

    Propeller .:.:--TACHYON--:.:. Forth V27150720.2030

    VER: Propeller .:.:--TACHYON--:.:. Forth V27150720.2030
    FREQ: 80MHZ (PLLEN OSCEN XTAL1 PLL16X)
    NAMES: $5567...716B for 7,172 bytes (+4,662)
    CODE: $0924...3F13 for 13,807 bytes (+9,362)
    CALLS: 333 vectors free
    RAM: 5,716 bytes free
    BUILD: FIRMWARE BUILD DATE 967295:967295
    BOOTS: 8
    BOOT: EXTEND.boot
    POLL:

    MODULES LOADED:
    1A81: EXTEND.fth Tachyon Forth Propeller hardware debugger and explorer - 1500


    I have a PCF8574 expander board connected to pin 28,29 of the Propeller.
    After I type "lsi2c" serveral times I got these results:

    lsi2c Scanning I2C bus
    Fast I/O EXPANDER #0 at $41: F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2
    Fast EEPROM or RTC #0 at $A1: C7 F4 F0 87 96 14 2C 35 C7 FC 80 C7 FC 80 C4 F4 ok
    lsi2c Scanning I2C bus
    Fast I/O EXPANDER #0 at $41: F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2
    Fast EEPROM or RTC #0 at $A1: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ok
    lsi2c Scanning I2C bus
    Fast I/O EXPANDER #0 at $41: F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2
    Fast EEPROM or RTC #0 at $A1: 56 43 46 47 82 B8 37 04 56 53 43 4C 82 B8 38 03 ok
    lsi2c Scanning I2C bus
    Fast I/O EXPANDER #0 at $41: F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2
    Fast EEPROM or RTC #0 at $A1: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ok
    lsi2c Scanning I2C bus
    Fast I/O EXPANDER #0 at $41: F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2
    Fast EEPROM or RTC #0 at $A1: 6F 8C 10 00 7C 7E 84 7E 50 7E 88 7E 6C 7E 02 00 ok
    lsi2c Scanning I2C bus
    Fast I/O EXPANDER #0 at $41: F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2
    Fast EEPROM or RTC #0 at $A1: 6F 8C 10 00 7C 7E 84 7E 50 7E 88 7E 6C 7E 02 00 ok

    I tried the example from the "I2C I/O EXPANDERS" document :
    $F0 3 $40 IO! \ Set 0..3 as outputs

    7 1 $40 IO! \ Write 7 to outputs

    0 $40 IO@ \ Read the inputs

    No matter what I write to the output I always read $F2 back.

    First I thought the expander board could be broken but it works without problems at an Arduino.

    Any ides what could be wrong ?

    Sven
  • Hi Sven, since the I2C chip responds it must be working but bear in mind that the 8574 doesn't have a direction register, only open-drain outputs with "pullups". In reality you can only write zeros to pull the output down as a one will simply leave it in input mode.

    So since there are no direction registers there is only the one implicit source and destination. You have tried to specify a register address 1 which is in fact the data that gets written to the port 1 $40 IO!, not quite what you meant.

    I found the code you must have loaded for these routines:
    \ Write to the port of the chip specified
    pub IO! ( data chip -- )             
         I2CSTART I2C! I2C! I2CSTOP
         ; 
    
    \ Read the port of the chip specified (using full 8-bit address)
    \ a negative ack (1) is used when reading to tell the chip that no more bytes will be read
    pub IO@ ( chip -- data )        
         I2CSTART 1+ I2C! 1 I2C@ I2CSTOP
         ;
    

    This is perhaps what you meant:
    7 $40 IO!
    $40 IO@
  • There is one thing to watch with this switch case break in that since the break is compiled as a "exit then" then it won't try to execute anything else as if you could tell it to jump to an end case and continue. This keeps it simple and efficient and so you should factor the case statements together in their own routine rather than one big long routine that continues on and on long after.

    Thanks Peter. That's what I was beginning to suspect. Will do. Now that I understand that point it should work great.
  • Thank's Peter,
    I've tried the follwing now:

    : test I2CSTART $40 I2C! 0 I2C! I2CSTOP ;

    and I thought that P0 - P7 of the 8574 drop from high level to low level,
    but they didn't .

    If I connect a pulldown resistor from P0 to ground and type lsi2c I get:

    lsi2c Scanning I2C bus
    Fast I/O EXPANDER #0 at $41: FE FE FE FE FE FE FE FE FE FE FE FE FE FE FE FE
    Fast EEPROM or RTC #0 at $A1: 6F 8C 10 00 7C 7E 84 7E 50 7E 88 7E 6C 7E 02 00

    So I think the reading works.

    Sven
  • I was expecting SERIN to work like KEY but instead it is like WKEY except that it returns with the port mask pushed onto the stack below the data. This can be removed with a NIP of course. Is this how it is intended to work?
  • i
    sven98de wrote: »
    Thank's Peter,
    I've tried the follwing now:

    : test I2CSTART $40 I2C! 0 I2C! I2CSTOP ;

    and I thought that P0 - P7 of the 8574 drop from high level to low level,
    but they didn't .

    If I connect a pulldown resistor from P0 to ground and type lsi2c I get:

    lsi2c Scanning I2C bus
    Fast I/O EXPANDER #0 at $41: FE FE FE FE FE FE FE FE FE FE FE FE FE FE FE FE
    Fast EEPROM or RTC #0 at $A1: 6F 8C 10 00 7C 7E 84 7E 50 7E 88 7E 6C 7E 02 00

    So I think the reading works.

    Sven

    I finally managed to locate an actual PCF8574 and tried it out but the device wasn't happy at all. So I specifically used the slow I2C routines to write to the device and it worked fine.
    $F0 $40 I2CSTART I2C! SI2C! I2CSTOP  ok
    lsi2c  Scanning I2C bus
    Fast I/O EXPANDER    #0 at $41: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ok
    I2CSTART $40 SI2C! $F0 SI2C! I2CSTOP  ok
    lsi2c  Scanning I2C bus
    Fast I/O EXPANDER    #0 at $41: F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0  ok
    

    I think the original PCF8574 is probably still spec'd to run at 100kHz in an age when 400kHz is standard so you could modify the routines as such:
    \ Write to the port of the chip specified
    pub IO! ( data chip -- )             
         I2CSTART SI2C! SI2C! I2CSTOP
         ; 
    
    \ Read the port of the chip specified (using full 8-bit address)
    \ a negative ack (1) is used when reading to tell the chip that no more bytes will be read
    pub IO@ ( chip -- data )        
         I2CSTART 1+ SI2C! 1 SI2C@ I2CSTOP
         ;
    
    Trying that out:
    $78 $40 IO!  ok
    $40 IO@ .BYTE 78 ok
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-12-23 03:58
    artkennedy wrote: »
    I was expecting SERIN to work like KEY but instead it is like WKEY except that it returns with the port mask pushed onto the stack below the data. This can be removed with a NIP of course. Is this how it is intended to work?

    Have never seen it do that but I did a quick test using P31 as the input
    !!SP  ok
    .S  Data Stack (1)
    $DEAD.BEEF - -559038737 ok
    31 SERIN  ok
     .S  Data Stack (2)
    $0000.00FF - 255
    $DEAD.BEEF - -559038737 ok
    
    The $FF is the data I'd expect to see due to difference between the SERIN baudrate and the console's baudrate.
    Make sure you have the current EXTEND.fth for whatever reason. SERIN should look like this:
    pub SERIN ( pin -- data \ receive 8 bit serial data from pin at rate set with SERBAUD, blocks )
    	MASK DUP 3 COGREG!					--- [5.8us]
     	baudcnt @ 2/ 200 -					--- [4.8us] serup half-bit delay with high speed compensation
    	(WAITPEQ)						--- [0.4us+] make sure we are not detecting the last data bit - wait for stop
    	(WAITPNE) DELTA 					--- wait for start bit then wait haf bit time
    	 0							--- [5.4us] setup pin mask and inital data to SHRINP 8 data
    	baudcnt @ DELTA 					--- delay to sample 1 bit later in 1st data bit
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP							--- last data bit
    	NIP #24 SHR						--- right justify 8-bit data
    ;
    


  • Bullseye. I had gotten sloppy.
  • After loading EXTEND.FTH I load some utility words before my project.
    This line seems to be causing problems.
    ALIAS PRINT$ .$
    I was trying to reload the whole thing by forgetting the first of the utility words and the console froze.
    So I started a binary search for the prob. I found that it is okay to FORGET any place in the file after the ALIAS line.

    Is there something wrong with that line?
  • Repost as I posted in an old thread,


    @Peter Jakacki

    Hi Peter,

    Should PWM be working with the latest Forth and Extend? I am using:

    MODULES LOADED:
    1A81: EXTEND.fth Tachyon Forth Propeller hardware debugger and explorer - 150902-0100

    VER: Propeller .:.:--TACHYON--:.:. Forth V27150902.0100
    FREQ: 80MHZ (PLLEN OSCEN XTAL1 PLL16X)
    NAMES: $5491...7163 for 7,378 bytes (+125)
    CODE: $0924...4482 for 15,198 bytes (+1,309)
    CALLS: 315 vectors free
    RAM: 4,111 bytes free
    BUILD: FIRMWARE BUILD DATE 654545:466585
    BOOTS: 1
    BOOT: EXTEND.boot
    POLL:

    I then load this code:

    TACHYON [~


    : motor.FTH ." Motor driver for Jimmy the mouse bot " ;

    {
    Motor driver for Jimmy the mouse bot.
    Using L298 compact motor driver H bridge - Solarbotics

    P26 enable right motor
    P27 enable left motor

    P22 L1
    P23 L2

    P24 L3
    P25 L4

    start with initpwm to initialize the PWM
    }

    DECIMAL
    \ 1 - allocate memory for a table
    256 LONGS pwms \ allocate a 256 longs table for the PWM samples

    : initpwm
    \ 2 - specify the outputs and the address of the table then the freq and start the PWM cog
    \ Start up PWM using from P0..7, P16..P23 for 16 channels
    \ PWM.START ( iomask table freq -- )
    \ %00000110_00000000_11111111_11111111

    %00001100_00000000_00000000_00000000 pwms 6000 PWM.START
    ;

    : driveahead
    \ 3 - set the duty cycle for individual pins or groups of pins
    100 % 26 SETPWM
    100 % 27 SETPWM
    \ motors drive ahead
    \ left motor
    #P22 LOW
    #P23 HIGH
    \ right motor
    #P24 LOW
    #P25 HIGH
    ;

    : drivebackw
    \ drive backwards
    100 % 26 SETPWM
    100 % 27 SETPWM
    \ left motor
    #P22 HIGH
    #P23 LOW
    \ right motor
    #P24 HIGH
    #P25 LOW
    ;

    : driveleft
    100 % 26 SETPWM
    90 % 27 SETPWM
    \ motors drive ahead
    \ left motor
    #P22 LOW
    #P23 HIGH
    \ right motor
    #P24 LOW
    #P25 HIGH
    ;

    : driveright
    90 % 26 SETPWM
    100 % 27 SETPWM
    \ motors drive ahead
    \ left motor
    #P22 LOW
    #P23 HIGH
    \ right motor
    #P24 LOW
    #P25 HIGH
    ;


    \ tank style on place turning

    : turnright
    50 % 26 SETPWM
    50 % 27 SETPWM
    \ motors drive ahead
    \ left motor
    #P22 LOW
    #P23 HIGH
    \ right motor
    #P24 HIGH
    #P25 LOW
    ;

    : turnleft
    50 % 26 SETPWM
    50 % 27 SETPWM
    \ motors drive ahead
    \ left motor
    #P22 HIGH
    #P23 LOW
    \ right motor
    #P24 LOW
    #P25 HIGH
    ;

    : drivestop
    \ switch motors off
    1 % 26 SETPWM
    1 % 27 SETPWM
    \ left motor
    #P22 LOW
    #P23 LOW
    \ right motor
    #P24 LOW
    #P25 LOW
    ;

    ]~
    END


    And run the following:
    initpwm ok
    driveahead ok
    drivestop ok
    turnright ok
    drivestop ok


    I have also tried
    motor.FTH
    initpwm ok
    driveahead ok
    drivestop ok
    turnright ok
    drivestop ok



    While the motors turn, there is no signs of PWM on P26 and P27, they are 100% on all the time.

    I have spent the last couple of days on this, tried the .24 Forth as well and older Extend.

    Any suggestions?

    many thanks

    Lee
  • lmclaren wrote: »
    Any suggestions?
    many thanks
    Lee

    The % got reused for more general use so that would mess up your stuff for starters.
    141030 Changes to use of % symbol. PWM speed is now PWM%. The % returns a percentage value, and %% returns the 8-bit percentage (per byte) value

    BTW, try enclosing your code in the code attribute just next to the strikeout in the posting menu or select and type ctrl+o


  • Thanks Peter,
    that' s it, with 100 kHz it works. I should better read the product specifications next time.
    The PCF8574 data sheet shows a maximum SCL clock frequency of 100kHz .

    Sven
  • Thank you Peter,

    That was the problem, I took out the % and it is working fine now.

  • Early days with TF so please correct me if I am wrong...

    I run out of memory if I try to load SDCARD and Easyfile on with Extend.

    I am using the SMALL option for Extend.

    Is it possible to expand / use the memory from eeproms only to store / backup / compact to?
    Propeller .:.:--TACHYON--:.:. Forth V27150902.0100
    
    VER:    Propeller .:.:--TACHYON--:.:. Forth V27150902.0100
    FREQ:   80MHZ (PLLEN OSCEN XTAL1  PLL16X)
    NAMES:  $5214...7163 for 8,015 bytes (+803)
    CODE:   $0924...444A for 15,142 bytes (+1,421)
    CALLS:  227 vectors free
    RAM:    3,530 bytes free
    BUILD:  FIRMWARE BUILD DATE 654545:466585
    BOOTS:  7
    BOOT:   EXTEND.boot
    POLL:
    
    MODULES LOADED:
    3EBD: BOEPAB.fth          TACHYON Robot Control for BOE Platform & Prop Activity Board
    1A80: EXTEND.fth          Primary extensions to TACHYON kernel - 150902-0100
    



    I have additional I2C EEPROMS
    lsi2c  Scanning I2C bus
    Fast EEPROM or RTC   #0 at $A1: 11 3F 19 00 00 00 00 00 00 00 00 00 00 B4 C4 04
    Fast EEPROM or RTC   #1 at $A3: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    Fast EEPROM or RTC   #2 at $A5: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ok
    
  • lmclaren wrote: »
    Early days with TF so please correct me if I am wrong...

    I run out of memory if I try to load SDCARD and Easyfile on with Extend.

    Even though the code is very compact the dictionary is not and can consume 10k so there is EEWORDS.fth that gets loaded sometime after EXTEND and the idea is to load your application last so add the filesystem functions and assuming you have 64k of EEPROM you can tell it to COMPACT the current dictionary into upper EEPROM. Thereafter you can load up your application normally with plenty of room to spare.

    Once this is done you can still load and forget your application but if for some reason you need to change any of the compacted words you will need to do this from a cold start.

  • Looks like i am up the well known creek, I am using a propstick atm,

    Key Features:
    Propeller P8X32A-M44 chip
    32 KB 24LC256-I/ST EEPROM
    FTDI FT232RG and mini USB connector
    USB data transfer indicator LEDs
    5 MHz crystal in a removable socket
    3.3 V, 500 mA voltage regulator
    Reset pushbutton switch

    Is it possible to use one of the other eeproms?
  • If you are comfortable with de-soldering, you could do a drop in replacement of 24LC512
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-12-28 00:22
    Before I started using the upper EEPROM for the dictionary I was using the SD card so there is an older version called SDWORDS.fth that you could use although the dictionary is then dependant on having the dictionary file on the SD and inserted! I hadn't bothered to use the EEPROM initially because it is very slow but I came up with a fast and efficient method that despite running out of EEPROM ends up about the same speed as RAM.

    Parallax uses 64k EEPROMs these days but If you can consider replacing the EEPROM then don't worry about desoldering as if you were ever going to reuse the old chip again. I just gently press down on the pins with a craft knife so that the chip is removed then just run your iron over the pads to remove the pins, maybe with a blob of fresh solder or some flux. Best to press on the pin close to the chip body and brace your hand so that it doesn't want to jab into the pcb afterwards although this method is very safe and reliable and much better than desoldering or even trying to cut the pins (vs pressing).

    btw, the 500ma figure for the regulator is practically useless, if you feed it from 5V that means at 500ma it would dissipate 1.7*0.5 = 850mW which is a lot of heat. The 500ma figure is probably only good for a 3.7V input. Never accept these figures for linear regs without taking power handling into consideration. Also I noticed the Propstick has the crystal in a socket which might be handy for the bench but please solder the crystal in if you intend to embed the Propstick.
  • I need a little help redirecting the console in and out.

    I am using this for a robot and can not remove the existing serial hardware so would like to preferably add a second in / out to be live at the same time as the original console or redirect the original console.

    I have this at the moment:
    57600d SERBAUD
    
    pub BlOut ser-txd_pin SEROUT ;
    pub BlIn ser-rxd_pin SERIN ;
    
    pub BT ' BlOut uemit W! ;
    pub BTin ' BlIn ukey W! ;
    

    It works for the output for TF but not the input, any suggestions please?
  • Is it possible to receive a character from one serial input and parrot it to the console?

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-12-31 03:15
    Since the receive and transmit routines rely on masks it is possible to receive exclusively from any receive input and to transmit to many outputs simultaneously. The snag is that while the transmit mask is easy to update on the fly the receive isn't as it is running in its own cog and you can't do a coginit again as the cog image as been reused in hub for the buffer. However the receive routine could be updated in source to update this mask from hub so that you could dynamically allocate rx and tx from the one receive cog. I will try and make the changes later.

    Of course you could use SERIN but unfortunately it blocks while waiting for a character. I have been meaning to add some enhancements to Tachyon and more flexible serial I/O might be one of them.
  • thank you Peter
Sign In or Register to comment.