Skip to content

Commit

Permalink
[example] Add BdSpiStackFlash test
Browse files Browse the repository at this point in the history
  • Loading branch information
rasmuskleist committed Aug 13, 2023
1 parent a1ad2a0 commit ba23833
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 0 deletions.
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>

0 comments on commit ba23833

Please sign in to comment.