Home | History | Annotate | Download | only in m24lr64e
      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