Skip to content

Commit

Permalink
Added handling of >32 bytes in a structure
Browse files Browse the repository at this point in the history
  • Loading branch information
SV-Zanshin committed Sep 6, 2017
1 parent 7a1eb9d commit b571131
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 19 deletions.
3 changes: 2 additions & 1 deletion Examples/ReadWrite/ReadWrite.ino
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
** **
** What sets this library apart is that it will autmatically detect up to 8 memories, in any combination of those **
** listed as supported above, and treats them as one contiguous block of memory. The read() and write() functions **
** also support structures and arrays. **
** also support structures and arrays. Although the internal I2C library has a 32 byte limitation on the buffer **
** size, the library allows for larger structures to be read and written. **
** **
** This program is free software: you can redistribute it and/or modify it under the terms of the GNU General **
** Public License as published by the Free Software Foundation, either version 3 of the License, or (at your **
Expand Down
17 changes: 17 additions & 0 deletions MB85_FRAM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,20 @@ uint8_t MB85_FRAM_Class::getDevice(uint32_t &memAddress,uint32_t &endAddress){//
uint16_t MB85_FRAM_Class::memSize(const uint8_t memNumber) { // Return memory size in bytes //
if(memNumber<=_DeviceCount) return(_I2C[memNumber]*1024); else return 0; // Return appropriate value //
} // of method memSize() //----------------------------------//

/*******************************************************************************************************************
** Method requestI2C() is an internal call used in the read() template to send the 2 byte address and request a **
** number of bytes to be read from that address **
*******************************************************************************************************************/
void MB85_FRAM_Class::requestI2C(const uint8_t device,const uint32_t memAddr, // Address device and request data //
const uint16_t dataSize,const bool endTrans){// //
Wire.beginTransmission(device+MB85_MIN_ADDRESS); // Address the I2C device //
Wire.write(memAddr>>8); // Send MSB register address //
Wire.write((uint8_t)memAddr); // Send LSB address to read //
if (endTrans) { // Read request, so end transmission//
_TransmissionStatus = Wire.endTransmission(); // Close transmission //
Wire.requestFrom(device+MB85_MIN_ADDRESS, dataSize); // Request n-bytes of data //
return Wire.available(); // Return actual bytes read //
} // of if-then endTransmission switch is set // //
return dataSize; // Return the dataSize on write //
} // of internal method requestI2C() //----------------------------------//
37 changes: 19 additions & 18 deletions MB85_FRAM.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
** **
** Vers. Date Developer Comments **
** ====== ========== ============================= ============================================================== **
** 1.0.1b 2017-09-06 https://github.com/SV-Zanshin Allow structures > 32 bytes, optimized memory use **
** 1.0.0b 2017-09-04 https://github.com/SV-Zanshin Prepared for release, final testing **
** 1.0.0a 2017-08-27 https://github.com/SV-Zanshin Started coding **
** **
Expand All @@ -58,6 +59,7 @@
uint8_t begin(); // Start using I2C Communications //
uint32_t totalBytes(); // Return the total memory available//
uint16_t memSize(const uint8_t memNumber); // Return memory size in bytes //

/*************************************************************************************************************
** Declare the read and write methods as template functions. All device I/O is done through these two **
** functions. If multiple memories have been found they are treated as if they were just one large memory, **
Expand All @@ -71,51 +73,48 @@
uint8_t structSize = sizeof(T); // Number of bytes in structure //
uint32_t memAddress = addr%_TotalMemory; // Ensure no value greater than max //
uint32_t endAddress = 0; // Last address on current memory //
uint8_t device = getDevice(memAddress,endAddress); // Compute the actual device to use //
Wire.beginTransmission(device+MB85_MIN_ADDRESS); // Address the I2C device //
Wire.write(memAddress>>8); // Send MSB register address //
Wire.write((uint8_t)memAddress); // Send LSB address to read //
_TransmissionStatus = Wire.endTransmission(); // Close transmission //
Wire.requestFrom(device+MB85_MIN_ADDRESS, sizeof(T)); // Request n-bytes of data //
structSize = Wire.available(); // Use the actual number of bytes //
uint8_t device = getDevice(memAddress,endAddress); // Compute the actual device to use //
uint8_t bufferPos = 0; // Buffer is limited to BUFFER_SIZE //
requestI2C(device,memAddress,sizeof(T),true); // Get bytes from memory //
for (uint8_t i=0;i<structSize;i++) { // loop for each byte to be read //
*bytePtr++ = Wire.read(); // Put byte read to pointer address //
bufferPos++; // Increment the buffer pointer //
if(memAddress++==endAddress) { // If we've reached the end-of-chip //
for(uint8_t j=0;j<MB85_MAX_DEVICES;j++) { // loop to get the next device //
if (device++==MB85_MAX_DEVICES) device = 0; // Increment device or start at 0 //
if (_I2C[device]) { // On a match, address device //
Wire.beginTransmission(device+MB85_MIN_ADDRESS); // Address the I2C device //
Wire.write((uint8_t)0); // Send MSB register address //
Wire.write((uint8_t)0); // Send LSB address to read //
_TransmissionStatus = Wire.endTransmission(); // Close transmission //
Wire.requestFrom(device+MB85_MIN_ADDRESS, sizeof(T)); // Request n-bytes of data //
requestI2C(device,0,sizeof(T),true); // Get bytes from new memory chip //
memAddress = 1; // New memory address //
bufferPos = 0; // read buffer is empty again //
break; // And stop looking for a new memory//
} // of if we've got the next memory // //
} // of for-next loop through each device // //
} // of if-then we've reached the end of the physical memory // //
if(bufferPos==BUFFER_LENGTH) { // If the buffer is full, then we //
bufferPos = 0; // Reset the buffer position //
requestI2C(device,memAddress,sizeof(T),true); // Get bytes from memory //
structSize = Wire.available(); // Use the actual number of bytes //
bufferPos = 0; // Reset the buffer position //
} // if our read buffer is full // //
} // of loop for each byte // // //
return(structSize); // return the number of bytes read //
} // of method read() //----------------------------------//

template<typename T>uint8_t &write(const uint32_t addr,const T &value) {// method to write a structure //
const uint8_t* bytePtr = (const uint8_t*)&value; // Pointer to structure beginning //
uint8_t structSize = sizeof(T); // Number of bytes in structure //
uint32_t memAddress = addr%_TotalMemory; // Ensure no value greater than max //
uint32_t endAddress = 0; // Last address on current memory //
uint8_t device = getDevice(memAddress,endAddress); // Compute the actual device to use //
Wire.beginTransmission(device+MB85_MIN_ADDRESS); // Address the I2C device //
Wire.write(memAddress>>8); // Send MSB register address //
Wire.write((uint8_t)memAddress); // Send LSB address to read //
requestI2C(device,memAddress,sizeof(T),false); // Position memory pointer //
for (uint8_t i=0;i<sizeof(T);i++) { // loop for each byte to be written //
Wire.write(*bytePtr++); // Write current byte to memory //
if(memAddress++==endAddress) { // If we've reached the end-of-chip //
_TransmissionStatus = Wire.endTransmission(); // Close transmission //
for(uint8_t j=0;j<MB85_MAX_DEVICES;j++) { // loop to get the next device //
if (device++==MB85_MAX_DEVICES) device = 0; // Increment device or start at 0 //
if (_I2C[device]) { // On a match, address device //
Wire.beginTransmission(device+MB85_MIN_ADDRESS); // Address the I2C device //
Wire.write((uint8_t)0); // Send MSB register address //
Wire.write((uint8_t)0); // Send LSB address to read //
requestI2C(device,0,sizeof(T),false); // Position memory pointer to begin //
memAddress = 1; // New memory address //
break; // And stop looking for a new memory//
} // of if we've got the next memory // //
Expand All @@ -127,6 +126,8 @@
} // of method write() //----------------------------------//
private: // -------- Private methods ------- //
uint8_t getDevice(uint32_t &memAddress, uint32_t &endAddress); // Compute actual device to use //
void requestI2C(const uint8_t device,const uint32_t memAddress, // Address device and request data //
const uint16_t dataSize, const bool endTrans); // //
uint8_t _DeviceCount = 0; // Number of memories found //
uint32_t _TotalMemory = 0; // Number of bytes in total //
uint8_t _I2C[MB85_MAX_DEVICES] = {0}; // List of device kB capacities //
Expand Down

0 comments on commit b571131

Please sign in to comment.