Skip to content

Commit 1ab3c1b

Browse files
committed
main: moved SPI Flash to a dedicated function
1 parent 22fa006 commit 1ab3c1b

1 file changed

Lines changed: 182 additions & 164 deletions

File tree

src/main.cpp

Lines changed: 182 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ struct arguments {
132132
int run_xvc_server(const struct arguments &args, const cable_t &cable,
133133
const jtag_pins_conf_t *pins_config);
134134

135+
#ifdef USE_LIBFTDI
136+
int spi_comm(struct arguments args, const cable_t &cable,
137+
const jtag_pins_conf_t *pins_config, target_board_t *board);
138+
#endif
139+
135140
int parse_opt(int argc, char **argv, struct arguments *args,
136141
jtag_pins_conf_t *pins_config);
137142

@@ -285,171 +290,14 @@ int main(int argc, char **argv)
285290
cable.config.status_pin = args.status_pin;
286291

287292
#ifdef USE_LIBFTDI
288-
/* FLASH direct access */
289-
if (args.spi || (board && board->mode == COMM_SPI)) {
290-
/* if no instruction from user -> select flash mode */
291-
if (args.prg_type == Device::PRG_NONE)
292-
args.prg_type = Device::WR_FLASH;
293-
294-
FtdiSpi *spi = NULL;
295-
spi_pins_conf_t spi_pins_config;
296-
if (board && !args.pin_config)
297-
spi_pins_config = board->spi_pins_config;
298-
if (args.pin_config) {
299-
printInfo("Board default pins configuration overridden");
300-
spi_pins_config.cs_pin = (1 << pins_config.tms_pin);
301-
spi_pins_config.sck_pin = (1 << pins_config.tck_pin);
302-
spi_pins_config.mosi_pin = (1 << pins_config.tdi_pin);
303-
spi_pins_config.miso_pin = (1 << pins_config.tdo_pin);
304-
spi_pins_config.holdn_pin = (1 << pins_config.ext0_pin);
305-
spi_pins_config.wpn_pin = (1 << pins_config.ext1_pin);
306-
}
307-
308-
try {
309-
spi = new FtdiSpi(cable, spi_pins_config, args.freq, args.verbose);
310-
} catch (std::exception &e) {
311-
printError("Error: Failed to claim cable");
312-
return EXIT_FAILURE;
313-
}
314-
315-
int spi_ret = EXIT_SUCCESS;
316-
317-
if (board && board->manufacturer != "none") {
318-
Device *target;
319-
if (board->manufacturer == "efinix") {
320-
#ifdef ENABLE_EFINIX_SUPPORT
321-
target = new Efinix(spi, args.bit_file, args.file_type,
322-
board->reset_pin, board->done_pin, board->oe_pin,
323-
args.verify, args.verbose);
324-
#else
325-
printError("Support for Efinix FPGAs was not enabled at compile time");
326-
return EXIT_FAILURE;
327-
#endif
328-
} else if (board->manufacturer == "lattice") {
329-
if (board->fpga_part == "ice40") {
330-
#ifdef ENABLE_ICE40_SUPPORT
331-
target = new Ice40(spi, args.bit_file, args.file_type,
332-
args.prg_type,
333-
board->reset_pin, board->done_pin, args.verify, args.verbose);
334-
#else
335-
printError("Support for ICE40 FPGAs was not enabled at compile time");
336-
return EXIT_FAILURE;
337-
#endif
338-
} else if (board->fpga_part == "ecp5") {
339-
#ifdef ENABLE_LATTICESSPI_SUPPORT
340-
target = new LatticeSSPI(spi, args.bit_file, args.file_type, args.verbose);
341-
#else
342-
printError("Support for Lattice FPGAs (SSPI mode) was not enabled at compile time");
343-
return EXIT_FAILURE;
344-
#endif
345-
} else {
346-
printError("Error (SPI mode): " + board->fpga_part +
347-
" is an unsupported/unknown Lattice Model");
348-
return EXIT_FAILURE;
349-
}
350-
} else if (board->manufacturer == "colognechip") {
351-
#ifdef ENABLE_COLOGNECHIP_SUPPORT
352-
target = new CologneChip(spi, args.bit_file, args.file_type, args.prg_type,
353-
board->reset_pin, board->done_pin, DBUS6, board->oe_pin,
354-
args.verify, args.verbose);
293+
/* ----------------------- */
294+
/* SPI FLASH direct access */
295+
/* ----------------------- */
296+
if (args.spi || (board && board->mode == COMM_SPI))
297+
return spi_comm(args, cable, &pins_config, board);
355298
#else
356-
printError("Support for Gowin FPGAs was not enabled at compile time");
357-
return EXIT_FAILURE;
358-
#endif
359-
} else {
360-
printError("Error (SPI mode): " + board->manufacturer +
361-
" is an unsupported/unknown target");
362-
return EXIT_FAILURE;
363-
}
364-
if (args.prg_type == Device::RD_FLASH) {
365-
if (args.file_size == 0) {
366-
printError("Error: 0 size for dump");
367-
} else {
368-
target->dumpFlash(args.offset, args.file_size);
369-
}
370-
} else if ((args.prg_type == Device::WR_FLASH ||
371-
args.prg_type == Device::WR_SRAM) ||
372-
!args.bit_file.empty() || !args.file_type.empty()) {
373-
if (args.detect_flash)
374-
target->detect_flash();
375-
else
376-
target->program(args.offset, args.unprotect_flash);
377-
}
378-
if (args.unprotect_flash && args.bit_file.empty())
379-
if (!target->unprotect_flash())
380-
spi_ret = EXIT_FAILURE;
381-
if (args.bulk_erase_flash && args.bit_file.empty())
382-
if (!target->bulk_erase_flash())
383-
spi_ret = EXIT_FAILURE;
384-
if (args.protect_flash)
385-
if (!target->protect_flash(args.protect_flash))
386-
spi_ret = EXIT_FAILURE;
387-
} else {
388-
RawParser *bit = NULL;
389-
if (board && board->reset_pin) {
390-
spi->gpio_set_output(board->reset_pin, true);
391-
spi->gpio_clear(board->reset_pin, true);
392-
}
393-
394-
SPIFlash flash((SPIInterface *)spi, args.unprotect_flash, args.verbose);
395-
flash.display_status_reg();
396-
397-
if (args.prg_type != Device::RD_FLASH &&
398-
(!args.bit_file.empty() || !args.file_type.empty())) {
399-
printInfo("Open file " + args.bit_file + " ", false);
400-
try {
401-
bit = new RawParser(args.bit_file, false);
402-
printSuccess("DONE");
403-
} catch (std::exception &e) {
404-
printError("FAIL");
405-
delete spi;
406-
return EXIT_FAILURE;
407-
}
408-
409-
printInfo("Parse file ", false);
410-
if (bit->parse() == EXIT_FAILURE) {
411-
printError("FAIL");
412-
delete spi;
413-
return EXIT_FAILURE;
414-
} else {
415-
printSuccess("DONE");
416-
}
417-
418-
try {
419-
flash.erase_and_prog(args.offset, bit->getData(), bit->getLength()/8);
420-
} catch (std::exception &e) {
421-
printError("FAIL: " + string(e.what()));
422-
}
423-
424-
if (args.verify)
425-
flash.verify(args.offset, bit->getData(), bit->getLength() / 8);
426-
427-
delete bit;
428-
} else if (args.prg_type == Device::RD_FLASH) {
429-
if (args.file_size == 0)
430-
printError("Error: 0 size for dump");
431-
else
432-
flash.dump(args.bit_file, args.offset, args.file_size);
433-
}
434-
435-
if (args.unprotect_flash && args.bit_file.empty())
436-
if (!flash.disable_protection())
437-
spi_ret = EXIT_FAILURE;
438-
if (args.bulk_erase_flash && args.bit_file.empty())
439-
if (!flash.bulk_erase())
440-
spi_ret = EXIT_FAILURE;
441-
if (args.protect_flash)
442-
if (!flash.enable_protection(args.protect_flash))
443-
spi_ret = EXIT_FAILURE;
444-
445-
if (board && board->reset_pin)
446-
spi->gpio_set(board->reset_pin, true);
447-
}
448-
449-
delete spi;
450-
451-
return spi_ret;
452-
}
299+
printError("SPI Flash Direct access: disabled at build time");
300+
return EXIT_FAILURE;
453301
#endif
454302

455303
/* ------------------- */
@@ -830,6 +678,176 @@ int run_xvc_server(const struct arguments &args, const cable_t &cable,
830678
}
831679
#endif
832680

681+
#ifdef USE_LIBFTDI
682+
int spi_comm(struct arguments args, const cable_t &cable,
683+
const jtag_pins_conf_t *pins_config, target_board_t *board)
684+
{
685+
/* if no instruction from user -> select flash mode */
686+
if (args.prg_type == Device::PRG_NONE)
687+
args.prg_type = Device::WR_FLASH;
688+
689+
FtdiSpi *spi = NULL;
690+
spi_pins_conf_t spi_pins_config;
691+
if (board && !args.pin_config)
692+
spi_pins_config = board->spi_pins_config;
693+
if (args.pin_config) {
694+
printInfo("Board default pins configuration overridden");
695+
spi_pins_config.cs_pin = (1 << pins_config->tms_pin);
696+
spi_pins_config.sck_pin = (1 << pins_config->tck_pin);
697+
spi_pins_config.mosi_pin = (1 << pins_config->tdi_pin);
698+
spi_pins_config.miso_pin = (1 << pins_config->tdo_pin);
699+
spi_pins_config.holdn_pin = (1 << pins_config->ext0_pin);
700+
spi_pins_config.wpn_pin = (1 << pins_config->ext1_pin);
701+
}
702+
703+
try {
704+
spi = new FtdiSpi(cable, spi_pins_config, args.freq, args.verbose);
705+
} catch (std::exception &e) {
706+
printError("Error: Failed to claim cable");
707+
return EXIT_FAILURE;
708+
}
709+
710+
int spi_ret = EXIT_SUCCESS;
711+
712+
if (board && board->manufacturer != "none") {
713+
Device *target;
714+
if (board->manufacturer == "efinix") {
715+
#ifdef ENABLE_EFINIX_SUPPORT
716+
target = new Efinix(spi, args.bit_file, args.file_type,
717+
board->reset_pin, board->done_pin, board->oe_pin,
718+
args.verify, args.verbose);
719+
#else
720+
printError("Support for Efinix FPGAs was not enabled at compile time");
721+
return EXIT_FAILURE;
722+
#endif
723+
} else if (board->manufacturer == "lattice") {
724+
if (board->fpga_part == "ice40") {
725+
#ifdef ENABLE_ICE40_SUPPORT
726+
target = new Ice40(spi, args.bit_file, args.file_type,
727+
args.prg_type,
728+
board->reset_pin, board->done_pin, args.verify, args.verbose);
729+
#else
730+
printError("Support for ICE40 FPGAs was not enabled at compile time");
731+
return EXIT_FAILURE;
732+
#endif
733+
} else if (board->fpga_part == "ecp5") {
734+
#ifdef ENABLE_LATTICESSPI_SUPPORT
735+
target = new LatticeSSPI(spi, args.bit_file, args.file_type, args.verbose);
736+
#else
737+
printError("Support for Lattice FPGAs (SSPI mode) was not enabled at compile time");
738+
return EXIT_FAILURE;
739+
#endif
740+
} else {
741+
printError("Error (SPI mode): " + board->fpga_part +
742+
" is an unsupported/unknown Lattice Model");
743+
return EXIT_FAILURE;
744+
}
745+
} else if (board->manufacturer == "colognechip") {
746+
#ifdef ENABLE_COLOGNECHIP_SUPPORT
747+
target = new CologneChip(spi, args.bit_file, args.file_type, args.prg_type,
748+
board->reset_pin, board->done_pin, DBUS6, board->oe_pin,
749+
args.verify, args.verbose);
750+
#else
751+
printError("Support for Gowin FPGAs was not enabled at compile time");
752+
return EXIT_FAILURE;
753+
#endif
754+
} else {
755+
printError("Error (SPI mode): " + board->manufacturer +
756+
" is an unsupported/unknown target");
757+
return EXIT_FAILURE;
758+
}
759+
if (args.prg_type == Device::RD_FLASH) {
760+
if (args.file_size == 0) {
761+
printError("Error: 0 size for dump");
762+
} else {
763+
target->dumpFlash(args.offset, args.file_size);
764+
}
765+
} else if ((args.prg_type == Device::WR_FLASH ||
766+
args.prg_type == Device::WR_SRAM) ||
767+
!args.bit_file.empty() || !args.file_type.empty()) {
768+
if (args.detect_flash)
769+
target->detect_flash();
770+
else
771+
target->program(args.offset, args.unprotect_flash);
772+
}
773+
if (args.unprotect_flash && args.bit_file.empty())
774+
if (!target->unprotect_flash())
775+
spi_ret = EXIT_FAILURE;
776+
if (args.bulk_erase_flash && args.bit_file.empty())
777+
if (!target->bulk_erase_flash())
778+
spi_ret = EXIT_FAILURE;
779+
if (args.protect_flash)
780+
if (!target->protect_flash(args.protect_flash))
781+
spi_ret = EXIT_FAILURE;
782+
} else {
783+
RawParser *bit = NULL;
784+
if (board && board->reset_pin) {
785+
spi->gpio_set_output(board->reset_pin, true);
786+
spi->gpio_clear(board->reset_pin, true);
787+
}
788+
789+
SPIFlash flash((SPIInterface *)spi, args.unprotect_flash, args.verbose);
790+
flash.display_status_reg();
791+
792+
if (args.prg_type != Device::RD_FLASH &&
793+
(!args.bit_file.empty() || !args.file_type.empty())) {
794+
printInfo("Open file " + args.bit_file + " ", false);
795+
try {
796+
bit = new RawParser(args.bit_file, false);
797+
printSuccess("DONE");
798+
} catch (std::exception &e) {
799+
printError("FAIL");
800+
delete spi;
801+
return EXIT_FAILURE;
802+
}
803+
804+
printInfo("Parse file ", false);
805+
if (bit->parse() == EXIT_FAILURE) {
806+
printError("FAIL");
807+
delete bit;
808+
delete spi;
809+
return EXIT_FAILURE;
810+
} else {
811+
printSuccess("DONE");
812+
}
813+
814+
try {
815+
flash.erase_and_prog(args.offset, bit->getData(), bit->getLength()/8);
816+
} catch (std::exception &e) {
817+
printError("FAIL: " + string(e.what()));
818+
}
819+
820+
if (args.verify)
821+
flash.verify(args.offset, bit->getData(), bit->getLength() / 8);
822+
823+
delete bit;
824+
} else if (args.prg_type == Device::RD_FLASH) {
825+
if (args.file_size == 0)
826+
printError("Error: 0 size for dump");
827+
else
828+
flash.dump(args.bit_file, args.offset, args.file_size);
829+
}
830+
831+
if (args.unprotect_flash && args.bit_file.empty())
832+
if (!flash.disable_protection())
833+
spi_ret = EXIT_FAILURE;
834+
if (args.bulk_erase_flash && args.bit_file.empty())
835+
if (!flash.bulk_erase())
836+
spi_ret = EXIT_FAILURE;
837+
if (args.protect_flash)
838+
if (!flash.enable_protection(args.protect_flash))
839+
spi_ret = EXIT_FAILURE;
840+
841+
if (board && board->reset_pin)
842+
spi->gpio_set(board->reset_pin, true);
843+
}
844+
845+
delete spi;
846+
847+
return spi_ret;
848+
}
849+
#endif
850+
833851
// parse double from string in engineering notation
834852
// can deal with postfixes k and m, add more when required
835853
static int parse_eng(string arg, double *dst) {

0 commit comments

Comments
 (0)