From ba23833ad0960a57bf63194ce06175c5b169ab56 Mon Sep 17 00:00:00 2001 From: rasmuskleist Date: Thu, 3 Aug 2023 10:07:39 +0200 Subject: [PATCH] [example] Add BdSpiStackFlash test --- .../nucleo_f429zi/spistack_flash/main.cpp | 157 ++++++++++++++++++ .../nucleo_f429zi/spistack_flash/project.xml | 12 ++ 2 files changed, 169 insertions(+) create mode 100644 examples/nucleo_f429zi/spistack_flash/main.cpp create mode 100644 examples/nucleo_f429zi/spistack_flash/project.xml diff --git a/examples/nucleo_f429zi/spistack_flash/main.cpp b/examples/nucleo_f429zi/spistack_flash/main.cpp new file mode 100644 index 0000000000..82f0421cfa --- /dev/null +++ b/examples/nucleo_f429zi/spistack_flash/main.cpp @@ -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 + +#include +#include + +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; +using BdSpiStackFlash = modm::BdSpiStackFlash; + +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(); + SpiMaster::initialize(); + + 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(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; +} diff --git a/examples/nucleo_f429zi/spistack_flash/project.xml b/examples/nucleo_f429zi/spistack_flash/project.xml new file mode 100644 index 0000000000..29980df508 --- /dev/null +++ b/examples/nucleo_f429zi/spistack_flash/project.xml @@ -0,0 +1,12 @@ + + modm:nucleo-f429zi + + + + + modm:driver:block.device:spi.flash + modm:driver:block.device:spi.stack.flash + modm:platform:spi:1 + modm:build:scons + + \ No newline at end of file