Skip to content

Commit bd3a74a

Browse files
committed
drivers/at24cxxx: implement read_page
1 parent ea300c3 commit bd3a74a

3 files changed

Lines changed: 67 additions & 5 deletions

File tree

drivers/at24cxxx/at24cxxx.c

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
#endif
7070

7171
static
72-
int _read(const at24cxxx_t *dev, uint32_t pos, void *data, size_t len)
72+
int _read_page(const at24cxxx_t *dev, uint32_t pos, void *data, size_t len)
7373
{
7474
int check;
7575
uint8_t polls = DEV_MAX_POLLS;
@@ -97,7 +97,31 @@ int _read(const at24cxxx_t *dev, uint32_t pos, void *data, size_t len)
9797
}
9898
xtimer_usleep(AT24CXXX_POLL_DELAY_US);
9999
}
100+
100101
DEBUG("[at24cxxx] i2c_read_regs(): %d; polls: %d\n", check, polls);
102+
103+
return check;
104+
}
105+
106+
static
107+
int _read(const at24cxxx_t *dev, uint32_t pos, void *data, size_t len)
108+
{
109+
int check = 0;
110+
111+
while (len) {
112+
size_t clen = MIN(len, DEV_PAGE_SIZE - MOD_POW2(pos, DEV_PAGE_SIZE));
113+
114+
check = _read_page(dev, pos, data, clen);
115+
116+
if (!check) {
117+
len -= clen;
118+
pos += clen;
119+
data += clen;
120+
}
121+
else {
122+
break;
123+
}
124+
}
101125
return check;
102126
}
103127

@@ -107,25 +131,24 @@ int _write_page(const at24cxxx_t *dev, uint32_t pos, const void *data, size_t le
107131
int check;
108132
uint8_t polls = DEV_MAX_POLLS;
109133
uint8_t dev_addr;
110-
uint16_t _pos;
111134
uint8_t flags = 0;
112135

113136
if (DEV_EEPROM_SIZE > 2048) {
114137
/* 2 bytes word address length if more than 11 bits are
115138
used for addressing */
116139
/* append page address bits to device address (if any) */
117140
dev_addr = (DEV_I2C_ADDR | ((pos & 0xFF0000) >> 16));
118-
_pos = (pos & 0xFFFF);
141+
pos &= 0xFFFF;
119142
flags = I2C_REG16;
120143
}
121144
else {
122145
/* append page address bits to device address (if any) */
123146
dev_addr = (DEV_I2C_ADDR | ((pos & 0xFF00) >> 8));
124-
_pos = pos & 0xFF;
147+
pos &= 0xFF;
125148
}
126149

127150
while (-ENXIO == (check = i2c_write_regs(DEV_I2C_BUS, dev_addr,
128-
_pos, data, len, flags))) {
151+
pos, data, len, flags))) {
129152
if (--polls == 0) {
130153
break;
131154
}
@@ -225,6 +248,23 @@ int at24cxxx_read(const at24cxxx_t *dev, uint32_t pos, void *data,
225248
return check;
226249
}
227250

251+
int at24cxxx_read_page(const at24cxxx_t *dev, uint32_t page, uint32_t offset, void *data, size_t len)
252+
{
253+
int check;
254+
255+
assert(offset < DEV_PAGE_SIZE);
256+
257+
/* read no more than to the end of the current page to prevent wrap-around */
258+
size_t remaining = DEV_PAGE_SIZE - offset;
259+
len = MIN(len, remaining);
260+
261+
i2c_acquire(DEV_I2C_BUS);
262+
check = _read_page(dev, page * DEV_PAGE_SIZE + offset, data, len);
263+
i2c_release(DEV_I2C_BUS);
264+
265+
return check ? check : (int) len;
266+
}
267+
228268
int at24cxxx_write_byte(const at24cxxx_t *dev, uint32_t pos, uint8_t data)
229269
{
230270
if (pos >= DEV_EEPROM_SIZE) {

drivers/at24cxxx/mtd/mtd.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ static int _mtd_at24cxxx_read(mtd_dev_t *mtd, void *dest, uint32_t addr,
5151
return at24cxxx_read(DEV(mtd), addr, dest, size) == AT24CXXX_OK ? 0 : -EIO;
5252
}
5353

54+
static int _mtd_at24cxxx_read_page(mtd_dev_t *mtd, void *dest, uint32_t page, uint32_t offset, uint32_t size)
55+
{
56+
return at24cxxx_read_page(DEV(mtd), page, offset, dest, size);
57+
}
58+
5459
static int _mtd_at24cxxx_write(mtd_dev_t *mtd, const void *src, uint32_t addr,
5560
uint32_t size)
5661
{
@@ -78,6 +83,7 @@ static int _mtd_at24cxxx_power(mtd_dev_t *mtd, enum mtd_power_state power)
7883
const mtd_desc_t mtd_at24cxxx_driver = {
7984
.init = _mtd_at24cxxx_init,
8085
.read = _mtd_at24cxxx_read,
86+
.read_page = _mtd_at24cxxx_read_page,
8187
.write = _mtd_at24cxxx_write,
8288
.write_page = mtd_at24cxxx_write_page,
8389
.erase = _mtd_at24cxxx_erase,

drivers/include/at24cxxx.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,22 @@ int at24cxxx_read_byte(const at24cxxx_t *dev, uint32_t pos, void *dest);
9999
int at24cxxx_read(const at24cxxx_t *dev, uint32_t pos, void *data,
100100
size_t len);
101101

102+
/**
103+
* @brief Sequentially read @p len bytes from a given @p page.
104+
* The function will read up to the page boundary and then return
105+
* the number of bytes read up to that.
106+
*
107+
* @param[in] dev AT24CXXX device handle
108+
* @param[in] page page of EEPROM memory
109+
* @param[in] offset offset from the start of the page, must be < page size
110+
* @param[in] data read buffer
111+
* @param[in] len requested length to be read
112+
*
113+
* @return number of bytes read on success
114+
* @return error on failure
115+
*/
116+
int at24cxxx_read_page(const at24cxxx_t *dev, uint32_t page, uint32_t offset, void *data, size_t len);
117+
102118
/**
103119
* @brief Write a byte at a given position @p pos
104120
*

0 commit comments

Comments
 (0)