Cypress CY8C9520A I/O expander -need help
SexieWASD
Posts: 41
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.
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?