Skip to content

Commit

Permalink
improve getSize() - FM24V10 FM24V05 (#50)
Browse files Browse the repository at this point in the history
- improve getSize() to support Infineon FM24V10 and FM24V05 (#49)
- update readme.md
- minor edits examples
  • Loading branch information
RobTillaart authored Jan 9, 2024
1 parent c481465 commit 768065a
Show file tree
Hide file tree
Showing 34 changed files with 185 additions and 131 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.7.1] - 2024-01-09
- improve getSize() to support Infineon FM24V10 and FM24V05 (#49)
- update readme.md
- minor edits examples


## [0.7.0] - 2023-10-30
- refactor / simplify begin() =>
- User has to call Wire.begin() explicitly.
Expand Down
71 changes: 45 additions & 26 deletions FRAM.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// FILE: FRAM.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.7.0
// VERSION: 0.7.1
// DATE: 2018-01-24
// PURPOSE: Arduino library for I2C FRAM
// URL: https://github.com/RobTillaart/FRAM_I2C
Expand All @@ -10,15 +10,15 @@
#include "FRAM.h"


// DENSITY CODES
// DENSITY CODES

#define FRAM_MB85RC64 0x03
#define FRAM_MB85RC256 0x05
#define FRAM_MB85RC512 0x06
#define FRAM_MB85RC1M 0x07


// used for metadata and sleep
// used for metadata and sleep
const uint8_t FRAM_SLAVE_ID_ = 0x7C; // == 0xF8
const uint8_t FRAM_SLEEP_CMD = 0x86; //

Expand Down Expand Up @@ -180,7 +180,7 @@ void FRAM::read(uint16_t memAddr, uint8_t * obj, uint16_t size)
p += blocksize;
size -= blocksize;
}
// remainder
// remainder
if (size > 0)
{
_readBlock(memAddr, p, size);
Expand All @@ -199,7 +199,8 @@ int32_t FRAM::readUntil(uint16_t memAddr, char * buffer, uint16_t bufferLength,
{
if (buffer[length] == separator)
{
buffer[length] = 0; // replace separator => \0 EndChar
// replace separator => \0 EndChar
buffer[length] = 0;
return length;
}
}
Expand All @@ -216,7 +217,8 @@ int32_t FRAM::readLine(uint16_t memAddr, char * buffer, uint16_t bufferLength)
{
if (buffer[length] == '\n')
{
buffer[length + 1] = 0; // add \0 EndChar after '\n'
// add \0 EndChar after '\n'
buffer[length + 1] = 0;
return length + 1;
}
}
Expand All @@ -243,6 +245,10 @@ bool FRAM::getWriteProtect()
}


////////////////////////////////////////////////////////////////
//
// MANUFACTURER PRODUCTID SIZE
//
uint16_t FRAM::getManufacturerID()
{
uint32_t value = _getMetaData();
Expand All @@ -257,20 +263,37 @@ uint16_t FRAM::getProductID()
}


// DENSITY
// Fujitsu data sheet
#define FRAM_MANU_FUJITSU 0x0A
#define FRAM_MANU_CYPRESS 0x04

// DENSITY Fujitsu data sheet
// 3 => MB85RC64 = 64 Kbit.
// 5 => MB85RC256
// 6 => MB85RC512
// 7 => MB85RC1M
//
// DENSITY Cypress / Infineon data sheet
// 3 => FM24V05 = 64 KByte.
// 4 => FM24V10 = 128 KByte.
//
// NOTE: returns the size in kiloBYTE (0 is read error)
uint16_t FRAM::getSize()
{
uint32_t value = _getMetaData();
if (value == 0xFFFFFFFF) return 0;

uint16_t manufacturer = (value >> 12) & 0x0FFF;

if (manufacturer == FRAM_MANU_CYPRESS)
{
uint16_t density = (value >> 8) & 0x0F;
uint16_t size = (1UL << density) * 8; // KB
_sizeBytes = size * 1024UL;
return size;
}
// default FRAM_MANU_FUJITSU
uint16_t density = (value >> 8) & 0x0F;
uint16_t size = (1UL << density);
uint16_t size = (1UL << density) * 1; // KB
_sizeBytes = size * 1024UL;
return size;
}
Expand Down Expand Up @@ -319,11 +342,13 @@ void FRAM::sleep()
// page 12 datasheet trec <= 400us
bool FRAM::wakeup(uint32_t timeRecover)
{
bool b = isConnected(); // wakeup
// wakeup
bool b = isConnected();
if (timeRecover == 0) return b;
// wait recovery time
delayMicroseconds(timeRecover);
return isConnected(); // check recovery OK
// check recovery OK
return isConnected();
}


Expand Down Expand Up @@ -389,7 +414,6 @@ void FRAM::_readBlock(uint16_t memAddr, uint8_t * obj, uint8_t size)
//
// FRAM32 PUBLIC
//

FRAM32::FRAM32(TwoWire *wire) : FRAM(wire)
{
}
Expand Down Expand Up @@ -448,7 +472,7 @@ void FRAM32::write(uint32_t memAddr, uint8_t * obj, uint16_t size)
p += blocksize;
size -= blocksize;
}
// remaining
// remaining
if (size > 0)
{
_writeBlock(memAddr, p, size);
Expand Down Expand Up @@ -531,7 +555,8 @@ int32_t FRAM32::readUntil(uint32_t memAddr, char * buffer, uint16_t bufferLength
{
if (buffer[length] == separator)
{
buffer[length] = 0; // replace separator => \0 EndChar
// replace separator => \0 EndChar
buffer[length] = 0;
return length;
}
}
Expand All @@ -548,7 +573,8 @@ int32_t FRAM32::readLine(uint32_t memAddr, char * buffer, uint16_t bufferLength)
{
if (buffer[length] == '\n')
{
buffer[length + 1] = 0; // add \0 EndChar after '\n'
// add \0 EndChar after '\n'
buffer[length + 1] = 0;
return length + 1;
}
}
Expand All @@ -571,8 +597,6 @@ uint32_t FRAM32::clear(uint8_t value)
}




/////////////////////////////////////////////////////////////////////////////
//
// FRAM32 PROTECTED
Expand Down Expand Up @@ -612,8 +636,6 @@ void FRAM32::_readBlock(uint32_t memAddr, uint8_t * obj, uint8_t size)
}




/////////////////////////////////////////////////////////////////////////////
//
// FRAM11
Expand Down Expand Up @@ -644,7 +666,7 @@ uint16_t FRAM11::getSize()
//
void FRAM11::_writeBlock(uint16_t memAddr, uint8_t * obj, uint8_t size)
{
// Device uses Address Pages
// Device uses Address Pages
uint8_t DeviceAddrWithPageBits = _address | ((memAddr & 0x0700) >> 8);
_wire->beginTransmission(DeviceAddrWithPageBits);
_wire->write((uint8_t) (memAddr & 0xFF));
Expand All @@ -660,7 +682,7 @@ void FRAM11::_writeBlock(uint16_t memAddr, uint8_t * obj, uint8_t size)

void FRAM11::_readBlock(uint16_t memAddr, uint8_t * obj, uint8_t size)
{
// Device uses Address Pages
// Device uses Address Pages
uint8_t DeviceAddrWithPageBits = _address | ((memAddr & 0x0700) >> 8);
_wire->beginTransmission(DeviceAddrWithPageBits);
_wire->write((uint8_t) (memAddr & 0xFF));
Expand All @@ -675,8 +697,6 @@ void FRAM11::_readBlock(uint16_t memAddr, uint8_t * obj, uint8_t size)
}




/////////////////////////////////////////////////////////////////////////////
//
// FRAM9
Expand All @@ -701,14 +721,13 @@ uint16_t FRAM9::getSize()
}



/////////////////////////////////////////////////////////////////////////////
//
// FRAM9 PROTECTED
//
void FRAM9::_writeBlock(uint16_t memAddr, uint8_t * obj, uint8_t size)
{
// Device uses Address Pages
// Device uses Address Pages
uint8_t DeviceAddrWithPageBits = _address | ((memAddr & 0x0100) >> 8);
_wire->beginTransmission(DeviceAddrWithPageBits);
_wire->write((uint8_t) (memAddr & 0xFF));
Expand All @@ -724,7 +743,7 @@ void FRAM9::_writeBlock(uint16_t memAddr, uint8_t * obj, uint8_t size)

void FRAM9::_readBlock(uint16_t memAddr, uint8_t * obj, uint8_t size)
{
// Device uses Address Pages
// Device uses Address Pages
uint8_t DeviceAddrWithPageBits = _address | ((memAddr & 0x0100) >> 8);
_wire->beginTransmission(DeviceAddrWithPageBits);
_wire->write((uint8_t) (memAddr & 0xFF));
Expand Down
6 changes: 3 additions & 3 deletions FRAM.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// FILE: FRAM.h
// AUTHOR: Rob Tillaart
// VERSION: 0.7.0
// VERSION: 0.7.1
// DATE: 2018-01-24
// PURPOSE: Arduino library for I2C FRAM
// URL: https://github.com/RobTillaart/FRAM_I2C
Expand All @@ -12,7 +12,7 @@
#include "Wire.h"


#define FRAM_LIB_VERSION (F("0.7.0"))
#define FRAM_LIB_VERSION (F("0.7.1"))


#define FRAM_OK 0
Expand Down Expand Up @@ -100,7 +100,7 @@ class FRAM

// MEAT INFO
// may not work for devices with no deviceID register.
// Fujitsu = 0x000A, Ramtron = 0x004
// Fujitsu = 0x000A, Ramtron et al = 0x004
uint16_t getManufacturerID();
// Proprietary product ID
uint16_t getProductID();
Expand Down
19 changes: 11 additions & 8 deletions FRAM_MULTILANGUAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@ Library for FRAM_MULTILANGUAGE (FRAM_ML) to be used with the FRAM_I2C library.

## Description

The FRAM_MULTILANGUAGE (FRAM_ML) is an experimental library that uses an FRAM object to
persistent store text tables. Typical use is to implement multi languages translations.
The storage of text in FRAM reduces RAM usage of an Arduino quit a lot.

The FRAM_ML supports up to 5 languages, this is hard coded in the first version (0.5.1).
An FRAM of 32KB can easily store many hundreds or even thousands (shorter) strings.
This allows to store e.g. 600 strings in one language or 300 in two languages
The **FRAM_MULTILANGUAGE (FRAM_ML)** is an experimental library that uses an FRAM object to
persistently store text tables. Typical use is to implement multiple translations.
However it can be used to store strings in only a single language too.
The storage of text in FRAM reduces the RAM usage of an Arduino quite a lot.

The FRAM_ML library supports up to 5 languages. This is hard coded in the first version (0.5.1).
An FRAM module of 32KB can easily store many hundreds or even thousands (shorter) strings.
This allows to store e.g. 600 long strings in one language or 300 in two languages
or 120 in five languages.

The FRAM_ML can use only part of an FRAM and multiple FRAM_ML objects can use the same FRAM.
The FRAM_ML library can be configured to use only part of an FRAM and multiple FRAM_ML
objects can use the same FRAM.

The current implementation is very straightforward, which is not memory efficient.
The advantage is it performs pretty well as every string can be found with little math.
Expand Down Expand Up @@ -130,6 +132,7 @@ Address is relative to base address.

- add **setName(const char \* str)** + **getName(char \* str)**
- length 8, position 2..9
- to label the text tables.


### Could
Expand Down
20 changes: 9 additions & 11 deletions FRAM_RINGBUFFER.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Library for FRAM_RINGBUFFER to be used with the FRAM_I2C library.

## Description

FRAM_RINGBUFFER is a class that uses an FRAM object to implement
**FRAM_RINGBUFFER** is a class that uses an FRAM object to implement
a ring buffer that can be made persistent over reboots.
The ring buffer can hold any size objects, but the user is responsible
to manage the contents.
Expand Down Expand Up @@ -53,7 +53,7 @@ it has no separate version number.
#include "FRAM_RINGBUFFER.h"
```

### Admin
### Administration

- **FRAM_RINGBUFFER()** Constructor.
- **uint32_t begin(FRAM \*fram, uint32_t size, uint32_t memAddr)** initializes
Expand All @@ -71,7 +71,7 @@ the ring buffer.
- **bool empty()** returns true if the ring buffer has no data in it.


### read / write (bytes)
### Read / write (bytes)

- **int write(uint8_t value)** writes a byte to the ring buffer.
- returns the number of bytes written (1) or **FRAM_RB_ERR_BUF_FULL**
Expand All @@ -81,7 +81,7 @@ the ring buffer.
- returns **FRAM_RB_ERR_BUF_EMPTY** in case of an empty buffer.


### read / write (objects)
### Read / write (objects)

- **template <class T> int write(T &obj)** writes an object to the ring buffer.
- returns the number of bytes written or **FRAM_RB_ERR_BUF_NO_ROOM**
Expand All @@ -94,7 +94,7 @@ the ring buffer.
bytes than the object requested.


### persistency
### Persistency

- **bool isSaved()** returns true if the administration of the ring buffer
is written to FRAM.
Expand Down Expand Up @@ -123,26 +123,24 @@ See examples.

## Future

#### Must

### high
#### Should

- elaborate FRAM_RINGBUFFER documentation
- add bool flag to **load(bool overrule = false)** to overrule the checksum verification.
- default false.
- add bool flag to **wipe(bool all = true)** to overwrite all or the
administration part only.


### medium

### Could

- example for a ring-buffer with different size objects
- struct with size and type info.
- preceding every object with type + size - 1..4 bytes
- add debugging tooling
- add object count?

### low

- create a RING_BUFFER class that can work with any type of storage.
- SD card, EEPROM etc.

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2018-2023 Rob Tillaart
Copyright (c) 2018-2024 Rob Tillaart

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
Loading

0 comments on commit 768065a

Please sign in to comment.