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.
Diff: M24512.cpp
- Revision:
- 0:11e6262c2981
- Child:
- 3:b6d7714cd171
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/M24512.cpp Fri Jun 07 14:45:45 2019 +0100
@@ -0,0 +1,196 @@
+/* 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 = 20000;
+
+ // 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;
+
+ // 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];
+ }
+
+ ret = _i2c.write(_addr | M24512_COMMAND_WRITE, (const char*)&cmd, size + 2 );
+ 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;
+}
+
+