From a9f35706da55b9e72c43970709157961181331ab Mon Sep 17 00:00:00 2001 From: Gerry Stellenberg Date: Tue, 25 Jun 2013 18:54:54 -0500 Subject: [PATCH] Changes for p3-roc --- CMakeLists.txt | 2 +- src/PRCommon.h | 2 + src/PRDevice.cpp | 4 +- src/PRHardware.cpp | 8 +- src/PRHardware.h | 27 ++++ src/pinproc.cpp | 1 + utils/pinprocfw/pinprocfw.cpp | 265 ++++++++++++++++++++++++++++++---- utils/pinprocfw/pinprocfw.h | 15 +- 8 files changed, 285 insertions(+), 39 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 33b717f..5aca904 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -100,7 +100,7 @@ if(WIN32) set(CMAKE_INSTALL_PREFIX "C:/") endif() else() - set(lib_ftdi_usb usb ftdi) + set(lib_ftdi_usb usb ftdi1) endif() # GCC specialities diff --git a/src/PRCommon.h b/src/PRCommon.h index 8508761..b748acc 100644 --- a/src/PRCommon.h +++ b/src/PRCommon.h @@ -37,4 +37,6 @@ void PRLog(PRLogLevel level, const char *format, ...); void PRSetLastErrorText(const char *format, ...); +#define NULL 0 + #endif /* PINPROC_PRCOMMON_H */ diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index d626820..5002757 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -374,7 +374,7 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint const bool mappedSternDriverGroupPolarity[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; const int lastWPCCoilDriverGroup = 9; const int lastSternCoilDriverGroup = 7; - const int mappedWPCDriverGroupSlowTime[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 400, 400, 400, 400, 400, 400, 400, 400, 0, 0, 0, 0, 0, 0, 0, 0}; + const int mappedWPCDriverGroupSlowTime[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 100, 100, 100, 100, 100, 100, 100, 0, 0, 0, 0, 0, 0, 0, 0}; const int mappedSternDriverGroupSlowTime[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400}; const int mappedWPCDriverGroupActivateIndex[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0}; const int mappedSternDriverGroupActivateIndex[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}; @@ -1087,7 +1087,7 @@ PRResult PRDevice::VerifyChipID() buffer[i] = requestedDataQueue.front(); requestedDataQueue.pop(); // Ignore address word. TODO: Verify the address. } - if (buffer[1] != P_ROC_CHIP_ID) + if (buffer[1] != P_ROC_CHIP_ID && buffer[1] != P3_ROC_CHIP_ID) { DEBUG(PRLog(kPRLogError, "Error in VerifyID(): Dumping buffer\n")); for (i = 0; i < bufferWords; i++) diff --git a/src/PRHardware.cpp b/src/PRHardware.cpp index 2f2885b..db22afc 100644 --- a/src/PRHardware.cpp +++ b/src/PRHardware.cpp @@ -511,6 +511,7 @@ PRResult PRHardwareOpen() // We first enumerate all of the devices: int numDevices = ftdi_usb_find_all(&ftdic, &devlist, FTDI_VENDOR_ID, FTDI_FT245RL_PRODUCT_ID); + if (numDevices <=0) numDevices = ftdi_usb_find_all(&ftdic, &devlist, FTDI_VENDOR_ID, FTDI_FT240X_PRODUCT_ID); if (numDevices < 0) { PRSetLastErrorText("ftdi_usb_find_all failed: %d: %s", numDevices, ftdi_get_error_string(&ftdic)); ftdi_deinit(&ftdic); @@ -537,7 +538,7 @@ PRResult PRHardwareOpen() // Don't need the device list anymore ftdi_list_free (&devlist); - if ((rc = (int32_t)ftdi_usb_open(&ftdic, FTDI_VENDOR_ID, FTDI_FT245RL_PRODUCT_ID)) < 0) + if (((rc = (int32_t)ftdi_usb_open(&ftdic, FTDI_VENDOR_ID, FTDI_FT245RL_PRODUCT_ID)) < 0) && ((rc = (int32_t)ftdi_usb_open(&ftdic, FTDI_VENDOR_ID, FTDI_FT240X_PRODUCT_ID)) < 0)) { PRSetLastErrorText("Unable to open ftdi device: %d: %s", rc, ftdi_get_error_string(&ftdic)); return kPRFailure; @@ -545,7 +546,8 @@ PRResult PRHardwareOpen() else { rc = kPRSuccess; - if (ftdic.type == TYPE_R) { + //if (ftdic.type == TYPE_R) { + if (1) { uint32_t chipid; ftdi_read_chipid(&ftdic,&chipid); DEBUG(PRLog(kPRLogInfo, "FTDI chip_id = 0x%x\n", chipid)); @@ -572,10 +574,12 @@ void PRHardwareClose() } int PRHardwareRead(uint8_t *buffer, int maxBytes) { + //return 0; return ftdi_read_data(&ftdic, buffer, maxBytes); } int PRHardwareWrite(uint8_t *buffer, int bytes) { + //return 0; return ftdi_write_data(&ftdic, buffer, bytes); } diff --git a/src/PRHardware.h b/src/PRHardware.h index 5216fac..b1661a0 100644 --- a/src/PRHardware.h +++ b/src/PRHardware.h @@ -41,12 +41,14 @@ const int32_t FTDI_VENDOR_ID = 0x0403; const int32_t FTDI_FT245RL_PRODUCT_ID = 0x6001; +const int32_t FTDI_FT240X_PRODUCT_ID = 0x6015; //const int32_t FTDI_BUFFER_SIZE = 2048; const int32_t FTDI_BUFFER_SIZE = 8192; const uint32_t P_ROC_INIT_PATTERN_A = 0x801F1122; const uint32_t P_ROC_INIT_PATTERN_B = 0x345678AB; const uint32_t P_ROC_CHIP_ID = 0xfeedbeef; +const uint32_t P3_ROC_CHIP_ID = 0xf33db33f; const uint32_t P_ROC_VER_REV_FIXED_SWITCH_STATE_READS = 0x10013; // 1.19 @@ -86,6 +88,16 @@ const uint32_t P_ROC_BUS_STATE_CHANGE_PROC_SELECT = 4; const uint32_t P_ROC_BUS_DMD_SELECT = 5; const uint32_t P_ROC_BUS_UNASSOCIATED_SELECT = 15; +const uint32_t P3_ROC_MANAGER_SELECT = 0; +const uint32_t P3_ROC_BUS_SPI_SELECT = 1; +const uint32_t P3_ROC_BUS_SWITCH_CTRL_SELECT = 2; +const uint32_t P3_ROC_BUS_DRIVER_CTRL_SELECT = 3; +const uint32_t P3_ROC_BUS_STATE_CHANGE_PROC_SELECT = 4; +const uint32_t P3_ROC_BUS_AUX_CTRL_SELECT = 5; +const uint32_t P3_ROC_BUS_ACCELEROMETER_SELECT = 6; +const uint32_t P3_ROC_BUS_I2C_SELECT = 7; +const uint32_t P3_ROC_BUS_UNASSOCIATED_SELECT = 15; + const uint32_t P_ROC_REG_CHIP_ID_ADDR = 0; const uint32_t P_ROC_REG_VERSION_ADDR = 1; const uint32_t P_ROC_REG_WATCHDOG_ADDR = 2; @@ -97,6 +109,21 @@ const uint32_t P_ROC_MANAGER_WATCHDOG_RESET_TIME_SHIFT = 0; const uint32_t P_ROC_MANAGER_REUSE_DMD_DATA_FOR_AUX_SHIFT = 10; const uint32_t P_ROC_MANAGER_INVERT_DIPSWITCH_1_SHIFT = 9; +const uint32_t P3_ROC_SPI_OPCODE_SHIFT = 24; + +const uint32_t P3_ROC_SPI_OPCODE_WR_ENABLE = 0; +const uint32_t P3_ROC_SPI_OPCODE_WR_DISABLE = 1; +const uint32_t P3_ROC_SPI_OPCODE_RD_ID = 2; +const uint32_t P3_ROC_SPI_OPCODE_RD_STATUS = 3; +const uint32_t P3_ROC_SPI_OPCODE_WR_STATUS = 4; +const uint32_t P3_ROC_SPI_OPCODE_RD_DATA = 5; +const uint32_t P3_ROC_SPI_OPCODE_FRD_DATA = 6; +const uint32_t P3_ROC_SPI_OPCODE_PP = 7; +const uint32_t P3_ROC_SPI_OPCODE_SECTOR_ERASE = 8; +const uint32_t P3_ROC_SPI_OPCODE_BULK_ERASE = 9; +const uint32_t P3_ROC_SPI_OPCODE_DEEP_POWERDN = 10; +const uint32_t P3_ROC_SPI_OPCODE_RELEASE = 11; + const uint32_t P_ROC_JTAG_SHIFT_EXIT_SHIFT = 16; const uint32_t P_ROC_JTAG_SHIFT_NUM_BITS_SHIFT = 0; diff --git a/src/pinproc.cpp b/src/pinproc.cpp index 55910f6..be3e687 100644 --- a/src/pinproc.cpp +++ b/src/pinproc.cpp @@ -44,6 +44,7 @@ typedef void (*PRLogCallback)(PRLogLevel level, const char *text); PRLogCallback logCallback = NULL; +//PRLogLevel logLevel = kPRLogError; PRLogLevel logLevel = kPRLogError; void PRLog(PRLogLevel level, const char *format, ...) diff --git a/utils/pinprocfw/pinprocfw.cpp b/utils/pinprocfw/pinprocfw.cpp index b313757..4de1368 100644 --- a/utils/pinprocfw/pinprocfw.cpp +++ b/utils/pinprocfw/pinprocfw.cpp @@ -32,6 +32,7 @@ #endif /* DEBUG_MODE */ #include "pinprocfw.h" +#include "../../src/PRHardware.h" #include "lenval.h" #ifndef _MSC_VER #include @@ -525,7 +526,7 @@ void readByte(unsigned char *data) if (numBytesCurrent == 10) { fprintf(stderr, "\n\nUpdating P-ROC. This may take a couple of minutes.\n"); fprintf(stderr, "WARNING: DO NOT POWER CYCLE UNTIL COMPLETE!\n"); - printf("\nErasing... "); + printf("\nErasing PROM... "); fflush(stdout); } @@ -1902,6 +1903,219 @@ void printUsage(char * name) fprintf(stderr, " filename = the .xsvf or .p-roc file to execute.\n" ); } +int getNumFileBytes() { + unsigned char data; + int i=0; + while (!feof(in)) + { + data = (unsigned char)fgetc( in ); + i++; + } + return i; +} + +// Move file pointer to beginning of XSVF data. +void preparePROCFile() { + int temp, num_header_words; + int i; + + fscanf(in, "%x\n", &temp); + num_header_words = (int)(0x012345678 - temp); + + for (i=0; i 5) { + fprintf(stderr, "."); + iters = 0; + } + } + } + while (dataBuffer[0] & 0x1); + + return 1; +} + +void P3ROC_SPISendWEL() +{ + uint32_t dataBuffer[512]; + uint32_t addr = 0; + + dataBuffer[0] = P3_ROC_SPI_OPCODE_WR_ENABLE << P3_ROC_SPI_OPCODE_SHIFT; + PRWriteData (proc, P3_ROC_BUS_SPI_SELECT, addr, 1, dataBuffer); +} + +void P3ROC_SPIBulkErase() +{ + uint32_t dataBuffer[512]; + uint32_t addr = 0; + + P3ROC_SPISendWEL(); + + // Send bulk_erase command + printf("\nErasing flash ."); + fflush(stdout); + dataBuffer[0] = P3_ROC_SPI_OPCODE_BULK_ERASE << P3_ROC_SPI_OPCODE_SHIFT; + PRWriteData (proc, P3_ROC_BUS_SPI_SELECT, addr, 1, dataBuffer); + P3ROC_SPIWaitForReady(); +} + +void P3ROC_SPIReadPage(uint32_t page_addr, uint32_t * dataBuffer) +{ + uint32_t addr = 0; + + dataBuffer[0] = P3_ROC_SPI_OPCODE_RD_DATA << P3_ROC_SPI_OPCODE_SHIFT; + dataBuffer[0] = dataBuffer[0] | (page_addr << 8); + PRWriteData (proc, P3_ROC_BUS_SPI_SELECT, 0, 1, dataBuffer); + PRReadData(proc, P3_ROC_BUS_SPI_SELECT, 0x10, 64, dataBuffer); +} + +void P3ROC_SPIWritePage(uint32_t page_addr, uint32_t * writeDataBuffer) +{ + uint32_t addr = 0; + uint32_t dataBuffer[512]; + + PRWriteData (proc, P3_ROC_BUS_SPI_SELECT, 0x10, 64, writeDataBuffer); + P3ROC_SPISendWEL(); + + dataBuffer[0] = P3_ROC_SPI_OPCODE_PP << P3_ROC_SPI_OPCODE_SHIFT; + dataBuffer[0] = dataBuffer[0] | (page_addr << 8); + PRWriteData (proc, P3_ROC_BUS_SPI_SELECT, 0, 1, dataBuffer); + P3ROC_SPIWaitForReady(); +} + +int verifyP3ROCImage() +{ + unsigned char inChars [4]; + uint32_t dataBuffer[512]; + uint32_t readBuffer[64]; + + int pageAddr = 0; + long int bytesPerTenth = numBytesTotal / 10; + long int bytesPer200th = numBytesTotal / 200; + numBytesCurrent = 0; + + P3ROC_SPIWaitForReady(); + printf("\n\nVerifying image:\n0%% "); + fflush(stdout); + while (!feof(in)) { + for (int i=0; i<64; i++) + { + if (!feof(in)) + { + for (int j=0; j<4; j++) + { + inChars[j] = fgetc(in); + numBytesCurrent++; + if (numBytesCurrent % bytesPerTenth == 0) { + printf("\n%ld0%% ",numBytesCurrent/bytesPerTenth); + fflush(stdout); + } + else if (numBytesCurrent % bytesPer200th == 0) { + printf("."); + fflush(stdout); + } + + } + dataBuffer[i] = inChars[0] << 24 | inChars[1] << 16 | \ + inChars[2] << 8 | inChars[3]; + } + } + + //fprintf(stderr, "\nWriting Page: %x", pageAddr); + P3ROC_SPIReadPage(pageAddr, &readBuffer[0]); + + for (int i=0; i<64; i++) + { + if (readBuffer[i] != dataBuffer[i]) return 0; + } + + pageAddr++; + } + + XSVFDBG_PRINTF( 0, "\n\nSUCCESS - Operation completed successfully. Cycle P3-ROC power to activate any changes.\n" ); +} + +void writeP3ROCImage() +{ + unsigned char inChars [4]; + uint32_t dataBuffer[512]; + + int pageAddr = 0; + long int bytesPerTenth = numBytesTotal / 10; + long int bytesPer200th = numBytesTotal / 200; + numBytesCurrent = 0; + + P3ROC_SPIWaitForReady(); + printf("\nProgramming new image:\n0%% "); + fflush(stdout); + while (!feof(in)) { + for (int i=0; i<64; i++) + { + if (!feof(in)) + { + for (int j=0; j<4; j++) + { + inChars[j] = fgetc(in); + numBytesCurrent++; + if (numBytesCurrent % bytesPerTenth == 0) { + printf("\n%ld0%% ",numBytesCurrent/bytesPerTenth); + fflush(stdout); + } + else if (numBytesCurrent % bytesPer200th == 0) { + printf("."); + fflush(stdout); + } + + } + dataBuffer[i] = inChars[0] << 24 | inChars[1] << 16 | \ + inChars[2] << 8 | inChars[3]; + } + } + + //fprintf(stderr, "\nWriting Page: %x", pageAddr); + P3ROC_SPIWritePage(pageAddr, &dataBuffer[0]); + + //for (int i=0; i<64; i++) + //{ + // fprintf(stderr, "\nPage: %x, Byte: %x:%x", pageAddr, i*4, dataBuffer[i]); + //} + + pageAddr++; + } + +} + +void processP3ROCFile() +{ + fprintf(stderr, "\n\nUpdating P3-ROC. This may take a couple of minutes.\n"); + fprintf(stderr, "WARNING: DO NOT POWER CYCLE UNTIL COMPLETE!\n"); + P3ROC_SPIWaitForReady(); + P3ROC_SPIBulkErase(); + fprintf(stderr, "\nFlash erased.\n"); + writeP3ROCImage(); + rewind(in); + preparePROCFile(); + if (verifyP3ROCImage() == 0) + fprintf(stderr, "\nERROR: Verification failed. Please retry. DO NOT CYCLE POWER.\n\n"); +} + int processFile() { clock_t startClock; @@ -1934,8 +2148,10 @@ int checkPROCFile() { if (!fscanf(in, "%x\n", &temp)) return 0; num_header_words = (int)(0x012345678 - temp); + //fprintf(stderr, "\nproc_file_version: %x, %x", num_header_words, temp); if (!fscanf(in, "%x\n", &temp)) return 0; proc_file_version = (int)(-1 - temp); + //fprintf(stderr, "\nproc_file_version: %x, %x", proc_file_version, temp); if (!fscanf(in, "%x\n", &temp)) return 0; file_i = (int)(-1 - temp); //fprintf(stderr, "\nbyte count: %d, %x", file_i, temp); @@ -1965,13 +2181,18 @@ int checkPROCFile() { (board_rev & 0x10) >> 1; if (proc_file_version != 0) { - fprintf(stderr, "\nERROR: Unsupported .p-roc file version. Check for an updated version of this tool.\n\n"); + fprintf(stderr, "\nERROR: Unsupported .p-roc file version: %x. Check for an updated version of this tool.\n\n", proc_file_version); return 0; } // Check for valid board ID and rev if (board_id != file_board_id) { - fprintf(stderr, "\nERROR: This image is not compatible with the P-ROC board (ID: %x)\n\n", board_id); + fprintf(stderr, "\nERROR: board type mismatch.", board_id); + if (board_id == P_ROC_CHIP_ID && file_board_id == P3_ROC_CHIP_ID) + fprintf(stderr, "\nCannot program a P3-ROC image onto a P-ROC\n\n", file_board_id, board_id); + else if (board_id == P3_ROC_CHIP_ID && file_board_id == P_ROC_CHIP_ID) + fprintf(stderr, "\nCannot program a P-ROC image onto a P3-ROC\n\n", file_board_id, board_id); + else fprintf(stderr, "\nBoard and image are incompatible\n\n", file_board_id, board_id); return 0; } else fprintf(stderr, "\nBoard ID verified"); @@ -2002,29 +2223,7 @@ int checkPROCFile() { numBytesTotal = i; - return 1; -} - -int getNumFileBytes() { - unsigned char data; - int i=0; - while (!feof(in)) - { - data = (unsigned char)fgetc( in ); - i++; - } - return i; -} - -// Move file pointer to beginning of XSVF data. -void preparePROCFile() { - int temp, num_header_words; - int i; - - fscanf(in, "%x\n", &temp); - num_header_words = (int)(0x012345678 - temp); - - for (i=0; i - #define PRSleep(milliseconds) Sleep(milliseconds) -#else - #define PRSleep(milliseconds) sleep(milliseconds/1000) -#endif +//#if defined(__WIN32__) || defined(_WIN32) +// #include +// #define PRSleep(milliseconds) Sleep(milliseconds) +//#else +// #define PRSleep(milliseconds) sleep(milliseconds/1000) +//#endif /* Legacy error codes for xsvfExecute from original XSVF player v2.0 */ #define XSVF_LEGACY_SUCCESS 1 @@ -55,6 +55,9 @@ extern int xsvfExecute(); #define TMS (short) 1 #define TDI (short) 2 +//#define P_ROC_ID 0xfeedbeef +//#define P3_ROC_ID 0xf33db33f + /* set the port "p" (TCK, TMS, or TDI) to val (0 or 1) */ void setPort(short p, short val);