add zlib support (currently limited to altera spiOverJtag)
This commit is contained in:
parent
70e9671b3a
commit
7a19f94f19
|
|
@ -34,7 +34,8 @@ jobs:
|
||||||
libhidapi-dev \
|
libhidapi-dev \
|
||||||
libudev-dev \
|
libudev-dev \
|
||||||
pkg-config \
|
pkg-config \
|
||||||
tree
|
tree \
|
||||||
|
zlib1g-dev
|
||||||
|
|
||||||
- name: '🚧 Build tarball'
|
- name: '🚧 Build tarball'
|
||||||
run: |
|
run: |
|
||||||
|
|
@ -86,7 +87,8 @@ jobs:
|
||||||
sudo apt install -y \
|
sudo apt install -y \
|
||||||
libftdi1-2 \
|
libftdi1-2 \
|
||||||
libhidapi-hidraw0 \
|
libhidapi-hidraw0 \
|
||||||
udev
|
udev \
|
||||||
|
zlib1g
|
||||||
|
|
||||||
- name: '📥 Download artifact: package'
|
- name: '📥 Download artifact: package'
|
||||||
uses: actions/download-artifact@v2
|
uses: actions/download-artifact@v2
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ if(USE_PKGCONFIG)
|
||||||
pkg_check_modules(LIBFTDI REQUIRED libftdi1)
|
pkg_check_modules(LIBFTDI REQUIRED libftdi1)
|
||||||
pkg_check_modules(LIBUSB REQUIRED libusb-1.0)
|
pkg_check_modules(LIBUSB REQUIRED libusb-1.0)
|
||||||
pkg_check_modules(HIDAPI hidapi-hidraw)
|
pkg_check_modules(HIDAPI hidapi-hidraw)
|
||||||
|
pkg_check_modules(ZLIB zlib)
|
||||||
# if hidraw not found try with libusb
|
# if hidraw not found try with libusb
|
||||||
if(NOT HIDAPI_FOUND)
|
if(NOT HIDAPI_FOUND)
|
||||||
pkg_check_modules(HIDAPI hidapi-libusb)
|
pkg_check_modules(HIDAPI hidapi-libusb)
|
||||||
|
|
@ -198,6 +199,13 @@ else()
|
||||||
endif()
|
endif()
|
||||||
endif(ENABLE_CMSISDAP)
|
endif(ENABLE_CMSISDAP)
|
||||||
|
|
||||||
|
if (ZLIB_FOUND)
|
||||||
|
include_directories(${ZLIB_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(openFPGALoader ${ZLIB_LIBRARIES})
|
||||||
|
add_definitions(-DHAS_ZLIB=1)
|
||||||
|
else()
|
||||||
|
message("zlib library not found: can't flash intel/altera devices")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (LINK_CMAKE_THREADS)
|
if (LINK_CMAKE_THREADS)
|
||||||
|
|
@ -205,7 +213,6 @@ if (LINK_CMAKE_THREADS)
|
||||||
target_link_libraries(openFPGALoader Threads::Threads)
|
target_link_libraries(openFPGALoader Threads::Threads)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
# libftdi < 1.4 as no usb_addr
|
# libftdi < 1.4 as no usb_addr
|
||||||
# libftdi >= 1.5 as purge_buffer obsolete
|
# libftdi >= 1.5 as purge_buffer obsolete
|
||||||
string(REPLACE "." ";" VERSION_LIST ${LIBFTDI_VERSION})
|
string(REPLACE "." ";" VERSION_LIST ${LIBFTDI_VERSION})
|
||||||
|
|
@ -218,9 +225,11 @@ add_definitions(-DFTDI_VERSION=${FTDI_VAL})
|
||||||
install(TARGETS openFPGALoader DESTINATION bin)
|
install(TARGETS openFPGALoader DESTINATION bin)
|
||||||
file(GLOB BITS_FILES spiOverJtag/spiOverJtag_*.bit)
|
file(GLOB BITS_FILES spiOverJtag/spiOverJtag_*.bit)
|
||||||
file(GLOB RBF_FILES spiOverJtag/spiOverJtag_*.rbf)
|
file(GLOB RBF_FILES spiOverJtag/spiOverJtag_*.rbf)
|
||||||
|
file(GLOB GZ_FILES spiOverJtag/spiOverJtag_*.rbf.gz)
|
||||||
install(FILES
|
install(FILES
|
||||||
test_sfl.svf
|
test_sfl.svf
|
||||||
${BITS_FILES}
|
${BITS_FILES}
|
||||||
${RBF_FILES}
|
${RBF_FILES}
|
||||||
|
${GZ_FILES}
|
||||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/openFPGALoader
|
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/openFPGALoader
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,10 @@ pkgdesc="openFPGALoader: universal utility for programming FPGA (mingw-w64)"
|
||||||
arch=('any')
|
arch=('any')
|
||||||
url="https://github.com/trabucayre/openFPGALoader"
|
url="https://github.com/trabucayre/openFPGALoader"
|
||||||
license=('Apache-2.0')
|
license=('Apache-2.0')
|
||||||
depends=("${MINGW_PACKAGE_PREFIX}-libftdi")
|
depends=(
|
||||||
|
"${MINGW_PACKAGE_PREFIX}-libftdi"
|
||||||
|
"${MINGW_PACKAGE_PREFIX}-zlib"
|
||||||
|
)
|
||||||
makedepends=(
|
makedepends=(
|
||||||
"${MINGW_PACKAGE_PREFIX}-gcc"
|
"${MINGW_PACKAGE_PREFIX}-gcc"
|
||||||
"${MINGW_PACKAGE_PREFIX}-cmake"
|
"${MINGW_PACKAGE_PREFIX}-cmake"
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,11 @@ bool Altera::load_bridge()
|
||||||
|
|
||||||
// DATA_DIR is defined at compile time.
|
// DATA_DIR is defined at compile time.
|
||||||
std::string bitname = DATA_DIR "/openFPGALoader/spiOverJtag_";
|
std::string bitname = DATA_DIR "/openFPGALoader/spiOverJtag_";
|
||||||
|
#ifdef HAS_ZLIB
|
||||||
|
bitname += _device_package + ".rbf.gz";
|
||||||
|
#else
|
||||||
bitname += _device_package + ".rbf";
|
bitname += _device_package + ".rbf";
|
||||||
|
#endif
|
||||||
|
|
||||||
std::cout << "use: " << bitname << std::endl;
|
std::cout << "use: " << bitname << std::endl;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,10 @@
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef HAS_ZLIB
|
||||||
|
#include <zlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "display.hpp"
|
#include "display.hpp"
|
||||||
|
|
||||||
#include "configBitstreamParser.hpp"
|
#include "configBitstreamParser.hpp"
|
||||||
|
|
@ -23,21 +27,49 @@ ConfigBitstreamParser::ConfigBitstreamParser(const string &filename, int mode,
|
||||||
{
|
{
|
||||||
(void) mode;
|
(void) mode;
|
||||||
if (!filename.empty()) {
|
if (!filename.empty()) {
|
||||||
|
uint32_t offset = filename.find_last_of(".");
|
||||||
|
|
||||||
FILE *_fd = fopen(filename.c_str(), "rb");
|
FILE *_fd = fopen(filename.c_str(), "rb");
|
||||||
if (!_fd)
|
if (!_fd) {
|
||||||
throw std::runtime_error("Error: fail to open " + _filename);
|
printf("1\n");
|
||||||
|
/* if file not found it's maybe a gz -> try without gz */
|
||||||
|
if (offset != string::npos) {
|
||||||
|
printf("2\n");
|
||||||
|
_filename = filename.substr(0, offset);
|
||||||
|
printf("%s\n", _filename.c_str());
|
||||||
|
_fd = fopen(_filename.c_str(), "rb");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* test again */
|
||||||
|
if (!_fd)
|
||||||
|
throw std::runtime_error("Error: fail to open " + filename);
|
||||||
|
}
|
||||||
|
|
||||||
fseek(_fd, 0, SEEK_END);
|
fseek(_fd, 0, SEEK_END);
|
||||||
_file_size = ftell(_fd);
|
_file_size = ftell(_fd);
|
||||||
fseek(_fd, 0, SEEK_SET);
|
fseek(_fd, 0, SEEK_SET);
|
||||||
|
|
||||||
_raw_data.resize(_file_size);
|
_raw_data.resize(_file_size);
|
||||||
_bit_data.reserve(_file_size);
|
|
||||||
|
|
||||||
int ret = fread((char *)&_raw_data[0], sizeof(char), _file_size, _fd);
|
int ret = fread((char *)&_raw_data[0], sizeof(char), _file_size, _fd);
|
||||||
|
fclose(_fd);
|
||||||
if (ret != _file_size)
|
if (ret != _file_size)
|
||||||
throw std::runtime_error("Error: fail to read " + _filename);
|
throw std::runtime_error("Error: fail to read " + _filename);
|
||||||
fclose(_fd);
|
|
||||||
|
if (offset != string::npos) {
|
||||||
|
string extension = _filename.substr(_filename.find_last_of(".") +1);
|
||||||
|
if (extension == "gz" || extension == "gzip") {
|
||||||
|
string tmp;
|
||||||
|
tmp.reserve(_file_size);
|
||||||
|
if (!decompress_bitstream(_raw_data, &tmp))
|
||||||
|
throw std::runtime_error("Error: decompress failed");
|
||||||
|
_raw_data.clear();
|
||||||
|
_raw_data.append(std::move(tmp));
|
||||||
|
_file_size = _raw_data.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_bit_data.reserve(_file_size);
|
||||||
|
|
||||||
} else if (!isatty(fileno(stdin))) {
|
} else if (!isatty(fileno(stdin))) {
|
||||||
_file_size = 0;
|
_file_size = 0;
|
||||||
string tmp;
|
string tmp;
|
||||||
|
|
@ -119,3 +151,66 @@ uint8_t ConfigBitstreamParser::reverseByte(uint8_t src)
|
||||||
return revertByteArr[src];
|
return revertByteArr[src];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ConfigBitstreamParser::decompress_bitstream(string source, string *dest)
|
||||||
|
{
|
||||||
|
#ifndef HAS_ZLIB
|
||||||
|
(void)source;
|
||||||
|
(void)dest;
|
||||||
|
printError("openFPGALoader is build without zlib support\n"
|
||||||
|
"can't uncompress file\n");
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
#define CHUNK 16384
|
||||||
|
int ret;
|
||||||
|
unsigned have;
|
||||||
|
z_stream strm;
|
||||||
|
unsigned char *in = (unsigned char *)&source[0];
|
||||||
|
unsigned char out[CHUNK];
|
||||||
|
|
||||||
|
/* allocate inflate state */
|
||||||
|
strm.zalloc = Z_NULL;
|
||||||
|
strm.zfree = Z_NULL;
|
||||||
|
strm.opaque = Z_NULL;
|
||||||
|
strm.avail_in = 0;
|
||||||
|
strm.next_in = Z_NULL;
|
||||||
|
ret = inflateInit2(&strm, 15+16);
|
||||||
|
if (ret != Z_OK)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
uint32_t pos = source.size();
|
||||||
|
uint32_t xfer = CHUNK;
|
||||||
|
|
||||||
|
/* decompress until deflate stream ends or end of file */
|
||||||
|
do {
|
||||||
|
/* if buffer has a size < CHUNK */
|
||||||
|
if (pos < CHUNK)
|
||||||
|
xfer = pos;
|
||||||
|
strm.next_in = in; // chunk to uncompress
|
||||||
|
strm.avail_in = xfer; // chunk size
|
||||||
|
|
||||||
|
/* run inflate() on input until output buffer not full */
|
||||||
|
do {
|
||||||
|
strm.avail_out = CHUNK; // specify buffer size
|
||||||
|
strm.next_out = out; // buffer
|
||||||
|
ret = inflate(&strm, Z_BLOCK);
|
||||||
|
if (ret == Z_NEED_DICT || ret == Z_DATA_ERROR
|
||||||
|
|| ret == Z_MEM_ERROR) {
|
||||||
|
(void)inflateEnd(&strm);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
have = CHUNK - strm.avail_out; // compute data size
|
||||||
|
// after uncompress
|
||||||
|
dest->append((const char*)out, have); // store
|
||||||
|
} while (strm.avail_in != 0);
|
||||||
|
in += xfer; // update input buffer position
|
||||||
|
pos -= xfer; // update len to decompress
|
||||||
|
|
||||||
|
/* done when inflate() says it's done */
|
||||||
|
} while (ret != Z_STREAM_END);
|
||||||
|
|
||||||
|
/* clean up and return */
|
||||||
|
(void)inflateEnd(&strm);
|
||||||
|
return ret == Z_STREAM_END;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,16 @@ class ConfigBitstreamParser {
|
||||||
|
|
||||||
static uint8_t reverseByte(uint8_t src);
|
static uint8_t reverseByte(uint8_t src);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* \brief decompress bitstream in gzip format
|
||||||
|
* \param[in] source: raw compressed data
|
||||||
|
* \param[out] dest: raw uncompressed data
|
||||||
|
* \return false if openFPGALoader is build without zlib or
|
||||||
|
* if uncompress fails
|
||||||
|
*/
|
||||||
|
bool decompress_bitstream(std::string source, std::string *dest);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string _filename;
|
std::string _filename;
|
||||||
int _bit_length;
|
int _bit_length;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue