From 5989465eb98b4f653de984b0339db0d7e3b29cdc Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 14:30:28 -0700 Subject: [PATCH] Add SGPIO configuration API and code, extracted from existing SGPIO projects. --- firmware/common/sgpio.c | 301 +++++++++++++++++++++++++++++++++++ firmware/common/sgpio.h | 34 ++++ firmware/sgpio-rx/Makefile | 1 + firmware/sgpio-rx/sgpio-rx.c | 192 ++-------------------- firmware/sgpio/Makefile | 1 + firmware/sgpio/sgpio.c | 187 +--------------------- 6 files changed, 354 insertions(+), 362 deletions(-) create mode 100644 firmware/common/sgpio.c create mode 100644 firmware/common/sgpio.h diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c new file mode 100644 index 00000000..2db69608 --- /dev/null +++ b/firmware/common/sgpio.c @@ -0,0 +1,301 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include + +void sgpio_configure_pin_functions() { + scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); + scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); + scu_pinmux(SCU_PINMUX_SGPIO2, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); + scu_pinmux(SCU_PINMUX_SGPIO3, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); + scu_pinmux(SCU_PINMUX_SGPIO4, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); + scu_pinmux(SCU_PINMUX_SGPIO5, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); + scu_pinmux(SCU_PINMUX_SGPIO6, SCU_GPIO_FAST | SCU_CONF_FUNCTION0); + scu_pinmux(SCU_PINMUX_SGPIO7, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); + scu_pinmux(SCU_PINMUX_SGPIO8, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); + scu_pinmux(SCU_PINMUX_SGPIO9, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); + scu_pinmux(SCU_PINMUX_SGPIO10, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); + scu_pinmux(SCU_PINMUX_SGPIO11, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); + scu_pinmux(SCU_PINMUX_SGPIO12, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); + scu_pinmux(SCU_PINMUX_SGPIO13, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); + scu_pinmux(SCU_PINMUX_SGPIO14, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); + scu_pinmux(SCU_PINMUX_SGPIO15, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); +} + + +void sgpio_test_interface() { + const uint_fast8_t host_clock_sgpio_pin = 8; // Input + const uint_fast8_t host_capture_sgpio_pin = 9; // Input + const uint_fast8_t host_disable_sgpio_pin = 10; // Output + const uint_fast8_t host_direction_sgpio_pin = 11; // Output + + SGPIO_GPIO_OENREG = 0; // All inputs for the moment. + + // Disable all counters during configuration + SGPIO_CTRL_ENABLE = 0; + + sgpio_configure_pin_functions(); + + // 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); + } + + // Set SGPIO output values. + 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); + + // Configure SGPIO slices. + + // Enable codec data stream. + SGPIO_GPIO_OUTREG &= ~(1L << host_disable_sgpio_pin); + + while (1) { + for (uint_fast8_t i = 0; i < 8; i++) { + SGPIO_GPIO_OUTREG ^= (1L << i); + } + } +} + +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_for_rx_deep() { + // 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) + } + + 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 = (slice_index == SGPIO_SLICE_A) ? 0 : 3; + const uint_fast8_t concat_enable = (slice_index == SGPIO_SLICE_A) ? 0 : 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_cpld_stream_enable() { + // Enable codec data stream. + SGPIO_GPIO_OUTREG &= ~(1L << 10); +} + +void sgpio_cpld_stream_disable() { + // Disable codec data stream. + SGPIO_GPIO_OUTREG |= (1L << 10); +} + +bool sgpio_cpld_stream_is_enabled() { + return (SGPIO_GPIO_OUTREG & (1L << 10)) == 0; +} \ No newline at end of file diff --git a/firmware/common/sgpio.h b/firmware/common/sgpio.h new file mode 100644 index 00000000..8b8f471c --- /dev/null +++ b/firmware/common/sgpio.h @@ -0,0 +1,34 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __SGPIO_H__ +#define __SGPIO_H__ + +void sgpio_configure_pin_functions(); +void sgpio_test_interface(); +void sgpio_configure_for_tx(); +void sgpio_configure_for_rx(); +void sgpio_configure_for_rx_deep(); +void sgpio_cpld_stream_enable(); +void sgpio_cpld_stream_disable(); +bool sgpio_cpld_stream_is_enabled(); + +#endif//__SGPIO_H__ diff --git a/firmware/sgpio-rx/Makefile b/firmware/sgpio-rx/Makefile index 9f750ea3..894853b0 100644 --- a/firmware/sgpio-rx/Makefile +++ b/firmware/sgpio-rx/Makefile @@ -4,6 +4,7 @@ BINARY = sgpio-rx SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/sgpio.c \ ../common/si5351c.c \ ../common/max2837.c \ ../common/max5864.c \ diff --git a/firmware/sgpio-rx/sgpio-rx.c b/firmware/sgpio-rx/sgpio-rx.c index 284c1d69..ff87195b 100644 --- a/firmware/sgpio-rx/sgpio-rx.c +++ b/firmware/sgpio-rx/sgpio-rx.c @@ -30,127 +30,11 @@ #include #include #include +#include -void configure_sgpio_pin_functions() { - scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); - scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); - scu_pinmux(SCU_PINMUX_SGPIO2, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); - scu_pinmux(SCU_PINMUX_SGPIO3, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); - scu_pinmux(SCU_PINMUX_SGPIO4, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); - scu_pinmux(SCU_PINMUX_SGPIO5, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); - scu_pinmux(SCU_PINMUX_SGPIO6, SCU_GPIO_FAST | SCU_CONF_FUNCTION0); - scu_pinmux(SCU_PINMUX_SGPIO7, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO8, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO9, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); - scu_pinmux(SCU_PINMUX_SGPIO10, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO11, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO12, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO13, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); - scu_pinmux(SCU_PINMUX_SGPIO14, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); - scu_pinmux(SCU_PINMUX_SGPIO15, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); -} - -void test_sgpio_interface() { - const uint_fast8_t host_clock_sgpio_pin = 8; // Input - const uint_fast8_t host_capture_sgpio_pin = 9; // Input - const uint_fast8_t host_disable_sgpio_pin = 10; // Output - const uint_fast8_t host_direction_sgpio_pin = 11; // Output - - SGPIO_GPIO_OENREG = 0; // All inputs for the moment. - - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - configure_sgpio_pin_functions(); - - // 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); - } - - // Set SGPIO output values. - 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); - - // Configure SGPIO slices. - - // Enable codec data stream. - SGPIO_GPIO_OUTREG &= ~(1L << host_disable_sgpio_pin); - - while (1) { - for (uint_fast8_t i = 0; i < 8; i++) { - SGPIO_GPIO_OUTREG ^= (1L << i); - } - } -} - -void configure_sgpio_test_tx() { - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - configure_sgpio_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 - - 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 tx_test() { + sgpio_configure_for_tx(); + // LSB goes out first, samples are 0x volatile uint32_t buffer[] = { 0xda808080, @@ -160,8 +44,7 @@ void configure_sgpio_test_tx() { }; uint32_t i = 0; - // Enable codec data stream. - SGPIO_GPIO_OUTREG &= ~(1L << 10); + sgpio_cpld_stream_enable(); while(true) { while(SGPIO_STATUS_1 == 0); @@ -170,72 +53,15 @@ void configure_sgpio_test_tx() { } } -void configure_sgpio_test_rx() { - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - configure_sgpio_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 - - 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) = (0x3L << 8) | (0x3L << 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 rx_test() { + sgpio_configure_for_rx(); volatile uint32_t buffer[4096]; uint32_t i = 0; int16_t magsq; int8_t sigi, sigq; - // Enable codec data stream. - SGPIO_GPIO_OUTREG &= ~(1L << 10); + sgpio_cpld_stream_enable(); gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */ while(true) { @@ -293,7 +119,7 @@ int main(void) { ssp1_set_mode_max5864(); max5864_xcvr(); - configure_sgpio_test_rx(); + rx_test(); gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */ while (1) { diff --git a/firmware/sgpio/Makefile b/firmware/sgpio/Makefile index 24eefbd1..1c214bbb 100644 --- a/firmware/sgpio/Makefile +++ b/firmware/sgpio/Makefile @@ -4,6 +4,7 @@ BINARY = sgpio SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/sgpio.c \ ../common/si5351c.c \ ../common/max2837.c \ ../common/max5864.c diff --git a/firmware/sgpio/sgpio.c b/firmware/sgpio/sgpio.c index 5d17238d..88008313 100644 --- a/firmware/sgpio/sgpio.c +++ b/firmware/sgpio/sgpio.c @@ -28,126 +28,10 @@ #include #include +#include -void configure_sgpio_pin_functions() { - scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); - scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); - scu_pinmux(SCU_PINMUX_SGPIO2, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); - scu_pinmux(SCU_PINMUX_SGPIO3, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); - scu_pinmux(SCU_PINMUX_SGPIO4, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); - scu_pinmux(SCU_PINMUX_SGPIO5, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); - scu_pinmux(SCU_PINMUX_SGPIO6, SCU_GPIO_FAST | SCU_CONF_FUNCTION0); - scu_pinmux(SCU_PINMUX_SGPIO7, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO8, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO9, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); - scu_pinmux(SCU_PINMUX_SGPIO10, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO11, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO12, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO13, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); - scu_pinmux(SCU_PINMUX_SGPIO14, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); - scu_pinmux(SCU_PINMUX_SGPIO15, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); -} - -void test_sgpio_interface() { - const uint_fast8_t host_clock_sgpio_pin = 8; // Input - const uint_fast8_t host_capture_sgpio_pin = 9; // Input - const uint_fast8_t host_disable_sgpio_pin = 10; // Output - const uint_fast8_t host_direction_sgpio_pin = 11; // Output - - SGPIO_GPIO_OENREG = 0; // All inputs for the moment. - - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - configure_sgpio_pin_functions(); - - // 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); - } - - // Set SGPIO output values. - 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); - - // Configure SGPIO slices. - - // Enable codec data stream. - SGPIO_GPIO_OUTREG &= ~(1L << host_disable_sgpio_pin); - - while (1) { - for (uint_fast8_t i = 0; i < 8; i++) { - SGPIO_GPIO_OUTREG ^= (1L << i); - } - } -} - -void configure_sgpio_test_tx() { - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - configure_sgpio_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 tx_test() { + sgpio_configure_for_tx(); // LSB goes out first, samples are 0x volatile uint32_t buffer[] = { @@ -158,9 +42,8 @@ void configure_sgpio_test_tx() { }; uint32_t i = 0; - // Enable codec data stream. - SGPIO_GPIO_OUTREG &= ~(1L << 10); - + sgpio_cpld_stream_enable(); + while(true) { while(SGPIO_STATUS_1 == 0); SGPIO_REG_SS(SGPIO_SLICE_A) = buffer[(i++) & 3]; @@ -168,67 +51,13 @@ void configure_sgpio_test_tx() { } } -void configure_sgpio_test_rx() { - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - configure_sgpio_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) - (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) = (3 << 8) | (3 << 0); - SGPIO_REG(SGPIO_SLICE_A) = 0xCAFEBABE; // Primary output data register - SGPIO_REG_SS(SGPIO_SLICE_A) = 0xDEADBEEF; // Shadow output data register +void rx_test() { + sgpio_configure_for_rx(); volatile uint32_t buffer[4096]; uint32_t i = 0; - // Enable codec data stream. - SGPIO_GPIO_OUTREG &= ~(1L << 10); + sgpio_cpld_stream_enable(); while(true) { while(SGPIO_STATUS_1 == 0);