11//
22// FILE: FRAM.cpp
33// AUTHOR: Rob Tillaart
4- // VERSION: 0.1.1
5- // PURPOSE: Class for FRAM memory
6- // URL:
4+ // VERSION: 0.2.1
5+ // DATE: 2018-01-24
6+ // PURPOSE: Arduino library for I2C FRAM
7+ // URL: https://github.com/RobTillaart/FRAM_I2C
78//
89// HISTORY:
9- // 0.1.0 initial version
10- // 0.1.1 added suppport for Fujitsu 64Kbit MB85RC64T (kudos ysoyipek)
10+ // 0.1.0 2018-01-24 initial version
11+ // 0.1.1 2019-07-31 added suppport for Fujitsu 64Kbit MB85RC64T (kudos ysoyipek)
12+ // 0.2.0 2020-04-30 refactor, add writeProtectPin code
13+ // 0.2.1 2020-06-10 fix library.json
1114
1215#include " FRAM.h"
1316
14- # define FRAM_SLAVE_ID_ 0x7C
17+ const uint8_t FRAM_SLAVE_ID_= 0x7C ;
1518
1619// ///////////////////////////////////////////////////
1720//
2023FRAM::FRAM ()
2124{}
2225
23- int FRAM::begin (int address = 0X50 )
26+ int FRAM::begin (uint8_t address, int8_t writeProtectPin )
2427{
2528 if (address < 0x50 || address > 0x57 )
2629 {
@@ -30,18 +33,11 @@ int FRAM::begin(int address = 0X50)
3033 _address = address;
3134 Wire.begin ();
3235
33- uint16_t mid = getManufacturerID ();
34- uint16_t pid = getProductID ();
35- _size = 0 ; // UNKNOWN
36- if (mid == 0x000A ) // fujitsu
36+ if (writeProtectPin > -1 )
3737 {
38- // note pid's are from fujitsu SIZE TYPE
39- if (pid == 0x0358 ) _size = 8 ; // 8KB MB85RC64T
40- if (pid == 0x0510 ) _size = 32 ; // 32KB MB85RC256V
41- if (pid == 0x0658 ) _size = 64 ; // 64KB MB85RC512T
42- if (pid == 0x0758 ) _size = 128 ; // 128KB MB85RC1MT
38+ _writeProtectPin = writeProtectPin;
39+ pinMode (_writeProtectPin, OUTPUT);
4340 }
44-
4541 return FRAM_OK;
4642}
4743
@@ -104,7 +100,7 @@ uint32_t FRAM::read32(uint16_t memaddr)
104100
105101void FRAM::read (uint16_t memaddr, uint8_t * obj, uint16_t size)
106102{
107- const int blocksize = 24 ;
103+ const uint8_t blocksize = 24 ;
108104 uint8_t * p = obj;
109105 while (size >= blocksize)
110106 {
@@ -113,44 +109,70 @@ void FRAM::read(uint16_t memaddr, uint8_t * obj, uint16_t size)
113109 p += blocksize;
114110 size -= blocksize;
115111 }
112+ // remainder
116113 if (size > 0 )
117114 {
118115 readBlock (memaddr, p, size);
119116 }
120117}
121118
119+ bool FRAM::setWriteProtect (bool b)
120+ {
121+ if (_writeProtectPin == -1 ) return false ;
122+ digitalWrite (_writeProtectPin, b ? HIGH : LOW);
123+ return true ;
124+ }
125+
122126uint16_t FRAM::getManufacturerID ()
123127{
124- uint16_t value = 0 ;
125- Wire.beginTransmission (FRAM_SLAVE_ID_);
126- Wire.write (_address << 1 );
127- Wire.endTransmission (false );
128- int x = Wire.requestFrom (FRAM_SLAVE_ID_, 2 );
129- if (x != 2 ) return -1 ;
130- value = Wire.read () << 4 ;
131- value |= Wire.read () >> 4 ;
132- return value;
128+ return getMetaData (0 );
133129}
134130
135131uint16_t FRAM::getProductID ()
136132{
137- uint16_t value = 0 ;
133+ return getMetaData (1 );
134+ }
135+
136+ uint16_t FRAM::getSize ()
137+ {
138+ uint16_t val = getMetaData (2 ); // density bits
139+ if (val > 0 ) return 1 << val;
140+ return 0 ;
141+ }
142+
143+ // /////////////////////////////////////////////////////////
144+ //
145+ // PRIVATE
146+ //
147+
148+ // metadata is packed as [....MMMM][MMMMDDDD][PPPPPPPP]
149+ // M = manufacturerID
150+ // D = density => memsize = 2^D KB
151+ // P = product ID (together with D)
152+ uint16_t FRAM::getMetaData (uint8_t field)
153+ {
154+ if (field > 2 ) return 0 ;
155+
138156 Wire.beginTransmission (FRAM_SLAVE_ID_);
139157 Wire.write (_address << 1 );
140158 Wire.endTransmission (false );
141- int x = Wire.requestFrom (FRAM_SLAVE_ID_, 3 );
159+ int x = Wire.requestFrom (FRAM_SLAVE_ID_, ( uint8_t ) 3 );
142160 if (x != 3 ) return -1 ;
143- Wire.read ();
144- value = (Wire.read () & 0x0F ) << 8 ;
161+
162+ uint32_t value = 0 ;
163+ value = Wire.read ();
164+ value |= Wire.read ();
145165 value |= Wire.read ();
146- return value;
166+ // MANUFACTURER
167+ if (field == 0 ) return (value >> 12 ) & 0xFF ;
168+ // PRODUCT ID
169+ if (field == 1 ) return value & 0x0FFF ;
170+ // DENSITY
171+ if (field == 2 ) return (value >> 8 ) & 0x0F ;
172+ return 0 ;
147173}
148174
149- // /////////////////////////////////////////////////////////
150- //
151- // PRIVATE
152- //
153- void FRAM::writeBlock (uint16_t memaddr, uint8_t * obj, uint16_t size)
175+ void FRAM::writeBlock (uint16_t memaddr, uint8_t * obj, uint8_t size)
154176{
155177 // TODO constrain size < 30 ??
156178 Wire.beginTransmission (_address);
@@ -164,7 +186,7 @@ void FRAM::writeBlock(uint16_t memaddr, uint8_t * obj, uint16_t size)
164186 Wire.endTransmission ();
165187}
166188
167- void FRAM::readBlock (uint16_t memaddr, uint8_t * obj, uint16_t size)
189+ void FRAM::readBlock (uint16_t memaddr, uint8_t * obj, uint8_t size)
168190{
169191 Wire.beginTransmission (_address);
170192 Wire.write (memaddr >> 8 );
@@ -178,4 +200,4 @@ void FRAM::readBlock(uint16_t memaddr, uint8_t * obj, uint16_t size)
178200 }
179201}
180202
181- // END OF FILE
203+ // -- END OF FILE --
0 commit comments