Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 23:51 05 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Talking to FRAM chips with I2C....

     Page 1 of 4    
Author Message
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 06:41pm 29 Sep 2014
Copy link to clipboard 
Print this post

Hi folks.

My 256Kb FRAM chips arrived today, so I have been playing.

Although writing seems to be working fine in my test code, I cannot read anything useful back - the results are always zero.

I have a feeling I am addressing the thing wrong - could some of you I2C gurus prod me in the right direction?

I thought I was getting the hang of I2C till I hit this brick wall.

As this device is word-addressed, to keep things nice and simple for testing, I elected to just start at address zero, meaning that along with the slave address, I need to send bytes 2 and 3 to the device as memory address bytes - both being zero.

I have a feeling I am stuffing my addressing up somehow. Writes complete fine, according to the test code, writing 1024 bytes in just 310mS - pretty good!

Here is my test code:


I2C OPEN 400,100
I2C WRITE &B1010000,0,2,0,0 'Set start address as decimal zero(start of FRAM)

Timer=0

For X=1 To 1024
I2C WRITE &B1010000,0,1,Asc("*")
Print "*";
Next

I2C Close

Print:Print
Print "Bytes = 1024"
Print "Write time = ";Timer;" ms"

Pause 3000

Print:Print
Print "Now reading back...":Print

I2C OPEN 400,100
I2C WRITE &B1010000,0,2,0,0 'Reset start address for reading

Timer=0

For X=1 To 1024
I2C READ &B1010000,0,1,B$
Print B$;
Next

I2C Close

Print:Print
Print "Bytes = 1024"
Print "Read time = ";Timer;" ms"
Print:Print
Print "Test ended."

End


The PDF for the device can be found here

EDIT: Before anyone asks - yes I have the 4k7 pull-ups on SDA and SCL. I have the device running from 3v3, which the datasheet lists as typical.

I THINK I have a feeling what is going on - I am only sending address bytes as far as the FRAM is thinking. I THINK I need to set my read/write address, then hold on to the bus(option 1 rather then 0), so as NOT to send an automatic STOP. Following bytes should then be able to be sent, and THEN close the I2C bus.

The testing continues.....Edited by Grogster 2014-10-01
Smoke makes things work. When the smoke gets out, it stops!
 
BobD

Guru

Joined: 07/12/2011
Location: Australia
Posts: 935
Posted: 07:08pm 29 Sep 2014
Copy link to clipboard 
Print this post

I think the easiest solution is to include the starting memory address in each read or write. I think you are reading zeroes because you never wrote anything. This is theory only. Caveat emptor.
 
BobD

Guru

Joined: 07/12/2011
Location: Australia
Posts: 935
Posted: 07:31pm 29 Sep 2014
Copy link to clipboard 
Print this post

Sorry, I'm a bit distracted trying to clone a GPT HDD on windoze 8.1 x64 to a new SSD and I'm not succeeding. The Samsung utility did not copy all partitions or all of the data. Now I'm trying Acronis and it can't boot because it's not in some table somewhere. arrgh.

I would do this
[code]
I2C WRITE &B1010000,0,3,MSB,LSB,Asc("*")
[/code]

and

[code]
I2C READ &B1010000,0,3,MSB,LSB,B$
[/code]
There is a bit of calculating and incrementing the MSB LSB or else you could do a multi byte write or read which would save the effort.

Multi byte
[code]
I2C WRITE &B1010000,0,Len(A$)+2,MSB,LSB,A$
[/code]

[code]
I2C READ &B1010000,0,LengthToRead+2,MSB,LSB,B$
[/code]

 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 08:23pm 29 Sep 2014
Copy link to clipboard 
Print this post

Here is my latest test:

[code]
TEST2:
BYTE$="***"
I2C open 400,100
I2C write &B1010000,0,5,0,0,BYTE$
I2C write &B1010000,0,2,0,0
I2C read &B1010000,0,3,A,B,C
Print A,B,C
End
> goto test2
[45] I2C write &B1010000,0,5,0,0,BYTE$
Error: Incorrect argument count
>
[/code]

Byte$ too long perhaps?

[code]
TEST2:
BYTE$="*"
I2C open 400,100
I2C write &B1010000,0,3,0,0,BYTE$
I2C write &B1010000,0,2,0,0
I2C read &B1010000,0,1,A
Print A
End
> goto test2
[45] I2C write &B1010000,0,3,0,0,BYTE$
Error: Expected a number
>
[/code]

Nope......

FRAM and/or MMBASIC don't like me. Edited by Grogster 2014-10-01
Smoke makes things work. When the smoke gets out, it stops!
 
Lee3
Regular Member

Joined: 17/09/2014
Location: Australia
Posts: 57
Posted: 10:30pm 29 Sep 2014
Copy link to clipboard 
Print this post

I can't help you out.... I'm keen to learn how these chips work though, keeping an eye on this thread.... :)
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2794
Posted: 12:36am 30 Sep 2014
Copy link to clipboard 
Print this post

I am playing too - got some success in MMBasic and will post code later when back home.

For now Grogs, write a number (i.e. '123') rather than a string.

Also play around with I2C option 1 (no stop condition) if setting address in one line of code and then writing the data in another line of code.

We WILL solve this between us

WW


For everything Micromite visit micromite.org

Direct Email: whitewizzard@micromite.o
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 12:15pm 30 Sep 2014
Copy link to clipboard 
Print this post

Thanks for the encouragement, WW - yep, will keep at it.

NUMBER does seem to work ok:

[code]
TEST2:
BYTE$="*"
I2C open 400,100
I2C write &B1010000,0,3,0,0,42
I2C write &B1010000,0,2,0,0
I2C read &B1010000,0,1,A
Print A
End
> goto test2
42
>
[/code]

The uM manual, page 59, says you can send a string, so I was expecting that to work.

PERHAPS there is a small bug in the I2C command, when you are using strings?

Smoke makes things work. When the smoke gets out, it stops!
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5914
Posted: 12:35pm 30 Sep 2014
Copy link to clipboard 
Print this post

I think you were trying to send a combination of bytes and strings.
If the chip needs the address sent with each write, you will have to stick with all bytes.

Jim
VK7JH
MMedit   MMBasic Help
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 12:43pm 30 Sep 2014
Copy link to clipboard 
Print this post

Yes, I was, but I did not think that was an "Illegal request".

I do really need to be able to send strings, so I will play around with the option 1 thing as hinted at by WW - set the address with a write using bytes, then hold onto the bus, and in the next command, send the string, then close the bus.

Will keep the thread posted.
Smoke makes things work. When the smoke gets out, it stops!
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5914
Posted: 12:54pm 30 Sep 2014
Copy link to clipboard 
Print this post

You could also try putting the address bytes in the front of the string as chr$(hibyte) etc

There might be a problem with any zero value bytes - that would need to be checked.
Otherwise a simple function to read the strings char at a time and place the values into an array (my preferred method).

Jim

VK7JH
MMedit   MMBasic Help
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2794
Posted: 01:45pm 30 Sep 2014
Copy link to clipboard 
Print this post

Ok Grogs - Try the following code.

When run, it simply waits for an input (string) and then writes it one byte at a time into FRAM.
It then reads the memory contents back and displays the result. (i.e. echoes input)

For reference I am using a 2048 x 8 FRAM (had one lying next to keyboard). It has the 3 LSBits in the I2C address (set to 000 in code below) to access the FRAM's 'segment', and then requires one byte to access the memory location within the Segment. Put it another way, it has an 11 bit address. Below I am using Segment 000 and locations 1 through to length of inputted string.

May not be 'exactly' what you require but it shows a working example that can be 'expanded' upon.

I2C open 100,100

input a$
for x = 1 to len(a$)
I2C write &B1010000,0 ,2, x, asc(mid$(a$,x,1))
next x

for x = 1 to len(a$)
I2C write &B1010000,0, 1,x
I2C READ &B1010000, 0, 1, rcvbuf
print chr$(rcvbuf);
next x


Let me know how it goes for you!

WW
For everything Micromite visit micromite.org

Direct Email: whitewizzard@micromite.o
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 02:16pm 30 Sep 2014
Copy link to clipboard 
Print this post

FRAM does not like me.

[code]
TEST3:
I2C open 400,100
Input A$
I2C write &B1010000,1,2,0,0 'Set start address, and hold bus
For Y=1 To Len(A$)
I2C write &B1010000,1,1,Asc(Mid$(a$,Y,1)) 'Write byte, and keep holding bus
Next Y.

I2C write &B1010000,0,2,0,0 'Reset address, and send a STOP

For Y=1 To Len(A$)
I2C read &B1010000,0,1,B 'Suck a byte out of the FRAM
Print Chr$(B);
Next Y
> goto test3
? Hello
[57] Next Y.
Error: Cannot find variable
>
[/code]

What's up with the "Can't find variable" error - it's freakin' there!

EDIT: STUPID FULL-STOP ON LINE 57!!!!!!!

Well, that fixed the "Can't find variable" problem, but I still can't read anything back. The only reply I get back from the read for/next, is a single * character.Edited by Grogster 2014-10-02
Smoke makes things work. When the smoke gets out, it stops!
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2794
Posted: 02:36pm 30 Sep 2014
Copy link to clipboard 
Print this post

For now, I would personally write one byte at a time - don't do 'sequential' writes (or Reads) yet until you have the basics working.


Have you tried my code (copy/paste)?

WW

For everything Micromite visit micromite.org

Direct Email: whitewizzard@micromite.o
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2794
Posted: 02:39pm 30 Sep 2014
Copy link to clipboard 
Print this post

Change your Write loop from:

I2C write &B1010000,1,1,Asc(Mid$(a$,Y,1)) 'Write byte, and keep holding bus

to

I2C write &B1010000,0,2,Y,Asc(Mid$(a$,Y,1)) 'Write byte

(i.e. address and data byte in one command (then stop condition sent)
Edited by WhiteWizzard 2014-10-02
For everything Micromite visit micromite.org

Direct Email: whitewizzard@micromite.o
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 02:45pm 30 Sep 2014
Copy link to clipboard 
Print this post

No-go.

I expect this WON'T work for me, simply cos the 256's need a two-byte WORD address, so single byte addressing will not work.

[code]
TEST3:
I2C open 100,100
Input A$
I2C write &B1010000,1,2,0,0 'Set start address, and hold bus
For Y=1 To Len(A$)
I2C write &B1010000,0,2,Y,Asc(Mid$(a$,Y,1)) 'Write byte, keep holding bus
Next Y

I2C write &B1010000,0,1,13 'Send final CR byte, and STOP
I2C write &B1010000,0,2,0,0 'Reset address, and send a STOP
A$=""

For Y=1 To 25
I2C read &B1010000,1,1,B 'Suck a byte out of FRAM
Print Chr$(B);
A$=A$+Chr$(B)
Next Y
Print Len(A$)
End
> goto test3
? Hello
* 25
>
[/code]

I will have a play with the formula posted in the other FRAM thread, for calculating the MSB and LSB, and try merging that into the same line - stay tuned.
Smoke makes things work. When the smoke gets out, it stops!
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2794
Posted: 02:56pm 30 Sep 2014
Copy link to clipboard 
Print this post

If TWO byte word then change to:

TEST3:
I2C open 100,100
Input A$
'I2C write &B1010000,1,2,0,0 'Set start address, and hold bus
For Y=1 To Len(A$)
I2C write &B1010000,0,3,0,Y,Asc(Mid$(a$,Y,1)) 'Write address & byte
Next Y

I2C write &B1010000,0,3,0,Y+1,13 'Send final CR byte, and STOP

'I2C write &B1010000,0,2,0,0 'Reset address, and send a STOP
A$=""

For Y=1 To 25
I2C write &B1010000,0,2,0,0 'Reset address
I2C read &B1010000,0,3,0,Y,B 'Suck a byte out of FRAM
Print Chr$(B);
A$=A$+Chr$(B)
Next Y
Print Len(A$)
EndEdited by WhiteWizzard 2014-10-02
For everything Micromite visit micromite.org

Direct Email: whitewizzard@micromite.o
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 03:05pm 30 Sep 2014
Copy link to clipboard 
Print this post

Read command rejected that syntax - won't allow you to receive multipule bytes seperately, looks like you must use a string if more then one byte.

Anyhoo, here is my latest attempt:

[code]
TEST3:
I2C open 100,100
Input A$
For Y=1 To Len(A$)
MSB=Y\256:LSB=Y Mod 256 'Figure out bytes for address word
I2C write &B1010000,0,3,MSB,LSB,Asc(Mid$(a$,Y,1)) 'Write address & byte
Next Y

I2C write &B1010000,0,2,0,0 'Reset address, and send a STOP
B$=""

For Y=1 To Len(A$)+1
MSB=Y\256:LSB=Y Mod 256
I2C read &B1010000,1,1,B 'Suck a byte out of FRAM & hold bus
B$=B$+Chr$(B)
Next Y
I2C Close
Print B$,Len(B$)
End
> goto test3
? Hello
*Hello 6
>
[/code]

Progress - I am getting results now, but still have the rouge asterisk character.

Tinkering continues...

EDIT: I know where the * is coming from - address zero. If I change the line that resets the FRAM address to I2C WRITE &B1010000,0,2,0,1, that should fix that issue, as the FOR/NEXT loops will then jive with the preset address of the FRAM.Edited by Grogster 2014-10-02
Smoke makes things work. When the smoke gets out, it stops!
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2794
Posted: 03:15pm 30 Sep 2014
Copy link to clipboard 
Print this post

I just cant get 'sequential' data-byte writes to work - I have to write the address and data byte as one command

For everything Micromite visit micromite.org

Direct Email: whitewizzard@micromite.o
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 05:52pm 30 Sep 2014
Copy link to clipboard 
Print this post

Do you think that is the FRAM being difficult, or something in the way that MMBASIC is doing it's I2C?

EDIT: I have other EEPROM chips, so I will set one of them up on the breadboard, now that I have the basic commands working OK. I will stick to sequential writes inside any one page, starting at the top of page 1, just to find out if sequential writing is working OK on EEPROM chips - it might be the FRAM that is being difficult....

[code]
TEST3:
I2C open 100,100
Input A$
For Y=1 To Len(A$)
MSB=Y\256:LSB=Y Mod 256 'Figure out bytes for address word
I2C write &B1010000,0,3,MSB,LSB,Asc(Mid$(a$,Y,1)) 'Write address & byte
Next Y

I2C write &B1010000,0,2,0,1 'Reset address, and send a STOP
B$=""

For Y=1 To Len(A$)
MSB=Y\256:LSB=Y Mod 256
I2C read &B1010000,1,1,B 'Suck a byte out of FRAM & hold bus
B$=B$+Chr$(B)
Next Y
I2C Close
Print B$,Len(B$)
End
> goto test3
? Hello Backshed People!
Hello Backshed People! 22
>
[/code]
Edited by Grogster 2014-10-02
Smoke makes things work. When the smoke gets out, it stops!
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 08:33pm 30 Sep 2014
Copy link to clipboard 
Print this post






Edited by Grogster 2014-10-02
Smoke makes things work. When the smoke gets out, it stops!
 
     Page 1 of 4    
Print this page
© JAQ Software 2024