add support for ice40 FPGA and iCEBreaker, icestick, iCE40-HX8K, iCE40-HX1K-EVN boards
This commit is contained in:
parent
66ecf3e5c0
commit
14c5b8e681
|
|
@ -46,6 +46,7 @@ set(OPENFPGALOADER_SOURCE
|
|||
src/dirtyJtag.cpp
|
||||
src/efinix.cpp
|
||||
src/efinixHexParser.cpp
|
||||
src/ice40.cpp
|
||||
src/spiFlash.cpp
|
||||
src/rawParser.cpp
|
||||
src/usbBlaster.cpp
|
||||
|
|
@ -81,6 +82,7 @@ set(OPENFPGALOADER_HEADERS
|
|||
src/dirtyJtag.hpp
|
||||
src/efinix.hpp
|
||||
src/efinixHexParser.hpp
|
||||
src/ice40.cpp
|
||||
src/progressBar.hpp
|
||||
src/rawParser.hpp
|
||||
src/usbBlaster.hpp
|
||||
|
|
|
|||
32
README.md
32
README.md
|
|
@ -9,11 +9,15 @@ __Current support kits:__
|
|||
* [Digilent Arty S7 xc7s50](https://reference.digilentinc.com/reference/programmable-logic/arty-s7/start) (memory and spi flash)
|
||||
* [Digilent Nexys Video xc7a200t](https://reference.digilentinc.com/reference/programmable-logic/nexys-video/start) (memory and spi flash)
|
||||
* [Fireant Trion T8](https://www.crowdsupply.com/jungle-elec/fireant) (spi flash active mode)
|
||||
* [iCEBreaker](https://1bitsquared.com/collections/fpga/products/icebreaker)
|
||||
* [icestick](https://www.latticesemi.com/icestick)
|
||||
* [iCE40-HX8K](https://www.latticesemi.com/Products/DevelopmentBoardsAndKits/iCE40HX8KBreakoutBoard.aspx)
|
||||
* [Lattice MachXO2 Breakout Board Evaluation Kit (LCMXO2-7000HE)](https://www.latticesemi.com/products/developmentboardsandkits/machxo2breakoutboard) (memory and flash)
|
||||
* Lattice MachXO3LF Starter Kit LCMX03LF-6900C (memory and flash)
|
||||
* [Lattice MachXO3D Development Board (LCMXO3D-9400HC)](https://www.latticesemi.com/products/developmentboardsandkits/machxo3d_development_board)
|
||||
* [Lattice CrossLink-NX Evaluation Board (LIFCL-40-EVN)](https://www.latticesemi.com/en/Products/DevelopmentBoardsAndKits/CrossLink-NXEvaluationBoard) (memory and spi flash)
|
||||
* [Lattice ECP5 5G Evaluation Board (LFE5UM5G-85F-EVN)](https://www.latticesemi.com/en/Products/DevelopmentBoardsAndKits/ECP5EvaluationBoard) (memory and spi flash)
|
||||
* [Olimex iCE40HX1K-EVB](https://www.olimex.com/Products/FPGA/iCE40/iCE40HX1K-EVB/open-source-hardware)
|
||||
* [QMTech CycloneV Core Board](https://fr.aliexpress.com/i/1000006622149.html) (memory)
|
||||
* [Trenz Gowin LittleBee (TEC0117)](https://shop.trenz-electronic.de/en/TEC0117-01-FPGA-Module-with-GOWIN-LittleBee-and-8-MByte-internal-SDRAM)
|
||||
* [Saanlima Pipistrello LX45](http://pipistrello.saanlima.com/index.php?title=Welcome_to_Pipistrello) (memory)
|
||||
|
|
@ -28,6 +32,7 @@ __Supported (tested) FPGA:__
|
|||
* Anlogic [EG4S20](http://www.anlogic.com/prod_view.aspx?TypeId=10&Id=168&FId=t3:10:3) (SRAM and Flash)
|
||||
* Efinix [Trion T8](https://www.efinixinc.com/products-trion.html) (active mode)
|
||||
* Gowin [GW1N (GW1N-1, GW1N-4, GW1NR-9)](https://www.gowinsemi.com/en/product/detail/2/) (SRAM and Flash)
|
||||
* Lattice [iCE40 (HX1K,HX8K, UP5K)](https://www.latticesemi.com/en/Products/FPGAandCPLD/iCE40)
|
||||
* Lattice [MachXO2](https://www.latticesemi.com/en/Products/FPGAandCPLD/MachXO2) (SRAM and Flash)
|
||||
* Lattice [MachXO3LF](http://www.latticesemi.com/en/Products/FPGAandCPLD/MachXO3.aspx) (SRAM and Flash)
|
||||
* Lattice [MachXO3D](http://www.latticesemi.com/en/Products/FPGAandCPLD/MachXO3D.aspx) (SRAM and Flash)
|
||||
|
|
@ -442,4 +447,29 @@ __hex file load__
|
|||
openFPGALoader -b fireant /somewhere/project/outflow/*.hex
|
||||
```
|
||||
|
||||
Since openFPGALoader access the flash directly in SPI mode the *-b fireant* is required (no autodetection possible)
|
||||
Since openFPGALoader access the flash directly in SPI mode the *-b fireant* is required (no autodetection possible)
|
||||
|
||||
### ice40 boards (icestick, iCE40-HX8K, iCEBreaker, iCE40HX1K-EVB)
|
||||
|
||||
*.bin* is the default format generated by *nextpnr*, so nothing special
|
||||
must be done.
|
||||
|
||||
Since most ice40 boards uses the same pinout between *FTDI* and *SPI flash* a generic *ice40_generic* board is provided.
|
||||
|
||||
For the specific case of the *iCE40HX1K-EVB* where no onboard programmer is present, please use this:
|
||||
|
||||
| FTDI | iCE40HX1K-EVB (PGM1) |
|
||||
|--------------|----------------------|
|
||||
| SCK (ADBUS0) | Pin 9 |
|
||||
| SI (ADBUS1) | Pin 7 |
|
||||
| SO (ADBUS2) | Pin 8 |
|
||||
| CS (ABDUS4) | Pin 10 |
|
||||
| RST (ADBUS6 | Pin 6 |
|
||||
| DONE (ADBUS7)| Pin 5 |
|
||||
|
||||
__bin file load__
|
||||
```bash
|
||||
openFPGALoader -b ice40_generic /somewhere/*.bin
|
||||
```
|
||||
|
||||
Since it's a direct access to the flash (SPI) the *-b* option is required.
|
||||
|
|
@ -93,6 +93,11 @@ static std::map <std::string, target_cable_t> board_list = {
|
|||
JTAG_BOARD("ecp5_evn", "ft2232", 0, 0),
|
||||
SPI_BOARD("fireant", "efinix", "ft232",
|
||||
DBUS4, DBUS5, DBUS3, DBUS0, DBUS1, DBUS2, DBUS6, 0),
|
||||
/* most ice40 boards uses the same pinout */
|
||||
SPI_BOARD("ice40_generic", "lattice", "ft2232",
|
||||
DBUS7, DBUS6,
|
||||
DBUS4, DBUS0, DBUS1, DBUS2,
|
||||
0, 0),
|
||||
JTAG_BOARD("machXO2EVN", "ft2232", 0, 0),
|
||||
JTAG_BOARD("machXO3SK", "ft2232", 0, 0),
|
||||
JTAG_BOARD("machXO3EVN", "ft2232", 0, 0),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ice40.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "display.hpp"
|
||||
#include "ftdispi.hpp"
|
||||
#include "device.hpp"
|
||||
#include "rawParser.hpp"
|
||||
#include "spiFlash.hpp"
|
||||
|
||||
Ice40::Ice40(FtdiSpi* spi, const std::string &filename,
|
||||
uint16_t rst_pin, uint16_t done_pin,
|
||||
bool verbose):
|
||||
Device(NULL, filename, verbose), _rst_pin(rst_pin),
|
||||
_done_pin(done_pin)
|
||||
{
|
||||
_spi = spi;
|
||||
_spi->gpio_set_input(_done_pin);
|
||||
_spi->gpio_set_output(_rst_pin);
|
||||
}
|
||||
|
||||
Ice40::~Ice40()
|
||||
{}
|
||||
|
||||
void Ice40::reset()
|
||||
{
|
||||
uint32_t timeout = 1000;
|
||||
_spi->gpio_clear(_rst_pin);
|
||||
usleep(1000);
|
||||
_spi->gpio_set(_rst_pin);
|
||||
printInfo("Reset ", false);
|
||||
do {
|
||||
timeout--;
|
||||
usleep(12000);
|
||||
} while (((_spi->gpio_get(true) & _done_pin) == 0) || timeout > 0);
|
||||
if (timeout == 0)
|
||||
printError("FAIL");
|
||||
else
|
||||
printSuccess("DONE");
|
||||
}
|
||||
|
||||
void Ice40::program(unsigned int offset)
|
||||
{
|
||||
uint32_t timeout = 1000;
|
||||
|
||||
if (_filename == "")
|
||||
return;
|
||||
|
||||
RawParser bit(_filename, false);
|
||||
|
||||
printInfo("Parse file ", false);
|
||||
if (bit.parse() == EXIT_SUCCESS) {
|
||||
printSuccess("DONE");
|
||||
} else {
|
||||
printError("FAIL");
|
||||
return;
|
||||
}
|
||||
|
||||
_spi->gpio_clear(_rst_pin);
|
||||
|
||||
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), _verbose);
|
||||
flash.reset();
|
||||
flash.power_up();
|
||||
|
||||
printf("%02x\n", flash.read_status_reg());
|
||||
flash.read_id();
|
||||
flash.erase_and_prog(offset, bit.getData(), bit.getLength() / 8);
|
||||
|
||||
_spi->gpio_set(_rst_pin);
|
||||
usleep(12000);
|
||||
|
||||
printInfo("Wait for CDONE ", false);
|
||||
do {
|
||||
timeout--;
|
||||
usleep(12000);
|
||||
} while (((_spi->gpio_get(true) & _done_pin) == 0) && timeout > 0);
|
||||
if (timeout == 0)
|
||||
printError("FAIL");
|
||||
else
|
||||
printSuccess("DONE");
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SRC_ICE40_HPP_
|
||||
#define SRC_ICE40_HPP_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "device.hpp"
|
||||
#include "ftdispi.hpp"
|
||||
|
||||
class Ice40: public Device {
|
||||
public:
|
||||
Ice40(FtdiSpi *spi, const std::string &filename,
|
||||
uint16_t rst_pin, uint16_t done_pin,
|
||||
bool verbose);
|
||||
~Ice40();
|
||||
|
||||
void program(unsigned int offset = 0) override;
|
||||
/* not supported in SPI Active mode */
|
||||
int idCode() override {return 0;}
|
||||
void reset() override;
|
||||
|
||||
private:
|
||||
FtdiSpi *_spi;
|
||||
uint16_t _rst_pin;
|
||||
uint16_t _done_pin;
|
||||
};
|
||||
|
||||
#endif // SRC_ICE40_HPP_
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
#include "efinix.hpp"
|
||||
#include "ftdispi.hpp"
|
||||
#include "gowin.hpp"
|
||||
#include "ice40.hpp"
|
||||
#include "lattice.hpp"
|
||||
#include "jtag.hpp"
|
||||
#include "part.hpp"
|
||||
|
|
@ -163,6 +164,10 @@ int main(int argc, char **argv)
|
|||
Efinix target(spi, args.bit_file, board->reset_pin, board->done_pin,
|
||||
args.verbose);
|
||||
target.program(args.offset);
|
||||
} else if (board->manufacturer == "lattice") {
|
||||
Ice40 target(spi, args.bit_file, board->reset_pin, board->done_pin,
|
||||
args.verbose);
|
||||
target.program(args.offset);
|
||||
} else {
|
||||
RawParser *bit = NULL;
|
||||
if (board->reset_pin) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue