fx2_ll: check load_firmware return code. Added some progressbar. Allows caller to set the alternate setting for an interface. Expose windex in write_ctrl/read_ctrl
This commit is contained in:
parent
22e782ac95
commit
ef92800ac3
|
|
@ -14,7 +14,7 @@
|
||||||
#include "display.hpp"
|
#include "display.hpp"
|
||||||
#include "fx2_ll.hpp"
|
#include "fx2_ll.hpp"
|
||||||
#include "ihexParser.hpp"
|
#include "ihexParser.hpp"
|
||||||
|
#include "progressBar.hpp"
|
||||||
|
|
||||||
#define FX2_FIRM_LOAD 0xA0
|
#define FX2_FIRM_LOAD 0xA0
|
||||||
#define FX2_GCR_CPUCS 0xe600
|
#define FX2_GCR_CPUCS 0xe600
|
||||||
|
|
@ -42,27 +42,36 @@ FX2_ll::FX2_ll(uint16_t uninit_vid, uint16_t uninit_pid,
|
||||||
throw std::runtime_error("claim interface failed");
|
throw std::runtime_error("claim interface failed");
|
||||||
}
|
}
|
||||||
/* load firmware */
|
/* load firmware */
|
||||||
load_firmware(firmware_path);
|
if (!load_firmware(firmware_path)) {
|
||||||
|
libusb_close(dev_handle);
|
||||||
|
libusb_exit(usb_ctx);
|
||||||
|
throw std::runtime_error("fx2 firmware load failed");
|
||||||
|
}
|
||||||
close();
|
close();
|
||||||
reenum = true;
|
reenum = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try to open an already init device
|
/* try to open an already init device
|
||||||
* since fx2 may be not immediately ready
|
* since fx2 may be not immediatly ready
|
||||||
* retry with a delay
|
* retry with a delay
|
||||||
*/
|
*/
|
||||||
|
ProgressBar progress("Waiting reload", 100, 50, false);
|
||||||
int timeout = 100;
|
int timeout = 100;
|
||||||
do {
|
do {
|
||||||
dev_handle = libusb_open_device_with_vid_pid(usb_ctx,
|
dev_handle = libusb_open_device_with_vid_pid(usb_ctx,
|
||||||
vid, pid);
|
vid, pid);
|
||||||
timeout--;
|
timeout--;
|
||||||
|
progress.display(100-timeout);
|
||||||
if (!dev_handle)
|
if (!dev_handle)
|
||||||
sleep(1);
|
sleep(1);
|
||||||
} while (!dev_handle && timeout > 0 && reenum);
|
} while (!dev_handle && timeout > 0 && reenum);
|
||||||
|
|
||||||
if (!dev_handle)
|
if (!dev_handle) {
|
||||||
|
progress.fail();
|
||||||
throw std::runtime_error("FX2: fail to open device");
|
throw std::runtime_error("FX2: fail to open device");
|
||||||
|
}
|
||||||
|
progress.done();
|
||||||
|
|
||||||
ret = libusb_claim_interface(dev_handle, 0);
|
ret = libusb_claim_interface(dev_handle, 0);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|
@ -72,6 +81,18 @@ FX2_ll::FX2_ll(uint16_t uninit_vid, uint16_t uninit_pid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FX2_ll::set_interface_alt_setting(const int if_num, const int alt_setting)
|
||||||
|
{
|
||||||
|
const int ret = libusb_set_interface_alt_setting(dev_handle, if_num,
|
||||||
|
alt_setting);
|
||||||
|
if (ret && ret != LIBUSB_ERROR_NOT_FOUND) {
|
||||||
|
printWarn("unable to select alternate interface 1: "
|
||||||
|
+ std::string(libusb_error_name(ret)));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* destructor: close current device and
|
/* destructor: close current device and
|
||||||
* destroy context
|
* destroy context
|
||||||
*/
|
*/
|
||||||
|
|
@ -134,11 +155,11 @@ int FX2_ll::read(uint8_t endpoint, uint8_t *buff, uint16_t len)
|
||||||
/* write len data using control
|
/* write len data using control
|
||||||
*/
|
*/
|
||||||
int FX2_ll::write_ctrl(uint8_t bRequest, uint16_t wValue,
|
int FX2_ll::write_ctrl(uint8_t bRequest, uint16_t wValue,
|
||||||
uint8_t *buff, uint16_t len)
|
uint8_t *buff, uint16_t len, uint16_t wIndex)
|
||||||
{
|
{
|
||||||
int ret = libusb_control_transfer(dev_handle,
|
int ret = libusb_control_transfer(dev_handle,
|
||||||
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT,
|
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT,
|
||||||
bRequest, wValue, 0x0000, buff, len, 100);
|
bRequest, wValue, wIndex, buff, len, 100);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printError("Unable to send control request: "
|
printError("Unable to send control request: "
|
||||||
+ std::string(libusb_error_name(ret)));
|
+ std::string(libusb_error_name(ret)));
|
||||||
|
|
@ -150,11 +171,11 @@ int FX2_ll::write_ctrl(uint8_t bRequest, uint16_t wValue,
|
||||||
/* read len data using control
|
/* read len data using control
|
||||||
*/
|
*/
|
||||||
int FX2_ll::read_ctrl(uint8_t bRequest, uint16_t wValue,
|
int FX2_ll::read_ctrl(uint8_t bRequest, uint16_t wValue,
|
||||||
uint8_t *buff, uint16_t len)
|
uint8_t *buff, uint16_t len, uint16_t wIndex)
|
||||||
{
|
{
|
||||||
int ret = libusb_control_transfer(dev_handle,
|
int ret = libusb_control_transfer(dev_handle,
|
||||||
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN,
|
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN,
|
||||||
bRequest, wValue, 0x0000, buff, len, 100);
|
bRequest, wValue, wIndex, buff, len, 100);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printError("Unable to read control request: "
|
printError("Unable to read control request: "
|
||||||
+ std::string(libusb_error_name(ret)));
|
+ std::string(libusb_error_name(ret)));
|
||||||
|
|
@ -177,6 +198,7 @@ bool FX2_ll::load_firmware(std::string firmware_path)
|
||||||
return false;
|
return false;
|
||||||
/* load */
|
/* load */
|
||||||
std::vector<IhexParser::data_line_t> data = ihex.getDataArray();
|
std::vector<IhexParser::data_line_t> data = ihex.getDataArray();
|
||||||
|
ProgressBar progress("Loading firmware", data.size(), 50, false);
|
||||||
for (size_t i = 0; i < data.size(); i++) {
|
for (size_t i = 0; i < data.size(); i++) {
|
||||||
IhexParser::data_line_t data_line = data[i];
|
IhexParser::data_line_t data_line = data[i];
|
||||||
|
|
||||||
|
|
@ -186,14 +208,16 @@ bool FX2_ll::load_firmware(std::string firmware_path)
|
||||||
while (toSend > 0) {
|
while (toSend > 0) {
|
||||||
uint16_t xfer_len = (toSend > 64) ? 64: toSend;
|
uint16_t xfer_len = (toSend > 64) ? 64: toSend;
|
||||||
if (!write_ctrl(FX2_FIRM_LOAD, addr, tx_buff, xfer_len)) {
|
if (!write_ctrl(FX2_FIRM_LOAD, addr, tx_buff, xfer_len)) {
|
||||||
printError("load firmware failed\n");
|
progress.fail();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
toSend -= xfer_len;
|
toSend -= xfer_len;
|
||||||
tx_buff += xfer_len;
|
tx_buff += xfer_len;
|
||||||
addr += xfer_len;
|
addr += xfer_len;
|
||||||
}
|
}
|
||||||
|
progress.display(i);
|
||||||
}
|
}
|
||||||
|
progress.done();
|
||||||
|
|
||||||
/* unset reset */
|
/* unset reset */
|
||||||
if (!reset(0))
|
if (!reset(0))
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
|
* Copyright (c) 2021-2026 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SRC_FX2_LL_HPP_
|
#ifndef SRC_FX2_LL_HPP_
|
||||||
|
|
@ -31,6 +31,14 @@ class FX2_ll {
|
||||||
uint16_t vid, uint16_t pid, const std::string &firmware_path);
|
uint16_t vid, uint16_t pid, const std::string &firmware_path);
|
||||||
~FX2_ll();
|
~FX2_ll();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief libusb_set_interface_alt_setting wrapper
|
||||||
|
* \param[in] if_num: Interface number
|
||||||
|
* \param[in] alt_setting: alternate setting
|
||||||
|
* \return true on success
|
||||||
|
*/
|
||||||
|
bool set_interface_alt_setting(const int if_num, const int alt_setting);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief bulk write
|
* \brief bulk write
|
||||||
* \param[in] endpoint: endpoint to use
|
* \param[in] endpoint: endpoint to use
|
||||||
|
|
@ -53,20 +61,22 @@ class FX2_ll {
|
||||||
* \param[in] wValue
|
* \param[in] wValue
|
||||||
* \param[in] buff: buffer to write
|
* \param[in] buff: buffer to write
|
||||||
* \param[in] len: buffer length
|
* \param[in] len: buffer length
|
||||||
|
* \param[in] wIndex: the index field for the setup packet
|
||||||
* \return false when transfer fails, true otherwise
|
* \return false when transfer fails, true otherwise
|
||||||
*/
|
*/
|
||||||
int write_ctrl(uint8_t bRequest, uint16_t wValue,
|
int write_ctrl(uint8_t bRequest, uint16_t wValue,
|
||||||
uint8_t *buff, uint16_t len);
|
uint8_t *buff, uint16_t len, uint16_t wIndex=0x0000);
|
||||||
/*!
|
/*!
|
||||||
* \brief control write
|
* \brief control write
|
||||||
* \param[in] bRequest
|
* \param[in] bRequest
|
||||||
* \param[in] wValue
|
* \param[in] wValue
|
||||||
* \param[in] buff: buffer to write
|
* \param[in] buff: buffer to write
|
||||||
* \param[in] len: buffer length
|
* \param[in] len: buffer length
|
||||||
|
* \param[in] wIndex: the index field for the setup packet
|
||||||
* \return false when transfer fails, true otherwise
|
* \return false when transfer fails, true otherwise
|
||||||
*/
|
*/
|
||||||
int read_ctrl(uint8_t bRequest, uint16_t wValue,
|
int read_ctrl(uint8_t bRequest, uint16_t wValue,
|
||||||
uint8_t *buff, uint16_t len);
|
uint8_t *buff, uint16_t len, uint16_t wIndex=0x0000);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*!
|
/*!
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue