#include #include #include #include #include #include #define DEVICE(x) ((x >> 16)&0x07) #define PAGE(x) (x >> 7) #define PAGEBASE(x) (x & 0xFF80) #define PAGEOFFSET(x) (x & 0x007F) struct i2cee_state { uint16_t offset; uint16_t len; uint8_t *p; }; static int i2cee_save_cb(void *p,int n,int ch){ switch (n){ case 0: return (((struct i2cee_state*)p)->offset >> 8) & 0xFF; case 1: return (((struct i2cee_state*)p)->offset) & 0xFF; default: if ( (n-2) < ((struct i2cee_state*)p)->len ) return ((struct i2cee_state*)p)->p[n-2]; return -1; }; }; int i2cee_save(int32_t base,void *p,int16_t len){ uint8_t *b = p; uint16_t ilen,slen; int32_t offset = base; struct i2cee_state state; uint8_t n; int r; MUTEXED(&i2c.mutex); slen = 0; while (len){ if (!(i2cee.emask & (1< len) { ilen = len; }; state.offset = offset; state.len = ilen; state.p = b; r = i2c_transfer_ex( 0xA0 + (DEVICE(offset) << 1), i2cee_save_cb, &state); noassert(r); if ((r >= 0) && (r != (ilen+2))){ return -ESHORT; }; for (n=0;n<10;n++){ r = i2c_transfer( 0xA0 + (DEVICE(offset) << 1), (void*)&offset, 2); if (r >= 0) { break; } else if (r == -EFAIL) { wait_ms(1); continue; } else { noassert(r); return r; }; }; assert(r); len -= ilen; b += ilen; offset += ilen; slen += ilen; }; return slen; };