Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
M24512.cpp
00001 /* ISL MBED Libraries 00002 * Copyright (C) 2019 - Invisible Systems Ltd. All Rights Reserved. 00003 */ 00004 #include "M24512.h" 00005 #include "mbed.h" 00006 00007 00008 00009 /** I2C Frequency 00010 Roughly calculate time to write a full page based on freq 00011 ((1 / 500000) * (130*9) * 1000) + 5 00012 */ 00013 #define M24512_DEFAULT_FREQUENCY (uint32_t)50000 00014 00015 /** Read command | on device address 00016 */ 00017 #define M24512_COMMAND_READ (uint8_t)0 00018 00019 /** Write command | on device address 00020 */ 00021 #define M24512_COMMAND_WRITE (uint8_t)1 00022 00023 /** Device Page Size 00024 */ 00025 #define M24512_EEPROM_PAGE_SIZE (uint16_t)128 00026 00027 /** Device Page Count 00028 */ 00029 #define M24512_EEPROM_PAGES (uint16_t)512 00030 00031 00032 00033 M24512::M24512(PinName sda, PinName scl, uint8_t address) : _i2c(sda,scl), _addr(address) 00034 { 00035 frequency(M24512_DEFAULT_FREQUENCY); 00036 } 00037 00038 00039 M24512::~M24512() 00040 { 00041 00042 } 00043 00044 00045 void M24512::frequency(uint32_t hz) 00046 { 00047 _i2c.frequency(hz); 00048 } 00049 00050 00051 uint32_t M24512::get_total_memory() const 00052 { 00053 return (get_page_size() * get_page_count()) / 1024 ; 00054 } 00055 00056 00057 uint16_t M24512::get_page_size() const 00058 { 00059 return M24512_EEPROM_PAGE_SIZE; 00060 } 00061 00062 00063 uint16_t M24512::get_page_count() const 00064 { 00065 return M24512_EEPROM_PAGES; 00066 } 00067 00068 00069 M24512::status_t M24512::ready() 00070 { 00071 int8_t ack; 00072 char cmd[2] = {0,0}; 00073 int timeout = 60; 00074 00075 // Wait for end of write 00076 do{ 00077 // read from addr 0 with a length of 0 just to check the i2c state 00078 ack = _i2c.write( _addr | M24512_COMMAND_READ, cmd, 0 ); 00079 if (ack == 0 || timeout-- == 0) 00080 { 00081 return (ack == 0) ? M24512::M24512_SUCCESS : M24512::M24512_RDY_TIMEOUT ; 00082 }else 00083 { 00084 //printf("waiting for ready...\r\n"); 00085 } 00086 }while(ack != 0); 00087 00088 return (ack == 0) ? M24512::M24512_SUCCESS : M24512::M24512_I2C_ERROR ; 00089 } 00090 00091 00092 M24512::status_t M24512::read(uint16_t addr, char* data, uint16_t size) 00093 { 00094 int ret = 0; 00095 char cmd[2]; 00096 00097 00098 // check for overflow 00099 if ( ( addr + size) > (get_page_size() * get_page_count()) ) 00100 { 00101 return M24512::M24512_MEM_OVERFLOW ; 00102 } 00103 00104 cmd[0] = addr >> 8; 00105 cmd[1] = addr; 00106 00107 // set address to read from 00108 ret = _i2c.write(_addr | M24512_COMMAND_READ, (const char*)&cmd, 2, true ); 00109 if (ret != 0) 00110 { 00111 return M24512::M24512_I2C_ERROR ; 00112 } 00113 00114 // read data into buffer 00115 ret = _i2c.read(_addr | M24512_COMMAND_READ, (char*)data, size ); 00116 if (ret != 0) 00117 { 00118 return M24512::M24512_I2C_ERROR ; 00119 } 00120 00121 return ready(); 00122 } 00123 00124 00125 M24512::status_t M24512::write_page(uint16_t addr, const char* data, uint16_t size) 00126 { 00127 /** TODO - Change this to dynamic incase page size increase! */ 00128 char cmd[M24512_EEPROM_PAGE_SIZE]; 00129 int ret = 0; 00130 int8_t retry = 3; 00131 00132 // check for overflow 00133 if ( ( addr + size) > (get_page_size() * get_page_count()) ) 00134 { 00135 return M24512::M24512_MEM_OVERFLOW ; 00136 } 00137 00138 // check for page boundary 00139 /** TODO - Change this to get_page_size incase change in size */ 00140 if (size > M24512_EEPROM_PAGE_SIZE) 00141 { 00142 return M24512::M24512_MEM_OVERFLOW ; 00143 } 00144 00145 cmd[0] = addr >> 8; 00146 cmd[1] = addr; 00147 00148 for (uint8_t i = 0; i < size ; i++) 00149 { 00150 cmd[2+i] = data[i]; 00151 } 00152 00153 while (retry--) 00154 { 00155 ret = _i2c.write(_addr | M24512_COMMAND_WRITE, (const char*)&cmd, size + 2 ); 00156 if (ret != 0) 00157 { 00158 osDelay(100); 00159 }else{ 00160 break; 00161 } 00162 } 00163 00164 if (ret != 0) 00165 { 00166 return M24512::M24512_I2C_ERROR ; 00167 } 00168 00169 return ready(); 00170 } 00171 00172 00173 M24512::status_t M24512::write(uint16_t addr, const char* data, uint16_t size) 00174 { 00175 M24512::status_t ret = M24512_SUCCESS ; 00176 00177 int16_t wlen = 0; // write length 00178 int16_t dlen = size; // data length remaining 00179 int16_t addr_ofst = 0; // address to write 00180 00181 00182 while (dlen > 0) 00183 { 00184 wlen = ((dlen > get_page_size()) ? get_page_size() : dlen); 00185 00186 // if addr is not at the start of a page then write bytes until we hit the boundary 00187 if ( addr_ofst == 0 && (addr % get_page_size()) != 0 ) 00188 { 00189 wlen = get_page_size() - (addr % get_page_size()); 00190 // check we have enough data to hit end of page if not just write the entire length 00191 if (size < wlen) 00192 { 00193 wlen = size; 00194 } 00195 } 00196 00197 //printf("Write: Addr:%d Write: %d Remain: %d next: %d\n", addr + addr_ofst, wlen, dlen - wlen , addr_ofst + wlen); 00198 00199 // write in blocks of %page_size% 00200 ret = write_page( addr + addr_ofst, data + addr_ofst, wlen ); 00201 if ( ret != M24512::M24512_SUCCESS ) 00202 { 00203 return ret; 00204 } 00205 00206 dlen -= wlen; 00207 addr_ofst += wlen; 00208 } 00209 00210 return ret; 00211 } 00212 00213
Generated on Wed Jul 13 2022 10:03:02 by
1.7.2