Merge pull request #48 from TitanMKD/master
Fixed libhackrf, hackrf_cpldjtag (host) & usb_performance (firmware)
This commit is contained in:
@ -50,6 +50,11 @@ static const uint32_t usb_bulk_buffer_mask = 32768 - 1;
|
|||||||
|
|
||||||
usb_transfer_descriptor_t usb_td_bulk[2] ATTR_ALIGNED(64);
|
usb_transfer_descriptor_t usb_td_bulk[2] ATTR_ALIGNED(64);
|
||||||
const uint_fast8_t usb_td_bulk_count = sizeof(usb_td_bulk) / sizeof(usb_td_bulk[0]);
|
const uint_fast8_t usb_td_bulk_count = sizeof(usb_td_bulk) / sizeof(usb_td_bulk[0]);
|
||||||
|
|
||||||
|
/* TODO remove this big buffer and use streaming for CPLD */
|
||||||
|
#define CPLD_XSVF_MAX_LEN (65536)
|
||||||
|
uint8_t cpld_xsvf_buffer[CPLD_XSVF_MAX_LEN];
|
||||||
|
uint16_t write_cpld_idx = 0;
|
||||||
|
|
||||||
uint8_t spiflash_buffer[W25Q80BV_PAGE_LEN];
|
uint8_t spiflash_buffer[W25Q80BV_PAGE_LEN];
|
||||||
char version_string[] = VERSION_STRING;
|
char version_string[] = VERSION_STRING;
|
||||||
@ -61,8 +66,6 @@ typedef struct {
|
|||||||
|
|
||||||
set_freq_params_t set_freq_params;
|
set_freq_params_t set_freq_params;
|
||||||
|
|
||||||
uint8_t spiflash_buffer[W25Q80BV_PAGE_LEN];
|
|
||||||
|
|
||||||
uint8_t switchctrl = 0;
|
uint8_t switchctrl = 0;
|
||||||
|
|
||||||
void update_switches(void)
|
void update_switches(void)
|
||||||
@ -586,15 +589,62 @@ usb_request_status_t usb_vendor_request_read_spiflash(
|
|||||||
|
|
||||||
usb_request_status_t usb_vendor_request_write_cpld(
|
usb_request_status_t usb_vendor_request_write_cpld(
|
||||||
usb_endpoint_t* const endpoint,
|
usb_endpoint_t* const endpoint,
|
||||||
const usb_transfer_stage_t stage
|
const usb_transfer_stage_t stage)
|
||||||
) {
|
{
|
||||||
if( stage == USB_TRANSFER_STAGE_SETUP )
|
int error, i;
|
||||||
|
uint16_t total_len;
|
||||||
|
uint16_t len;
|
||||||
|
#define WAIT_LOOP_DELAY (6000000)
|
||||||
|
#define ALL_LEDS (PIN_LED1|PIN_LED2|PIN_LED3)
|
||||||
|
|
||||||
|
if (stage == USB_TRANSFER_STAGE_SETUP)
|
||||||
{
|
{
|
||||||
//FIXME endpoint->buffer can't be used like this
|
// len is limited to 64KB 16bits no overflow can happen
|
||||||
cpld_jtag_program(endpoint->setup.length, endpoint->buffer);
|
total_len = endpoint->setup.value;
|
||||||
usb_endpoint_schedule_ack(endpoint->in);
|
len = endpoint->setup.length;
|
||||||
|
usb_endpoint_schedule(endpoint->out, &cpld_xsvf_buffer[write_cpld_idx], len);
|
||||||
return USB_REQUEST_STATUS_OK;
|
return USB_REQUEST_STATUS_OK;
|
||||||
} else {
|
} else if (stage == USB_TRANSFER_STAGE_DATA)
|
||||||
|
{
|
||||||
|
// len is limited to 64KB 16bits no overflow can happen
|
||||||
|
total_len = endpoint->setup.value;
|
||||||
|
len = endpoint->setup.length;
|
||||||
|
write_cpld_idx = write_cpld_idx + len;
|
||||||
|
// Check if all bytes received and write CPLD
|
||||||
|
if(write_cpld_idx == total_len)
|
||||||
|
{
|
||||||
|
write_cpld_idx = 0;
|
||||||
|
error = cpld_jtag_program(total_len, &cpld_xsvf_buffer[write_cpld_idx]);
|
||||||
|
// TO FIX ACK shall be not delayed so much as cpld prog can take up to 5s.
|
||||||
|
if(error == 0)
|
||||||
|
{
|
||||||
|
usb_endpoint_schedule_ack(endpoint->in);
|
||||||
|
|
||||||
|
/* blink LED1, LED2, and LED3 on success */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
gpio_set(PORT_LED1_3, ALL_LEDS); /* LEDs on */
|
||||||
|
for (i = 0; i < WAIT_LOOP_DELAY; i++) /* Wait a bit. */
|
||||||
|
__asm__("nop");
|
||||||
|
gpio_clear(PORT_LED1_3, ALL_LEDS); /* LEDs off */
|
||||||
|
for (i = 0; i < WAIT_LOOP_DELAY; i++) /* Wait a bit. */
|
||||||
|
__asm__("nop");
|
||||||
|
}
|
||||||
|
return USB_REQUEST_STATUS_OK;
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
/* LED3 (Red) steady on error */
|
||||||
|
gpio_set(PORT_LED1_3, PIN_LED3); /* LEDs on */
|
||||||
|
while (1);
|
||||||
|
return USB_REQUEST_STATUS_STALL;
|
||||||
|
}
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
usb_endpoint_schedule_ack(endpoint->in);
|
||||||
|
return USB_REQUEST_STATUS_OK;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
return USB_REQUEST_STATUS_OK;
|
return USB_REQUEST_STATUS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,11 @@
|
|||||||
|
|
||||||
/* input file shouldn't be any longer than this */
|
/* input file shouldn't be any longer than this */
|
||||||
#define MAX_XSVF_LENGTH 0x10000
|
#define MAX_XSVF_LENGTH 0x10000
|
||||||
|
#define PACKET_LEN 4096
|
||||||
|
|
||||||
|
uint8_t data[MAX_XSVF_LENGTH];
|
||||||
|
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{ "length", required_argument, 0, 'l' },
|
|
||||||
{ "xsvf", required_argument, 0, 'x' },
|
{ "xsvf", required_argument, 0, 'x' },
|
||||||
{ 0, 0, 0, 0 },
|
{ 0, 0, 0, 0 },
|
||||||
};
|
};
|
||||||
@ -66,8 +68,6 @@ int parse_int(char* s, uint32_t* const value)
|
|||||||
static void usage()
|
static void usage()
|
||||||
{
|
{
|
||||||
printf("Usage:\n");
|
printf("Usage:\n");
|
||||||
//FIXME length should be automatic
|
|
||||||
printf("\t-l, --length <n>: length of XSVF file (default: 0)\n");
|
|
||||||
printf("\t-x <filename>: XSVF file to be written to CPLD.\n");
|
printf("\t-x <filename>: XSVF file to be written to CPLD.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,20 +75,19 @@ int main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
int opt;
|
int opt;
|
||||||
uint32_t length = 0;
|
uint32_t length = 0;
|
||||||
|
uint32_t total_length = 0;
|
||||||
const char* path = NULL;
|
const char* path = NULL;
|
||||||
hackrf_device* device = NULL;
|
hackrf_device* device = NULL;
|
||||||
int result = HACKRF_SUCCESS;
|
int result = HACKRF_SUCCESS;
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
uint8_t data[MAX_XSVF_LENGTH];
|
|
||||||
FILE* fd = NULL;
|
FILE* fd = NULL;
|
||||||
|
ssize_t bytes_read;
|
||||||
|
uint16_t xfer_len = 0;
|
||||||
|
uint8_t* pdata = &data[0];
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, "l:x:", long_options,
|
while ((opt = getopt_long(argc, argv, "x:", long_options,
|
||||||
&option_index)) != EOF) {
|
&option_index)) != EOF) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'l':
|
|
||||||
result = parse_int(optarg, &length);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'x':
|
case 'x':
|
||||||
path = optarg;
|
path = optarg;
|
||||||
break;
|
break;
|
||||||
@ -112,22 +111,31 @@ int main(int argc, char** argv)
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fd = fopen(path, "rb");
|
||||||
|
if (fd == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to open file: %s\n", path);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
/* Get size of the file */
|
||||||
|
fseek(fd, 0, SEEK_END); /* Not really portable but work on major OS Linux/Win32 */
|
||||||
|
length = ftell(fd);
|
||||||
|
/* Move to start */
|
||||||
|
rewind(fd);
|
||||||
|
printf("File size %d bytes.\n", length);
|
||||||
|
|
||||||
if (length > MAX_XSVF_LENGTH) {
|
if (length > MAX_XSVF_LENGTH) {
|
||||||
fprintf(stderr, "XSVF file too large.\n");
|
fprintf(stderr, "XSVF file too large.\n");
|
||||||
usage();
|
usage();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = fopen(path, "rb");
|
total_length = length;
|
||||||
if (fd == NULL) {
|
bytes_read = fread(data, 1, total_length, fd);
|
||||||
fprintf(stderr, "Failed to open file: %s\n", path);
|
if (bytes_read != total_length)
|
||||||
return EXIT_FAILURE;
|
{
|
||||||
}
|
fprintf(stderr, "Failed to read all bytes (read %d bytes instead of %d bytes).\n",
|
||||||
|
(int)bytes_read, total_length);
|
||||||
const ssize_t bytes_read = fread(data, 1, length, fd);
|
|
||||||
if (bytes_read != length) {
|
|
||||||
fprintf(stderr, "Failed read file (read %d bytes).\n",
|
|
||||||
(int)bytes_read);
|
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
fd = NULL;
|
fd = NULL;
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
@ -147,17 +155,32 @@ int main(int argc, char** argv)
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = hackrf_cpld_write(device, length, data);
|
printf("LED1/2/3 blinking means CPLD program success.\nLED3/RED steady means error.\n");
|
||||||
if (result != HACKRF_SUCCESS) {
|
printf("Wait message 'Write finished' or in case of LED3/RED steady, Power OFF/Disconnect the Jawbreaker.\n");
|
||||||
fprintf(stderr, "hackrf_cpld_write() failed: %s (%d)\n",
|
while( length )
|
||||||
hackrf_error_name(result), result);
|
{
|
||||||
fclose(fd);
|
xfer_len = (length > PACKET_LEN) ? PACKET_LEN : length;
|
||||||
fd = NULL;
|
result = hackrf_cpld_write(device, xfer_len, pdata, total_length);
|
||||||
return EXIT_FAILURE;
|
if (result != HACKRF_SUCCESS)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "hackrf_cpld_write() failed: %s (%d)\n",
|
||||||
|
hackrf_error_name(result), result);
|
||||||
|
fclose(fd);
|
||||||
|
fd = NULL;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
pdata += xfer_len;
|
||||||
|
length -= xfer_len;
|
||||||
|
printf("hackrf_cpld_write() Writing %d bytes, remaining %d bytes.\n",
|
||||||
|
xfer_len, length);
|
||||||
}
|
}
|
||||||
|
printf("Write finished.\n");
|
||||||
|
printf("Please Power OFF/Disconnect the Jawbreaker.\n");
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
result = hackrf_close(device);
|
result = hackrf_close(device);
|
||||||
if (result != HACKRF_SUCCESS) {
|
if( result != HACKRF_SUCCESS )
|
||||||
|
{
|
||||||
fprintf(stderr, "hackrf_close() failed: %s (%d)\n",
|
fprintf(stderr, "hackrf_close() failed: %s (%d)\n",
|
||||||
hackrf_error_name(result), result);
|
hackrf_error_name(result), result);
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
|
@ -634,22 +634,20 @@ int ADDCALL hackrf_spiflash_read(hackrf_device* device, const uint32_t address,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ADDCALL hackrf_cpld_write(hackrf_device* device, const uint16_t length,
|
int ADDCALL hackrf_cpld_write(hackrf_device* device, const uint16_t length,
|
||||||
unsigned char* const data)
|
unsigned char* const data, const uint16_t total_length)
|
||||||
{
|
{
|
||||||
int result;
|
int result = libusb_control_transfer(
|
||||||
result = libusb_control_transfer(
|
|
||||||
device->usb_device,
|
device->usb_device,
|
||||||
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
|
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
|
||||||
HACKRF_VENDOR_REQUEST_CPLD_WRITE,
|
HACKRF_VENDOR_REQUEST_CPLD_WRITE,
|
||||||
0,
|
total_length,
|
||||||
0,
|
0,
|
||||||
data,
|
data,
|
||||||
length,
|
length,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result < length)
|
if (result < length) {
|
||||||
{
|
|
||||||
return HACKRF_ERROR_LIBUSB;
|
return HACKRF_ERROR_LIBUSB;
|
||||||
} else {
|
} else {
|
||||||
return HACKRF_SUCCESS;
|
return HACKRF_SUCCESS;
|
||||||
|
@ -121,9 +121,10 @@ extern ADDAPI int ADDCALL hackrf_rffc5071_write(hackrf_device* device, uint8_t r
|
|||||||
extern ADDAPI int ADDCALL hackrf_spiflash_erase(hackrf_device* device);
|
extern ADDAPI int ADDCALL hackrf_spiflash_erase(hackrf_device* device);
|
||||||
extern ADDAPI int ADDCALL hackrf_spiflash_write(hackrf_device* device, const uint32_t address, const uint16_t length, unsigned char* const data);
|
extern ADDAPI int ADDCALL hackrf_spiflash_write(hackrf_device* device, const uint32_t address, const uint16_t length, unsigned char* const data);
|
||||||
extern ADDAPI int ADDCALL hackrf_spiflash_read(hackrf_device* device, const uint32_t address, const uint16_t length, unsigned char* data);
|
extern ADDAPI int ADDCALL hackrf_spiflash_read(hackrf_device* device, const uint32_t address, const uint16_t length, unsigned char* data);
|
||||||
|
|
||||||
extern ADDAPI int ADDCALL hackrf_cpld_write(hackrf_device* device, const uint16_t length, unsigned char* const data);
|
|
||||||
|
|
||||||
|
extern ADDAPI int ADDCALL hackrf_cpld_write(hackrf_device* device, const uint16_t length,
|
||||||
|
unsigned char* const data, const uint16_t total_length);
|
||||||
|
|
||||||
extern ADDAPI int ADDCALL hackrf_board_id_read(hackrf_device* device, uint8_t* value);
|
extern ADDAPI int ADDCALL hackrf_board_id_read(hackrf_device* device, uint8_t* value);
|
||||||
extern ADDAPI int ADDCALL hackrf_version_string_read(hackrf_device* device, char* version, uint8_t length);
|
extern ADDAPI int ADDCALL hackrf_version_string_read(hackrf_device* device, char* version, uint8_t length);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user