Cypress CY8C9520A I/O expander -need help
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.
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.
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
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
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.
http://obex.parallax.com/objects/539/
It has good I2C code to use in its private methods section. Try to use that code.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
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?