Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[driver] Adding SpiStack Flash #1054

Merged
merged 7 commits into from
Aug 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions examples/nucleo_f429zi/spi_flash/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,24 +107,24 @@ main()
std::memset(bufferB, 0x55, BlockSize);

bool initializeSuccess = false;

MODM_LOG_INFO << "Erasing complete flash chip... (This may take a while)" << modm::endl;

if(!RF_CALL_BLOCKING(storageDevice.initialize())) {
if (RF_CALL_BLOCKING(storageDevice.initialize())) {
MODM_LOG_INFO << "Erasing complete flash chip... (This may take a while)" << modm::endl;
if (RF_CALL_BLOCKING(storageDevice.erase(0, MemorySize))) {
RF_CALL_BLOCKING(storageDevice.waitWhileBusy());
initializeSuccess = true;
} else {
MODM_LOG_INFO << "Error: Unable to erase device.";
}
} else {
MODM_LOG_INFO << "Error: Unable to initialize device.";
}
else if(!RF_CALL_BLOCKING(storageDevice.erase(0, MemorySize))) {
MODM_LOG_INFO << "Error: Unable to erase device.";
}
else {

if (initializeSuccess) {
auto id = RF_CALL_BLOCKING(storageDevice.readId());
MODM_LOG_INFO << "deviceId=" << id.deviceId << " manufacturerId=" << id.manufacturerId;
MODM_LOG_INFO << " deviceType=" << id.deviceType << modm::endl;

MODM_LOG_INFO << "deviceType=" << id.deviceType << modm::endl;
MODM_LOG_INFO << "status=" << static_cast<uint8_t>(RF_CALL_BLOCKING(storageDevice.readStatus())) << modm::endl;

MODM_LOG_INFO << "Press USER button to start the memory test." << modm::endl;
initializeSuccess = true;
}

while (true)
Expand Down
157 changes: 157 additions & 0 deletions examples/nucleo_f429zi/spistack_flash/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
* Copyright (c) 2023, Rasmus Kleist Hørlyck Sørensen
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include <modm/board.hpp>

#include <modm/driver/storage/block_device_spiflash.hpp>
#include <modm/driver/storage/block_device_spistack_flash.hpp>

using namespace Board;

void printMemoryContent(const uint8_t* address, std::size_t size) {
for (std::size_t i = 0; i < size; i++) {
MODM_LOG_INFO.printf("%x", address[i]);
}
}

using SpiMaster = SpiMaster1;

// Spi flash chip wiring:
using Cs = GpioA4;
using Mosi = GpioB5;
using Miso = GpioB4;
using Sck = GpioB3;
// Connect WP and HOLD pins to +3V3
// and of course Vdd to +3V3 and Vss to GND


constexpr uint32_t BlockSize = 256;
constexpr uint32_t DieSize = 32*1024*1024;
constexpr uint32_t DieCount = 2;
constexpr uint32_t MemorySize = DieCount * DieSize;
constexpr uint32_t TestMemorySize = 4*1024;
constexpr uint32_t TestMemoryAddress[] = {0, DieSize - TestMemorySize, DieSize, MemorySize - TestMemorySize};

uint8_t bufferA[BlockSize];
uint8_t bufferB[BlockSize];
uint8_t bufferC[BlockSize];

using BdSpiFlash = modm::BdSpiFlash<SpiMaster, Cs, DieSize>;
using BdSpiStackFlash = modm::BdSpiStackFlash<BdSpiFlash, DieCount>;

BdSpiFlash storageDevice;
BdSpiStackFlash storageDeviceStack;

void doMemoryTest()
{
LedBlue::set();
MODM_LOG_INFO << "Starting memory test!" << modm::endl;

for(uint16_t iteration = 0; iteration < 4; iteration++) {

for(const uint32_t address : TestMemoryAddress) {

auto dv = std::ldiv(address, DieSize);
uint8_t* pattern = (iteration % 2 == dv.quot) ? bufferA : bufferB;
if(!RF_CALL_BLOCKING(storageDeviceStack.erase(address, TestMemorySize))) {
MODM_LOG_INFO << "Error: Unable to erase device.";
return;
}

for(uint32_t i = 0; i < TestMemorySize; i += BlockSize) {
if(!RF_CALL_BLOCKING(storageDeviceStack.program(pattern, address + i, BlockSize))) {
MODM_LOG_INFO << "Error: Unable to write data.";
return;
}
MODM_LOG_INFO << ".";
}
}

for(const uint32_t address : TestMemoryAddress) {

auto dv = std::ldiv(address, DieSize);
uint8_t* pattern = (iteration % 2 == dv.quot) ? bufferA : bufferB;
for(uint32_t i = 0; i < TestMemorySize; i += BlockSize) {
if(!RF_CALL_BLOCKING(storageDeviceStack.read(bufferC, address + i, BlockSize))) {
MODM_LOG_INFO << "Error: Unable to read data.";
return;
}
else if(std::memcmp(pattern, bufferC, BlockSize)) {
MODM_LOG_INFO << "i=" << i << modm::endl;
MODM_LOG_INFO << "Error: Read '";
printMemoryContent(bufferC, BlockSize);
MODM_LOG_INFO << "', expected: '";
printMemoryContent(pattern, BlockSize);
MODM_LOG_INFO << "'." << modm::endl;
return;
}
}
}

MODM_LOG_INFO << "." << modm::endl;
}

MODM_LOG_INFO << modm::endl << "Finished!" << modm::endl;
LedBlue::reset();
}

int
main()
{
/**
* This example/test writes alternating patterns to a 256 MBit
* stacked die flash chip (W25M512VJ) attached to SPI0 using the
* `modm::BdSpiStackFlash` block device interface.
* The memory content is afterwards read and compared
* to the pattern.
* Write and read operations are done on 64 byte blocks.
*
* See above for how to wire the flash chip.
*/

// initialize board and SPI
Board::initialize();
SpiMaster::connect<Mosi::Mosi, Miso::Miso, Sck::Sck>();
SpiMaster::initialize<Board::SystemClock, 11_MHz>();

std::memset(bufferA, 0xAA, BlockSize);
std::memset(bufferB, 0x55, BlockSize);

bool initializeSuccess = false;
if (RF_CALL_BLOCKING(storageDeviceStack.initialize())) {
MODM_LOG_INFO << "Erasing complete flash chip... (This may take a while)" << modm::endl;
if (RF_CALL_BLOCKING(storageDeviceStack.erase(0, MemorySize))) {
RF_CALL_BLOCKING(storageDeviceStack.waitWhileBusy());
initializeSuccess = true;
} else {
MODM_LOG_INFO << "Error: Unable to erase device.";
}
} else {
MODM_LOG_INFO << "Error: Unable to initialize device.";
}

if (initializeSuccess) {
auto id = RF_CALL_BLOCKING(storageDevice.readId());
MODM_LOG_INFO << "deviceId=" << id.deviceId << " manufacturerId=" << id.manufacturerId;
MODM_LOG_INFO << "deviceType=" << id.deviceType << modm::endl;
MODM_LOG_INFO << "status=" << static_cast<uint8_t>(RF_CALL_BLOCKING(storageDevice.readStatus())) << modm::endl;
MODM_LOG_INFO << "Press USER button to start the memory test." << modm::endl;
}

while (true)
{
if(initializeSuccess && Button::read())
{
doMemoryTest();
}
}

return 0;
}
12 changes: 12 additions & 0 deletions examples/nucleo_f429zi/spistack_flash/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<library>
<extends>modm:nucleo-f429zi</extends>
<options>
<option name="modm:build:build.path">../../../build/nucleo_f429zi/spistack_flash</option>
</options>
<modules>
<module>modm:driver:block.device:spi.flash</module>
<module>modm:driver:block.device:spi.stack.flash</module>
<module>modm:platform:spi:1</module>
<module>modm:build:scons</module>
</modules>
</library>
16 changes: 16 additions & 0 deletions src/modm/driver/storage/block_device.lb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,21 @@ Microchip SST26VF064B 64MBit flash chip in SOIJ-8, WDFN-8 or SOIC-16.
env.copy("block_device_spiflash_impl.hpp")
# -----------------------------------------------------------------------------

class BlockDeviceSpiStackFlash(Module):
def init(self, module):
module.name = "spi.stack.flash"
module.description = "SpiStack homogeneous flash memory"

def prepare(self, module, options):
module.depends(":architecture:block.device")
return True

def build(self, env):
env.outbasepath = "modm/src/modm/driver/storage"
env.copy("block_device_spistack_flash.hpp")
env.copy("block_device_spistack_flash_impl.hpp")
# -----------------------------------------------------------------------------

def init(module):
module.name = ":driver:block.device"
module.description = "Block Devices"
Expand All @@ -80,6 +95,7 @@ def prepare(module, options):
module.add_submodule(BlockDeviceHeap())
module.add_submodule(BlockDeviceMirror())
module.add_submodule(BlockDeviceSpiFlash())
module.add_submodule(BlockDeviceSpiStackFlash())
return True

def build(env):
Expand Down
Loading