Coder Social home page Coder Social logo

zanduino / mb85_fram Goto Github PK

View Code? Open in Web Editor NEW
4.0 2.0 1.0 844 KB

Fujitsu MB85-xxxx family of FRAM I2C Memory Chips

License: GNU General Public License v3.0

C++ 100.00%
arduino-library arduino mb85rc512t mb85rc256v mb85rc128a mb85rc64ta mb85rc64a mb85rc64v fram i2c

mb85_fram's People

Contributors

sv-zanshin avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

eyewonder

mb85_fram's Issues

Chip identification issue

I found something strange when I attach different memories to i2c using the auto-identification method.
Analyzing the code I've found this in begin method:

        Wire.write((uint8_t)memSize >> 8);             // Write MSB of address
        Wire.write((uint8_t)memSize);                     // Write LsB of address

But in C++ and Gcc the cast operator (type) takes precedence over the bitwise scroll operator >>.
https://en.cppreference.com/w/c/language/operator_precedence
In effect, what you obtain is to cast the memSize (which is 16bit unsigned) to an unsigned 8bit AND THEN scroll it 8 position right; but when you cast a 16bit over a 8 bit only the LsB part of the source is copied into the destination variable, so you completely loose the MSB part when you send data through the i2c bus.

This is why you need to add a special case to detect 32kb memory at the end of the for cycle.

Finally I correct your method as follows:

uint8_t MB85_FRAM_Class::begin(const uint32_t i2cSpeed) {

  _wireCh->begin();
  _wireCh->setClock(i2cSpeed);
  for (uint8_t i = MB85_MIN_ADDRESS; i < MB85_MIN_ADDRESS + MB85_MAX_DEVICES; i++)  // loop all possible addresses
  {
    _wireCh->beginTransmission(i);
    if (_wireCh->endTransmission() == 0)  // If no error we have a device at this address
    {
      _wireCh->beginTransmission(i);  // Start transmission
      _wireCh->write((uint8_t)0);
      _wireCh->write((uint8_t)0);                        // Start at address 0
      _TransmissionStatus = _wireCh->endTransmission();  // Close transmission
      _wireCh->requestFrom(i, (uint8_t)1);               // Request 1 byte of data
      uint8_t minimumByte = _wireCh->read();             // Store value of byte 0

      _wireCh->beginTransmission(i);  // Start transmission
      _wireCh->write((uint8_t)0);
      _wireCh->write((uint8_t)0);                        // Start at address 0
      _wireCh->write(0xFF);                              // write high value to address 0
      _TransmissionStatus = _wireCh->endTransmission();  // Close transmission

      for (uint16_t memSize = 8192; memSize != 0; memSize = memSize * 2)  // Check each memory size
      {
        _wireCh->beginTransmission(i);                     // Start transmission
        _wireCh->write((uint8_t)(memSize >> 8));             // Write MSB of address
        _wireCh->write((uint8_t)memSize);                  // Write LsB of address
        _TransmissionStatus = _wireCh->endTransmission();  // Close transmission
        _wireCh->requestFrom(i, (uint8_t)1);               // Request 1 byte of data
        uint8_t maximumByte = _wireCh->read();             // Store value of high byte for chip
        _wireCh->beginTransmission(i);                     // Start transmission
        _wireCh->write((uint8_t)(memSize >> 8));             // Write MSB of address
        _wireCh->write((uint8_t)memSize);                  // Write LsB of address
        _wireCh->write(0x00);                              // write low value to max address
        _TransmissionStatus = _wireCh->endTransmission();  // Close transmission

        _wireCh->beginTransmission(i);  // Start transmission
        _wireCh->write((uint8_t)0);
        _wireCh->write((uint8_t)0);                        // Start at address 0
        _TransmissionStatus = _wireCh->endTransmission();  // Close transmission
        _wireCh->requestFrom(i, (uint8_t)1);               // Request 1 byte of data
        uint8_t newMinimumByte = _wireCh->read();          // Store value of byte 0
        if (newMinimumByte == 0x00)                    // If the value has changed
        {
          _I2C[i - MB85_MIN_ADDRESS] = memSize / 1024;  // Store memory size in kB
          _TotalMemory += memSize;                      // Add value to total
          _wireCh->beginTransmission(i);                     // Start transmission
          _wireCh->write((uint8_t)0);
          _wireCh->write((uint8_t)0);                        // Position to address 0
          _wireCh->write(minimumByte);                       // restore original value
          _TransmissionStatus = _wireCh->endTransmission();  // Close transmission
          break;                                             // Exit the loop
        } else {
          _wireCh->beginTransmission(i);                     // Start transmission
          _wireCh->write((uint8_t)(memSize >> 8));           // Write MSB of address
          _wireCh->write((uint8_t)memSize);                  // Write LsB of address
          _wireCh->write(maximumByte);                       // restore original value
          _TransmissionStatus = _wireCh->endTransmission();  // Close transmission
        }                                                // of if-then-else we've got a wraparound
      }                                     // of for-next loop for each memory size
      _DeviceCount++;                       // Increment the found count
    }                                       // of if-then we have found a device
  }                                         // of for-next each I2C address loop
  return _DeviceCount;                      // return number of memories found

As you can notice, I also moved the read part of the 0 address out of the memSize for since you don't really need to read the 0 address each time. In addition I've added a new constructor to manage multiple i2c ports.

MB85_FRAM_Class::MB85_FRAM_Class(TwoWire *wireChannel) {
  _wireCh = wireChannel;
}

And a local field to handle the instance:

TwoWire *_wireCh = &Wire; ///< Wire channel to use (for multi-channel platforms)

For "static" configurations I suggest you to add a begin override with a pre-defined configuration like this:

uint8_t MB85_FRAM_Class::begin(const uint8_t devices[MB85_MAX_DEVICES], const uint32_t i2cSpeed) {
  _wireCh->begin();
  _wireCh->setClock(i2cSpeed);

  for (uint8_t i = MB85_MIN_ADDRESS; i < MB85_MIN_ADDRESS + MB85_MAX_DEVICES; i++)
  {
    if (devices[i - MB85_MIN_ADDRESS] != 0)
    {
      _wireCh->beginTransmission(i);
      if (_wireCh->endTransmission() == 0)  // If no error we have a device at this address
      {
        _I2C[i - MB85_MIN_ADDRESS] = devices[i - MB85_MIN_ADDRESS];
        _TotalMemory += (devices[i - MB85_MIN_ADDRESS] * 1024);
        _DeviceCount++;
      }
    }
  }

  return _DeviceCount;
} 

In this case you can avoid to read and write memory to detect the configuration if system has a pre-determined one.
Obviously, other minor changes were made in the code to adapt to the Wire pointer.

HTH

Lorenz

Specifications

  • Library Version: 1.0.7
  • IDE Version: platformIO
  • Platform: Win10 64
  • Subsystem: Teensy 4.0

Support faster I2C bus speeds

This Family of memories supports up to 3400KHz I2C bus Speeds ("high Speed mode"), so the library should allow the user to specifiy faster Transfer Speeds than the Default 100KHz

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.