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
- Committer:
- martyn gilbertson
- Date:
- 2019-10-16
- Revision:
- 4:336ef5db5e78
- Parent:
- 3:b6d7714cd171
- Child:
- 5:431b0b0c00d3
File content as of revision 4:336ef5db5e78:
/* ISL MBED Libraries
* Copyright (C) 2019 - Invisible Systems Ltd. All Rights Reserved.
*/
#include "M24512.h"
/** I2C Frequency
Roughly calculate time to write a full page based on freq
((1 / 500000) * (130*9) * 1000) + 5
*/
#define M24512_DEFAULT_FREQUENCY (uint32_t)500000
/** Read command | on device address
*/
#define M24512_COMMAND_READ (uint8_t)0
/** Write command | on device address
*/
#define M24512_COMMAND_WRITE (uint8_t)1
/** Device Page Size
*/
#define M24512_EEPROM_PAGE_SIZE (uint16_t)128
/** Device Page Count
*/
#define M24512_EEPROM_PAGES (uint16_t)512
M24512::M24512(PinName sda, PinName scl, uint8_t address) : _i2c(sda,scl), _addr(address)
{
frequency(M24512_DEFAULT_FREQUENCY);
}
M24512::~M24512()
{
}
void M24512::frequency(uint32_t hz)
{
_i2c.frequency(hz);
}
uint32_t M24512::get_total_memory() const
{
return (get_page_size() * get_page_count()) / 1024 ;
}
uint16_t M24512::get_page_size() const
{
return M24512_EEPROM_PAGE_SIZE;
}
uint16_t M24512::get_page_count() const
{
return M24512_EEPROM_PAGES;
}
M24512::status_t M24512::ready()
{
int8_t ack;
char cmd[2] = {0,0};
int timeout = 20;
// Wait for end of write
do{
// read from addr 0 with a length of 0 just to check the i2c state
ack = _i2c.write( _addr | M24512_COMMAND_READ, cmd, 0 );
if (timeout-- == 0)
{
return (ack == 0) ? M24512::M24512_SUCCESS : M24512::M24512_RDY_TIMEOUT;
}
}while(ack != 0);
return (ack == 0) ? M24512::M24512_SUCCESS : M24512::M24512_I2C_ERROR;
}
M24512::status_t M24512::read(uint16_t addr, char* data, uint16_t size)
{
int ret = 0;
char cmd[2];
// check for overflow
if ( ( addr + size) > (get_page_size() * get_page_count()) )
{
return M24512::M24512_MEM_OVERFLOW;
}
cmd[0] = addr >> 8;
cmd[1] = addr;
// set address to read from
ret = _i2c.write(_addr | M24512_COMMAND_READ, (const char*)&cmd, 2, true );
if (ret != 0)
{
return M24512::M24512_I2C_ERROR;
}
// read data into buffer
ret = _i2c.read(_addr | M24512_COMMAND_READ, (char*)data, size );
if (ret != 0)
{
return M24512::M24512_I2C_ERROR;
}
return ready();
}
M24512::status_t M24512::write_page(uint16_t addr, const char* data, uint16_t size)
{
/** TODO - Change this to dynamic incase page size increase! */
char cmd[M24512_EEPROM_PAGE_SIZE];
int ret = 0;
int8_t retry = 3;
// check for overflow
if ( ( addr + size) > (get_page_size() * get_page_count()) )
{
return M24512::M24512_MEM_OVERFLOW;
}
// check for page boundary
/** TODO - Change this to get_page_size incase change in size */
if (size > M24512_EEPROM_PAGE_SIZE)
{
return M24512::M24512_MEM_OVERFLOW;
}
cmd[0] = addr >> 8;
cmd[1] = addr;
for (uint8_t i = 0; i < size ; i++)
{
cmd[2+i] = data[i];
}
while (retry--)
{
ret = _i2c.write(_addr | M24512_COMMAND_WRITE, (const char*)&cmd, size + 2 );
if (ret != 0)
{
osDelay(100);
}else{
break;
}
}
if (ret != 0)
{
return M24512::M24512_I2C_ERROR;
}
return ready();
}
M24512::status_t M24512::write(uint16_t addr, const char* data, uint16_t size)
{
M24512::status_t ret = M24512_SUCCESS;
int16_t wlen = 0; // write length
int16_t dlen = size; // data length remaining
int16_t addr_ofst = 0; // address to write
while (dlen > 0)
{
wlen = ((dlen > get_page_size()) ? get_page_size() : dlen);
// if addr is not at the start of a page then write bytes until we hit the boundary
if ( addr_ofst == 0 && (addr % get_page_size()) != 0 )
{
wlen = get_page_size() - (addr % get_page_size());
// check we have enough data to hit end of page if not just write the entire length
if (size < wlen)
{
wlen = size;
}
}
//printf("Write: Addr:%d Write: %d Remain: %d next: %d\n", addr + addr_ofst, wlen, dlen - wlen , addr_ofst + wlen);
// write in blocks of %page_size%
ret = write_page( addr + addr_ofst, data + addr_ofst, wlen );
if ( ret != M24512::M24512_SUCCESS )
{
return ret;
}
dlen -= wlen;
addr_ofst += wlen;
}
return ret;
}