@@ -361,26 +361,60 @@ void Altera::max10_program()
361361 * Single Uncompressed Image with Memory Initialization (256Kbits UFM):
362362 * set_global_assignment -name INTERNAL_FLASH_UPDATE_MODE "SINGLE IMAGE WITH ERAM"
363363 */
364- const uint8_t *cfm_data = _bit.getData (" CFM0" );
365- const uint8_t *ufm_data = _bit.getData (" UFM" );
366- const uint8_t *dsm_data = _bit.getData (" ICB" );
364+ uint8_t *cfm0_data = _bit.getData (" CFM0" );
365+ uint8_t *cfm1_data = _bit.getData (" CFM1" );
366+ uint8_t *cfm2_data = _bit.getData (" CFM2" );
367+ uint8_t *ufm_data = _bit.getData (" UFM" );
368+ uint8_t *dsm_data = _bit.getData (" ICB" );
367369 const int dsm_len = _bit.getLength (" ICB" ) / 32 ; // getLength (bits) dsm_len in 32bits word
370+ // cfm0 len is required to deduces mode
371+ const uint32_t cfm0_len = _bit.getLength (" CFM0" ) / 8 ;
372+ // full configuration section is required
373+ const uint32_t cfm_len = (mem.cfm_len [0 ] + mem.cfm_len [1 ] + mem.cfm_len [2 ]) * 4 ;
374+
375+ /* we needs to know how many sections are present in the POF file */
376+ const bool cfm1_null = cfm1_data == NULL ;
377+ const bool cfm2_null = cfm2_data == NULL ;
378+
379+ /* Reorganize CFM sections */
380+ if (cfm2_null && cfm1_null) { // POF contains only CFM0 section (mode 2, 3, 4 or 5)
381+ // CFM0 contains CFM2+CFM1+CFM0 (in this order) (mode 3 or 4)
382+ if (cfm0_len == cfm_len) {
383+ cfm2_data = cfm0_data;
384+ cfm1_data = &cfm2_data[mem.cfm_len [2 ] * 4 ];
385+ cfm0_data = &cfm1_data[mem.cfm_len [1 ] * 4 ];
386+ } else { // CFM2 or CMF2+CFM1 used for UFM
387+ // Single Uncompressed Image (CFM1 + CFM0) (mode 2)
388+ if (cfm0_len == cfm_len - (mem.cfm_len [2 ] * 4 )) {
389+ cfm1_data = cfm0_data;
390+ cfm0_data = &cfm1_data[mem.cfm_len [1 ] * 4 ];
391+ // Single Compressed image (CFM0) (mode 5)
392+ // CFM0 contains CFM0...
393+ } else if (cfm0_len == (mem.cfm_len [0 ] * 4 )) {
394+ // nothing to do CFM0 == CFM0, no CFM1/CFM2
395+ // unknown mode
396+ } else {
397+ throw std::runtime_error (" Unknown mode" );
398+ }
399+ }
400+ } else if (cfm2_null) { // POF with CFM0 & CFM1 (mode 1 only)
401+ // CFM0 == CFM0 (nothing to change)
402+ // CFM1 contains CFM2 + CFM1 in this order
403+ cfm2_data = cfm1_data;
404+ cfm1_data = &cfm2_data[mem.cfm_len [2 ] * 4 ];
405+ } else {
406+ throw std::runtime_error (" Error: can't be happens" );
407+ }
408+
368409
369410 max_10_flow_enable ();
370411
371412 max10_flow_erase ();
372413 max10_dsm_verify ();
373414
374415 /* Write */
375- // CFM2->0
376- offset = 0 ;
377- base_addr = mem.cfm_addr ;
378- for (int i = 2 ; i >= 0 ; i--) {
379- printInfo (" Write CFM" + std::to_string (i));
380- writeXFM (cfm_data, base_addr, offset, mem.cfm_len [i]);
381- base_addr += mem.cfm_len [i];
382- offset += (mem.cfm_len [i] * 4 );
383- }
416+ uint8_t *cfm_d;
417+
384418 // UFM1->0
385419 offset = 0 ;
386420 base_addr = mem.ufm_addr ;
@@ -391,18 +425,30 @@ void Altera::max10_program()
391425 base_addr += mem.ufm_len [i];
392426 }
393427
394- /* Verify */
395- if (_verify) {
396- // CFM2->0
397- offset = 0 ;
398- base_addr = mem.cfm_addr ;
399- for (int i = 2 ; i >= 0 ; i--) {
400- printInfo (" Verify CFM" + std::to_string (i));
401- verifyxFM (cfm_data, base_addr, offset, mem.cfm_len [i]);
402- base_addr += mem.cfm_len [i];
403- offset += (mem.cfm_len [i] * 4 );
428+ // CFM2->0
429+ for (int i = 2 ; i >= 0 ; i--) {
430+ switch (i) {
431+ case 0 : // just after CFM1
432+ cfm_d = cfm0_data;
433+ base_addr = mem.cfm_addr + mem.cfm_len [2 ] + mem.cfm_len [1 ];
434+ break ;
435+ case 1 : // just after CFM2
436+ cfm_d = cfm1_data;
437+ base_addr = mem.cfm_addr + mem.cfm_len [2 ];
438+ break ;
439+ case 2 : // beginning of the Configuration Flash Memory Sectors
440+ cfm_d = cfm2_data;
441+ base_addr = mem.cfm_addr ;
442+ break ;
443+ }
444+ if (cfm_d) {
445+ printInfo (" Write CFM" + std::to_string (i));
446+ writeXFM (cfm_d, base_addr, 0 , mem.cfm_len [i]);
404447 }
448+ }
405449
450+ /* Verify */
451+ if (_verify) {
406452 // UFM1->0
407453 offset = 0 ;
408454 base_addr = mem.ufm_addr ;
@@ -412,6 +458,32 @@ void Altera::max10_program()
412458 offset += mem.ufm_len [i] * 4 ;
413459 base_addr += mem.ufm_len [i];
414460 }
461+
462+ // CFM2->0
463+ for (int i = 2 ; i >= 0 ; i--) {
464+ uint8_t fake_cfm[mem.cfm_len [i] * 4 ];
465+ switch (i) {
466+ case 0 :
467+ cfm_d = cfm0_data;
468+ base_addr = mem.cfm_addr + mem.cfm_len [2 ] + mem.cfm_len [1 ];
469+ break ;
470+ case 1 :
471+ cfm_d = cfm1_data;
472+ base_addr = mem.cfm_addr + mem.cfm_len [2 ];
473+ break ;
474+ case 2 :
475+ cfm_d = cfm2_data;
476+ base_addr = mem.cfm_addr ;
477+ break ;
478+ }
479+ if (!cfm_d) {
480+ memset (fake_cfm, 0xff , mem.cfm_len [i] * 4 );
481+ cfm_d = fake_cfm;
482+ }
483+
484+ printInfo (" Verify CFM" + std::to_string (i));
485+ verifyxFM (cfm_d, base_addr, 0 , mem.cfm_len [i]);
486+ }
415487 }
416488
417489 // DSM
0 commit comments