-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathI2C_ROMEngine.spin
300 lines (233 loc) · 11.8 KB
/
I2C_ROMEngine.spin
1
{{///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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,//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// I2C Circuit://// 3.3V// |// R 10KOHM// |// Data Pin Number --- EEPROM SDA Pin.//// 3.3V// |// R 10KOHM// |// Clock Pin Number --- EEPROM SCL Pin.///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////}}PUB 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.'' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// result &= readPage(EEPROMaddress, @result, 1)PUB 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.'' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// return writePage(EEPROMaddress, @value, 1)PUB 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.'' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// result &= readPage(EEPROMaddress, @result, 2)PUB 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.'' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// return writePage(EEPROMaddress, @value, 2)PUB 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.'' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// result &= readPage(EEPROMaddress, @result, 4)PUB 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.'' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// return writePage(EEPROMaddress, @value, 4)PUB 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.'' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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 clearLockPUB 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.'' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// result := eepromPoll(EEPROMaddress) if(result) repeat ((byteCount <# (65_536 - (RAMaddress #> 0))) #> 0) result and= transmitPacket(byte[RAMaddress++]) stopDataTransfer clearLockPUB 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.'' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ROMEngineStop dataPin := ((dataPinNumber <# 31) #> 0) clockPin := ((clockPinNumber <# 31) #> 0) if((dataPin <> clockPin) and (chipver == 1)) lockNumber := lockNumberToUse if(lockNumberToUse == -1) lockNumber := locknew result or= ++lockNumberPUB ROMEngineStop '' 3 Stack Longs'' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////'' // Returns the lock used by the driver.'' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if(lockNumber) lockret(-1 + lockNumber~)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)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] := truePRI 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] := truePRI startDataTransfer ' 3 Stack Longs outa[dataPin] := false outa[clockPin] := false dira[dataPin] := true dira[clockPin] := truePRI stopDataTransfer ' 3 Stack Longs dira[clockPin] := false dira[dataPin] := falsePRI setLock ' 3 Stack Longs if(lockNumber) repeat while(lockset(lockNumber - 1))PRI clearLock ' 3 Stack Longs if(lockNumber) lockclr(lockNumber - 1)DAT' //////////////////////Variable Array/////////////////////////////////////////////////////////////////////////////////////////dataPin byte 29 ' Default data pin.clockPin byte 28 ' Default clock pin.lockNumber byte 00 ' Driver lock number.' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////{{///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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.///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////}}