Interesting, Jerry. I tried the code David posted with my new library and that worked fine and even in my original code it correctly selected the Longword routine when I was writing a Longword variable.
Do you think it is something wrong with my code, or is what I've done confusing the compiler in some way? I'll post the entire library below but one thing I did notice is that I've actually done the modification slightly differently from the way the original works. That had the WriteItem routines - in the main - calling another routine which actually did the writing. The exception to this it the string writing routine which processes the string in the WriteItem routine rather than having / calling a WriteString. I don't know if there is a reason for this, maybe to avoid passing the string on too many times - I had issued with that a while back although I believe David has since fixed that problem.
My routines process the array in the WriteItem. I'm wondering if creating a WriteArray routine and calling that from the WriteItem will help.
Actually, that may even be the source of my problem - I've got two WriteItem routines for arrays, one for const arrays and one for string arrays - I can see the need to use either and as arrays can only be passed by reference it is necessary to have separate routines. Maybe that is causing the problem? I also need to work out in my head if I can do the double-passing in these circumstances.
I know a simple solution would just be to create WriteArray routines and remove the WriteItem ones but for neatness it would be good to get this working and also it may be ther eis an underlying issue here.
I doubt it makes a difference, but for reference I'm using a PIC18F46K22 which has 1024 bytes of EEPROM, although at the moment I'm only using the first 256 bytes.
My EEPROM.bas library:
Code: Select all
Module EE
Include "system.bas"
// does device support EEPROM...
#if _eeprom = 0
#error _device + " does not support EEPROM"
// EEPROM address is 8 bits...
#elseif _eeprom = 256
Dim TAddress As EEADR
// EEPROM address is 16 bits...
#else
Dim TAddress As EEADR.AsWord
#endif
// EEPROM address...
Public Dim
Address As TAddress
{
****************************************************************************
* Name : SetAddress (PRIVATE) *
* Purpose : Sets the current EEPROM address *
****************************************************************************
}
Sub SetAddress(pAddress As TAddress)
End Sub
{
****************************************************************************
* Name : BackToFLASH (PRIVATE) *
* Purpose : Restores EECON1 register to FLASH program access. Swordfish *
* : needs EEPGD to be set in order to access program memory *
* : constants (such as strings) to be accessed when a program is *
* : executing. This inline sub restores EEPGD after EEPROM access *
****************************************************************************
}
Inline Sub BackToFLASH()
EECON1 = $80
End Sub
{
****************************************************************************
* Name : ReadByte *
* Purpose : Read a byte from EEPROM *
* : pAddress is EEADR (EEADRH) *
* : Returned in EEDATA *
****************************************************************************
}
Public Function ReadByte(pAddress As TAddress) As Byte
Dim RD As EECON1.Booleans(0)
EECON1 = $00
RD = true
result = EEDATA
BackToFLASH
Inc(Address)
ClrWDT
End Function
{
****************************************************************************
* Name : ReadBoolean *
* Purpose : Read a boolean value from EEPROM *
****************************************************************************
}
Public Function ReadBoolean(pAddress As TAddress) As Boolean
Result = Boolean(ReadByte(pAddress))
End Function
{
****************************************************************************
* Name : ReadWord *
* Purpose : Read a word from EEPROM *
****************************************************************************
}
Public Function ReadWord(pAddress As TAddress) As Word
Result.Bytes(0) = ReadByte(pAddress)
Result.Bytes(1) = ReadByte(pAddress)
End Function
{
****************************************************************************
* Name : ReadLongWord *
* Purpose : Read a long word from EEPROM *
****************************************************************************
}
Public Function ReadLongWord(pAddress As TAddress) As LongWord
Result.Bytes(0) = ReadByte(pAddress)
Result.Bytes(1) = ReadByte(pAddress)
Result.Bytes(2) = ReadByte(pAddress)
Result.Bytes(3) = ReadByte(pAddress)
End Function
{
****************************************************************************
* Name : ReadFloat *
* Purpose : Read a floating point value from EEPROM *
****************************************************************************
}
Public Function ReadFloat(pAddress As TAddress) As Float
Result.Bytes(0) = ReadByte(pAddress)
Result.Bytes(1) = ReadByte(pAddress)
Result.Bytes(2) = ReadByte(pAddress)
Result.Bytes(3) = ReadByte(pAddress)
End Function
{
****************************************************************************
* Name : WriteByte *
* Purpose : Write a byte to EEPROM *
* : pAddress is EEADR (EEADRH) *
* : pValue is EEDATA *
****************************************************************************
}
Public Sub WriteByte(pAddress As TAddress, pValue As EEDATA)
Dim WR As EECON1.Booleans(1)
Dim WREN As EECON1.Booleans(2)
Dim INTCON_SHADOW As Byte
// enable writes...
EECON1 = $00
WREN = true
INTCON_SHADOW = INTCON
// required write sequence...
INTCON = 0
EECON2 = $55
EECON2 = $AA
WR = true
INTCON = INTCON_SHADOW
// wait for write completion...
Repeat
ClrWDT
Until Not WR
WREN = false // disable writes
BackToFLASH
Inc(Address)
End Sub
{
****************************************************************************
* Name : WriteBoolean *
* Purpose : Write a boolean to EEPROM *
****************************************************************************
}
Public Sub WriteBoolean(pAddress As TAddress,pValue As Boolean)
WriteByte(pAddress,Byte(pValue))
End Sub
{
****************************************************************************
* Name : WriteWord *
* Purpose : Write a word to EEPROM *
****************************************************************************
}
Public Sub WriteWord(pAddress As TAddress,pValue As Word)
WriteByte(pAddress,pValue.Bytes(0))
WriteByte(pAddress,pValue.Bytes(1))
End Sub
{
****************************************************************************
* Name : WriteLongWord *
* Purpose : Write a long word to EEPROM *
****************************************************************************
}
Public Sub WriteLongWord(pAddress As TAddress, pValue As LongWord)
WriteByte(pAddress,pValue.Bytes(0))
WriteByte(pAddress,pValue.Bytes(1))
WriteByte(pAddress,pValue.Bytes(2))
WriteByte(pAddress,pValue.Bytes(3))
End Sub
{
****************************************************************************
* Name : WriteFloat *
* Purpose : Write a floating point value to EEPROM *
****************************************************************************
}
Public Sub WriteFloat(pAddress As TAddress, pValue As Float)
WriteByte(pAddress,pValue.Bytes(0))
WriteByte(pAddress,pValue.Bytes(1))
WriteByte(pAddress,pValue.Bytes(2))
WriteByte(pAddress,pValue.Bytes(3))
End Sub
{
****************************************************************************
* Name : ReadItem (OVERLOAD) *
* Purpose : Read a boolean value from EEPROM *
****************************************************************************
}
Sub ReadItem(ByRef pValue As Boolean)
pValue = Boolean(ReadByte(Address))
End Sub
{
****************************************************************************
* Name : ReadItem (OVERLOAD) *
* Purpose : Read a byte value from EEPROM *
****************************************************************************
}
Sub ReadItem(ByRef pValue As Byte)
pValue = ReadByte(Address)
End Sub
{
****************************************************************************
* Name : ReadItem (OVERLOAD) *
* Purpose : Read a shortint value from EEPROM *
****************************************************************************
}
Sub ReadItem(ByRef pValue As ShortInt)
pValue = ReadByte(Address)
End Sub
{
****************************************************************************
* Name : ReadItem (OVERLOAD) *
* Purpose : Read a word from EEPROM *
****************************************************************************
}
Sub ReadItem(ByRef pValue As Word)
pValue = ReadWord(Address)
End Sub
{
****************************************************************************
* Name : ReadItem (OVERLOAD) *
* Purpose : Read an integer from EEPROM *
****************************************************************************
}
Sub ReadItem(ByRef pValue As Integer)
pValue = ReadWord(Address)
End Sub
{
****************************************************************************
* Name : ReadItem (OVERLOAD) *
* Purpose : Read a long word from EEPROM *
****************************************************************************
}
Sub ReadItem(ByRef pValue As LongWord)
pValue = ReadLongWord(Address)
End Sub
{
****************************************************************************
* Name : ReadItem (OVERLOAD) *
* Purpose : Read a long integer from EEPROM *
****************************************************************************
}
Sub ReadItem(ByRef pValue As LongInt)
pValue = ReadLongWord(Address)
End Sub
{
****************************************************************************
* Name : ReadItem (OVERLOAD) *
* Purpose : Read a floating point value from EEPROM *
****************************************************************************
}
Sub ReadItem(ByRef pValue As Float)
pValue = ReadFloat(Address)
End Sub
{
****************************************************************************
* Name : ReadItem (OVERLOAD) *
* Purpose : Read a string from EEPROM *
****************************************************************************
}
Sub ReadItem(ByRef pStr As String)
Dim StrPtr As POSTINC0
FSR0 = @pStr
Repeat
StrPtr = ReadByte(Address)
Until Char(EEDATA) = null
End Sub
{
***
* ReadItem for an array passed by reference
**
}
Sub ReadItem(ByRef pValue() As Byte)
Dim aPtr As Byte
For aPtr = 0 To Bound(pValue)
pValue(aPtr) = ReadByte(Address)
Next
End Sub
{
****************************************************************************
* Name : Read (COMPOUND) *
* Purpose : Read multiple items to EEPROM *
****************************************************************************
}
Public Compound Sub Read(SetAddress, ReadItem)
{
****************************************************************************
* Name : WriteItem (OVERLOAD) *
* Purpose : Write a boolean to EEPROM *
****************************************************************************
}
Sub WriteItem(pValue As Boolean)
WriteByte(Address,Byte(pValue))
End Sub
{
****************************************************************************
* Name : WriteItem (OVERLOAD) *
* Purpose : Write a byte to EEPROM *
****************************************************************************
}
Sub WriteItem(pValue As Byte)
WriteByte(Address,pValue)
End Sub
{
****************************************************************************
* Name : WriteItem (OVERLOAD) *
* Purpose : Write a short integer to EEPROM *
****************************************************************************
}
Sub WriteItem(pValue As ShortInt)
WriteByte(Address,pValue)
End Sub
{
****************************************************************************
* Name : WriteItem (OVERLOAD) *
* Purpose : Write a word to EEPROM *
****************************************************************************
}
Sub WriteItem(pValue As Word)
WriteWord(Address, pValue)
End Sub
{
****************************************************************************
* Name : WriteItem (OVERLOAD) *
* Purpose : Write an integer to EEPROM *
****************************************************************************
}
Sub WriteItem(pValue As Integer)
WriteWord(Address, pValue)
End Sub
{
****************************************************************************
* Name : WriteItem (OVERLOAD) *
* Purpose : Write a long word to EEPROM *
****************************************************************************
}
Sub WriteItem(pValue As LongWord)
WriteLongWord(Address, pValue)
End Sub
{
****************************************************************************
* Name : WriteItem (OVERLOAD) *
* Purpose : Write a long integer to EEPROM *
****************************************************************************
}
Sub WriteItem(pValue As LongInt)
WriteLongWord(Address, pValue)
End Sub
{
****************************************************************************
* Name : WriteItem (OVERLOAD) *
* Purpose : Write a floating point value to EEPROM *
****************************************************************************
}
Sub WriteItem(pValue As Float)
WriteFloat(Address, pValue)
End Sub
{
****************************************************************************
* Name : WriteItem (OVERLOAD) *
* Purpose : Write a string value to EEPROM *
****************************************************************************
}
Sub WriteItem(pValue As String)
Dim StrPtr As POSTINC0
FSR0 = @pValue
Repeat
WriteByte(Address,StrPtr)
Until Char(EEDATA) = null
End Sub
{
***
* WriteItem for an array passed by reference
**
}
Sub WriteItem(ByRef pValue() As Byte)
Dim aPtr As Byte
For aPtr = 0 To Bound(pValue)
WriteByte(Address,pValue(aPtr))
Next
End Sub
// As above for const arrays
Sub WriteItem(ByRefConst pValue() As Byte)
Dim aPtr As Byte
For aPtr = 0 To Bound(pValue)
WriteByte(Address,pValue(aPtr))
Next
End Sub
{
****************************************************************************
* Name : Write (COMPOUND) *
* Purpose : Write multiple items to EEPROM *
****************************************************************************
}
Public Compound Sub Write(SetAddress, WriteItem)
{
****************************************************************************
* Name : RefreshArray() *
* Purpose : Reads and writes back the entire EEPROM memory. This should be *
* done periodically to ensure data is not lost. *
* Disable interrupts before calling this routine. *
****************************************************************************
}
Public Sub RefreshArray()
Dim RD As EECON1.Booleans(0)
Dim WR As EECON1.Booleans(1)
Dim WREN As EECON1.Booleans(2)
EEADR = 0 // Set address to zero
EECON1 = $00 // enable writes...
WREN = true
Repeat
RD = true // Read in to EEDATA register
EECON2 = $55 // required write sequence...
EECON2 = $AA
WR = true // Initiate write - will write the contents of EEDATA back to the same location
Repeat // wait for write completion...
ClrWDT
Until Not WR
Inc(EEADR) // Increment EEADR, will loop to zero when memory size exceeded
Until EEADR = 0
WREN = false // disable writes
BackToFLASH
End Sub