FM24C64 I2C Data is not what was written

Go To Last Post
21 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am trying to get this FRAM memory to work but I do not have any luck getting an ACK. Attached scope output

Link to datasheet: RAMTRON chips

http://www.datasheetcatalog.com/datasheets_pdf/F/M/2/4/FM24C64.shtml

Using a tiny45, 5V battery (not connected to STK500 during test)

2.2k resistors pullups on buss, Pins PB0 and PB1 connected to SCL SDA

Pins 0,1,2,3 and 6 on FRAM to ground (device = 0 and no write protect)

From what I can see on the scope it looks like it should work.

Using the ATMEL I2C assembler code I found on this site. I changed D to B for port addressing

Anything look like it is a problem?

Program attached.

Attachment(s): 

Last Edited: Wed. Sep 13, 2006 - 04:42 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, here's a dumb question for you. In order to receive the ACK, you need to change the SDA port pin from an output to an input after the 8th clock, or it will stay high regardless. Do you, in fact, do this? When you changed the port from D to B, did you remember also to change the DDRD to DDRB and clear the right bit?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes , both SDA and SCL toggle between input and output via DDRB. The pullup resistors are pulling it high when it goes to input the avr sinks the current via toggeling to output (LOW), The chip is simply not going low to sink the current you can see that on the scope output. I tried some 10K resistors for the pullups thinking the chip was not able to pull it low with the 2.2k, but the datasheet says 1.8K pullup is minimum so that indeed is not the problem.

I just finished writing code for SPI EEprom without looking at any other code, from the datasheet alone and it works fine both input and output. It may take someone who has worked with these FRAM chips to spot the problem because I think i am doing it right as far as the datasheets go but i must be missing something.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

metron9 wrote:

Pins 0,1,2,3 and 6 on FRAM to ground (device = 0 and no write protect)

I think code is ok, and pull-ups and all that, but could you check how you have connected the FRAM chip to AVR? I mean, pin numbering does not usually start from 0 like you said (and the pins are numbered in counter-clockwise order). And is the FRAM chip correctly soldered and mounted the correct way around?

And are you sure that you have not accidentally swapped SCL and SDA pins on the FRAM chip, so swapping SDA and SCL definitions in code is an option too if you want to test that.

pins 1,2,3,4,7 should be GND
pin 5=SDA
pin 6=SCL
pin 8=VCC (same supply as AVR and pull-up resistors have)

- Jani

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I will re check SDA and SCL connections I had double and triple checked them allready when I hooked up the scope probes but I will look again. Yes I see counting from zero for most everything in programming has rubbed off on counting pins. Indeed the connections to ground are as you point out.

If you would like I have some 8pin dips and the SOIC, I could send you one if you want to test it out, it is frustrating when everything looks right but still can't get it to work.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

metron9 wrote:
I will re check SDA and SCL connections I had double and triple checked them allready when I hooked up the scope probes but I will look again. Yes I see counting from zero for most everything in programming has rubbed off on counting pins. Indeed the connections to ground are as you point out.

Ok, no problems there then. Just trying to be sure :) How about VCC then? After making sure all connections are OK, try changing the chip, as wrong connections or static electricity might have killed the chip.

metron9 wrote:

If you would like I have some 8pin dips and the SOIC, I could send you one if you want to test it out, it is frustrating when everything looks right but still can't get it to work.

There's no need for that, as I seem to have an unlimited supply of standard I2C EEPROMs at work, and the protocol is exactly the same. I can't even count the times I've written software I2C routines from scratch.. So we can settle for remote assistance :)

- Jani

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I will as you say check all connections again voltage to chip as well. I was going to order some I2C eeproms just to see if it is a problem with the FRAM chip. Yes, after checking connections I did put another chip in surmising that indeed I could have a bad chip (or smoked it somehow)

If you have a suggestion for RAM or similar to the FRAM chip I could use that instead of these, I only have 8 chips. (not really giving up yet but I am at work so I can't do any testing till tonight)

What I am using it for is a datalogging device. I built a pulse oxcimiter to measure O2 blood levels because I have APNIA. I have a datalogging APNIA machine (resmed) to log when I use it but I need to monitor when I don't use it so a battery powered O2 logger that simply clips on my finger will tell me if I have APNIA attacks when not using the CPAP machine.

When I lose extra weight and pump iron for a few months i seem to be able to sleep without CPAP machine but that is what I want to document, lose weight and excercise to eliminate the APNIA.

I could just buy a O2 monitor on ebay but that would be to easy.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I´m not sure but are you clocking the ACK.

AFAIK. the master has to output an extra clock cycle for the ACK. Then the slave has to answer with an ACK = Low.

Klaus
********************************
Look at: www.megausb.de (German)
********************************

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey, that may be it MegaJSBFreak, When I gave up last night and switched to program SPI code for some EEproms I had (first time played with these) I noticed on the read cycle the falling edge of the clock on the last clock after the address byte was the first bit out of the eeprom.

So here I release the SDA, then Release the SCL but I never pull the clock line low again, maby that is where the chip responds on the falling edge of that last clock cycle it is not getting from me.

I will re read again the datasheet.

EDIT>>>>

After re reading, i just remembered I did not write the code, Atmel did so it must be doing it correctly.
I will look at other I2C chip datasheets to see if the ACK communication is any different from the FRAM datasheet, I would think they are the same though.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In the photo above, SCL does go high after the 8th clock, so that should enable the ACK. Besides, the slave device doesn't wait for the clock to go high - it pulls SDA low as soon as SCL goes low for the 8th time, because it needs to be already low at the next SCL rising edge.

I use the Ramtron FM24 series but I've never had this problem - they always work perfectly. The signals in the photo are all correct (very helpful photo, by the way). The problem can only be that the device isn't recognizing its address... Perhaps the device select pins (1, 2 and 3) are not really at 0V, or you accidentally swapped SCL and SDA.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
it pulls SDA low as soon as SCL goes low for the 8th time,

The datasheet table shows the maximum time after the SCL goes low for the ACK to pull SDA low is 3us (tAA)

I don't know how long that low should last, perhaps it is pulling it low, it would seem then that I would have to release the SDA like this

8th data bit output:

SDA = high or low (1 or 0 bit)
SCL release (FRAM receives bit)
SDA release by master while SCL is high this would be a stop condition though?
SCL Pull Low
SDA pulled low for ACK by FRAM on falling edge of SCL

So I am still confused but let's let it go for now till i get back home and figure out if I really messed up on those connections.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

8th data bit output:

SDA = high or low (1 or 0 bit) (while SCL low)
SCL release (FRAM receives bit) (SCL high)
SDA release by master while SCL is high this would be a stop condition though? (don't do this)
(now drive SCL low)
(now release SDA)
SCL release (not yet - leave SCL low)
SDA pulled low for ACK by FRAM (hopefully!)

(now one more SCL high, then low)

If you inadvertently send a stop condition, then there will be no ACK. But I don't see that happening in your photo.

I'd advise not to float the clock. I don't know how the Atmel code does it - I think the I2C spec calls for SCL to be open collector so that slaves can hold it low to slow down the master, but that isn't a feature used by the 24 series. I would keep SCL always as an output, and leave it low on idle. The slave takes ACK low after the 8th clock falling edge and holds it low until after the 9th clock falling edge, so you do need to take SCL high then low during ACK or you can't start the next operation.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank's to all who helped

Japael hit the nail on the head, they must have been swapped (I had disconnected them last night)

When I reconnected and ran the code I had I could see the ACK but it stayed low

MegaUSBFreak was correct as he suspected it was not clocked.

Thanks to Peret I understand exactly what happens to the ns or at least at the microsecond level. I modofied the code and it now works perfect.

All in all this was a very good learning experiance for me because if it just worked out of the box I would just have to find something else that did not work and try to fix it. The only reason I used the ATMEL code in the first place was the code I had written from reading the datasheets had the exact same problem, (dugh the SDA and SCL were mixed up) so that should have given me a clue but instead I must have said to myself ahh ha I must be right because it is doing the same thing with code that atmel wrote. There are some differences though outlined below.

The code I had downloaded was this:
from MasterasmI2c.asm

i2c_get_ack:
sbi DDRD,SCLP ; force SCL low
cbi DDRD,SDAP ; release SDA
rcall i2c_hp_delay ; half period delay
cbi DDRD,SCLP ; release SCL

i2c_get_ack_wait:
sbis PIND,SCLP ; wait SCL high
   ;(In case wait states are inserted)
rjmp i2c_get_ack_wait

clc   ; clear carry flag
sbic PIND,SDAP ; if SDA is high
sec   ; set carry flag
rcall i2c_hp_delay ; half period delay
ret

The modified code that works is:

i2c_get_ack:
sbi ddrb,SCLP ; force SCL low
cbi ddrb,SDAP ; release SDA (high) (ACK pulls it low here)
rcall i2c_hp_delay ; half period delay

;Code to Read the ACK 
clc                ; clear carry flag
sbic pinb,SDAP     ; if SDA is high
sec                ; set carry flag
rcall i2c_hp_delay ; half period delay

cbi ddrb,SCLP ;High then
sbi ddrb,SCLP ;Low to get the device to release SDA  
cbi ddrb,SCLP ;And finally release the buss
ret

Attached, another pretty picture showing line by line the final 8th bit and the ACK response.

Now I am going to order some 4Mbit atmel dataflash chips... oh, and reduce the clk_delays to nops I think...

Attachment(s): 

Last Edited: Tue. Sep 12, 2006 - 01:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Darn it, I went on to send the MSB address using the same code write routine and I don't get the ACK after the byte is sent. I must again inlist your help as the clock winds into the night. Picture attached. some of LSB in picture as well.

Attachment(s): 

Last Edited: Tue. Sep 12, 2006 - 01:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

metron: can you post screenshots in PNG-format? It´s much smaller and without loss in details.

Klaus
********************************
Look at: www.megausb.de (German)
********************************

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ohh PNG format, I did not realize that, sure I will
but I wont need this thread anymore because I now have success.

I thought of it a few steps from my bed when I got up this morning.

What I did wrong was release the SCL in the ACK code not thinking that a release at that point was the leading edge of the clock for the NEXT BYTE, the MSBit of the MSB of the address. So the following 8 bits I did send turned out to be 9 bits to the receiver. I of course could not see on the scope that the receiver indeed pulled the buss low after the 8th bit because the bus was low already from the 0 bit that was being sent.

With that, I will toss in the final picture in ONG format, snd edit some of the other pics above to make this thread easier to read.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

nice to see that everything is OK now with the I2C.

PNG:
PNG is good if you use only a vies colors. green, black, blue, red, grey..without fading/change_in_brightness.
Terfore you have only 40kB at your latest picture.
The other pictures were JPG. JPG is good for photographs with many different colors.
Changing back from JPG to PNG is not that compact, because of the many colors of JPG.

But thanks for choosing compact formats. I´m in a region only with slow internet connection (ISDN) :-(

Klaus
********************************
Look at: www.megausb.de (German)
********************************

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Seems like I am just at a dead end here with this FRAM chip. I have come so far, the scope shows ACKs just fine bor both Write and Read operations but the DATA Read is not the data Written. So I thought I had it because the scope says everything is good. I will leave it connected for one more day and then I will put the fram chips back in the box. I don't usually give up on things but this is just nuts.

If someone has a working example for I2c that works with the FM24C64 FRAM chip I would love to try it.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh don't give up, you're very close. I see your problem. Unless I misunderstand your (lower) scope image, you go right ahead and send an A1 data byte after the second address. What this does is write A1 into the addressed memory location! It leaves the chip in write mode. What you actually need to do is send another START condition to terminate the write. Immediately after the 3rd ACK when SCK goes low, take SDA high, then raise SCK, then drop SDA - exactly like the first A0 byte, except with data A1. After the chip ACKs you, the next 8 clocks fetch the addressed byte. ACK the data to the 24C64 by taking SDA low and giving it a 9th clock. Repeat until done. DO NOT ACK the last byte you read - send a stop condition instead.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Write procedure of single byte to given address:
1)start
2)send byte i2c address with write bit (0xa0)
3)FRAM chip responds with ACK
4)send byte ram address to write to (0x00..0xff)
5)FRAM chip responds with ACK
6)send byte data to write to ram address (0x00..0xff)
7)FRAM chip responds with ACK
8)stop

Write of multiple bytes (8 or more, depends on page size, but FRAM chip I saw does not have pages) to given address: just repeat normal write steps 6 and 7 until all bytes are written.

Read procedure of single byte from given address:
1)start
2)send byte i2c address with write bit (0xa0)
3)FRAM chip responds with ACK
4)send byte ram address to read from (0x00..0xff)
5)FRAM chip responds with ACK
6)send (repeated) start
7)send byte i2c address with read bit (0xa1)
8)FRAM chip responds with ACK
9)read byte of ram data
10) give FRAM chip an acknowledge bit (NAK for single byte)
11) stop

Reading of multiple bytes from given address:
just repeat 9 and 10, but give the FRAM chip an ACK after every byte, and when the last byte is read, then give NAK and generate stop.

Hope this helps, but this is just interpreting the datasheet to words, and this info comes from my memory, as I can't remember when I last read I2C or Serial EEPROM datasheets (propably not that long ago).

- Jani

EDIT: If you are unsure how to operate on ready-made I2C routines, why not try making your own - then you'll know for sure what your routines do. First routines are how to generate delays and start and stop conditions. Next might be how to generate clock pulses. The next thing then is writing a single data bit, and maybe reading too. Then it is easy to write routines that write or read bytes, and as bytes include the ACK/NAK bits, the byte reading/writing routines can also check for the ACK/NAK bits. After this, you can have a routine which reads or writes memory if you give three parameters, i2c address, ram address and data byte. Next step again is to write routines to access the ram with multiple bytes at a time. Do it in C, WinAVR is so easy to set up. This is how I do all my I2C routines, if they must be done in software.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I tried to post last night after reading your post Peret but the BB went down or something.

SUCCESS! :D

That was exactly it, I guess having such bad eyesight is making it hard for me to see those little things like the little "S" in figure 9 Selective (Random) Read.

It was not just a Start though, Remember I have as the last commands in the Write routine falling edge of 8th data bit, then the HIGH/LOW of the SCL on the falling edge of the LOW the FRAM releases the SDA. Now the SCL is still LOW and issuing just a start (In the code I used) did not release the SCL line first, there was a IC2_RPT_START: just above the comments of the I2C_START:, that released the SCL before the start command.

All in all I have to say this one was a tough one to finally get and I was 90% there the whole time. I then quickly made a loop to write 255 locations and read back the data. Rotating a bit from right to left for each write I watched my scope with the dancing bit walk from right to left. Then I kicked the processor into 8MHZ no clkdiv, removed the delay code from the delay subroutines by simply doing a RET and watched as it wrote and read at over 300,000 BPS, picture of one bit being read, time div = 1uS

Thank you very much Peret for hanging in there with me.

Hi Japael thank you for your response. The first night (start of this thread) I wrote my own code from the datasheet, I could not get a ACK I then turned to the ready made code to try and veryfy what I had done wrong. After seeing it operated the same and not receiving a ACK I was stumped. I had the SCL and SDA lines reversed. As this thread progresses from that point I was missing the small details in that the scope told me I was doing what I wanted it to do the problem was I was simply telling it to do it wrong. So I agree fully with what you say writing my own code.

Now I can finish that Oxcimeter code and datalogger so I can adjust my cpap pressure and get a good night sleep. I also am working on a dBase type interface that will combine a uC and memory chip to read and write datafiles with records and fields / Upload and download from USB and......and.....and.....

Red line is the SDA line, Blue is the clock, this shows 2 bits a 1 and a 0 being clocked in with 4 uS per bit timimg. I will clean up the code and make it easer to interface with and post it in the finished projects in case anyone else wants to try FRAM memory.

Attachment(s):