@@ -62,99 +62,92 @@ int I2CEEBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
62
62
// Check the address and size fit onto the chip.
63
63
MBED_ASSERT (is_valid_read (addr, size));
64
64
65
- auto *charBuffer = reinterpret_cast <char *>(buffer);
65
+ auto *pBuffer = reinterpret_cast <char *>(buffer);
66
+
67
+ while (size > 0 ) {
68
+ uint32_t off = addr % _block;
69
+ uint32_t chunk = (off + size < _block) ? size : (_block - off);
66
70
67
- auto const handler = [&](const bd_addr_t &pagedStart, const bd_size_t &pagedLength, const uint8_t &pagedDeviceAddress) -> int {
68
71
_i2c->start ();
69
72
70
- if (1 != _i2c->write (pagedDeviceAddress))
71
- {
73
+ if (1 != _i2c->write (get_paged_device_address (addr))) {
72
74
return BD_ERROR_DEVICE_ERROR;
73
75
}
74
76
75
- if (!_address_is_eight_bit && 1 != _i2c->write ((char )(pagedStart >> 8u )))
76
- {
77
+ if (!_address_is_eight_bit && 1 != _i2c->write ((char )(addr >> 8u ))) {
77
78
return BD_ERROR_DEVICE_ERROR;
78
79
}
79
80
80
- if (1 != _i2c->write ((char )(pagedStart & 0xffu )))
81
- {
81
+ if (1 != _i2c->write ((char )(addr & 0xffu ))) {
82
82
return BD_ERROR_DEVICE_ERROR;
83
83
}
84
84
85
85
_i2c->stop ();
86
86
87
87
auto err = _sync ();
88
- if (err)
89
- {
88
+
89
+ if (err) {
90
90
return err;
91
91
}
92
92
93
- if (0 != _i2c->read (_i2c_addr, charBuffer, pagedLength))
94
- {
93
+ if (0 != _i2c->read (_i2c_addr, pBuffer, chunk)) {
95
94
return BD_ERROR_DEVICE_ERROR;
96
95
}
97
96
98
- charBuffer += size ;
99
-
100
- return BD_ERROR_OK ;
101
- };
97
+ addr += chunk ;
98
+ size -= chunk;
99
+ pBuffer += chunk ;
100
+ }
102
101
103
- return do_paged (addr, size, handler) ;
102
+ return BD_ERROR_OK ;
104
103
}
105
104
106
105
int I2CEEBlockDevice::program (const void *buffer, bd_addr_t addr, bd_size_t size)
107
106
{
108
107
// Check the addr and size fit onto the chip.
109
108
MBED_ASSERT (is_valid_program (addr, size));
110
109
111
- auto const *charBuffer = reinterpret_cast <char const *>(buffer);
110
+ auto const *pBuffer = reinterpret_cast <char const *>(buffer);
112
111
113
- auto const handler = [&](const bd_addr_t &pagedStart, const bd_size_t &pagedLength, const uint8_t &pagedDeviceAddress) -> int {
114
- // While we have some more data to write.
115
- while (size > 0 )
116
- {
117
- uint32_t off = addr % _block;
118
- uint32_t chunk = (off + size < _block) ? size : (_block - off);
112
+ // While we have some more data to write.
113
+ while (size > 0 ) {
114
+ uint32_t off = addr % _block;
115
+ uint32_t chunk = (off + size < _block) ? size : (_block - off);
119
116
120
- _i2c->start ();
117
+ _i2c->start ();
121
118
122
- if (1 != _i2c->write (pagedDeviceAddress )) {
123
- return BD_ERROR_DEVICE_ERROR;
124
- }
119
+ if (1 != _i2c->write (get_paged_device_address (addr) )) {
120
+ return BD_ERROR_DEVICE_ERROR;
121
+ }
125
122
126
- if (!_address_is_eight_bit && 1 != _i2c->write ((char )(pagedStart >> 8u ))) {
127
- return BD_ERROR_DEVICE_ERROR;
128
- }
123
+ if (!_address_is_eight_bit && 1 != _i2c->write ((char )(addr >> 8u ))) {
124
+ return BD_ERROR_DEVICE_ERROR;
125
+ }
129
126
130
- if (1 != _i2c->write ((char )(addr & 0xffu ))) {
131
- return BD_ERROR_DEVICE_ERROR;
132
- }
127
+ if (1 != _i2c->write ((char )(addr & 0xffu ))) {
128
+ return BD_ERROR_DEVICE_ERROR;
129
+ }
133
130
134
- for (unsigned i = 0 ; i < chunk; i++) {
135
- if (1 != _i2c->write (charBuffer[i])) {
136
- return BD_ERROR_DEVICE_ERROR;
137
- }
131
+ for (unsigned i = 0 ; i < chunk; i++) {
132
+ if (1 != _i2c->write (pBuffer[i])) {
133
+ return BD_ERROR_DEVICE_ERROR;
138
134
}
135
+ }
139
136
140
- _i2c->stop ();
141
-
142
- int err = _sync ();
137
+ _i2c->stop ();
143
138
144
- if (err) {
145
- return err;
146
- }
139
+ int err = _sync ();
147
140
148
- addr += chunk;
149
- size -= chunk;
150
- charBuffer += chunk;
141
+ if (err) {
142
+ return err;
151
143
}
152
144
153
- return BD_ERROR_OK;
154
- };
145
+ addr += chunk;
146
+ size -= chunk;
147
+ pBuffer += chunk;
148
+ }
155
149
156
- auto const originalSize = size;
157
- return do_paged (addr, originalSize, handler);
150
+ return BD_ERROR_OK;
158
151
}
159
152
160
153
int I2CEEBlockDevice::erase (bd_addr_t addr, bd_size_t size)
@@ -204,68 +197,13 @@ const char *I2CEEBlockDevice::get_type() const
204
197
return " I2CEE" ;
205
198
}
206
199
207
- int I2CEEBlockDevice::do_paged (const bd_addr_t &startAddress,
208
- const bd_size_t &length,
209
- const paged_handler &handler)
210
- {
211
- // This helper is only used for eight bit mode.
212
- if (!this ->_address_is_eight_bit ) {
213
- return handler (startAddress, length, get_paged_device_address (0 ));
214
- }
215
-
216
- auto currentStartAddress = startAddress;
217
-
218
- auto const pageSize = 256 ;
219
- bd_size_t lengthDone = 0 ;
220
- while (lengthDone != length) {
221
- /* Integer division => Round down */
222
- uint8_t const currentPage = currentStartAddress / pageSize;
223
- bd_addr_t const nextPageBegin = (currentPage + 1 ) * pageSize;
224
- bd_addr_t const currentReadEndAddressExclusive = std::min (nextPageBegin, startAddress + length);
225
- bd_size_t const currentLength = currentReadEndAddressExclusive - currentStartAddress;
226
- bd_addr_t const pagedBegin = currentStartAddress - (currentPage * pageSize);
227
- uint8_t const pagedDeviceAddress = get_paged_device_address (currentPage);
228
-
229
- auto const handlerReturn = handler (pagedBegin, currentLength, pagedDeviceAddress);
230
- if (handlerReturn != BD_ERROR_OK) {
231
- return handlerReturn;
232
- }
233
-
234
- currentStartAddress = currentReadEndAddressExclusive;
235
- lengthDone += currentLength;
236
- }
237
-
238
- return BD_ERROR_OK;
239
- }
240
-
241
- uint8_t I2CEEBlockDevice::get_paged_device_address (const uint8_t &page)
200
+ uint8_t I2CEEBlockDevice::get_paged_device_address (const bd_addr_t &address)
242
201
{
243
202
if (!this ->_address_is_eight_bit ) {
244
203
return this ->_i2c_addr ;
245
204
} else {
246
- // This method uses a dynamically created bit mask for the page given.
247
- // This ensures compatibility with all sizes of ICs.
248
- // E. g. the 512K variants have two user address bits and one page bit.
249
- // We don't want to forcefully override the two user address bits.
250
-
251
- // Create a mask to cover all bits required to set page
252
- // i starts at one because the LSB is used for R/W in I2C
253
- uint8_t i = 1 ;
254
- uint8_t addressMask = 0 ;
255
- auto p = page;
256
- while (p != 0u ) {
257
- addressMask |= (1u << i);
258
- p >>= 1u ;
259
- i++;
260
- }
261
-
262
- uint8_t pagedDeviceAddress = this ->_i2c_addr & static_cast <uint8_t >(~addressMask);
263
- // Assert page < 0b111, because we don't have
264
- // more bits for page encoding
265
- // Don't actually write 0b111, this is a nonstandard extension.
266
- MBED_ASSERT (page < 0x7 );
267
- pagedDeviceAddress |= static_cast <uint8_t >(page << 1u );
268
-
269
- return pagedDeviceAddress;
205
+ // Use the three least significant bits of the 2nd byte as the page
206
+ // The page will be bits 2-4 of the user defined addresses.
207
+ return this ->_i2c_addr | ((address & 0x0700u ) >> 7u );
270
208
}
271
- }
209
+ }
0 commit comments