Shop OBEX P1 Docs P2 Docs Learn Events
Cypress CY8C9520A I/O expander -need help — Parallax Forums

Cypress CY8C9520A I/O expander -need help

SexieWASDSexieWASD Posts: 41
edited 2010-01-13 03:28 in Propeller 1
Has anyone used one of these?

I believe that hardware wise everything is correct, but I still can't switch any of the pins.
I think the problem must be a misunderstanding of the datasheet and application notes

I once got one pin to go to 0v, but I haven't been able to reproduce that, and at the time I was trying to turn off the whole block of pins (GPort 0 bits 0-7), and I wasn't able to get to to go back to 3.3v after either.

Does anyone know what must be done to assign a pin to output and pull it to 0 volts? If I have some code that I know should work then I will at least know if it's software related.

Here is what I'm using for code at the moment.


CON
  _clkmode = xtal1 + pll16x                             ' Crystal and PLL settings.
  _xinfreq = 5_000_000                                  ' 5 MHz crystal (5 MHz x 16 = 80 MHz).

  MP_Address = %0100_0010
  MEM_Address    = %1010_0010
  SDA = 24                                          'set i2c data pin to prop pin #24
  SCL = 26                                          'set i2c clock pin to prop pin #26
  
OBJ
  i2c      : "Basic_I2C_Driver"
  Debug    : "Parallax Serial Terminal"

PUB Main                                 
  i2c.Initialize(SCL, SDA)

  i2c.Start(SCL, SDA)
  i2c.write(SCL, SDA, MP_Address)                             'Device address
  i2c.write(SCL, SDA, $18)                             'Port select register
  i2c.write(SCL, SDA, $00)                             'Select GPort 0

  i2c.Start(SCL, SDA)
  i2c.write(SCL, SDA, MP_Address)                             'Device address
  i2c.write(SCL, SDA, $1C)                             'Pin direction register
  i2c.write(SCL, SDA, $00)                             'Set all as output

  i2c.Start(SCL, SDA)
  i2c.write(SCL, SDA, MP_Address)                             'Device address
  i2c.write(SCL, SDA, $1D)                             'Pull up drive mode register
  i2c.write(SCL, SDA, $00)                             'Set as false
  
  i2c.Start(SCL, SDA)
  i2c.write(SCL, SDA, MP_Address)                             'Device address
  i2c.write(SCL, SDA, $1F)                             'Open drain high drive mode register
  i2c.write(SCL, SDA, $FF)                             'Set as true

  i2c.Start(SCL, SDA)
  i2c.write(SCL, SDA, MP_Address)                             'Device address
  i2c.write(SCL, SDA, $08)                             'GPort 0 output register
  i2c.write(SCL, SDA, $FF)                             'Set as all true
  
  i2c.Stop(SCL, SDA)




This is part of Basic_I2C_Driver (i2cObject_v2_1) that I changed because my SDA and SCL pins are not consecutive, I also added the Testpins function to test that the variables were ok.
PUB Testpins(SCL, SDA)

'This is an infinate loop, it will break a program.
  outa[noparse][[/noparse]SCL] := 1
  dira[noparse][[/noparse]SCL] := 1
  outa[noparse][[/noparse]SDA] := 1
  dira[noparse][[/noparse]SDA] := 1
repeat

PUB Initialize(SCL, SDA)             ' An I2C device may be left in an
                                    '  invalid state and may need to be
   outa[noparse][[/noparse]SCL] := 1                       '   reinitialized.  Drive SCL high.
   dira[noparse][[/noparse]SCL] := 1
   dira[noparse][[/noparse]SDA] := 0                       ' Set SDA as input
   repeat 9
      outa[noparse][[/noparse]SCL] := 0                    ' Put out up to 9 clock pulses
      outa[noparse][[/noparse]SCL] := 1
      if ina[noparse][[/noparse]SDA]                      ' Repeat if SDA not driven high
         quit                          '  by the EEPROM

PUB Start(SCL, SDA)                   ' SDA goes HIGH to LOW with SCL HIGH

   outa[noparse][[/noparse]SCL]~~                         ' Initially drive SCL HIGH
   dira[noparse][[/noparse]SCL]~~
   outa[noparse][[/noparse]SDA]~~                         ' Initially drive SDA HIGH
   dira[noparse][[/noparse]SDA]~~
   outa[noparse][[/noparse]SDA]~                          ' Now drive SDA LOW
   outa[noparse][[/noparse]SCL]~                          ' Leave SCL LOW
  
PUB Stop(SCL, SDA)                 ' SDA goes LOW to HIGH with SCL High

   outa[noparse][[/noparse]SCL]~~                         ' Drive SCL HIGH
   outa[noparse][[/noparse]SDA]~~                         '  then SDA HIGH
   dira[noparse][[/noparse]SCL]~                          ' Now let them float
   dira[noparse][[/noparse]SDA]~                          ' If pullups present, they'll stay HIGH

PUB Write(SCL, SDA, data) : ackbit
'' Write i2c data.  Data byte is output MSB first, SDA data line is valid
'' only while the SCL line is HIGH.  Data is always 8 bits (+ ACK/NAK).
'' SDA is assumed LOW and SCL and SDA are both left in the LOW state.

   ackbit := 0 
   data <<= 24
   repeat 8                            ' Output data to SDA
      outa[noparse][[/noparse]SDA] := (data <-= 1) & 1
      outa[noparse][[/noparse]SCL]~~                      ' Toggle SCL from LOW to HIGH to LOW
      outa[noparse][[/noparse]SCL]~
   dira[noparse][[/noparse]SDA]~                          ' Set SDA to input for ACK/NAK
   outa[noparse][[/noparse]SCL]~~
   ackbit := ina[noparse][[/noparse]SDA]                  ' Sample SDA when SCL is HIGH
   outa[noparse][[/noparse]SCL]~
   outa[noparse][[/noparse]SDA]~                          ' Leave SDA driven LOW
   dira[noparse][[/noparse]SDA]~~





Also I do not have pull up resistors on either SDA or SCL, I don't know if that matters or not.

Post Edited (SexieWASD) : 1/6/2010 4:24:01 AM GMT

Comments

  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-01-06 04:30
    You *should* have them on both, per the I2C spec, though the driver you're using drivers the clock high and low; put one on the SDA line and you should get better results.
  • SexieWASDSexieWASD Posts: 41
    edited 2010-01-06 23:06
    no luck. I am beginning to think that it might be trying to stretch the clock, but I only have a cheap multimeter so I can't know for sure. I'll try adding some delays and see if it works.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-01-06 23:26
    My I2C object allows for clock stretching -- and requires pull-ups on both the SDA and SCL pins. Many Propeller boards omit the SCL pull-up because it drives the SCL line high and low; my I2C routines don't (i.e., a "1" on SCL requires a pull-up).
  • SexieWASDSexieWASD Posts: 41
    edited 2010-01-13 00:48
    Still no luck, so when are we getting the prop2 with more pins?

    I'm using your driver with 4.9kohm pullups on SCL and SDA lines. As far as I can tell it just doesn't want to work.
  • KyeKye Posts: 2,200
    edited 2010-01-13 01:04
    Use this:

    http://obex.parallax.com/objects/539/

    It has good I2C code to use in its private methods section. Try to use that code.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-01-13 01:11
    There's nothing wrong with the I2C drivers he's tried to use (both have "good code to use") -- I think there must be something in how he's attempting to use them.
  • Miner_with_a_PICMiner_with_a_PIC Posts: 123
    edited 2010-01-13 01:23
    The code has SCL and SDA as constants but they are being used by your i2c object's functions as local variables; is this okay? Perhaps you could try using different variable names in these functions, this might help.
  • SexieWASDSexieWASD Posts: 41
    edited 2010-01-13 02:47
    So, I've just got it working actually [noparse]:D[/noparse] (using JonnyMac's driver)

    Notice the "_clkmode = xtal1 + pll1x" part? I guess it's just really slow.

    CON
      _clkmode = xtal1 + pll1x                             ' Crystal and PLL settings.
      _xinfreq = 5_000_000                                  ' 5 MHz crystal (5 MHz x 16 = 80 MHz).
    
    OBJ
      i2c      : "jm_i2c"
      Debug    : "Parallax Serial Terminal"
    
    PUB Main
      Debug.Start(115200)
      i2c.init(26, 24)
    
      Debug.Str(String("Starting..."))
      Debug.NewLine
    
      i2c.start
      i2c.putbyte($42, $18, $00)
      
      i2c.start
      i2c.putbyte($42, $1c, $00) 
      
      i2c.start
      i2c.putbyte($42, $08, $00)
    
      Debug.Str(String("Completed"))
      Debug.NewLine
    
    



    From Cypress' FAQ

    "Question: What is the maximum I2C Clock Frequency for CY8C9520?

    Response: The maximum SCL clock frequency of the CY8C9520 is only 100 KHz for both 3.3V and 5V operations. There is an error in the data sheet which mentions 400 KHz as the maximum I2C speed."

    Shouldn't this have been well under 100 KHz anyway?
  • photomankcphotomankc Posts: 943
    edited 2010-01-13 03:28
    The SPIN I2C functions are all under 35KHz in operation. There is no way SPIN I2C exceeded 100KHz at any clock frequency for the prop.
Sign In or Register to comment.