Shop OBEX P1 Docs P2 Docs Learn Events
General purpose I2C driver written in PropForth V5.0 ??? — Parallax Forums

General purpose I2C driver written in PropForth V5.0 ???

Duane C. JohnsonDuane C. Johnson Posts: 955
edited 2012-04-10 09:03 in Propeller 1
I'm looking for a general purpose I2C driver written in PropForth V5.0.

Wishes:
1. Single byte writes and reads to the I2C device.
2. Can operate with pins other than P28,P29.( i.e. not using EEPROM words.)
3. Written entirely in PropForth V5.0 words.
4. Bonus, if the I2C clock speed can be slowed down to less than 9KHz.

Thanks!

Duane J

Comments

  • prof_brainoprof_braino Posts: 4,313
    edited 2012-04-08 13:29
    On the propforth downloads page, please nick lordi's contributions for spi and c3. I think these have something on i2c
  • caskazcaskaz Posts: 957
    edited 2012-04-08 16:06
    Hi.
    I wrote code of rtc(DS1337).
    This use eeprom word.
    But you can modify this code for a general purpose I2C driver.
    {
         PropForth 5.0
    
         RTC DS1337 driver 
         24/03/2012 22:17:10
         RTC DS1337   Propeller
    
         scl    ----  P28   0x1c
         sda    ----  P29   0x1d
    }
    
    hex
    
    \ bcd> ( n1 -- n2 ) convert bcd byte n1 to hex byte n2
    [ifndef bcd>
    : bcd>
    	dup F and
    	swap F0 and
    	1 rshift dup
    	2 rshift + +
    ;
    ]
    
    \
    \ >bcd ( n1 -- n2 ) convert hex byte n1 to bcd byte n2
    [ifndef >bcd
    : >bcd
    	A u/mod 4 lshift +
    ;
    ]
    
    \ _rtcflip7 ( n7 n6 n5 n4 n3 n2 n1 -- n1 n2 n3 n4 n5 n6 n7 ) flip the top 7 items on the stack
    : _rtcflip7 
    	rot >r rot >r rot >r rot >r rot >r
    	swap
    	r> r> r> r> r>
    	rot >r rot >r rot >r
    	swap
    	r> r> r>
    	swap rot
    ;
    
    \
    \ _DS1337_w ( c1 -- )
    : _DS1337_w
    	_eewrite
    	if
    		8007 ERR
    	then
    ;
    
    \ _DS1337_s ( n1 -- )   I2C Start for DS1337  
    \                         n1:register address  c1:wr[0]/rd[1]  
    : _DS1337_s
    	_eestart
    	D0 _DS1337_w         \ slave address + wr[0]
    	_DS1337_w            \ register adress 
    ;
    
    \ ( -- )  only Data Read
    : _DS1337_sr 
    	_eestart  
    	D1 _DS1337_w        \ slave address + rd[1] 
    ;
    
    
    \  ( -- n1 n2 n3 n4 n5 n6 n7 ) read 7 bytes from DS1337
    \ n1 - second		(00 - 59)
    \ n2 - minute		(00 - 59)
    \ n3 - hour		(00 - 23)
    \ n4 - day of week 	(1 - 7)
    \ n5 - day		(01 - 31)
    \ n6 - month		(01 - 12)
    \ n7 - yesr		(00 - 99)   
    : _DS1337_time_r 0 _DS1337_s _DS1337_sr 6 0 do 0 _eeread loop -1 _eeread _eestop ;
    \ ( n1 n2 n3 n4 n5 n6 n7 -- ) write 7 bytes to DS1337 
    : _DS1337_time_w _rtcflip7 0 _DS1337_s 7 0 do _DS1337_w loop 0 _eeread drop _eestop ;
    
    \ Read Hr/Min from Ds1337 ( -- n1 n2 )  n1:Minute  n2:Hour
    : read_hrmin
    _DS1337_time_r
    3drop drop
    bcd> swap bcd> rot drop swap
    ;
    
    \ Read&convert all time-data from DS1337
    \ ( -- n1 n2 n3 n4 n5 n6 n7 )
    \ n1 - second		(00 - 59)
    \ n2 - minute		(00 - 59)
    \ n3 - hour		(00 - 23)
    \ n4 - day of week 	(1 - 7)
    \ n5 - day		(01 - 31)
    \ n6 - month		(01 - 12)
    \ n7 - yesr		(2000 - 2099)   
    : read_time 
    _DS1337_time_r                
    bcd> 7D0 + >r         \ Year
    bcd> >r               \ Month  
    bcd> >r                \ Day 
     >r                    \ week 
    bcd> >r                \ Hour 
    bcd> >r                \ Minute 
    bcd>                \ Second
    r> r> r> r> r> r>
    ;
    
    \ ( n1 n2 n3 n4 n5 -- ) write Input-datas to DS1337 
    \ n1 - yesr		(00 - 99)   
    \ n2 - month		(01 - 12)
    \ n3 - day		(01 - 31)
    \ n4 - hour		(00 - 23)
    \ n5 - minute		(00 - 59)
    : set_time 
    0 rtc_busy W! 
    >bcd >r             \ minute
    >bcd >r             \ hour
    >bcd >r             \ day
    >bcd >r             \ month
    7D0 - >bcd          \ year
    r> r> 0 r> r> 0 _rtcflip7
    _DS1337_time_w
    read_time . . . . . . .
    ;
    
    decimal
    
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2012-04-08 16:59
    Hi Professor:

    I've searched high and low and can't find this.

    There is some reference to SPI, and a bit on I2C but nowhere is there a link to any code? (That I can find)

    Where can I find this?

    Duane J
  • prof_brainoprof_braino Posts: 4,313
    edited 2012-04-08 18:20
    From this page http://code.google.com/p/propforth/downloads/list

    the links I was referring to are:
    http://code.google.com/p/propforth/downloads/detail?name=C3SPI.rtf&can=2&q=
    http://code.google.com/p/propforth/downloads/detail?name=PF_SFM.rtf&can=2&q=

    You should start with caskaz' example, I think you can just change the pin assignments.
    Can you tell us your example I2C device, and what pins you have it on, etc?

    We can help you work through it if you want.
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2012-04-08 20:17
    Hi Professor:

    My long term project is for use in computation based solar trackers. The plan for this rendition is to use an SD-card to store many years, (maybe 30 years), of pre-computed stepper movements. I use a high accuracy ephemeris program in my PC to make the data files on the SD-card.

    Currently I have everything running on a simple plugboard using FemtoBasic. The problem is the slow access reading even 1 month of data on the SD-card.

    I have 3 devices in mind to be used on pins 16 & 17.
    1. The DS1307 clock with 56 bytes of static ram
    Clock_DS1307_Real-Time-Clock_RTC_I2C_DIP-8
    2. PCA9554 or PCA9555 Expander, very easy to use.
    Expander_PCA9554_8-bit-I2C-bus-and-SMBus-IO-port_MicroChip_DIP-16
    3. MCP23017 Expander, A bit more complicated.
    Expander_MCP23017_16-Bit-IO-Expander-with-Serial-Interface_MicroChip_DIP-28

    All of these were pretty easy to drive using Mike Greens I2C driver in FemtoBasic.

    Or possibly a shift register.
    4. 74HCT595 shift register. However, this requires 4 pins to do right.
    CMOS_74HCT595_8-bit-serial-in-serial-or-parallel-out-latched-tristate_DIP-16

    The reason I want to run the I2C buss at less than 9KHz is that at that speed shielding and filtering will eliminate any radio interference or emissions. Only the processor would need to be RF tight.

    I am an old fan of forth. I started with an Apple ][, then a Z80, 1802, M68HC11, and a number of others over the years. My problem is I'm not a software engineer, I do pretty good when I see examples of how things are done them modify for my needs. I don't do so well when I'm on my own. I specifically choose the Propeller because it had a forth interpreter. I have done a bunch of stuff on V2.0. But I kind of backed off for a while waiting for the SD version of PropForth.

    Anyway I would really appreciate all the help I can get on examples of I2C drivers.

    Duane J
  • prof_brainoprof_braino Posts: 4,313
    edited 2012-04-09 06:54
    Hi Duane

    I'm not a EE, I'm a SWE, so I generally leave the hardware drivers to the EE's, unless I have the parts in the lab for testing. Other takes are first in the queue, and the only part similar to yours is the DS1302 on my PDB.
    http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CIABEBYwAA&url=http%3A%2F%2Fwww.parallax.com%2Ftabid%2F786%2FProductID%2F515%2FList%2F0%2FDefault.aspx&ei=TuiCT9npNIqQ8wTl6rHZBw&usg=AFQjCNFveye5Y4_38SnwGaXOhsDWt1Quog&sig2=imXvvDONeEaKnKwDQTbKgA

    So I might be able to look at that. I actually don't know the difference between SPI and I2C, as I have not had a project that required me to work on these.

    Did you have any progress with caskaz' code? He is one of the premier users of propforth, tap his brain as much as possible.

    The extensions we are currently working on for propforth v5.1 may also prove to be of interest. These are CSP channels, which should be the stepping stone to execution automation and logging.
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2012-04-09 20:05
    Hi Professor;

    I looked at the spec for the DS1302:
    Clock_DS1302_Real-Time-Clock_RTC_Serial-Clock_DIP-8
    And compared it with the DS1307 which uses an I2C interface.
    The DS1302 interface is similar to SPI, but not quite. SPI has separate data in and out pins, the DS1302 has bidirectional data.

    SPI is a much simpler interface. Basically data is shifted in and out and controlled by the clock. Fairly easy to do.

    I2C is similar but the clock has more specific functions.
    Take a look at the MCP23017/MCP23S17 spec which describes both.
    Expander_MCP23017_16-Bit-IO-Expander-with-Serial-Interface_MicroChip_DIP-28

    I've been thinking about the procedure to implement this. I suspect 1 forth word can be written for each bit type:
    1. Start and Restart
    2. Out bit
    3 In bit
    4. W/R bit
    5. ACK/NAK bit
    6. Stop bit
    Some of these are complicated, especially the Start, and ACK bits.
    I think this would be a real challenge to get right.
    Start with the Prop being the master and transfer a single byte at a time.

    The formatting of the data should be fairly easy.
    1. 7 bit device op code
    2. Read byte
    3. Write byte.

    I think this would be fun to try to do.
    I would like to try. What do you think?

    Duane J
  • prof_brainoprof_braino Posts: 4,313
    edited 2012-04-10 09:03
    Hi Professor;

    Some of these are complicated, especially the Start, and ACK bits.
    I think this would be a real challenge to get right.
    Start with the Prop being the master and transfer a single byte at a time.

    If you can dig through the serial material in the tutorials, you might get some ideas. Sal has implemented all this stuff or similar. He pointed out the code where this happens, it very short and simple looking, but over my head. I got the impression its a lot simpler than it seems, we just have to break it down in the simplest thing that gets the job done, and resist the temptation to add the kitchen sink, which is the real trick.

    It looks like you are on the right path though.
Sign In or Register to comment.