@@ -56,18 +56,25 @@ uint32_t ExternalEEPROM::length()
56
56
}
57
57
58
58
// Returns true if device is detected
59
- bool ExternalEEPROM::isConnected ()
59
+ bool ExternalEEPROM::isConnected (uint8_t i2cAddress )
60
60
{
61
- settings.i2cPort ->beginTransmission ((uint8_t )settings.deviceAddress );
61
+ if (i2cAddress == 255 )
62
+ i2cAddress = settings.deviceAddress ; // We can't set the default to settings.deviceAddress so we use 255 instead
63
+
64
+ settings.i2cPort ->beginTransmission ((uint8_t )i2cAddress);
62
65
if (settings.i2cPort ->endTransmission () == 0 )
63
66
return (true );
64
67
return (false );
65
68
}
66
69
67
70
// Returns true if device is not answering (currently writing)
68
- bool ExternalEEPROM::isBusy ()
71
+ // Caller can pass in an i2c address. This is helpful for larger EEPROMs that have two addresses (see block bit 2).
72
+ bool ExternalEEPROM::isBusy (uint8_t i2cAddress)
69
73
{
70
- if (isConnected ())
74
+ if (i2cAddress == 255 )
75
+ i2cAddress = settings.deviceAddress ; // We can't set the default to settings.deviceAddress so we use 255 instead
76
+
77
+ if (isConnected (i2cAddress))
71
78
return (false );
72
79
return (true );
73
80
}
@@ -108,7 +115,14 @@ void ExternalEEPROM::disablePollForWriteComplete()
108
115
{
109
116
settings.pollForWriteComplete = false ;
110
117
}
111
-
118
+ void ExternalEEPROM::setI2CBufferSize (uint16_t numberOfBytes)
119
+ {
120
+ settings.i2cBufferSize = numberOfBytes;
121
+ }
122
+ uint16_t ExternalEEPROM::getI2CBufferSize ()
123
+ {
124
+ return settings.i2cBufferSize ;
125
+ }
112
126
// Read a byte from a given location
113
127
uint8_t ExternalEEPROM::read (uint32_t eepromLocation)
114
128
{
@@ -118,25 +132,33 @@ uint8_t ExternalEEPROM::read(uint32_t eepromLocation)
118
132
}
119
133
120
134
// Bulk read from EEPROM
121
- // Handles breaking up read amt into 32 byte chunks
135
+ // Handles breaking up read amt into 32 byte chunks (can override with serI2CBufferSize)
122
136
// Handles a read that straddles the 512kbit barrier
123
137
void ExternalEEPROM::read (uint32_t eepromLocation, uint8_t *buff, uint16_t bufferSize)
124
138
{
139
+ // See if EEPROM is available or still writing a previous request
140
+ uint8_t i2cAddress = settings.deviceAddress ;
141
+ while (isBusy (i2cAddress) == true ) // Poll device
142
+ delayMicroseconds (100 ); // This shortens the amount of time waiting between writes but hammers the I2C bus
143
+
125
144
uint16_t received = 0 ;
126
145
while (received < bufferSize)
127
146
{
128
147
// Limit the amount to write to a page size
129
148
int amtToRead = bufferSize - received;
130
- if (amtToRead > 32 ) // Arduino I2C buffer size limit
131
- amtToRead = 32 ;
149
+ if (amtToRead > settings. i2cBufferSize ) // Arduino I2C buffer size limit
150
+ amtToRead = settings. i2cBufferSize ;
132
151
133
152
// Check if we are dealing with large (>512kbit) EEPROMs
134
153
uint8_t i2cAddress = settings.deviceAddress ;
135
154
if (settings.memorySize_bytes > 0xFFFF )
136
155
{
137
156
// Figure out if we are going to cross the barrier with this read
138
- if (0xFFFF - (eepromLocation + received) < amtToRead) // 0xFFFF - 0xFFFA < 32
139
- amtToRead = 0xFFFF - (eepromLocation + received); // Limit the read amt to go right up to edge of barrier
157
+ if (eepromLocation + received < 0xFFFF )
158
+ {
159
+ if (0xFFFF - (eepromLocation + received) < amtToRead) // 0xFFFF - 0xFFFA < 32
160
+ amtToRead = 0xFFFF - (eepromLocation + received); // Limit the read amt to go right up to edge of barrier
161
+ }
140
162
141
163
// Figure out if we are accessing the lower half or the upper half
142
164
if (eepromLocation + received > 0xFFFF )
@@ -165,15 +187,22 @@ void ExternalEEPROM::write(uint32_t eepromLocation, uint8_t dataToWrite)
165
187
}
166
188
167
189
// Write large bulk amounts
190
+ // Limits writes to the I2C buffer size (default is 32 bytes)
168
191
void ExternalEEPROM::write (uint32_t eepromLocation, const uint8_t *dataToWrite, uint16_t bufferSize)
169
192
{
170
193
// Error check
171
194
if (eepromLocation + bufferSize >= settings.memorySize_bytes )
172
195
bufferSize = settings.memorySize_bytes - eepromLocation;
173
196
174
197
uint16_t maxWriteSize = settings.pageSize_bytes ;
175
- if (maxWriteSize > 30 )
176
- maxWriteSize = 30 ; // Arduino has 32 byte limit. We loose two to the EEPROM address
198
+ if (maxWriteSize > settings.i2cBufferSize - 2 )
199
+ maxWriteSize = settings.i2cBufferSize - 2 ; // Arduino has 32 byte limit. We loose two to the EEPROM address
200
+
201
+ uint8_t i2cAddress = settings.deviceAddress ;
202
+
203
+ // See if EEPROM is available or still writing a previous request
204
+ while (isBusy (i2cAddress) == true ) // Poll device
205
+ delayMicroseconds (100 ); // This shortens the amount of time waiting between writes but hammers the I2C bus
177
206
178
207
// Break the buffer into page sized chunks
179
208
uint16_t recorded = 0 ;
@@ -194,12 +223,13 @@ void ExternalEEPROM::write(uint32_t eepromLocation, const uint8_t *dataToWrite,
194
223
}
195
224
196
225
// Check if we are dealing with large (>512kbit) EEPROMs
197
- uint8_t i2cAddress = settings.deviceAddress ;
198
226
if (settings.memorySize_bytes > 0xFFFF )
199
227
{
200
228
// Figure out if we are accessing the lower half or the upper half
201
229
if (eepromLocation + recorded > 0xFFFF )
230
+ {
202
231
i2cAddress |= 0b100 ; // Set the block bit to 1
232
+ }
203
233
}
204
234
settings.i2cPort ->beginTransmission (i2cAddress);
205
235
@@ -213,13 +243,7 @@ void ExternalEEPROM::write(uint32_t eepromLocation, const uint8_t *dataToWrite,
213
243
214
244
recorded += amtToWrite;
215
245
216
- if (settings.pollForWriteComplete == true )
217
- {
218
- while (isBusy () == true ) // Poll device
219
- delayMicroseconds (100 ); // This shortens the amount of time waiting between writes but hammers the I2C bus
220
- // delay(1);
221
- }
222
- else
246
+ if (settings.pollForWriteComplete == false )
223
247
delay (settings.pageWriteTime_ms ); // Delay the amount of time to record a page
224
248
}
225
249
}
0 commit comments