24LC640

Swordfish already includes a module to read and write data to a 24LC640 EEPROM - see the sample samples folder. However, this little bit of code strips away the various module layers so you can see how it's done. It should be very easy to modify and add new functionality.

The following code implements a WaitFor() routine. This is very useful if you want to (a) wait until writes are enabled on the device and (b) wait for write completion. The latter call is very useful and removes the need for an explicit delay after each write. The code also implements an Available() function, which checks to see if the SPI EEPROM is ready to receive commands or not.

// device and clock...
Device = 18F452
Clock = 20

// use software or hardware SPI...
#option USE_SOFTWARE_SPI = false

// import modules...
Include "usart.bas"
Include "convert.bas"

#if USE_SOFTWARE_SPI
#option SSPI_SCK = PORTC.3
#option SSPI_SDI = PORTC.4
#option SSPI_SDO = PORTC.5
Include "SSPI.bas"
Dim
   SPIWriteByte As SSPI.WriteByte,
   SPIReadByte As SSPI.ReadByte
#else
Include "SPI.bas"
Dim
   SPIWriteByte As SPI.WriteByte,
   SPIReadByte As SPI.ReadByte
#endif

// SPI EEPROM constants...
Const
   cmdRead = $03,
   cmdWrite = $02,
   cmdWriteEnable = $06,
   cmdWriteDisable = $04,
   cmdReadStatus = $05,
   cmdWriteStatus = $01,
   stWriteEnabled = $02,
   stWriteFinished = $00

// chip select pin...   
Dim CS As PORTC.1

// enable writes...
Sub EnableWrite()
   CS = 0                              // chip select on
   SPIWriteByte(cmdWriteEnable)       // enable writes
   CS = 1                              // chip select off
End Sub

// wait for command acknowledge - parameters may be stWriteEnabled
// and stWriteFinished 
Sub WaitFor(pStatus As Byte)
   Dim WriteStatus As Byte
   Repeat
      CS = 0
      SPIWriteByte(cmdReadStatus)
      WriteStatus = SPIReadByte
      CS = 1
   Until WriteStatus = pStatus
End Sub

// Read a byte...
Function ReadByte(pAddress As Word) As Byte
   CS = 0                             // chip select on 
   SPIWriteByte(cmdRead)             // read command
   SPIWriteByte(pAddress.Byte1)      // write address (high byte)
   SPIWriteByte(pAddress.Byte0)      // write address (low byte)
   Result = SPIReadByte              // read the data
   CS = 1                             // chip select off
End Function

// Write a byte...
Sub WriteByte(pAddress As Word, pData As Byte)
   EnableWrite                        // enable writes
   WaitFor(stWriteEnabled)            // wait for write enable flag
   CS = 0                             // chip select on
   SPIWriteByte(cmdWrite)            // write command
   SPIWriteByte(pAddress.Byte1)      // write address (high byte)
   SPIWriteByte(pAddress.Byte0)      // write address (low byte)
   SPIWriteByte(pData)               // write the data
   CS = 1                             // chip select off
   WaitFor(stWriteFinished)           // wait for write completion
End Sub

// see if the device is ready to accept commands...
Function Available() As Boolean
   CS = 0
   SPIWriteByte(cmdReadStatus)
   Result = Boolean(Not SPIReadByte)
   CS = 1
End Function

// local variables...
Dim Address As Word
Dim Index As Byte

// initialise...
SetBaudrate(br115200)
#if USE_SOFTWARE_SPI
SSPI.Initialize
SSPI.SetClock(spiIdleHigh)
#else
SPI.SetAsMaster(spiOscDiv64)
SPI.SetClock(spiIdleHigh, spiRisingEdge)
SPI.SetSample(spiSampleEnd)
SPI.Enabled = true
#endif
Output(CS)

// write and read back 10 numbers to SPI EEPROM...   
If Not Available Then
   USART.Write("NOT FOUND",13,10)
Else   
   USART.Write("Available, writing data...",13,10)
   Index = 0
   For Address = 0 To 10 
      WriteByte(Address, Index)
      Inc(Index, 10)
   Next

   USART.Write("Reading data...",13,10)
   For Address = 0 To 10
      Index = ReadByte(Address)
      USART.Write(DecToStr(Index),13,10)
      DelayMS(500)
   Next
EndIf