Skip to content

Commit

Permalink
- rename API to enterSleep()/exitSleep()
Browse files Browse the repository at this point in the history
- check if sleep mode is supported by device
  • Loading branch information
hathach committed Jul 18, 2024
1 parent 1da3889 commit 87d9344
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 73 deletions.
13 changes: 4 additions & 9 deletions .github/workflows/githubci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,14 @@ name: Arduino Library CI
on: [pull_request, push, repository_dispatch]

jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

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

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

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

- uses: actions/checkout@v4
with:
repository: adafruit/ci-arduino
Expand Down
146 changes: 86 additions & 60 deletions Adafruit_FRAM_SPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,36 +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, 0x2803, 256 * 1024UL}, // MB85RS2MT
{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 @@ -63,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 @@ -92,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 @@ -113,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 @@ -129,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 @@ -143,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 @@ -188,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 @@ -215,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 @@ -236,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 @@ -263,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 @@ -350,11 +374,11 @@ void Adafruit_FRAM_SPI::setAddressSize(uint8_t nAddressSize) {
* @return true if successful
*/
// WARNING: this method has not yet been validated
bool Adafruit_FRAM_SPI::enter_low_power_mode(void) {
uint8_t cmd;

cmd = OPCODE_SLEEP;

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);
}

Expand All @@ -363,10 +387,12 @@ bool Adafruit_FRAM_SPI::enter_low_power_mode(void) {
* @return true if successful
*/
// WARNING: this method has not yet been validated
bool Adafruit_FRAM_SPI::exit_low_power_mode(void) {
uint8_t cmd;
bool Adafruit_FRAM_SPI::exitSleep(void) {
if (_dev_idx == -1 || !_supported_devices[_dev_idx].support_sleep) {
return false;
}

// Returning to an normal operation from the SLEEP mode is carried out after
// 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);
Expand All @@ -375,5 +401,5 @@ bool Adafruit_FRAM_SPI::exit_low_power_mode(void) {
spi_dev->endTransactionWithDeassertingCS();
delayMicroseconds(100);

return spi_dev->write(&cmd, 1);
return true;
}
11 changes: 7 additions & 4 deletions Adafruit_FRAM_SPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ typedef enum opcodes_e {
OPCODE_READ = 0b0011, /* Read Memory */
OPCODE_WRITE = 0b0010, /* Write Memory */
OPCODE_RDID = 0b10011111, /* Read Device ID */
OPCODE_SLEEP = 0b10111001 /* Sleep Mode by FUEL4EP */
OPCODE_SLEEP = 0b10111001 /* Sleep Mode */
} opcodes_t;

/*!
Expand All @@ -47,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 @@ -58,12 +59,14 @@ class Adafruit_FRAM_SPI {
uint8_t getStatusRegister(void);
bool setStatusRegister(uint8_t value);
void setAddressSize(uint8_t nAddressSize);
bool enter_low_power_mode(void); // added by FUEL4EP
bool exit_low_power_mode(void); // added by FUEL4EP
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

0 comments on commit 87d9344

Please sign in to comment.