@@ -132,6 +132,11 @@ struct arguments {
132132int 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+
135140int 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
835853static int parse_eng (string arg, double *dst) {
0 commit comments