int main ( void ) { uint8_t bld_status; uint16_t length = 0; register uint8_t temp, tempSREG; void (*start) ( void ) = (void*) 0x0000; // function pointer to application code DBG_INIT(); // disable all interrupts cli(); // move interrupt vector table to bootloader section tempSREG = SREG; temp = MCUCR; MCUCR = temp | (1 << IVCE); // needed to unlock IVSEL MCUCR = temp | (1 << IVSEL); // set IVSEL (within 4 cycles) SREG = tempSREG; bld_status = 0; // initialize external SPI eeprom spi_master_init_blk(); eep_initialize(); // check internal EEProm if a new application has to be flashed bld_status = eeprom_read_byte(&g_reg_internal_eep[MOD_eCfg_BldFlag]); bld_status &= ~((1<<eBldFlagCRCMismatch) | (1 << eBldFlagControllerTypeMismatch) | (1 << eBldFlagBoardTypeMismatch)); if (bld_status & (1<<eBldFlagAppProgram)) { bld_status &= ~(1<<eBldFlagAppProgram); DBG_SET_PIN0(); do { // check external EEProm if (!check_crc(&length)) { bld_status |= (1 << eBldFlagCRCMismatch); break; } DBG_SET_PIN1(); // check controller if (!check_controller_id()) { bld_status |= (1 << eBldFlagControllerTypeMismatch); DBG_SET_PIN5(); break; } // check board type if (!check_board_type()) { bld_status |= (1 << eBldFlagBoardTypeMismatch); break; } // check application ID if (has_app_id_changed()) { bld_status |= (1 << eBldFlagAppIDChanged); } // check application version if (has_app_version_changed()) { bld_status |= (1 << eBldFlagAppVersionChanged); } DBG_SET_PIN2(); // flash new application program_flash(0, length); DBG_SET_PIN3(); bld_status |= (1 << eBldFlagNewSWProgrammed); // re-enable RWW-section again. We need this if we want to jump back // to the application after bootloading. boot_rww_enable (); } while ( false ); eeprom_write_byte(&g_reg_internal_eep[MOD_eCfg_BldFlag], bld_status); } DBG_SET_PIN4(); DBG_ALL_OFF(); DBG_ALL_ON(); DBG_ALL_OFF(); DBG_ALL_ON(); DBG_ALL_OFF(); DBG_ALL_ON(); DBG_ALL_OFF(); // restore interrupt vector table cli(); temp = MCUCR; MCUCR = temp | (1<<IVCE); MCUCR = temp & ~(1<<IVSEL); // start application start(); return 0; }
void flash(char *file, unsigned char skip_validation) { FILE *fp; long flash_length; char *flash_data; struct mpsse_context *mpsse; printf("reading input file.."); fflush(stdout); fp = fopen(file, "r"); if (!fp) { printf("failed!\n"); fprintf(stderr, "error: could not open '%s'", file); exit(1); } fseek(fp, 0L, SEEK_END); flash_length = ftell(fp); if (!flash_length) { printf("failed!\n"); fprintf(stderr, "error: file length was 0 bytes\n"); fclose(fp); exit(1); } if (flash_length > N25Q128A_TOTAL_BYTES) { printf("failed!\n"); fprintf(stderr, "error: file length exceeds flash capacity\n"); fclose(fp); exit(1); } rewind(fp); flash_data = (char *)malloc(flash_length * sizeof(char)); if (!flash_data) { printf("failed!\n"); fprintf(stderr, "error: could not allocate memory"); fclose(fp); exit(1); } if (fread(flash_data, 1, flash_length, fp) != flash_length) { printf("failed!\n"); fprintf(stderr, "error: could not read entire file"); free(flash_data); fclose(fp); exit(1); } fclose(fp); printf("\n"); mpsse = initialize_mpsse(); if (!mpsse) exit(1); printf("flashing chip.."); fflush(stdout); if (set_spartan_program_b(mpsse, 0) != MPSSE_OK) goto program_b_error; if (erase_flash(mpsse) != MPSSE_OK) goto error; if (program_flash(mpsse, flash_data, flash_length) != MPSSE_OK) goto error; if (!skip_validation) { unsigned char matched; printf("\nvalidating.."); fflush(stdout); if (validate_flash(mpsse, flash_data, flash_length, &matched) != MPSSE_OK) goto error; if (!matched) { printf("failed!\n"); fprintf(stderr, "error: flash mismatch\n"); goto validation_error; } } printf("success!\n"); if (set_spartan_program_b(mpsse, 1) != MPSSE_OK) goto program_b_error_quiet; free(flash_data); Close(mpsse); return; error: printf("failed!\n"); fprintf(stderr, "mpsse error: %s\n", ErrorString(mpsse)); validation_error: if (set_spartan_program_b(mpsse, 1) != MPSSE_OK) goto program_b_error_quiet; free(flash_data); Close(mpsse); exit(1); program_b_error: printf("failed!\n"); program_b_error_quiet: fprintf(stderr, "error: unable to change PROGRAM_B pin!\n"); fprintf(stderr, "mpsse error: %s\n", ErrorString(mpsse)); free(flash_data); Close(mpsse); exit(1); }