Files

copied
Last update 2 years 1 month by Gianpaolo Macario
Filesfirmwarecommon
..
rad1o
xapp058
LPC4320_M4_memory.ld
LPC4330_M4_memory.ld
LPC43xx_M0_memory.ld
LPC43xx_M4_M0_image_from_text.ld
LPC43xx_M4_memory.ld
README
bitband.c
bitband.h
clkin.c
clkin.h
configure_file.cmake
cpld_jtag.c
cpld_jtag.h
cpld_xc2c.c
cpld_xc2c.h
crc.c
crc.h
fault_handler.c
fault_handler.h
firmware_info.c
firmware_info.h
gpdma.c
gpdma.h
gpio.h
gpio_lpc.c
gpio_lpc.h
hackrf_core.c
hackrf_core.h
hackrf_ui.c
hackrf_ui.h
i2c_bus.c
i2c_bus.h
i2c_lpc.c
i2c_lpc.h
m0_bin.s.cmake
m0_sleep.c
max2837.c
max2837.h
max2837_regs.def
max2837_target.c
max2837_target.h
max2839.c
max2839.h
max2839_regs.def
max2839_target.c
max2839_target.h
max283x.c
max283x.h
max2871.c
max2871.h
max2871_regs.c
max2871_regs.h
max5864.c
max5864.h
max5864_target.c
max5864_target.h
mixer.c
mixer.h
operacake.c
operacake.h
operacake_sctimer.c
operacake_sctimer.h
platform_detect.c
platform_detect.h
portapack.c
portapack.h
rf_path.c
rf_path.h
rffc5071.c
rffc5071.h
rffc5071_regs.def
rffc5071_spi.c
rffc5071_spi.h
rom_iap.c
rom_iap.h
sct.h
sgpio.c
sgpio.h
si5351c.c
si5351c.h
spi_bus.c
spi_bus.h
spi_ssp.c
spi_ssp.h
streaming.c
streaming.h
tuning.c
tuning.h
ui_portapack.c
ui_portapack.h
ui_rad1o.c
ui_rad1o.h
usb.c
usb.h
usb_queue.c
usb_queue.h
usb_request.c
usb_request.h
usb_standard_request.c
usb_standard_request.h
usb_type.h
w25q80bv.c
w25q80bv.h
w25q80bv_target.c
w25q80bv_target.h
operacake_sctimer.c
/* * Copyright 2017-2022 Great Scott Gadgets <info@greatscottgadgets.com> * Copyright 2018 Schuyler St. Leger * * 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 "operacake_sctimer.h" #include <hackrf_core.h> #include <libopencm3/lpc43xx/sgpio.h> #include <libopencm3/lpc43xx/rgu.h> #include <libopencm3/lpc43xx/scu.h> #include <libopencm3/lpc43xx/gima.h> #include "sct.h" #define U1CTRL_SET SCT_OUT14_SET #define U1CTRL_CLR SCT_OUT14_CLR #define U2CTRL0_SET SCT_OUT13_SET #define U2CTRL0_CLR SCT_OUT13_CLR #define U2CTRL1_SET SCT_OUT12_SET #define U2CTRL1_CLR SCT_OUT12_CLR #define U3CTRL0_SET SCT_OUT11_SET #define U3CTRL0_CLR SCT_OUT11_CLR #define U3CTRL1_SET SCT_OUT8_SET #define U3CTRL1_CLR SCT_OUT8_CLR static uint32_t default_output = 0; /** * Configure the SCTimer to rotate the antennas with the Operacake in phase with * the sample clock. This will configure the SCTimer to output to the pins for * GPIO control of the Operacake, however the Operacake must be configured for * GPIO control. The timing is not set in this function. * * To trigger the antenna switching synchronously with the sample clock, the * SGPIO is configured to output its clock (f=2 * sample clock) to the SCTimer. */ void operacake_sctimer_init() { // We start by resetting the SCTimer RESET_CTRL1 = RESET_CTRL1_SCT_RST; // Delay to allow reset sigal to be processed // The reset generator uses a 12MHz clock (IRC) // The difference between this and the core clock (CCLK) // determines this value (CCLK/IRC). // The value used here is a bit shorter than would be required, since // there are additional instructions that fill the time. If the duration of // the actions from here to the first access to the SCTimer is changed, then // this delay may need to be increased. delay(8); // Pin definitions for the HackRF // U2CTRL0 scu_pinmux( P7_4, SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_FUNCTION1); // U2CTRL1 scu_pinmux( P7_5, SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_FUNCTION1); // U3CTRL0 scu_pinmux( P7_6, SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_FUNCTION1); // U3CTRL1 scu_pinmux( P7_7, SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_FUNCTION1); // U1CTRL scu_pinmux( P7_0, SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_FUNCTION1); // Configure the SGPIO to output the clock (f=2 * sample clock) on pin 12 SGPIO_OUT_MUX_CFG12 = SGPIO_OUT_MUX_CFG_P_OUT_CFG(0x08) | // clkout output mode SGPIO_OUT_MUX_CFG_P_OE_CFG(0); // gpio_oe SGPIO_GPIO_OENREG |= BIT12; // Use the GIMA to connect the SGPIO clock to the SCTimer GIMA_CTIN_1_IN = 0x2 << 4; // Route SGPIO12 to SCTIN1 // We configure this register first, because the user manual says to SCT_CONFIG |= SCT_CONFIG_UNIFY_32_BIT | SCT_CONFIG_CLKMODE_PRESCALED_BUS_CLOCK | SCT_CONFIG_CKSEL_RISING_EDGES_ON_INPUT_1; // Halt the SCTimer to enable it to be configured SCT_CTRL = SCT_CTRL_HALT_L(1); // Prescaler - run at half the SGPIO clock (ie: at the sample clock) SCT_CTRL |= SCT_CTRL_PRE_L(1); // Default to state 0, events disabled SCT_STATE = 0; // Enable the SCTimer SCT_CTRL &= ~SCT_CTRL_HALT_L(1); } static uint32_t operacake_sctimer_port_to_output(uint8_t port) { int bit0 = (port >> 0) & 1; int bit1 = (port >> 1) & 1; int bit2 = (port >> 2) & 1; return (bit0 << 11) | (bit0 << 13) | (bit1 << 8) | (bit1 << 12) | (((~bit2) & 1) << 14); } void operacake_sctimer_enable(bool enable) { SCT_CTRL = SCT_CTRL_HALT_L(1); SCT_STATE = enable; SCT_CTRL &= ~SCT_CTRL_HALT_L(1); } void operacake_sctimer_set_dwell_times(struct operacake_dwell_times* times, int n) { SCT_CTRL = SCT_CTRL_HALT_L(1); uint32_t counter = 0; uint32_t bit0_set = 0, bit0_clr = 0, bit1_set = 0, bit1_clr = 0, bit2_set = 0, bit2_clr = 0; for (int i = 0; i < n; i++) { // Enable event i in state 1, set to match on match register i SCT_EVn_STATE(i) = SCT_EVn_STATE_STATEMSK1(1); SCT_EVn_CTRL(i) = SCT_EVn_CTRL_COMBMODE_MATCH | SCT_EVn_CTRL_MATCHSEL(i); // Calculate the counter value to match on counter += times[i].dwell; // Wrapping from SCT_LIMIT seems to add an extra cycle, // so we reduce the counter value for the first event. if (i == 0) { counter -= 1; } SCT_MATCHn(i) = counter; SCT_MATCHRELn(i) = counter; // The match event selects the *next* port, so retreive that here. int port; if (i == n - 1) { port = times[0].port; } else { port = times[i + 1].port; } int bit0 = (port >> 0) & 1; int bit1 = (port >> 1) & 1; int bit2 = (port >> 2) & 1; // Find bits to set/clear on event i bit0_set |= SCT_OUTn_SETm(bit0, i); bit0_clr |= SCT_OUTn_CLRm(~bit0, i); bit1_set |= SCT_OUTn_SETm(bit1, i); bit1_clr |= SCT_OUTn_CLRm(~bit1, i); // (U1CTRL is inverted) bit2_set |= SCT_OUTn_SETm(~bit2, i); bit2_clr |= SCT_OUTn_CLRm(bit2, i); } // Apply event set/clear mappings U2CTRL0_SET = bit0_set; U2CTRL0_CLR = bit0_clr; U3CTRL0_SET = bit0_set; U3CTRL0_CLR = bit0_clr; U2CTRL1_SET = bit1_set; U2CTRL1_CLR = bit1_clr; U3CTRL1_SET = bit1_set; U3CTRL1_CLR = bit1_clr; U1CTRL_SET = bit2_set; U1CTRL_CLR = bit2_clr; // Set output pins to select the first port in the list default_output = operacake_sctimer_port_to_output(times[0].port); SCT_OUTPUT = default_output; // Reset counter on final event SCT_LIMIT = (1 << (n - 1)); SCT_CTRL &= ~SCT_CTRL_HALT_L(1); } void operacake_sctimer_stop() { // Halt timer SCT_CTRL |= SCT_CTRL_HALT_L(1); } /** * This will reset the state of the SCTimer, but retains its configuration. * This reset will return the selected antenna to 1 and samesided. This is * called by set_transceiver_mode so the HackRF starts capturing with the * same antenna selected each time. */ void operacake_sctimer_reset_state() { SCT_CTRL |= SCT_CTRL_HALT_L(1); // Clear the counter value SCT_CTRL |= SCT_CTRL_CLRCTR_L(1); // Reset to select the first port SCT_OUTPUT = default_output; SCT_CTRL &= ~SCT_CTRL_HALT_L(1); }
Report a bug