1 /* 2 * Author: Jon Trulson <jtrulson (at) ics.com> 3 * Copyright (c) 2015 Intel Corporation. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be 14 * included in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 #include <unistd.h> 26 #include <math.h> 27 #include <iostream> 28 #include <string> 29 30 #include "m24lr64e.h" 31 32 using namespace upm; 33 using namespace std; 34 35 36 M24LR64E::M24LR64E(int bus, AccessMode mode): 37 m_i2c(bus) 38 { 39 if (mode == USER_MODE) 40 m_addr = M24LR64E_DEFAULT_I2C_ADDR; 41 else 42 m_addr = M24LR64E_DEFAULT_I2C_ADDR_E2; 43 44 mraa::Result rv; 45 if ( (rv = m_i2c.address(m_addr)) != mraa::SUCCESS) 46 { 47 throw std::runtime_error(std::string(__FUNCTION__) + 48 ": I2c.address() failed"); 49 return; 50 } 51 } 52 53 M24LR64E::~M24LR64E() 54 { 55 } 56 57 bool M24LR64E::submitPasswd(uint32_t passwd) 58 { 59 // this device actually uses two bytes to address a register 60 const int pktLen = 11; 61 uint8_t buf[pktLen]; 62 63 buf[0] = 0x09; 64 buf[1] = 0x00; 65 66 buf[2] = ((passwd >> 24) & 0xff); 67 buf[3] = ((passwd >> 16) & 0xff); 68 buf[4] = ((passwd >> 8) & 0xff); 69 buf[5] = (passwd & 0xff); 70 71 buf[6] = 0x09; 72 73 // the password is written twice 74 buf[7] = ((passwd >> 24) & 0xff); 75 buf[8] = ((passwd >> 16) & 0xff); 76 buf[9] = ((passwd >> 8) & 0xff); 77 buf[10] = (passwd & 0xff); 78 79 if (m_i2c.write(buf, pktLen)) 80 { 81 throw std::runtime_error(std::string(__FUNCTION__) + 82 ": I2c.write() failed"); 83 return false; 84 } 85 86 return true; 87 } 88 89 bool M24LR64E::writePasswd(uint32_t passwd) 90 { 91 const int pktLen = 11; 92 uint8_t buf[pktLen]; 93 94 buf[0] = 0x09; 95 buf[1] = 0x00; 96 97 buf[2] = ((passwd >> 24) & 0xff); 98 buf[3] = ((passwd >> 16) & 0xff); 99 buf[4] = ((passwd >> 8) & 0xff); 100 buf[5] = (passwd & 0xff); 101 102 buf[6] = 0x07; 103 104 // the password is written twice 105 buf[7] = ((passwd >> 24) & 0xff); 106 buf[8] = ((passwd >> 16) & 0xff); 107 buf[9] = ((passwd >> 8) & 0xff); 108 buf[10] = (passwd & 0xff); 109 110 if (m_i2c.write(buf, pktLen)) 111 { 112 throw std::runtime_error(std::string(__FUNCTION__) + 113 ": I2c.write() failed"); 114 return false; 115 } 116 117 return true; 118 } 119 120 void M24LR64E::sectorProtectConfig(unsigned int sectorNumber, 121 bool protectEnable, 122 SectorAccessRight accessRight, 123 SectorSelectPassWd passwd) 124 { 125 if(!protectEnable) { 126 EEPROM_Write_Byte(sectorNumber,0x0); 127 } else { 128 EEPROM_Write_Byte(sectorNumber, 129 protectEnable | (accessRight<<1) |(passwd<<2)); 130 } 131 } 132 133 void M24LR64E::clearSectorProtect(void) 134 { 135 uint8_t buf[64]={0x0}; 136 EEPROM_Write_Bytes(0, buf, 64); 137 } 138 139 140 void M24LR64E::sectorWriteLockBit(unsigned int sectorNumber, 141 bool sockEnable) 142 { 143 unsigned int sectorAddress = SECTOR_SECURITY_STATUS_BASE_ADDR 144 + (sectorNumber/8); 145 uint8_t sectorBit = sectorNumber % 8; 146 uint8_t preStatus = EEPROM_Read_Byte(sectorAddress); 147 148 bool status = (preStatus >> sectorBit) & 0x01; 149 if(status != sockEnable) { 150 if(status == true) { 151 writeByte(sectorAddress,preStatus&(~(1<<sectorBit))); 152 } else { 153 writeByte(sectorAddress,preStatus|(1<<sectorBit)); 154 } 155 } 156 } 157 158 uint8_t M24LR64E::getDSFID() 159 { 160 return EEPROM_Read_Byte(DSFID_ADDR); 161 } 162 163 uint8_t M24LR64E::getAFI() 164 { 165 return EEPROM_Read_Byte(AFI_ADDR); 166 } 167 168 uint8_t *M24LR64E::getUID() 169 { 170 uint8_t* buffer = new uint8_t[UID_LENGTH]; 171 EEPROM_Read_Bytes(UID_ADDR, buffer, UID_LENGTH); 172 173 return buffer; 174 } 175 176 uint32_t M24LR64E::getMemorySize() 177 { 178 uint32_t volume = 0x0; 179 volume = EEPROM_Read_Byte(MEM_SIZE_ADDR); 180 volume = volume<<8|EEPROM_Read_Byte(MEM_SIZE_ADDR+1); 181 volume = volume<<8|EEPROM_Read_Byte(MEM_SIZE_ADDR+2); 182 return volume; 183 } 184 185 void M24LR64E::clearMemory() 186 { 187 for(int i = 0; i < EEPROM_I2C_LENGTH; i++){ 188 writeByte(i,0x0); 189 } 190 } 191 192 mraa::Result M24LR64E::writeByte(unsigned int address, uint8_t data) 193 { 194 return EEPROM_Write_Byte(address, data); 195 } 196 197 mraa::Result M24LR64E::writeBytes(unsigned int address, uint8_t* buffer, int len) 198 { 199 return EEPROM_Write_Bytes(address, buffer, len); 200 } 201 202 uint8_t M24LR64E::readByte(unsigned int address) 203 { 204 return EEPROM_Read_Byte(address); 205 } 206 207 int M24LR64E::readBytes(unsigned int address, uint8_t* buffer, int len) 208 { 209 return EEPROM_Read_Bytes(address, buffer, len); 210 } 211 212 mraa::Result M24LR64E::EEPROM_Write_Byte(unsigned int address, uint8_t data) 213 { 214 const int pktLen = 3; 215 uint8_t buf[pktLen]; 216 mraa::Result rv; 217 218 buf[0] = ((address >> 8) & 0xff); 219 buf[1] = (address & 0xff); 220 buf[2] = data; 221 222 if ((rv = m_i2c.write(buf, pktLen))) 223 throw std::runtime_error(std::string(__FUNCTION__) + 224 ": I2c.write() failed"); 225 226 usleep(I2C_WRITE_TIME * 1000); 227 return rv; 228 } 229 230 mraa::Result M24LR64E::EEPROM_Write_Bytes(unsigned int address, uint8_t* data, 231 int len) 232 { 233 const int pktLen = 2 + len; 234 uint8_t buf[pktLen]; 235 mraa::Result rv; 236 237 buf[0] = ((address >> 8) & 0xff); 238 buf[1] = (address & 0xff); 239 240 for (int i=0; i<len; i++) 241 buf[2+i] = data[i]; 242 243 if ((rv = m_i2c.write(buf, pktLen))) 244 throw std::runtime_error(std::string(__FUNCTION__) + 245 ": I2c.write() failed"); 246 247 usleep(I2C_WRITE_TIME * 1000); 248 249 return rv; 250 } 251 252 uint8_t M24LR64E::EEPROM_Read_Byte(unsigned int address) 253 { 254 const int apktLen = 2; 255 uint8_t abuf[apktLen]; 256 257 abuf[0] = ((address >> 8) & 0xff); 258 abuf[1] = (address & 0xff); 259 260 if (m_i2c.write(abuf, apktLen)) 261 { 262 throw std::runtime_error(std::string(__FUNCTION__) + 263 ": I2c.write() failed"); 264 return 0x00; 265 } 266 267 const int pktLen = 1; 268 uint8_t buf[apktLen]; 269 270 buf[0] = 0; 271 272 if (m_i2c.read(buf, pktLen) != pktLen) 273 { 274 throw std::runtime_error(std::string(__FUNCTION__) + 275 ": I2c.write() failed"); 276 return 0x00; 277 } 278 279 return buf[0]; 280 } 281 282 int M24LR64E::EEPROM_Read_Bytes(unsigned int address, 283 uint8_t* buffer, int len) 284 { 285 const int apktLen = 2; 286 uint8_t abuf[apktLen]; 287 288 abuf[0] = ((address >> 8) & 0xff); 289 abuf[1] = (address & 0xff); 290 291 if (m_i2c.write(abuf, apktLen)) 292 { 293 throw std::runtime_error(std::string(__FUNCTION__) + 294 ": I2c.write() failed"); 295 return false; 296 } 297 298 int rv = m_i2c.read(buffer, len); 299 if (rv != len) 300 { 301 throw std::runtime_error(std::string(__FUNCTION__) + 302 ": I2c.read() failed"); 303 } 304 305 return rv; 306 } 307