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 2 of 4 | |||||
Author | Message | ||||
jman Guru Joined: 12/06/2011 Location: New ZealandPosts: 711 |
Hi Thanks to Grogster I got some Fram chips today The real simple code below proves they work just fine I2C open 400, 100 test=197 I2C Write &H50,0,3,&H0,&H0,Test Print MM.I2C ' Should be 0 if all is good I2C Write &h50,0,2,&H0,&H0 I2C Read &H50,0,1,Rtest Print MM.I2C ' Should be 0 if all is good I2C Close Print Rtest Regards Jman |
||||
BobDevries Senior Member Joined: 08/06/2011 Location: AustraliaPosts: 266 |
@Grogster... Unless I'm missing something, you're using a \ instead of / in your code. Maybe a typo? Regards, Bob Devries Bob Devries Dalby, QLD, Australia |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9082 |
You're missing something. I did the divide thing myself as a mistake at the start of my tinkering, IE: A/256, when it needs to be A\256. A\256 is integer divide. This was pointed out to me by other forum members.(TassyJim and G8JCF) Smoke makes things work. When the smoke gets out, it stops! |
||||
BobDevries Senior Member Joined: 08/06/2011 Location: AustraliaPosts: 266 |
Thanks, Grogster. Now that you mention it, I do vaguely recollect a mention of that. Regards, Bob Devries Dalby, QLD, Australia |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 5923 |
The integer divide is a bit faster than INT(divide). a = 1000
timer = 0 for n = 1 to 10000 b = a\256 next n print timer timer = 0 for n = 1 to 10000 b = int(a/256) next n print timer > RUN
1310 1507 > Jim VK7JH MMedit MMBasic Help |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9082 |
...so sounds like the one to use then. Smoke makes things work. When the smoke gets out, it stops! |
||||
WhiteWizzard Guru Joined: 05/04/2013 Location: United KingdomPosts: 2794 |
Hi Grogs, Two questions: 1> Which exact 256-FRAM did you end up using? (just curious as to what other functions it may have (RTC?)) 2> Have you been able to do 'sequential' writes yet? i.e. set address once, then send bytes one after the other without addressing them (FRAM has auto address increment). Regarding the second point, sequential reads are easy whereby you just need to send I2C READ (one byte), but for writing you need to send 3-bytes (Address MSB, Address LSB, DATA). Could it be an MMBasic I2C issue do you think? How can we test this? WW For everything Micromite visit micromite.org Direct Email: whitewizzard@micromite.o |
||||
jman Guru Joined: 12/06/2011 Location: New ZealandPosts: 711 |
Hi Tried the Fram with my Nokia LCD data and it seems to work ok This the code I used to read the Fram hope it helps I2CADDr = &H50 GoSub Codes Print CData; " Codes Read" End Codes: 'Rem READ From Fram I2C Open 400,100 'ENABLE I2C I2C Write I2CADDR, 0,2,&H7F,&HFE 'Array size location I2C Read I2CADDR, 0,1,C 'Read remainder of blocks from EE I2C Read I2CADDR, 0,1,D 'Read number of blocks from EE CData=(D*256)+C 'Array size Blocks*256 + remainder Dim GCodes(504) 'Temporary Array for Graphics Dim Codes(CData-504) 'Dimension array L=0:K=0 'To Ensure we start at 0 BC=&HFF 'Complete Block For J=0 To D 'Number of complete blocks If J=D Then BC=(CData-(D*256)) 'Check for end of array For I=0 To BC I2C Write I2CADDR, 0,2,J,I If L > Cdata-504 Then I2C Read I2CADDR, 0,1,GCodes(K) K=K+1 Else I2C Read I2CADDR, 0,1,Codes(L) EndIf L=L+1 'Increment counter Next I : Next J I2C Close Return I have attached the Write code as it is a little long with all the data statements 2014-10-02_083059_WriteFram.zip Regards Jman |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9082 |
@ WW - Sequential reads are easy - no problems. Sequential writes are impossible - no matter what I try, it fails - same as you. I can successfully sequentially write, only by issuing the address with each data byte - as did you. Would love to know how we could test this further..... As to the actual part number, it is a Ramtron FM24W256. Smoke makes things work. When the smoke gets out, it stops! |
||||
jman Guru Joined: 12/06/2011 Location: New ZealandPosts: 711 |
To quote the data sheet " All writes begin with a slave address then a memory address" This normal for EEprom's not just the Fram You need to specify the memory address with every write. You can write more than byte at a time ie i2c write slave address, 5, 0, 0, byte1, byte2, byte3 This will write bytes1 - byte3 sequentially to location 0,1,2 If you want to write one byte at a time then you need i2c write slave address, 3, 0, 0, byte This what I use to sequentially write to EEprom / Fram 2CADDR=&H50 'Address of Fram I2C Open 400,100 'ENABLE I2C BC=&HFF 'Complete block For J=&h0 To S 'Number of blocks to write If J=S Then BC = CData-(S*256) 'Full block or remainder For I=&h0 To BC I2C Write I2CADDR, 0,3,J,I,Codes(Cnt) 'Write to EE Cnt = cnt + 1 'Increment array counter Next i: Next j I2C Write I2CADDR, 0,4,&H7F,&HFE,BC,S 'Write item count to EE I2C Close Regards Jman |
||||
centrex Guru Joined: 13/11/2011 Location: AustraliaPosts: 320 |
Has anybody looked at how it is done with the Arduino, I am waiting for a fram from Adafruit. They have a sample file in their library, I know they have things like the .h files but it could give a clue. Keep up the good work. Cliff Cliff |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9082 |
@ jman - if you look back in this thread, you will see that we've tried to write multipule bytes at a time, but it is not working. Individual bytes as you are showing them will work, but sending a string won't. It is very possible I am still doing something wrong, but if you look back, you will see that the likes of writing a string, which the manual says you should be able to do in a single write, fails every time - MMBASIC complains. I have a feeling it is because MMBASIC's I2C write only supports writing strings for byte-addressed memory. As soon as you add the extra address byte for word-addressed memory, MMBASIC falls over. Have a look at page 59 of the uM manual. Last example for writing a string is I2C WRITE &H6F, 1, 3, STRING$ - this probably works. However, with word addressing, there is an extra byte in the command, and this seems to be throwing MMBASIC out: I2C WRITE &H6F, 1, 5, 0, 1,STRING$ - throws an error if you try to specify the write address before the string. I guess you could always add the address bytes to the string - someone else here suggested that earlier, but I thought there MUST be a way to do it other then that. Once you start adding address bytes to the start of the string, it is bound to confuse anyone trying to read you code, however - I suppose that is where a commented line of code would be a good thing...... I will try that as an experiment later today.(add MSB and LSB to a string, then add D$ to the end of that, and send that using the first example from the manual.) Smoke makes things work. When the smoke gets out, it stops! |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9082 |
OK, progress - jman WAS right, I was just interpreting the syntax for writing strings wrong. Here is the SEQUENTIAL WRITING test routine: [code] FW2: D$="Hello there, backshed people.":A=15000 MSB=A\256:LSB=A Mod 256 D2$=Chr$(MSB) + Chr$(LSB) + D$ + Chr$(13) 'Build address + string I2C open 400,100 I2C write &B1010000,0,Len(D2$),D2$ 'Write address + string I2C write &B1010000,0,2,MSB,LSB 'Reset start address Do I2C read &B1010000,1,1,B D3$=D3$+Chr$(B) If B=13 Then Exit Do Loop Print D3$ End [/code] Smoke makes things work. When the smoke gets out, it stops! |
||||
WhiteWizzard Guru Joined: 05/04/2013 Location: United KingdomPosts: 2794 |
@Grogster, This is what we had before and not what I would call sequential writing (you're just adding two address bytes to the data string, but still writing it in one line of code). If you refer back to my first example, there I was writing a string into memory after first writing the one address byte (for my FRAM only requiring one byte for address byte - yours needs two). All this was in one line of code. I am saying that sequential writing is to write the start address in one line of code, and then use multiple lines just writing the data byte(s) without specifying an address (as the FRAM will auto increment the address for each byte written; with roll-over when reaching last address location). I am still trying various things here but no joy whatsoever (yet!) WW EDIT: SORRY GROGSTER - just re-read the thread - I didn't post my code that I thought I did! I have it in my notes here though! Anyway, the above still stands in my definition of sequential writing. For everything Micromite visit micromite.org Direct Email: whitewizzard@micromite.o |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9082 |
Hi WW. I will play with that idea now. One would THINK that if you held onto the bus after the first write, you should be able to do it again...... My latest routine is: [code] FW2: D1$="Hello there, backshed people.":A=15000 D2$=D1$ + D1$ + D1$ + D1$ + D1$ + D1$ + D1$ + D1$ 'Build large string MSB=A\256:LSB=A Mod 256 D3$=Chr$(MSB) + Chr$(LSB) + D2$ + Chr$(13) 'Build address + string I2C open 400,100:Timer=0 I2C write &B1010000,0,Len(D3$),D3$ 'Write address + string T1=Timer:Timer=0 I2C write &B1010000,0,2,MSB,LSB 'Reset start address Do I2C read &B1010000,1,1,B D4$=D4$+Chr$(B) If B=13 Then Exit Do Loop T2=Timer Print D4$ Print "Data length: ";Len(d4$) Print "Write time : ";T1;"ms" Print "Read time : ";T2;"ms" End [/code] This builds a nice big(and useless!) text message, then writes it in one operation to the FRAM. Averages 6ms write time, which is excellent, and I never need to worry about page boundries - yay! Smoke makes things work. When the smoke gets out, it stops! |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9082 |
Yeah, WW - I can't make it work for me either. [code] FW3: D1$="Hello WhiteWizzard!":A=10000 X1$="Tra-la-la...":D3$="" D2$=Chr$(A\256) + Chr$(A Mod 256) + D1$ I2C open 400,100 I2C write &B1010000,1,Len(D2$),D2$ I2C write &B1010000,1,Len(X1$),X1$ I2C write &B1010000,1,1,13 I2C write &B1010000,0,2,A\256,A Mod 256 LAST=Len(D1$) + Len(X1$) + 1 For X=1 To LAST I2C read &B1010000,1,1,B D3$=D3$ + Chr$(B) If B=13 Then Exit For Next Print D3$ End [/code] I have replaced the read DO/LOOP with a FOR/NEXT, as I kept getting string length errors. First write works, the next ones don't WITHOUT addressing byte(s). Smoke makes things work. When the smoke gets out, it stops! |
||||
palcal Guru Joined: 12/10/2011 Location: AustraliaPosts: 1805 |
I have a use in mind for these chips, they seem to be a bit of a problem to read and write to. When we have the 170 chip is this something that Geoff could conjure up a read and write command for or are there too many variables for it to be generic. Paul "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9082 |
They are not a problem really. It just requires a little time to work it all out, then once we have a working routine, I will probably submit it to the library.(with credits to all other members who chimed in with ideas) Reading is no problem - I have done some tests reading the entire memory inside a loop. That is no issue. The issue is continuous sequential writing, and this is only really an issue, if you CAN'T contain all you want to write at any one time, within the 256 byte limit of MMBASIC strings. IE: Assuming that you can get all you want into a string, and it is less then 256 bytes in length(including address bytes), then there is no problem at all. WW and me are trying to work out why you can't write heaps to the device once you have opened it and sent the initial address - more for academic reasons, then reasons of practical application.(I think! I hope!) Smoke makes things work. When the smoke gets out, it stops! |
||||
WhiteWizzard Guru Joined: 05/04/2013 Location: United KingdomPosts: 2794 |
@palcal, Just re-enforcing what Grogster has just posted. There isn't really a need for incorporating any 'FRAM' commands into MMBasic (unless there are surplus 'command indexes' for Geoff to play with then it would be a nice inclusion). The sequential write is something I see useful; however, what Grogs & I have both confirmed working so far is more than usable for using these brilliant devices. I have mentioned & recommended FRAM's before in several posts; but now thanks to Grogster, we are now starting to share how to incorporate them. For everything Micromite visit micromite.org Direct Email: whitewizzard@micromite.o |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 5923 |
The first 2 bytes sent to the FRAM as a 'write' are assumed by the FRAM to be address bytes. If you don't keep track of the address yourself, and send it at the start each time, strange things will happen. Fortunately, keeping track of the address pointer is easy to do. I have some FRAM chips on the way but I don't expect them too soon. Jim VK7JH MMedit MMBasic Help |
||||
Page 2 of 4 |
Print this page |