@@ -120,19 +120,37 @@ static msg_t eeprom_read(const I2CEepromFileConfig *eepcfg,
120120 uint32_t offset , uint8_t * data , size_t len ) {
121121
122122 msg_t status = MSG_RESET ;
123- systime_t tmo = calc_timeout (eepcfg -> i2cp , 2 , len );
123+ /* Determine addressing mode based on device size. Devices up to 16 Kbit (2 KB)
124+ use a 1-byte word address with block select bits in the I2C address. Larger
125+ devices use 2-byte word addresses. */
126+ const bool one_byte_addr = (eepcfg -> size <= 2048U );
127+ const uint32_t eff_off = offset + eepcfg -> barrier_low ;
128+ const size_t addr_bytes = one_byte_addr ? 1U : 2U ;
129+ systime_t tmo = calc_timeout (eepcfg -> i2cp , addr_bytes , len );
124130
125131 osalDbgAssert (((len <= eepcfg -> size ) && ((offset + len ) <= eepcfg -> size )),
126132 "out of device bounds" );
127133
128- eeprom_split_addr (eepcfg -> write_buf , (offset + eepcfg -> barrier_low ));
134+ /* Prepare address buffer */
135+ if (one_byte_addr ) {
136+ eepcfg -> write_buf [0 ] = (uint8_t )(eff_off & 0xFFU );
137+ } else {
138+ eeprom_split_addr (eepcfg -> write_buf , eff_off );
139+ }
140+
141+ /* Compute 7-bit I2C address, adding block select bits for small-density parts. */
142+ i2caddr_t i2c_addr = eepcfg -> addr ;
143+ if (one_byte_addr ) {
144+ /* Up to 8 blocks (24C16) use bits [10:8]; for 24C08 only [9:8] are used. */
145+ i2c_addr = (i2caddr_t )(eepcfg -> addr | ((eff_off >> 8U ) & 0x07U ));
146+ }
129147
130148#if I2C_USE_MUTUAL_EXCLUSION
131149 i2cAcquireBus (eepcfg -> i2cp );
132150#endif
133151
134- status = i2cMasterTransmitTimeout (eepcfg -> i2cp , eepcfg -> addr ,
135- eepcfg -> write_buf , 2 , data , len , tmo );
152+ status = i2cMasterTransmitTimeout (eepcfg -> i2cp , i2c_addr ,
153+ eepcfg -> write_buf , addr_bytes , data , len , tmo );
136154
137155#if I2C_USE_MUTUAL_EXCLUSION
138156 i2cReleaseBus (eepcfg -> i2cp );
@@ -154,7 +172,10 @@ static msg_t eeprom_read(const I2CEepromFileConfig *eepcfg,
154172static msg_t eeprom_write (const I2CEepromFileConfig * eepcfg , uint32_t offset ,
155173 const uint8_t * data , size_t len ) {
156174 msg_t status = MSG_RESET ;
157- systime_t tmo = calc_timeout (eepcfg -> i2cp , (len + 2 ), 0 );
175+ const bool one_byte_addr = (eepcfg -> size <= 2048U );
176+ const uint32_t eff_off = offset + eepcfg -> barrier_low ;
177+ const size_t addr_bytes = one_byte_addr ? 1U : 2U ;
178+ systime_t tmo = calc_timeout (eepcfg -> i2cp , (len + addr_bytes ), 0 );
158179
159180 osalDbgAssert (((len <= eepcfg -> size ) && ((offset + len ) <= eepcfg -> size )),
160181 "out of device bounds" );
@@ -163,16 +184,26 @@ static msg_t eeprom_write(const I2CEepromFileConfig *eepcfg, uint32_t offset,
163184 "data can not be fitted in single page" );
164185
165186 /* write address bytes */
166- eeprom_split_addr (eepcfg -> write_buf , (offset + eepcfg -> barrier_low ));
187+ if (one_byte_addr ) {
188+ eepcfg -> write_buf [0 ] = (uint8_t )(eff_off & 0xFFU );
189+ } else {
190+ eeprom_split_addr (eepcfg -> write_buf , eff_off );
191+ }
167192 /* write data bytes */
168- memcpy (& (eepcfg -> write_buf [2 ]), data , len );
193+ memcpy (& (eepcfg -> write_buf [addr_bytes ]), data , len );
194+
195+ /* Compute 7-bit I2C address, adding block select bits for small-density parts. */
196+ i2caddr_t i2c_addr = eepcfg -> addr ;
197+ if (one_byte_addr ) {
198+ i2c_addr = (i2caddr_t )(eepcfg -> addr | ((eff_off >> 8U ) & 0x07U ));
199+ }
169200
170201#if I2C_USE_MUTUAL_EXCLUSION
171202 i2cAcquireBus (eepcfg -> i2cp );
172203#endif
173204
174- status = i2cMasterTransmitTimeout (eepcfg -> i2cp , eepcfg -> addr ,
175- eepcfg -> write_buf , (len + 2 ), NULL , 0 , tmo );
205+ status = i2cMasterTransmitTimeout (eepcfg -> i2cp , i2c_addr ,
206+ eepcfg -> write_buf , (len + addr_bytes ), NULL , 0 , tmo );
176207
177208#if I2C_USE_MUTUAL_EXCLUSION
178209 i2cReleaseBus (eepcfg -> i2cp );
@@ -228,6 +259,7 @@ static size_t write(void *ip, const uint8_t *bp, size_t n) {
228259 uint16_t pagesize ;
229260 uint32_t firstpage ;
230261 uint32_t lastpage ;
262+ bool one_byte_addr ;
231263
232264 osalDbgCheck ((ip != NULL ) && (((EepromFileStream * )ip )-> vmt != NULL ));
233265
@@ -239,6 +271,7 @@ static size_t write(void *ip, const uint8_t *bp, size_t n) {
239271 return 0 ;
240272
241273 pagesize = ((EepromFileStream * )ip )-> cfg -> pagesize ;
274+ one_byte_addr = (((EepromFileStream * )ip )-> cfg -> size <= 2048U );
242275 firstpage = (((EepromFileStream * )ip )-> cfg -> barrier_low +
243276 eepfs_getposition (ip , NULL )) / pagesize ;
244277 lastpage = (((EepromFileStream * )ip )-> cfg -> barrier_low +
@@ -247,6 +280,13 @@ static size_t write(void *ip, const uint8_t *bp, size_t n) {
247280 /* data fits in single page */
248281 if (firstpage == lastpage ) {
249282 len = n ;
283+ if (one_byte_addr ) {
284+ /* Do not cross 256-byte block address boundary in one transaction */
285+ uint32_t pos = eepfs_getposition (ip , NULL );
286+ uint32_t eff_pos = ((EepromFileStream * )ip )-> cfg -> barrier_low + pos ;
287+ size_t block_rem = 256U - (eff_pos & 0xFFU );
288+ if (len > block_rem ) len = block_rem ;
289+ }
250290 __fitted_write (ip , bp , len , & written );
251291 return written ;
252292 }
@@ -255,13 +295,25 @@ static size_t write(void *ip, const uint8_t *bp, size_t n) {
255295 /* write first piece of data to first page boundary */
256296 len = ((firstpage + 1 ) * pagesize ) - eepfs_getposition (ip , NULL );
257297 len -= ((EepromFileStream * )ip )-> cfg -> barrier_low ;
298+ if (one_byte_addr ) {
299+ uint32_t pos = eepfs_getposition (ip , NULL );
300+ uint32_t eff_pos = ((EepromFileStream * )ip )-> cfg -> barrier_low + pos ;
301+ size_t block_rem = 256U - (eff_pos & 0xFFU );
302+ if (len > block_rem ) len = block_rem ;
303+ }
258304 if (__fitted_write (ip , bp , len , & written ) != MSG_OK )
259305 return written ;
260306 bp += len ;
261307
262308 /* now write page sized blocks (zero or more) */
263309 while ((n - written ) > pagesize ) {
264310 len = pagesize ;
311+ if (one_byte_addr ) {
312+ uint32_t pos = eepfs_getposition (ip , NULL );
313+ uint32_t eff_pos = ((EepromFileStream * )ip )-> cfg -> barrier_low + pos ;
314+ size_t block_rem = 256U - (eff_pos & 0xFFU );
315+ if (len > block_rem ) len = block_rem ;
316+ }
265317 if (__fitted_write (ip , bp , len , & written ) != MSG_OK )
266318 return written ;
267319 bp += len ;
@@ -272,6 +324,12 @@ static size_t write(void *ip, const uint8_t *bp, size_t n) {
272324 if (len == 0 )
273325 return written ;
274326 else {
327+ if (one_byte_addr ) {
328+ uint32_t pos = eepfs_getposition (ip , NULL );
329+ uint32_t eff_pos = ((EepromFileStream * )ip )-> cfg -> barrier_low + pos ;
330+ size_t block_rem = 256U - (eff_pos & 0xFFU );
331+ if (len > block_rem ) len = block_rem ;
332+ }
275333 __fitted_write (ip , bp , len , & written );
276334 }
277335 }
@@ -324,15 +382,28 @@ static size_t read(void *ip, uint8_t *bp, size_t n) {
324382 }
325383#endif /* defined(STM32F1XX_I2C) */
326384
327- /* call low level function */
328- status = eeprom_read (((I2CEepromFileStream * )ip )-> cfg ,
329- eepfs_getposition (ip , NULL ), bp , n );
330- if (status != MSG_OK )
331- return 0 ;
332- else {
333- eepfs_lseek (ip , (eepfs_getposition (ip , NULL ) + n ));
334- return n ;
385+ /* Perform reads, splitting at 256-byte block boundaries for small devices. */
386+ size_t read_total = 0 ;
387+ const bool one_byte_addr = (((I2CEepromFileStream * )ip )-> cfg -> size <= 2048U );
388+ while (n > 0 ) {
389+ size_t chunk = n ;
390+ if (one_byte_addr ) {
391+ uint32_t pos = eepfs_getposition (ip , NULL );
392+ uint32_t eff_pos = ((I2CEepromFileStream * )ip )-> cfg -> barrier_low + pos ;
393+ size_t block_rem = 256U - (eff_pos & 0xFFU );
394+ if (chunk > block_rem ) chunk = block_rem ;
395+ }
396+ status = eeprom_read (((I2CEepromFileStream * )ip )-> cfg ,
397+ eepfs_getposition (ip , NULL ), bp , chunk );
398+ if (status != MSG_OK ) {
399+ return read_total ; /* return bytes read so far */
400+ }
401+ eepfs_lseek (ip , (eepfs_getposition (ip , NULL ) + chunk ));
402+ bp += chunk ;
403+ n -= chunk ;
404+ read_total += chunk ;
335405 }
406+ return read_total ;
336407}
337408
338409static const struct EepromFileStreamVMT vmt = {
0 commit comments