Netduino home hardware projects downloads community

Jump to content


Photo

Test I2C Communication


  • Please log in to reply
11 replies to this topic

#1 firestar

firestar

    Member

  • Members
  • PipPip
  • 15 posts

Posted 12 December 2012 - 02:15 PM

Hi all, I have managed that get my EEprom working on I2C, however at this point im trying to find the best way for diagnostics on it. Writing or reading to the eeprom will always execute but one can not predict the results. Als the I2CDevice.Execute will not give any diagnostics. Even writing to the eeprom that does not exist will give a number of bytes written result. I have been thinking of allocating some registers to a default value that you should always read first to make sure the eeprom is there and working. Have others played with this idea before and how did you solve it? BR, Martin

#2 Nevyn

Nevyn

    Advanced Member

  • Members
  • PipPipPip
  • 1070 posts
  • LocationNorth Yorkshire, UK

Posted 12 December 2012 - 09:10 PM

I have managed that get my EEprom working on I2C, however at this point im trying to find the best way for diagnostics on it. Writing or reading to the eeprom will always execute but one can not predict the results. Als the I2CDevice.Execute will not give any diagnostics. Even writing to the eeprom that does not exist will give a number of bytes written result.

Martin,

Welcome to the community.

Do you have any pull-up resistors connected to the I2C lines?

Regards,
Mark

To be or not to be = 0xFF

 

Blogging about Netduino, .NET, STM8S and STM32 and generally waffling on about life

Follow @nevynuk on Twitter


#3 firestar

firestar

    Member

  • Members
  • PipPip
  • 15 posts

Posted 12 December 2012 - 09:34 PM

Martin,

Welcome to the community.

Do you have any pull-up resistors connected to the I2C lines?

Regards,
Mark



Hi Mark,

Yes, I have 4k7 going to +5V. Everything is working fine at this point, I can write/read from any of the registers. My problem is im training to simulate fail criteria for instance if the EEprom wouldnt work, or wasnt installed at all. When I write to a wrong address, I2CDevice.Execute will still return a byte count to me. There's no acknowledge signal that I can find to check?

Right now to test the eeprom, I write a dummy value (random) to an address, and read it couple ms later and compare them. But I just wanted to check to see if this is the way to go or that there are diagnostics somewhere that I have missed.

BR,
Martin

#4 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 12 December 2012 - 10:48 PM

fail criteria for instance if the EEprom wouldnt work, or wasnt installed at all. When I write to a wrong address, I2CDevice.Execute will still return a byte count to me. There's no acknowledge signal that I can find to check?

IMHO it depends on the particular device you are using. For example, 24C256 (and similar) EEPROMs, which I used during development of I2C repeated start condition, always acknowledge write command, even if its write protection is on ("If an attempt is made to write to the array with the WP pin held high, the device will acknowledge the command but no write cycle will occur, no data will be written, and the device will immediately accept a new command."). I am not sure at the moment what happens in case of an invalid address, whether the address is rolled over the maximum or there is no action performed at all, but it seems the device responds with acknowledge too. You should be able to detect when there is no device with the matching address on the bus (no acknowledge, Execute() returns zero), but you'd probably need to use a custom mechanism to detect the proper function of the memory, like you've already mentioned in the original post. I would also consider error detection (CRC, XOR checksum etc.), where appropriate.

#5 firestar

firestar

    Member

  • Members
  • PipPip
  • 15 posts

Posted 13 December 2012 - 07:06 AM

Hi C2W, Thanks for your reply, partly im confused though and I will try again later today. But if I remember correctly when I used an address yesterday that did not exist .Execute() returned 1 to me. I'd have to test if I write a single byte if that would return 2 to me or just 1. Then I can at least check on 1. I guess i'll go with using some of the space for a dummy string now that I will write, then read to see if it exists and test for function. I did not think about using CRCs for the data actually. Would you implement that for any data written to the EEprom? How would you normally store your data? I was thinking of creating an object and mapping this to addresses on the EEprom side. Or I just may serialize the whole object, do a CRC on that and then do page writes. Where did you see your device needs the repeated start bit? I just looked at mine (24LC64) and I could not find it. Also the current methods I'm using (default .NET ones) seem to work? Thanks. Martin

#6 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 13 December 2012 - 08:02 AM

I did not think about using CRCs for the data actually. Would you implement that for any data written to the EEprom? How would you normally store your data? I was thinking of creating an object and mapping this to addresses on the EEprom side. Or I just may serialize the whole object, do a CRC on that and then do page writes.

Well, I guess it depends on the nature of the data - for example, I would probably use regular and complemented form for storing a configuration constant or 'last' value (i.e. written twice, once in a regular form x and once in bit-complement form ~x, so they can be easily checked with XOR), I would use error detection for the most critical data. I have not had a need for object serialization yet, I used only numbers or byte arrays.

Where did you see your device needs the repeated start bit? I just looked at mine (24LC64) and I could not find it.

The 24LC64 requires repeated start condition for Random Read (fig. 8-2 in the device datasheet), there is no stop after Address Low byte. You'd need special method to achieve that, pass the address via internalAddress parameter, internalAddressSize is 2 in this case; default I2C methods work for all the other EEPROM operations.

#7 firestar

firestar

    Member

  • Members
  • PipPip
  • 15 posts

Posted 13 December 2012 - 09:03 AM

Hi C2W, Thanks that explains. However I'm confused, right now I was doing simple reads on addresses and that seems to work with the current methods. I'm doing a write transaction for the address first, then read. With the next function I will write the address again and then read the data. If i'm doing sequential reads with my current methods, can I use your extension methods without any problems? BR, Martin

#8 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 13 December 2012 - 09:27 AM

Thanks that explains. However I'm confused, right now I was doing simple reads on addresses and that seems to work with the current methods.

Yes, writes, current address and sequential reads work with the default I2C methods.

I'm doing a write transaction for the address first, then read. With the next function I will write the address again and then read the data.

I am not sure if I understand it correctly, but if you mean I2C transactions, i.e. write transaction with only two bytes (address) followed by read transaction, then it is probably just an edge case (*) - I guess the device does not start the write cycle because it does not receive any data and does not increment the internal address counter, so the subsequent read operation reads from the same address. Normally, if you follow the protocol as described in the documentation, write transaction with a valid data causes the internal address counter to be incremented, so it points to the address following the last one written, and subsequent Current Address or Sequential Read starts reading from there. So to verify the written data you'd need to use Random Read where you can specify the address, or Sequential Read that reads so much data (e.g. repeatedly using smaller buffer) that the address counter rolls over to the desired address.

(*) It seems to be rather nice trick, worth more investigation...

#9 firestar

firestar

    Member

  • Members
  • PipPip
  • 15 posts

Posted 13 December 2012 - 12:14 PM

Hi C2W,

I based on the following text:

This is done by sending the word address to the
24XX64 as part of a write operation (R/W bit set to 0).
After the word address is sent, the master generates a
START condition following the acknowledge. This terminates
the write operation, but not before the internal
address pointer is set. Then the master issues the
control byte again but with the R/W bit set to a one.


The problem im having is im not quite sure how .NET under the hood uses this R/W bit, as its part of the Address and from the managed side i can only influence the first 7 bits I believe. So I believe the R/W bit is part of the transaction and set internally by .NET, I have little I2C experience with other devices so im not sure if all devices use this 8th bit for R/W.

I am doing paged writes in my code as the datasheet warned me for that, but for sequential reads im doing full number of bytes assuming the eeprom will increment the address counter, I have not tested this yet.

BR,
Martin

#10 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 13 December 2012 - 12:39 PM

The problem im having is im not quite sure how .NET under the hood uses this R/W bit, as its part of the Address and from the managed side i can only influence the first 7 bits I believe. So I believe the R/W bit is part of the transaction and set internally by .NET...

Technically, the R/W bit is not part of the slave address - the slave address is 7 bits, followed by the R/W bit (= 8 bits, usually called 'control byte' or similar). You don't need to care about the R/W bit, the managed code just passes the [7 bit] slave address to underlying I2C driver, which sets it to the appropriate register and then manipulates 'read-write mode' bit to generate the state of R/W bit based on the type of the transaction. The hardware I2C module can do even more things automagically, as in case of AT91SAM7X microcontroller, it can output the whole Start - Slave Address - R/W - InternalAddress - Start - Stave Address - R/W - data - Stop sequence at once.

#11 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 13 December 2012 - 12:52 PM


This is done by sending the word address to the 24XX64 as part of a write operation (R/W bit set to 0). After the word address is sent, the master generates a START condition following the acknowledge. This terminates the write operation, but not before the internal address pointer is set. Then the master issues the control byte again but with the R/W bit set to a one.

Yes, exactly - the key is that the internal address pointer is set during the write operation, even if there is no data following. Which is basically almost the same what happens when you issue that Random Read with repeated start, the only difference is the missing STOP. I am not arguing here, if it works then it works Posted Image

#12 firestar

firestar

    Member

  • Members
  • PipPip
  • 15 posts

Posted 14 December 2012 - 06:55 AM

I did some testing last night and so far it seems to all work with the 2 transactions for random reading. I dont have a logic analyzer to see what is going over the bus, so I cant really check. I also did not dive into the source of .NET MF to find out how its exactly working under the hood. I suppose since it works its ok. I have your extension methods put in and commented them out, so if i ever run into problems I can just switch to them.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.