Skip to content

Commit 0e0bfc2

Browse files
committed
main: SPI mode: added select between ice40 and ecp5 in SSPI when manufacturer is lattice
1 parent 16b7171 commit 0e0bfc2

File tree

3 files changed

+36
-44
lines changed

3 files changed

+36
-44
lines changed

src/latticeSSPI.cpp

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@
33
* Copyright (C) 2025 Gwenhael Goavec-Merou <[email protected]>
44
*/
55

6-
#define __STDC_FORMAT_MACROS
7-
#include <iostream>
8-
#include <string>
9-
#include <cinttypes>
6+
#include "latticeSSPI.hpp"
107

118
#include <string.h>
129
#include <unistd.h>
1310

11+
#define __STDC_FORMAT_MACROS
12+
#include <cinttypes>
13+
#include <iostream>
14+
#include <string>
15+
1416
#include "device.hpp"
1517
#include "ftdispi.hpp"
1618
#include "latticeBitParser.hpp"
1719
#include "progressBar.hpp"
1820

19-
#include "latticeSSPI.hpp"
20-
2121
#define SSPI_READ_ID 0xE0
2222
#define SSPI_ISC_READ_STATUS 0x3C
2323
#define ISC_ENABLE 0xC6 /* ISC_ENABLE - Offline Mode */
@@ -46,15 +46,15 @@ LatticeSSPI::LatticeSSPI(FtdiSpi *spi, const std::string &filename,
4646
_spi->setMode(0);
4747
}
4848

49-
uint32_t LatticeSSPI::char_array_to_word(uint8_t *in)
49+
uint32_t LatticeSSPI::char_array_to_word(const uint8_t *in)
5050
{
5151
return static_cast<uint32_t>(in[0] << 24) |
5252
static_cast<uint32_t>(in[1] << 16) |
5353
static_cast<uint32_t>(in[2] << 8) |
5454
static_cast<uint32_t>(in[3] << 0);
5555
}
5656

57-
bool LatticeSSPI::EnableISC(uint8_t flash_mode)
57+
bool LatticeSSPI::EnableISC(uint8_t /*flash_mode*/)
5858
{
5959
cmd_class_c(ISC_ENABLE);
6060

@@ -82,7 +82,7 @@ uint32_t LatticeSSPI::readStatusReg()
8282

8383
cmd_class_a(SSPI_ISC_READ_STATUS, rx, 4 * 8);
8484

85-
return static_cast<uint64_t>(char_array_to_word(rx));
85+
return char_array_to_word(rx);
8686
}
8787

8888
/*
@@ -93,7 +93,7 @@ uint32_t LatticeSSPI::readStatusReg()
9393
bool LatticeSSPI::cmd_class_a(uint8_t cmd, uint8_t *rx, uint32_t len)
9494
{
9595
const uint32_t xferByteLen = (len + 7) / 8;
96-
const uint32_t kBytetLen = xferByteLen + 3; // Convert bits to bytes after adding dummy
96+
const uint32_t kBytetLen = xferByteLen + 3; // Convert bits to bytes after adding dummy
9797
uint8_t lrx[kBytetLen];
9898
uint8_t ltx[kBytetLen];
9999
memset(ltx, 0x00, kBytetLen);
@@ -105,12 +105,6 @@ bool LatticeSSPI::cmd_class_a(uint8_t cmd, uint8_t *rx, uint32_t len)
105105
return true;
106106
}
107107

108-
bool LatticeSSPI::cmd_class_b(uint8_t cmd, uint8_t *tx, uint32_t len)
109-
{
110-
throw std::runtime_error("Not implemented");
111-
return true;
112-
}
113-
114108
bool LatticeSSPI::cmd_class_c(uint8_t cmd)
115109
{
116110
const uint8_t ltx[3] = {0x00, 0x00, 0x00};
@@ -146,7 +140,7 @@ bool LatticeSSPI::pollBusyFlag(bool verbose)
146140
return true;
147141
}
148142

149-
bool LatticeSSPI::flashErase(uint32_t mask)
143+
bool LatticeSSPI::flashErase(uint32_t /*mask*/)
150144
{
151145
const uint8_t tx[] = {0x01, 0x00, 0x00};
152146
_spi->spi_put(FLASH_ERASE, tx, 0, 3);
@@ -162,13 +156,12 @@ bool LatticeSSPI::flashErase(uint32_t mask)
162156

163157
bool LatticeSSPI::program_mem()
164158
{
165-
bool err;
166159
LatticeBitParser _bit(_filename, false, _verbose);
167160

168161
printInfo("Open file: ", false);
169162
printSuccess("DONE");
170163

171-
err = _bit.parse();
164+
const bool err = _bit.parse();
172165

173166
printInfo("Parse file: ", false);
174167
if (err == EXIT_FAILURE) {
@@ -183,11 +176,11 @@ bool LatticeSSPI::program_mem()
183176

184177
/* Prepare bitstream */
185178
const uint8_t *data = _bit.getData();
186-
int length = _bit.getLength()/8;
179+
const int length = _bit.getLength() / 8;
187180

188181
/* read ID Code 0xE0 and compare to bitstream */
189-
uint32_t bit_idcode = std::stoul(_bit.getHeaderVal("idcode").c_str(), NULL, 16);
190-
uint32_t idcode = idCode();
182+
const uint32_t bit_idcode = std::stoul(_bit.getHeaderVal("idcode").c_str(), NULL, 16);
183+
const uint32_t idcode = idCode();
191184
if (idcode != bit_idcode) {
192185
char mess[256];
193186
snprintf(mess, 256, "mismatch between target's idcode and bitstream idcode\n"
@@ -224,7 +217,6 @@ bool LatticeSSPI::program_mem()
224217
* For Nexus family (from svf file): 1 byte to tx 0x00
225218
*/
226219
printInfo("SRAM erase: ", false);
227-
//uint32_t mask_erase[1] = {FLASH_ERASE_SRAM};
228220

229221
if (flashErase(0x01/*mask_erase[0]*/) == false) {
230222
printError("FAIL");
@@ -245,22 +237,17 @@ bool LatticeSSPI::program_mem()
245237
_spi->clearCs();
246238
cmd_class_c(0x7A);
247239

248-
uint8_t tmp[1024];
249240
int size = 1024;
250241

251242
ProgressBar progress("Loading", length, 50, _quiet);
252243

253244
for (int i = 0; i < length; i += size) {
254245
progress.display(i);
255246

256-
if (length < i + size) {
247+
if (length < i + size)
257248
size = length-i;
258-
}
259-
260-
for (int ii = 0; ii < size; ii++)
261-
tmp[ii] = data[i+ii];
262249

263-
_spi->spi_put(tmp, NULL, size);
250+
_spi->spi_put(&data[i], NULL, size);
264251
}
265252
progress.done();
266253
/* Switch CS to Automatic mode */
@@ -281,26 +268,24 @@ bool LatticeSSPI::program_mem()
281268

282269
if (_verbose)
283270
displayReadReg(readStatusReg());
284-
uint8_t nop[] = {0xff, 0xff, 0xff, 0xff};
271+
const uint8_t nop[] = {0xff, 0xff, 0xff, 0xff};
285272
_spi->spi_put(nop, NULL, 4);
286273

287274
return true;
288275
}
289276

290-
void LatticeSSPI::program(unsigned int offset, bool unprotect_flash)
277+
void LatticeSSPI::program(unsigned int /*offset*/, bool /*unprotect_flash*/)
291278
{
292-
bool retval = true;
293279
if (_mode == FLASH_MODE)
294280
throw std::runtime_error("Flash mode not avaible when programming in Slave SPI");
295281

296-
retval = program_mem();
282+
const bool retval = program_mem();
297283
if (!retval)
298284
throw std::exception();
299285
}
300286

301287
void LatticeSSPI::displayReadReg(uint32_t dev)
302288
{
303-
uint8_t err;
304289
printf("displayReadReg 0x%08x\n", dev);
305290
if (dev & 1<<0) printf("\tTRAN Mode\n");
306291
printf("\tConfig Target Selection : %" PRIx32 "\n", (dev >> 1) & 0x07);
@@ -323,7 +308,7 @@ void LatticeSSPI::displayReadReg(uint32_t dev)
323308
if (dev & 1 << 20) printf("\tEncryption PreAmble\n");
324309
if (dev & 1 << 21) printf("\tStd PreAmble\n");
325310
if (dev & 1 << 22) printf("\tSPIm Fail1\n");
326-
err = (dev >> 23)&0x07;
311+
const uint8_t err = (dev >> 23)&0x07;
327312

328313
printf("\tBSE Error Code\n");
329314
printf("\t\t");

src/latticeSSPI.hpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ class LatticeSSPI: public Device {
2121
void reset() override {}
2222
void program(unsigned int offset, bool unprotect_flash) override;
2323

24-
bool protect_flash(uint32_t len) override { return false; }
24+
bool protect_flash(uint32_t /*len*/) override { return false; }
2525
bool unprotect_flash() override { return false; }
2626
bool bulk_erase_flash() override { return false; }
2727

2828
private:
2929
bool program_mem();
30-
bool pollBusyFlag(bool verbose=false);
30+
bool pollBusyFlag(bool verbose = false);
3131
uint32_t readStatusReg();
3232
void displayReadReg(uint32_t dev);
3333
bool EnableISC(uint8_t flash_mode);
@@ -38,9 +38,8 @@ class LatticeSSPI: public Device {
3838
}
3939

4040
bool cmd_class_a(uint8_t cmd, uint8_t *rx, uint32_t len);
41-
bool cmd_class_b(uint8_t cmd, uint8_t *tx, uint32_t len);
4241
bool cmd_class_c(uint8_t cmd);
43-
uint32_t char_array_to_word(uint8_t *in);
42+
uint32_t char_array_to_word(const uint8_t *in);
4443
FtdiSpi *_spi;
4544
};
46-
#endif /* SRC_LATTICESSPI_HPP_ */
45+
#endif // SRC_LATTICESSPI_HPP_

src/main.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,17 @@ int main(int argc, char **argv)
285285
board->reset_pin, board->done_pin, board->oe_pin,
286286
args.verify, args.verbose);
287287
} else if (board->manufacturer == "lattice") {
288-
target = new Ice40(spi, args.bit_file, args.file_type,
289-
args.prg_type,
290-
board->reset_pin, board->done_pin, args.verify, args.verbose);
288+
if (board->fpga_part == "ice40") {
289+
target = new Ice40(spi, args.bit_file, args.file_type,
290+
args.prg_type,
291+
board->reset_pin, board->done_pin, args.verify, args.verbose);
292+
} else if (board->fpga_part == "ecp5") {
293+
target = new LatticeSSPI(spi, args.bit_file, args.file_type, args.verbose);
294+
} else {
295+
printError("Error (SPI mode): " + board->fpga_part +
296+
" is an unsupported/unknown Lattice Model");
297+
return EXIT_FAILURE;
298+
}
291299
} else if (board->manufacturer == "colognechip") {
292300
target = new CologneChip(spi, args.bit_file, args.file_type, args.prg_type,
293301
board->reset_pin, board->done_pin, DBUS6, board->oe_pin,

0 commit comments

Comments
 (0)