How to use I2C without a register address and read sequential FIFO?
4Alex
Posts: 119
Hi All,
I am using the I2C SPIN Object from James Burrows (May 2006 Version 1.3).
I am trying (very hard) to interface a keypad controller (MAX11041 - 30 keys). This chip can monitor up to 30 keys, and report which one was pressed, in what sequence if any, and for how long. Great for a custom made mp3 player...
I have a working proto and I can detect the presence of the IC using 'devicePresent(deviceAddress)'. My problems comes when I try to read the key log of the chip. The key log is composed of 8-word FIFO (8 keystrokes can be logged sequentially: K1Byte1=key#, K1Byte2=duration, K2Byte1=key#, K2Byte2=duration, and so on).
From the datasheet (page 9), you can read the IC using the slave address ($42 in my case) and then 8 consecutive bytes (chip ID, control reg, key byte1, key byte2), separated by 1 ACK each. The read is terminated by a stop.
My question: how can I read an I2C device knowing only the slave address, not referencing any register, and read successively 4 bytes separated with an ACK? The method I use is readLocation(deviceAddress, deviceRegister, addressbits, databits). It doesn't work with this IC.
Any help would be greatly appreciated. Thanks in advance.
Cheers,
Alex
PS1: The url is www.maxim-ic.com/quick_view2.cfm/qv_pk/4944
PS2: I've used the following modified code but it doesn't seems to work either:
[url=http://][/url]
I am using the I2C SPIN Object from James Burrows (May 2006 Version 1.3).
I am trying (very hard) to interface a keypad controller (MAX11041 - 30 keys). This chip can monitor up to 30 keys, and report which one was pressed, in what sequence if any, and for how long. Great for a custom made mp3 player...
I have a working proto and I can detect the presence of the IC using 'devicePresent(deviceAddress)'. My problems comes when I try to read the key log of the chip. The key log is composed of 8-word FIFO (8 keystrokes can be logged sequentially: K1Byte1=key#, K1Byte2=duration, K2Byte1=key#, K2Byte2=duration, and so on).
From the datasheet (page 9), you can read the IC using the slave address ($42 in my case) and then 8 consecutive bytes (chip ID, control reg, key byte1, key byte2), separated by 1 ACK each. The read is terminated by a stop.
My question: how can I read an I2C device knowing only the slave address, not referencing any register, and read successively 4 bytes separated with an ACK? The method I use is readLocation(deviceAddress, deviceRegister, addressbits, databits). It doesn't work with this IC.
Any help would be greatly appreciated. Thanks in advance.
Cheers,
Alex
PS1: The url is www.maxim-ic.com/quick_view2.cfm/qv_pk/4944
PS2: I've used the following modified code but it doesn't seems to work either:
PUB readMax11041(deviceAddress,seq) : i2cData | ackbit,deviceRegister ' read a device's register ackbit := _i2cACK deviceRegister := 0 if i2cStarted == true if seq == "1" i2cStart ackbit := (ackbit << 1) | i2cWrite(deviceAddress | 0,8) 'send a 8 bit deviceRegister. (i2cWrite will shift left 24 bits) ackbit := (ackbit << 1) | i2cWrite(deviceRegister << 24, 0) i2cStart 'Ireg ackbit := (ackbit << 1) | i2cWrite(deviceAddress | 1, 8) i2cData := i2cRead(_i2cACK) if seq == "2" 'i2cStart 'Creg 'ackbit := (ackbit << 1) | i2cWrite(deviceAddress | 1, 8) i2cData := i2cRead(_i2cACK) if seq == "3" 'i2cStart 'Kreg 'ackbit := (ackbit << 1) | i2cWrite(deviceAddress | 1, 8) i2cData := i2cRead(_i2cACK) if seq == "4" 'i2cStart 'Treg 'ackbit := (ackbit << 1) | i2cWrite(deviceAddress | 1, 8) i2cData := i2cRead(_i2cNAK) i2cStop else ackbit := _i2cNAK ' set the last i2cACK bit lastackbit := ackbit ' return the data return i2cData
[url=http://][/url]
Comments
i2cStart
i2cWrite with the device select code and a read bit in bit0
as many i2cRead cycles as you need/want.· The last cycle has ACK=0.· All the others have ACK=1
i2cStop
Take a look at some of the examples in the I2C routines if the above isn't clear
Post Edited (Mike Green) : 10/1/2008 7:02:24 PM GMT
Thank you so much for your reply.
I have done the following (and several other variants) but it still doesn't work. Clearly, there's something I don't get. Sorry if I'm so obtuse.
I have re-checked all contacts, shorts, etc., and compared with typical app schematics. All are ok.
Any other suggestions? (please, pretty please)
Cheers,
Alex
i2cObject.i2cWrite ($42,8)
Is setting the R/!W bit to a 1?
Also I don't know why the datasheet says this, but it says to give an ACK after every read. It's possible that a NACK will confuse it down the line.
The last read has to have a NACK so the device knows that this is the last byte to be transferred and a stop will follow.
Yes I'm aware that this is normally done however the datasheet says:
"
...
5) The MAX11041/MAX11042 send the corresponding
keypress time duration (OF, T6–T0) stored in the
FIFO starting with the most significant bit (OF).
Afterwards the master must send an ACK bit.
6) The master must generate a stop condition (P)."
So I'm just pointing this out in case he still has problems after fixing the slave address.
That example can be found at:
http://forums.parallax.com/forums/default.aspx?f=25&m=294507
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
---
Jo
Thank you for reminding me to add '1' to the base address for reading: I already knew that but while swearing () at the circuit, I simply forgot to increment the address in the code! I have corrected this mistake and I get the first segment properly. The rest of the data makes no sense at all...
I have also implemented the 'reset' code mentionned in the DS, using the approach you suggested and this too seems to work. Thanks again.
The following code does result in correct values for the first reading:
@Keith:
Thank you for checking the datasheet. The least I can say about the DS is that it is written in an arcane way! Thank you for your suggestion to check the ACK bit. Simple question: how do you do that in an easy way?!?
@Joao:
Your posting is very interesting. Thank you for the Nunchuck object.
Thank you all for your help.
Cheers,
Alex
You will never cease to amaze me! How in in the world did you found that?!? I will try this tomorrow morning and report.
As for the circuit board, I unfortunately have to report that I have somewhat roughended a few pads...
Many thanks again,
Cheers,
Alex
Thanks, everything is working fine now. I had to repair a couple of pads, reprogrammed using your approach, and (not surprisingly) I can now read the whole register properly. Many thanks again for your help.
Cheers,
Alex
I received a reply from tech support at Maxim regarding the MAX11041. Since they clarify the datasheet (and some errors in it), I tought it would be becoming to share this reply with you (just in case someone wants to use the IC in the future):
Many thanks again to those who helped - its very appreciated.
Cheers,
Alex