add support for ice40 FPGA and iCEBreaker, icestick, iCE40-HX8K, iCE40-HX1K-EVN boards

This commit is contained in:
Gwenhael Goavec-Merou 2020-10-31 15:02:54 +01:00
parent 66ecf3e5c0
commit 14c5b8e681
6 changed files with 189 additions and 1 deletions

View File

@ -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

View File

@ -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.

View File

@ -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),

102
src/ice40.cpp Normal file
View File

@ -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");
}

44
src/ice40.hpp Normal file
View File

@ -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_

View File

@ -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) {