int SPI_DOWNLOAD_THREAD::spi_erase_sector(unsigned short nsector,int sector) { unsigned char stat; int timeout = 10; int r; r = cyusb_control_transfer(h, 0x40, 0xC4, 1, nsector, NULL, 0, VENDORCMD_TIMEOUT); if (r != 0) { printf("SPI sector erase failed\n"); return -1; } // Wait for the SPI flash to become ready again. do { r = cyusb_control_transfer(h, 0xC0, 0xC4, 0, 0, &stat, 1, VENDORCMD_TIMEOUT); if (r != 1) { printf("SPI status read failed\n"); return -2; } sleep (1); timeout--; } while ( (stat != 0) && (timeout > 0) ); if (stat != 0) { printf("Timed out on SPI status read\n"); return -3; } printf("Erased sector %d of SPI flash\n", nsector); emit sendSpiDownloadStatus(QString("Erased sector"),((nsector+1)*100)/sector); return 0; }
static int fx3_spi_erase_sector ( cyusb_handle *h, unsigned short nsector) { unsigned char stat; int timeout = 10; int r; r = cyusb_control_transfer (h, 0x40, 0xC4, 1, nsector, NULL, 0, VENDORCMD_TIMEOUT); if (r != 0) { fprintf (stderr, "Error: SPI sector erase failed\n"); return -1; } // Wait for the SPI flash to become ready again. do { r = cyusb_control_transfer (h, 0xC0, 0xC4, 0, 0, &stat, 1, VENDORCMD_TIMEOUT); if (r != 1) { fprintf (stderr, "Error: SPI status read failed\n"); return -2; } sleep (1); timeout--; } while ((stat != 0) && (timeout > 0)); if (stat != 0) { fprintf (stderr, "Error: Timed out on SPI status read\n"); return -3; } printf ("Info: Erased sector %d of SPI flash\n", nsector); return 0; }
int cyusb_download_fx2(cyusb_handle *h, char *filename, unsigned char vendor_command) { FILE *fp = NULL; char buf[256]; char tbuf1[3]; char tbuf2[5]; char tbuf3[3]; unsigned char reset = 0; int r; int count = 0; unsigned char num_bytes = 0; unsigned short address = 0; unsigned char *dbuf = NULL; int i; fp = fopen(filename, "r" ); tbuf1[2] ='\0'; tbuf2[4] = '\0'; tbuf3[2] = '\0'; reset = 1; r = cyusb_control_transfer(h, 0x40, 0xA0, 0xE600, 0x00, &reset, 0x01, 1000); if ( !r ) { printf("Error in control_transfer\n"); return r; } sleep(1); count = 0; while ( fgets(buf, 256, fp) != NULL ) { if ( buf[8] == '1' ) break; strncpy(tbuf1,buf+1,2); num_bytes = strtoul(tbuf1,NULL,16); strncpy(tbuf2,buf+3,4); address = strtoul(tbuf2,NULL,16); dbuf = (unsigned char *)malloc(num_bytes); for ( i = 0; i < num_bytes; ++i ) { strncpy(tbuf3,&buf[9+i*2],2); dbuf[i] = strtoul(tbuf3,NULL,16); } r = cyusb_control_transfer(h, 0x40, vendor_command, address, 0x00, dbuf, num_bytes, 1000); if ( !r ) { printf("Error in control_transfer\n"); free(dbuf); return r; } count += num_bytes; free(dbuf); } printf("Total bytes downloaded = %d\n", count); sleep(1); reset = 0; r = cyusb_control_transfer(h, 0x40, 0xA0, 0xE600, 0x00, &reset, 0x01, 1000); fclose(fp); return 0; }
static int fx3_ram_write ( cyusb_handle *h, unsigned char *buf, unsigned int ramAddress, int len) { int r; int index = 0; int size; while (len > 0) { size = (len > MAX_WRITE_SIZE) ? MAX_WRITE_SIZE : len; r = cyusb_control_transfer (h, 0x40, 0xA0, GET_LSW(ramAddress), GET_MSW(ramAddress), &buf[index], size, VENDORCMD_TIMEOUT); if (r != size) { fprintf (stderr, "Error: Vendor write to FX3 RAM failed\n"); return -1; } ramAddress += size; index += size; len -= size; } return 0; }
static int fx3_spi_write ( cyusb_handle *h, unsigned char *buf, int len) { int r = 0; int index = 0; int size; unsigned short page_address = 0; while (len > 0) { size = (len > MAX_WRITE_SIZE) ? MAX_WRITE_SIZE : len; r = cyusb_control_transfer (h, 0x40, 0xC2, 0, page_address, &buf[index], size, VENDORCMD_TIMEOUT); if (r != size) { fprintf (stderr, "Error: Write to SPI flash failed\n"); return -1; } index += size; len -= size; page_address += (size / SPI_PAGE_SIZE); } return 0; }
/* Function to read I2C data and compare against the expected value. */ static int fx3_i2c_read_verify ( cyusb_handle *h, unsigned char *expData, int devAddr, int len) { int r = 0; int index = 0; unsigned short address = 0; int size; unsigned char tmpBuf[MAX_WRITE_SIZE]; while (len > 0) { size = (len > MAX_WRITE_SIZE) ? MAX_WRITE_SIZE : len; r = cyusb_control_transfer (h, 0xC0, 0xBB, devAddr, address, tmpBuf, size, VENDORCMD_TIMEOUT); if (r != size) { fprintf (stderr, "Error: I2C read failed\n"); return -1; } if (memcmp (expData + index, tmpBuf, size) != 0) { fprintf (stderr, "Error: Failed to read expected data from I2C EEPROM\n"); return -2; } address += size ; index += size; len -= size; } return 0; }
static int fx3_i2c_write ( cyusb_handle *h, unsigned char *buf, int devAddr, int start, int len) { int r = 0; int index = start; unsigned short address = 0; int size; while (len > 0) { size = (len > MAX_WRITE_SIZE) ? MAX_WRITE_SIZE : len; r = cyusb_control_transfer (h, 0x40, 0xBA, devAddr, address, &buf[index], size, VENDORCMD_TIMEOUT); if (r != size) { fprintf (stderr, "Error: I2C write failed\n"); return -1; } address += size ; index += size; len -= size; } return 0; }
/* Check if the current device handle corresponds to the FX3 flash programmer. */ int SPI_DOWNLOAD_THREAD::check_fx3_flashprog(cyusb_handle *handle) { int r; char local[8]; r = cyusb_control_transfer(handle, 0xC0, 0xB0, 0, 0, (unsigned char *)local, 8, VENDORCMD_TIMEOUT); if ( ( r != 8 ) || ( strncasecmp(local, "FX3PROG", 7) != 0 ) ) { printf("Current device is not the FX3 flash programmer\n"); return -1; } printf("Found FX3 flash programmer\n"); return 0; }
/* Function to force FX2 CPU into (cpu_enable = 0) or out (cpu_enable != 0) of reset. */ static int fx2_reset ( cyusb_handle *h, int cpu_enable) { unsigned char reset = (cpu_enable) ? 0 : 1; int r; r = cyusb_control_transfer(h, 0x40, 0xA0, FX2_CPUCS_ADDR, 0x00, &reset, 0x01, VENDORCMD_TIMEOUT); if ( r != 1 ) { fprintf (stderr, "ERROR: FX2 reset command failed\n"); return -1; } return 0; }
/* Function to load the Vend_Ax firmware into the FX3 RAM. */ static int fx2_load_vendax ( cyusb_handle *h) { int r, j; unsigned int i; unsigned char *fw_p; unsigned char databuf[MAX_BYTES_PER_LINE]; unsigned char num_bytes = 0; unsigned short address = 0; printf("Info: Downloading Vend_ax hex into FX2 RAM\n"); for ( i = 0; ((i < FX2_VENDAX_SIZE) && (fx2_vendax[i][8] == 0x30)); i++ ) { fw_p = (unsigned char *)&fx2_vendax[i][1]; num_bytes = GET_HEX_BYTE(fw_p); fw_p += 2; address = GET_HEX_WORD(fw_p); fw_p += 6; for ( j = 0; j < num_bytes; j++ ) { databuf[j] = GET_HEX_BYTE(fw_p); fw_p += 2; } r = cyusb_control_transfer(h, 0x40, 0xA0, address, 0x00, databuf, num_bytes, VENDORCMD_TIMEOUT); if ( r != num_bytes ) { printf("Error in control_transfer\n"); return -2; } } printf("Info: Releasing FX2 CPU from reset\n"); r = fx2_reset (h, 1); if ( r != 0 ) { fprintf (stderr, "Error: Failed to get FX2 out of reset\n"); return -3; } return 0; }
int SPI_DOWNLOAD_THREAD::ram_write(unsigned char *buf, unsigned int ramAddress, int len) { int r; int index = 0; int size; while ( len > 0 ) { size = (len > MAX_WRITE_SIZE) ? MAX_WRITE_SIZE : len; r = cyusb_control_transfer(h, 0x40, 0xA0, GET_LSW(ramAddress), GET_MSW(ramAddress), &buf[index], size, VENDORCMD_TIMEOUT); if ( r != size ) { printf("Vendor write to FX3 RAM failed\n"); return -1; } ramAddress += size; index += size; len -= size; } return 0; }
int SPI_DOWNLOAD_THREAD::spi_write(unsigned char *buf, int len) { int r = 0; int index = 0; int size; unsigned short page_address = 0; while ( len > 0 ) { size = ( len > MAX_WRITE_SIZE ) ? MAX_WRITE_SIZE : len; r = cyusb_control_transfer(h, 0x40, 0xC2, 0, page_address, &buf[index], size, VENDORCMD_TIMEOUT); if ( r != size ) { printf("Write to SPI flash failed\n"); return -1; } index += size; len -= size; page_address += (size / SPI_PAGE_SIZE); emit sendSpiDownloadStatus( QString("firmware download"),(index *100) / filesize); } return 0; }
int SPI_DOWNLOAD_THREAD::fx3_usbboot_download(const char *filename) { unsigned char *fwBuf; unsigned int *data_p; unsigned int i, checksum; unsigned int address, length; int r, index; fwBuf = (unsigned char *)calloc (1, MAX_FWIMG_SIZE); if ( fwBuf == 0 ) { printf("Failed to allocate buffer to store firmware binary\n"); sb->showMessage("Error: Failed to get memory for download\n", 5000); return -1; } // Read the firmware image into the local RAM buffer. r = read_firmware_image(filename, fwBuf, NULL); if ( r != 0 ) { printf("Failed to read firmware file %s\n", filename); sb->showMessage("Error: Failed to read firmware binary\n", 5000); free(fwBuf); return -2; } // Run through each section of code, and use vendor commands to download them to RAM. index = 4; checksum = 0; while ( index < filesize ) { data_p = (unsigned int *)(fwBuf + index); length = data_p[0]; address = data_p[1]; if (length != 0) { for (i = 0; i < length; i++) checksum += data_p[2 + i]; r = ram_write(fwBuf + index + 8, address, length * 4); if (r != 0) { printf("Failed to download data to FX3 RAM\n"); sb->showMessage("Error: Write to FX3 RAM failed", 5000); free(fwBuf); return -3; } } else { if (checksum != data_p[2]) { printf ("Checksum error in firmware binary\n"); sb->showMessage("Error: Firmware checksum error", 5000); free(fwBuf); return -4; } r = cyusb_control_transfer(h, 0x40, 0xA0, GET_LSW(address), GET_MSW(address), NULL, 0, VENDORCMD_TIMEOUT); if ( r != 0 ) printf("Ignored error in control transfer: %d\n", r); break; } index += (8 + length * 4); } free(fwBuf); return 0; }
/* Function to download IIC file into an I2C EEPROM. */ static int fx2_eeprom_download ( cyusb_handle *h, const char *filename, int large) { int fd; unsigned char buf[EEPROM_WRITE_SIZE]; int r; unsigned short address = 0; int nbr; int filsz; struct stat filbuf; stat(filename, &filbuf); filsz = filbuf.st_size; if ((!large) && (filsz > 256)) { fprintf(stderr, "Error: File size greater than small EEPROM size\n"); return -1; } fd = open(filename, O_RDONLY); if ( fd < 0 ) { fprintf(stderr, "Error: Failed to open file %s\n", filename); return -2; } printf("Info: Forcing FX2 CPU into reset\n"); r = fx2_reset(h, 0); if ( r != 0 ) { fprintf (stderr, "Error: Failed to force FX2 CPU into reset\n"); close (fd); return -3; } /* Load the Vend_ax firmware to support the EEPROM write commands. */ r = fx2_load_vendax(h); if ( r != 0 ) { fprintf(stderr, "Error: Failed to load Vend_Ax firmware\n"); close(fd); return -4; } while ( (nbr = read(fd, buf, EEPROM_WRITE_SIZE)) ) { if (large) nbr = ROUND_UP(nbr, 64); else nbr = ROUND_UP(nbr, 8); r = cyusb_control_transfer(h, 0x40, ((large) ? 0xA9 : 0xA2), address, 0x00, buf, nbr, VENDORCMD_TIMEOUT); if ( r != nbr ) { fprintf(stderr, "Error: Control transfer to write EEPROM failed\n"); close(fd); return -5; } address += nbr; } close(fd); return 0; }
static int fx2_ram_download ( cyusb_handle *h, const char *filename, int extended) { unsigned char fw_buf[FX2_MAX_FW_SIZE]; fx2_fw_fmt fmt; unsigned int address = 0, length = 0; int i, r; fmt = read_fx2_firmware (filename, fw_buf, &address); if (fmt != FW_FORMAT_BIN) { fprintf (stderr, "Error: Invalid firmware file format\n"); return -1; } if ((address > FX2_INT_RAMSIZE) && (!extended)) { fprintf (stderr, "Error: Firmware too big to fit in internal RAM\n"); return -2; } r = fx2_reset (h, 0); if (r != 0) { fprintf (stderr, "Error: Failed to force FX2 into reset\n"); return -3; } /* Wait for some time. */ sleep(1); if ((extended) && (address > FX2_INT_RAMSIZE)) { printf ("Loading VEND-AX firmware\n"); r = fx2_load_vendax(h); if ( r != 0 ) { fprintf (stderr, "Failed to download Vend_Ax firmware to aid programming\n"); return -4; } /* Load the external RAM part first. */ for (i = FX2_INT_RAMSIZE; i < address; i += EEPROM_WRITE_SIZE) { length = ((address - i) > EEPROM_WRITE_SIZE) ? EEPROM_WRITE_SIZE : (address - i); r = cyusb_control_transfer (h, 0x40, 0xA3, i, 0x00, &fw_buf[i], length, VENDORCMD_TIMEOUT); if (r != length) { fprintf (stderr, "Vendor write to RAM failed\n"); return -5; } } /* All data has been loaded on external RAM. Now halt the CPU and load the internal RAM. */ printf ("Info: Forcing FX2 CPU into reset\n"); r = fx2_reset(h, 0); if ( r != 0 ) { fprintf (stderr, "Error: Failed to halt FX2 CPU\n"); return -6; } /* We can reduce the size to the internal RAM size now. */ address = FX2_INT_RAMSIZE; } /* Load the internal RAM part now. */ for (i = 0; i < address; i += EEPROM_WRITE_SIZE) { length = ((address - i) > EEPROM_WRITE_SIZE) ? EEPROM_WRITE_SIZE : (address - i); r = cyusb_control_transfer (h, 0x40, 0xA0, i, 0x00, &fw_buf[i], length, VENDORCMD_TIMEOUT); if (r != length) { fprintf (stderr, "Vendor write to RAM failed\n"); return -7; } } /* Now release CPU from reset. */ printf ("Info: Releasing FX2 CPU from reset\n"); r = fx2_reset(h, 1); if ( r != 0 ) { fprintf (stderr, "Error: Failed to release FX2 from reset\n"); return -8; } return 0; }