Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
f0b7215e1This 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 "spiInterface.hpp"
#include "spiFlash.hpp"
SPIInterface::SPIInterface():_spif_verbose(0), _spif_rd_burst(0),
_spif_verify(false), _skip_load_bridge(false)
{}
SPIInterface::SPIInterface(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 SPIInterface::detect_flash()
{
bool ret = true;
printInfo("protect_flash: ", false);
/* 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 SPIInterface::protect_flash(uint32_t len)
{
bool ret = true;
printInfo("protect_flash: ", false);
/* 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 SPIInterface::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: ", false);
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 SPIInterface::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: ", false);
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 SPIInterface::bulk_erase_flash()
{
bool ret = true;
printInfo("bulk_erase: ", false);
/* 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 SPIInterface::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);
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 SPIInterface::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 SPIInterface::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;
}