Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
676e53ec7This 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) 2019 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
*/
#ifndef SRC_GOWIN_HPP_
#define SRC_GOWIN_HPP_
#include <stdint.h>
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include "configBitstreamParser.hpp"
#include "device.hpp"
#include "jtag.hpp"
#include "jtagInterface.hpp"
#include "flashInterface.hpp"
class Gowin: public Device, FlashInterface {
public:
Gowin(Jtag *jtag, std::string filename, const std::string &file_type,
std::string mcufw, Device::prog_type_t prg_type,
bool external_flash, bool verify, int8_t verbose,
const std::string& user_flash);
uint32_t idCode() override;
void reset() override;
void program(unsigned int offset, bool unprotect_flash) override;
bool connectJtagToMCU() override;
/* spi interface */
bool detect_flash() override {
if (is_gw5a || is_gw2a)
return FlashInterface::detect_flash();
printError("detect flash not supported"); return false;}
bool protect_flash(uint32_t len) override {
(void) len;
printError("protect flash not supported"); return false;}
bool unprotect_flash() override {
if (is_gw5a)
return FlashInterface::unprotect_flash();
printError("unprotect flash not supported"); return false;}
bool bulk_erase_flash() override {
if (is_gw5a || is_gw2a)
return FlashInterface::bulk_erase_flash();
printError("bulk erase flash not supported"); return false;}
bool dumpFlash(uint32_t base_addr, uint32_t len) override;
int spi_put(uint8_t cmd, const uint8_t *tx, uint8_t *rx,
uint32_t len) override;
int spi_put(const uint8_t *tx, uint8_t *rx, uint32_t len) override;
int spi_wait(uint8_t cmd, uint8_t mask, uint8_t cond,
uint32_t timeout, bool verbose) override;
/* -------------- */
/* Arora specific */
/* -------------- */
/*!
* \brief undocumented sequence required after an SPI flash failure (CRC Bit set)
*/
void gw2a_force_state();
/* ---------------- */
/* Arora V specific */
/* ---------------- */
/*!
* \brief Send cmd, followed by (optional) tx sequence and fill
* rx if not null
* \param[in] cmd: SPI command
* \param[in] rx: Byte sequence to write (may be null)
* \param[out] tx: Byte buffer when read is requested
* \param[in] len: number of Byte to read/write (0 when no read/write)
* \return 0 on success, -1 otherwise
*/
int spi_put_gw5a(const uint8_t cmd, const uint8_t *tx, uint8_t *rx,
uint32_t len);
/*!
* \brief poll on cmd register until timeout or SPI reg content match
* cond with mask
* \param[in] cmd: SPI command
* \param[in] mask: mask to apply on SPI rx
* \param[in] cond: SPI rx value value
* \param[in] timeout: number of try before fail
* \param[in] verbose: display try
* \return 0 on success, -1 otherwise
*/
int spi_wait_gw5a(uint8_t cmd, uint8_t mask, uint8_t cond,
uint32_t timeout, bool verbose);
protected:
/*!
* \brief prepare SPI flash access
*/
bool prepare_flash_access() override;
/*!
* \brief end of SPI flash access
*/
bool post_flash_access() override;
private:
bool detectFamily();
bool send_command(uint8_t cmd);
void spi_gowin_write(const uint8_t *wr, uint8_t *rd, unsigned len);
uint32_t readReg32(uint8_t cmd);
void sendClkUs(unsigned us);
bool enableCfg();
bool disableCfg();
bool pollFlag(uint32_t mask, uint32_t value);
bool eraseSRAM();
bool eraseFLASH();
void programFlash();
void programExtFlash(unsigned int offset, bool unprotect_flash);
void programSRAM();
bool writeSRAM(const uint8_t *data, int length);
bool writeFLASH(uint32_t page, const uint8_t *data, int length, bool invert_bits = false);
void displayReadReg(const char *, uint32_t dev);
uint32_t readStatusReg();
uint32_t readUserCode();
/*!
* \brief compare usercode register with fs checksum and/or
* .fs usercode field
*/
void checkCRC();
/* ---------------- */
/* Arora V specific */
/* ---------------- */
/*!
* \brief Send the sequence to pass GW5A to SPI mode.
* \return true on success, false otherwise
*/
bool gw5a_disable_spi();
/*!
* \brief Send the sequence to disable SPI mode for GW5A.
* \return true on success, false otherwise
*/
bool gw5a_enable_spi();
std::unique_ptr<ConfigBitstreamParser> _fs;
std::unique_ptr<ConfigBitstreamParser> _mcufw;
std::unique_ptr<ConfigBitstreamParser> _userflash;
uint32_t _idcode;
bool is_gw1n1;
bool is_gw1n4;
bool is_gw1n9;
bool is_gw2a;
bool is_gw5a;
bool skip_checksum; /**< bypass checksum verification (GW2A) */
bool _external_flash; /**< select between int or ext flash */
uint8_t _spi_sck; /**< clk signal offset in bscan SPI */
uint8_t _spi_cs; /**< cs signal offset in bscan SPI */
uint8_t _spi_di; /**< di signal (mosi) offset in bscan SPI */
uint8_t _spi_do; /**< do signal (miso) offset in bscan SPI */
uint8_t _spi_msk; /** default spi msk with only do out */
JtagInterface::tck_edge_t _prev_rd_edge; /**< default probe rd edge cfg */
JtagInterface::tck_edge_t _prev_wr_edge; /**< default probe wr edge cfg */
};
#endif // SRC_GOWIN_HPP_