diff --git a/alchitry-loader/.gitignore b/alchitry-loader/.gitignore new file mode 100644 index 0000000..679fb6f --- /dev/null +++ b/alchitry-loader/.gitignore @@ -0,0 +1 @@ +alchitry_loader diff --git a/alchitry-loader/CMakeLists.txt b/alchitry-loader/CMakeLists.txt new file mode 100644 index 0000000..083517d --- /dev/null +++ b/alchitry-loader/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.0) +project(alchitry_loader) + +set(CMAKE_CXX_STANDARD 14) + +include_directories(src) + +add_executable(alchitry_loader + src/Alchitry_Loader.cpp + src/config_type.cpp + src/config_type.h + src/ftd2xx.h + src/jtag.cpp + src/jtag.h + src/jtag_fsm.cpp + src/jtag_fsm.h + src/loader.cpp + src/loader.h + src/mingw.thread.h + src/spi.cpp + src/spi.h + src/WinTypes.h) + + +target_link_libraries(alchitry_loader + ${CMAKE_SOURCE_DIR}/lib/linux/libftd2xx.a + ${CMAKE_SOURCE_DIR}/lib/windows/ftd2xx.lib + pthread) \ No newline at end of file diff --git a/alchitry-loader/Dockerfile b/alchitry-loader/Dockerfile index 7ca2190..3d90004 100644 --- a/alchitry-loader/Dockerfile +++ b/alchitry-loader/Dockerfile @@ -1,16 +1,18 @@ FROM debian:bookworm AS deps -RUN apt-get update -qq && apt-get install -qq -y --no-install-recommends build-essential +RUN apt-get update -qq && apt-get install -qq -y --no-install-recommends build-essential cmake FROM deps AS build -ADD . /workspace +ADD src /workspace/src +ADD lib /workspace/lib +ADD CMakeLists.txt /workspace/ WORKDIR /workspace -RUN make loader +RUN mkdir build && cd build && cmake .. && make FROM scratch AS export -COPY --from=build /workspace/loader / +COPY --from=build /workspace/build/alchitry_loader / diff --git a/alchitry-loader/Makefile b/alchitry-loader/Makefile index ef5a3c2..ddf375d 100644 --- a/alchitry-loader/Makefile +++ b/alchitry-loader/Makefile @@ -1,24 +1,6 @@ -sources = $(wildcard src/*.cpp) -objects = $(sources:.cpp=.o) -os = $(shell uname -s) -static_libs = lib/$(os)/libftd2xx.a -libs = -lpthread - -CXXFLAGS = -std=c++11 - export DOCKER_BUILDKIT=1 -# Assume target is Mac OS if build host is Mac OS; any other host targets Linux -ifeq ($(os), Darwin) - libs += -lobjc -framework IOKit -framework CoreFoundation -else - libs += -lrt -endif - -loader: $(objects) ## build the loader executable - $(CXX) $(LDFLAGS) -o $@ $^ $(static_libs) $(libs) - -build: ## build the loader in docker (linux) +loader: ## build the loader in docker (linux) docker build -o . . .PHONY: clean diff --git a/alchitry-loader/README.md b/alchitry-loader/README.md new file mode 100644 index 0000000..afd5f2a --- /dev/null +++ b/alchitry-loader/README.md @@ -0,0 +1,63 @@ +# Alchitry Loader (based on D2XX) +This project was originally used as a tool by Alchitry Labs to program the Alchitry boards using the +official D2XX library from FTDI. You can find D2XX here https://ftdichip.com/drivers/d2xx-drivers/ + +It has been updated to include the Alchitry Au+ and can be used as a stand-alone command line tool for +loading the Alchitry boards without using Alchitry Labs. + +Alchitry Labs no longer relies on this loader and instead has a fully Java loader built in. + +## Building +Clone the repository + +`git clone https://github.com/alchitry/alchitry-loader.git` + +Enter the project files + +`cd alchitry-loader` + +Create the Makefile + +`cmake CMakeLists.txt` + +Build the project + +`make` + +Test it out + +`./alchitry_loader` + +## Usage + +``` +Usage: "loader arguments" + +Arguments: +-e : erase FPGA flash +-l : list detected boards +-h : print this help message +-f config.bin : write FPGA flash +-r config.bin : write FPGA RAM +-u config.data : write FTDI eeprom +-b n : select board "n" (defaults to 0) +-p loader.bin : Au bridge bin +-t TYPE : TYPE can be au, au+, or cu (defaults to au) +``` + +### Examples +Load a .bin onto an Au's RAM (lost on power cycle) + +`./alchitry_loader -t au -r au_config.bin` + +Load a .bin onto an Au+'s flash (persistent config) + +`./alchitry_loader -t "au+" -f au_config.bin -p ./bridge/au_plus_loader.bin` + +Note that to load to the Au or Au+ flash memory you need to specify a bridge bin file. These can be found +in the bridge folder of this repo. This file is loaded onto the Au and allows this loader to program the +flash memory. It acts as a bridge from the JTAG port to the SPI of the flash memory. + +The source for the bridge files can be found here https://github.com/alchitry/au-bridge + +This isn't needed for the Cu which has direct access to the flash over the SPI protocol. \ No newline at end of file diff --git a/alchitry-loader/au_loader.bin b/alchitry-loader/au_loader.bin deleted file mode 100644 index 2689979..0000000 Binary files a/alchitry-loader/au_loader.bin and /dev/null differ diff --git a/alchitry-loader/lib/Linux/libftd2xx.a b/alchitry-loader/lib/Linux/libftd2xx.a deleted file mode 100644 index 2de7c50..0000000 Binary files a/alchitry-loader/lib/Linux/libftd2xx.a and /dev/null differ diff --git a/alchitry-loader/lib/linux/libftd2xx.a b/alchitry-loader/lib/linux/libftd2xx.a new file mode 100644 index 0000000..768f19e Binary files /dev/null and b/alchitry-loader/lib/linux/libftd2xx.a differ diff --git a/alchitry-loader/lib/Darwin/libftd2xx.a b/alchitry-loader/lib/macos/libftd2xx.a similarity index 100% rename from alchitry-loader/lib/Darwin/libftd2xx.a rename to alchitry-loader/lib/macos/libftd2xx.a diff --git a/alchitry-loader/lib/windows/ftbusui.dll b/alchitry-loader/lib/windows/ftbusui.dll index c55695a..cab5e6b 100644 Binary files a/alchitry-loader/lib/windows/ftbusui.dll and b/alchitry-loader/lib/windows/ftbusui.dll differ diff --git a/alchitry-loader/lib/windows/ftcserco.dll b/alchitry-loader/lib/windows/ftcserco.dll index ca6d397..ad02c2d 100644 Binary files a/alchitry-loader/lib/windows/ftcserco.dll and b/alchitry-loader/lib/windows/ftcserco.dll differ diff --git a/alchitry-loader/lib/windows/ftd2xx.dll b/alchitry-loader/lib/windows/ftd2xx.dll deleted file mode 100644 index ecafeb7..0000000 Binary files a/alchitry-loader/lib/windows/ftd2xx.dll and /dev/null differ diff --git a/alchitry-loader/lib/windows/ftd2xx.lib b/alchitry-loader/lib/windows/ftd2xx.lib index b2e0a53..7b28fab 100644 Binary files a/alchitry-loader/lib/windows/ftd2xx.lib and b/alchitry-loader/lib/windows/ftd2xx.lib differ diff --git a/alchitry-loader/lib/windows/ftd2xx64.dll b/alchitry-loader/lib/windows/ftd2xx64.dll new file mode 100644 index 0000000..bd6246a Binary files /dev/null and b/alchitry-loader/lib/windows/ftd2xx64.dll differ diff --git a/alchitry-loader/lib/windows/ftdibus.sys b/alchitry-loader/lib/windows/ftdibus.sys index e779f07..d803f07 100644 Binary files a/alchitry-loader/lib/windows/ftdibus.sys and b/alchitry-loader/lib/windows/ftdibus.sys differ diff --git a/alchitry-loader/lib/windows/ftlang.dll b/alchitry-loader/lib/windows/ftlang.dll index b57a0bb..23987a6 100644 Binary files a/alchitry-loader/lib/windows/ftlang.dll and b/alchitry-loader/lib/windows/ftlang.dll differ diff --git a/alchitry-loader/lib/windows/ftser2k.sys b/alchitry-loader/lib/windows/ftser2k.sys index 12795e8..f146245 100644 Binary files a/alchitry-loader/lib/windows/ftser2k.sys and b/alchitry-loader/lib/windows/ftser2k.sys differ diff --git a/alchitry-loader/lib/windows/ftserui2.dll b/alchitry-loader/lib/windows/ftserui2.dll index 471234c..e1708b2 100644 Binary files a/alchitry-loader/lib/windows/ftserui2.dll and b/alchitry-loader/lib/windows/ftserui2.dll differ diff --git a/alchitry-loader/src/Alchitry_Loader.cpp b/alchitry-loader/src/Alchitry_Loader.cpp index 1eeeedb..b2eafb3 100644 --- a/alchitry-loader/src/Alchitry_Loader.cpp +++ b/alchitry-loader/src/Alchitry_Loader.cpp @@ -14,18 +14,23 @@ #include #include "loader.h" #include + #ifdef _WIN32 #include "mingw.thread.h" #else + #include + #endif + #include #include "config_type.h" #define BOARD_ERROR -2 #define BOARD_UNKNOWN -1 #define BOARD_AU 0 -#define BOARD_CU 1 +#define BOARD_AU_PLUS 1 +#define BOARD_CU 2 using namespace std; using get_time = chrono::steady_clock; @@ -35,577 +40,598 @@ char ManufacturerIdBuf[16]; char DescriptionBuf[64]; char SerialNumberBuf[16]; -string getErrorName(int error) { - switch (error) { - case FT_OK: - return "FT_OK"; - case FT_INVALID_HANDLE: - return "FT_INVALID_HANDLE"; - case FT_DEVICE_NOT_FOUND: - return "FT_DEVICE_NOT_FOUND"; - case FT_DEVICE_NOT_OPENED: - return "FT_DEVICE_NOT_OPENED"; - case FT_IO_ERROR: - return "FT_IO_ERROR"; - case FT_INSUFFICIENT_RESOURCES: - return "FT_INSUFFICIENT_RESOURCES"; - case FT_INVALID_PARAMETER: - return "FT_INVALID_PARAMETER"; - case FT_INVALID_BAUD_RATE: - return "FT_INVALID_BAUD_RATE"; +string getErrorName(unsigned int error) { + switch (error) { + case FT_OK: + return "FT_OK"; + case FT_INVALID_HANDLE: + return "FT_INVALID_HANDLE"; + case FT_DEVICE_NOT_FOUND: + return "FT_DEVICE_NOT_FOUND"; + case FT_DEVICE_NOT_OPENED: + return "FT_DEVICE_NOT_OPENED"; + case FT_IO_ERROR: + return "FT_IO_ERROR"; + case FT_INSUFFICIENT_RESOURCES: + return "FT_INSUFFICIENT_RESOURCES"; + case FT_INVALID_PARAMETER: + return "FT_INVALID_PARAMETER"; + case FT_INVALID_BAUD_RATE: + return "FT_INVALID_BAUD_RATE"; - case FT_DEVICE_NOT_OPENED_FOR_ERASE: - return "FT_DEVICE_NOT_OPENED_FOR_ERASE"; - case FT_DEVICE_NOT_OPENED_FOR_WRITE: - return "FT_DEVICE_NOT_OPENED_FOR_WRITE"; - case FT_FAILED_TO_WRITE_DEVICE: - return "FT_FAILED_TO_WRITE_DEVICE"; - case FT_EEPROM_READ_FAILED: - return "FT_EEPROM_READ_FAILED"; - case FT_EEPROM_WRITE_FAILED: - return "FT_EEPROM_WRITE_FAILED"; - case FT_EEPROM_ERASE_FAILED: - return "FT_EEPROM_ERASE_FAILED"; - case FT_EEPROM_NOT_PRESENT: - return "FT_EEPROM_NOT_PRESENT"; - case FT_EEPROM_NOT_PROGRAMMED: - return "FT_EEPROM_NOT_PROGRAMMED"; - case FT_INVALID_ARGS: - return "FT_INVALID_ARGS"; - case FT_NOT_SUPPORTED: - return "FT_NOT_SUPPORTED"; - case FT_OTHER_ERROR: - return "FT_OTHER_ERROR"; - case FT_DEVICE_LIST_NOT_READY: - return "FT_DEVICE_LIST_NOT_READY"; - } - return "Unknown"; + case FT_DEVICE_NOT_OPENED_FOR_ERASE: + return "FT_DEVICE_NOT_OPENED_FOR_ERASE"; + case FT_DEVICE_NOT_OPENED_FOR_WRITE: + return "FT_DEVICE_NOT_OPENED_FOR_WRITE"; + case FT_FAILED_TO_WRITE_DEVICE: + return "FT_FAILED_TO_WRITE_DEVICE"; + case FT_EEPROM_READ_FAILED: + return "FT_EEPROM_READ_FAILED"; + case FT_EEPROM_WRITE_FAILED: + return "FT_EEPROM_WRITE_FAILED"; + case FT_EEPROM_ERASE_FAILED: + return "FT_EEPROM_ERASE_FAILED"; + case FT_EEPROM_NOT_PRESENT: + return "FT_EEPROM_NOT_PRESENT"; + case FT_EEPROM_NOT_PROGRAMMED: + return "FT_EEPROM_NOT_PROGRAMMED"; + case FT_INVALID_ARGS: + return "FT_INVALID_ARGS"; + case FT_NOT_SUPPORTED: + return "FT_NOT_SUPPORTED"; + case FT_OTHER_ERROR: + return "FT_OTHER_ERROR"; + case FT_DEVICE_LIST_NOT_READY: + return "FT_DEVICE_LIST_NOT_READY"; + default: + return "Unknown"; + } } -void write_to_file(string file, PFT_PROGRAM_DATA ftData) { - ofstream output_file(file, ios::binary); - CONFIG_DATA config; - ft_to_config(&config, ftData); - output_file.write((char*) &config, sizeof(CONFIG_DATA)); - output_file.write(ManufacturerBuf, sizeof(ManufacturerBuf)); - output_file.write(ManufacturerIdBuf, sizeof(ManufacturerIdBuf)); - output_file.write(DescriptionBuf, sizeof(DescriptionBuf)); - output_file.write(SerialNumberBuf, sizeof(SerialNumberBuf)); - output_file.close(); +void write_to_file(const string& file, PFT_PROGRAM_DATA ftData) { + ofstream output_file(file, ios::binary); + CONFIG_DATA config; + ft_to_config(&config, ftData); + output_file.write((char *) &config, sizeof(CONFIG_DATA)); + output_file.write(ManufacturerBuf, sizeof(ManufacturerBuf)); + output_file.write(ManufacturerIdBuf, sizeof(ManufacturerIdBuf)); + output_file.write(DescriptionBuf, sizeof(DescriptionBuf)); + output_file.write(SerialNumberBuf, sizeof(SerialNumberBuf)); + output_file.close(); } -bool read_from_file(string file, PFT_PROGRAM_DATA ftData) { - cout << "Reading " << file << endl; - try { - ifstream input_file(file, ios::in | ios::binary); - if (!input_file.is_open()) { - cerr << "Failed to open file " << file << endl; - return false; - } - CONFIG_DATA config; +bool read_from_file(const string& file, PFT_PROGRAM_DATA ftData) { + cout << "Reading " << file << endl; + try { + ifstream input_file(file, ios::in | ios::binary); + if (!input_file.is_open()) { + cerr << "Failed to open file " << file << endl; + return false; + } + CONFIG_DATA config; - input_file.read((char*) &config, sizeof(CONFIG_DATA)); - config_to_ft(ftData, &config); - input_file.read(ManufacturerBuf, sizeof(ManufacturerBuf)); - input_file.read(ManufacturerIdBuf, sizeof(ManufacturerIdBuf)); - input_file.read(DescriptionBuf, sizeof(DescriptionBuf)); - input_file.read(SerialNumberBuf, sizeof(SerialNumberBuf)); - input_file.close(); - ftData->Manufacturer = ManufacturerBuf; - ftData->ManufacturerId = ManufacturerIdBuf; - ftData->Description = DescriptionBuf; - ftData->SerialNumber = SerialNumberBuf; - } catch (...) { - cerr << "Failed to read file " << file << endl; - return false; - } - return true; + input_file.read((char *) &config, sizeof(CONFIG_DATA)); + config_to_ft(ftData, &config); + input_file.read(ManufacturerBuf, sizeof(ManufacturerBuf)); + input_file.read(ManufacturerIdBuf, sizeof(ManufacturerIdBuf)); + input_file.read(DescriptionBuf, sizeof(DescriptionBuf)); + input_file.read(SerialNumberBuf, sizeof(SerialNumberBuf)); + input_file.close(); + ftData->Manufacturer = ManufacturerBuf; + ftData->ManufacturerId = ManufacturerIdBuf; + ftData->Description = DescriptionBuf; + ftData->SerialNumber = SerialNumberBuf; + } catch (...) { + cerr << "Failed to read file " << file << endl; + return false; + } + return true; } FT_STATUS read_from_device(FT_HANDLE ftHandle, PFT_PROGRAM_DATA ftData) { - ftData->Signature1 = 0x00000000; - ftData->Signature2 = 0xffffffff; - ftData->Version = 0x00000005; - ftData->Manufacturer = ManufacturerBuf; - ftData->ManufacturerId = ManufacturerIdBuf; - ftData->Description = DescriptionBuf; - ftData->SerialNumber = SerialNumberBuf; + ftData->Signature1 = 0x00000000; + ftData->Signature2 = 0xffffffff; + ftData->Version = 0x00000005; + ftData->Manufacturer = ManufacturerBuf; + ftData->ManufacturerId = ManufacturerIdBuf; + ftData->Description = DescriptionBuf; + ftData->SerialNumber = SerialNumberBuf; - return FT_EE_Read(ftHandle, ftData); + return FT_EE_Read(ftHandle, ftData); } void print_info() { - cout << "Manufacture: " << ManufacturerBuf << endl; - cout << "ManufacturerId: " << ManufacturerIdBuf << endl; - cout << "Description: " << DescriptionBuf << endl; - cout << "SerialNumber: " << SerialNumberBuf << endl; + cout << "Manufacture: " << ManufacturerBuf << endl; + cout << "ManufacturerId: " << ManufacturerIdBuf << endl; + cout << "Description: " << DescriptionBuf << endl; + cout << "SerialNumber: " << SerialNumberBuf << endl; } void erase(FT_HANDLE ftHandle) { - cout << "Erasing... "; - FT_STATUS ftStatus = FT_EraseEE(ftHandle); - if (ftStatus != FT_OK) // Did the command execute OK? - { - cerr << "Error in erasing device!" << endl; - FT_Close(ftHandle); - return; - } - cout << "Done." << endl; + cout << "Erasing... "; + FT_STATUS ftStatus = FT_EraseEE(ftHandle); + if (ftStatus != FT_OK) // Did the command execute OK? + { + cerr << "Error in erasing device!" << endl; + FT_Close(ftHandle); + return; + } + cout << "Done." << endl; } -bool programDevice(unsigned int devNumber, string file) { - FT_HANDLE ftHandle; +bool programDevice(int devNumber, const string& file) { + FT_HANDLE ftHandle; - cout << "Opening device... "; - FT_STATUS ftStatus = FT_Open(devNumber, &ftHandle); - if (ftStatus != FT_OK) // Did the command execute OK? - { - printf("Error in opening device!\n"); - return false; // Exit with error - } - cout << "Done." << endl; - FT_PROGRAM_DATA ftData; + cout << "Opening device... "; + FT_STATUS ftStatus = FT_Open(devNumber, &ftHandle); + if (ftStatus != FT_OK) // Did the command execute OK? + { + printf("Error in opening device!\n"); + return false; // Exit with error + } + cout << "Done." << endl; + FT_PROGRAM_DATA ftData; - cout << "Checking EEPROM... "; - ftStatus = read_from_device(ftHandle, &ftData); + cout << "Checking EEPROM... "; + ftStatus = read_from_device(ftHandle, &ftData); - if (ftStatus != FT_EEPROM_NOT_PROGRAMMED) { // device isn't blank - if (ftStatus == FT_OK) { - cout << "Not blank." << endl; - erase(ftHandle); - } else if (ftStatus == FT_EEPROM_NOT_PRESENT) { - cout << "Not present!" << endl; - FT_Close(ftHandle); - return false; - } else { - cout << getErrorName(ftStatus) << endl; - FT_Close(ftHandle); - return false; - } - } else { - cout << "Blank." << endl; - } + if (ftStatus != FT_EEPROM_NOT_PROGRAMMED) { // device isn't blank + if (ftStatus == FT_OK) { + cout << "Not blank." << endl; + erase(ftHandle); + } else if (ftStatus == FT_EEPROM_NOT_PRESENT) { + cout << "Not present!" << endl; + FT_Close(ftHandle); + return false; + } else { + cout << getErrorName(ftStatus) << endl; + FT_Close(ftHandle); + return false; + } + } else { + cout << "Blank." << endl; + } - if (!read_from_file(file, &ftData)) { - FT_Close(ftHandle); - return false; - } + if (!read_from_file(file, &ftData)) { + FT_Close(ftHandle); + return false; + } - print_info(); + print_info(); - cout << "Programming... "; - ftStatus = FT_EE_Program(ftHandle, &ftData); - if (ftStatus != FT_OK) // Did the command execute OK? - { - cout << "ERROR: " << getErrorName(ftStatus) << endl; - FT_Close(ftHandle); - return false; - } - cout << "Done." << endl; + cout << "Programming... "; + ftStatus = FT_EE_Program(ftHandle, &ftData); + if (ftStatus != FT_OK) // Did the command execute OK? + { + cout << "ERROR: " << getErrorName(ftStatus) << endl; + FT_Close(ftHandle); + return false; + } + cout << "Done." << endl; - FT_Close(ftHandle); - return true; + FT_Close(ftHandle); + return true; } -string descriptionToName(string des) { - if (des == "Alchitry Cu A") { - return "Alchitry Cu"; - } else if (des == "Alchitry Au A") { - return "Alchitry Au"; - } else { - return "Unknown"; - } +string descriptionToName(const string &des) { + if (des == "Alchitry Cu A") { + return "Alchitry Cu"; + } else if (des == "Alchitry Au A") { + return "Alchitry Au"; + } else if (des == "Alchitry Au+ A") { + return "Alchitry Au+"; + } else { + return "Unknown"; + } } -int desciptionToType(string des) { - if (des == "Alchitry Cu A") { - return BOARD_CU; - } else if (des == "Alchitry Au A") { - return BOARD_AU; - } else { - return BOARD_UNKNOWN; - } +int descriptionToType(const string &des) { + if (des == "Alchitry Cu A") { + return BOARD_CU; + } else if (des == "Alchitry Au A") { + return BOARD_AU; + } else if (des == "Alchitry Au+ A") { + return BOARD_AU_PLUS; + } else { + return BOARD_UNKNOWN; + } +} + +string boardToName(int board) { + switch (board) { + case BOARD_AU: + return "Alchitry Au"; + case BOARD_AU_PLUS: + return "Alchitry Au+"; + case BOARD_CU: + return "Alchitry Cu"; + default: + return "Unknown"; + } } void printDeviceList() { - FT_STATUS ftStatus; - FT_DEVICE_LIST_INFO_NODE *devInfo; - DWORD numDevs = 0; - // create the device information list - ftStatus = FT_CreateDeviceInfoList(&numDevs); - if (ftStatus != FT_OK) { - cerr << "Could not read device list!" << endl; - return; - } + FT_STATUS ftStatus; + FT_DEVICE_LIST_INFO_NODE *devInfo; + DWORD numDevs = 0; + // create the device information list + ftStatus = FT_CreateDeviceInfoList(&numDevs); + if (ftStatus != FT_OK) { + cerr << "Could not read device list!" << endl; + return; + } - if (numDevs > 0) { - cout << "Devices: " << endl; - // allocate storage for list based on numDevs - devInfo = (FT_DEVICE_LIST_INFO_NODE*) malloc( - sizeof(FT_DEVICE_LIST_INFO_NODE) * numDevs); - // get the device information list - ftStatus = FT_GetDeviceInfoList(devInfo, &numDevs); - if (ftStatus == FT_OK) { - for (unsigned int i = 0; i < numDevs; i++) { - cout << " " << i << ": " - << descriptionToName(devInfo[i].Description) << endl; - } - } else { - cerr << "Error getting device list!" << endl; - } - free(devInfo); - } else { - cout << "No devices found!" << endl; - } + if (numDevs > 0) { + cout << "Devices: " << endl; + // allocate storage for list based on numDevs + devInfo = (FT_DEVICE_LIST_INFO_NODE *) malloc( + sizeof(FT_DEVICE_LIST_INFO_NODE) * numDevs); + // get the device information list + ftStatus = FT_GetDeviceInfoList(devInfo, &numDevs); + if (ftStatus == FT_OK) { + for (unsigned int i = 0; i < numDevs; i++) { + cout << " " << i << ": " + << descriptionToName(devInfo[i].Description) << endl; + } + } else { + cerr << "Error getting device list!" << endl; + } + free(devInfo); + } else { + cout << "No devices found!" << endl; + } } int getDeviceType(unsigned int devNumber) { - FT_STATUS ftStatus; - FT_DEVICE_LIST_INFO_NODE *devInfo; - DWORD numDevs = 0; - int board = BOARD_ERROR; - // create the device information list - ftStatus = FT_CreateDeviceInfoList(&numDevs); - if (ftStatus != FT_OK) { - cerr << "Could not read device list!" << endl; - return BOARD_ERROR; - } + FT_STATUS ftStatus; + FT_DEVICE_LIST_INFO_NODE *devInfo; + DWORD numDevs = 0; + int board = BOARD_ERROR; + // create the device information list + ftStatus = FT_CreateDeviceInfoList(&numDevs); + if (ftStatus != FT_OK) { + cerr << "Could not read device list!" << endl; + return BOARD_ERROR; + } - if (numDevs <= devNumber) { - cerr << "Invalid device number!" << endl; - return BOARD_ERROR; - } + if (numDevs <= devNumber) { + cerr << "Invalid device number!" << endl; + return BOARD_ERROR; + } - // allocate storage for list based on numDevs - devInfo = (FT_DEVICE_LIST_INFO_NODE*) malloc( - sizeof(FT_DEVICE_LIST_INFO_NODE) * numDevs); - // get the device information list - ftStatus = FT_GetDeviceInfoList(devInfo, &numDevs); - if (ftStatus == FT_OK) { - string boardDescription = devInfo[devNumber].Description; - if (boardDescription == "Alchitry Cu A") { - board = BOARD_CU; - } else if (boardDescription == "Alchitry Au A") { - board = BOARD_AU; - } else { - board = BOARD_UNKNOWN; - } - } else { - cerr << "Error getting device list!" << endl; - } - free(devInfo); + // allocate storage for list based on numDevs + devInfo = (FT_DEVICE_LIST_INFO_NODE *) malloc( + sizeof(FT_DEVICE_LIST_INFO_NODE) * numDevs); + // get the device information list + ftStatus = FT_GetDeviceInfoList(devInfo, &numDevs); + if (ftStatus == FT_OK) { + string boardDescription = devInfo[devNumber].Description; + if (boardDescription == "Alchitry Cu A") { + board = BOARD_CU; + } else if (boardDescription == "Alchitry Au A") { + board = BOARD_AU; + } else if (boardDescription == "Alchitry Au+ A") { + board = BOARD_AU_PLUS; + } else { + board = BOARD_UNKNOWN; + } + } else { + cerr << "Error getting device list!" << endl; + } + free(devInfo); - return board; + return board; } int getFirstDeviceOfType(int board) { - FT_STATUS ftStatus; - FT_DEVICE_LIST_INFO_NODE *devInfo; - DWORD numDevs = 0; + FT_STATUS ftStatus; + FT_DEVICE_LIST_INFO_NODE *devInfo; + DWORD numDevs = 0; - // create the device information list - ftStatus = FT_CreateDeviceInfoList(&numDevs); - if (ftStatus != FT_OK) { - cerr << "Could not read device list!" << endl; - return -1; - } + // create the device information list + ftStatus = FT_CreateDeviceInfoList(&numDevs); + if (ftStatus != FT_OK) { + cerr << "Could not read device list!" << endl; + return -1; + } - if (numDevs < 1) { - cerr << "No devices found!" << endl; - return -1; - } + if (numDevs < 1) { + cerr << "No devices found!" << endl; + return -1; + } - // allocate storage for list based on numDevs - devInfo = (FT_DEVICE_LIST_INFO_NODE*) malloc( - sizeof(FT_DEVICE_LIST_INFO_NODE) * numDevs); - // get the device information list - ftStatus = FT_GetDeviceInfoList(devInfo, &numDevs); + // allocate storage for list based on numDevs + devInfo = (FT_DEVICE_LIST_INFO_NODE *) malloc( + sizeof(FT_DEVICE_LIST_INFO_NODE) * numDevs); + // get the device information list + ftStatus = FT_GetDeviceInfoList(devInfo, &numDevs); - if (ftStatus == FT_OK) { - for (int devNumber = 0; devNumber < numDevs; devNumber++) { - string boardDescription = devInfo[devNumber].Description; - int type = desciptionToType(boardDescription); - if (type == board) { - free(devInfo); - return devNumber; - } - } - } else { - cerr << "Error getting device list!" << endl; - } - free(devInfo); - return -1; + if (ftStatus == FT_OK) { + for (int devNumber = 0; devNumber < numDevs; devNumber++) { + string boardDescription = devInfo[devNumber].Description; + int type = descriptionToType(boardDescription); + if (type == board) { + free(devInfo); + return devNumber; + } + } + } else { + cerr << "Error getting device list!" << endl; + } + free(devInfo); + return -1; } -bool readAndSaveFTDI(string file) { - FT_HANDLE ftHandle; +bool readAndSaveFTDI(const string& file) { + FT_HANDLE ftHandle; - cout << "Opening device... "; - FT_STATUS ftStatus = FT_Open(0, &ftHandle); - if (ftStatus != FT_OK) // Did the command execute OK? - { - printf("Error in opening device!\n"); - return false; // Exit with error - } - cout << "Done." << endl; - FT_PROGRAM_DATA ftData; + cout << "Opening device... "; + FT_STATUS ftStatus = FT_Open(0, &ftHandle); + if (ftStatus != FT_OK) // Did the command execute OK? + { + printf("Error in opening device!\n"); + return false; // Exit with error + } + cout << "Done." << endl; + FT_PROGRAM_DATA ftData; - cout << "Checking EEPROM... "; - ftStatus = read_from_device(ftHandle, &ftData); + cout << "Checking EEPROM... "; + ftStatus = read_from_device(ftHandle, &ftData); - if (ftStatus != FT_OK) { - if (ftStatus == FT_EEPROM_NOT_PROGRAMMED) { - cout << "Blank." << endl; - return false; - } else if (ftStatus == FT_EEPROM_NOT_PRESENT) { - cout << "Not present!" << endl; - FT_Close(ftHandle); - return false; - } else { - cout << "Unknown error " << ftStatus << endl; - FT_Close(ftHandle); - return false; - } - } else { // eeprom not blank - cout << "Done." << endl; - } + if (ftStatus != FT_OK) { + if (ftStatus == FT_EEPROM_NOT_PROGRAMMED) { + cout << "Blank." << endl; + return false; + } else if (ftStatus == FT_EEPROM_NOT_PRESENT) { + cout << "Not present!" << endl; + FT_Close(ftHandle); + return false; + } else { + cout << "Unknown error " << ftStatus << endl; + FT_Close(ftHandle); + return false; + } + } else { // eeprom not blank + cout << "Done." << endl; + } - cout << "Writing to file... "; + cout << "Writing to file... "; - write_to_file(file, &ftData); + write_to_file(file, &ftData); - cout << "Done." << endl; + cout << "Done." << endl; - FT_Close(ftHandle); - return true; + FT_Close(ftHandle); + return true; } void printUsage() { - cout << "Usage: \"loader arguments\"" << endl; - cout << endl; - cout << "Arguments:" << endl; - cout << " -e : erase FPGA flash" << endl; - cout << " -l : list detected boards" << endl; - cout << " -h : print this help message" << endl; - cout << " -f config.bin : write FPGA flash" << endl; - cout << " -r config.bin : write FPGA RAM" << endl; - cout << " -u config.data : write FTDI eeprom" << endl; - cout << " -b n : select board \"n\" (defaults to 0)" << endl; - cout << " -p loader.bin : Au bridge bin" << endl; - cout << " -t TYPE : TYPE can be au or cu (defaults to au)" << endl; + cout << "Usage: \"loader arguments\"" << endl; + cout << endl; + cout << "Arguments:" << endl; + cout << " -e : erase FPGA flash" << endl; + cout << " -l : list detected boards" << endl; + cout << " -h : print this help message" << endl; + cout << " -f config.bin : write FPGA flash" << endl; + cout << " -r config.bin : write FPGA RAM" << endl; + cout << " -u config.data : write FTDI eeprom" << endl; + cout << " -b n : select board \"n\" (defaults to 0)" << endl; + cout << " -p loader.bin : Au bridge bin" << endl; + cout << " -t TYPE : TYPE can be au, au+, or cu (defaults to au)" << endl; } int main(int argc, char *argv[]) { - if (argc < 2) { - printUsage(); - return 1; - } + if (argc < 2) { + printUsage(); + return 1; + } - bool fpgaFlash = false; - bool fpgaRam = false; - bool eeprom = false; - string eepromConfig; - string fpgaBinFlash; - string fpgaBinRam; - bool erase = false; - bool list = false; - bool print = false; - int deviceNumber = -1; - bool bridgeProvided = false; - string auBridgeBin; - bool isAu = true; + bool fpgaFlash = false; + bool fpgaRam = false; + bool eeprom = false; + string eepromConfig; + string fpgaBinFlash; + string fpgaBinRam; + bool erase = false; + bool list = false; + bool print = false; + int deviceNumber = -1; + bool bridgeProvided = false; + string auBridgeBin; + int board = BOARD_AU; - for (int i = 1; i < argc;) { - string arg = argv[i]; - if (arg == "-e") { - i++; - erase = true; - } else if (arg == "-l") { - i++; - list = true; - } else if (arg == "-h") { - i++; - print = true; - } else if (arg == "-f") { - if (argc <= i + 1) { - cerr << "Missing bin file!" << endl; - printUsage(); - return 1; - } - fpgaFlash = true; - fpgaBinFlash = argv[i + 1]; - i += 2; - } else if (arg == "-r") { - if (argc <= i + 1) { - cerr << "Missing bin file!" << endl; - printUsage(); - return 1; - } - fpgaRam = true; - fpgaBinRam = argv[i + 1]; - i += 2; - } else if (arg == "-u") { - if (argc <= i + 1) { - cerr << "Missing data file!" << endl; - printUsage(); - return 1; - } - eeprom = true; - eepromConfig = argv[i + 1]; - i += 2; - } else if (arg == "-b") { - if (argc <= i + 1) { - cerr << "Missing board number!" << endl; - printUsage(); - return 1; - } - try { - deviceNumber = stoi(argv[i + 1]); - } catch (const std::invalid_argument& ia) { - cerr << argv[i + 1] << " is not a number!" << endl; - printUsage(); - return 1; - } - if (deviceNumber < 0) { - cerr << "Device numbers can't be negative!" << endl; - printUsage(); - return 1; - } - i += 2; - } else if (arg == "-p") { - if (argc <= i + 1) { - cerr << "Missing bin file!" << endl; - printUsage(); - return 1; - } - bridgeProvided = true; - auBridgeBin = argv[i + 1]; - i += 2; - } else if (arg == "-t") { - if (argc <= i + 1) { - cerr << "Missing board type!" << endl; - printUsage(); - return 1; - } - if (strcmp(argv[i + 1], "au") == 0) { - isAu = true; - } else if (strcmp(argv[i + 1], "cu") == 0) { - isAu = false; - } else { - cerr << "Invalid board type: " << argv[i + 1] << endl; - printUsage(); - return 1; - } - i += 2; + for (int i = 1; i < argc;) { + string arg = argv[i]; + if (arg == "-e") { + i++; + erase = true; + } else if (arg == "-l") { + i++; + list = true; + } else if (arg == "-h") { + i++; + print = true; + } else if (arg == "-f") { + if (argc <= i + 1) { + cerr << "Missing bin file!" << endl; + printUsage(); + return 1; + } + fpgaFlash = true; + fpgaBinFlash = argv[i + 1]; + i += 2; + } else if (arg == "-r") { + if (argc <= i + 1) { + cerr << "Missing bin file!" << endl; + printUsage(); + return 1; + } + fpgaRam = true; + fpgaBinRam = argv[i + 1]; + i += 2; + } else if (arg == "-u") { + if (argc <= i + 1) { + cerr << "Missing data file!" << endl; + printUsage(); + return 1; + } + eeprom = true; + eepromConfig = argv[i + 1]; + i += 2; + } else if (arg == "-b") { + if (argc <= i + 1) { + cerr << "Missing board number!" << endl; + printUsage(); + return 1; + } + try { + deviceNumber = stoi(argv[i + 1]); + } catch (const std::invalid_argument &ia) { + cerr << argv[i + 1] << " is not a number!" << endl; + printUsage(); + return 1; + } + if (deviceNumber < 0) { + cerr << "Device numbers can't be negative!" << endl; + printUsage(); + return 1; + } + i += 2; + } else if (arg == "-p") { + if (argc <= i + 1) { + cerr << "Missing bin file!" << endl; + printUsage(); + return 1; + } + bridgeProvided = true; + auBridgeBin = argv[i + 1]; + i += 2; + } else if (arg == "-t") { + if (argc <= i + 1) { + cerr << "Missing board type!" << endl; + printUsage(); + return 1; + } + if (strcmp(argv[i + 1], "au") == 0) { + board = BOARD_AU; + } else if (strcmp(argv[i + 1], "au+") == 0) { + board = BOARD_AU_PLUS; + } else if (strcmp(argv[i + 1], "cu") == 0) { + board = BOARD_CU; + } else { + cerr << "Invalid board type: " << argv[i + 1] << endl; + printUsage(); + return 1; + } + i += 2; - } else { - cerr << "Unknown argument " << arg << endl; - printUsage(); - return 1; - } - } + } else { + cerr << "Unknown argument " << arg << endl; + printUsage(); + return 1; + } + } - if (print) - printUsage(); + if (print) + printUsage(); - if (list) - printDeviceList(); + if (list) + printDeviceList(); - if (deviceNumber < 0) - deviceNumber = getFirstDeviceOfType(isAu ? BOARD_AU : BOARD_CU); + if (deviceNumber < 0) + deviceNumber = getFirstDeviceOfType(board); - if (deviceNumber < 0) { - cerr << "Couldn't find device!" << endl; - return 2; - } + if (deviceNumber < 0) { + cerr << "Couldn't find device!" << endl; + return 2; + } - cout << "Found " << (isAu ? "Au" : "Cu") << " as device " << deviceNumber - << "." << endl; + cout << "Found " << boardToName(board) << " as device " << deviceNumber + << "." << endl; - if (eeprom) - programDevice(deviceNumber, eepromConfig); + if (eeprom) + programDevice(deviceNumber, eepromConfig); - if (erase || fpgaFlash || fpgaRam) { - int boardType = getDeviceType(deviceNumber); - if ((isAu && boardType != BOARD_AU) - || (!isAu && boardType != BOARD_CU)) { - cerr << "Invalid board type detected!" << endl; - return 2; - } + if (erase || fpgaFlash || fpgaRam) { + int boardType = getDeviceType(deviceNumber); + if (board != boardType) { + cerr << "Invalid board type detected!" << endl; + return 2; + } - if (boardType == BOARD_AU) { - if (bridgeProvided == false && (erase || fpgaFlash)) { - cerr << "No Au bridge bin provided!" << endl; - return 2; - } - Jtag jtag; - if (jtag.connect(deviceNumber) != FT_OK) { - cerr << "Failed to connect to JTAG!" << endl; - return 2; - } - if (jtag.initialize() == false) { - cerr << "Failed to initialize JTAG!" << endl; - return 2; - } - Loader loader(&jtag); + if (boardType == BOARD_AU || boardType == BOARD_AU_PLUS) { + if (!bridgeProvided && (erase || fpgaFlash)) { + cerr << "No bridge bin provided!" << endl; + return 2; + } + Jtag jtag; + if (jtag.connect(deviceNumber) != FT_OK) { + cerr << "Failed to connect to JTAG!" << endl; + return 2; + } + if (!jtag.initialize()) { + cerr << "Failed to initialize JTAG!" << endl; + return 2; + } + Loader loader(&jtag); - if (erase) { - if (!loader.eraseFlash(auBridgeBin)) { - cerr << "Failed to erase flash!" << endl; - } else { - cout << "Done." << endl; - } - } + if (erase) { + if (!loader.eraseFlash(auBridgeBin)) { + cerr << "Failed to erase flash!" << endl; + } else { + cout << "Done." << endl; + } + } - if (fpgaFlash) { - if (!loader.writeBin(fpgaBinFlash, true, auBridgeBin)) { - cerr << "Failed to write FPGA flash!" << endl; - } - } + if (fpgaFlash) { + if (!loader.writeBin(fpgaBinFlash, true, auBridgeBin)) { + cerr << "Failed to write FPGA flash!" << endl; + } + } - if (fpgaRam) { - if (!loader.writeBin(fpgaBinRam, false, "")) { - cerr << "Failed to write FPGA RAM!" << endl; - } - } + if (fpgaRam) { + if (!loader.writeBin(fpgaBinRam, false, "")) { + cerr << "Failed to write FPGA RAM!" << endl; + } + } - jtag.disconnect(); - } else if (boardType == BOARD_CU) { - Spi spi; - if (spi.connect(deviceNumber) != FT_OK) { - cerr << "Failed to connect to SPI!" << endl; - return 2; - } - if (spi.initialize() == false) { - cerr << "Failed to initialize SPI!" << endl; - return 2; - } + jtag.disconnect(); + } else if (boardType == BOARD_CU) { + Spi spi; + if (spi.connect(deviceNumber) != FT_OK) { + cerr << "Failed to connect to SPI!" << endl; + return 2; + } + if (!spi.initialize()) { + cerr << "Failed to initialize SPI!" << endl; + return 2; + } - if (erase) { - if (!spi.eraseFlash()) { - cerr << "Failed to erase flash!" << endl; - } else { - cout << "Done." << endl; - } - } + if (erase) { + if (!spi.eraseFlash()) { + cerr << "Failed to erase flash!" << endl; + } else { + cout << "Done." << endl; + } + } - if (fpgaFlash) { - if (!spi.writeBin(fpgaBinFlash)) { - cerr << "Failed to write FPGA flash!" << endl; - } - } + if (fpgaFlash) { + if (!spi.writeBin(fpgaBinFlash)) { + cerr << "Failed to write FPGA flash!" << endl; + } + } - if (fpgaRam) { - cerr << "Alchitry Cu doesn't support RAM only programming!" - << endl; - return 1; - } - } else { - cerr << "Unknown board type!" << endl; - return 2; - } - } + if (fpgaRam) { + cerr << "Alchitry Cu doesn't support RAM only programming!" + << endl; + return 1; + } + } else { + cerr << "Unknown board type!" << endl; + return 2; + } + } - return 0; + return 0; } diff --git a/alchitry-loader/src/WinTypes.h b/alchitry-loader/src/WinTypes.h old mode 100644 new mode 100755 diff --git a/alchitry-loader/src/ftd2xx.h b/alchitry-loader/src/ftd2xx.h index e5bbb46..3225268 100644 --- a/alchitry-loader/src/ftd2xx.h +++ b/alchitry-loader/src/ftd2xx.h @@ -1,6 +1,6 @@ /*++ -Copyright © 2001-2011 Future Technology Devices International Limited +Copyright © 2001-2021 Future Technology Devices International Limited THIS SOFTWARE IS PROVIDED BY FUTURE TECHNOLOGY DEVICES INTERNATIONAL LIMITED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -27,7 +27,7 @@ ftd2xx.h Abstract: -Native USB device driver for FTDI FT232x, FT245x, FT2232x and FT4232x devices +Native USB device driver for FTDI FT232x, FT245x, FT2232x, FT4232x, FT2233H and FT4233H devices FTD2XX library definitions Environment: @@ -191,7 +191,7 @@ enum { // Events // -typedef void (*PFT_EVENT_HANDLER)(DWORD,DWORD); +typedef void(*PFT_EVENT_HANDLER)(DWORD, DWORD); #define FT_EVENT_RXCHAR 1 #define FT_EVENT_MODEM_STATUS 2 @@ -224,7 +224,19 @@ enum { FT_DEVICE_4222H_0, FT_DEVICE_4222H_1_2, FT_DEVICE_4222H_3, - FT_DEVICE_4222_PROG, + FT_DEVICE_4222_PROG, + FT_DEVICE_900, + FT_DEVICE_930, + FT_DEVICE_UMFTPD3A, + FT_DEVICE_2233HP, + FT_DEVICE_4233HP, + FT_DEVICE_2232HP, + FT_DEVICE_4232HP, + FT_DEVICE_233HP, + FT_DEVICE_232HP, + FT_DEVICE_2232HA, + FT_DEVICE_4232HA, + FT_DEVICE_232RN, }; // @@ -316,15 +328,15 @@ extern "C" { #ifdef FTD2XX_STATIC - FTD2XX_API - FT_STATUS WINAPI FT_Initialise( - void - ); + FTD2XX_API + FT_STATUS WINAPI FT_Initialise( + void + ); - FTD2XX_API - void WINAPI FT_Finalise( - void - ); + FTD2XX_API + void WINAPI FT_Finalise( + void + ); #endif // FTD2XX_STATIC FTD2XX_API @@ -340,7 +352,7 @@ extern "C" { FT_HANDLE *pHandle ); - FTD2XX_API + FTD2XX_API FT_STATUS WINAPI FT_ListDevices( PVOID pArg1, PVOID pArg2, @@ -360,7 +372,7 @@ extern "C" { LPDWORD lpBytesReturned ); - FTD2XX_API + FTD2XX_API FT_STATUS WINAPI FT_Write( FT_HANDLE ftHandle, LPVOID lpBuffer, @@ -368,7 +380,7 @@ extern "C" { LPDWORD lpBytesWritten ); - FTD2XX_API + FTD2XX_API FT_STATUS WINAPI FT_IoCtl( FT_HANDLE ftHandle, DWORD dwIoControlCode, @@ -690,7 +702,7 @@ extern "C" { UCHAR FT1248FlowControlH; // FT1248 flow control enable UCHAR IsVCPH; // non-zero if interface is to use VCP drivers UCHAR PowerSaveEnableH; // non-zero if using ACBUS7 to save power for self-powered designs - + } FT_PROGRAM_DATA, *PFT_PROGRAM_DATA; FTD2XX_API @@ -784,8 +796,8 @@ extern "C" { UCHAR BIsFifoTar; // non-zero if interface is 245 FIFO CPU target UCHAR BIsFastSer; // non-zero if interface is Fast serial // Driver option - UCHAR ADriverType; // - UCHAR BDriverType; // + UCHAR ADriverType; // non-zero if interface is to use VCP drivers + UCHAR BDriverType; // non-zero if interface is to use VCP drivers } FT_EEPROM_2232, *PFT_EEPROM_2232; @@ -811,7 +823,7 @@ extern "C" { UCHAR Cbus3; // Cbus Mux control UCHAR Cbus4; // Cbus Mux control // Driver option - UCHAR DriverType; // + UCHAR DriverType; // non-zero if using D2XX driver } FT_EEPROM_232R, *PFT_EEPROM_232R; @@ -841,8 +853,8 @@ extern "C" { UCHAR BIsFastSer; // non-zero if interface is Fast serial UCHAR PowerSaveEnable; // non-zero if using BCBUS7 to save power for self-powered designs // Driver option - UCHAR ADriverType; // - UCHAR BDriverType; // + UCHAR ADriverType; // non-zero if interface is to use VCP drivers + UCHAR BDriverType; // non-zero if interface is to use VCP drivers } FT_EEPROM_2232H, *PFT_EEPROM_2232H; @@ -869,10 +881,10 @@ extern "C" { UCHAR CRIIsTXDEN; // non-zero if port C uses RI as RS485 TXDEN UCHAR DRIIsTXDEN; // non-zero if port D uses RI as RS485 TXDEN // Driver option - UCHAR ADriverType; // - UCHAR BDriverType; // - UCHAR CDriverType; // - UCHAR DDriverType; // + UCHAR ADriverType; // non-zero if interface is to use VCP drivers + UCHAR BDriverType; // non-zero if interface is to use VCP drivers + UCHAR CDriverType; // non-zero if interface is to use VCP drivers + UCHAR DDriverType; // non-zero if interface is to use VCP drivers } FT_EEPROM_4232H, *PFT_EEPROM_4232H; @@ -906,10 +918,10 @@ extern "C" { UCHAR IsFifo; // non-zero if interface is 245 FIFO UCHAR IsFifoTar; // non-zero if interface is 245 FIFO CPU target UCHAR IsFastSer; // non-zero if interface is Fast serial - UCHAR IsFT1248 ; // non-zero if interface is FT1248 + UCHAR IsFT1248; // non-zero if interface is FT1248 UCHAR PowerSaveEnable; // // Driver option - UCHAR DriverType; // + UCHAR DriverType; // non-zero if interface is to use VCP drivers } FT_EEPROM_232H, *PFT_EEPROM_232H; @@ -957,10 +969,223 @@ extern "C" { UCHAR RS485EchoSuppress; // UCHAR PowerSaveEnable; // // Driver option - UCHAR DriverType; // + UCHAR DriverType; // non-zero if interface is to use VCP drivers } FT_EEPROM_X_SERIES, *PFT_EEPROM_X_SERIES; + // FT4222H EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program + typedef struct ft_eeprom_4222h { + // Common header + FT_EEPROM_HEADER common; // common elements for all device EEPROMs + CHAR Revision; // 'A', 'B', 'C', or 'D'. + UCHAR I2C_Slave_Address; + // Suspend + UCHAR SPISuspend; // 0 for "Disable SPI, tristate pins", 2 for "Keep SPI pin status", 3 for "Enable SPI pin control" + UCHAR SuspendOutPol; // 0 for negative, 1 for positive (not implemented on Rev A) + UCHAR EnableSuspendOut; // non-zero to enable (not implemented on Rev A) + // QSPI + UCHAR Clock_SlowSlew; // non-zero if clock pin has slow slew + UCHAR Clock_Drive; // valid values are 4mA, 8mA, 12mA, 16mA + UCHAR IO0_SlowSlew; // non-zero if IO0 pin has slow slew + UCHAR IO1_SlowSlew; // non-zero if IO1 pin has slow slew + UCHAR IO2_SlowSlew; // non-zero if IO2 pin has slow slew + UCHAR IO3_SlowSlew; // non-zero if IO3 pin has slow slew + UCHAR IO_Drive; // valid values are 4mA, 8mA, 12mA, 16mA + UCHAR SlaveSelect_PullUp; // non-zero to enable pull up + UCHAR SlaveSelect_PullDown; // non-zero to enable pull down + UCHAR SlaveSelect_Drive; // valid values are 4mA, 8mA, 12mA, 16mA + UCHAR SlaveSelect_SlowSlew; // non-zero if slave select pin has slow slew + UCHAR MISO_Suspend; // 2 for push-low, 3 for push high, 0 and 1 reserved + UCHAR SIMO_Suspend; // 2 for push-low, 3 for push high, 0 and 1 reserved + UCHAR IO2_IO3_Suspend; // 2 for push-low, 3 for push high, 0 and 1 reserved + UCHAR SlaveSelect_Suspend; // 0 for no-change (not implemented on Rev A), 2 for push-low, 3 for push high, 1 reserved + // GPIO + UCHAR GPIO0_Drive; // valid values are 4mA, 8mA, 12mA, 16mA + UCHAR GPIO1_Drive; // valid values are 4mA, 8mA, 12mA, 16mA + UCHAR GPIO2_Drive; // valid values are 4mA, 8mA, 12mA, 16mA + UCHAR GPIO3_Drive; // valid values are 4mA, 8mA, 12mA, 16mA + UCHAR GPIO0_SlowSlew; // non-zero if IO0 pin has slow slew + UCHAR GPIO1_SlowSlew; // non-zero if IO0 pin has slow slew + UCHAR GPIO2_SlowSlew; // non-zero if IO0 pin has slow slew + UCHAR GPIO3_SlowSlew; // non-zero if IO0 pin has slow slew + UCHAR GPIO0_PullDown; // non-zero to enable pull down + UCHAR GPIO1_PullDown; // non-zero to enable pull down + UCHAR GPIO2_PullDown; // non-zero to enable pull down + UCHAR GPIO3_PullDown; // non-zero to enable pull down + UCHAR GPIO0_PullUp; // non-zero to enable pull up + UCHAR GPIO1_PullUp; // non-zero to enable pull up + UCHAR GPIO2_PullUp; // non-zero to enable pull up + UCHAR GPIO3_PullUp; // non-zero to enable pull up + UCHAR GPIO0_OpenDrain; // non-zero to enable open drain + UCHAR GPIO1_OpenDrain; // non-zero to enable open drain + UCHAR GPIO2_OpenDrain; // non-zero to enable open drain + UCHAR GPIO3_OpenDrain; // non-zero to enable open drain + UCHAR GPIO0_Suspend; // 0 for no-change, 1 for input (not implemented on Rev A), 2 for push-low, 3 for push high + UCHAR GPIO1_Suspend; // 0 for no-change, 1 for input (not implemented on Rev A), 2 for push-low, 3 for push high + UCHAR GPIO2_Suspend; // 0 for no-change, 1 for input (not implemented on Rev A), 2 for push-low, 3 for push high + UCHAR GPIO3_Suspend; // 0 for no-change, 1 for input (not implemented on Rev A), 2 for push-low, 3 for push high + UCHAR FallingEdge; // non-zero to change GPIO on falling edge + // BCD + UCHAR BCD_Disable; // non-zero to disable BCD + UCHAR BCD_OutputActiveLow; // non-zero to set BCD output active low + UCHAR BCD_Drive; // valid values are 4mA, 8mA, 12mA, 16mA + } FT_EEPROM_4222H, *PFT_EEPROM_4222H; + + + // Power Delivery structures for use with FT_EEPROM_Read and FT_EEPROM_Program + // PDO Configuration structure, mA supported values 0 to 10230mA, mV supported values 0 to 51100mV + // This is part of the FT_EEPROM_PD structure. + typedef struct ft_eeprom_PD_PDO_mv_ma { + USHORT PDO1ma; // PDO1 mA + USHORT PDO1mv; // PDO1 mV + USHORT PDO2ma; // PDO2 mA + USHORT PDO2mv; // PDO2 mV + USHORT PDO3ma; // PDO3 mA + USHORT PDO3mv; // PDO3 mV + USHORT PDO4ma; // PDO4 mA + USHORT PDO4mv; // PDO4 mV + USHORT PDO5ma; // PDO5 mA (FTx233HP only) + USHORT PDO5mv; // PDO5 mV (FTx233HP only) + USHORT PDO6ma; // PDO6 mA (FTx233HP only) + USHORT PDO6mv; // PDO6 mV (FTx233HP only) + USHORT PDO7ma; // PDO7 mA (FTx233HP only) + USHORT PDO7mv; // PDO7 mV (FTx233HP only) + } FT_EEPROM_PD_PDO_mv_ma; + + // PD EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program + // This is appended to the end of the base device structure. e_g. + // struct { + // FT_EEPROM_xxx base; + // FT_EEPROM_PD pd; + // }; + // Device GPIO values are: + // FTx233HP - 0 to 7, 15 for N/A + // FTx232HP - 0 to 3, 15 for N/A + typedef struct ft_eeprom_pd { + // Configuration + UCHAR srprs; // non-zero to enable Sink Request Power Role Swap + UCHAR sraprs; // non-zero to enable Sink Accept PR Swap + UCHAR srrprs; // non-zero to enable Source Request PR SWAP + UCHAR saprs; // non-zero to enable Source Accept PR SWAP + UCHAR vconns; // non-zero to enable vConn Swap + UCHAR passthru; // non-zero to enable Pass Through (FTx233HP only) + UCHAR extmcu; // non-zero to enable External MCU + UCHAR pd2en; // non-zero to enable PD2 (FTx233HP only) + UCHAR pd1autoclk; // non-zero to enable PD1 Auto Clock + UCHAR pd2autoclk; // non-zero to enable PD2 Auto Clock (FTx233HP only) + UCHAR useefuse; // non-zero to Use EFUSE + UCHAR extvconn; // non-zero to enable External vConn + + // GPIO Configuration + UCHAR count; // GPIO Count, supported values are 0 to 7 + UCHAR gpio1; // GPIO Number 1, supports device GPIO values + UCHAR gpio2; // GPIO Number 2, supports device GPIO values + UCHAR gpio3; // GPIO Number 3, supports device GPIO values + UCHAR gpio4; // GPIO Number 4, supports device GPIO values + UCHAR gpio5; // GPIO Number 5, supports device GPIO values (FTx233HP only) + UCHAR gpio6; // GPIO Number 6, supports device GPIO values (FTx233HP only) + UCHAR gpio7; // GPIO Number 7, supports device GPIO values (FTx233HP only) + UCHAR pd1lden; // PD1 Load Enable, supports device GPIO values + UCHAR pd2lden; // PD2 Load Enable, supports device GPIO values (FTx233HP only) + UCHAR dispin; // Discharge Pin, supports device GPIO values + UCHAR disenbm; // Discharge Enable BM, 0 for "Drive Hi", 1 for "Drive Low", 2 for "Input Mode", 3 for "Don't Care" + UCHAR disdisbm; // Discharge Disable BM, 0 for "Drive Hi", 1 for "Drive Low", 2 for "Input Mode", 3 for "Don't Care" + UCHAR ccselect; // CC Select Indicator, supports device GPIO values + + // ISET Configuration + UCHAR iset1; // ISET1, supports device GPIO values + UCHAR iset2; // ISET2, supports device GPIO values + UCHAR iset3; // ISET3, supports device GPIO values + UCHAR extiset; // non-zero to enable EXTEND_ISET + UCHAR isetpd2; // non-zero to enable ISET_PD2 + UCHAR iseten; // non-zero to set ISET_ENABLED + + // BM Configuration, 0 for "Drive Hi", 1 for "Drive Low", 2 for "Input Mode", 3 for "Don't Care" + UCHAR PDO1_GPIO[7]; // PDO1 GPIO1 to GPIO7 + UCHAR PDO2_GPIO[7]; // PDO2 GPIO1 to GPIO7 + UCHAR PDO3_GPIO[7]; // PDO3 GPIO1 to GPIO7 + UCHAR PDO4_GPIO[7]; // PDO4 GPIO1 to GPIO7 + UCHAR PDO5_GPIO[7]; // PDO5 GPIO1 to GPIO7 (FTx233HP only) + UCHAR PDO6_GPIO[7]; // PDO6 GPIO1 to GPIO7 (FTx233HP only) + UCHAR PDO7_GPIO[7]; // PDO7 GPIO1 to GPIO7 (FTx233HP only) + UCHAR VSET0V_GPIO[7]; // PDO7 GPIO1 to GPIO7 + UCHAR VSAFE5V_GPIO[7]; // PDO7 GPIO1 to GPIO7 + + FT_EEPROM_PD_PDO_mv_ma BM_PDO_Sink; + FT_EEPROM_PD_PDO_mv_ma BM_PDO_Source; + FT_EEPROM_PD_PDO_mv_ma BM_PDO_Sink_2; // (FTx233HP only) + + // PD Timers + UCHAR srt; // Sender Response Timer + UCHAR hrt; // Hard Reset Timer + UCHAR sct; // Source Capability Timer + UCHAR dit; // Discover Identity Timer + USHORT srcrt; // Source Recover Timer + USHORT trt; // Transition Timer + USHORT sofft; // Source off timer + USHORT nrt; // No Response Timer + USHORT swct; // Sink Wait Capability Timer + USHORT snkrt; // Sink Request Timer + UCHAR dt; // Discharge Timer + UCHAR cnst; // Chunk not supported timer + USHORT it; // Idle Timer + + // PD Control + UCHAR i2caddr; // I2C Address (hex) + UINT prou; // Power Reserved for OWN use + UINT trim1; // TRIM1 + UINT trim2; // TRIM2 + UCHAR extdc; // non-zero to enable ETERNAL_DC_POWER + } FT_EEPROM_PD, *PFT_EEPROM_PD; + + // FT2233HP EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program + // FT2232H with power delivery + typedef struct _ft_eeprom_2233hp + { + FT_EEPROM_2232H ft2232h; + FT_EEPROM_PD pd; + } FT_EEPROM_2233HP, *PFT_EEPROM_2233HP; + + // FT4233HP EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program + // FT4232H with power delivery + typedef struct _ft_eeprom_4233hp + { + FT_EEPROM_4232H ft4232h; + FT_EEPROM_PD pd; + } FT_EEPROM_4233HP, *PFT_EEPROM_4233HP; + + // FT2232HP EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program + // FT2232H with power delivery + typedef struct _ft_eeprom_2232hp + { + FT_EEPROM_2232H ft2232h; + FT_EEPROM_PD pd; + } FT_EEPROM_2232HP, *PFT_EEPROM_2232HP; + + // FT4232HP EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program + // FT4232H with power delivery + typedef struct _ft_eeprom_4232hp + { + FT_EEPROM_4232H ft4232h; + FT_EEPROM_PD pd; + } FT_EEPROM_4232HP, *PFT_EEPROM_4232HP; + + // FT233HP EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program + // FT233H with power delivery + typedef struct _ft_eeprom_233hp + { + FT_EEPROM_232H ft232h; + FT_EEPROM_PD pd; + } FT_EEPROM_233HP, *PFT_EEPROM_233HP; + + // FT232HP EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program + // FT232H with power delivery + typedef struct _ft_eeprom_232hp + { + FT_EEPROM_232H ft232h; + FT_EEPROM_PD pd; + } FT_EEPROM_232HP, *PFT_EEPROM_232HP; + FTD2XX_API FT_STATUS WINAPI FT_EEPROM_Read( FT_HANDLE ftHandle, @@ -1029,13 +1254,13 @@ extern "C" { FTD2XX_API FT_STATUS FT_SetVIDPID( - DWORD dwVID, + DWORD dwVID, DWORD dwPID ); - + FTD2XX_API FT_STATUS FT_GetVIDPID( - DWORD * pdwVID, + DWORD * pdwVID, DWORD * pdwPID ); @@ -1159,20 +1384,20 @@ extern "C" { typedef struct _FTDCB { DWORD DCBlength; /* sizeof(FTDCB) */ DWORD BaudRate; /* Baudrate at which running */ - DWORD fBinary: 1; /* Binary Mode (skip EOF check) */ - DWORD fParity: 1; /* Enable parity checking */ - DWORD fOutxCtsFlow:1; /* CTS handshaking on output */ - DWORD fOutxDsrFlow:1; /* DSR handshaking on output */ - DWORD fDtrControl:2; /* DTR Flow control */ - DWORD fDsrSensitivity:1; /* DSR Sensitivity */ - DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */ - DWORD fOutX: 1; /* Enable output X-ON/X-OFF */ - DWORD fInX: 1; /* Enable input X-ON/X-OFF */ - DWORD fErrorChar: 1; /* Enable Err Replacement */ - DWORD fNull: 1; /* Enable Null stripping */ - DWORD fRtsControl:2; /* Rts Flow control */ - DWORD fAbortOnError:1; /* Abort all reads and writes on Error */ - DWORD fDummy2:17; /* Reserved */ + DWORD fBinary : 1; /* Binary Mode (skip EOF check) */ + DWORD fParity : 1; /* Enable parity checking */ + DWORD fOutxCtsFlow : 1; /* CTS handshaking on output */ + DWORD fOutxDsrFlow : 1; /* DSR handshaking on output */ + DWORD fDtrControl : 2; /* DTR Flow control */ + DWORD fDsrSensitivity : 1; /* DSR Sensitivity */ + DWORD fTXContinueOnXoff : 1; /* Continue TX when Xoff sent */ + DWORD fOutX : 1; /* Enable output X-ON/X-OFF */ + DWORD fInX : 1; /* Enable input X-ON/X-OFF */ + DWORD fErrorChar : 1; /* Enable Err Replacement */ + DWORD fNull : 1; /* Enable Null stripping */ + DWORD fRtsControl : 2; /* Rts Flow control */ + DWORD fAbortOnError : 1; /* Abort all reads and writes on Error */ + DWORD fDummy2 : 17; /* Reserved */ WORD wReserved; /* Not currently used */ WORD XonLim; /* Transmit X-ON threshold */ WORD XoffLim; /* Transmit X-OFF threshold */ @@ -1193,7 +1418,7 @@ extern "C" { DWORD ReadTotalTimeoutConstant; /* Constant in milliseconds. */ DWORD WriteTotalTimeoutMultiplier; /* Multiplier of characters. */ DWORD WriteTotalTimeoutConstant; /* Constant in milliseconds. */ - } FTTIMEOUTS,*LPFTTIMEOUTS; + } FTTIMEOUTS, *LPFTTIMEOUTS; FTD2XX_API @@ -1440,4 +1665,3 @@ extern "C" { #endif /* FTD2XX_H */ - diff --git a/alchitry-loader/src/jtag.cpp b/alchitry-loader/src/jtag.cpp old mode 100644 new mode 100755 diff --git a/alchitry-loader/src/jtag.h b/alchitry-loader/src/jtag.h old mode 100644 new mode 100755 diff --git a/alchitry-loader/src/jtag_fsm.cpp b/alchitry-loader/src/jtag_fsm.cpp old mode 100644 new mode 100755 diff --git a/alchitry-loader/src/jtag_fsm.h b/alchitry-loader/src/jtag_fsm.h old mode 100644 new mode 100755 diff --git a/alchitry-loader/src/loader.cpp b/alchitry-loader/src/loader.cpp old mode 100644 new mode 100755 index b6ac849..4e966ab --- a/alchitry-loader/src/loader.cpp +++ b/alchitry-loader/src/loader.cpp @@ -134,6 +134,11 @@ string Loader::shiftDR(int bits, string write) { bool Loader::loadBin(string file) { string binStr = fileToBinStr(file); + if (binStr.empty()) { + cerr << "Failed to read bin file: "+ file << endl; + return false; + } + string reversedBinStr = reverseBytes(binStr); if (!device->setFreq(10000000)) { diff --git a/alchitry-loader/src/loader.h b/alchitry-loader/src/loader.h old mode 100644 new mode 100755 diff --git a/alchitry-loader/src/spi.h b/alchitry-loader/src/spi.h index 10631ca..744ca3d 100644 --- a/alchitry-loader/src/spi.h +++ b/alchitry-loader/src/spi.h @@ -9,9 +9,9 @@ #define SPI_H_ #include "ftd2xx.h" -#include #include #include +#include using namespace std;