Ringbuffers en super arrays

Inmiddels een werkende Virtual Memory controller gereed. Werkt prima met I2C ic's. Volgende week krijg ik 2 x SPI 128kb x8 bit ic's binnen. Dan kan ik verder. Op dit moment werkt het met 2 x Adafruit 32kbx8bit FRAM modules.
Er zijn 2 classes.
a) I2CMemory controller:

I2CMemoryController.h

/*
 Name:       I2CChipController.h
 Created:    24-12-2018 12:36:00
 Author:     nico verduin
 Brief:      Controller to handle I2C FRAM IC's
 */


#ifndef I2CMEMORYCONTROLLER_H_
#define I2CMEMORYCONTROLLER_H_

// includes
#include <Arduino.h>
#include <Wire.h>

// opcodes used for reading and writing
enum {
  READ,
  WRITE
};

class I2CMemoryController {

protected:
  uint32_t  capacity;         // contains the capacity of chip memory
  char      thisI2CAddress;   // I2C address of the chip

  // functions
public:
  I2CMemoryController(uint8_t);
  void        init();
  void        processOperation(uint8_t , uint32_t , uint32_t, char *);
  uint32_t    getCapacity();
};

#endif /* I2C_CHIPCONTROLLER_H_ */

I2CMemoryController.cpp

/*
 Name:       I2CMemoryController.h
 Created:    24-12-2018 12:36:00
 Author:     nico verduin
 Brief:      Controller to handle I2C FRAM IC's
 */

#include "I2CMemoryController.h"


/**
 * @name I2CMemoryController
 * @param uint8_t I2C address of chip
 * @brief Constructor
 */
I2CMemoryController::I2CMemoryController(uint8_t address) {

  // save this chip's address
  thisI2CAddress = address;

  // initialize other parameters
  capacity  = 0;
}

/**
 * @name init
 * @brief Initializes the chip by determining how much memory the chip
 * contains.
 */
void I2CMemoryController::init() {

  // determine memory capacity of the chip
  // put a 0x00 on address 0
  Wire.beginTransmission(thisI2CAddress);
  Wire.write(0);
  Wire.write(0);
  Wire.write(0x00);
  Wire.endTransmission();

  // now put on every power of 2 address an 0xFF
  // we can handle a max of 2 GigaBytes
  uint32_t i = 1;

  // once i = 0 we have looped through 2 Gigabytes address space
  while (i != 0){

    // write our 0xFF
    Wire.beginTransmission(thisI2CAddress);
    Wire.write(i >> 8);
    Wire.write(i & 0xFF);
    Wire.write(0xFF);
    Wire.endTransmission();

    // assuming the memory capacity is a factor of 2^n, we will reach a loop
    // around to address 0. So if we have written a 0xFF on address 0x0000,
    // i contains the max capacity of the chip. And we are done searching for
    // the capacity
    Wire.beginTransmission(thisI2CAddress);
    Wire.write(0x00);
    Wire.write(0x00);
    Wire.endTransmission();

    // ask for our byte
    Wire.requestFrom(thisI2CAddress, 1, true);
    uint8_t result = Wire.read();

    // check if wrap around
    if (result == 0xFF) {

      // save capacity
      capacity = i;

      // if there is no chip, Wire returns a 0xFF. This will happen
      // on the first value of i (which is 1). Thus we need to
      // subtract 1 from the capacity to return 0 bytes capacity
      if (capacity == 1) {
        // no chip recognized on this address
        capacity = 0;
      }

      // loop is finished
      break;
    }

    // i * 2
    i  = i << 1;
  }
}


/**
 * processOperation
 * @param opcode operation type (READ or WRITE)
 * @param char * pointer to where data is read from or sent to
 * @brief reads or write a block from/to chip to/from local
 * memory
 */
void I2CMemoryController::processOperation( uint8_t   opcode,
                                            uint32_t addressPtr,
                                            uint32_t blockSize,
                                            char * ptr) {

  char bufferCtr   = 0;      // max 32 bytes counter

  // process the whole block within this chip
  while (blockSize != 0UL) {

    // if the buffer is empty we need to setup the chip
    if (bufferCtr == 0UL) {

      // setup start address
      Wire.beginTransmission(thisI2CAddress);

      // set our address within the chip
      Wire.write(addressPtr >> 8);
      Wire.write(addressPtr & 0xFF);

      // determine the size of our I2C buffer to use
      if (opcode == READ) {
        if (blockSize > BUFFER_LENGTH) {
          bufferCtr = BUFFER_LENGTH;
        } else {
          bufferCtr = blockSize;
        }
        // close transmission
        Wire.endTransmission();

        // ask for our bytes.
        Wire.requestFrom(thisI2CAddress, bufferCtr, true);
      }

      // for Writing we are already using 2 bytes of the buffer
      // for the memory address
      if (opcode == WRITE) {
        if (blockSize > (BUFFER_LENGTH - 2)) {
          bufferCtr = BUFFER_LENGTH - 2;
        } else {
          bufferCtr = blockSize;
        }
      }
    }

    // decrease total to transfer bytes in advance and increase
    // address Pointer
    blockSize   -= bufferCtr;
    addressPtr  += bufferCtr;

    // process bufferCnt number of bytes
    while (bufferCtr != 0UL){

      if (opcode == READ){
        if (Wire.available()) {
          *ptr = Wire.read();
          ptr++;
          bufferCtr--;
        }
      }
      if (opcode == WRITE){
        Wire.write(*ptr);
        ptr++;
        bufferCtr--;
      }
    }

    // I2C command at end of writing
    if (opcode == WRITE){
      // close transmission
      Wire.endTransmission();
    }
  }
}

/*
 * @name getCapacity
 * @return uint32_t capacity of the chip
 * @brief returns the chip memory capacity
 */
uint32_t I2CMemoryController::getCapacity() {
  return capacity;
}