I2C_ROMEngine

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// I2C Electrically Erasable Programmable Read Only Memory Engine
//
// Author: Kwabena W. Agyeman
// Updated: 7/27/2010
// Designed For: P8X32A
// Version: 1.1
//
// Copyright (c) 2010 Kwabena W. Agyeman
// See end of file for terms of use.
//
// Update History:
//
// v1.0 - Original release - 8/8/2009.
// v1.1 - Added variable pin support - 7/27/2010.
//
// For each included copy of this object only one spin interpreter should access it at a time.
//
// Nyamekye,
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Connection Diagram

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // I2C Circuit: // // 3.3V // | // R 10KOHM // | // Data Pin Number --- EEPROM SDA Pin. // // 3.3V // | // R 10KOHM // | // Clock Pin Number --- EEPROM SCL Pin. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Public Spin methods

Start and Stop

ROMEngineStart and ROMEngineStop methods are used for starting and stopping this object. This uses/frees the pins used.


ROMEngineStop


3 Stack Longs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Returns the lock used by the driver. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SOURCE CODE...
PUB ROMEngineStop
  if(lockNumber)
    lockret(-1 + lockNumber~)


ROMEngineStart(dataPinNumber, clockPinNumber, lockNumberToUse)


9 Stack Longs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Checks out a lock for the driver and changes the I2C Circuit pins. // // Returns true on success and false on failure. // // DataPinNumber - Pin to use to drive the SDA data line circuit. // ClockPinNumber - Pin to use to drive the SCL clock line circuit. // LockNumberToUse - Lock number to use if sharing the I2C bus (0 - 7). -1 to request a new lock number. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SOURCE CODE...
PUB ROMEngineStart(dataPinNumber, clockPinNumber, lockNumberToUse)
  ROMEngineStop
  dataPin := ((dataPinNumber <# 31) #> 0)
  clockPin := ((clockPinNumber <# 31) #> 0)
  if((dataPin <> clockPin) and (chipver == 1))
    lockNumber := lockNumberToUse
    if(lockNumberToUse == -1)
      lockNumber := locknew
    result or= ++lockNumber


EEPROM read/write

Her you find basic send/receive-methods for single bytes.


readByte(EEPROMaddress)


18 Stack Longs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Reads a byte from the EEPROM. It is recommended to read the byte on a byte boundary. // // Returns the byte on success and false on failure. Could return a byte of value 0. // // EEPROMaddress - Starting byte address of the data to access. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SOURCE CODE...
PUB readByte(EEPROMaddress) 
  result &= readPage(EEPROMaddress, @result, 1)


writeByte(EEPROMaddress, value)


19 Stack Longs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Writes a byte to the EEPROM. It is recommended to write the byte on a byte boundary. // // Returns true on success and false on failure. // // EEPROMaddress - Starting byte address of the data to access. // Value - Value to write to the EEPROM. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SOURCE CODE...
PUB writeByte(EEPROMaddress, value) 
  return writePage(EEPROMaddress, @value, 1)


readWord(EEPROMaddress)


18 Stack Longs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Reads a word from the EEPROM. It is recommended to read the word on a word boundary. // // Returns the word on success and false on failure. Could return a word of value 0. // // EEPROMaddress - Starting byte address of the data to access. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SOURCE CODE...
PUB readWord(EEPROMaddress) 
  result &= readPage(EEPROMaddress, @result, 2)


writeWord(EEPROMaddress, value)


19 Stack Longs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Writes a word to the EEPROM. It is recommended to write the word on a word boundary. // // Returns true on success and false on failure. // // EEPROMaddress - Starting byte address of the data to access. // Value - Value to write to the EEPROM. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SOURCE CODE...
PUB writeWord(EEPROMaddress, value) 
  return writePage(EEPROMaddress, @value, 2)


readLong(EEPROMaddress)


18 Stack Longs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Reads a long from the EEPROM. It is recommended to read the long on a long boundary. // // Returns the long on success and false on failure. Could return a long of value 0. // // EEPROMaddress - Starting byte address of the data to access. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SOURCE CODE...
PUB readLong(EEPROMaddress) 
  result &= readPage(EEPROMaddress, @result, 4)


writeLong(EEPROMaddress, value)


19 Stack Longs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Writes a long to the EEPROM. It is recommended to write the long on a long boundary. // // Returns true on success and false on failure. // // EEPROMaddress - Starting byte address of the data to access. // Value - Value to write to the EEPROM. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SOURCE CODE...
PUB writeLong(EEPROMaddress, value) 
  return writePage(EEPROMaddress, @value, 4)


readPage(EEPROMaddress, RAMaddress, byteCount)


14 Stack Longs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Reads bytes from the EEPROM. Uses a 19 bit addressing scheme which can acess multiple EERPOMs on a bus. // // This rountine can only read from the EEPROM selected. Any reads past that EEPROM will warp arround. // // It is recommended to use the byte/word/long read rountines used on byte/word/long boundaries respectively. // // Returns true on success and false on failure. // // EEPROMaddress - Starting byte address of the data to access. // RAMaddress - Starting byte address of the data to write to. // ByteCount - Number of bytes to read. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SOURCE CODE...
PUB readPage(EEPROMaddress, RAMaddress, byteCount) 
  result := eepromPoll(EEPROMaddress)

  if(result)

    stopDataTransfer
    startDataTransfer

    result and= transmitPacket(constant((10 << 4) | 1) | ((EEPROMaddress >> 15) & $E))

    repeat ((byteCount <# (65_536 - (RAMaddress #> 0))) #> 0)
      byte[RAMaddress++] := receivePacket(--byteCount)

  stopDataTransfer
  clearLock


writePage(EEPROMaddress, RAMaddress, byteCount)


14 Stack Longs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Writes bytes to the EEPROM. Uses a 19 bit addressing scheme which can access multiple EERPOMs on a bus. // // This rountine can only write to the page of the EEPROM selected. Any writes past that page will warp arround. // // It is recommended to use the byte/word/long write rountines used on byte/word/long boundaries respectively. // // Returns true on success and false on failure. // // EEPROMaddress - Starting byte address of the data to access. // RAMaddress - Starting byte address of the data to read from. // ByteCount - Number of bytes to write. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SOURCE CODE...
PUB writePage(EEPROMaddress, RAMaddress, byteCount) 
  result := eepromPoll(EEPROMaddress)

  if(result)

    repeat ((byteCount <# (65_536 - (RAMaddress #> 0))) #> 0)
      result and= transmitPacket(byte[RAMaddress++])

  stopDataTransfer
  clearLock


PRIvate Methods


eepromPoll(EEPROMaddress)


SOURCE CODE...
PRI eepromPoll(EEPROMaddress) 
' 8 Stack Longs 
  setLock
  startDataTransfer
  result := cnt

  repeat until(transmitPacket(constant(10 << 4) | ((EEPROMaddress >> 15) & $E)))

    stopDataTransfer
    startDataTransfer

    if((||(cnt - result)) > (clkfreq / constant(1_000 / 5)))
      return false

  result := transmitPacket(EEPROMaddress >> 8)
  result and= transmitPacket(EEPROMaddress)


transmitPacket(value)


SOURCE CODE...
PRI transmitPacket(value) ' 4 Stack Longs

  value := ((!value) >< 8)

  repeat 8
    dira[dataPin] := value
    dira[clockPin] := false
    dira[clockPin] := true
    value >>= 1

  dira[dataPin] := false
  dira[clockPin] := false
  result := not(ina[dataPin])
  dira[clockPin] := true
  dira[dataPin] := true


receivePacket(aknowledge)


SOURCE CODE...
PRI receivePacket(aknowledge) ' 4 Stack Longs

  dira[dataPin] := false

  repeat 8
    result <<= 1
    dira[clockPin] := false
    result |= ina[dataPin]
    dira[clockPin] := true

  dira[dataPin] := (not(not(aknowledge)))
  dira[clockPin] := false
  dira[clockPin] := true
  dira[dataPin] := true


startDataTransfer ' 3 Stack Longs


SOURCE CODE...
PRI startDataTransfer ' 3 Stack Longs

  outa[dataPin] := false
  outa[clockPin] := false
  dira[dataPin] := true
  dira[clockPin] := true


stopDataTransfer ' 3 Stack Longs


SOURCE CODE...
PRI stopDataTransfer ' 3 Stack Longs

  dira[clockPin] := false
  dira[dataPin] := false


setLock ' 3 Stack Longs


SOURCE CODE...
PRI setLock ' 3 Stack Longs

  if(lockNumber)
    repeat while(lockset(lockNumber - 1))


clearLock ' 3 Stack Longs


SOURCE CODE...
PRI clearLock ' 3 Stack Longs

  if(lockNumber)
    lockclr(lockNumber - 1)


Global Static DATa


SOURCE CODE...

' //////////////////////Variable Array/////////////////////////////////////////////////////////////////////////////////////////

dataPin                 byte 29 ' Default data pin.
clockPin                byte 28 ' Default clock pin.
lockNumber              byte 00 ' Driver lock number.

' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


License

┌──────────────────────────────────────────────────────────────────────────────────────┐
│                            TERMS OF USE: MIT License                                 │                                                            
├──────────────────────────────────────────────────────────────────────────────────────┤
│Permission is hereby granted, free of charge, to any person obtaining a copy of this  │
│software and associated documentation files (the "Software"), to deal in the Software │
│without restriction, including without limitation the rights to use, copy, modify,    │
│merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    │
│permit persons to whom the Software is furnished to do so, subject to the following   │
│conditions:                                                                           │
│                                                                                      │
│The above copyright notice and this permission notice shall be included in all copies │
│or substantial portions of the Software.                                              │
│                                                                                      │
│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   │
│INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         │
│PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    │
│HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  │
│CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  │
│OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         │
└──────────────────────────────────────────────────────────────────────────────────────┘

Source

This documentation was generated purely thru the power of the mind of @PhiPi out of the source
<a href='I2C_ROMEngine.spin' target='_blank'>I2C_ROMEngine.spin</a>
using <a href='http://www.phipi.com/spin2html/' target='_blank'>Spin Code Documenter</a>