From a8745e24c8c2ed41f02e62bae5a7a7361a25aee7 Mon Sep 17 00:00:00 2001 From: ChaeHee Won Date: Fri, 20 Sep 2019 12:19:45 -0400 Subject: [PATCH] Fix #220: Add class cFram_FM24CL16B and class cFram2k use it --- keywords.txt | 1 + src/Catena_Fram2k.h | 6 +- src/Catena_Fram_fm24cl16b.h | 66 ++++++ src/Catena_Mb85rc64ta.h | 35 +-- src/lib/Catena_Fram8k.cpp | 6 +- src/lib/Catena_Fram_fm24cl16b.cpp | 362 ++++++++++++++++++++++++++++++ src/lib/Catena_Mb85rc64ta.cpp | 68 ++---- 7 files changed, 460 insertions(+), 84 deletions(-) create mode 100644 src/Catena_Fram_fm24cl16b.h create mode 100644 src/lib/Catena_Fram_fm24cl16b.cpp diff --git a/keywords.txt b/keywords.txt index 773df52..d596010 100644 --- a/keywords.txt +++ b/keywords.txt @@ -119,6 +119,7 @@ cCommandStream KEYWORD1 cCompletion KEYWORD1 cFlash_AT25SF081 KEYWORD1 cFram KEYWORD1 +cFram_FM24CL16B KEYWORD1 cFram2k KEYWORD1 cFram8k KEYWORD1 cFramStorage KEYWORD1 diff --git a/src/Catena_Fram2k.h b/src/Catena_Fram2k.h index dae2b9d..4be7ad9 100644 --- a/src/Catena_Fram2k.h +++ b/src/Catena_Fram2k.h @@ -40,8 +40,8 @@ Revision history: # include "Catena_Fram.h" #endif -#ifndef _ADAFRUIT_FRAM_I2C_H_ -# include +#ifndef _CATENA_FRAM_FM24CL16B_H_ +# include "Catena_Fram_fm24cl16b.h" #endif /****************************************************************************\ @@ -84,7 +84,7 @@ class cFram2k : public cFram protected: private: - Adafruit_FRAM_I2C m_hw; + cFram_FM24CL16B m_hw; }; }; // namespace McciCatena diff --git a/src/Catena_Fram_fm24cl16b.h b/src/Catena_Fram_fm24cl16b.h new file mode 100644 index 0000000..8ff74af --- /dev/null +++ b/src/Catena_Fram_fm24cl16b.h @@ -0,0 +1,66 @@ +/* + +Module: Catena_Fram_fm24cl16b.h + +Function: + class cFram_FM24CL16B: 2K I2C FRAM + +Copyright notice: + See accompanying LICENSE file. + +Author: + ChaeHee Won, MCCI Corporation September 2019 + +*/ + +#ifndef _CATENA_FRAM_FM24CL16B_H_ /* prevent multiple includes */ +#define _CATENA_FRAM_FM24CL16B_H_ + +#pragma once + +#include +#include + +namespace McciCatena { + +class cFram_FM24CL16B + { +public: + cFram_FM24CL16B(void); + + static constexpr uint8_t CATENA_FM24CL16B_ADDRESS = 0x50; + static constexpr int CATENA_FM24CL16B_SLAVE_ID = (0xF8 >> 1); + + // set up and probe device + boolean begin(uint8_t DeviceAddress = CATENA_FM24CL16B_ADDRESS, + TwoWire *pWire = &Wire); + + // write a single byte + void write8(uint16_t framAddr, uint8_t value); + + // write a buffer + void write(uint16_t framAddr, uint8_t const *pBuffer, size_t nBuffer); + + // read a single byte + uint8_t read8(uint16_t framAddr); + + // read a buffer + size_t read(uint16_t framAddr, uint8_t *pBuffer, size_t nBuffer); + + // read ID + void readId(uint16_t *pManufactureId, uint16_t *pProductId); + +private: + uint8_t m_DeviceAddress; + boolean m_Initialized; + boolean m_PowerDown; + TwoWire * m_pWire; + + void prepIO(void) const; + uint8_t getDeviceAddress(uint16_t framAddr) const; + }; + +} // namespace McciCatena + +/**** end of Catena_Fram_fm24cl16b.h ****/ +#endif /* _CATENA_FRAM_FM24CL16B_H_ */ diff --git a/src/Catena_Mb85rc64ta.h b/src/Catena_Mb85rc64ta.h index c9d5339..a09ba40 100644 --- a/src/Catena_Mb85rc64ta.h +++ b/src/Catena_Mb85rc64ta.h @@ -1,36 +1,15 @@ -/* Catena_Mb85rc64ta.h Wed Dec 06 2017 15:30:56 chwon */ - /* Module: Catena_Mb85rc64ta.h Function: - class Catena_Mb85rc64ta - -Version: - V0.6.0 Wed Dec 06 2017 15:30:56 chwon Edit level 2 + class Catena_Mb85rc64ta: 8K I2C FRAM Copyright notice: - This file copyright (C) 2017 by - - MCCI Corporation - 3520 Krums Corners Road - Ithaca, NY 14850 - - An unpublished work. All rights reserved. - - This file is proprietary information, and may not be disclosed or - copied without the prior permission of MCCI Corporation. + See accompanying LICENSE file. Author: - ChaeHee Won, MCCI Corporation October 2017 - -Revision history: - 0.6.0 Fri Oct 13 2017 15:19:30 chwon - Module created. - - 0.6.0 Wed Dec 06 2017 15:30:56 chwon - Add readId and power control. + ChaeHee Won, MCCI Corporation October 2017 */ @@ -42,11 +21,6 @@ Revision history: #include #include -/* TODO: change these to enums and constepxrs in the McciCatena namespace */ - -#define CATENA_MB85RC64TA_ADDRESS (0x50) -#define CATENA_MB85RC64TA_SLAVE_ID (0xF8 >> 1) - namespace McciCatena { class Catena_Mb85rc64ta @@ -54,6 +28,9 @@ class Catena_Mb85rc64ta public: Catena_Mb85rc64ta(void); + static constexpr uint8_t CATENA_MB85RC64TA_ADDRESS = 0x50; + static constexpr int CATENA_MB85RC64TA_SLAVE_ID = (0xF8 >> 1); + // set up and probe device boolean begin(uint8_t DeviceAddress = CATENA_MB85RC64TA_ADDRESS, TwoWire *pWire = &Wire); diff --git a/src/lib/Catena_Fram8k.cpp b/src/lib/Catena_Fram8k.cpp index 504c45b..8efe257 100644 --- a/src/lib/Catena_Fram8k.cpp +++ b/src/lib/Catena_Fram8k.cpp @@ -64,7 +64,7 @@ Name: McciCatena::cFram8k::begin() McciCatena::cFram8k::begin() Description: - Initialize an cFram2K object prior to operation. + Initialize an cFram8k object prior to operation. Returns: true for success, false for failure. @@ -84,7 +84,7 @@ McciCatena::cFram8k::begin() /* -Name: McciCatena::cFram2K::read() +Name: McciCatena::cFram8k::read() Function: Read a string of bytes from the FRAM @@ -117,7 +117,7 @@ McciCatena::cFram8k::read( /* -Name: McciCatena::cFram2K::write() +Name: McciCatena::cFram8k::write() Function: Write a sequence of bytes to the FRAM. diff --git a/src/lib/Catena_Fram_fm24cl16b.cpp b/src/lib/Catena_Fram_fm24cl16b.cpp new file mode 100644 index 0000000..9a7c274 --- /dev/null +++ b/src/lib/Catena_Fram_fm24cl16b.cpp @@ -0,0 +1,362 @@ +/* + +Module: Catena_Fram_fm24cl16b.cpp + +Function: + class cFram_FM24CL16B: 2K I2C FRAM + +Copyright notice: + See accompanying LICENSE file. + +Author: + ChaeHee Won, MCCI Corporation September 2019 + +*/ + +#include +#include + +#include "Catena_Fram_fm24cl16b.h" +using namespace McciCatena; + +/****************************************************************************\ +| +| Manifest constants & typedefs. +| +| This is strictly for private types and constants which will not +| be exported. +| +\****************************************************************************/ + + + +/****************************************************************************\ +| +| Read-only data. +| +| If program is to be ROM-able, these must all be tagged read-only +| using the ROM storage class; they may be global. +| +\****************************************************************************/ + + + +/****************************************************************************\ +| +| VARIABLES: +| +| If program is to be ROM-able, these must be initialized +| using the BSS keyword. (This allows for compilers that require +| every variable to have an initializer.) Note that only those +| variables owned by this module should be declared here, using the BSS +| keyword; this allows for linkers that dislike multiple declarations +| of objects. +| +\****************************************************************************/ + + +/* +|| Constructors +*/ + +cFram_FM24CL16B::cFram_FM24CL16B(void) + { + this->m_Initialized = false; + } + +void cFram_FM24CL16B::prepIO(void) const + { + /* this->m_pWire->setClock(1000000); */ + } + +uint8_t cFram_FM24CL16B::getDeviceAddress(uint16_t framAddr) const + { + return this->m_DeviceAddress + ((framAddr >> 8) & 0x7); + } + +/* +|| Public functions +*/ + +/* + +Name: cFram_FM24CL16B::begin + +Function: + Begin method + +Definition: + boolean cFram_FM24CL16B::begin( + uint8_t DeviceAddress, + TwoWire *pWire + ); + +Description: + This function initializes I2C and configures the chip. + +Returns: + true if success + +*/ + +boolean cFram_FM24CL16B::begin( + uint8_t DeviceAddress, + TwoWire *pWire + ) + { + uint8_t i; + uint8_t uError; + + /* scrub and save the address */ + if (DeviceAddress == 0) + DeviceAddress = CATENA_FM24CL16B_ADDRESS; + + this->m_DeviceAddress = DeviceAddress & ~0x7; + this->m_pWire = pWire; + + pWire->begin(); + + /* Make sure we're actually connected */ + this->prepIO(); + + for (i = 0; i < 8; ++i) + { + pWire->beginTransmission(this->m_DeviceAddress + i); + uError = pWire->endTransmission(); + if (uError != 0) + { + // device didn't ack + return false; + } + } + + /* Everything seems to be properly initialised and connected */ + this->m_Initialized = true; + + return true; + } + +/* + +Name: cFram_FM24CL16B::write8 + +Function: + Writes a byte at the specific FRAM address + +Definition: + void cFram_FM24CL16B::write8( + uint16_t framAddr, + uint8_t value + ); + +Description: + This function writes a byte at the specific FRAM address. + +Returns: + No explicit result. + +*/ + +void cFram_FM24CL16B::write8( + uint16_t framAddr, + uint8_t value + ) + { + uint8_t const DeviceAddress = this->getDeviceAddress(framAddr); + + this->prepIO(); + this->m_pWire->beginTransmission(DeviceAddress); + this->m_pWire->write(framAddr & 0xFF); + this->m_pWire->write(value); + this->m_pWire->endTransmission(); + } + +/* + +Name: cFram_FM24CL16B::write + +Function: + Writes a buffer to the specific FRAM address + +Definition: + void cFram_FM24CL16B::write( + uint16_t framAddr, + const uint8_t *pBuffer, + size_t nBuffer + ); + +Description: + This function writes a buffer to the specific FRAM address + +Returns: + No explicit result. + +*/ + +void cFram_FM24CL16B::write( + uint16_t framAddr, + const uint8_t *pBuffer, + size_t nBuffer + ) + { + uint8_t const DeviceAddress = this->getDeviceAddress(framAddr); + + this->prepIO(); + this->m_pWire->beginTransmission(DeviceAddress); + this->m_pWire->write(framAddr & 0xFF); + this->m_pWire->write(pBuffer, nBuffer); + this->m_pWire->endTransmission(); + } + +/* + +Name: cFram_FM24CL16B::read8 + +Function: + Reads an 8 bit value from the specified FRAM address + +Definition: + uint8_t cFram_FM24CL16B::read8( + uint16_t framAddr + ); + +Description: + This function reads an 8 bit value from the specified FRAM address. + +Returns: + The 8-bit value retrieved at framAddr. + +*/ + +uint8_t cFram_FM24CL16B::read8( + uint16_t framAddr + ) + { + uint8_t const DeviceAddress = this->getDeviceAddress(framAddr); + + this->prepIO(); + this->m_pWire->beginTransmission(DeviceAddress); + this->m_pWire->write(framAddr & 0xFF); + this->m_pWire->endTransmission(); + + this->m_pWire->requestFrom(DeviceAddress, (uint8_t)1); + while (! this->m_pWire->available()) + /* loop */; + + return this->m_pWire->read(); + } + +/* + +Name: cFram_FM24CL16B::read + +Function: + Reads a buffer from the specified FRAM address + +Definition: + size_t cFram_FM24CL16B::read( + uint16_t framAddr, + uint8_t *pBuffer, + size_t nBuffer + ); + +Description: + This function reads a buffer from the specified FRAM address. + +Returns: + The number of bytes retrieved at framAddr. + +*/ + +size_t cFram_FM24CL16B::read( + uint16_t framAddr, + uint8_t *pBuffer, + size_t nBuffer + ) + { + size_t const save_nBuffer = nBuffer; + + this->prepIO(); + while (nBuffer > 0) + { + uint8_t const DeviceAddress = this->getDeviceAddress(framAddr); + uint8_t nRead; + + this->m_pWire->beginTransmission(DeviceAddress); + this->m_pWire->write(framAddr & 0xFF); + this->m_pWire->endTransmission(); + + nRead = nBuffer > 128 ? 128 : (uint8_t) nBuffer; + nRead = this->m_pWire->requestFrom( + DeviceAddress, + nRead + ); + if (nRead == 0) + { + break; + } + + framAddr += nRead; + nBuffer -= nRead; + while (this->m_pWire->available() && nRead > 0) + { + *pBuffer++ = this->m_pWire->read(); + --nRead; + } + } + + return save_nBuffer - nBuffer; + } + +/* + +Name: cFram_FM24CL16B::readId + +Function: + Reads a buffer from the specified FRAM address + +Definition: + void cFram_FM24CL16B::readId( + uint16_t *pManufactureId, + uint16_t *pProductId + ); + +Description: + This function reads a buffer from the specified FRAM address. + +Returns: + No explicit result. + +*/ + +void cFram_FM24CL16B::readId( + uint16_t *pManufactureId, + uint16_t *pProductId + ) + { + uint8_t data; + + this->prepIO(); + this->m_pWire->beginTransmission(CATENA_FM24CL16B_SLAVE_ID); + this->m_pWire->write(this->m_DeviceAddress << 1); + this->m_pWire->endTransmission(false); + + data = this->m_pWire->requestFrom( + CATENA_FM24CL16B_SLAVE_ID, + 3 + ); + if (data == 0) + { + Serial.println("FRAM readId() failed"); + } + + data = this->m_pWire->read(); + *pManufactureId = data << 4; + data = this->m_pWire->read(); + *pManufactureId |= data >> 4; + *pProductId = (data & 0x0Fu) << 8; + data = this->m_pWire->read(); + *pProductId |= data; + } + +/**** end of Catena_Fram_fm24cl16b.cpp ****/ diff --git a/src/lib/Catena_Mb85rc64ta.cpp b/src/lib/Catena_Mb85rc64ta.cpp index 561f820..ef5e969 100644 --- a/src/lib/Catena_Mb85rc64ta.cpp +++ b/src/lib/Catena_Mb85rc64ta.cpp @@ -1,36 +1,15 @@ -/* Catena_Mb85rc64ta.cpp Wed Dec 06 2017 15:33:28 chwon */ - /* Module: Catena_Mb85rc64ta.cpp Function: - Class for Catena_Mb85rc64ta. - -Version: - V0.6.0 Wed Dec 06 2017 15:33:28 chwon Edit level 2 + class Catena_Mb85rc64ta: 8K I2C FRAM Copyright notice: - This file copyright (C) 2017 by - - MCCI Corporation - 3520 Krums Corners Road - Ithaca, NY 14850 - - An unpublished work. All rights reserved. - - This file is proprietary information, and may not be disclosed or - copied without the prior permission of MCCI Corporation. + See accompanying LICENSE file. Author: - ChaeHee Won, MCCI Corporation October 2017 - -Revision history: - 0.6.0 Fri Oct 13 2017 15:19:30 chwon - Module created. - - 0.6.0 Wed Dec 06 2017 15:33:28 chwon - Add readId and power control. + ChaeHee Won, MCCI Corporation October 2017 */ @@ -120,14 +99,13 @@ boolean Catena_Mb85rc64ta::begin( TwoWire *pWire ) { - uint8_t i; uint8_t uError; /* scrub and save the address */ if (DeviceAddress == 0) DeviceAddress = CATENA_MB85RC64TA_ADDRESS; - this->m_DeviceAddress = DeviceAddress & ~0x7; + this->m_DeviceAddress = DeviceAddress; this->m_pWire = pWire; pWire->begin(); @@ -135,22 +113,13 @@ boolean Catena_Mb85rc64ta::begin( /* Make sure we're actually connected */ this->prepIO(); - for (i = 0; i < 8; ++this->m_DeviceAddress, ++i) - { - /* force to put stand-by mode, just in case */ - this->m_PowerDown = true; - this->powerUp(); + /* force to put stand-by mode, just in case */ + this->m_PowerDown = true; + this->powerUp(); - pWire->beginTransmission(this->m_DeviceAddress); - uError = pWire->endTransmission(); - if (uError == 0) - { - break; - } - - } - - if (i == 8) + pWire->beginTransmission(this->m_DeviceAddress); + uError = pWire->endTransmission(); + if (uError != 0) { // device didn't ack return false; @@ -271,7 +240,7 @@ uint8_t Catena_Mb85rc64ta::read8( /* -Name: Catena_Mb85rc64ta::read8 +Name: Catena_Mb85rc64ta::read Function: Reads a buffer from the specified FRAM address @@ -309,9 +278,10 @@ size_t Catena_Mb85rc64ta::read( this->m_pWire->write(framAddr & 0xFF); this->m_pWire->endTransmission(); + nRead = nBuffer > 128 ? 128 : (uint8_t) nBuffer; nRead = this->m_pWire->requestFrom( this->m_DeviceAddress, - (uint8_t) nBuffer + nRead ); if (nRead == 0) { @@ -319,10 +289,11 @@ size_t Catena_Mb85rc64ta::read( } framAddr += nRead; - while (this->m_pWire->available() && nBuffer > 0) + nBuffer -= nRead; + while (this->m_pWire->available() && nRead > 0) { *pBuffer++ = this->m_pWire->read(); - --nBuffer; + --nRead; } } @@ -369,7 +340,7 @@ void Catena_Mb85rc64ta::readId( #else this->m_pWire->beginTransmission(CATENA_MB85RC64TA_SLAVE_ID); this->m_pWire->write(this->m_DeviceAddress << 1); - this->m_pWire->endTransmission(); + this->m_pWire->endTransmission(false); data = this->m_pWire->requestFrom( CATENA_MB85RC64TA_SLAVE_ID, @@ -384,9 +355,8 @@ void Catena_Mb85rc64ta::readId( data = this->m_pWire->read(); *pManufactureId = data << 4; data = this->m_pWire->read(); - *pManufactureId |= data & 0x0Fu; - data = this->m_pWire->read(); - *pProductId = data & 0xF0u << 8; + *pManufactureId |= data >> 4; + *pProductId = (data & 0x0Fu) << 8; data = this->m_pWire->read(); *pProductId |= data; }