Skip to content

Commit

Permalink
Merge pull request #31 from FUEL4EP/FUEL4EP_1
Browse files Browse the repository at this point in the history
added Fujitsu MB85RS4MT FRAM; added sleep mode
  • Loading branch information
hathach authored Jul 18, 2024
2 parents 6615844 + 87d9344 commit a9f8d19
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 116 deletions.
15 changes: 6 additions & 9 deletions .github/workflows/githubci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ on: [pull_request, push, repository_dispatch]
jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- uses: actions/checkout@v3
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Run pre-commit
uses: pre-commit/[email protected]

- uses: actions/checkout@v4
with:
repository: adafruit/ci-arduino
path: ci
Expand All @@ -22,9 +22,6 @@ jobs:
- name: test platforms
run: python3 ci/build_platform.py main_platforms

- name: clang
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .

- name: doxygen
env:
GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
Expand Down
10 changes: 10 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# SPDX-FileCopyrightText: 2020 Diego Elio Pettenò
#
# SPDX-License-Identifier: Unlicense

repos:
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v15.0.7
hooks:
- id: clang-format
types_or: [c++, c, header]
160 changes: 110 additions & 50 deletions Adafruit_FRAM_SPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,39 @@
* @section license License
*
* BSD license, all text above must be included in any redistribution
*
* History
* - FUEL4EP: Added sleep mode support
*/

#include <math.h>
#include <stdlib.h>

#include "Adafruit_FRAM_SPI.h"

/// Supported flash devices
const struct {
uint8_t manufID; ///< Manufacture ID
uint16_t prodID; ///< Product ID
uint32_t size; ///< Size in bytes
uint8_t manufID; ///< Manufacture ID
uint16_t prodID; ///< Product ID
uint32_t size; ///< Size in bytes
bool support_sleep; ///< Support sleep mode
} _supported_devices[] = {
// Sorted in numerical order
// Fujitsu
{0x04, 0x0101, 2 * 1024UL}, // MB85RS16
{0x04, 0x0302, 8 * 1024UL}, // MB85RS64V
{0x04, 0x2303, 8 * 1024UL}, // MB85RS64T
{0x04, 0x2503, 32 * 1024UL}, // MB85RS256TY
{0x04, 0x2703, 128 * 1024UL}, // MB85RS1MT
{0x04, 0x4803, 256 * 1024UL}, // MB85RS2MTA
{0x04, 0x4903, 512 * 1024UL}, // MB85RS4MT
{0x04, 0x0101, 2 * 1024UL, false}, // MB85RS16
{0x04, 0x0302, 8 * 1024UL, false}, // MB85RS64V
{0x04, 0x2303, 8 * 1024UL, true}, // MB85RS64T
{0x04, 0x2503, 32 * 1024UL, true}, // MB85RS256TY
{0x04, 0x2703, 128 * 1024UL, true}, // MB85RS1MT
{0x04, 0x4803, 256 * 1024UL, true}, // MB85RS2MTA
{0x04, 0x2803, 256 * 1024UL, true}, // MB85RS2MT
{0x04, 0x4903, 512 * 1024UL, true}, // MB85RS4MT

// Cypress
{0x7F, 0x7F7f, 32 * 1024UL}, // FM25V02
// (manu = 7F7F7F7F7F7FC2, device = 0x2200)
{0x7F, 0x7F7f, 32 * 1024UL, false}, // FM25V02
// (manu = 7F7F7F7F7F7FC2, device = 0x2200)

// Lapis
{0xAE, 0x8305, 8 * 1024UL} // MR45V064B
{0xAE, 0x8305, 8 * 1024UL, false} // MR45V064B
};

/*!
Expand All @@ -62,22 +66,25 @@ const struct {
* ManufactureID to be checked
* @param prodID
* ProductID to be checked
* @return size of device, 0 if not supported
* @return device index, -1 if not supported
*/
static uint32_t check_supported_device(uint8_t manufID, uint16_t prodID) {
for (uint8_t i = 0;
static int get_supported_idx(uint8_t manufID, uint16_t prodID) {
for (int i = 0;
i < sizeof(_supported_devices) / sizeof(_supported_devices[0]); i++) {
if (manufID == _supported_devices[i].manufID &&
prodID == _supported_devices[i].prodID)
return _supported_devices[i].size;
return i;
}

Serial.print(F("Unexpected Device: Manufacturer ID = 0x"));
Serial.print(manufID, HEX);
Serial.print(F(", Product ID = 0x"));
Serial.println(prodID, HEX);
return -1;
}

return 0;
/*!
* @brief Initialize the SPI FRAM class
*/
void Adafruit_FRAM_SPI::init(void) {
_nAddressSizeBytes = 0;
_dev_idx = -1;
}

/*!
Expand All @@ -91,10 +98,7 @@ static uint32_t check_supported_device(uint8_t manufID, uint16_t prodID) {
*/
Adafruit_FRAM_SPI::Adafruit_FRAM_SPI(int8_t cs, SPIClass *theSPI,
uint32_t freq) {
if (spi_dev) {
delete spi_dev;
}

init();
spi_dev = new Adafruit_SPIDevice(cs, freq, SPI_BITORDER_MSBFIRST, SPI_MODE0,
theSPI);
}
Expand All @@ -112,12 +116,15 @@ Adafruit_FRAM_SPI::Adafruit_FRAM_SPI(int8_t cs, SPIClass *theSPI,
*/
Adafruit_FRAM_SPI::Adafruit_FRAM_SPI(int8_t clk, int8_t miso, int8_t mosi,
int8_t cs) {
init();
spi_dev = new Adafruit_SPIDevice(cs, clk, miso, mosi, 1000000,
SPI_BITORDER_MSBFIRST, SPI_MODE0);
}

Adafruit_FRAM_SPI::~Adafruit_FRAM_SPI(void) {
if (spi_dev) {
delete spi_dev;
}

spi_dev = new Adafruit_SPIDevice(cs, clk, miso, mosi, 1000000,
SPI_BITORDER_MSBFIRST, SPI_MODE0);
}

/*!
Expand All @@ -128,8 +135,8 @@ Adafruit_FRAM_SPI::Adafruit_FRAM_SPI(int8_t clk, int8_t miso, int8_t mosi,
* @return true if successful
*/
bool Adafruit_FRAM_SPI::begin(uint8_t nAddressSizeBytes) {
(void)
nAddressSizeBytes; // not used anymore, since we will use auto-detect size
// not used anymore, since we will use auto-detect size
(void)nAddressSizeBytes;

/* Configure SPI */
if (!spi_dev->begin()) {
Expand All @@ -142,19 +149,29 @@ bool Adafruit_FRAM_SPI::begin(uint8_t nAddressSizeBytes) {
getDeviceID(&manufID, &prodID);

/* Everything seems to be properly initialised and connected */
uint32_t fram_size = check_supported_device(manufID, prodID);

Serial.print(F("FRAM Size = 0x"));
Serial.println(fram_size, HEX);
_dev_idx = get_supported_idx(manufID, prodID);

// Detect address size in bytes either 2 or 3 bytes (4 bytes is not supported)
if (fram_size > 64UL * 1024) {
setAddressSize(3);
if (_dev_idx == -1) {
Serial.print(F("Unexpected Device: Manufacturer ID = 0x"));
Serial.print(manufID, HEX);
Serial.print(F(", Product ID = 0x"));
Serial.println(prodID, HEX);
return false;
} else {
setAddressSize(2);
uint32_t fram_size = _supported_devices[_dev_idx].size;
Serial.print(F("FRAM Size = 0x"));
Serial.println(fram_size, HEX);

// Detect address size in bytes either 2 or 3 bytes (4 bytes is not
// supported)
if (fram_size > 64UL * 1024) {
setAddressSize(3);
} else {
setAddressSize(2);
}

return true;
}

return fram_size != 0;
}

/*!
Expand Down Expand Up @@ -187,10 +204,12 @@ bool Adafruit_FRAM_SPI::write8(uint32_t addr, uint8_t value) {
uint8_t i = 0;

buffer[i++] = OPCODE_WRITE;
if (_nAddressSizeBytes > 3)
if (_nAddressSizeBytes > 3) {
buffer[i++] = (uint8_t)(addr >> 24);
if (_nAddressSizeBytes > 2)
}
if (_nAddressSizeBytes > 2) {
buffer[i++] = (uint8_t)(addr >> 16);
}
buffer[i++] = (uint8_t)(addr >> 8);
buffer[i++] = (uint8_t)(addr & 0xFF);
buffer[i++] = value;
Expand All @@ -214,10 +233,12 @@ bool Adafruit_FRAM_SPI::write(uint32_t addr, const uint8_t *values,
uint8_t i = 0;

prebuf[i++] = OPCODE_WRITE;
if (_nAddressSizeBytes > 3)
if (_nAddressSizeBytes > 3) {
prebuf[i++] = (uint8_t)(addr >> 24);
if (_nAddressSizeBytes > 2)
}
if (_nAddressSizeBytes > 2) {
prebuf[i++] = (uint8_t)(addr >> 16);
}
prebuf[i++] = (uint8_t)(addr >> 8);
prebuf[i++] = (uint8_t)(addr & 0xFF);

Expand All @@ -235,10 +256,12 @@ uint8_t Adafruit_FRAM_SPI::read8(uint32_t addr) {
uint8_t i = 0;

buffer[i++] = OPCODE_READ;
if (_nAddressSizeBytes > 3)
if (_nAddressSizeBytes > 3) {
buffer[i++] = (uint8_t)(addr >> 24);
if (_nAddressSizeBytes > 2)
}
if (_nAddressSizeBytes > 2) {
buffer[i++] = (uint8_t)(addr >> 16);
}
buffer[i++] = (uint8_t)(addr >> 8);
buffer[i++] = (uint8_t)(addr & 0xFF);

Expand All @@ -262,10 +285,12 @@ bool Adafruit_FRAM_SPI::read(uint32_t addr, uint8_t *values, size_t count) {
uint8_t i = 0;

buffer[i++] = OPCODE_READ;
if (_nAddressSizeBytes > 3)
if (_nAddressSizeBytes > 3) {
buffer[i++] = (uint8_t)(addr >> 24);
if (_nAddressSizeBytes > 2)
}
if (_nAddressSizeBytes > 2) {
buffer[i++] = (uint8_t)(addr >> 16);
}
buffer[i++] = (uint8_t)(addr >> 8);
buffer[i++] = (uint8_t)(addr & 0xFF);

Expand Down Expand Up @@ -343,3 +368,38 @@ bool Adafruit_FRAM_SPI::setStatusRegister(uint8_t value) {
void Adafruit_FRAM_SPI::setAddressSize(uint8_t nAddressSize) {
_nAddressSizeBytes = nAddressSize;
}

/*!
* @brief Enters the FRAM's low power sleep mode
* @return true if successful
*/
// WARNING: this method has not yet been validated
bool Adafruit_FRAM_SPI::enterSleep(void) {
if (_dev_idx == -1 || !_supported_devices[_dev_idx].support_sleep) {
return false;
}
uint8_t cmd = OPCODE_SLEEP;
return spi_dev->write(&cmd, 1);
}

/*!
* @brief exits the FRAM's low power sleep mode
* @return true if successful
*/
// WARNING: this method has not yet been validated
bool Adafruit_FRAM_SPI::exitSleep(void) {
if (_dev_idx == -1 || !_supported_devices[_dev_idx].support_sleep) {
return false;
}

// Returning to a normal operation from the SLEEP mode is carried out after
// tREC (Max 400 μs) time from the falling edge of CS
spi_dev->beginTransactionWithAssertingCS();
delayMicroseconds(300);
// It is possible to return CS to H level before tREC time. However, it
// is prohibited to bring down CS to L level again during tREC period.
spi_dev->endTransactionWithDeassertingCS();
delayMicroseconds(100);

return true;
}
23 changes: 15 additions & 8 deletions Adafruit_FRAM_SPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*
* BSD license, all text above must be included in any redistribution
*/

#ifndef _ADAFRUIT_FRAM_SPI_H_
#define _ADAFRUIT_FRAM_SPI_H_

Expand All @@ -27,13 +28,14 @@

/** Operation Codes **/
typedef enum opcodes_e {
OPCODE_WREN = 0b0110, /* Write Enable Latch */
OPCODE_WRDI = 0b0100, /* Reset Write Enable Latch */
OPCODE_RDSR = 0b0101, /* Read Status Register */
OPCODE_WRSR = 0b0001, /* Write Status Register */
OPCODE_READ = 0b0011, /* Read Memory */
OPCODE_WRITE = 0b0010, /* Write Memory */
OPCODE_RDID = 0b10011111 /* Read Device ID */
OPCODE_WREN = 0b0110, /* Write Enable Latch */
OPCODE_WRDI = 0b0100, /* Reset Write Enable Latch */
OPCODE_RDSR = 0b0101, /* Read Status Register */
OPCODE_WRSR = 0b0001, /* Write Status Register */
OPCODE_READ = 0b0011, /* Read Memory */
OPCODE_WRITE = 0b0010, /* Write Memory */
OPCODE_RDID = 0b10011111, /* Read Device ID */
OPCODE_SLEEP = 0b10111001 /* Sleep Mode */
} opcodes_t;

/*!
Expand All @@ -45,6 +47,7 @@ class Adafruit_FRAM_SPI {
Adafruit_FRAM_SPI(int8_t cs, SPIClass *theSPI = &SPI,
uint32_t freq = 1000000);
Adafruit_FRAM_SPI(int8_t clk, int8_t miso, int8_t mosi, int8_t cs);
virtual ~Adafruit_FRAM_SPI(void);

bool begin(uint8_t nAddressSizeBytes = 2);
bool writeEnable(bool enable);
Expand All @@ -56,10 +59,14 @@ class Adafruit_FRAM_SPI {
uint8_t getStatusRegister(void);
bool setStatusRegister(uint8_t value);
void setAddressSize(uint8_t nAddressSize);
bool enterSleep(void);
bool exitSleep(void);

private:
Adafruit_SPIDevice *spi_dev = NULL;
void init(void);
Adafruit_SPIDevice *spi_dev;
uint8_t _nAddressSizeBytes;
int _dev_idx;
};

#endif
Loading

0 comments on commit a9f8d19

Please sign in to comment.