openFPGALoader/src/gowin.hpp

149 lines
4.8 KiB
C++
Raw Normal View History

2021-06-26 15:24:07 +02:00
// SPDX-License-Identifier: Apache-2.0
2019-12-06 07:27:08 +01:00
/*
* Copyright (C) 2019 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
*/
2023-09-01 19:24:33 +02:00
#ifndef SRC_GOWIN_HPP_
#define SRC_GOWIN_HPP_
2019-12-06 07:27:08 +01:00
#include <stdint.h>
#include <iostream>
#include <string>
#include <vector>
#include <memory>
2019-12-06 07:27:08 +01:00
#include "configBitstreamParser.hpp"
2023-09-01 19:24:33 +02:00
#include "device.hpp"
#include "jtag.hpp"
2023-11-19 13:29:15 +01:00
#include "jtagInterface.hpp"
#include "spiInterface.hpp"
2019-12-06 07:27:08 +01:00
class Gowin: public Device, SPIInterface {
2019-12-06 07:27:08 +01:00
public:
2023-09-01 19:24:33 +02:00
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);
2023-08-10 12:50:26 +02:00
uint32_t idCode() override;
2020-01-15 09:49:09 +01:00
void reset() override;
void program(unsigned int offset, bool unprotect_flash) override;
bool connectJtagToMCU() override;
2019-12-06 07:27:08 +01:00
/* spi interface */
bool detect_flash() override {
if (is_gw5a || is_gw2a)
return SPIInterface::detect_flash();
printError("detect flash not supported"); return false;}
2023-09-01 19:24:33 +02:00
bool protect_flash(uint32_t len) override {
(void) len;
printError("protect flash not supported"); return false;}
2023-09-01 19:24:33 +02:00
bool unprotect_flash() override {
2023-11-19 13:29:15 +01:00
if (is_gw5a)
return SPIInterface::unprotect_flash();
printError("unprotect flash not supported"); return false;}
2023-09-01 19:24:33 +02:00
bool bulk_erase_flash() override {
if (is_gw5a || is_gw2a)
2023-11-19 13:29:15 +01:00
return SPIInterface::bulk_erase_flash();
printError("bulk erase flash not supported"); return false;}
2023-11-19 13:29:15 +01:00
bool dumpFlash(uint32_t base_addr, uint32_t len) override;
2023-08-08 15:54:27 +02:00
int spi_put(uint8_t cmd, const uint8_t *tx, uint8_t *rx,
uint32_t len) override;
2023-08-08 15:54:27 +02:00
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;
2023-11-19 13:29:15 +01:00
/* ---------------- */
/* 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;
2019-12-06 07:27:08 +01:00
private:
2023-11-19 10:18:45 +01:00
bool detectFamily();
2023-09-01 19:24:33 +02:00
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();
2019-12-06 07:27:08 +01:00
bool pollFlag(uint32_t mask, uint32_t value);
bool eraseSRAM();
bool eraseFLASH();
2023-09-01 19:24:33 +02:00
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);
void displayReadReg(const char *, uint32_t dev);
2019-12-06 07:27:08 +01:00
uint32_t readStatusReg();
uint32_t readUserCode();
/*!
* \brief compare usercode register with fs checksum and/or
* .fs usercode field
*/
void checkCRC();
2023-11-19 13:29:15 +01:00
/* ---------------- */
/* 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;
2023-11-19 10:18:45 +01:00
uint32_t _idcode;
bool is_gw1n1;
2022-09-06 21:24:40 +02:00
bool is_gw2a;
2023-09-01 19:24:33 +02:00
bool is_gw1n4;
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 */
2023-11-19 13:29:15 +01:00
JtagInterface::tck_edge_t _prev_rd_edge; /**< default probe rd edge cfg */
JtagInterface::tck_edge_t _prev_wr_edge; /**< default probe wr edge cfg */
2019-12-06 07:27:08 +01:00
};
2023-09-01 19:24:33 +02:00
#endif // SRC_GOWIN_HPP_