Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
389d9edc5This file is pinned to the selected release. Download the original to open it in your design tool.
// SPDX-License-Identifier: Apache-2.0
/*
* Copyright (C) 2021 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
*/
#include <iostream>
#include <vector>
#include "display.hpp"
#include "flashInterface.hpp"
#include "spiFlash.hpp"
FlashInterface::FlashInterface():_spif_verbose(0), _spif_rd_burst(0),
_spif_verify(false), _skip_load_bridge(false)
{}
FlashInterface::FlashInterface(const std::string &filename, int8_t verbose,
uint32_t rd_burst, bool verify, bool skip_load_bridge,
bool skip_reset):
_spif_verbose(verbose), _spif_rd_burst(rd_burst),
_spif_verify(verify), _skip_load_bridge(skip_load_bridge),
_skip_reset(skip_reset), _spif_filename(filename)
{}
/* spiFlash generic acces */
bool FlashInterface::detect_flash()
{
bool ret = true;
printInfo("Detect flash:");
/* move device to spi access */
if (!prepare_flash_access()) {
printError("Fail");
return false;
}
/* spi flash access */
try {
// instanciate call (display flash ID is automatic)
SPIFlash flash(this, false, _spif_verbose);
// display status register
flash.display_status_reg();
printSuccess("Done");
} catch (std::exception &e) {
printError("Fail");
printError(e.what());
ret = false;
}
/* reload bitstream */
return post_flash_access() && ret;
}
bool FlashInterface::protect_flash(uint32_t len)
{
bool ret = true;
printInfo("protect_flash:");
/* move device to spi access */
if (!prepare_flash_access()) {
printError("Fail");
return false;
}
/* spi flash access */
try {
SPIFlash flash(this, false, _spif_verbose);
/* configure flash protection */
ret = (flash.enable_protection(len) == 0);
if (!ret)
printError("Fail");
else
printSuccess("Done");
} catch (std::exception &e) {
printError("Fail");
printError(e.what());
ret = false;
}
/* reload bitstream */
return post_flash_access() && ret;
}
bool FlashInterface::unprotect_flash()
{
bool ret = true;
/* move device to spi access */
if (!prepare_flash_access()) {
printError("SPI Flash prepare access failed");
return false;
}
/* spi flash access */
try {
SPIFlash flash(this, false, _spif_verbose);
/* configure flash protection */
printInfo("unprotect_flash:");
ret = (flash.disable_protection() == 0);
if (!ret)
printError("Fail");
else
printSuccess("Done");
} catch (std::exception &e) {
printError("SPI Flash access failed: ", false);
printError(e.what());
ret = false;
}
/* reload bitstream */
return post_flash_access() && ret;
}
bool FlashInterface::set_quad_bit(bool set_quad)
{
bool ret = true;
/* move device to spi access */
if (!prepare_flash_access()) {
printError("SPI Flash prepare access failed");
return false;
}
/* spi flash access */
try {
SPIFlash flash(this, false, _spif_verbose);
/* configure flash protection */
printInfo("set_quad_bit:");
ret = flash.set_quad_bit(set_quad);
if (!ret)
printError("Fail");
else
printSuccess("Done");
} catch (std::exception &e) {
printError("SPI Flash access failed: ", false);
printError(e.what());
ret = false;
}
/* reload bitstream */
return post_flash_access() && ret;
}
bool FlashInterface::bulk_erase_flash()
{
bool ret = true;
printInfo("bulk_erase:");
/* move device to spi access */
if (!prepare_flash_access()) {
printError("Fail");
return false;
}
/* spi flash access */
try {
SPIFlash flash(this, false, _spif_verbose);
/* bulk erase flash */
ret = (flash.bulk_erase() == 0);
if (!ret)
printError("Fail");
else
printSuccess("Done");
} catch (std::exception &e) {
printError("Fail");
printError(e.what());
ret = false;
}
/* reload bitstream */
return post_flash_access() && ret;
}
bool FlashInterface::write(const std::vector<FlashDataSection>§ions,
bool unprotect_flash, bool full_erase)
{
bool ret = true;
if (!prepare_flash_access())
return false;
/* test SPI */
try {
SPIFlash flash(this, unprotect_flash, _spif_verbose);
flash.read_status_reg();
if (!flash.erase_and_prog(sections, full_erase))
ret = false;
if (_spif_verify && ret)
printInfo("Verify not supported in this mode");
//ret = flash.verify(offset, data, len, _spif_rd_burst);
} catch (std::exception &e) {
printError(e.what());
ret = false;
}
bool ret2 = post_flash_access();
return ret && ret2;
}
bool FlashInterface::write(uint32_t offset, const uint8_t *data, uint32_t len,
bool unprotect_flash)
{
bool ret = true;
if (!prepare_flash_access())
return false;
/* test SPI */
try {
SPIFlash flash(this, unprotect_flash, _spif_verbose);
restore_flash_access_frequency();
flash.read_status_reg();
if (flash.erase_and_prog(offset, data, len) == -1)
ret = false;
if (_spif_verify && ret)
ret = flash.verify(offset, data, len, _spif_rd_burst);
} catch (std::exception &e) {
printError(e.what());
ret = false;
}
bool ret2 = post_flash_access();
return ret && ret2;
}
bool FlashInterface::read(uint8_t *data, uint32_t base_addr, uint32_t len)
{
bool ret = true;
/* enable SPI flash access */
if (!prepare_flash_access())
return false;
try {
SPIFlash flash(this, false, _spif_verbose);
ret = flash.read(base_addr, data, len);
} catch (std::exception &e) {
printError(e.what());
ret = false;
}
/* reload bitstream */
return post_flash_access() && ret == 0;
}
bool FlashInterface::dump(uint32_t base_addr, uint32_t len)
{
bool ret = true;
/* enable SPI flash access */
if (!prepare_flash_access())
return false;
try {
SPIFlash flash(this, false, _spif_verbose);
ret = flash.dump(_spif_filename, base_addr, len, _spif_rd_burst);
} catch (std::exception &e) {
printError(e.what());
ret = false;
}
/* reload bitstream */
return post_flash_access() && ret;
}