From 0f81d361c7542cd7c460adbd2f542a03637b6065 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 22:11:44 -0700 Subject: [PATCH 01/11] Added code to support transmit from usb_test host program. Reorganization of code to support making usb_test a useful utility... --- host/usb_test/usb_test.c | 135 ++++++++++++++++++++++++++++++--------- 1 file changed, 105 insertions(+), 30 deletions(-) diff --git a/host/usb_test/usb_test.c b/host/usb_test/usb_test.c index 29f08a86..5ce79244 100644 --- a/host/usb_test/usb_test.c +++ b/host/usb_test/usb_test.c @@ -24,10 +24,20 @@ #include #include +#include #include #include +const uint16_t hackrf_usb_pid = 0x1d50; +const uint16_t hackrf_usb_vid = 0x604b; + +typedef enum { + TRANSCEIVER_MODE_RX, + TRANSCEIVER_MODE_TX, +} transceiver_mode_t; +static transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_RX; + static float TimevalDiff(const struct timeval *a, const struct timeval *b) { @@ -48,31 +58,27 @@ void write_callback(struct libusb_transfer* transfer) { } } -int main(int argc, char** argv) { - if( argc != 2 ) { - printf("Usage: usb_test \n"); - return -1; - } - - const uint32_t buffer_size = 16384; - - fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO); - if( fd == -1 ) { - printf("Failed to open file for write\n"); - return -2; +void read_callback(struct libusb_transfer* transfer) { + if( transfer->status == LIBUSB_TRANSFER_COMPLETED ) { + byte_count += transfer->actual_length; + read(fd, transfer->buffer, transfer->actual_length); + libusb_submit_transfer(transfer); + } else { + printf("transfer status was not 'completed'\n"); } +} - libusb_context* context = NULL; +libusb_device_handle* open_device(libusb_context* const context) { int result = libusb_init(NULL); if( result != 0 ) { printf("libusb_init() failed: %d\n", result); - return -4; + return NULL; } - libusb_device_handle* device = libusb_open_device_with_vid_pid(context, 0x1d50, 0x604b); + libusb_device_handle* device = libusb_open_device_with_vid_pid(context, hackrf_usb_pid, hackrf_usb_vid); if( device == NULL ) { printf("libusb_open_device_with_vid_pid() failed\n"); - return -5; + return NULL; } //int speed = libusb_get_device_speed(device); @@ -80,26 +86,46 @@ int main(int argc, char** argv) { result = libusb_set_configuration(device, 1); if( result != 0 ) { + libusb_close(device); printf("libusb_set_configuration() failed: %d\n", result); - return -6; + return NULL; } result = libusb_claim_interface(device, 0); if( result != 0 ) { + libusb_close(device); printf("libusb_claim_interface() failed: %d\n", result); - return -7; + return NULL; } - - unsigned char endpoint_address = 0x81; - //unsigned char endpoint_address = 0x02; - const uint32_t transfer_count = 1024; - struct libusb_transfer* transfers[transfer_count]; + return device; +} + +void free_transfers(struct libusb_transfer** const transfers, const uint32_t transfer_count) { + for(uint32_t transfer_index=0; transfer_indexbuffer == 0 ) { + if( transfers[transfer_index]->buffer == NULL ) { + free_transfers(transfers, transfer_count); printf("malloc() failed\n"); - return -7; + return NULL; } int error = libusb_submit_transfer(transfers[transfer_index]); if( error != 0 ) { + free_transfers(transfers, transfer_count); printf("libusb_submit_transfer() failed: %d\n", error); - return -8; + return NULL; } } + return transfers; +} + +int main(int argc, char** argv) { + if( argc != 2 ) { + printf("Usage: usb_test \n"); + return -1; + } + + const char* const path = argv[1]; + + fd = -1; + uint_fast8_t endpoint_address = 0; + libusb_transfer_cb_fn callback = NULL; + + if( transceiver_mode == TRANSCEIVER_MODE_RX ) { + fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO); + endpoint_address = 0x81; + callback = &write_callback; + } else { + fd = open(path, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO); + endpoint_address = 0x02; + callback = &read_callback; + } + + if( fd == -1 ) { + printf("Failed to open file: errno %d\n", errno); + return fd; + } + + libusb_context* const context = NULL; + libusb_device_handle* const device = open_device(context); + if( device == NULL ) { + return -3; + } + + const uint32_t transfer_count = 1024; + const uint32_t buffer_size = 16384; + struct libusb_transfer** const transfers = prepare_transfers( + device, endpoint_address, transfer_count, buffer_size, callback + ); + if( transfers == NULL ) { + return -4; + } + ////////////////////////////////////////////////////////////// struct timeval timeout = { 0, 500000 }; @@ -158,7 +231,9 @@ int main(int argc, char** argv) { call_count += 1; } while(1); - result = libusb_release_interface(device, 0); + free_transfers(transfers, transfer_count); + + int result = libusb_release_interface(device, 0); if( result != 0 ) { printf("libusb_release_interface() failed: %d\n", result); return -2000; From 8291d7fac040ecb7c4882db300da16d246908495 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 11 Oct 2012 13:04:30 -0700 Subject: [PATCH 02/11] Add SGPIO configuration function for "deep" (8-slice) TX mode. --- firmware/common/sgpio.c | 79 +++++++++++++++++++++++++++++++++++++++++ firmware/common/sgpio.h | 1 + 2 files changed, 80 insertions(+) diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index 2db69608..e38c3d3e 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -146,6 +146,85 @@ void sgpio_configure_for_tx() { ; } +void sgpio_configure_for_tx_deep() { + // Disable all counters during configuration + SGPIO_CTRL_ENABLE = 0; + + sgpio_configure_pin_functions(); + + // Set SGPIO output values. + SGPIO_GPIO_OUTREG = + (1L << 11) | // direction + (1L << 10); // disable + + // Enable SGPIO pin outputs. + SGPIO_GPIO_OENREG = + (1L << 11) | // direction: TX: data to CPLD + (1L << 10) | // disable + (0L << 9) | // capture + (0L << 8) | // clock + 0xFF; // data: output + + SGPIO_OUT_MUX_CFG( 8) = 0; // SGPIO: Input: clock + SGPIO_OUT_MUX_CFG( 9) = 0; // SGPIO: Input: qualifier + SGPIO_OUT_MUX_CFG(10) = (0L << 4) | (4L << 0); // GPIO: Output: disable + SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction + + for(uint_fast8_t i=0; i<8; i++) { + // SGPIO pin 0 outputs slice A bit "i". + SGPIO_OUT_MUX_CFG(i) = + (0L << 4) | // P_OE_CFG = 0 + (11L << 0); // P_OUT_CFG = 11, dout_doutm8c (8-bit mode 8c) + } + + const uint_fast8_t slice_indices[] = { + SGPIO_SLICE_A, + SGPIO_SLICE_I, + SGPIO_SLICE_E, + SGPIO_SLICE_J, + SGPIO_SLICE_C, + SGPIO_SLICE_K, + SGPIO_SLICE_F, + SGPIO_SLICE_L, + }; + + uint32_t slice_enable_mask = 0; + for(uint_fast8_t i=0; i<8; i++) { + uint_fast8_t slice_index = slice_indices[i]; + const uint_fast8_t concat_order = 3; + const uint_fast8_t concat_enable = 1; + SGPIO_MUX_CFG(slice_index) = + (concat_order << 12) | // CONCAT_ORDER = 3 (eight slices) + (concat_enable << 11) | // CONCAT_ENABLE = 1 (concatenate data) + (0L << 9) | // QUALIFIER_SLICE_MODE = X + (1L << 7) | // QUALIFIER_PIN_MODE = 1 (SGPIO9) + (3L << 5) | // QUALIFIER_MODE = 3 (external SGPIO pin) + (0L << 3) | // CLK_SOURCE_SLICE_MODE = X + (0L << 1) | // CLK_SOURCE_PIN_MODE = 0 (SGPIO8) + (1L << 0); // EXT_CLK_ENABLE = 1, external clock signal (slice) + + SGPIO_SLICE_MUX_CFG(slice_index) = + (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) + (3L << 6) | // PARALLEL_MODE = 3 (shift 8 bits per clock) + (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) + (0L << 3) | // INV_OUT_CLK = X + (1L << 2) | // CLKGEN_MODE = 1 (use external pin clock) + (1L << 1) | // CLK_CAPTURE_MODE = 1 (use falling clock edge) + (0L << 0); // MATCH_MODE = 0 (do not match data) + + SGPIO_PRESET(slice_index) = 0; // External clock, don't care + SGPIO_COUNT(slice_index) = 0; // External clock, don't care + SGPIO_POS(slice_index) = (0x1f << 8) | (0x1f << 0); + SGPIO_REG(slice_index) = 0xFFFFFFFF; // Primary output data register + SGPIO_REG_SS(slice_index) = 0xFFFFFFFF; // Shadow output data register + + slice_enable_mask |= (1 << slice_index); + } + + // Start SGPIO operation by enabling slice clocks. + SGPIO_CTRL_ENABLE = slice_enable_mask; +} + void sgpio_configure_for_rx() { // Disable all counters during configuration SGPIO_CTRL_ENABLE = 0; diff --git a/firmware/common/sgpio.h b/firmware/common/sgpio.h index 8b8f471c..d41acef4 100644 --- a/firmware/common/sgpio.h +++ b/firmware/common/sgpio.h @@ -25,6 +25,7 @@ void sgpio_configure_pin_functions(); void sgpio_test_interface(); void sgpio_configure_for_tx(); +void sgpio_configure_for_tx_deep(); void sgpio_configure_for_rx(); void sgpio_configure_for_rx_deep(); void sgpio_cpld_stream_enable(); From fb9ce63f7f5ca464028eff2783a0bb7b6894f38c Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 11 Oct 2012 13:06:27 -0700 Subject: [PATCH 03/11] Add (manual) switch for TX and RX mode. Add code for configuring TX mode. TODO: Consolidate lots of repetitive code. --- firmware/usb_performance/usb_performance.c | 85 ++++++++++++++++------ 1 file changed, 64 insertions(+), 21 deletions(-) diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index 5a6989e3..b5eaa6fa 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -38,6 +38,12 @@ #include "usb_descriptor.h" #include "usb_standard_request.h" +typedef enum { + TRANSCEIVER_MODE_RX, + TRANSCEIVER_MODE_TX, +} transceiver_mode_t; +static transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_TX; + uint8_t* const usb_bulk_buffer = (uint8_t*)0x20004000; static volatile uint32_t usb_bulk_buffer_offset = 0; static const uint32_t usb_bulk_buffer_mask = 32768 - 1; @@ -202,12 +208,15 @@ bool usb_set_configuration( // hard-coding, this whole function can move into a shared/reusable // library. if( device->configuration && (device->configuration->number == 1) ) { - usb_endpoint_init(&usb_endpoint_bulk_in); - usb_endpoint_init(&usb_endpoint_bulk_out); + if( transceiver_mode == TRANSCEIVER_MODE_RX ) { + sgpio_configure_for_rx_deep(); + usb_endpoint_init(&usb_endpoint_bulk_in); + } else { + sgpio_configure_for_tx_deep(); + usb_endpoint_init(&usb_endpoint_bulk_out); + } usb_init_buffers_bulk(); - - sgpio_configure_for_rx_deep(); nvic_set_priority(NVIC_M4_SGPIO_IRQ, 0); nvic_enable_irq(NVIC_M4_SGPIO_IRQ); @@ -237,15 +246,26 @@ void sgpio_irqhandler() { SGPIO_CLR_STATUS_1 = 0xFFFFFFFF; uint32_t* const p = (uint32_t*)&usb_bulk_buffer[usb_bulk_buffer_offset]; - p[7] = SGPIO_REG_SS(SGPIO_SLICE_A); - p[6] = SGPIO_REG_SS(SGPIO_SLICE_I); - p[5] = SGPIO_REG_SS(SGPIO_SLICE_E); - p[4] = SGPIO_REG_SS(SGPIO_SLICE_J); - p[3] = SGPIO_REG_SS(SGPIO_SLICE_C); - p[2] = SGPIO_REG_SS(SGPIO_SLICE_K); - p[1] = SGPIO_REG_SS(SGPIO_SLICE_F); - p[0] = SGPIO_REG_SS(SGPIO_SLICE_L); - + if( transceiver_mode == TRANSCEIVER_MODE_RX ) { + p[7] = SGPIO_REG_SS(SGPIO_SLICE_A); + p[6] = SGPIO_REG_SS(SGPIO_SLICE_I); + p[5] = SGPIO_REG_SS(SGPIO_SLICE_E); + p[4] = SGPIO_REG_SS(SGPIO_SLICE_J); + p[3] = SGPIO_REG_SS(SGPIO_SLICE_C); + p[2] = SGPIO_REG_SS(SGPIO_SLICE_K); + p[1] = SGPIO_REG_SS(SGPIO_SLICE_F); + p[0] = SGPIO_REG_SS(SGPIO_SLICE_L); + } else { + SGPIO_REG_SS(SGPIO_SLICE_A) = p[7]; + SGPIO_REG_SS(SGPIO_SLICE_I) = p[6]; + SGPIO_REG_SS(SGPIO_SLICE_E) = p[5]; + SGPIO_REG_SS(SGPIO_SLICE_J) = p[4]; + SGPIO_REG_SS(SGPIO_SLICE_C) = p[3]; + SGPIO_REG_SS(SGPIO_SLICE_K) = p[2]; + SGPIO_REG_SS(SGPIO_SLICE_F) = p[1]; + SGPIO_REG_SS(SGPIO_SLICE_L) = p[0]; + } + usb_bulk_buffer_offset = (usb_bulk_buffer_offset + 32) & usb_bulk_buffer_mask; } @@ -290,14 +310,37 @@ int main(void) { max2837_rx(); ssp1_set_mode_max5864(); max5864_xcvr(); - - while(true) { - while( usb_bulk_buffer_offset < 16384 ); - usb_endpoint_schedule_no_int(&usb_endpoint_bulk_in, &usb_td_bulk[0]); - - while( usb_bulk_buffer_offset >= 16384 ); - usb_endpoint_schedule_no_int(&usb_endpoint_bulk_in, &usb_td_bulk[1]); - } + // TODO: If this turns out to be the same code, simplify. + if( transceiver_mode == TRANSCEIVER_MODE_RX ) { + while(true) { + // Wait until buffer 0 is received. + while( usb_bulk_buffer_offset < 16384 ); + + // Set up IN transfer to send buffer 0. + usb_endpoint_schedule_no_int(&usb_endpoint_bulk_in, &usb_td_bulk[0]); + + // Wait until buffer 1 is received. + while( usb_bulk_buffer_offset >= 16384 ); + + // Set up IN transfer to send buffer 1. + usb_endpoint_schedule_no_int(&usb_endpoint_bulk_in, &usb_td_bulk[1]); + } + } else { + while(true) { + // Wait until buffer 0 is transmitted. + while( usb_bulk_buffer_offset < 16384 ); + + // Set up OUT transfer to fill buffer 0. + usb_endpoint_schedule_no_int(&usb_endpoint_bulk_out, &usb_td_bulk[0]); + + // Wait until buffer 1 is transmitted. + while( usb_bulk_buffer_offset >= 16384 ); + + // Set up OUT transfer to fill buffer 1. + usb_endpoint_schedule_no_int(&usb_endpoint_bulk_out, &usb_td_bulk[1]); + } + } + return 0; } From c0cb64f3166a7c3b3d026369e6de8222a7e49db6 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 11 Oct 2012 13:07:25 -0700 Subject: [PATCH 04/11] Add support for TX mode. Add getopt control of RX or TX mode. --- host/usb_test/usb_test.c | 55 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/host/usb_test/usb_test.c b/host/usb_test/usb_test.c index 5ce79244..c984898c 100644 --- a/host/usb_test/usb_test.c +++ b/host/usb_test/usb_test.c @@ -21,7 +21,9 @@ #include #include +#include #include +#include #include #include @@ -156,13 +158,56 @@ struct libusb_transfer** prepare_transfers( return transfers; } +static void usage() { + printf("Usage:\n"); + printf("\tGo fish.\n"); +} + int main(int argc, char** argv) { - if( argc != 2 ) { - printf("Usage: usb_test \n"); - return -1; - } + int opt; + bool receive = false; + bool transmit = false; + const char* path = NULL; - const char* const path = argv[1]; + while( (opt = getopt(argc, argv, "r:t:")) != EOF ) { + switch( opt ) { + case 'r': + receive = true; + path = optarg; + break; + + case 't': + transmit = true; + path = optarg; + break; + + default: + usage(); + return 1; + } + } + + if( transmit == receive ) { + if( transmit == true ) { + fprintf(stderr, "receive and transmit options are mutually exclusive\n"); + } else { + fprintf(stderr, "specify either transmit or receive option\n"); + } + return 1; + } + + if( receive ) { + transceiver_mode = TRANSCEIVER_MODE_RX; + } + + if( transmit ) { + transceiver_mode = TRANSCEIVER_MODE_TX; + } + + if( path == NULL ) { + fprintf(stderr, "specify a path to a file to transmit/receive\n"); + return 1; + } fd = -1; uint_fast8_t endpoint_address = 0; From 6f0fda0beeafc7e4739fe9078fcb8dbb951b0740 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 11 Oct 2012 15:12:25 -0700 Subject: [PATCH 05/11] Moved transceiver_mode_t to hackrf_core.h. Changed transceiver_mode to volatile, since it's liable to be accessed at interrupt time. --- firmware/common/hackrf_core.h | 5 +++++ firmware/usb_performance/usb_performance.c | 6 +----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index 37722b1c..7eb57698 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -200,6 +200,11 @@ extern "C" /* TODO add other Pins */ +typedef enum { + TRANSCEIVER_MODE_RX, + TRANSCEIVER_MODE_TX, +} transceiver_mode_t; + void delay(uint32_t duration); void cpu_clock_init(void); diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index b5eaa6fa..a4f7fd0d 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -38,11 +38,7 @@ #include "usb_descriptor.h" #include "usb_standard_request.h" -typedef enum { - TRANSCEIVER_MODE_RX, - TRANSCEIVER_MODE_TX, -} transceiver_mode_t; -static transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_TX; +static volatile transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_TX; uint8_t* const usb_bulk_buffer = (uint8_t*)0x20004000; static volatile uint32_t usb_bulk_buffer_offset = 0; From 1bad2d8536e7486616aa7234ead9f42c700e966a Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 11 Oct 2012 15:18:16 -0700 Subject: [PATCH 06/11] Consolidated two "deep" SGPIO configuration functions into one, qualified by transceiver mode (RX or TX). 95-ish % of the code was common. --- firmware/common/sgpio.c | 101 +++------------------ firmware/common/sgpio.h | 5 +- firmware/usb_performance/usb_performance.c | 4 +- 3 files changed, 20 insertions(+), 90 deletions(-) diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index e38c3d3e..d81a5ac2 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -146,85 +146,6 @@ void sgpio_configure_for_tx() { ; } -void sgpio_configure_for_tx_deep() { - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - sgpio_configure_pin_functions(); - - // Set SGPIO output values. - SGPIO_GPIO_OUTREG = - (1L << 11) | // direction - (1L << 10); // disable - - // Enable SGPIO pin outputs. - SGPIO_GPIO_OENREG = - (1L << 11) | // direction: TX: data to CPLD - (1L << 10) | // disable - (0L << 9) | // capture - (0L << 8) | // clock - 0xFF; // data: output - - SGPIO_OUT_MUX_CFG( 8) = 0; // SGPIO: Input: clock - SGPIO_OUT_MUX_CFG( 9) = 0; // SGPIO: Input: qualifier - SGPIO_OUT_MUX_CFG(10) = (0L << 4) | (4L << 0); // GPIO: Output: disable - SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction - - for(uint_fast8_t i=0; i<8; i++) { - // SGPIO pin 0 outputs slice A bit "i". - SGPIO_OUT_MUX_CFG(i) = - (0L << 4) | // P_OE_CFG = 0 - (11L << 0); // P_OUT_CFG = 11, dout_doutm8c (8-bit mode 8c) - } - - const uint_fast8_t slice_indices[] = { - SGPIO_SLICE_A, - SGPIO_SLICE_I, - SGPIO_SLICE_E, - SGPIO_SLICE_J, - SGPIO_SLICE_C, - SGPIO_SLICE_K, - SGPIO_SLICE_F, - SGPIO_SLICE_L, - }; - - uint32_t slice_enable_mask = 0; - for(uint_fast8_t i=0; i<8; i++) { - uint_fast8_t slice_index = slice_indices[i]; - const uint_fast8_t concat_order = 3; - const uint_fast8_t concat_enable = 1; - SGPIO_MUX_CFG(slice_index) = - (concat_order << 12) | // CONCAT_ORDER = 3 (eight slices) - (concat_enable << 11) | // CONCAT_ENABLE = 1 (concatenate data) - (0L << 9) | // QUALIFIER_SLICE_MODE = X - (1L << 7) | // QUALIFIER_PIN_MODE = 1 (SGPIO9) - (3L << 5) | // QUALIFIER_MODE = 3 (external SGPIO pin) - (0L << 3) | // CLK_SOURCE_SLICE_MODE = X - (0L << 1) | // CLK_SOURCE_PIN_MODE = 0 (SGPIO8) - (1L << 0); // EXT_CLK_ENABLE = 1, external clock signal (slice) - - SGPIO_SLICE_MUX_CFG(slice_index) = - (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) - (3L << 6) | // PARALLEL_MODE = 3 (shift 8 bits per clock) - (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) - (0L << 3) | // INV_OUT_CLK = X - (1L << 2) | // CLKGEN_MODE = 1 (use external pin clock) - (1L << 1) | // CLK_CAPTURE_MODE = 1 (use falling clock edge) - (0L << 0); // MATCH_MODE = 0 (do not match data) - - SGPIO_PRESET(slice_index) = 0; // External clock, don't care - SGPIO_COUNT(slice_index) = 0; // External clock, don't care - SGPIO_POS(slice_index) = (0x1f << 8) | (0x1f << 0); - SGPIO_REG(slice_index) = 0xFFFFFFFF; // Primary output data register - SGPIO_REG_SS(slice_index) = 0xFFFFFFFF; // Shadow output data register - - slice_enable_mask |= (1 << slice_index); - } - - // Start SGPIO operation by enabling slice clocks. - SGPIO_CTRL_ENABLE = slice_enable_mask; -} - void sgpio_configure_for_rx() { // Disable all counters during configuration SGPIO_CTRL_ENABLE = 0; @@ -287,24 +208,30 @@ void sgpio_configure_for_rx() { ; } -void sgpio_configure_for_rx_deep() { +void sgpio_configure_deep(const transceiver_mode_t transceiver_mode) { // Disable all counters during configuration SGPIO_CTRL_ENABLE = 0; sgpio_configure_pin_functions(); // Set SGPIO output values. + const uint_fast8_t cpld_direction = + (transceiver_mode == TRANSCEIVER_MODE_TX) ? 1 : 0; SGPIO_GPIO_OUTREG = - (0L << 11) | // direction + (cpld_direction << 11) | // direction (1L << 10); // disable // Enable SGPIO pin outputs. + const uint_fast16_t sgpio_gpio_data_direction = + (transceiver_mode == TRANSCEIVER_MODE_TX) + ? (0xFF << 0) + : (0x00 << 0); SGPIO_GPIO_OENREG = - (1L << 11) | // direction: RX: data from CPLD + (1L << 11) | // direction (1L << 10) | // disable (0L << 9) | // capture (0L << 8) | // clock - 0x00; // data: input + sgpio_gpio_data_direction; // data: output SGPIO_OUT_MUX_CFG( 8) = 0; // SGPIO: Input: clock SGPIO_OUT_MUX_CFG( 9) = 0; // SGPIO: Input: qualifier @@ -312,9 +239,10 @@ void sgpio_configure_for_rx_deep() { SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction for(uint_fast8_t i=0; i<8; i++) { + // SGPIO pin 0 outputs slice A bit "i". SGPIO_OUT_MUX_CFG(i) = (0L << 4) | // P_OE_CFG = 0 - (9L << 0); // P_OUT_CFG = 9, dout_doutm8a (8-bit mode 8a) + (11L << 0); // P_OUT_CFG = 11, dout_doutm8c (8-bit mode 8c) } const uint_fast8_t slice_indices[] = { @@ -331,8 +259,9 @@ void sgpio_configure_for_rx_deep() { uint32_t slice_enable_mask = 0; for(uint_fast8_t i=0; i<8; i++) { uint_fast8_t slice_index = slice_indices[i]; - const uint_fast8_t concat_order = (slice_index == SGPIO_SLICE_A) ? 0 : 3; - const uint_fast8_t concat_enable = (slice_index == SGPIO_SLICE_A) ? 0 : 1; + const bool input_slice = (i == 0) && (transceiver_mode == TRANSCEIVER_MODE_RX); + const uint_fast8_t concat_order = input_slice ? 0 : 3; + const uint_fast8_t concat_enable = input_slice ? 0 : 1; SGPIO_MUX_CFG(slice_index) = (concat_order << 12) | // CONCAT_ORDER = 3 (eight slices) (concat_enable << 11) | // CONCAT_ENABLE = 1 (concatenate data) diff --git a/firmware/common/sgpio.h b/firmware/common/sgpio.h index d41acef4..622ed802 100644 --- a/firmware/common/sgpio.h +++ b/firmware/common/sgpio.h @@ -22,12 +22,13 @@ #ifndef __SGPIO_H__ #define __SGPIO_H__ +#include + void sgpio_configure_pin_functions(); void sgpio_test_interface(); void sgpio_configure_for_tx(); -void sgpio_configure_for_tx_deep(); void sgpio_configure_for_rx(); -void sgpio_configure_for_rx_deep(); +void sgpio_configure_deep(const transceiver_mode_t transceiver_mode); void sgpio_cpld_stream_enable(); void sgpio_cpld_stream_disable(); bool sgpio_cpld_stream_is_enabled(); diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index a4f7fd0d..7e8752ef 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -205,10 +205,10 @@ bool usb_set_configuration( // library. if( device->configuration && (device->configuration->number == 1) ) { if( transceiver_mode == TRANSCEIVER_MODE_RX ) { - sgpio_configure_for_rx_deep(); + sgpio_configure_deep(transceiver_mode); usb_endpoint_init(&usb_endpoint_bulk_in); } else { - sgpio_configure_for_tx_deep(); + sgpio_configure_deep(transceiver_mode); usb_endpoint_init(&usb_endpoint_bulk_out); } From 1b5574d2b9f28376c94b0254f82e4731c946c0f5 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 11 Oct 2012 15:19:01 -0700 Subject: [PATCH 07/11] RX and TX sample buffer loops turned out to be the same, so they're consolidated. --- firmware/usb_performance/usb_performance.c | 37 ++++++---------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index 7e8752ef..1a54927a 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -307,35 +307,18 @@ int main(void) { ssp1_set_mode_max5864(); max5864_xcvr(); - // TODO: If this turns out to be the same code, simplify. - if( transceiver_mode == TRANSCEIVER_MODE_RX ) { - while(true) { - // Wait until buffer 0 is received. - while( usb_bulk_buffer_offset < 16384 ); + while(true) { + // Wait until buffer 0 is transmitted/received. + while( usb_bulk_buffer_offset < 16384 ); - // Set up IN transfer to send buffer 0. - usb_endpoint_schedule_no_int(&usb_endpoint_bulk_in, &usb_td_bulk[0]); - - // Wait until buffer 1 is received. - while( usb_bulk_buffer_offset >= 16384 ); + // Set up IN transfer of buffer 0. + usb_endpoint_schedule_no_int(&usb_endpoint_bulk_in, &usb_td_bulk[0]); + + // Wait until buffer 1 is transmitted/received. + while( usb_bulk_buffer_offset >= 16384 ); - // Set up IN transfer to send buffer 1. - usb_endpoint_schedule_no_int(&usb_endpoint_bulk_in, &usb_td_bulk[1]); - } - } else { - while(true) { - // Wait until buffer 0 is transmitted. - while( usb_bulk_buffer_offset < 16384 ); - - // Set up OUT transfer to fill buffer 0. - usb_endpoint_schedule_no_int(&usb_endpoint_bulk_out, &usb_td_bulk[0]); - - // Wait until buffer 1 is transmitted. - while( usb_bulk_buffer_offset >= 16384 ); - - // Set up OUT transfer to fill buffer 1. - usb_endpoint_schedule_no_int(&usb_endpoint_bulk_out, &usb_td_bulk[1]); - } + // Set up IN transfer of buffer 1. + usb_endpoint_schedule_no_int(&usb_endpoint_bulk_in, &usb_td_bulk[1]); } return 0; From 9b579232a72f9b47ed507b5679c6e0bf5fdb160b Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 11 Oct 2012 15:45:28 -0700 Subject: [PATCH 08/11] Consolidated single-slice SGPIO configuration functions into single sgpio_configure() function. --- firmware/common/sgpio.c | 156 +++------------------ firmware/common/sgpio.h | 7 +- firmware/sgpio-rx/sgpio-rx.c | 4 +- firmware/sgpio/sgpio.c | 4 +- firmware/usb_performance/usb_performance.c | 4 +- 5 files changed, 30 insertions(+), 145 deletions(-) diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index d81a5ac2..c04f39da 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -83,132 +83,10 @@ void sgpio_test_interface() { } } -void sgpio_configure_for_tx() { - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - sgpio_configure_pin_functions(); - - // Set SGPIO output values. - SGPIO_GPIO_OUTREG = - (1L << 11) | // direction - (1L << 10); // disable - - // Enable SGPIO pin outputs. - SGPIO_GPIO_OENREG = - (1L << 11) | // direction: TX: data to CPLD - (1L << 10) | // disable - (0L << 9) | // capture - (0L << 8) | // clock - 0xFF; // data: output - - SGPIO_OUT_MUX_CFG( 8) = 0; // SGPIO: Input: clock - SGPIO_OUT_MUX_CFG( 9) = 0; // SGPIO: Input: qualifier - SGPIO_OUT_MUX_CFG(10) = (0L << 4) | (4L << 0); // GPIO: Output: disable - SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction - - for(uint_fast8_t i=0; i<8; i++) { - // SGPIO pin 0 outputs slice A bit "i". - SGPIO_OUT_MUX_CFG(i) = - (0L << 4) | // P_OE_CFG = 0 - (9L << 0); // P_OUT_CFG = 9, dout_doutm8a (8-bit mode 8a) - } - - // Slice A - SGPIO_MUX_CFG(SGPIO_SLICE_A) = - (0L << 12) | // CONCAT_ORDER = 0 (self-loop) - (1L << 11) | // CONCAT_ENABLE = 1 (concatenate data) - (0L << 9) | // QUALIFIER_SLICE_MODE = X - (1L << 7) | // QUALIFIER_PIN_MODE = 1 (SGPIO9) - (3L << 5) | // QUALIFIER_MODE = 3 (external SGPIO pin) - (0L << 3) | // CLK_SOURCE_SLICE_MODE = X - (0L << 1) | // CLK_SOURCE_PIN_MODE = 0 (SGPIO8) - (1L << 0); // EXT_CLK_ENABLE = 1, external clock signal (slice) - - SGPIO_SLICE_MUX_CFG(SGPIO_SLICE_A) = - (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) - (3L << 6) | // PARALLEL_MODE = 3 (shift 8 bits per clock) - (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) - (0L << 3) | // INV_OUT_CLK = 0 (normal clock) - (1L << 2) | // CLKGEN_MODE = 1 (use external pin clock) - (0L << 1) | // CLK_CAPTURE_MODE = 0 (use rising clock edge) - (0L << 0); // MATCH_MODE = 0 (do not match data) - - SGPIO_PRESET(SGPIO_SLICE_A) = 0; - SGPIO_COUNT(SGPIO_SLICE_A) = 0; - SGPIO_POS(SGPIO_SLICE_A) = (0x3L << 8) | (0x3L << 0); - SGPIO_REG(SGPIO_SLICE_A) = 0x80808080; // Primary output data register - SGPIO_REG_SS(SGPIO_SLICE_A) = 0x80808080; // Shadow output data register - - // Start SGPIO operation by enabling slice clocks. - SGPIO_CTRL_ENABLE = - (1L << SGPIO_SLICE_A) - ; -} - -void sgpio_configure_for_rx() { - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - sgpio_configure_pin_functions(); - - // Set SGPIO output values. - SGPIO_GPIO_OUTREG = - (0L << 11) | // direction - (1L << 10); // disable - - // Enable SGPIO pin outputs. - SGPIO_GPIO_OENREG = - (1L << 11) | // direction: RX: data from CPLD - (1L << 10) | // disable - (0L << 9) | // capture - (0L << 8) | // clock - 0x00; // data: input - - SGPIO_OUT_MUX_CFG( 8) = 0; // SGPIO: Input: clock - SGPIO_OUT_MUX_CFG( 9) = 0; // SGPIO: Input: qualifier - SGPIO_OUT_MUX_CFG(10) = (0L << 4) | (4L << 0); // GPIO: Output: disable - SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction - - for(uint_fast8_t i=0; i<8; i++) { - SGPIO_OUT_MUX_CFG(i) = - (0L << 4) | // P_OE_CFG = 0 - (9L << 0); // P_OUT_CFG = 9, dout_doutm8a (8-bit mode 8a) - } - - // Slice A - SGPIO_MUX_CFG(SGPIO_SLICE_A) = - (0L << 12) | // CONCAT_ORDER = X - (0L << 11) | // CONCAT_ENABLE = 0 (concatenate data) - (0L << 9) | // QUALIFIER_SLICE_MODE = X - (1L << 7) | // QUALIFIER_PIN_MODE = 1 (SGPIO9) - (3L << 5) | // QUALIFIER_MODE = 3 (external SGPIO pin) - (0L << 3) | // CLK_SOURCE_SLICE_MODE = X - (0L << 1) | // CLK_SOURCE_PIN_MODE = 0 (SGPIO8) - (1L << 0); // EXT_CLK_ENABLE = 1, external clock signal (slice) - - SGPIO_SLICE_MUX_CFG(SGPIO_SLICE_A) = - (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) - (3L << 6) | // PARALLEL_MODE = 3 (shift 8 bits per clock) - (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) - (0L << 3) | // INV_OUT_CLK = X - (1L << 2) | // CLKGEN_MODE = 1 (use external pin clock) - (1L << 1) | // CLK_CAPTURE_MODE = 1 (use falling clock edge) - (0L << 0); // MATCH_MODE = 0 (do not match data) - - SGPIO_PRESET(SGPIO_SLICE_A) = 0; - SGPIO_COUNT(SGPIO_SLICE_A) = 0; - SGPIO_POS(SGPIO_SLICE_A) = (0 << 8) | (0 << 0); - SGPIO_REG(SGPIO_SLICE_A) = 0xCAFEBABE; // Primary output data register - SGPIO_REG_SS(SGPIO_SLICE_A) = 0xDEADBEEF; // Shadow output data register - - // Start SGPIO operation by enabling slice clocks. - SGPIO_CTRL_ENABLE = - (1L << SGPIO_SLICE_A) - ; -} - -void sgpio_configure_deep(const transceiver_mode_t transceiver_mode) { +void sgpio_configure( + const transceiver_mode_t transceiver_mode, + const bool multi_slice +) { // Disable all counters during configuration SGPIO_CTRL_ENABLE = 0; @@ -238,11 +116,13 @@ void sgpio_configure_deep(const transceiver_mode_t transceiver_mode) { SGPIO_OUT_MUX_CFG(10) = (0L << 4) | (4L << 0); // GPIO: Output: disable SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction + const uint_fast8_t output_multiplexing_mode = + multi_slice ? 11 : 9; for(uint_fast8_t i=0; i<8; i++) { // SGPIO pin 0 outputs slice A bit "i". SGPIO_OUT_MUX_CFG(i) = (0L << 4) | // P_OE_CFG = 0 - (11L << 0); // P_OUT_CFG = 11, dout_doutm8c (8-bit mode 8c) + (output_multiplexing_mode << 0); } const uint_fast8_t slice_indices[] = { @@ -256,15 +136,19 @@ void sgpio_configure_deep(const transceiver_mode_t transceiver_mode) { SGPIO_SLICE_L, }; + const bool single_slice = !multi_slice; + const uint_fast8_t slice_count = multi_slice ? 8 : 1; + uint32_t slice_enable_mask = 0; - for(uint_fast8_t i=0; i<8; i++) { - uint_fast8_t slice_index = slice_indices[i]; + for(uint_fast8_t i=0; i void tx_test() { - sgpio_configure_for_tx(); + sgpio_configure(TRANSCEIVER_MODE_TX, false); // LSB goes out first, samples are 0x volatile uint32_t buffer[] = { @@ -54,7 +54,7 @@ void tx_test() { } void rx_test() { - sgpio_configure_for_rx(); + sgpio_configure(TRANSCEIVER_MODE_RX, false); volatile uint32_t buffer[4096]; uint32_t i = 0; diff --git a/firmware/sgpio/sgpio.c b/firmware/sgpio/sgpio.c index 88008313..fbf40ffd 100644 --- a/firmware/sgpio/sgpio.c +++ b/firmware/sgpio/sgpio.c @@ -31,7 +31,7 @@ #include void tx_test() { - sgpio_configure_for_tx(); + sgpio_configure(TRANSCEIVER_MODE_TX, false); // LSB goes out first, samples are 0x volatile uint32_t buffer[] = { @@ -52,7 +52,7 @@ void tx_test() { } void rx_test() { - sgpio_configure_for_rx(); + sgpio_configure(TRANSCEIVER_MODE_RX, false); volatile uint32_t buffer[4096]; uint32_t i = 0; diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index 1a54927a..2766981d 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -205,10 +205,10 @@ bool usb_set_configuration( // library. if( device->configuration && (device->configuration->number == 1) ) { if( transceiver_mode == TRANSCEIVER_MODE_RX ) { - sgpio_configure_deep(transceiver_mode); + sgpio_configure(transceiver_mode, true); usb_endpoint_init(&usb_endpoint_bulk_in); } else { - sgpio_configure_deep(transceiver_mode); + sgpio_configure(transceiver_mode, true); usb_endpoint_init(&usb_endpoint_bulk_out); } From a1af4356b62eec3ae978be02ed9eba38ea7016e8 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 11 Oct 2012 20:46:21 -0700 Subject: [PATCH 09/11] Reworked sgpio.c to make use of #defines for fields, instead of hard-coding shifts. Proper. --- firmware/common/sgpio.c | 99 ++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 36 deletions(-) diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index c04f39da..451e9c52 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -59,17 +59,23 @@ void sgpio_test_interface() { // Make all SGPIO controlled by SGPIO's "GPIO" registers for (uint_fast8_t i = 0; i < 16; i++) { - SGPIO_OUT_MUX_CFG(i) = (0L << 4) | (4L << 0); + SGPIO_OUT_MUX_CFG(i) = + SGPIO_OUT_MUX_CFG_P_OE_CFG(0) + | SGPIO_OUT_MUX_CFG_P_OUT_CFG(4); } // Set SGPIO output values. - SGPIO_GPIO_OUTREG = (1L << host_direction_sgpio_pin) - | (1L << host_disable_sgpio_pin); + SGPIO_GPIO_OUTREG = + (1L << host_direction_sgpio_pin) + | (1L << host_disable_sgpio_pin); // Enable SGPIO pin outputs. - SGPIO_GPIO_OENREG = (1L << host_direction_sgpio_pin) - | (1L << host_disable_sgpio_pin) | (0L << host_capture_sgpio_pin) - | (0L << host_clock_sgpio_pin) | (0xFF << 0); + SGPIO_GPIO_OENREG = + (1L << host_direction_sgpio_pin) + | (1L << host_disable_sgpio_pin) + | (0L << host_capture_sgpio_pin) + | (0L << host_clock_sgpio_pin) + | (0xFF << 0); // Configure SGPIO slices. @@ -96,8 +102,9 @@ void sgpio_configure( const uint_fast8_t cpld_direction = (transceiver_mode == TRANSCEIVER_MODE_TX) ? 1 : 0; SGPIO_GPIO_OUTREG = - (cpld_direction << 11) | // direction - (1L << 10); // disable + (cpld_direction << 11) + | (1L << 10) // disable + ; // Enable SGPIO pin outputs. const uint_fast16_t sgpio_gpio_data_direction = @@ -105,24 +112,38 @@ void sgpio_configure( ? (0xFF << 0) : (0x00 << 0); SGPIO_GPIO_OENREG = - (1L << 11) | // direction - (1L << 10) | // disable - (0L << 9) | // capture - (0L << 8) | // clock - sgpio_gpio_data_direction; // data: output + (1L << 11) // direction + | (1L << 10) // disable + | (0L << 9) // capture + | (0L << 8) // clock + | sgpio_gpio_data_direction + ; - SGPIO_OUT_MUX_CFG( 8) = 0; // SGPIO: Input: clock - SGPIO_OUT_MUX_CFG( 9) = 0; // SGPIO: Input: qualifier - SGPIO_OUT_MUX_CFG(10) = (0L << 4) | (4L << 0); // GPIO: Output: disable - SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction + SGPIO_OUT_MUX_CFG( 8) = // SGPIO: Input: clock + SGPIO_OUT_MUX_CFG_P_OE_CFG(0) + | SGPIO_OUT_MUX_CFG_P_OUT_CFG(0) + ; + SGPIO_OUT_MUX_CFG( 9) = // SGPIO: Input: qualifier + SGPIO_OUT_MUX_CFG_P_OE_CFG(0) + | SGPIO_OUT_MUX_CFG_P_OUT_CFG(0) + ; + SGPIO_OUT_MUX_CFG(10) = // GPIO: Output: disable + SGPIO_OUT_MUX_CFG_P_OE_CFG(0) + | SGPIO_OUT_MUX_CFG_P_OUT_CFG(4) + ; + SGPIO_OUT_MUX_CFG(11) = // GPIO: Output: direction + SGPIO_OUT_MUX_CFG_P_OE_CFG(0) + | SGPIO_OUT_MUX_CFG_P_OUT_CFG(4) + ; const uint_fast8_t output_multiplexing_mode = multi_slice ? 11 : 9; for(uint_fast8_t i=0; i<8; i++) { // SGPIO pin 0 outputs slice A bit "i". SGPIO_OUT_MUX_CFG(i) = - (0L << 4) | // P_OE_CFG = 0 - (output_multiplexing_mode << 0); + SGPIO_OUT_MUX_CFG_P_OE_CFG(0) + | SGPIO_OUT_MUX_CFG_P_OUT_CFG(output_multiplexing_mode) + ; } const uint_fast8_t slice_indices[] = { @@ -146,28 +167,34 @@ void sgpio_configure( const uint_fast8_t concat_order = (input_slice || single_slice) ? 0 : 3; const uint_fast8_t concat_enable = (input_slice || single_slice) ? 0 : 1; const uint_fast8_t pos = multi_slice ? 0x1f : 0x03; + SGPIO_MUX_CFG(slice_index) = - (concat_order << 12) | - (concat_enable << 11) | - (0L << 9) | // QUALIFIER_SLICE_MODE = X - (1L << 7) | // QUALIFIER_PIN_MODE = 1 (SGPIO9) - (3L << 5) | // QUALIFIER_MODE = 3 (external SGPIO pin) - (0L << 3) | // CLK_SOURCE_SLICE_MODE = X - (0L << 1) | // CLK_SOURCE_PIN_MODE = 0 (SGPIO8) - (1L << 0); // EXT_CLK_ENABLE = 1, external clock signal (slice) + SGPIO_MUX_CFG_CONCAT_ORDER(concat_order) + | SGPIO_MUX_CFG_CONCAT_ENABLE(concat_enable) + | SGPIO_MUX_CFG_QUALIFIER_SLICE_MODE(0) + | SGPIO_MUX_CFG_QUALIFIER_PIN_MODE(1) + | SGPIO_MUX_CFG_QUALIFIER_MODE(3) + | SGPIO_MUX_CFG_CLK_SOURCE_SLICE_MODE(0) + | SGPIO_MUX_CFG_CLK_SOURCE_PIN_MODE(0) + | SGPIO_MUX_CFG_EXT_CLK_ENABLE(1) + ; SGPIO_SLICE_MUX_CFG(slice_index) = - (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) - (3L << 6) | // PARALLEL_MODE = 3 (shift 8 bits per clock) - (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) - (0L << 3) | // INV_OUT_CLK = X - (1L << 2) | // CLKGEN_MODE = 1 (use external pin clock) - (1L << 1) | // CLK_CAPTURE_MODE = 1 (use falling clock edge) - (0L << 0); // MATCH_MODE = 0 (do not match data) + SGPIO_SLICE_MUX_CFG_INV_QUALIFIER(0) + | SGPIO_SLICE_MUX_CFG_PARALLEL_MODE(3) + | SGPIO_SLICE_MUX_CFG_DATA_CAPTURE_MODE(0) + | SGPIO_SLICE_MUX_CFG_INV_OUT_CLK(0) + | SGPIO_SLICE_MUX_CFG_CLKGEN_MODE(1) + | SGPIO_SLICE_MUX_CFG_CLK_CAPTURE_MODE(1) + | SGPIO_SLICE_MUX_CFG_MATCH_MODE(0) + ; SGPIO_PRESET(slice_index) = 0; // External clock, don't care SGPIO_COUNT(slice_index) = 0; // External clock, don't care - SGPIO_POS(slice_index) = (pos << 8) | (pos << 0); + SGPIO_POS(slice_index) = + SGPIO_POS_POS_RESET(pos) + | SGPIO_POS_POS(pos) + ; SGPIO_REG(slice_index) = 0x80808080; // Primary output data register SGPIO_REG_SS(slice_index) = 0x80808080; // Shadow output data register @@ -190,4 +217,4 @@ void sgpio_cpld_stream_disable() { bool sgpio_cpld_stream_is_enabled() { return (SGPIO_GPIO_OUTREG & (1L << 10)) == 0; -} \ No newline at end of file +} From 9824a723b779981e3c5ddd320627e1fcb0741770 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 12 Oct 2012 09:45:18 -0700 Subject: [PATCH 10/11] Moved invariant in sgpio_configure() loop out of loop. Originally, so I could use the value to calculate another invariant. --- firmware/common/sgpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index 451e9c52..d53c3f87 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -157,6 +157,7 @@ void sgpio_configure( SGPIO_SLICE_L, }; + const uint_fast8_t pos = multi_slice ? 0x1f : 0x03; const bool single_slice = !multi_slice; const uint_fast8_t slice_count = multi_slice ? 8 : 1; @@ -166,7 +167,6 @@ void sgpio_configure( const bool input_slice = (i == 0) && (transceiver_mode == TRANSCEIVER_MODE_RX); const uint_fast8_t concat_order = (input_slice || single_slice) ? 0 : 3; const uint_fast8_t concat_enable = (input_slice || single_slice) ? 0 : 1; - const uint_fast8_t pos = multi_slice ? 0x1f : 0x03; SGPIO_MUX_CFG(slice_index) = SGPIO_MUX_CFG_CONCAT_ORDER(concat_order) From 8d14de21ce0d502daaa42c7ecee37a153a64ce06 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 12 Oct 2012 09:46:49 -0700 Subject: [PATCH 11/11] Fixed prior commit, where I lost the switch between endpoints based on RX or TX mode. --- firmware/usb_performance/usb_performance.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index 2766981d..376863b8 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -312,13 +312,21 @@ int main(void) { while( usb_bulk_buffer_offset < 16384 ); // Set up IN transfer of buffer 0. - usb_endpoint_schedule_no_int(&usb_endpoint_bulk_in, &usb_td_bulk[0]); + usb_endpoint_schedule_no_int( + (transceiver_mode == TRANSCEIVER_MODE_RX) + ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, + &usb_td_bulk[0] + ); // Wait until buffer 1 is transmitted/received. while( usb_bulk_buffer_offset >= 16384 ); // Set up IN transfer of buffer 1. - usb_endpoint_schedule_no_int(&usb_endpoint_bulk_in, &usb_td_bulk[1]); + usb_endpoint_schedule_no_int( + (transceiver_mode == TRANSCEIVER_MODE_RX) + ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, + &usb_td_bulk[1] + ); } return 0;