Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 03:21 08 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 : MMBasic VAR SAVE and VAR RESTORE

     Page 2 of 2    
Author Message
viscomjim
Guru

Joined: 08/01/2014
Location: United States
Posts: 925
Posted: 03:24pm 13 Aug 2014
Copy link to clipboard 
Print this post

Hey Grogster, can you provide a code example of writing something that is bigger than one page? I'm trying to make head or tails of this and really appreciate that you brought this up before us uMiters lost too much hair over this.

A big Thank you in advance!!!
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9067
Posted: 03:35pm 13 Aug 2014
Copy link to clipboard 
Print this post

I'm beginning to wonder if I should have even brought it up....

I have never written any MM code for EEPROMS, but I will do it for an experiment.
All my previous experiments with EEPROMS were in PICAXE chips.

The concept remains the same, though.

Your confusion is exactly the same as mine was at the time, and page-boundries in EEPROM chips seem to trip up lots of people.

I MAKE NO CLAIM TO BEING ANY KIND OF EXPERT HERE - I am just sharing what I found out when I started using EEPROMS. Other members here may have better examples, or may be able to explain it better then I.

I will have to research a little on EEPROMS cos I have not used them myself for a year or two, now preferring the ease of SD card files and the likes of the MaxiMite.

From memory(pardon the pun!), to page write, the first byte sent is the address, and any subsequent bytes are treated as data, with the EEPROM advancing the address pointer automatically. Anything more then 5mS or whatever the commit period is, and you have to send another address byte before the data bytes.

I need to check up on all this, and will have a read and post back some examples later, but the key rule here is:

- On any one page, do not cross the page barrier in any one write command.

Provided you don't do that, you can store data anywhere you like, and it will be where it is expected to be.
Smoke makes things work. When the smoke gets out, it stops!
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9067
Posted: 05:46pm 13 Aug 2014
Copy link to clipboard 
Print this post

From the Microchip datasheet for the 24LC64 EEPROM(8KB), page 8:

  Quote  
Page write operations are limited to writing bytes within a single physical page, regardless of the number of bytes actually being written. Physical page boundaries start at addresses that are integer multiples of the page buffer size (or ‘page size’) and end at addresses that are integer multiples of [page size – 1]. If a Page Write command attempts to write across a physical page boundary, the result is that the data wraps around to the beginning of the current page (overwriting data previously stored there), instead of being written to the next page, as might be expected. It is therefore necessary for the application software to prevent page write operations that would attempt to cross a page boundary.


That might make it easier to understand then my ramblings.....
Smoke makes things work. When the smoke gets out, it stops!
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1135
Posted: 01:26am 14 Aug 2014
Copy link to clipboard 
Print this post

@viscomjim

the code above is for MAXImite, sorry. Maybe some print-functions are different on µmite? I have no access to µmites.

On my Duinomite the output from eeDump looks like this:



Perhaps this will work on your µmite also (needs no format$-function)?



' example:
T$="The BackShed eeprom test "

eeWrite$ 70, t$

Print eeRead$(70,Len(t$))+"<"
Print eeGet$(70)+"<"

end



'******************************
Sub eeWrite$ (address, text$)
' Writes a string to AT24C32
'******************************

I2CADDR=&H57 ' 24C32-DS3231
a=0

If Len(text$)+address>4095 Then Print "Error: Address to high!":End

I2C open 100,100 'ENABLE I2C
For x= address To address+Len(text$) 'writes 0-byte at the end!
a=a+1
msb=Int(x/256) 'MSB
lsb=x Mod 256 'LSB

I2C write I2CADDR, 0, 3, msb, lsb, Asc(Mid$(text$,a,1))

If MM.I2C <>0 Then Print "Error! 1=NAK 2=TIMEOUT"; MM.I2C: End Sub
Pause 5
Next x
I2C close

Print "At"address" string "+Chr$(34)+text$+Chr$(34)+"is written into EEPROM."
End Sub


'******************************
Function eeRead$ (address, bytes)
' Reads a string from AT24C32
'******************************

I2CADDR=&H57 ' 24C32-DS3231
eeRead$=""

If address>4095 Then Print "Error: Address to high!":End
If bytes>255 Then Print "Error: String too long!":End

I2C open 100,100 'ENABLE I2C
For x= address To address+bytes-1

msb=Int(x/256) 'MSB
lsb=x Mod 256 'LSB

I2C write I2CADDR, 0,2,msb,lsb
I2C read I2CADDR, 0,1,tmp

If MM.I2C <>0 Then Print "Error! 1=NAK 2=TIMEOUT"; MM.I2C: End Sub
eeRead$=eeRead$+Chr$(tmp)

Next x
I2C close
End Function


'******************************
Function eeGet$ (address)
' Gets a zero-terminated string from AT24C32
'******************************

I2CADDR=&H57 ' 24C32-DS3231
eeGet$=""

If address>4095 Then Print "Error: Address to high!":End

I2C open 100,100 'ENABLE I2C

Do

msb=Int(address/256) 'MSB
lsb=address Mod 256 'LSB

I2C write I2CADDR, 0,2,msb,lsb
I2C read I2CADDR, 0,1,tmp

If MM.I2C <>0 Then Print "Error! 1=NAK 2=TIMEOUT"; MM.I2C: End Sub
If tmp=0 Then Exit 'leave loop
eeGet$=eeGet$+Chr$(tmp)
address=address+1

Loop While Len(eeGet$)<255
I2C close
End Function




Michael Edited by twofingers 2014-08-15
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1135
Posted: 08:52am 14 Aug 2014
Copy link to clipboard 
Print this post

@Grogster

I think you'll confirm that for Byte Write, as in my code, no problems should be expected? Page Write has some advantage but it maks things more complicated. The Microchip datasheet says a 24C32 has a page size of 8 bytes.

Also interesting:
  Quote  The 24C32 is organized as a continuous 32K block of
memory. However, the first 4K, starting at address 000,
is rated at 10,000,000 E/W cycles guaranteed. The
remainder of the array, 28K bits, is rated at 100,000 E/
W cycles guaranteed.


10,000,000 E/W cycles for the first 512 bytes is nice!

Important for DS3231-modul user: The 24C32 voltage operating range is 4.5V to 5.5V. The DS3231 should run on 3,3V but I guess 5V is better. I got a strange behavior with 3,3V for the DS3231 (I could not reproduce).

Michael

 
viscomjim
Guru

Joined: 08/01/2014
Location: United States
Posts: 925
Posted: 09:51am 14 Aug 2014
Copy link to clipboard 
Print this post

Hi TF, I copied this from the amtel website...

• Low-Voltage and Standard-Voltage Operation
– 2.7 (VCC = 2.7V to 5.5V)
– 1.8 (VCC = 1.8V to 5.5V)
• Low-Power Devices (ISB = 2 μA at 5.5V) Available
• Internally Organized 4096 x 8, 8192 x 8
• 2-Wire Serial Interface
• Schmitt Trigger, Filtered Inputs for Noise Suppression
• Bidirectional Data Transfer Protocol
• 100 kHz (1.8V, 2.5V, 2.7V) and 400 kHz (5V) Clock Rate
• Write Protect Pin for Hardware Data Protection
• 32-Byte Page Write Mode (Partial Page Writes Allowed)
• Self-Timed Write Cycle (10 ms max)
• High Reliability
– Endurance: 1 Million Write Cycles
– Data Retention: 100 Years
• Automotive Grade and Extended

So, I am guessing that 3.3v should be ok? Also, check the speed... 400khz only at 5v

But the Microchip version, which apparently is an obsolete device now has these specs....

• Voltage operating range: 4.5V to 5.5V
- Peak write current 3 mA at 5.5V
- Maximum read current 150 μA at 5.5V
- Standby current 1 μA typical
• Industry standard two-wire bus protocol, I2C
compatible
- Including 100 kHz and 400 kHz modes
• Self-timed write cycle (including auto-erase)
• Power on/off data protection circuitry
• Endurance:
- 10,000,000 Erase/Write cycles
guaranteed for High Endurance Block
- 1,000,000 E/W cycles guaranteed for
Standard Endurance Block

This one is 4.5v to 5.5v.

I will have to zoom into my ds3231/24c32 module and see if I can decipher which manufacturer made the eeprom.

As far as the ds3231 it can definitely run on 3.3v. That is all I've ever used with no problems... From Maxim data sheet...

Fast (400kHz) I˛C Interface
3.3V Operation
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1135
Posted: 10:16am 14 Aug 2014
Copy link to clipboard 
Print this post

Hi viscomjim,

thanks! You are right. Next time I had to take better befor a look on my modules: its a Atmel!

Perhaps i should test the endurance with a now obsolete DS1307/24C32 module.

  Quote  As far as the ds3231 it can definitely run on 3.3v.

I'm not sure about that.

Michael
 
viscomjim
Guru

Joined: 08/01/2014
Location: United States
Posts: 925
Posted: 11:04am 14 Aug 2014
Copy link to clipboard 
Print this post

I checked my module also and it is an Atmel. Yeah! I will try your code next.

HERE is the link for DS3231. Check the voltage...
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1135
Posted: 11:34am 14 Aug 2014
Copy link to clipboard 
Print this post

@viscomjim

  Quote  Check the voltage...


I have not doubted your words. I know the spezification of the DS3231. Only my experience says something different. For example: I connected to 3,3V and suddenly I lost exact a whole minute, seconds are okay. Or the temperature varies between 0 and 22 °C ... later then everything seems okay again. The reason could be perhaps the wiring, but with 5V are there no issues. But this DS3231 discussion is here off-topic? If I know more then I will tell you.

MichaelEdited by twofingers 2014-08-15
 
viscomjim
Guru

Joined: 08/01/2014
Location: United States
Posts: 925
Posted: 11:56am 14 Aug 2014
Copy link to clipboard 
Print this post

Hi TF, do you have more than one module that you can test? Maybe there is something flaky with that module, but at least it works properly at 5V. Just don't use it in a pacemaker or something like that.
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2794
Posted: 12:08pm 14 Aug 2014
Copy link to clipboard 
Print this post

  viscomjim said  Maybe there is something flaky with that module. . . .

Cheap module . . Something flaky . . . Surely not, how is that possible!
For everything Micromite visit micromite.org

Direct Email: whitewizzard@micromite.o
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1135
Posted: 01:16pm 14 Aug 2014
Copy link to clipboard 
Print this post

@viscomjim

  Quote  do you have more than one module that you can test?


enough!

  Quote  Just don't use it in a pacemaker


I hope I will not need such a device in the near future.


@WhiteWizzard

Cheap module . . AND cheap wires! I got what I paid for.

1. working 5V RTC 2ppm drift
2. 4KB EEPROM
3. thermometer
4. CR2032
5. a signal generator (32768 Hz)
6. ...

for 1,8 bucks! Thats exactly what I need for my 25 EUR Duinomite or my little 2 EUR arduinos.

regards

Michael
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9067
Posted: 01:52pm 14 Aug 2014
Copy link to clipboard 
Print this post

  twofingers said   @Grogster

I think you'll confirm that for Byte Write, as in my code, no problems should be expected? Page Write has some advantage but it maks things more complicated. The Microchip datasheet says a 24C32 has a page size of 8 bytes.


Confirmed - and exactly right.

Byte writing is not a problem, page-writing IS.

...IF you page write, which is what I was doing in my application, then you can easily get yourself into a hell of a mix, which is what happened to me, until the guys over at the PICAXE forums explained pages to me, so I just did not want anyone here having that same issue.

The reason your screen-dump works fine, is cos you have the pause 5 after every byte write to the I2C bus, which gives the EEPROM time to commit it, so with that delay in place within the loop, you should have no problems at all byte-by-byte writing across the page boundry.

Try doing that as a page write WITHOUT the 5ms delay.
Smoke makes things work. When the smoke gets out, it stops!
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1135
Posted: 02:38am 15 Aug 2014
Copy link to clipboard 
Print this post

@Grogster

  Quote  Try doing that as a page write

this way?
'**************************************
' ERASE WHOLE EEPROM (fill with zero)
' using PAGE WRITE
'**************************************
Sub eeErase
Dim fill(34) ' fill will contain 2 bytes for address + 32 fillbytes
I2CADDR=&H57 ' 24C32-DS3231
K=&H00 'zero value or some fill value

For i = 2 To 34:fill(i)=K: Next i

Print "Erasing ..."
I2C open 100,100 'ENABLE I2C
For J=&h0 To &hF 'MSB
For I=&h0 To &hFF Step 32'LSB
fill(0)=j:fill(1)=i
'fill(0)+(1) = MSB + LSB
I2C write I2CADDR, 0,34,fill(0)

Pause 5 '? Write needs some time ...
If MM.I2C <>0 Then Print "1=NAK 2=TIMEOUT"; MM.I2C,j,i:End:EndIf
Next i
L=(j*256+I)
Print "Byte ";L, " ";Chr$(13);
Next j
I2C close
Print "EEPROM HAS BEEN ERASED "

End Sub


Seems to be somewhat faster!

The "Page Write" reminds me of the old days with 8086-Assembler, DOS and the "memory segmentation" (in german: Speichersegmentierung).

Michael
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1135
Posted: 05:34am 16 Aug 2014
Copy link to clipboard 
Print this post

As a small supplement or replacement to the code above.
eeSaveF and eeLoadF are new.

Now you can save and load your floatingpoint vars to/from EEPROM AT24V32.

for string handling use
' eeWrite$
' eeRead$
' eeGet$
from code above or here: EEPROM0.5.zip edit (21-08-2014):obsolete! !
Some parts are for MAXIMITE-Basic V4.5 only!


'********************************************
'********************************************
' for ATMEL 24V32 (32kBit EEPROM) on DS3231
' MMBasic 4.5 for Maximite/Duinomite
'********************************************
'********************************************
'
' eeWrite$: writes a string to address
' eeRead$: some bytes from address
' eeGet$: reads a string from address
' eeWriteN: writes a number (1 byte) to address
' eeReadN: reads a number (1 byte) from address
' address may be between 0 to 4095
'
' eeSaveF: writes a 32 bit floatinpoint number
' eeLoadF: reads a 32 bit floatinpoint number
' to/back from EEPROM using PEEK and POKE
' uses eeWriteN respectively eeReadN
'
' eeErase: deletes the whole eeprom
' eeDump: shows content of eeprom
'
'
' EEPROM-Collection v0.5
' by twofingers 08-2014
' with parts from MMBasic Library
' (should be public domain)
'
'********************************************
'********************************************

' example code:

Dim Z(20)

'debug = 1 ' debugmode switch

test = Pi
Print "Save: "test
eeSaveF (0, test)
test=0
Print "Set to zero:"test
eeLoadF (0, test)
Print "Restored: "test
Print:Print

' test an array
For i = 1 To 20
Z(i)=1/i
Print "Save: ",i, Z(i)
eeSaveF (i*4, z(i))
z(i)=0
Print "Set to zero:",i, Z(i)
eeLoadF (i*4, z(i))
Print "Restored: ",i, Z(i)
Print
wait "<Press any key>"
Next i
eeDump

End
'********** END EXAMPLE CODE ************
'****************************************

'******************************
Sub eeSaveF (address, v)
' Saves a floatingp. var to AT24C32
'******************************
local i

For i = 0 To 3
eewriteN address+i, Peek(VAR v,i)
Next i

End Sub


'******************************
Sub eeLoadF (address, v)
' Load a floatingp. var from AT24C32
'******************************
local i

For i = 0 To 3
Poke VAR v,i, eeReadN(address+i)
Next i

End Sub



'******************************
Sub eeWriteN (address, Number)
' Write a number to AT24C32
'******************************
local MSB, LSB
I2CADDR=&H57 ' 24C32-DS3231

I2C open 100,100 'ENABLE I2C
msb=Int(address/256) 'MSB
lsb=address Mod 256 'LSB

I2C write I2CADDR, 0, 3, msb, lsb, Number
Pause 5
If MM.I2C <>0 Then Print "Error! 1=NAK 2=TIMEOUT"; MM.I2C:End:EndIf
I2C close

If debug Then Print Number;" written into EEPROM."
End Sub


'******************************
Function eeReadN (address)
' Read a number from AT24C32
'******************************
local MSB, LSB
I2CADDR=&H57 ' 24C32-DS3231

I2C open 100,100 'ENABLE I2C
msb=Int(address/256) 'MSB
lsb=address Mod 256 'LSB

I2C write I2CADDR, 0,2,msb,lsb
I2C read I2CADDR, 0,1,eeReadN

If MM.I2C <>0 Then Print "ERROR! 1=NAK 2=TIMEOUT"; MM.I2C:eeReadN=-1:End:EndIf
I2C close

End Function


'**************************************
' EEPROM komplett LESEN
' Shows content from AT24C32
'**************************************
Sub eedump

Local i, j, y, L, RTCBUFF(4096)
I2CADDR=&H57 ' 24C32-DS3231

For I = 0 To 4095
RTCBUFF(I)=&H0
Next I

Print " Reading buffer in ..."

I2C open 100,100 'ENABLE I2C
For J=&H0 To &HF
For I=&h0 To &hFF
L=(j*256+I)

I2C write I2CADDR, 0,2,J,I
I2C read I2CADDR, 0,1,RTCBUFF(L)

If MM.I2C <>0 Then Print "ERROR! 1=NAK 2=TIMEOUT"; MM.I2C,j,i:End:EndIf
Next I
Next J

I2C close

Print " Show buffer (Press any key!) ..."

For I=0 To 4095 Step 16
Print "Byte ";Format$(I,"%4g");" ||";
For y = 0 To 15
Print Right$("0"+Hex$(RTCBUFF(I+y)),2);"|";
Next y
Print "|";
For y = 0 To 15
If RTCBUFF(I+y) >=32 And RTCBUFF(I+y)<=126 Then ' show ascii only
C$=Chr$(RTCBUFF(I+y))
Else
C$=" "
EndIf
Print C$;
Next y
Print "|"
wait
Next I
End Sub


' wait for any key
Sub wait prompt$
If prompt$<>"" Then Print prompt$
Do While Inkey$="":Loop
End Sub



MichaelEdited by twofingers 2014-08-22
 
     Page 2 of 2    
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024