+ while (count && result)
+ {
+ /*
+ * Split write in multiple sequential mode operations that
+ * don't cross page boundaries.
+ */
+ size_t size =
+ MIN(count, (size_t)(EEPROM_BLKSIZE - (addr & (EEPROM_BLKSIZE - 1))));
+
+ #if CONFIG_EEPROM_TYPE == EEPROM_24XX16
+ /*
+ * The 24LC16 uses the slave address as a 3-bit
+ * block address.
+ */
+ uint8_t blk_addr = (uint8_t)((addr >> 8) & 0x07);
+ uint8_t blk_offs = (uint8_t)addr;
+
+ result =
+ twi_start_w(blk_addr)
+ && twi_send(&blk_offs, sizeof blk_offs)
+ && twi_send(buf, size);
+
+ #elif CONFIG_EEPROM_TYPE == EEPROM_24XX256
+
+ // 24LC256 wants big-endian addresses
+ uint16_t addr_be = cpu_to_be16(addr);
+
+ result =
+ twi_start_w(0)
+ && twi_send((uint8_t *)&addr_be, sizeof addr_be)
+ && twi_send(buf, size);
+
+ #else
+ #error Unknown device type
+ #endif
+
+ twi_stop();
+
+ // DEBUG
+ //kprintf("addr=%d, count=%d, size=%d, *#?=%d\n",
+ // addr, count, size,
+ // (EEPROM_BLKSIZE - (addr & (EEPROM_BLKSIZE - 1)))
+ //);
+
+ /* Update count and addr for next operation */
+ count -= size;
+ addr += size;
+ buf = ((const char *)buf) + size;
+ }