Compare commits

...
Sign in to create a new pull request.

24 commits

Author SHA1 Message Date
Martin Ling
2ad78ce6de Use IS macros for all conditional compilation.
Some checks failed
Check code style / clang-format-2 (push) Failing after 13s
Check code style / clang-format-3 (push) Failing after 7s
Check includes / includes-check (HACKRF_ONE, 3.10.0) (push) Failing after 3s
Check includes / includes-check (HACKRF_ONE, latest) (push) Failing after 4s
Check includes / includes-check (JAWBREAKER, 3.10.0) (push) Failing after 4s
Check includes / includes-check (JAWBREAKER, latest) (push) Failing after 5s
Check includes / includes-check (PRALINE, 3.10.0) (push) Failing after 6s
Check includes / includes-check (PRALINE, latest) (push) Failing after 8s
Check includes / includes-check (RAD1O, 3.10.0) (push) Failing after 9s
Check includes / includes-check (RAD1O, latest) (push) Failing after 9s
Check includes / includes-check (UNIVERSAL, 3.10.0) (push) Failing after 7s
Check includes / includes-check (UNIVERSAL, latest) (push) Failing after 6s
Build / host (4.0.0, map[os:macos shell:bash]) (push) Has been cancelled
Build / host (latest, --install-prefix=/usr/local, map[os:windows shell:msys2]) (push) Has been cancelled
Build / host (3.10.0, map[os:macos shell:bash]) (push) Has been cancelled
Build / host (3.16.0, map[os:macos shell:bash]) (push) Has been cancelled
Build / host (3.21.0, -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake --install-prefix=$env:GITHUB_WORKSPACE/install, map[os:windows shell:pwsh]) (push) Has been cancelled
Build / host (3.21.0, map[os:macos shell:bash]) (push) Has been cancelled
Build / host (4.0.0, -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake --install-prefix=$env:GITHUB_WORKSPACE/install, map[os:windows shell:pwsh]) (push) Has been cancelled
Build / host (latest, -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake --install-prefix=$env:GITHUB_WORKSPACE/install, map[os:windows shell:pwsh]) (push) Has been cancelled
Build / host (latest, map[os:macos shell:bash]) (push) Has been cancelled
Build / firmware (HACKRF_ONE, latest, windows) (push) Has been cancelled
Build / firmware (JAWBREAKER, latest, windows) (push) Has been cancelled
Build / firmware (PRALINE, 3.10.0, macos) (push) Has been cancelled
Build / firmware (PRALINE, latest, macos) (push) Has been cancelled
Build / firmware (PRALINE, latest, windows) (push) Has been cancelled
Build / firmware (UNIVERSAL, latest, macos) (push) Has been cancelled
Build / firmware (UNIVERSAL, latest, windows) (push) Has been cancelled
Build / firmware (RAD1O, latest, windows) (push) Has been cancelled
Build / firmware (UNIVERSAL, 3.10.0, macos) (push) Has been cancelled
2026-04-14 12:11:01 +01:00
Martin Ling
4d40c806f2 firmware: Separate compile-time and runtime platform checks. 2026-04-11 23:19:57 +01:00
Martin Ling
62378c8b1c firmware: Use macros to simplify platform-specific code. 2026-04-11 23:19:57 +01:00
Martin Ling
338c248617 max283x: Add macros to simplify variant-specific dispatch. 2026-04-11 23:19:57 +01:00
Martin Ling
05d3ef58d0 max283x: Move platform switch inside max283x_setup(). 2026-04-11 23:19:57 +01:00
Martin Ling
02f5e6347f Jenkinsfile: add tests with BOARD=UNIVERSAL. 2026-04-11 23:19:57 +01:00
Martin Ling
a26c19146e Add UNIVERSAL firmware build to GitHub Actions. 2026-04-11 23:19:57 +01:00
Martin Ling
74b8410aee Add UNIVERSAL board target. 2026-04-11 23:19:57 +01:00
Martin Ling
6a6d5d3acf Universalize: firmware/hackrf_usb
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-11 23:19:57 +01:00
Martin Ling
b6bbb393a2 Universalize: hackrf_core.{c,h}, selftest.h, tune_config.h
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-11 23:19:57 +01:00
Martin Ling
292ba6dabd Universalize: radio.c
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-11 23:19:49 +01:00
Martin Ling
37fb675e5c Universalize: sgpio.{c,h}
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-11 23:19:38 +01:00
Martin Ling
797fdd8153 Universalize: w25q80bv.c
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-11 23:19:38 +01:00
Martin Ling
70162eef43 Universalize: operacake_sctimer.c
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-11 23:19:38 +01:00
Martin Ling
23011713b4 Universalize: hackrf_ui.c
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-11 23:19:38 +01:00
Martin Ling
3a5ddb940e Universalize: tuning.{c,h}
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-11 23:19:38 +01:00
Martin Ling
c8ec62437e Universalize: mixer.{c,h}, usb_api_register.c
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-11 23:19:38 +01:00
Martin Ling
54d4cdc641 Universalize: rf_path.{c,h}
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-11 23:19:38 +01:00
Martin Ling
fcc53a312b Universalize: si5351.c
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-11 23:19:35 +01:00
Martin Ling
59a0dbf970 Universalize: rffc5071.{c,h}
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-11 22:31:29 +01:00
Martin Ling
7116bb6759 Universalize: max283x.{c,h}
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-11 22:31:29 +01:00
Martin Ling
a769653084 Universalize: cpld_jtag.{c,h}
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-11 22:31:29 +01:00
Martin Ling
1e0aebd797 Universalize: platform_scu.{c,h}
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-11 22:31:29 +01:00
Martin Ling
106864a6e1 Universalize: platform_gpio.{c,h}
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-11 22:31:29 +01:00
50 changed files with 2904 additions and 2056 deletions

View file

@ -159,7 +159,7 @@ jobs:
strategy:
matrix:
os: ['macos', 'ubuntu', 'windows']
board: ['HACKRF_ONE', 'JAWBREAKER', 'RAD1O', 'PRALINE']
board: ['HACKRF_ONE', 'JAWBREAKER', 'RAD1O', 'PRALINE', 'UNIVERSAL']
cmake: ['3.10.0', 'latest']
exclude:
- os: 'windows'

View file

@ -13,7 +13,7 @@ jobs:
options: --user 0
strategy:
matrix:
board: ['HACKRF_ONE', 'JAWBREAKER', 'RAD1O', 'PRALINE']
board: ['HACKRF_ONE', 'JAWBREAKER', 'RAD1O', 'PRALINE', 'UNIVERSAL']
cmake: ['3.10.0', 'latest']
# Don't cancel all builds when one fails

122
Jenkinsfile vendored
View file

@ -1,5 +1,21 @@
import org.jenkinsci.plugins.workflow.steps.FlowInterruptedException
def docker_args = '''--group-add=20 --group-add=46 --device-cgroup-rule="c 189:* rmw" \
--device-cgroup-rule="c 166:* rmw" -v /dev/bus/usb:/dev/bus/usb \
-v /tmp/req_pipe:/tmp/req_pipe -v /tmp/res_pipe:/tmp/res_pipe'''
def h1_test = '''python3 ci-scripts/hackrf_test.py --ci --log log \
--hostdir host/build/hackrf-tools/src/ \
--fwupdate firmware/hackrf_usb/build/ \
--tester 0000000000000000325866e629a25623 \
--eut RunningFromRAM --unattended --rev r4'''
def hpro_test = '''python3 ci-scripts/hackrf_pro_test.py --ci --log log \
--hostdir host/build/hackrf-tools/src \
--fwupdate firmware/hackrf_usb/build \
--tester 0000000000000000a06063c82338145f \
--eut RunningFromRAM -p --rev r1.2'''
pipeline {
agent any
stages {
@ -8,19 +24,17 @@ pipeline {
sh 'docker build -t hackrf https://github.com/greatscottgadgets/hackrf.git'
}
}
stage('Test HackRF One') {
stage('Test HackRF One with BOARD=HACKRF_ONE') {
agent {
docker {
image 'hackrf'
reuseNode true
args '''--group-add=20 --group-add=46 --device-cgroup-rule="c 189:* rmw" \
--device-cgroup-rule="c 166:* rmw" -v /dev/bus/usb:/dev/bus/usb \
-v /tmp/req_pipe:/tmp/req_pipe -v /tmp/res_pipe:/tmp/res_pipe'''
args docker_args
}
}
steps {
sh './ci-scripts/install_host.sh'
sh './ci-scripts/build_h1_firmware.sh'
sh './ci-scripts/build_firmware.sh HACKRF_ONE'
script {
allOff();
}
@ -38,13 +52,7 @@ pipeline {
sh 'sleep 1s'
script {
// Allow 5 minutes for the test to run
runCommand(5, 'MINUTES', "HackRF One Test",
'''python3 ci-scripts/hackrf_test.py --ci --log log \
--hostdir host/build/hackrf-tools/src/ \
--fwupdate firmware/hackrf_usb/build/ \
--tester 0000000000000000325866e629a25623 \
--eut RunningFromRAM --unattended --rev r4'''
)
runCommand(5, 'MINUTES', "HackRF One Test", h1_test)
allOff()
}
}
@ -57,19 +65,58 @@ pipeline {
}
}
}
stage('Test HackRF Pro') {
stage('Test HackRF One with BOARD=UNIVERSAL') {
agent {
docker {
image 'hackrf'
reuseNode true
args '''--group-add=20 --group-add=46 --device-cgroup-rule="c 189:* rmw" \
--device-cgroup-rule="c 166:* rmw" -v /dev/bus/usb:/dev/bus/usb \
-v /tmp/req_pipe:/tmp/req_pipe -v /tmp/res_pipe:/tmp/res_pipe'''
args docker_args
}
}
steps {
sh './ci-scripts/install_host.sh'
sh './ci-scripts/build_hpro_firmware.sh'
sh './ci-scripts/build_firmware.sh UNIVERSAL'
script {
allOff();
}
retry(3) {
script {
reset('h1_eut')
}
sh 'sleep 1s'
sh './ci-scripts/test_host.sh'
}
retry(3) {
script {
reset('h1_tester h1_eut')
}
sh 'sleep 1s'
script {
// Allow 5 minutes for the test to run
runCommand(5, 'MINUTES', "HackRF One Test", h1_test)
allOff()
}
}
retry(3) {
script {
reset('h1_eut')
}
sh 'sleep 1s'
sh 'python3 ci-scripts/test_sgpio_debug.py'
}
}
}
stage('Test HackRF Pro with BOARD=PRALINE') {
agent {
docker {
image 'hackrf'
reuseNode true
args "$docker_args"
}
}
steps {
sh './ci-scripts/install_host.sh'
sh './ci-scripts/build_firmware.sh PRALINE'
script {
allOff();
}
@ -87,13 +134,40 @@ pipeline {
sh 'sleep 1s'
script {
// Allow 5 minutes for the test to run
runCommand(5, 'MINUTES', "HackRF Pro Test",
'''python3 ci-scripts/hackrf_pro_test.py --ci --log log \
--hostdir host/build/hackrf-tools/src \
--fwupdate firmware/hackrf_usb/build \
--tester 0000000000000000a06063c82338145f \
--eut RunningFromRAM -p --rev r1.2'''
)
runCommand(5, 'MINUTES', "HackRF Pro Test", hpro_test)
}
}
}
}
stage('Test HackRF Pro with BOARD=UNIVERSAL') {
agent {
docker {
image 'hackrf'
reuseNode true
args "$docker_args"
}
}
steps {
sh './ci-scripts/install_host.sh'
sh './ci-scripts/build_firmware.sh UNIVERSAL'
script {
allOff();
}
retry(3) {
script {
reset('hpro_eut')
}
sh 'sleep 1s'
sh './ci-scripts/test_host.sh'
}
retry(3) {
script {
reset('hpro_tester hpro_eut')
}
sh 'sleep 1s'
script {
// Allow 5 minutes for the test to run
runCommand(5, 'MINUTES', "HackRF Pro Test", hpro_test)
}
}
}

View file

@ -4,6 +4,6 @@ git submodule init
git submodule update
cd firmware/hackrf_usb
rm -rf build
cmake -DBOARD=PRALINE -B build
cmake -DBOARD=$1 -B build
cmake --build build
cd ../..

View file

@ -1,9 +0,0 @@
#!/bin/bash
set -e
git submodule init
git submodule update
cd firmware/hackrf_usb
rm -rf build
cmake -DBOARD=HACKRF_ONE -B build
cmake --build build
cd ../..

View file

@ -19,16 +19,16 @@
* Boston, MA 02110-1301, USA.
*/
#if !defined(PRALINE)
#include <stdint.h>
#endif
#include "cpld_jtag.h"
#if !defined(PRALINE)
#include "platform_detect.h"
#if defined(IS_NOT_PRALINE)
#include <stdint.h>
#include "xapp058/micro.h"
#endif
#ifndef PRALINE
#if defined(IS_NOT_PRALINE)
static refill_buffer_cb refill_buffer;
static uint32_t xsvf_buffer_len, xsvf_pos;
static unsigned char* xsvf_buffer;
@ -41,25 +41,37 @@ void cpld_jtag_take(jtag_t* const jtag)
/* Set initial GPIO state to the voltages of the internal or external pull-ups/downs,
* to avoid any glitches.
*/
#if (defined HACKRF_ONE || defined PRALINE)
gpio_set(gpio->gpio_pp_tms);
#endif
gpio_clear(gpio->gpio_tck);
#ifndef PRALINE
gpio_set(gpio->gpio_tms);
gpio_set(gpio->gpio_tdi);
#if defined(IS_EXPANSION_COMPATIBLE)
if (IS_EXPANSION_COMPATIBLE) {
gpio_set(gpio->gpio_pp_tms);
}
#endif
#if (defined HACKRF_ONE || defined PRALINE)
/* Do not drive PortaPack-specific TMS pin initially, just to be cautious. */
gpio_input(gpio->gpio_pp_tms);
gpio_input(gpio->gpio_pp_tdo);
gpio_clear(gpio->gpio_tck);
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
gpio_set(gpio->gpio_tms);
gpio_set(gpio->gpio_tdi);
}
#endif
#if defined(IS_EXPANSION_COMPATIBLE)
if (IS_EXPANSION_COMPATIBLE) {
/* Do not drive PortaPack-specific TMS pin initially, just to be cautious. */
gpio_input(gpio->gpio_pp_tms);
gpio_input(gpio->gpio_pp_tdo);
}
#endif
gpio_output(gpio->gpio_tck);
#ifndef PRALINE
gpio_output(gpio->gpio_tms);
gpio_output(gpio->gpio_tdi);
gpio_input(gpio->gpio_tdo);
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
gpio_output(gpio->gpio_tms);
gpio_output(gpio->gpio_tdi);
gpio_input(gpio->gpio_tdo);
}
#endif
}
@ -70,20 +82,26 @@ void cpld_jtag_release(jtag_t* const jtag)
/* Make all pins inputs when JTAG interface not active.
* Let the pull-ups/downs do the work.
*/
#if (defined HACKRF_ONE || defined PRALINE)
/* Do not drive PortaPack-specific pins, initially, just to be cautious. */
gpio_input(gpio->gpio_pp_tms);
gpio_input(gpio->gpio_pp_tdo);
#if defined(IS_EXPANSION_COMPATIBLE)
if (IS_EXPANSION_COMPATIBLE) {
/* Do not drive PortaPack-specific pins, initially, just to be cautious. */
gpio_input(gpio->gpio_pp_tms);
gpio_input(gpio->gpio_pp_tdo);
}
#endif
gpio_input(gpio->gpio_tck);
#ifndef PRALINE
gpio_input(gpio->gpio_tms);
gpio_input(gpio->gpio_tdi);
gpio_input(gpio->gpio_tdo);
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
gpio_input(gpio->gpio_tms);
gpio_input(gpio->gpio_tdi);
gpio_input(gpio->gpio_tdo);
}
#endif
}
#ifndef PRALINE
#if defined(IS_NOT_PRALINE)
/* return 0 if success else return error code see xsvfExecute() */
int cpld_jtag_program(
jtag_t* const jtag,

View file

@ -24,15 +24,16 @@
#include <stdint.h>
#include "gpio.h"
#include "platform_detect.h"
typedef struct {
gpio_t gpio_tck;
#ifndef PRALINE
#if defined(IS_NOT_PRALINE)
gpio_t gpio_tms;
gpio_t gpio_tdi;
gpio_t gpio_tdo;
#endif
#if (defined HACKRF_ONE || defined PRALINE)
#if defined(IS_EXPANSION_COMPATIBLE)
gpio_t gpio_pp_tms;
gpio_t gpio_pp_tdo;
#endif

View file

@ -30,6 +30,9 @@
#define SUPPORTED_PLATFORM PLATFORM_RAD1O
#elif PRALINE
#define SUPPORTED_PLATFORM PLATFORM_PRALINE
#elif UNIVERSAL
#define SUPPORTED_PLATFORM \
(PLATFORM_PRALINE | PLATFORM_HACKRF1_OG | PLATFORM_HACKRF1_R9)
#else
#define SUPPORTED_PLATFORM 0
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 Great Scott Gadgets <info@greatscottgadgets.com>
* Copyright 2012-2026 Great Scott Gadgets <info@greatscottgadgets.com>
* Copyright 2012 Benjamin Vernoux <titanmkd@gmail.com>
* Copyright 2012 Jared Boone <jared@sharebrained.com>
*
@ -36,13 +36,14 @@ extern "C" {
#include "max283x.h"
#include "max5864.h"
#include "mixer.h"
#include "platform_detect.h"
#include "radio.h"
#include "rf_path.h"
#include "sgpio.h"
#include "si5351c.h"
#include "spi_ssp.h"
#include "w25q80bv.h"
#if defined(PRALINE)
#if defined(IS_PRALINE)
#include "fpga.h"
#include "ice40_spi.h"
#endif
@ -51,7 +52,8 @@ extern "C" {
extern si5351c_driver_t clock_gen;
extern ssp_config_t ssp_config_w25q80bv;
#ifdef PRALINE
extern max283x_driver_t max283x;
#if defined(IS_PRALINE)
extern ice40_spi_driver_t ice40;
extern fpga_driver_t fpga;
#endif
@ -70,28 +72,27 @@ void clock_gen_init(void);
void clock_gen_shutdown(void);
void ssp1_set_mode_max283x(void);
void ssp1_set_mode_max5864(void);
#ifdef PRALINE
#if defined(IS_PRALINE)
void ssp1_set_mode_ice40(void);
#endif
void pin_shutdown(void);
void pin_setup(void);
#ifdef PRALINE
#if defined(IS_PRALINE)
void enable_1v2_power(void);
void disable_1v2_power(void);
void enable_3v3aux_power(void);
void disable_3v3aux_power(void);
#else
#endif
void enable_1v8_power(void);
void disable_1v8_power(void);
#endif
fp_28_36_t sample_rate_set(const fp_28_36_t sample_rate, const bool program);
clock_source_t activate_best_clock_source(void);
#if (defined HACKRF_ONE || defined RAD1O || defined PRALINE)
#if defined(IS_RAD1O) || defined(IS_HACKRF_ONE) || defined(IS_PRALINE)
void enable_rf_power(void);
void disable_rf_power(void);
#endif
@ -112,7 +113,7 @@ void trigger_enable(const bool enable);
void halt_and_flash(const uint32_t duration);
#ifdef PRALINE
#if defined(IS_PRALINE)
typedef enum {
P1_SIGNAL_TRIGGER_IN = 0,
P1_SIGNAL_AUX_CLK1 = 1,

View file

@ -23,11 +23,12 @@
#include <stddef.h>
#include "hackrf_ui.h"
#include "platform_detect.h"
#include "transceiver_mode.h"
#if defined(PRALINE) || defined(HACKRF_ONE)
#if defined(IS_EXPANSION_COMPATIBLE)
#include "ui_portapack.h"
#endif
#if defined(RAD1O)
#if defined(IS_RAD1O)
#include "ui_rad1o.h"
#endif
@ -82,14 +83,18 @@ const hackrf_ui_t* hackrf_ui(void)
{
/* Detect on first use. If no UI hardware is detected, use a stub function table. */
if (ui == NULL && ui_enabled) {
#if (defined HACKRF_ONE || defined PRALINE)
if (portapack_hackrf_ui_init) {
ui = portapack_hackrf_ui_init();
#if defined(IS_EXPANSION_COMPATIBLE)
if (IS_EXPANSION_COMPATIBLE) {
if (portapack_hackrf_ui_init) {
ui = portapack_hackrf_ui_init();
}
}
#endif
#ifdef RAD1O
if (rad1o_ui_setup) {
ui = rad1o_ui_setup();
#if defined(IS_RAD1O)
if (IS_RAD1O) {
if (rad1o_ui_setup) {
ui = rad1o_ui_setup();
}
}
#endif
}

View file

@ -25,33 +25,39 @@
#include "max283x.h"
#include "platform_detect.h"
#include "platform_gpio.h"
#include "spi_bus.h"
#if defined(PRALINE)
#include "max2831.h"
#if defined(IS_PRALINE)
#include "max2831_target.h"
#else
#include "max2837.h"
#endif
#if defined(IS_NOT_PRALINE)
#include "max2837_target.h"
#include "max2839.h"
#endif
#if defined(IS_H1_R9)
#include "max2839_target.h"
#endif
extern spi_bus_t spi_bus_ssp1;
#ifdef PRALINE
#if defined(IS_PRALINE)
max2831_driver_t max2831 = {
.bus = &spi_bus_ssp1,
.target_init = max2831_target_init,
.set_mode = max2831_target_set_mode,
};
#else
#endif
#if defined(IS_NOT_PRALINE)
max2837_driver_t max2837 = {
.bus = &spi_bus_ssp1,
.target_init = max2837_target_init,
.set_mode = max2837_target_set_mode,
};
#endif
#if defined(IS_HACKRF_ONE)
max2839_driver_t max2839 = {
.bus = &spi_bus_ssp1,
.target_init = max2839_target_init,
@ -60,132 +66,136 @@ max2839_driver_t max2839 = {
#endif
/* Initialize chip. */
void max283x_setup(max283x_driver_t* const drv, max283x_variant_t type)
void max283x_setup(max283x_driver_t* const drv)
{
drv->type = type;
const platform_gpio_t* gpio = platform_gpio();
/* MAX283x GPIO PinMux */
#if defined(PRALINE)
max2831.gpio_enable = gpio->max283x_enable;
max2831.gpio_rxtx = gpio->max283x_rx_enable;
max2831.gpio_rxhp = gpio->max2831_rxhp;
max2831.gpio_ld = gpio->max2831_ld;
#else
max2837.gpio_enable = gpio->max283x_enable;
max2837.gpio_rx_enable = gpio->max283x_rx_enable;
max2837.gpio_tx_enable = gpio->max283x_tx_enable;
max2839.gpio_enable = gpio->max283x_enable;
max2839.gpio_rxtx = gpio->max283x_rx_enable;
#endif
switch (type) {
#ifdef PRALINE
case MAX2831_VARIANT:
#if defined(IS_PRALINE)
if (IS_PRALINE) {
drv->type = MAX2831_VARIANT;
max2831.gpio_enable = gpio->max283x_enable;
max2831.gpio_rxtx = gpio->max283x_rx_enable;
max2831.gpio_rxhp = gpio->max2831_rxhp;
max2831.gpio_ld = gpio->max2831_ld;
memcpy(&drv->drv.max2831, &max2831, sizeof(max2831));
max2831_setup(&drv->drv.max2831);
break;
#else
case MAX2837_VARIANT:
memcpy(&drv->drv.max2837, &max2837, sizeof(max2837));
max2837_setup(&drv->drv.max2837);
break;
case MAX2839_VARIANT:
memcpy(&drv->drv.max2839, &max2839, sizeof(max2839));
max2839_setup(&drv->drv.max2839);
break;
#endif
}
#endif
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
#if defined(IS_H1_R9)
if (IS_H1_R9) {
drv->type = MAX2839_VARIANT;
max2839.gpio_enable = gpio->max283x_enable;
max2839.gpio_rxtx = gpio->max283x_rx_enable;
memcpy(&drv->drv.max2839, &max2839, sizeof(max2839));
max2839_setup(&drv->drv.max2839);
}
#endif
#if defined(IS_NOT_H1_R9)
if (IS_NOT_H1_R9) {
drv->type = MAX2837_VARIANT;
max2837.gpio_enable = gpio->max283x_enable;
max2837.gpio_rx_enable = gpio->max283x_rx_enable;
max2837.gpio_tx_enable = gpio->max283x_tx_enable;
memcpy(&drv->drv.max2837, &max2837, sizeof(max2837));
max2837_setup(&drv->drv.max2837);
}
#endif
}
#endif
}
/* Macros to simplify dispatch of variant-specific operations. */
/* clang-format off */
#if defined(UNIVERSAL)
// UNIVERSAL: all variants
#define DISPATCH(_drv, _max2831, _max2837, _max2839) \
if (_drv->type == MAX2831_VARIANT) { \
_max2831; \
} else if (_drv->type == MAX2837_VARIANT) { \
_max2837; \
} else { \
_max2839; \
}
#elif defined(HACKRF_ONE)
// HACKRF_ONE: MAX2837 and MAX2839 only
#define DISPATCH(_drv, _max2831, _max2837, _max2839) \
if (_drv->type == MAX2837_VARIANT) { \
_max2837; \
} else { \
_max2839; \
}
#elif defined(PRALINE)
// PRALINE: MAX2831 only
#define DISPATCH(_drv, _max2831, _max2837, _max2839) \
(void) drv; \
_max2831
#else
// JAWBREAKER, RAD1O: MAX2837 only
#define DISPATCH(_drv, _max2831, _max2837, _max2839) \
(void) drv; \
_max2837
#endif
#define CALL(_drv, _func, ...) \
DISPATCH(drv, \
max2831_ ## _func(&_drv->drv.max2831, ##__VA_ARGS__), \
max2837_ ## _func(&_drv->drv.max2837, ##__VA_ARGS__), \
max2839_ ## _func(&_drv->drv.max2839, ##__VA_ARGS__) \
); \
#define RESULT(_drv, _type, _func, ...) ({ \
_type _result; \
DISPATCH(drv, \
_result = max2831_ ## _func(&_drv->drv.max2831, ##__VA_ARGS__), \
_result = max2837_ ## _func(&_drv->drv.max2837, ##__VA_ARGS__), \
_result = max2839_ ## _func(&_drv->drv.max2839, ##__VA_ARGS__) \
); \
_result; \
})
#define CONSTANT(_drv, _type, _name) ({\
_type value; \
DISPATCH(drv, \
value = MAX2831_ ## _name, \
value = MAX2837_ ## _name, \
value = MAX2839_ ## _name \
); \
value; \
})
#define PRALINE_ONLY(_drv, _max2831) DISPATCH(_drv, _max2831, , )
/* clang-format on */
/* Returns the number of registers supported by the driver. */
uint16_t max283x_num_regs(max283x_driver_t* const drv)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
return MAX2831_NUM_REGS;
break;
#else
case MAX2837_VARIANT:
return MAX2837_NUM_REGS;
break;
case MAX2839_VARIANT:
return MAX2839_NUM_REGS;
break;
#endif
}
return 0;
return CONSTANT(drv, uint16_t, NUM_REGS);
}
/* Returns the maximum data register value supported by the driver. */
uint16_t max283x_data_regs_max_value(max283x_driver_t* const drv)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
return MAX2831_DATA_REGS_MAX_VALUE;
break;
#else
case MAX2837_VARIANT:
return MAX2837_DATA_REGS_MAX_VALUE;
break;
case MAX2839_VARIANT:
return MAX2839_DATA_REGS_MAX_VALUE;
break;
#endif
}
return 0;
return CONSTANT(drv, uint16_t, DATA_REGS_MAX_VALUE);
}
/* Read a register via SPI. Save a copy to memory and return
* value. Mark clean. */
uint16_t max283x_reg_read(max283x_driver_t* const drv, uint8_t r)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
return max2831_reg_read(&drv->drv.max2831, r);
break;
#else
case MAX2837_VARIANT:
return max2837_reg_read(&drv->drv.max2837, r);
break;
case MAX2839_VARIANT:
return max2839_reg_read(&drv->drv.max2839, r);
break;
#endif
}
return 0;
return RESULT(drv, uint16_t, reg_read, r);
}
/* Write value to register via SPI and save a copy to memory. Mark
* clean. */
void max283x_reg_write(max283x_driver_t* const drv, uint8_t r, uint16_t v)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
max2831_reg_write(&drv->drv.max2831, r, v);
break;
#else
case MAX2837_VARIANT:
max2837_reg_write(&drv->drv.max2837, r, v);
break;
case MAX2839_VARIANT:
max2839_reg_write(&drv->drv.max2839, r, v);
break;
#endif
}
CALL(drv, reg_write, r, v);
}
/* Write all dirty registers via SPI from memory. Mark all clean. Some
@ -193,120 +203,43 @@ void max283x_reg_write(max283x_driver_t* const drv, uint8_t r, uint16_t v)
* provided routines for those operations. */
void max283x_regs_commit(max283x_driver_t* const drv)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
max2831_regs_commit(&drv->drv.max2831);
break;
#else
case MAX2837_VARIANT:
max2837_regs_commit(&drv->drv.max2837);
break;
case MAX2839_VARIANT:
max2839_regs_commit(&drv->drv.max2839);
break;
#endif
}
CALL(drv, regs_commit);
}
void max283x_set_mode(max283x_driver_t* const drv, const max283x_mode_t new_mode)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
max2831_set_mode(&drv->drv.max2831, (max2831_mode_t) new_mode);
break;
#else
case MAX2837_VARIANT:
max2837_set_mode(&drv->drv.max2837, (max2837_mode_t) new_mode);
break;
case MAX2839_VARIANT:
max2839_set_mode(&drv->drv.max2839, (max2839_mode_t) new_mode);
break;
#endif
}
DISPATCH(
drv,
max2831_set_mode(&drv->drv.max2831, (max2831_mode_t) new_mode),
max2837_set_mode(&drv->drv.max2837, (max2837_mode_t) new_mode),
max2839_set_mode(&drv->drv.max2839, (max2839_mode_t) new_mode));
}
max283x_mode_t max283x_mode(max283x_driver_t* const drv)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
return (max283x_mode_t) max2831_mode(&drv->drv.max2831);
break;
#else
case MAX2837_VARIANT:
return (max283x_mode_t) max2837_mode(&drv->drv.max2837);
break;
case MAX2839_VARIANT:
return (max283x_mode_t) max2839_mode(&drv->drv.max2839);
break;
#endif
}
return 0;
DISPATCH(
drv,
return (max283x_mode_t) max2831_mode(&drv->drv.max2831),
return (max283x_mode_t) max2837_mode(&drv->drv.max2837),
return (max283x_mode_t) max2839_mode(&drv->drv.max2839));
}
/* Turn on/off all chip functions. Does not control oscillator and CLKOUT */
void max283x_start(max283x_driver_t* const drv)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
max2831_start(&drv->drv.max2831);
break;
#else
case MAX2837_VARIANT:
max2837_start(&drv->drv.max2837);
break;
case MAX2839_VARIANT:
max2839_start(&drv->drv.max2839);
break;
#endif
}
CALL(drv, start);
}
void max283x_stop(max283x_driver_t* const drv)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
max2831_stop(&drv->drv.max2831);
break;
#else
case MAX2837_VARIANT:
max2837_stop(&drv->drv.max2837);
break;
case MAX2839_VARIANT:
max2839_stop(&drv->drv.max2839);
break;
#endif
}
CALL(drv, stop);
}
/* Set frequency in Hz. Frequency setting is a multi-step function
* where order of register writes matters. */
void max283x_set_frequency(max283x_driver_t* const drv, uint32_t freq)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
max2831_set_frequency(&drv->drv.max2831, freq);
break;
#else
case MAX2837_VARIANT:
max2837_set_frequency(&drv->drv.max2837, freq);
break;
case MAX2839_VARIANT:
max2839_set_frequency(&drv->drv.max2839, freq);
break;
#endif
}
CALL(drv, set_frequency, freq);
}
uint32_t max283x_set_lpf_bandwidth(
@ -314,194 +247,65 @@ uint32_t max283x_set_lpf_bandwidth(
const max283x_mode_t mode,
const uint32_t bandwidth_hz)
{
#ifndef PRALINE
#if !defined(IS_PRALINE)
(void) mode;
#endif
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
DISPATCH(
drv,
return max2831_set_lpf_bandwidth(
&drv->drv.max2831,
(max2831_mode_t) mode,
bandwidth_hz);
break;
#else
case MAX2837_VARIANT:
return max2837_set_lpf_bandwidth(&drv->drv.max2837, bandwidth_hz);
break;
case MAX2839_VARIANT:
return max2839_set_lpf_bandwidth(&drv->drv.max2839, bandwidth_hz);
break;
#endif
}
return 0;
bandwidth_hz),
return max2837_set_lpf_bandwidth(&drv->drv.max2837, bandwidth_hz),
return max2839_set_lpf_bandwidth(&drv->drv.max2839, bandwidth_hz));
}
bool max283x_set_lna_gain(max283x_driver_t* const drv, const uint32_t gain_db)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
return max2831_set_lna_gain(&drv->drv.max2831, gain_db);
break;
#else
case MAX2837_VARIANT:
return max2837_set_lna_gain(&drv->drv.max2837, gain_db);
break;
case MAX2839_VARIANT:
return max2839_set_lna_gain(&drv->drv.max2839, gain_db);
break;
#endif
}
return false;
return RESULT(drv, bool, set_lna_gain, gain_db);
}
bool max283x_set_vga_gain(max283x_driver_t* const drv, const uint32_t gain_db)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
return max2831_set_vga_gain(&drv->drv.max2831, gain_db);
break;
#else
case MAX2837_VARIANT:
return max2837_set_vga_gain(&drv->drv.max2837, gain_db);
break;
case MAX2839_VARIANT:
return max2839_set_vga_gain(&drv->drv.max2839, gain_db);
break;
#endif
}
return false;
return RESULT(drv, bool, set_vga_gain, gain_db);
}
bool max283x_set_txvga_gain(max283x_driver_t* const drv, const uint32_t gain_db)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
return max2831_set_txvga_gain(&drv->drv.max2831, gain_db);
break;
#else
case MAX2837_VARIANT:
return max2837_set_txvga_gain(&drv->drv.max2837, gain_db);
break;
case MAX2839_VARIANT:
return max2839_set_txvga_gain(&drv->drv.max2839, gain_db);
break;
#endif
}
return false;
return RESULT(drv, bool, set_txvga_gain, gain_db);
}
void max283x_tx(max283x_driver_t* const drv)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
max2831_tx(&drv->drv.max2831);
break;
#else
case MAX2837_VARIANT:
max2837_tx(&drv->drv.max2837);
break;
case MAX2839_VARIANT:
max2839_tx(&drv->drv.max2839);
break;
#endif
}
CALL(drv, tx);
}
void max283x_rx(max283x_driver_t* const drv)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
max2831_rx(&drv->drv.max2831);
break;
#else
case MAX2837_VARIANT:
max2837_rx(&drv->drv.max2837);
break;
case MAX2839_VARIANT:
max2839_rx(&drv->drv.max2839);
break;
#endif
}
CALL(drv, rx);
}
/* Set MAX2831 receiver high-pass filter corner frequency in Hz */
void max283x_set_rx_hpf_frequency(
max283x_driver_t* const drv,
const max283x_rx_hpf_freq_t freq)
{
#ifndef PRALINE
#if !defined(IS_PRALINE)
(void) freq;
#endif
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
PRALINE_ONLY(
drv,
max2831_set_rx_hpf_frequency(
&drv->drv.max2831,
(max2831_rx_hpf_freq_t) freq);
break;
#else
case MAX2837_VARIANT:
// unsupported
break;
case MAX2839_VARIANT:
// unsupported
break;
#endif
}
(max2831_rx_hpf_freq_t) freq));
}
void max283x_tx_calibration(max283x_driver_t* const drv)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
max2831_tx_calibration(&drv->drv.max2831);
break;
#else
case MAX2837_VARIANT:
// unsupported - use max283x_set_mode instead
break;
case MAX2839_VARIANT:
// unsupported - use max283x_set_mode instead
break;
#endif
}
PRALINE_ONLY(drv, max2831_tx_calibration(&drv->drv.max2831));
}
void max283x_rx_calibration(max283x_driver_t* const drv)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
max2831_rx_calibration(&drv->drv.max2831);
break;
#else
case MAX2837_VARIANT:
// unsupported - use max283x_set_mode instead
break;
case MAX2839_VARIANT:
// unsupported - use max283x_set_mode instead
break;
#endif
}
PRALINE_ONLY(drv, max2831_rx_calibration(&drv->drv.max2831));
}

View file

@ -26,10 +26,15 @@
#include <stdbool.h>
#include <stdint.h>
#if defined(PRALINE)
#include "platform_detect.h"
#if defined(IS_PRALINE)
#include "max2831.h"
#else
#endif
#if defined(IS_NOT_PRALINE)
#include "max2837.h"
#endif
#if defined(IS_H1_R9)
#include "max2839.h"
#endif
@ -51,10 +56,13 @@ typedef enum {
} max283x_rx_hpf_freq_t;
typedef enum {
#ifdef PRALINE
#if defined(IS_PRALINE)
MAX2831_VARIANT,
#else
#endif
#if defined(IS_NOT_PRALINE)
MAX2837_VARIANT,
#endif
#if defined(IS_H1_R9)
MAX2839_VARIANT,
#endif
} max283x_variant_t;
@ -63,17 +71,20 @@ typedef struct {
max283x_variant_t type;
union {
#ifdef PRALINE
#if defined(IS_PRALINE)
max2831_driver_t max2831;
#else
#endif
#if defined(IS_NOT_PRALINE)
max2837_driver_t max2837;
#endif
#if defined(IS_H1_R9)
max2839_driver_t max2839;
#endif
} drv;
} max283x_driver_t;
/* Initialize chip. */
void max283x_setup(max283x_driver_t* const drv, max283x_variant_t type);
void max283x_setup(max283x_driver_t* const drv);
/* Returns the number of registers supported by the driver. */
uint16_t max283x_num_regs(max283x_driver_t* const drv);

View file

@ -24,6 +24,8 @@
#include <stdbool.h>
#include <stdint.h>
#include <libopencm3/lpc43xx/scu.h>
#include "max2871_regs.h"
#include "selftest.h"
#include "platform_scu.h"
@ -33,7 +35,6 @@
#define LOG printf
#else
#define LOG(x, ...)
#include <libopencm3/lpc43xx/scu.h>
#endif
static uint32_t max2871_spi_read(max2871_driver_t* const drv);

View file

@ -20,103 +20,143 @@
*/
#include "mixer.h"
#include "platform_detect.h"
#include "platform_gpio.h"
#if defined(JAWBREAKER) || defined(HACKRF_ONE) || defined(PRALINE)
#if defined(IS_RAD1O)
#include "max2871.h"
#endif
#if defined(IS_NOT_RAD1O)
#include "rffc5071.h"
#include "rffc5071_spi.h"
#include "spi_bus.h"
#elif defined(RAD1O)
#include "max2871.h"
#endif
#if defined(JAWBREAKER) || defined(HACKRF_ONE) || defined(PRALINE)
#if defined(IS_NOT_RAD1O)
static rffc5071_spi_config_t rffc5071_spi_config;
spi_bus_t spi_bus_rffc5071 = {
static spi_bus_t spi_bus_rffc5071 = {
.config = &rffc5071_spi_config,
.start = rffc5071_spi_start,
.stop = rffc5071_spi_stop,
.transfer = rffc5071_spi_transfer,
.transfer_gather = rffc5071_spi_transfer_gather,
};
#endif
mixer_driver_t mixer = {
.bus = &spi_bus_rffc5071,
};
#elif defined(RAD1O)
mixer_driver_t mixer = {};
#if defined(IS_NOT_RAD1O)
.rffc5071.bus = &spi_bus_rffc5071,
#endif
};
void mixer_bus_setup(mixer_driver_t* const mixer)
{
(void) mixer;
#if defined(JAWBREAKER) || defined(HACKRF_ONE) || defined(PRALINE)
const platform_gpio_t* gpio = platform_gpio();
rffc5071_spi_config = (rffc5071_spi_config_t){
.gpio_select = gpio->rffc5072_select,
.gpio_clock = gpio->rffc5072_clock,
.gpio_data = gpio->rffc5072_data,
};
spi_bus_start(&spi_bus_rffc5071, &rffc5071_spi_config);
#if defined(IS_NOT_RAD1O)
if (IS_NOT_RAD1O) {
const platform_gpio_t* gpio = platform_gpio();
rffc5071_spi_config = (rffc5071_spi_config_t){
.gpio_select = gpio->rffc5072_select,
.gpio_clock = gpio->rffc5072_clock,
.gpio_data = gpio->rffc5072_data,
};
spi_bus_start(&spi_bus_rffc5071, &rffc5071_spi_config);
}
#endif
}
void mixer_setup(mixer_driver_t* const mixer)
void mixer_setup(mixer_driver_t* const mixer, mixer_variant_t type)
{
mixer->type = type;
const platform_gpio_t* gpio = platform_gpio();
#if defined(JAWBREAKER) || defined(HACKRF_ONE) || defined(PRALINE)
mixer->gpio_reset = gpio->rffc5072_reset;
#if defined(PRALINE)
mixer->gpio_ld = gpio->rffc5072_ld;
#endif
rffc5071_setup(mixer);
#elif defined(RAD1O)
mixer->gpio_vco_ce = gpio->vco_ce;
mixer->gpio_vco_sclk = gpio->vco_sclk;
mixer->gpio_vco_sdata = gpio->vco_sdata;
mixer->gpio_vco_le = gpio->vco_le;
mixer->gpio_synt_rfout_en = gpio->synt_rfout_en;
mixer->gpio_vco_mux = gpio->vco_mux;
max2871_setup(mixer);
/* Mixer GPIO serial interface PinMux */
#if defined(IS_PRALINE)
if (IS_PRALINE) {
mixer->rffc5071.gpio_ld = gpio->rffc5072_ld;
}
#endif
#if defined(IS_NOT_RAD1O)
if (IS_NOT_RAD1O) {
mixer->rffc5071.gpio_reset = gpio->rffc5072_reset;
rffc5071_setup(&mixer->rffc5071);
}
#endif
#if defined(IS_RAD1O)
if (IS_RAD1O) {
mixer->max2871.gpio_vco_ce = gpio->vco_ce;
mixer->max2871.gpio_vco_sclk = gpio->vco_sclk;
mixer->max2871.gpio_vco_sdata = gpio->vco_sdata;
mixer->max2871.gpio_vco_le = gpio->vco_le;
mixer->max2871.gpio_synt_rfout_en = gpio->synt_rfout_en;
mixer->max2871.gpio_vco_mux = gpio->vco_mux;
max2871_setup(&mixer->max2871);
}
#endif
}
uint64_t mixer_set_frequency(mixer_driver_t* const mixer, uint64_t hz)
{
#if defined(JAWBREAKER) || defined(HACKRF_ONE) || defined(PRALINE)
return rffc5071_set_frequency(mixer, hz);
#elif defined(RAD1O)
return max2871_set_frequency(mixer, hz / 1000000);
#if defined(IS_NOT_RAD1O)
if (IS_NOT_RAD1O) {
return rffc5071_set_frequency(&mixer->rffc5071, hz);
}
#endif
#if defined(IS_RAD1O)
if (IS_RAD1O) {
return max2871_set_frequency(&mixer->max2871, hz / 1000000);
}
#endif
}
void mixer_enable(mixer_driver_t* const mixer)
{
#if defined(JAWBREAKER) || defined(HACKRF_ONE) || defined(PRALINE)
rffc5071_enable(mixer);
#elif defined(RAD1O)
max2871_enable(mixer);
#if defined(IS_NOT_RAD1O)
if (IS_NOT_RAD1O) {
rffc5071_enable(&mixer->rffc5071);
}
#endif
#if defined(IS_RAD1O)
if (IS_RAD1O) {
max2871_enable(&mixer->max2871);
}
#endif
}
void mixer_disable(mixer_driver_t* const mixer)
{
#if defined(JAWBREAKER) || defined(HACKRF_ONE) || defined(PRALINE)
rffc5071_disable(mixer);
#elif defined(RAD1O)
max2871_disable(mixer);
#if defined(IS_NOT_RAD1O)
if (IS_NOT_RAD1O) {
rffc5071_disable(&mixer->rffc5071);
}
#endif
#if defined(IS_RAD1O)
if (IS_RAD1O) {
max2871_disable(&mixer->max2871);
}
#endif
}
void mixer_set_gpo(mixer_driver_t* const mixer, uint8_t gpo)
{
#if defined(JAWBREAKER) || defined(HACKRF_ONE) || defined(PRALINE)
rffc5071_set_gpo(mixer, gpo);
#elif defined(RAD1O)
(void) mixer;
(void) gpo;
#if defined(IS_NOT_RAD1O)
if (IS_NOT_RAD1O) {
rffc5071_set_gpo(&mixer->rffc5071, gpo);
}
#endif
#if defined(IS_RAD1O)
if (IS_RAD1O) {
(void) mixer;
(void) gpo;
}
#endif
}

View file

@ -22,17 +22,37 @@
#pragma once
#if defined(JAWBREAKER) || defined(HACKRF_ONE) || defined(PRALINE)
#include "rffc5071.h"
typedef rffc5071_driver_t mixer_driver_t;
#elif defined(RAD1O)
#include <stdint.h>
#include "platform_detect.h"
#if defined(IS_RAD1O)
#include "max2871.h"
typedef max2871_driver_t mixer_driver_t;
#endif
#if defined(IS_NOT_RAD1O)
#include "rffc5071.h"
#endif
#include <stdint.h>
typedef enum {
RFFC5071_VARIANT,
MAX2871_VARIANT,
} mixer_variant_t;
typedef struct {
mixer_variant_t type;
union {
#if defined(IS_RAD1O)
max2871_driver_t max2871;
#endif
#if defined(IS_NOT_RAD1O)
rffc5071_driver_t rffc5071;
#endif
};
} mixer_driver_t;
extern void mixer_bus_setup(mixer_driver_t* const mixer);
extern void mixer_setup(mixer_driver_t* const mixer);
extern void mixer_setup(mixer_driver_t* const mixer, mixer_variant_t type);
/* Set frequency (Hz). */
extern uint64_t mixer_set_frequency(mixer_driver_t* const mixer, uint64_t hz);

View file

@ -25,14 +25,16 @@
#include <libopencm3/lpc43xx/gima.h>
#include <libopencm3/lpc43xx/rgu.h>
#include <libopencm3/lpc43xx/scu.h>
#if !defined(PRALINE)
#include "delay.h"
#include "platform_detect.h"
#include "sct.h"
#if defined(IS_NOT_PRALINE)
#include <libopencm3/cm3/common.h>
#include <libopencm3/lpc43xx/sgpio.h>
#endif
#include "delay.h"
#include "sct.h"
#define U1CTRL_SET SCT_OUT14_SET
#define U1CTRL_CLR SCT_OUT14_CLR
#define U2CTRL0_SET SCT_OUT13_SET
@ -95,24 +97,31 @@ void operacake_sctimer_init(void)
P7_0,
SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_FUNCTION1);
#ifndef PRALINE
// 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;
uint8_t sct_clock_input;
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
// 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
// Use the GIMA to connect the SGPIO clock to the SCTimer
GIMA_CTIN_1_IN = 0x2 << 4; // Route SGPIO12 to SCTIN1
uint8_t sct_clock_input = SCT_CONFIG_CKSEL_RISING_EDGES_ON_INPUT_1;
#else
// Configure pin P6_4 as SCT_IN_6
scu_pinmux(P6_4, SCU_CLK_IN | SCU_CONF_FUNCTION1);
sct_clock_input = SCT_CONFIG_CKSEL_RISING_EDGES_ON_INPUT_1;
}
#endif
#if defined(IS_PRALINE)
if (IS_PRALINE) {
// Configure pin P6_4 as SCT_IN_6
scu_pinmux(P6_4, SCU_CLK_IN | SCU_CONF_FUNCTION1);
// Use the GIMA to connect MS0/CLK1 (SCT_CLK) on pin P6_4 to the SCTimer
GIMA_CTIN_6_IN = 0x0 << 4;
// Use the GIMA to connect MS0/CLK1 (SCT_CLK) on pin P6_4 to the SCTimer
GIMA_CTIN_6_IN = 0x0 << 4;
uint8_t sct_clock_input = SCT_CONFIG_CKSEL_RISING_EDGES_ON_INPUT_6;
sct_clock_input = SCT_CONFIG_CKSEL_RISING_EDGES_ON_INPUT_6;
}
#endif
// We configure this register first, because the user manual says to

View file

@ -21,6 +21,7 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#define BOARD_REV_GSG (0x80)
@ -31,6 +32,67 @@
#define PLATFORM_HACKRF1_R9 (1 << 3)
#define PLATFORM_PRALINE (1 << 4)
/* clang-format off */
/* Helper macros for platform-specific code. */
#if defined(UNIVERSAL)
#define IS_PRALINE (detected_platform() == BOARD_ID_PRALINE)
#define IS_NOT_PRALINE (!IS_PRALINE)
#define IS_HACKRF_ONE ( \
detected_platform() == BOARD_ID_HACKRF1_OG || \
detected_platform() == BOARD_ID_HACKRF1_R9 \
)
#define IS_NOT_HACKRF_ONE (!IS_HACKRF_ONE)
#define IS_H1_R9 (detected_platform() == BOARD_ID_HACKRF1_R9)
#define IS_NOT_H1_R9 (!IS_H1_R9)
#define IS_NOT_RAD1O true
#define IS_NOT_JAWBREAKER true
#define IS_H1_OR_PRALINE true
#define IS_H1_OR_RAD1O IS_HACKRF_ONE
#define IS_H1_OR_JAWBREAKER IS_HACKRF_ONE
#define IS_FOUR_LEDS IS_PRALINE
#define IS_EXPANSION_COMPATIBLE true
#elif defined(HACKRF_ONE)
#define IS_NOT_PRALINE true
#define IS_HACKRF_ONE true
#define IS_H1_R9 (detected_platform() == BOARD_ID_HACKRF1_R9)
#define IS_NOT_H1_R9 (!IS_H1_R9)
#define IS_NOT_RAD1O true
#define IS_NOT_JAWBREAKER true
#define IS_H1_OR_PRALINE true
#define IS_H1_OR_RAD1O true
#define IS_H1_OR_JAWBREAKER true
#define IS_EXPANSION_COMPATIBLE true
#elif defined(PRALINE)
#define IS_PRALINE true
#define IS_NOT_HACKRF_ONE true
#define IS_NOT_H1_R9 true
#define IS_NOT_RAD1O true
#define IS_NOT_JAWBREAKER true
#define IS_H1_OR_PRALINE true
#define IS_FOUR_LEDS true
#define IS_EXPANSION_COMPATIBLE true
#elif defined(RAD1O)
#define IS_NOT_PRALINE true
#define IS_NOT_HACKRF_ONE true
#define IS_NOT_H1_R9 true
#define IS_RAD1O true
#define IS_NOT_JAWBREAKER true
#define IS_H1_OR_RAD1O true
#define IS_FOUR_LEDS true
#elif defined(JAWBREAKER)
#define IS_NOT_PRALINE true
#define IS_NOT_HACKRF_ONE true
#define IS_NOT_H1_R9 true
#define IS_NOT_RAD1O true
#define IS_JAWBREAKER true
#define IS_H1_OR_JAWBREAKER true
#else
#error "No recognised platform defined"
#endif
/* clang-format on */
typedef enum {
BOARD_ID_JELLYBEAN = 0,
BOARD_ID_JAWBREAKER = 1,

View file

@ -23,9 +23,7 @@
#include <stddef.h>
#if defined(HACKRF_ONE)
#include "platform_detect.h"
#endif
#include "platform_detect.h"
// clang-format off
@ -42,184 +40,249 @@ const platform_gpio_t* platform_gpio(void)
gpio.led[0] = &GPIO2_1;
gpio.led[1] = &GPIO2_2;
gpio.led[2] = &GPIO2_8;
#if defined(RAD1O)
gpio.led[3] = &GPIO5_26;
#elif defined(PRALINE)
gpio.led[3] = &GPIO4_6;
#if defined(IS_RAD1O)
if (IS_RAD1O) {
gpio.led[3] = &GPIO5_26;
}
#endif
#if defined(IS_PRALINE)
if (IS_PRALINE) {
gpio.led[3] = &GPIO4_6;
}
#endif
/* Power Supply Control */
#if defined(PRALINE)
gpio.gpio_1v2_enable = &GPIO4_7;
gpio.gpio_3v3aux_enable_n = &GPIO5_15;
#else
gpio.gpio_1v8_enable = &GPIO3_6;
#if defined(IS_PRALINE)
if (IS_PRALINE) {
gpio.gpio_1v2_enable = &GPIO4_7;
gpio.gpio_3v3aux_enable_n = &GPIO5_15;
}
#endif
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
gpio.gpio_1v8_enable = &GPIO3_6;
}
#endif
/* MAX283x GPIO (XCVR_CTL / CS_XCVR) PinMux */
#if defined(PRALINE)
gpio.max283x_select = &GPIO6_28;
gpio.max283x_enable = &GPIO7_1;
gpio.max283x_rx_enable = &GPIO7_2;
gpio.max2831_rxhp = &GPIO6_29;
gpio.max2831_ld = &GPIO4_11;
#else
gpio.max283x_select = &GPIO0_15;
gpio.max283x_enable = &GPIO2_6;
gpio.max283x_rx_enable = &GPIO2_5;
gpio.max283x_tx_enable = &GPIO2_4;
#if defined(IS_PRALINE)
if (IS_PRALINE) {
gpio.max283x_select = &GPIO6_28;
gpio.max283x_enable = &GPIO7_1;
gpio.max283x_rx_enable = &GPIO7_2;
gpio.max2831_rxhp = &GPIO6_29;
gpio.max2831_ld = &GPIO4_11;
}
#endif
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
gpio.max283x_select = &GPIO0_15;
gpio.max283x_enable = &GPIO2_6;
gpio.max283x_rx_enable = &GPIO2_5;
gpio.max283x_tx_enable = &GPIO2_4;
}
#endif
/* MAX5864 SPI chip select (AD_CS / CS_AD) GPIO PinMux */
#if defined(PRALINE)
gpio.max5864_select = &GPIO6_30;
#else
gpio.max5864_select = &GPIO2_7;
#if defined(IS_PRALINE)
if (IS_PRALINE) {
gpio.max5864_select = &GPIO6_30;
}
#endif
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
gpio.max5864_select = &GPIO2_7;
}
#endif
/* RF supply (VAA) control */
#if defined(HACKRF_ONE)
gpio.vaa_disable = &GPIO2_9;
#elif defined(PRALINE)
gpio.vaa_disable = &GPIO4_1;
#elif defined(RAD1O)
gpio.vaa_enable = &GPIO2_9;
#if defined(IS_HACKRF_ONE)
if (IS_HACKRF_ONE) {
gpio.vaa_disable = &GPIO2_9;
}
#endif
#if defined(IS_PRALINE)
if (IS_PRALINE) {
gpio.vaa_disable = &GPIO4_1;
}
#endif
#if defined(IS_RAD1O)
if (IS_RAD1O) {
gpio.vaa_enable = &GPIO2_9;
}
#endif
/* W25Q80BV Flash */
gpio.w25q80bv_hold = &GPIO1_14;
gpio.w25q80bv_wp = &GPIO1_15;
gpio.w25q80bv_select = &GPIO5_11;
gpio.w25q80bv_hold = &GPIO1_14;
gpio.w25q80bv_wp = &GPIO1_15;
gpio.w25q80bv_select = &GPIO5_11;
/* RF switch control */
#if defined(HACKRF_ONE)
gpio.hp = &GPIO2_0;
gpio.lp = &GPIO2_10;
gpio.tx_mix_bp = &GPIO2_11;
gpio.no_mix_bypass = &GPIO1_0;
gpio.rx_mix_bp = &GPIO2_12;
gpio.tx_amp = &GPIO2_15;
gpio.tx = &GPIO5_15;
gpio.mix_bypass = &GPIO5_16;
gpio.rx = &GPIO5_5;
gpio.no_tx_amp_pwr = &GPIO3_5;
gpio.amp_bypass = &GPIO0_14;
gpio.rx_amp = &GPIO1_11;
gpio.no_rx_amp_pwr = &GPIO1_12;
// HackRF One rev 9
gpio.h1r9_rx = &GPIO0_7;
gpio.h1r9_no_ant_pwr = &GPIO2_4;
#elif defined(RAD1O)
gpio.tx_rx_n = &GPIO1_11;
gpio.tx_rx = &GPIO0_14;
gpio.by_mix = &GPIO1_12;
gpio.by_mix_n = &GPIO2_10;
gpio.by_amp = &GPIO1_0;
gpio.by_amp_n = &GPIO5_5;
gpio.mixer_en = &GPIO5_16;
gpio.low_high_filt = &GPIO2_11;
gpio.low_high_filt_n = &GPIO2_12;
gpio.tx_amp = &GPIO2_15;
gpio.rx_lna = &GPIO5_15;
#elif defined(PRALINE)
gpio.tx_en = &GPIO3_4;
gpio.mix_en_n = &GPIO3_2;
gpio.mix_en_n_r1_0 = &GPIO5_6;
gpio.lpf_en = &GPIO4_8;
gpio.rf_amp_en = &GPIO4_9;
gpio.ant_bias_en_n = &GPIO1_12;
#if defined(IS_HACKRF_ONE)
if (IS_HACKRF_ONE) {
gpio.hp = &GPIO2_0;
gpio.lp = &GPIO2_10;
gpio.tx_mix_bp = &GPIO2_11;
gpio.no_mix_bypass = &GPIO1_0;
gpio.rx_mix_bp = &GPIO2_12;
gpio.tx_amp = &GPIO2_15;
gpio.tx = &GPIO5_15;
gpio.mix_bypass = &GPIO5_16;
gpio.rx = &GPIO5_5;
gpio.no_tx_amp_pwr = &GPIO3_5;
gpio.amp_bypass = &GPIO0_14;
gpio.rx_amp = &GPIO1_11;
gpio.no_rx_amp_pwr = &GPIO1_12;
#if defined(IS_H1_R9)
if (IS_H1_R9) {
gpio.h1r9_rx = &GPIO0_7;
gpio.h1r9_no_ant_pwr = &GPIO2_4;
}
#endif
}
#endif
#if defined(IS_RAD1O)
if (IS_RAD1O) {
gpio.tx_rx_n = &GPIO1_11;
gpio.tx_rx = &GPIO0_14;
gpio.by_mix = &GPIO1_12;
gpio.by_mix_n = &GPIO2_10;
gpio.by_amp = &GPIO1_0;
gpio.by_amp_n = &GPIO5_5;
gpio.mixer_en = &GPIO5_16;
gpio.low_high_filt = &GPIO2_11;
gpio.low_high_filt_n = &GPIO2_12;
gpio.tx_amp = &GPIO2_15;
gpio.rx_lna = &GPIO5_15;
}
#endif
#if defined(IS_PRALINE)
if (IS_PRALINE) {
gpio.tx_en = &GPIO3_4;
gpio.mix_en_n = &GPIO3_2;
gpio.mix_en_n_r1_0 = &GPIO5_6;
gpio.lpf_en = &GPIO4_8;
gpio.rf_amp_en = &GPIO4_9;
gpio.ant_bias_en_n = &GPIO1_12;
}
#endif
/* CPLD JTAG interface GPIO pins_FPGA config pins in Praline */
gpio.cpld_tck = &GPIO3_0;
#if defined(PRALINE)
gpio.fpga_cfg_creset = &GPIO2_11;
gpio.fpga_cfg_cdone = &GPIO5_14;
gpio.fpga_cfg_spi_cs = &GPIO2_10;
gpio.cpld_tck = &GPIO3_0;
#if defined(IS_PRALINE)
if (IS_PRALINE) {
gpio.fpga_cfg_creset = &GPIO2_11;
gpio.fpga_cfg_cdone = &GPIO5_14;
gpio.fpga_cfg_spi_cs = &GPIO2_10;
}
#endif
#if defined(HACKRF_ONE) || defined(RAD1O)
gpio.cpld_tdo = &GPIO5_18;
gpio.cpld_tms = &GPIO3_4;
gpio.cpld_tdi = &GPIO3_1;
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
gpio.cpld_tdo = &GPIO5_18;
#if defined(IS_H1_OR_RAD1O)
if (IS_H1_OR_RAD1O) {
gpio.cpld_tms = &GPIO3_4;
gpio.cpld_tdi = &GPIO3_1;
}
#endif
#if defined(HACKRF_ONE) || defined(PRALINE)
gpio.cpld_pp_tms = &GPIO1_1;
gpio.cpld_pp_tdo = &GPIO1_8;
#if defined(IS_JAWBREAKER)
if (IS_JAWBREAKER) {
gpio.cpld_tms = &GPIO3_1;
gpio.cpld_tdi = &GPIO3_4;
}
#endif
}
#endif
#if defined(IS_EXPANSION_COMPATIBLE)
if (IS_EXPANSION_COMPATIBLE) {
gpio.cpld_pp_tms = &GPIO1_1;
gpio.cpld_pp_tdo = &GPIO1_8;
}
#endif
/* Other CPLD interface GPIO pins */
#if !defined(PRALINE)
gpio.trigger_enable = &GPIO5_12;
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
gpio.trigger_enable = &GPIO5_12;
}
#endif
gpio.q_invert = &GPIO0_13;
gpio.q_invert = &GPIO0_13;
/* RFFC5071 GPIO serial interface PinMux */
#if defined(JAWBREAKER) || defined(HACKRF_ONE)
gpio.rffc5072_select = &GPIO2_13;
gpio.rffc5072_clock = &GPIO5_6;
gpio.rffc5072_data = &GPIO3_3;
gpio.rffc5072_reset = &GPIO2_14;
#elif defined(RAD1O)
gpio.vco_ce = &GPIO2_13;
gpio.vco_sclk = &GPIO5_6;
gpio.vco_sdata = &GPIO3_3;
gpio.vco_le = &GPIO2_14;
gpio.vco_mux = &GPIO5_25;
gpio.synt_rfout_en = &GPIO3_5;
#elif defined(PRALINE)
gpio.rffc5072_select = &GPIO2_13;
gpio.rffc5072_clock = &GPIO5_18;
gpio.rffc5072_data = &GPIO4_14;
gpio.rffc5072_reset = &GPIO2_14;
gpio.rffc5072_ld = &GPIO6_25;
#if defined(IS_NOT_RAD1O)
if (IS_NOT_RAD1O) {
gpio.rffc5072_select = &GPIO2_13;
gpio.rffc5072_clock = &GPIO5_6;
gpio.rffc5072_data = &GPIO3_3;
gpio.rffc5072_reset = &GPIO2_14;
}
#endif
#if defined(IS_RAD1O)
if (IS_RAD1O) {
gpio.vco_ce = &GPIO2_13;
gpio.vco_sclk = &GPIO5_6;
gpio.vco_sdata = &GPIO3_3;
gpio.vco_le = &GPIO2_14;
gpio.vco_mux = &GPIO5_25;
gpio.synt_rfout_en = &GPIO3_5;
}
#endif
#if defined(IS_PRALINE)
if (IS_PRALINE) {
gpio.rffc5072_select = &GPIO2_13;
gpio.rffc5072_clock = &GPIO5_18;
gpio.rffc5072_data = &GPIO4_14;
gpio.rffc5072_reset = &GPIO2_14;
gpio.rffc5072_ld = &GPIO6_25;
}
#endif
/* Praline */
#if defined(PRALINE)
gpio.p2_ctrl0 = &GPIO7_3;
gpio.p2_ctrl1 = &GPIO7_4;
gpio.p1_ctrl0 = &GPIO0_14;
gpio.p1_ctrl1 = &GPIO5_16;
gpio.p1_ctrl2 = &GPIO3_5;
gpio.clkin_ctrl = &GPIO0_15;
gpio.aa_en = &GPIO1_7;
gpio.trigger_in = &GPIO6_26;
gpio.trigger_out = &GPIO5_6;
gpio.pps_out = &GPIO5_5;
#if defined(IS_PRALINE)
if (IS_PRALINE) {
gpio.p2_ctrl0 = &GPIO7_3;
gpio.p2_ctrl1 = &GPIO7_4;
gpio.p1_ctrl0 = &GPIO0_14;
gpio.p1_ctrl1 = &GPIO5_16;
gpio.p1_ctrl2 = &GPIO3_5;
gpio.clkin_ctrl = &GPIO0_15;
gpio.aa_en = &GPIO1_7;
gpio.trigger_in = &GPIO6_26;
gpio.trigger_out = &GPIO5_6;
gpio.pps_out = &GPIO5_5;
}
#endif
/* HackRF One r9 */
#if defined(HACKRF_ONE)
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
/* HackRF One r9 clock control */
/* HackRF One r9 clock control */
#if defined(IS_H1_R9)
if (IS_H1_R9) {
gpio.h1r9_clkin_en = &GPIO5_15;
gpio.h1r9_clkout_en = &GPIO0_9;
gpio.h1r9_mcu_clk_en = &GPIO0_8;
/* HackRF One r9 power control */
gpio.h1r9_1v8_enable = &GPIO2_9;
gpio.h1r9_vaa_disable = &GPIO3_6;
gpio.h1r9_1v8_enable = &GPIO2_9;
gpio.h1r9_vaa_disable = &GPIO3_6;
gpio.h1r9_trigger_enable = &GPIO5_5;
}
#endif
/* RAD1O */
#if defined(RAD1O)
gpio.lcd_cs = &GPIO4_12; /* P9_0 */
gpio.lcd_bl_en = &GPIO0_8; /* P1_1 */
gpio.lcd_reset = &GPIO5_17; /* P9_4 */
/* rad1o LCD */
#if defined(IS_RAD1O)
if (IS_RAD1O) {
gpio.lcd_cs = &GPIO4_12; /* P9_0 */
gpio.lcd_bl_en = &GPIO0_8; /* P1_1 */
gpio.lcd_reset = &GPIO5_17; /* P9_4 */
}
#endif
/* Portapack */
#if defined(HACKRF_ONE) || defined(PRALINE)
gpio.io_stbx = &GPIO5_0; /* P2_0 */
gpio.addr = &GPIO5_1; /* P2_1 */
gpio.lcd_te = &GPIO5_3; /* P2_3 */
gpio.unused = &GPIO5_7; /* P2_8 */
gpio.lcd_rdx = &GPIO5_4; /* P2_4 */
gpio.lcd_wrx = &GPIO1_10; /* P2_9 */
gpio.dir = &GPIO1_13; /* P2_13 */
#if defined(IS_EXPANSION_COMPATIBLE)
if (IS_EXPANSION_COMPATIBLE) {
gpio.io_stbx = &GPIO5_0; /* P2_0 */
gpio.addr = &GPIO5_1; /* P2_1 */
gpio.lcd_rdx = &GPIO5_4; /* P2_4 */
gpio.lcd_wrx = &GPIO1_10; /* P2_9 */
gpio.dir = &GPIO1_13; /* P2_13 */
}
#endif
_platform_gpio = &gpio;

View file

@ -27,10 +27,11 @@ extern "C" {
#include "gpio.h"
#include "gpio_lpc.h"
#include "platform_detect.h"
typedef struct {
/* LEDs */
#if defined(PRALINE) || defined(RAD1O)
#if defined(IS_FOUR_LEDS)
gpio_t led[4];
#else
gpio_t led[3];
@ -38,7 +39,7 @@ typedef struct {
/* Power Supply Control */
gpio_t gpio_1v8_enable;
#if defined(PRALINE)
#if defined(IS_PRALINE)
gpio_t gpio_1v2_enable;
gpio_t gpio_3v3aux_enable_n;
#endif
@ -48,7 +49,7 @@ typedef struct {
gpio_t max283x_enable;
gpio_t max283x_rx_enable;
gpio_t max283x_tx_enable;
#if defined(PRALINE)
#if defined(IS_PRALINE)
gpio_t max2831_rxhp;
gpio_t max2831_ld;
#endif
@ -58,7 +59,7 @@ typedef struct {
/* RF supply (VAA) control */
gpio_t vaa_disable;
#if defined(RAD1O)
#if defined(IS_RAD1O)
gpio_t vaa_enable;
#endif
@ -68,7 +69,7 @@ typedef struct {
gpio_t w25q80bv_select;
/* RF switch control */
#if defined(HACKRF_ONE)
#if defined(IS_HACKRF_ONE)
gpio_t hp;
gpio_t lp;
gpio_t tx_mix_bp;
@ -85,7 +86,7 @@ typedef struct {
gpio_t h1r9_no_ant_pwr; // HACKRF_ONE r9
gpio_t h1r9_rx; // HACKRF_ONE r9
#endif
#if defined(RAD1O)
#if defined(IS_RAD1O)
gpio_t tx_rx_n;
gpio_t tx_rx;
gpio_t by_mix;
@ -98,7 +99,7 @@ typedef struct {
gpio_t tx_amp;
gpio_t rx_lna;
#endif
#if defined(PRALINE)
#if defined(IS_PRALINE)
gpio_t tx_en;
gpio_t mix_en_n;
gpio_t mix_en_n_r1_0;
@ -109,23 +110,23 @@ typedef struct {
/* CPLD JTAG interface GPIO pins, FPGA config pins in Praline */
gpio_t cpld_tck;
#if defined(HACKRF_ONE) || defined(RAD1O)
gpio_t cpld_tdo;
#if defined(IS_NOT_PRALINE)
gpio_t cpld_tms;
gpio_t cpld_tdi;
#endif
#if defined(HACKRF_ONE) || defined(PRALINE)
#if defined(IS_HACKRF_ONE) || defined(IS_PRALINE)
gpio_t cpld_pp_tms;
gpio_t cpld_pp_tdo;
#endif
#if defined(PRALINE)
#if defined(IS_PRALINE)
gpio_t fpga_cfg_creset;
gpio_t fpga_cfg_cdone;
gpio_t fpga_cfg_spi_cs;
#endif
/* Other CPLD interface GPIO pins */
#if !defined(PRALINE)
#if defined(IS_NOT_PRALINE)
gpio_t trigger_enable;
#endif
gpio_t q_invert;
@ -144,7 +145,7 @@ typedef struct {
gpio_t synt_rfout_en; // RAD1O
/* Praline */
#if defined(PRALINE)
#if defined(IS_PRALINE)
gpio_t p2_ctrl0;
gpio_t p2_ctrl1;
gpio_t p1_ctrl0;
@ -157,8 +158,7 @@ typedef struct {
gpio_t pps_out;
#endif
/* HackRF One r9 */
#if defined(HACKRF_ONE)
#if defined(IS_HACKRF_ONE)
/* HackRF One r9 clock control */
gpio_t h1r9_clkin_en;
gpio_t h1r9_clkout_en;
@ -170,18 +170,16 @@ typedef struct {
#endif
/* RAD1O */
#if defined(RAD1O)
#if defined(IS_RAD1O)
gpio_t lcd_cs;
gpio_t lcd_bl_en;
gpio_t lcd_reset;
#endif
/* Portapack */
#if defined(HACKRF_ONE) || defined(PRALINE)
#if defined(IS_EXPANSION_COMPATIBLE)
gpio_t io_stbx;
gpio_t addr;
__attribute__((unused)) gpio_t lcd_te;
__attribute__((unused)) gpio_t unused;
gpio_t lcd_rdx;
gpio_t lcd_wrx;
gpio_t dir;

View file

@ -25,6 +25,8 @@
#include <libopencm3/lpc43xx/scu.h>
#include "platform_detect.h"
// clang-format off
const platform_scu_t* platform_scu(void)
@ -40,37 +42,43 @@ const platform_scu_t* platform_scu(void)
scu.PINMUX_LED1 = SCU_PINMUX_LED1; /* GPIO2[1] on P4_1 */
scu.PINMUX_LED2 = SCU_PINMUX_LED2; /* GPIO2[2] on P4_2 */
scu.PINMUX_LED3 = SCU_PINMUX_LED3; /* GPIO2[8] on P6_12 */
#if defined(PRALINE)
scu.PINMUX_LED4 = (P8_6); /* GPIO4[6] on P8_6 */
#elif defined(RAD1O)
scu.PINMUX_LED4 = (PB_6); /* GPIO5[26] on PB_6 */
#if defined(IS_RAD1O)
if (IS_RAD1O) {
scu.PINMUX_LED4 = (PB_6); /* GPIO5[26] on PB_6 */
}
#endif
#if defined(IS_PRALINE)
if (IS_PRALINE) {
scu.PINMUX_LED4 = (P8_6); /* GPIO4[6] on P8_6 */
}
#endif
/* Power Supply PinMux */
scu.PINMUX_EN1V8 = (P6_10); /* GPIO3[6] on P6_10 */
scu.PINMUX_EN1V2 = (P8_7); /* GPIO4[7] on P8_7 */
#if defined(PRALINE)
scu.PINMUX_EN3V3_AUX_N = (P6_7); /* GPIO5[15] on P6_7 */
scu.PINMUX_EN3V3_OC_N = (P6_11); /* GPIO3[7] on P6_11 */
scu.PINMUX_EN1V8 = (P6_10); /* GPIO3[6] on P6_10 */
scu.PINMUX_EN1V2 = (P8_7); /* GPIO4[7] on P8_7 */
#if defined(IS_PRALINE)
if (IS_PRALINE) {
scu.PINMUX_EN3V3_AUX_N = (P6_7); /* GPIO5[15] on P6_7 */
scu.PINMUX_EN3V3_OC_N = (P6_11); /* GPIO3[7] on P6_11 */
}
#endif
/* GPIO Input PinMux */
scu.PINMUX_BOOT0 = (P1_1); /* GPIO0[8] on P1_1 */
scu.PINMUX_BOOT1 = (P1_2); /* GPIO0[9] on P1_2 */
#if !defined(HACKRF_ONE)
scu.PINMUX_BOOT2 = (P2_8); /* GPIO5[7] on P2_8 */
scu.PINMUX_BOOT3 = (P2_9); /* GPIO1[10] on P2_9 */
#if defined(IS_NOT_HACKRF_ONE)
if (IS_NOT_HACKRF_ONE) {
scu.PINMUX_BOOT2 = (P2_8); /* GPIO5[7] on P2_8 */
scu.PINMUX_BOOT3 = (P2_9); /* GPIO1[10] on P2_9 */
}
#endif
scu.PINMUX_PP_LCD_TE = (P2_3); /* GPIO5[3] on P2_3 */
scu.PINMUX_PP_LCD_RDX = (P2_4); /* GPIO5[4] on P2_4 */
scu.PINMUX_PP_UNUSED = (P2_8); /* GPIO5[7] on P2_8 */
scu.PINMUX_PP_LCD_WRX = (P2_9); /* GPIO1[10] on P2_9 */
scu.PINMUX_PP_DIR = (P2_13); /* GPIO1[13] on P2_13 */
/* USB peripheral */
#if defined(JAWBREAKER)
scu.PINMUX_USB_LED0 = (P6_8);
scu.PINMUX_USB_LED1 = (P6_7);
#if defined(IS_JAWBREAKER)
if (IS_JAWBREAKER) {
scu.PINMUX_USB_LED0 = (P6_8);
scu.PINMUX_USB_LED1 = (P6_7);
}
#endif
/* SSP1 Peripheral PinMux */
@ -80,168 +88,212 @@ const platform_scu_t* platform_scu(void)
scu.SSP1_CS = (P1_20); /* P1_20 */
/* CPLD JTAG interface */
scu.PINMUX_CPLD_TCK = (P6_1); /* GPIO3[ 0] */
#if defined(PRALINE)
scu.PINMUX_FPGA_CRESET = (P5_2); /* GPIO2[11] on P5_2 */
scu.PINMUX_FPGA_CDONE = (P4_10); /* GPIO5[14] */
scu.PINMUX_FPGA_SPI_CS = (P5_1); /* GPIO2[10] */
#elif defined(RAD1O) || defined(HACKRF_ONE)
scu.PINMUX_CPLD_TMS = (P6_5); /* GPIO3[ 4] */
scu.PINMUX_CPLD_TDI = (P6_2); /* GPIO3[ 1] */
scu.PINMUX_CPLD_TDO = (P9_5); /* GPIO5[18] */
#else
scu.PINMUX_CPLD_TMS = (P6_2); /* GPIO3[ 1] */
scu.PINMUX_CPLD_TDI = (P6_5); /* GPIO3[ 4] */
#if defined(IS_PRALINE)
if (IS_PRALINE) {
scu.PINMUX_FPGA_CRESET = (P5_2); /* GPIO2[11] on P5_2 */
scu.PINMUX_FPGA_CDONE = (P4_10); /* GPIO5[14] */
scu.PINMUX_FPGA_SPI_CS = (P5_1); /* GPIO2[10] */
}
#endif
scu.PINMUX_CPLD_TDO = (P9_5); /* GPIO5[18] */
scu.PINMUX_CPLD_TCK = (P6_1); /* GPIO3[ 0] */
#if defined(IS_NOT_JAWBREAKER)
if (IS_NOT_JAWBREAKER) {
scu.PINMUX_CPLD_TMS = (P6_5); /* GPIO3[ 4] */
scu.PINMUX_CPLD_TDI = (P6_2); /* GPIO3[ 1] */
}
#endif
#if defined(IS_JAWBREAKER)
if (IS_JAWBREAKER) {
scu.PINMUX_CPLD_TMS = (P6_2); /* GPIO3[ 1] */
scu.PINMUX_CPLD_TDI = (P6_5); /* GPIO3[ 4] */
}
#endif
/* CPLD SGPIO interface */
#if defined(PRALINE)
scu.PINMUX_SGPIO0 = (P0_0);
scu.PINMUX_SGPIO1 = (P0_1);
scu.PINMUX_SGPIO2 = (P1_15);
scu.PINMUX_SGPIO3 = (P1_16);
scu.PINMUX_SGPIO4 = (P9_4);
scu.PINMUX_SGPIO5 = (P6_6);
scu.PINMUX_SGPIO6 = (P2_2);
scu.PINMUX_SGPIO7 = (P1_0);
scu.PINMUX_SGPIO8 = (P8_0);
scu.PINMUX_SGPIO9 = (P9_3);
scu.PINMUX_SGPIO10 = (P8_2);
scu.PINMUX_SGPIO11 = (P1_17);
scu.PINMUX_SGPIO12 = (P1_18);
scu.PINMUX_SGPIO14 = (P1_18);
scu.PINMUX_SGPIO15 = (P1_18);
#if defined(IS_PRALINE)
if (IS_PRALINE) {
scu.PINMUX_SGPIO0 = (P0_0);
scu.PINMUX_SGPIO1 = (P0_1);
scu.PINMUX_SGPIO2 = (P1_15);
scu.PINMUX_SGPIO3 = (P1_16);
scu.PINMUX_SGPIO4 = (P9_4);
scu.PINMUX_SGPIO5 = (P6_6);
scu.PINMUX_SGPIO6 = (P2_2);
scu.PINMUX_SGPIO7 = (P1_0);
scu.PINMUX_SGPIO8 = (P8_0);
scu.PINMUX_SGPIO9 = (P9_3);
scu.PINMUX_SGPIO10 = (P8_2);
scu.PINMUX_SGPIO11 = (P1_17);
scu.PINMUX_SGPIO12 = (P1_18);
scu.PINMUX_SGPIO14 = (P1_18);
scu.PINMUX_SGPIO15 = (P1_18);
scu.PINMUX_SGPIO0_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION3);
scu.PINMUX_SGPIO1_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION3);
scu.PINMUX_SGPIO2_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION2);
scu.PINMUX_SGPIO3_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION2);
scu.PINMUX_SGPIO4_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION6);
scu.PINMUX_SGPIO5_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION2);
scu.PINMUX_SGPIO6_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.PINMUX_SGPIO7_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION6);
scu.PINMUX_SGPIO8_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.PINMUX_SGPIO9_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION6);
scu.PINMUX_SGPIO10_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.PINMUX_SGPIO11_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION6);
scu.PINMUX_SGPIO12_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.PINMUX_SGPIO14_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.PINMUX_SGPIO15_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
#else
scu.PINMUX_SGPIO0 = (P0_0);
scu.PINMUX_SGPIO1 = (P0_1);
scu.PINMUX_SGPIO2 = (P1_15);
scu.PINMUX_SGPIO3 = (P1_16);
scu.PINMUX_SGPIO4 = (P6_3);
scu.PINMUX_SGPIO5 = (P6_6);
scu.PINMUX_SGPIO6 = (P2_2);
scu.PINMUX_SGPIO7 = (P1_0);
scu.PINMUX_SGPIO8 = (P9_6);
scu.PINMUX_SGPIO9 = (P4_3);
scu.PINMUX_SGPIO10 = (P1_14);
scu.PINMUX_SGPIO11 = (P1_17);
scu.PINMUX_SGPIO12 = (P1_18);
scu.PINMUX_SGPIO14 = (P4_9);
scu.PINMUX_SGPIO15 = (P4_10);
scu.PINMUX_SGPIO0_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION3);
scu.PINMUX_SGPIO1_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION3);
scu.PINMUX_SGPIO2_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION2);
scu.PINMUX_SGPIO3_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION2);
scu.PINMUX_SGPIO4_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION6);
scu.PINMUX_SGPIO5_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION2);
scu.PINMUX_SGPIO6_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.PINMUX_SGPIO7_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION6);
scu.PINMUX_SGPIO8_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.PINMUX_SGPIO9_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION6);
scu.PINMUX_SGPIO10_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.PINMUX_SGPIO11_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION6);
scu.PINMUX_SGPIO12_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.PINMUX_SGPIO14_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.PINMUX_SGPIO15_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
}
#endif
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
scu.PINMUX_SGPIO0 = (P0_0);
scu.PINMUX_SGPIO1 = (P0_1);
scu.PINMUX_SGPIO2 = (P1_15);
scu.PINMUX_SGPIO3 = (P1_16);
scu.PINMUX_SGPIO4 = (P6_3);
scu.PINMUX_SGPIO5 = (P6_6);
scu.PINMUX_SGPIO6 = (P2_2);
scu.PINMUX_SGPIO7 = (P1_0);
scu.PINMUX_SGPIO8 = (P9_6);
scu.PINMUX_SGPIO9 = (P4_3);
scu.PINMUX_SGPIO10 = (P1_14);
scu.PINMUX_SGPIO11 = (P1_17);
scu.PINMUX_SGPIO12 = (P1_18);
scu.PINMUX_SGPIO14 = (P4_9);
scu.PINMUX_SGPIO15 = (P4_10);
scu.PINMUX_SGPIO0_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION3);
scu.PINMUX_SGPIO1_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION3);
scu.PINMUX_SGPIO2_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION2);
scu.PINMUX_SGPIO3_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION2);
scu.PINMUX_SGPIO4_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION2);
scu.PINMUX_SGPIO5_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION2);
scu.PINMUX_SGPIO6_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.PINMUX_SGPIO7_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION6);
scu.PINMUX_SGPIO8_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION6);
scu.PINMUX_SGPIO9_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION7);
scu.PINMUX_SGPIO10_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION6);
scu.PINMUX_SGPIO11_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION6);
scu.PINMUX_SGPIO12_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.PINMUX_SGPIO14_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.PINMUX_SGPIO15_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.PINMUX_SGPIO0_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION3);
scu.PINMUX_SGPIO1_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION3);
scu.PINMUX_SGPIO2_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION2);
scu.PINMUX_SGPIO3_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION2);
scu.PINMUX_SGPIO4_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION2);
scu.PINMUX_SGPIO5_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION2);
scu.PINMUX_SGPIO6_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.PINMUX_SGPIO7_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION6);
scu.PINMUX_SGPIO8_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION6);
scu.PINMUX_SGPIO9_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION7);
scu.PINMUX_SGPIO10_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION6);
scu.PINMUX_SGPIO11_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION6);
scu.PINMUX_SGPIO12_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.PINMUX_SGPIO14_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.PINMUX_SGPIO15_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
}
#endif
scu.TRIGGER_EN = (P4_8); /* GPIO5[12] on P4_8 */
/* MAX283x GPIO (XCVR_CTL) PinMux */
#if defined(PRALINE)
scu.XCVR_ENABLE = PE_1; /* GPIO7[1] on PE_1 */
scu.XCVR_RXENABLE = PE_2; /* GPIO7[2] on PE_2 */
scu.XCVR_CS = PD_14; /* GPIO6[28] on PD_14 */
scu.XCVR_RXHP = PD_15; /* GPIO6[29] on PD_15 */
scu.XCVR_LD = P9_6; /* GPIO4[11] on P9_6 */
#if defined(IS_RAD1O)
if (IS_RAD1O) {
scu.XCVR_RXHP = P8_1; /* GPIO[] on P8_1 */
scu.XCVR_B6 = P8_2; /* GPIO[] on P8_2 */
scu.XCVR_B7 = P9_3; /* GPIO[] on P9_3 */
}
#endif
#if defined(IS_PRALINE)
if (IS_PRALINE) {
scu.XCVR_ENABLE = PE_1; /* GPIO7[1] on PE_1 */
scu.XCVR_RXENABLE = PE_2; /* GPIO7[2] on PE_2 */
scu.XCVR_CS = PD_14; /* GPIO6[28] on PD_14 */
scu.XCVR_RXHP = PD_15; /* GPIO6[29] on PD_15 */
scu.XCVR_LD = P9_6; /* GPIO4[11] on P9_6 */
scu.XCVR_ENABLE_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.XCVR_RXENABLE_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.XCVR_CS_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.XCVR_RXHP_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.XCVR_LD_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0 |
SCU_CONF_EPD_EN_PULLDOWN | SCU_CONF_EPUN_DIS_PULLUP);
#elif defined(JAWBREAKER) || defined(HACKRF_ONE)
scu.XCVR_ENABLE = P4_6; /* GPIO2[6] on P4_6 */
scu.XCVR_RXENABLE = P4_5; /* GPIO2[5] on P4_5 */
scu.XCVR_TXENABLE = P4_4; /* GPIO2[4] on P4_4 */
scu.XCVR_CS = P1_20; /* GPIO0[15] on P1_20 */
scu.XCVR_ENABLE_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.XCVR_RXENABLE_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.XCVR_CS_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.XCVR_RXHP_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.XCVR_LD_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0 |
SCU_CONF_EPD_EN_PULLDOWN | SCU_CONF_EPUN_DIS_PULLUP);
}
#endif
#if defined(IS_H1_OR_JAWBREAKER)
if (IS_H1_OR_JAWBREAKER) {
scu.XCVR_ENABLE = P4_6; /* GPIO2[6] on P4_6 */
scu.XCVR_RXENABLE = P4_5; /* GPIO2[5] on P4_5 */
scu.XCVR_TXENABLE = P4_4; /* GPIO2[4] on P4_4 */
scu.XCVR_CS = P1_20; /* GPIO0[15] on P1_20 */
scu.XCVR_ENABLE_PINCFG = (SCU_GPIO_FAST);
scu.XCVR_RXENABLE_PINCFG = (SCU_GPIO_FAST);
scu.XCVR_TXENABLE_PINCFG = (SCU_GPIO_FAST);
scu.XCVR_CS_PINCFG = (SCU_GPIO_FAST);
#elif defined(RAD1O)
scu.XCVR_RXHP = P8_1; /* GPIO[] on P8_1 */
scu.XCVR_B6 = P8_2; /* GPIO[] on P8_2 */
scu.XCVR_B7 = P9_3; /* GPIO[] on P9_3 */
scu.XCVR_ENABLE_PINCFG = (SCU_GPIO_FAST);
scu.XCVR_RXENABLE_PINCFG = (SCU_GPIO_FAST);
scu.XCVR_TXENABLE_PINCFG = (SCU_GPIO_FAST);
scu.XCVR_CS_PINCFG = (SCU_GPIO_FAST);
}
#endif
/* MAX5864 SPI chip select (AD_CS) GPIO PinMux */
#if defined(PRALINE)
scu.AD_CS = (PD_16); /* GPIO6[30] on PD_16 */
scu.AD_CS_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
#else
scu.AD_CS = (P5_7); /* GPIO2[7] on P5_7 */
scu.AD_CS_PINCFG = (SCU_GPIO_FAST);
#if defined(IS_PRALINE)
if (IS_PRALINE) {
scu.AD_CS = (PD_16); /* GPIO6[30] on PD_16 */
scu.AD_CS_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
}
#endif
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
scu.AD_CS = (P5_7); /* GPIO2[7] on P5_7 */
scu.AD_CS_PINCFG = (SCU_GPIO_FAST);
}
#endif
/* RFFC5071 GPIO serial interface PinMux */
#if defined(PRALINE)
scu.MIXER_ENX = (P5_4); /* GPIO2[13] on P5_4 */
scu.MIXER_SCLK = (P9_5); /* GPIO5[18] on P9_5 */
scu.MIXER_SDATA = (P9_2); /* GPIO4[14] on P9_2 */
scu.MIXER_RESETX = (P5_5); /* GPIO2[14] on P5_5 */
scu.MIXER_LD = (PD_11); /* GPIO6[25] on PD_11 */
#if defined(IS_H1_OR_JAWBREAKER)
if (IS_H1_OR_JAWBREAKER) {
scu.MIXER_ENX = (P5_4); /* GPIO2[13] on P5_4 */
scu.MIXER_SCLK = (P2_6); /* GPIO5[6] on P2_6 */
scu.MIXER_SDATA = (P6_4); /* GPIO3[3] on P6_4 */
scu.MIXER_RESETX = (P5_5); /* GPIO2[14] on P5_5 */
scu.MIXER_SCLK_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.MIXER_SDATA_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.MIXER_LD_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
#elif defined(JAWBREAKER) || defined(HACKRF_ONE)
scu.MIXER_ENX = (P5_4); /* GPIO2[13] on P5_4 */
scu.MIXER_SCLK = (P2_6); /* GPIO5[6] on P2_6 */
scu.MIXER_SDATA = (P6_4); /* GPIO3[3] on P6_4 */
scu.MIXER_RESETX = (P5_5); /* GPIO2[14] on P5_5 */
scu.MIXER_SCLK_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.MIXER_SDATA_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
}
#endif
#if defined(IS_PRALINE)
if (IS_PRALINE) {
scu.MIXER_ENX = (P5_4); /* GPIO2[13] on P5_4 */
scu.MIXER_SCLK = (P9_5); /* GPIO5[18] on P9_5 */
scu.MIXER_SDATA = (P9_2); /* GPIO4[14] on P9_2 */
scu.MIXER_RESETX = (P5_5); /* GPIO2[14] on P5_5 */
scu.MIXER_LD = (PD_11); /* GPIO6[25] on PD_11 */
scu.MIXER_SCLK_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.MIXER_SDATA_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
#elif defined(RAD1O)
scu.VCO_CE = (P5_4); /* GPIO2[13] on P5_4 */
scu.VCO_SCLK = (P2_6); /* GPIO5[6] on P2_6 */
scu.VCO_SDATA = (P6_4); /* GPIO3[3] on P6_4 */
scu.VCO_LE = (P5_5); /* GPIO2[14] on P5_5 */
scu.VCO_MUX = (PB_5); /* GPIO5[25] on PB_5 */
scu.MIXER_EN = (P6_8); /* GPIO5[16] on P6_8 */
scu.SYNT_RFOUT_EN = (P6_9); /* GPIO3[5] on P6_9 */
scu.MIXER_SCLK_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.MIXER_SDATA_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.MIXER_LD_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
}
#endif
#if defined(IS_RAD1O)
if (IS_RAD1O) {
scu.VCO_CE = (P5_4); /* GPIO2[13] on P5_4 */
scu.VCO_SCLK = (P2_6); /* GPIO5[6] on P2_6 */
scu.VCO_SDATA = (P6_4); /* GPIO3[3] on P6_4 */
scu.VCO_LE = (P5_5); /* GPIO2[14] on P5_5 */
scu.VCO_MUX = (PB_5); /* GPIO5[25] on PB_5 */
scu.MIXER_EN = (P6_8); /* GPIO5[16] on P6_8 */
scu.SYNT_RFOUT_EN = (P6_9); /* GPIO3[5] on P6_9 */
}
#endif
/* RF LDO control */
#if defined(JAWBREAKER)
scu.RF_LDO_ENABLE = (P5_0); /* GPIO2[9] on P5_0 */
#if defined(IS_JAWBREAKER)
if (IS_JAWBREAKER) {
scu.RF_LDO_ENABLE = (P5_0); /* GPIO2[9] on P5_0 */
}
#endif
/* RF supply (VAA) control */
#if defined(PRALINE)
scu.NO_VAA_ENABLE = P8_1; /* GPIO4[1] on P8_1 */
#elif defined(HACKRF_ONE)
scu.NO_VAA_ENABLE = P5_0; /* GPIO2[9] on P5_0 */
#elif defined(RAD1O)
scu.VAA_ENABLE = P5_0; /* GPIO2[9] on P5_0 */
#if defined(IS_HACKRF_ONE)
if (IS_HACKRF_ONE) {
scu.NO_VAA_ENABLE = P5_0; /* GPIO2[9] on P5_0 */
}
#endif
#if defined(IS_PRALINE)
if (IS_PRALINE) {
scu.NO_VAA_ENABLE = P8_1; /* GPIO4[1] on P8_1 */
}
#endif
#if defined(IS_RAD1O)
if (IS_RAD1O) {
scu.VAA_ENABLE = P5_0; /* GPIO2[9] on P5_0 */
}
#endif
/* SPI flash */
@ -253,114 +305,134 @@ const platform_scu_t* platform_scu(void)
scu.FLASH_WP = (P3_5); /* GPIO1[15] on P3_5 */
/* RF switch control */
#if defined(PRALINE)
scu.TX_EN = P6_5; /* GPIO3[4] on P6_5 */
scu.MIX_EN_N = P6_3; /* GPIO3[2] on P6_3 */
scu.MIX_EN_N_R1_0 = P2_6; /* GPIO5[6] on P2_6 */
scu.LPF_EN = PA_1; /* GPIO4[8] on PA_1 */
scu.RF_AMP_EN = PA_2; /* GPIO4[9] on PA_2 */
scu.ANT_BIAS_EN_N = P2_12; /* GPIO1[12] on P2_12 */
scu.ANT_BIAS_OC_N = P2_11; /* GPIO1[11] on P2_11 */
#elif defined(HACKRF_ONE)
scu.HP = P4_0; /* GPIO2[0] on P4_0 */
scu.LP = P5_1; /* GPIO2[10] on P5_1 */
scu.TX_MIX_BP = P5_2; /* GPIO2[11] on P5_2 */
scu.NO_MIX_BYPASS = P1_7; /* GPIO1[0] on P1_7 */
scu.RX_MIX_BP = P5_3; /* GPIO2[12] on P5_3 */
scu.TX_AMP = P5_6; /* GPIO2[15] on P5_6 */
scu.TX = P6_7; /* GPIO5[15] on P6_7 */
scu.MIX_BYPASS = P6_8; /* GPIO5[16] on P6_8 */
scu.RX = P2_5; /* GPIO5[5] on P2_5 */
scu.NO_TX_AMP_PWR = P6_9; /* GPIO3[5] on P6_9 */
scu.AMP_BYPASS = P2_10; /* GPIO0[14] on P2_10 */
scu.RX_AMP = P2_11; /* GPIO1[11] on P2_11 */
scu.NO_RX_AMP_PWR = P2_12; /* GPIO1[12] on P2_12 */
#elif defined(RAD1O)
scu.BY_AMP = P1_7; /* GPIO1[0] on P1_7 */
scu.BY_AMP_N = P2_5; /* GPIO5[5] on P2_5 */
scu.TX_RX = P2_10; /* GPIO0[14] on P2_10 */
scu.TX_RX_N = P2_11; /* GPIO1[11] on P2_11 */
scu.BY_MIX = P2_12; /* GPIO1[12] on P2_12 */
scu.BY_MIX_N = P5_1; /* GPIO2[10] on P5_1 */
scu.LOW_HIGH_FILT = P5_2; /* GPIO2[11] on P5_2 */
scu.LOW_HIGH_FILT_N = P5_3; /* GPIO2[12] on P5_3 */
scu.TX_AMP = P5_6; /* GPIO2[15] on P5_6 */
scu.RX_LNA = P6_7; /* GPIO5[15] on P6_7 */
#if defined(IS_HACKRF_ONE)
if (IS_HACKRF_ONE) {
scu.HP = P4_0; /* GPIO2[0] on P4_0 */
scu.LP = P5_1; /* GPIO2[10] on P5_1 */
scu.TX_MIX_BP = P5_2; /* GPIO2[11] on P5_2 */
scu.NO_MIX_BYPASS = P1_7; /* GPIO1[0] on P1_7 */
scu.RX_MIX_BP = P5_3; /* GPIO2[12] on P5_3 */
scu.TX_AMP = P5_6; /* GPIO2[15] on P5_6 */
scu.TX = P6_7; /* GPIO5[15] on P6_7 */
scu.MIX_BYPASS = P6_8; /* GPIO5[16] on P6_8 */
scu.RX = P2_5; /* GPIO5[5] on P2_5 */
scu.NO_TX_AMP_PWR = P6_9; /* GPIO3[5] on P6_9 */
scu.AMP_BYPASS = P2_10; /* GPIO0[14] on P2_10 */
scu.RX_AMP = P2_11; /* GPIO1[11] on P2_11 */
scu.NO_RX_AMP_PWR = P2_12; /* GPIO1[12] on P2_12 */
}
#endif
#if defined(IS_RAD1O)
if (IS_RAD1O) {
scu.BY_AMP = P1_7; /* GPIO1[0] on P1_7 */
scu.BY_AMP_N = P2_5; /* GPIO5[5] on P2_5 */
scu.TX_RX = P2_10; /* GPIO0[14] on P2_10 */
scu.TX_RX_N = P2_11; /* GPIO1[11] on P2_11 */
scu.BY_MIX = P2_12; /* GPIO1[12] on P2_12 */
scu.BY_MIX_N = P5_1; /* GPIO2[10] on P5_1 */
scu.LOW_HIGH_FILT = P5_2; /* GPIO2[11] on P5_2 */
scu.LOW_HIGH_FILT_N = P5_3; /* GPIO2[12] on P5_3 */
scu.TX_AMP = P5_6; /* GPIO2[15] on P5_6 */
scu.RX_LNA = P6_7; /* GPIO5[15] on P6_7 */
}
#endif
#if defined(IS_PRALINE)
if (IS_PRALINE) {
scu.TX_EN = P6_5; /* GPIO3[4] on P6_5 */
scu.MIX_EN_N = P6_3; /* GPIO3[2] on P6_3 */
scu.MIX_EN_N_R1_0 = P2_6; /* GPIO5[6] on P2_6 */
scu.LPF_EN = PA_1; /* GPIO4[8] on PA_1 */
scu.RF_AMP_EN = PA_2; /* GPIO4[9] on PA_2 */
scu.ANT_BIAS_EN_N = P2_12; /* GPIO1[12] on P2_12 */
scu.ANT_BIAS_OC_N = P2_11; /* GPIO1[11] on P2_11 */
}
#endif
/* Praline */
#if defined(PRALINE)
scu.P2_CTRL0 = (PE_3); /* GPIO7[3] on PE_3 */
scu.P2_CTRL1 = (PE_4); /* GPIO7[4] on PE_4 */
scu.P1_CTRL0 = (P2_10); /* GPIO0[14] on P2_10 */
scu.P1_CTRL1 = (P6_8); /* GPIO5[16] on P6_8 */
scu.P1_CTRL2 = (P6_9); /* GPIO3[5] on P6_9 */
scu.CLKIN_CTRL = (P1_20); /* GPIO0[15] on P1_20 */
scu.AA_EN = (P1_14); /* GPIO1[7] on P1_14 */
scu.TRIGGER_IN = (PD_12); /* GPIO6[26] on PD_12 */
scu.TRIGGER_OUT = (P2_6); /* GPIO5[6] on P2_6 */
scu.PPS_OUT = (P2_5); /* GPIO5[5] on P2_5 */
#if defined(IS_PRALINE)
if (IS_PRALINE) {
scu.P2_CTRL0 = (PE_3); /* GPIO7[3] on PE_3 */
scu.P2_CTRL1 = (PE_4); /* GPIO7[4] on PE_4 */
scu.P1_CTRL0 = (P2_10); /* GPIO0[14] on P2_10 */
scu.P1_CTRL1 = (P6_8); /* GPIO5[16] on P6_8 */
scu.P1_CTRL2 = (P6_9); /* GPIO3[5] on P6_9 */
scu.CLKIN_CTRL = (P1_20); /* GPIO0[15] on P1_20 */
scu.AA_EN = (P1_14); /* GPIO1[7] on P1_14 */
scu.TRIGGER_IN = (PD_12); /* GPIO6[26] on PD_12 */
scu.TRIGGER_OUT = (P2_6); /* GPIO5[6] on P2_6 */
scu.PPS_OUT = (P2_5); /* GPIO5[5] on P2_5 */
scu.P2_CTRL0_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.P2_CTRL1_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.P1_CTRL0_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.P1_CTRL1_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.P1_CTRL2_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.CLKIN_CTRL_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.AA_EN_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.TRIGGER_IN_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.TRIGGER_OUT_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.PPS_OUT_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.P2_CTRL0_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.P2_CTRL1_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.P1_CTRL0_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.P1_CTRL1_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.P1_CTRL2_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.CLKIN_CTRL_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.AA_EN_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu.TRIGGER_IN_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.TRIGGER_OUT_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu.PPS_OUT_PINCFG = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
}
#endif
/* HackRF One r9 */
#if defined(HACKRF_ONE)
scu.H1R9_CLKIN_EN = P6_7; /* GPIO5[15] on P6_7 */
scu.H1R9_CLKOUT_EN = P1_2; /* GPIO0[9] on P1_2 = has boot pull-down; */
scu.H1R9_MCU_CLK_EN = P1_1; /* GPIO0[8] on P1_1 = has boot pull-up; */
scu.H1R9_RX = P2_7; /* GPIO0[7] on P4_4 = has boot pull-up; */
scu.H1R9_NO_ANT_PWR = P4_4; /* GPIO2[4] on P4_4 */
scu.H1R9_EN1V8 = P5_0; /* GPIO2[9] on P5_0 */
scu.H1R9_NO_VAA_EN = P6_10; /* GPIO3[6] on P6_10 */
scu.H1R9_TRIGGER_EN = P2_5; /* GPIO5[5] on P2_5 */
#if defined(IS_H1_R9)
if (IS_H1_R9) {
scu.H1R9_CLKIN_EN = P6_7; /* GPIO5[15] on P6_7 */
scu.H1R9_CLKOUT_EN = P1_2; /* GPIO0[9] on P1_2 = has boot pull-down; */
scu.H1R9_MCU_CLK_EN = P1_1; /* GPIO0[8] on P1_1 = has boot pull-up; */
scu.H1R9_RX = P2_7; /* GPIO0[7] on P4_4 = has boot pull-up; */
scu.H1R9_NO_ANT_PWR = P4_4; /* GPIO2[4] on P4_4 */
scu.H1R9_EN1V8 = P5_0; /* GPIO2[9] on P5_0 */
scu.H1R9_NO_VAA_EN = P6_10; /* GPIO3[6] on P6_10 */
scu.H1R9_TRIGGER_EN = P2_5; /* GPIO5[5] on P2_5 */
}
#endif
/* Miscellaneous */
scu.PINMUX_PP_D0 = (P7_0); /* GPIO3[8] */
scu.PINMUX_PP_D1 = (P7_1); /* GPIO3[9] */
scu.PINMUX_PP_D2 = (P7_2); /* GPIO3[10] */
scu.PINMUX_PP_D3 = (P7_3); /* GPIO3[11] */
scu.PINMUX_PP_D4 = (P7_4); /* GPIO3[12] */
scu.PINMUX_PP_D5 = (P7_5); /* GPIO3[13] */
scu.PINMUX_PP_D6 = (P7_6); /* GPIO3[14] */
scu.PINMUX_PP_D7 = (P7_7); /* GPIO3[15] */
/* Expansion headers */
#if defined(IS_EXPANSION_COMPATIBLE)
if (IS_EXPANSION_COMPATIBLE) {
scu.PINMUX_PP_D0 = (P7_0); /* GPIO3[8] */
scu.PINMUX_PP_D1 = (P7_1); /* GPIO3[9] */
scu.PINMUX_PP_D2 = (P7_2); /* GPIO3[10] */
scu.PINMUX_PP_D3 = (P7_3); /* GPIO3[11] */
scu.PINMUX_PP_D4 = (P7_4); /* GPIO3[12] */
scu.PINMUX_PP_D5 = (P7_5); /* GPIO3[13] */
scu.PINMUX_PP_D6 = (P7_6); /* GPIO3[14] */
scu.PINMUX_PP_D7 = (P7_7); /* GPIO3[15] */
/* TODO add other Pins */
scu.PINMUX_PP_LCD_TE = (P2_3); /* GPIO5[3] on P2_3 */
scu.PINMUX_PP_LCD_RDX = (P2_4); /* GPIO5[4] on P2_4 */
scu.PINMUX_PP_UNUSED = (P2_8); /* GPIO5[7] on P2_8 */
scu.PINMUX_PP_LCD_WRX = (P2_9); /* GPIO1[10] on P2_9 */
scu.PINMUX_PP_DIR = (P2_13); /* GPIO1[13] on P2_13 */
scu.PINMUX_GPIO3_8 = (P7_0); /* GPIO3[8] */
scu.PINMUX_GPIO3_9 = (P7_1); /* GPIO3[9] */
scu.PINMUX_GPIO3_10 = (P7_2); /* GPIO3[10] */
scu.PINMUX_GPIO3_11 = (P7_3); /* GPIO3[11] */
scu.PINMUX_GPIO3_12 = (P7_4); /* GPIO3[12] */
scu.PINMUX_GPIO3_13 = (P7_5); /* GPIO3[13] */
scu.PINMUX_GPIO3_14 = (P7_6); /* GPIO3[14] */
scu.PINMUX_GPIO3_15 = (P7_7); /* GPIO3[15] */
scu.PINMUX_PP_TDO = (P1_5); /* GPIO1[8] */
scu.PINMUX_SD_POW = (P1_5); /* GPIO1[8] */
scu.PINMUX_SD_CMD = (P1_6); /* GPIO1[9] */
scu.PINMUX_PP_TMS = (P1_8); /* GPIO1[1] */
scu.PINMUX_SD_VOLT0 = (P1_8); /* GPIO1[1] */
scu.PINMUX_SD_DAT0 = (P1_9); /* GPIO1[2] */
scu.PINMUX_SD_DAT1 = (P1_10); /* GPIO1[3] */
scu.PINMUX_SD_DAT2 = (P1_11); /* GPIO1[4] */
scu.PINMUX_SD_DAT3 = (P1_12); /* GPIO1[5] */
scu.PINMUX_SD_CD = (P1_13); /* GPIO1[6] */
scu.PINMUX_PP_TDO = (P1_5); /* GPIO1[8] */
scu.PINMUX_SD_POW = (P1_5); /* GPIO1[8] */
scu.PINMUX_SD_CMD = (P1_6); /* GPIO1[9] */
scu.PINMUX_PP_TMS = (P1_8); /* GPIO1[1] */
scu.PINMUX_SD_VOLT0 = (P1_8); /* GPIO1[1] */
scu.PINMUX_SD_DAT0 = (P1_9); /* GPIO1[2] */
scu.PINMUX_SD_DAT1 = (P1_10); /* GPIO1[3] */
scu.PINMUX_SD_DAT2 = (P1_11); /* GPIO1[4] */
scu.PINMUX_SD_DAT3 = (P1_12); /* GPIO1[5] */
scu.PINMUX_SD_CD = (P1_13); /* GPIO1[6] */
scu.PINMUX_PP_IO_STBX = (P2_0); /* GPIO5[0] */
scu.PINMUX_PP_ADDR = (P2_1); /* GPIO5[1] */
scu.PINMUX_U0_TXD = (P2_0); /* GPIO5[0] */
scu.PINMUX_U0_RXD = (P2_1); /* GPIO5[1] */
scu.PINMUX_PP_IO_STBX = (P2_0); /* GPIO5[0] */
scu.PINMUX_PP_ADDR = (P2_1); /* GPIO5[1] */
scu.PINMUX_U0_TXD = (P2_0); /* GPIO5[0] */
scu.PINMUX_U0_RXD = (P2_1); /* GPIO5[1] */
scu.PINMUX_GPIO3_8 = (P7_0); /* GPIO3[8] */
scu.PINMUX_GPIO3_9 = (P7_1); /* GPIO3[9] */
scu.PINMUX_GPIO3_10 = (P7_2); /* GPIO3[10] */
scu.PINMUX_GPIO3_11 = (P7_3); /* GPIO3[11] */
scu.PINMUX_GPIO3_12 = (P7_4); /* GPIO3[12] */
scu.PINMUX_GPIO3_13 = (P7_5); /* GPIO3[13] */
scu.PINMUX_GPIO3_14 = (P7_6); /* GPIO3[14] */
scu.PINMUX_GPIO3_15 = (P7_7); /* GPIO3[15] */
}
#endif
scu.PINMUX_ISP = (P2_7); /* GPIO0[7] */

View file

@ -29,23 +29,24 @@ extern "C" {
#include <libopencm3/lpc43xx/scu.h>
#include "platform_detect.h"
/*
* SCU PinMux
*/
typedef struct {
/* LED PinMux */
/* GPIO Output PinMux */
scu_grp_pin_t PINMUX_LED1;
scu_grp_pin_t PINMUX_LED2;
scu_grp_pin_t PINMUX_LED3;
#if defined(RAD1O) || defined(PRALINE)
#if defined(IS_FOUR_LEDS)
scu_grp_pin_t PINMUX_LED4;
#endif
/* Power Supply PinMux */
scu_grp_pin_t PINMUX_EN1V8;
scu_grp_pin_t PINMUX_EN1V2;
#if defined(PRALINE)
#if defined(IS_PRALINE)
scu_grp_pin_t PINMUX_EN3V3_AUX_N;
scu_grp_pin_t PINMUX_EN3V3_OC_N;
#endif
@ -53,7 +54,7 @@ typedef struct {
/* GPIO Input PinMux */
scu_grp_pin_t PINMUX_BOOT0;
scu_grp_pin_t PINMUX_BOOT1;
#if !defined(HACKRF_ONE)
#if defined(IS_NOT_HACKRF_ONE)
scu_grp_pin_t PINMUX_BOOT2;
scu_grp_pin_t PINMUX_BOOT3;
#endif
@ -64,7 +65,7 @@ typedef struct {
scu_grp_pin_t PINMUX_PP_DIR;
/* USB peripheral */
#if defined(JAWBREAKER)
#if defined(IS_JAWBREAKER)
scu_grp_pin_t PINMUX_USB_LED0;
scu_grp_pin_t PINMUX_USB_LED1;
#endif
@ -76,16 +77,15 @@ typedef struct {
scu_grp_pin_t SSP1_CS;
/* CPLD JTAG interface */
#if defined(PRALINE)
#if defined(IS_PRALINE)
scu_grp_pin_t PINMUX_FPGA_CRESET;
scu_grp_pin_t PINMUX_FPGA_CDONE;
scu_grp_pin_t PINMUX_FPGA_SPI_CS;
#else
#endif
scu_grp_pin_t PINMUX_CPLD_TDO;
scu_grp_pin_t PINMUX_CPLD_TCK;
scu_grp_pin_t PINMUX_CPLD_TMS;
scu_grp_pin_t PINMUX_CPLD_TDI;
#endif
scu_grp_pin_t PINMUX_CPLD_TCK;
/* CPLD SGPIO interface */
scu_grp_pin_t PINMUX_SGPIO0;
@ -121,36 +121,45 @@ typedef struct {
scu_grp_pin_t TRIGGER_EN;
/* MAX283x GPIO (XCVR_CTL) PinMux */
scu_grp_pin_t XCVR_RXHP; // RAD1O, PRALINE
scu_grp_pin_t XCVR_B6; // RAD1O
scu_grp_pin_t XCVR_B7; // RAD1O
scu_grp_pin_t XCVR_ENABLE; // PRALINE, HACKRF_ONE
scu_grp_pin_t XCVR_RXENABLE; // PRALINE, HACKRF_ONE
scu_grp_pin_t XCVR_CS; // PRALINE, HACKRF_ONE
scu_grp_pin_t XCVR_LD; // PRALINE
uint32_t XCVR_ENABLE_PINCFG; // PRALINE, HACKRF_ONE
uint32_t XCVR_RXENABLE_PINCFG; // PRALINE, HACKRF_ONE
uint32_t XCVR_CS_PINCFG; // PRALINE, HACKRF_ONE
uint32_t XCVR_RXHP_PINCFG; // PRALINE
uint32_t XCVR_LD_PINCFG; // PRALINE
scu_grp_pin_t XCVR_TXENABLE; // HACKRF_ONE
uint32_t XCVR_TXENABLE_PINCFG; // HACKRF_ONE
scu_grp_pin_t XCVR_ENABLE;
scu_grp_pin_t XCVR_RXENABLE;
scu_grp_pin_t XCVR_TXENABLE;
scu_grp_pin_t XCVR_CS;
uint32_t XCVR_ENABLE_PINCFG;
uint32_t XCVR_RXENABLE_PINCFG;
uint32_t XCVR_TXENABLE_PINCFG;
uint32_t XCVR_CS_PINCFG;
#if defined(IS_PRALINE)
scu_grp_pin_t XCVR_LD;
uint32_t XCVR_LD_PINCFG;
uint32_t XCVR_RXHP_PINCFG;
#endif
#if defined(IS_RAD1O) || defined(IS_PRALINE)
scu_grp_pin_t XCVR_RXHP;
#endif
#if defined(IS_RAD1O)
scu_grp_pin_t XCVR_B6;
scu_grp_pin_t XCVR_B7;
#endif
/* MAX5864 SPI chip select (AD_CS) GPIO PinMux */
scu_grp_pin_t AD_CS;
scu_grp_pin_t AD_CS_PINCFG;
/* RFFC5071 GPIO serial interface PinMux */
#if defined(IS_NOT_RAD1O)
scu_grp_pin_t MIXER_ENX;
scu_grp_pin_t MIXER_SCLK;
scu_grp_pin_t MIXER_SDATA;
scu_grp_pin_t MIXER_RESETX;
uint32_t MIXER_SCLK_PINCFG;
uint32_t MIXER_SDATA_PINCFG;
#if defined(PRALINE)
#endif
#if defined(IS_PRALINE)
scu_grp_pin_t MIXER_LD;
uint32_t MIXER_LD_PINCFG;
#elif defined(RAD1O)
#endif
#if defined(IS_RAD1O)
scu_grp_pin_t VCO_CE;
scu_grp_pin_t VCO_SCLK;
scu_grp_pin_t VCO_SDATA;
@ -161,14 +170,15 @@ typedef struct {
#endif
/* RF LDO control */
#if defined(JAWBREAKER)
#if defined(IS_JAWBREAKER)
scu_grp_pin_t RF_LDO_ENABLE;
#endif
/* RF supply (VAA) control */
#if defined(PRALINE) || defined(HACKRF_ONE)
#if defined(IS_PRALINE) || defined(IS_HACKRF_ONE)
scu_grp_pin_t NO_VAA_ENABLE;
#elif defined(RAD1O)
#endif
#if defined(IS_RAD1O)
scu_grp_pin_t VAA_ENABLE;
#endif
@ -181,7 +191,7 @@ typedef struct {
scu_grp_pin_t FLASH_WP;
/* RF switch control */
#if defined(PRALINE)
#if defined(IS_PRALINE)
scu_grp_pin_t TX_EN;
scu_grp_pin_t MIX_EN_N;
scu_grp_pin_t MIX_EN_N_R1_0;
@ -189,7 +199,8 @@ typedef struct {
scu_grp_pin_t RF_AMP_EN;
scu_grp_pin_t ANT_BIAS_EN_N;
scu_grp_pin_t ANT_BIAS_OC_N;
#elif defined(HACKRF_ONE)
#endif
#if defined(IS_HACKRF_ONE)
scu_grp_pin_t HP;
scu_grp_pin_t LP;
scu_grp_pin_t TX_MIX_BP;
@ -203,7 +214,8 @@ typedef struct {
scu_grp_pin_t AMP_BYPASS;
scu_grp_pin_t RX_AMP;
scu_grp_pin_t NO_RX_AMP_PWR;
#elif defined(RAD1O)
#endif
#if defined(IS_RAD1O)
scu_grp_pin_t BY_AMP;
scu_grp_pin_t BY_AMP_N;
scu_grp_pin_t TX_RX;
@ -217,7 +229,7 @@ typedef struct {
#endif
/* Praline */
#if defined(PRALINE)
#if defined(IS_PRALINE)
scu_grp_pin_t P2_CTRL0;
scu_grp_pin_t P2_CTRL1;
scu_grp_pin_t P1_CTRL0;
@ -242,7 +254,7 @@ typedef struct {
#endif
/* HackRF One r9 */
#if defined(HACKRF_ONE)
#if defined(IS_HACKRF_ONE)
scu_grp_pin_t H1R9_CLKIN_EN;
scu_grp_pin_t H1R9_CLKOUT_EN;
scu_grp_pin_t H1R9_MCU_CLK_EN;
@ -262,9 +274,7 @@ typedef struct {
scu_grp_pin_t PINMUX_PP_D5;
scu_grp_pin_t PINMUX_PP_D6;
scu_grp_pin_t PINMUX_PP_D7;
/* TODO add other Pins */
scu_grp_pin_t PINMUX_GPIO3_8;
scu_grp_pin_t PINMUX_GPIO3_9;
scu_grp_pin_t PINMUX_GPIO3_10;

View file

@ -33,7 +33,7 @@
#include "rf_path.h"
#include "transceiver_mode.h"
#include "tuning.h"
#if defined(PRALINE)
#if defined(IS_PRALINE)
#include "fpga.h"
#include "tune_config.h"
#endif
@ -197,8 +197,10 @@ static bool radio_update_sample_rate(radio_t* const radio, uint64_t* bank)
case TRANSCEIVER_MODE_SS:
n = compute_resample_log(rate / SR_FP_ONE_HZ, requested_n);
if (n != radio->config[RADIO_BANK_APPLIED][RADIO_RESAMPLE_TX]) {
#ifdef PRALINE
fpga_set_tx_interpolation_ratio(&fpga, n);
#if defined(IS_PRALINE)
if (IS_PRALINE) {
fpga_set_tx_interpolation_ratio(&fpga, n);
}
#endif
radio->config[RADIO_BANK_APPLIED][RADIO_RESAMPLE_TX] = n;
}
@ -206,8 +208,10 @@ static bool radio_update_sample_rate(radio_t* const radio, uint64_t* bank)
default:
n = compute_resample_log(rate / SR_FP_ONE_HZ, requested_n);
if (n != radio->config[RADIO_BANK_APPLIED][RADIO_RESAMPLE_RX]) {
#ifdef PRALINE
fpga_set_rx_decimation_ratio(&fpga, n);
#if defined(IS_PRALINE)
if (IS_PRALINE) {
fpga_set_rx_decimation_ratio(&fpga, n);
}
#endif
radio->config[RADIO_BANK_APPLIED][RADIO_RESAMPLE_RX] = n;
}
@ -244,7 +248,7 @@ static bool radio_update_sample_rate(radio_t* const radio, uint64_t* bank)
static fp_28_36_t applied_offset = RADIO_UNSET;
#ifdef PRALINE
#if defined(IS_PRALINE)
static const tune_config_t* select_tune_config(uint64_t opmode)
{
switch (opmode) {
@ -301,15 +305,20 @@ static bool radio_update_frequency(radio_t* const radio, uint64_t* bank)
radio->config[RADIO_BANK_APPLIED][RADIO_FREQUENCY_RF] =
RADIO_UNSET;
}
#ifdef PRALINE
const uint64_t requested_rotation = bank[RADIO_ROTATION];
if (requested_rotation != RADIO_UNSET) {
rotation = requested_rotation;
} else if (radio->config[RADIO_BANK_APPLIED][RADIO_ROTATION] != RADIO_UNSET) {
return true;
#if defined(IS_PRALINE)
if (IS_PRALINE) {
const uint64_t requested_rotation = bank[RADIO_ROTATION];
if (requested_rotation != RADIO_UNSET) {
rotation = requested_rotation;
} else if (
radio->config[RADIO_BANK_APPLIED][RADIO_ROTATION] !=
RADIO_UNSET) {
return true;
}
fpga_set_rx_quarter_shift_mode(&fpga, rotation >> 6);
}
fpga_set_rx_quarter_shift_mode(&fpga, rotation >> 6);
#endif
radio->config[RADIO_BANK_APPLIED][RADIO_ROTATION] = rotation;
return true;
}
@ -323,44 +332,50 @@ static bool radio_update_frequency(radio_t* const radio, uint64_t* bank)
}
}
bool new_rf =
(radio->config[RADIO_BANK_APPLIED][RADIO_FREQUENCY_RF] != requested_rf);
uint64_t requested_rf_hz = requested_rf / FP_ONE_HZ;
#ifdef PRALINE
if (applied_afe_rate == RADIO_UNSET) {
return false;
}
const tune_config_t* tune_config = select_tune_config(opmode);
const tune_config_t* applied_tune_config =
select_tune_config(radio->config[RADIO_BANK_APPLIED][RADIO_OPMODE]);
bool new_config = (applied_tune_config != tune_config);
while ((tune_config->rf_range_end_mhz != 0) || (tune_config->if_mhz != 0)) {
if ((requested_rf_hz == 0) ||
(tune_config->rf_range_end_mhz > (requested_rf_hz / FREQ_ONE_MHZ))) {
break;
#if defined(IS_PRALINE)
if (IS_PRALINE) {
bool new_rf =
(radio->config[RADIO_BANK_APPLIED][RADIO_FREQUENCY_RF] !=
requested_rf);
if (applied_afe_rate == RADIO_UNSET) {
return false;
}
const tune_config_t* tune_config = select_tune_config(opmode);
const tune_config_t* applied_tune_config = select_tune_config(
radio->config[RADIO_BANK_APPLIED][RADIO_OPMODE]);
bool new_config = (applied_tune_config != tune_config);
while ((tune_config->rf_range_end_mhz != 0) ||
(tune_config->if_mhz != 0)) {
if ((requested_rf_hz == 0) ||
(tune_config->rf_range_end_mhz >
(requested_rf_hz / FREQ_ONE_MHZ))) {
break;
}
tune_config++;
}
bool new_rotation =
(radio->config[RADIO_BANK_APPLIED][RADIO_ROTATION] !=
((uint64_t) tune_config->shift << 6));
if (new_rotation) {
fpga_set_rx_quarter_shift_mode(&fpga, tune_config->shift);
radio->config[RADIO_BANK_APPLIED][RADIO_ROTATION] =
tune_config->shift << 6;
}
fp_28_36_t offset = applied_afe_rate / 4;
bool new_offset = (applied_offset != offset);
if (new_rotation || new_offset || new_config || new_rf) {
tuning_set_frequency(
tune_config,
requested_rf_hz,
offset / SR_FP_ONE_HZ,
opmode);
applied_offset = offset;
}
tune_config++;
}
bool new_rotation =
(radio->config[RADIO_BANK_APPLIED][RADIO_ROTATION] !=
((uint64_t) tune_config->shift << 6));
if (new_rotation) {
fpga_set_rx_quarter_shift_mode(&fpga, tune_config->shift);
radio->config[RADIO_BANK_APPLIED][RADIO_ROTATION] =
tune_config->shift << 6;
}
fp_28_36_t offset = applied_afe_rate / 4;
bool new_offset = (applied_offset != offset);
if (new_rotation || new_offset || new_config || new_rf) {
tuning_set_frequency(
tune_config,
requested_rf_hz,
offset / SR_FP_ONE_HZ,
opmode);
applied_offset = offset;
}
#else
if (new_rf) {
#endif
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
set_freq(requested_rf_hz, opmode);
}
#endif
@ -400,66 +415,92 @@ static bool radio_update_bandwidth(radio_t* const radio, uint64_t* bank)
{
bool new_bw = false;
#ifdef PRALINE
/* Praline legacy mode always sets baseband bandwidth automatically. */
(void) bank;
uint32_t lpf_bandwidth = auto_bandwidth(radio);
#if defined(IS_PRALINE)
if (IS_PRALINE) {
/* Praline legacy mode always sets baseband bandwidth automatically. */
(void) bank;
uint32_t lpf_bandwidth = auto_bandwidth(radio);
if (radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_TX_LPF] != lpf_bandwidth) {
max283x_set_lpf_bandwidth(&max283x, MAX283x_MODE_TX, lpf_bandwidth);
radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_TX_LPF] = lpf_bandwidth;
new_bw = true;
}
if (radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_RX_LPF] != lpf_bandwidth) {
max283x_set_lpf_bandwidth(&max283x, MAX283x_MODE_RX, lpf_bandwidth);
radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_RX_LPF] = lpf_bandwidth;
new_bw = true;
}
bool narrow_lpf_enable = false;
bool applied_narrow_lpf_enable =
radio->config[RADIO_BANK_APPLIED][RADIO_RX_NARROW_LPF];
if (lpf_bandwidth <= 1750000) {
narrow_lpf_enable = true;
}
if (applied_narrow_lpf_enable != narrow_lpf_enable) {
narrowband_filter_set(narrow_lpf_enable);
radio->config[RADIO_BANK_APPLIED][RADIO_RX_NARROW_LPF] =
narrow_lpf_enable;
new_bw = true;
}
/* Always set HPF bandwidth to 30 kHz for now. */
const max283x_rx_hpf_freq_t hpf_bandwidth = MAX283x_RX_HPF_30_KHZ;
if (radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_RX_HPF] != hpf_bandwidth) {
max283x_set_rx_hpf_frequency(&max283x, hpf_bandwidth);
radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_RX_HPF] = hpf_bandwidth;
new_bw = true;
}
#else
uint64_t lpf_bandwidth;
lpf_bandwidth = bank[RADIO_XCVR_TX_LPF];
if (lpf_bandwidth == RADIO_UNSET) {
lpf_bandwidth = bank[RADIO_XCVR_RX_LPF];
}
if (lpf_bandwidth == RADIO_UNSET) {
lpf_bandwidth = bank[RADIO_BB_BANDWIDTH_TX];
}
if (lpf_bandwidth == RADIO_UNSET) {
lpf_bandwidth = bank[RADIO_BB_BANDWIDTH_RX];
}
if (lpf_bandwidth == RADIO_UNSET) {
lpf_bandwidth = radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_TX_LPF];
}
if (lpf_bandwidth == RADIO_UNSET) {
lpf_bandwidth = auto_bandwidth(radio);
if (radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_TX_LPF] !=
lpf_bandwidth) {
max283x_set_lpf_bandwidth(
&max283x,
MAX283x_MODE_TX,
lpf_bandwidth);
radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_TX_LPF] =
lpf_bandwidth;
new_bw = true;
}
if (radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_RX_LPF] !=
lpf_bandwidth) {
max283x_set_lpf_bandwidth(
&max283x,
MAX283x_MODE_RX,
lpf_bandwidth);
radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_RX_LPF] =
lpf_bandwidth;
new_bw = true;
}
bool narrow_lpf_enable = false;
bool applied_narrow_lpf_enable =
radio->config[RADIO_BANK_APPLIED][RADIO_RX_NARROW_LPF];
if (lpf_bandwidth <= 1750000) {
narrow_lpf_enable = true;
}
if (applied_narrow_lpf_enable != narrow_lpf_enable) {
narrowband_filter_set(narrow_lpf_enable);
radio->config[RADIO_BANK_APPLIED][RADIO_RX_NARROW_LPF] =
narrow_lpf_enable;
new_bw = true;
}
/* Always set HPF bandwidth to 30 kHz for now. */
const max283x_rx_hpf_freq_t hpf_bandwidth = MAX283x_RX_HPF_30_KHZ;
if (radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_RX_HPF] !=
hpf_bandwidth) {
max283x_set_rx_hpf_frequency(&max283x, hpf_bandwidth);
radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_RX_HPF] =
hpf_bandwidth;
new_bw = true;
}
}
#endif
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
uint64_t lpf_bandwidth;
lpf_bandwidth = bank[RADIO_XCVR_TX_LPF];
if (lpf_bandwidth == RADIO_UNSET) {
lpf_bandwidth = bank[RADIO_XCVR_RX_LPF];
}
if (lpf_bandwidth == RADIO_UNSET) {
lpf_bandwidth = bank[RADIO_BB_BANDWIDTH_TX];
}
if (lpf_bandwidth == RADIO_UNSET) {
lpf_bandwidth = bank[RADIO_BB_BANDWIDTH_RX];
}
if (lpf_bandwidth == RADIO_UNSET) {
lpf_bandwidth =
radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_TX_LPF];
}
if (lpf_bandwidth == RADIO_UNSET) {
lpf_bandwidth = auto_bandwidth(radio);
}
if (radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_TX_LPF] != lpf_bandwidth) {
max283x_set_lpf_bandwidth(&max283x, MAX283x_MODE_TX, lpf_bandwidth);
radio->config[RADIO_BANK_APPLIED][RADIO_BB_BANDWIDTH_RX] = lpf_bandwidth;
radio->config[RADIO_BANK_APPLIED][RADIO_BB_BANDWIDTH_TX] = lpf_bandwidth;
radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_TX_LPF] = lpf_bandwidth;
radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_RX_LPF] = lpf_bandwidth;
new_bw = true;
if (radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_TX_LPF] !=
lpf_bandwidth) {
max283x_set_lpf_bandwidth(
&max283x,
MAX283x_MODE_TX,
lpf_bandwidth);
radio->config[RADIO_BANK_APPLIED][RADIO_BB_BANDWIDTH_RX] =
lpf_bandwidth;
radio->config[RADIO_BANK_APPLIED][RADIO_BB_BANDWIDTH_TX] =
lpf_bandwidth;
radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_TX_LPF] =
lpf_bandwidth;
radio->config[RADIO_BANK_APPLIED][RADIO_XCVR_RX_LPF] =
lpf_bandwidth;
new_bw = true;
}
}
#endif
return new_bw;
@ -597,26 +638,29 @@ static bool radio_update_trigger(radio_t* const radio, uint64_t* bank)
static bool radio_update_dc_block(radio_t* const radio, uint64_t* bank)
{
#ifndef PRALINE
#if defined(IS_PRALINE)
if (IS_PRALINE) {
const uint64_t requested = bank[RADIO_DC_BLOCK];
bool enable = requested;
if (requested == RADIO_UNSET) {
enable = true;
}
if (radio->config[RADIO_BANK_APPLIED][RADIO_DC_BLOCK] ==
(uint64_t) enable) {
return false;
}
fpga_set_rx_dc_block_enable(&fpga, enable);
radio->config[RADIO_BANK_APPLIED][RADIO_DC_BLOCK] = enable;
return true;
}
#endif
(void) radio;
(void) bank;
return false;
#else
const uint64_t requested = bank[RADIO_DC_BLOCK];
bool enable = requested;
if (requested == RADIO_UNSET) {
enable = true;
}
if (radio->config[RADIO_BANK_APPLIED][RADIO_DC_BLOCK] == (uint64_t) enable) {
return false;
}
fpga_set_rx_dc_block_enable(&fpga, enable);
radio->config[RADIO_BANK_APPLIED][RADIO_DC_BLOCK] = enable;
return true;
#endif
}
bool radio_update(radio_t* const radio)

View file

@ -23,10 +23,6 @@
#include "rf_path.h"
#if defined(HACKRF_ONE) || defined(RAD1O) || defined(PRALINE)
#include <libopencm3/lpc43xx/scu.h>
#endif
#include "hackrf_core.h"
#include "hackrf_ui.h"
#include "max283x.h"
@ -35,7 +31,9 @@
#include "platform_detect.h"
#include "sgpio.h"
#include "transceiver_mode.h"
#if defined(HACKRF_ONE) || defined(RAD1O) || defined(PRALINE)
#if defined(IS_NOT_JAWBREAKER)
#include <libopencm3/lpc43xx/scu.h>
#include "gpio.h"
#include "platform_scu.h"
#endif
@ -95,17 +93,18 @@
#define SWITCHCTRL_ANT_PWR (1 << 6) /* turn on antenna port power */
#ifdef HACKRF_ONE
#if defined(IS_HACKRF_ONE)
static void switchctrl_set_hackrf_one(rf_path_t* const rf_path, uint8_t ctrl)
{
board_id_t board_id = detected_platform();
if (ctrl & SWITCHCTRL_TX) {
if (detected_platform() != BOARD_ID_HACKRF1_R9) {
if (board_id != BOARD_ID_HACKRF1_R9) {
gpio_set(rf_path->gpio_tx);
}
gpio_clear(rf_path->gpio_rx);
} else {
if (detected_platform() != BOARD_ID_HACKRF1_R9) {
if (board_id != BOARD_ID_HACKRF1_R9) {
gpio_clear(rf_path->gpio_tx);
}
gpio_set(rf_path->gpio_rx);
@ -168,7 +167,7 @@ static void switchctrl_set_hackrf_one(rf_path_t* const rf_path, uint8_t ctrl)
gpio_set(rf_path->gpio_no_rx_amp_pwr);
}
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
if (board_id == BOARD_ID_HACKRF1_R9) {
if (ctrl & SWITCHCTRL_ANT_PWR) {
gpio_clear(rf_path->gpio_h1r9_no_ant_pwr);
} else {
@ -188,7 +187,7 @@ static void switchctrl_set_hackrf_one(rf_path_t* const rf_path, uint8_t ctrl)
}
#endif
#ifdef PRALINE
#if defined(IS_PRALINE)
static void switchctrl_set_praline(rf_path_t* const rf_path, uint8_t ctrl)
{
if (ctrl & SWITCHCTRL_TX) {
@ -229,7 +228,7 @@ static void switchctrl_set_praline(rf_path_t* const rf_path, uint8_t ctrl)
}
#endif
#ifdef RAD1O
#if defined(RAD1O)
static void switchctrl_set_rad1o(rf_path_t* const rf_path, uint8_t ctrl)
{
if (ctrl & SWITCHCTRL_TX) {
@ -296,142 +295,170 @@ static void switchctrl_set_rad1o(rf_path_t* const rf_path, uint8_t ctrl)
static void switchctrl_set(rf_path_t* const rf_path, const uint8_t gpo)
{
#ifdef JAWBREAKER
(void) rf_path; /* silence unused param warning */
mixer_set_gpo(&mixer, gpo);
#elif HACKRF_ONE
switchctrl_set_hackrf_one(rf_path, gpo);
#elif PRALINE
switchctrl_set_praline(rf_path, gpo);
#elif RAD1O
switchctrl_set_rad1o(rf_path, gpo);
#else
(void) gpo;
#if defined(IS_JAWBREAKER)
if (IS_JAWBREAKER) {
(void) rf_path;
mixer_set_gpo(&mixer, gpo);
}
#endif
#if defined(IS_HACKRF_ONE)
if (IS_HACKRF_ONE) {
switchctrl_set_hackrf_one(rf_path, gpo);
}
#endif
#if defined(IS_PRALINE)
if (IS_PRALINE) {
switchctrl_set_praline(rf_path, gpo);
}
#endif
#if defined(IS_RAD1O)
if (IS_RAD1O) {
switchctrl_set_rad1o(rf_path, gpo);
}
#endif
}
void rf_path_pin_setup(rf_path_t* const rf_path)
{
#if !defined(JAWBREAKER)
#if defined(JAWBREAKER)
(void) rf_path;
#else
const platform_scu_t* scu = platform_scu();
#endif
#ifdef HACKRF_ONE
/* Configure RF switch control signals */
// clang-format off
scu_pinmux(scu->HP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->LP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->TX_MIX_BP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->NO_MIX_BYPASS, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->RX_MIX_BP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->TX_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->MIX_BYPASS, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu_pinmux(scu->NO_TX_AMP_PWR, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->AMP_BYPASS, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->RX_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->NO_RX_AMP_PWR, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
// clang-format on
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
scu_pinmux(scu->H1R9_RX, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->H1R9_NO_ANT_PWR, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
gpio_clear(rf_path->gpio_h1r9_no_ant_pwr);
gpio_output(rf_path->gpio_h1r9_no_ant_pwr);
scu_pinmux(scu->H1R9_NO_VAA_EN, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
} else {
scu_pinmux(scu->TX, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu_pinmux(scu->RX, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
gpio_output(rf_path->gpio_tx);
#if defined(IS_HACKRF_ONE)
if (IS_HACKRF_ONE) {
/* Configure RF switch control signals */
// clang-format off
scu_pinmux(scu->HP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->LP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->TX_MIX_BP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->NO_MIX_BYPASS, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->RX_MIX_BP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->TX_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->MIX_BYPASS, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu_pinmux(scu->NO_TX_AMP_PWR, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->AMP_BYPASS, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->RX_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->NO_RX_AMP_PWR, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
// clang-format on
#if defined(IS_H1_R9)
if (IS_H1_R9) {
scu_pinmux(scu->H1R9_RX, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(
scu->H1R9_NO_ANT_PWR,
SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
gpio_clear(rf_path->gpio_h1r9_no_ant_pwr);
gpio_output(rf_path->gpio_h1r9_no_ant_pwr);
scu_pinmux(
scu->H1R9_NO_VAA_EN,
SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
}
#endif
#if defined(IS_NOT_H1_R9)
if (IS_NOT_H1_R9) {
scu_pinmux(scu->TX, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu_pinmux(scu->RX, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
gpio_output(rf_path->gpio_tx);
scu_pinmux(scu->NO_VAA_ENABLE, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
}
#endif
/*
* Safe (initial) switch settings turn off both amplifiers and antenna port
* power and enable both amp bypass and mixer bypass.
*/
switchctrl_set(rf_path, SWITCHCTRL_SAFE);
/* Configure RF switch control signals as outputs */
gpio_output(rf_path->gpio_amp_bypass);
gpio_output(rf_path->gpio_no_mix_bypass);
gpio_output(rf_path->gpio_rx_amp);
gpio_output(rf_path->gpio_no_rx_amp_pwr);
gpio_output(rf_path->gpio_hp);
gpio_output(rf_path->gpio_lp);
gpio_output(rf_path->gpio_tx_mix_bp);
gpio_output(rf_path->gpio_rx_mix_bp);
gpio_output(rf_path->gpio_tx_amp);
gpio_output(rf_path->gpio_no_tx_amp_pwr);
gpio_output(rf_path->gpio_mix_bypass);
gpio_output(rf_path->gpio_rx);
}
#endif
#if defined(IS_RAD1O)
if (IS_RAD1O) {
/* Configure RF switch control signals */
// clang-format off
scu_pinmux(scu->BY_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->BY_AMP_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu_pinmux(scu->TX_RX, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->TX_RX_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->BY_MIX, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->BY_MIX_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->LOW_HIGH_FILT, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->LOW_HIGH_FILT_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->TX_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->RX_LNA, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu_pinmux(scu->MIXER_EN, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
// clang-format on
/* Configure RF power supply (VAA) switch */
scu_pinmux(scu->VAA_ENABLE, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
/*
* Safe (initial) switch settings turn off both amplifiers and antenna port
* power and enable both amp bypass and mixer bypass.
*/
switchctrl_set(rf_path, SWITCHCTRL_SAFE);
/* Configure RF switch control signals as outputs */
gpio_output(rf_path->gpio_tx_rx_n);
gpio_output(rf_path->gpio_tx_rx);
gpio_output(rf_path->gpio_by_mix);
gpio_output(rf_path->gpio_by_mix_n);
gpio_output(rf_path->gpio_by_amp);
gpio_output(rf_path->gpio_by_amp_n);
gpio_output(rf_path->gpio_mixer_en);
gpio_output(rf_path->gpio_low_high_filt);
gpio_output(rf_path->gpio_low_high_filt_n);
gpio_output(rf_path->gpio_tx_amp);
gpio_output(rf_path->gpio_rx_lna);
}
#endif
#if defined(IS_PRALINE)
if (IS_PRALINE) {
/* Configure RF switch control signals */
scu_pinmux(scu->TX_EN, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
board_rev_t rev = detected_revision();
if ((rev == BOARD_REV_PRALINE_R1_0) ||
(rev == BOARD_REV_GSG_PRALINE_R1_0)) {
scu_pinmux(scu->MIX_EN_N_R1_0, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
} else {
scu_pinmux(scu->MIX_EN_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
}
scu_pinmux(scu->LPF_EN, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->RF_AMP_EN, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
/* Configure antenna port power control signal */
scu_pinmux(scu->ANT_BIAS_EN_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
/* Configure RF power supply (VAA) switch */
scu_pinmux(scu->NO_VAA_ENABLE, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
/*
* Safe (initial) switch settings turn off both amplifiers and antenna port
* power and enable both amp bypass and mixer bypass.
*/
switchctrl_set(rf_path, SWITCHCTRL_SAFE);
/* Configure RF switch control signals as outputs */
gpio_output(rf_path->gpio_ant_bias_en_n);
gpio_output(rf_path->gpio_tx_en);
gpio_output(rf_path->gpio_mix_en_n);
gpio_output(rf_path->gpio_lpf_en);
gpio_output(rf_path->gpio_rf_amp_en);
}
/*
* Safe (initial) switch settings turn off both amplifiers and antenna port
* power and enable both amp bypass and mixer bypass.
*/
switchctrl_set(rf_path, SWITCHCTRL_SAFE);
/* Configure RF switch control signals as outputs */
gpio_output(rf_path->gpio_amp_bypass);
gpio_output(rf_path->gpio_no_mix_bypass);
gpio_output(rf_path->gpio_rx_amp);
gpio_output(rf_path->gpio_no_rx_amp_pwr);
gpio_output(rf_path->gpio_hp);
gpio_output(rf_path->gpio_lp);
gpio_output(rf_path->gpio_tx_mix_bp);
gpio_output(rf_path->gpio_rx_mix_bp);
gpio_output(rf_path->gpio_tx_amp);
gpio_output(rf_path->gpio_no_tx_amp_pwr);
gpio_output(rf_path->gpio_mix_bypass);
gpio_output(rf_path->gpio_rx);
#elif RAD1O
/* Configure RF switch control signals */
// clang-format off
scu_pinmux(scu->BY_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->BY_AMP_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu_pinmux(scu->TX_RX, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->TX_RX_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->BY_MIX, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->BY_MIX_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->LOW_HIGH_FILT, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->LOW_HIGH_FILT_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->TX_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->RX_LNA, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu_pinmux(scu->MIXER_EN, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
// clang-format on
/* Configure RF power supply (VAA) switch */
scu_pinmux(scu->VAA_ENABLE, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
/*
* Safe (initial) switch settings turn off both amplifiers and antenna port
* power and enable both amp bypass and mixer bypass.
*/
switchctrl_set(rf_path, SWITCHCTRL_SAFE);
/* Configure RF switch control signals as outputs */
gpio_output(rf_path->gpio_tx_rx_n);
gpio_output(rf_path->gpio_tx_rx);
gpio_output(rf_path->gpio_by_mix);
gpio_output(rf_path->gpio_by_mix_n);
gpio_output(rf_path->gpio_by_amp);
gpio_output(rf_path->gpio_by_amp_n);
gpio_output(rf_path->gpio_mixer_en);
gpio_output(rf_path->gpio_low_high_filt);
gpio_output(rf_path->gpio_low_high_filt_n);
gpio_output(rf_path->gpio_tx_amp);
gpio_output(rf_path->gpio_rx_lna);
#elif PRALINE
/* Configure RF switch control signals */
scu_pinmux(scu->TX_EN, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
board_rev_t rev = detected_revision();
if ((rev == BOARD_REV_PRALINE_R1_0) || (rev == BOARD_REV_GSG_PRALINE_R1_0)) {
scu_pinmux(scu->MIX_EN_N_R1_0, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
} else {
scu_pinmux(scu->MIX_EN_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
}
scu_pinmux(scu->LPF_EN, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(scu->RF_AMP_EN, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
/* Configure antenna port power control signal */
scu_pinmux(scu->ANT_BIAS_EN_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
/* Configure RF power supply (VAA) switch */
scu_pinmux(scu->NO_VAA_ENABLE, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
/*
* Safe (initial) switch settings turn off both amplifiers and antenna port
* power and enable both amp bypass and mixer bypass.
*/
switchctrl_set(rf_path, SWITCHCTRL_SAFE);
/* Configure RF switch control signals as outputs */
gpio_output(rf_path->gpio_ant_bias_en_n);
gpio_output(rf_path->gpio_tx_en);
gpio_output(rf_path->gpio_mix_en_n);
gpio_output(rf_path->gpio_lpf_en);
gpio_output(rf_path->gpio_rf_amp_en);
#else
(void) rf_path; /* silence unused param warning */
#endif
}
@ -442,20 +469,22 @@ void rf_path_init(rf_path_t* const rf_path)
max5864_shutdown(&max5864);
ssp1_set_mode_max283x();
#ifdef PRALINE
max283x_setup(&max283x, MAX2831_VARIANT);
#else
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
max283x_setup(&max283x, MAX2839_VARIANT);
} else {
max283x_setup(&max283x, MAX2837_VARIANT);
}
#endif
max283x_setup(&max283x);
max283x_start(&max283x);
// On HackRF One, the mixer is now set up earlier in boot.
#ifndef HACKRF_ONE
mixer_setup(&mixer);
#if defined(IS_RAD1O)
if (IS_RAD1O) {
mixer_setup(&mixer, MAX2871_VARIANT);
}
#endif
#if defined(IS_NOT_RAD1O)
if (IS_NOT_RAD1O) {
#if defined(IS_NOT_HACKRF_ONE)
if (IS_NOT_HACKRF_ONE) {
mixer_setup(&mixer, RFFC5071_VARIANT);
}
#endif
}
#endif
rf_path->switchctrl = SWITCHCTRL_SAFE;
}
@ -502,7 +531,7 @@ void rf_path_set_direction(rf_path_t* const rf_path, const rf_path_direction_t d
sgpio_configure(&sgpio_config, SGPIO_DIRECTION_RX);
break;
#ifdef PRALINE
#if defined(IS_PRALINE)
case RF_PATH_DIRECTION_TX_CALIBRATION:
case RF_PATH_DIRECTION_RX_CALIBRATION:
rf_path->switchctrl &= ~SWITCHCTRL_TX;

View file

@ -25,8 +25,9 @@
#include <stdint.h>
#include "platform_detect.h"
#include "transceiver_mode.h"
#if defined(HACKRF_ONE) || defined(RAD1O) || defined(PRALINE)
#if defined(IS_HACKRF_ONE) || defined(IS_RAD1O) || defined(IS_PRALINE)
#include "gpio.h"
#endif
@ -34,7 +35,7 @@ typedef enum {
RF_PATH_DIRECTION_OFF,
RF_PATH_DIRECTION_RX,
RF_PATH_DIRECTION_TX,
#ifdef PRALINE
#if defined(IS_PRALINE)
RF_PATH_DIRECTION_TX_CALIBRATION,
RF_PATH_DIRECTION_RX_CALIBRATION,
#endif
@ -48,43 +49,48 @@ typedef enum {
typedef struct {
uint8_t switchctrl;
#ifdef HACKRF_ONE
gpio_t gpio_hp;
gpio_t gpio_lp;
gpio_t gpio_tx_mix_bp;
gpio_t gpio_no_mix_bypass;
gpio_t gpio_rx_mix_bp;
gpio_t gpio_tx_amp;
gpio_t gpio_tx;
gpio_t gpio_mix_bypass;
gpio_t gpio_rx;
gpio_t gpio_no_tx_amp_pwr;
gpio_t gpio_amp_bypass;
gpio_t gpio_rx_amp;
gpio_t gpio_no_rx_amp_pwr;
// In HackRF One r9 this control signal has been moved to the microcontroller.
gpio_t gpio_h1r9_no_ant_pwr;
struct {
#if defined(IS_HACKRF_ONE)
gpio_t gpio_hp;
gpio_t gpio_lp;
gpio_t gpio_tx_mix_bp;
gpio_t gpio_no_mix_bypass;
gpio_t gpio_rx_mix_bp;
gpio_t gpio_tx_amp;
gpio_t gpio_tx;
gpio_t gpio_mix_bypass;
gpio_t gpio_rx;
gpio_t gpio_no_tx_amp_pwr;
gpio_t gpio_amp_bypass;
gpio_t gpio_rx_amp;
gpio_t gpio_no_rx_amp_pwr;
// In HackRF One r9 this control signal has been moved to the microcontroller.
gpio_t gpio_h1r9_no_ant_pwr;
#endif
#ifdef RAD1O
gpio_t gpio_tx_rx_n;
gpio_t gpio_tx_rx;
gpio_t gpio_by_mix;
gpio_t gpio_by_mix_n;
gpio_t gpio_by_amp;
gpio_t gpio_by_amp_n;
gpio_t gpio_mixer_en;
gpio_t gpio_low_high_filt;
gpio_t gpio_low_high_filt_n;
gpio_t gpio_tx_amp;
gpio_t gpio_rx_lna;
#if defined(IS_RAD1O)
gpio_t gpio_tx_rx_n;
gpio_t gpio_tx_rx;
gpio_t gpio_by_mix;
gpio_t gpio_by_mix_n;
gpio_t gpio_by_amp;
gpio_t gpio_by_amp_n;
gpio_t gpio_mixer_en;
gpio_t gpio_low_high_filt;
gpio_t gpio_low_high_filt_n;
gpio_t gpio_tx_amp;
gpio_t gpio_rx_lna;
#endif
#ifdef PRALINE
gpio_t gpio_tx_en;
gpio_t gpio_mix_en_n;
gpio_t gpio_lpf_en;
gpio_t gpio_rf_amp_en;
gpio_t gpio_ant_bias_en_n;
#if defined(IS_PRALINE)
gpio_t gpio_tx_en;
gpio_t gpio_mix_en_n;
gpio_t gpio_lpf_en;
gpio_t gpio_rf_amp_en;
gpio_t gpio_ant_bias_en_n;
#endif
};
} rf_path_t;
void rf_path_pin_setup(rf_path_t* const rf_path);

View file

@ -34,15 +34,13 @@
#include <stdint.h>
#include <string.h>
#if defined(PRALINE)
#include <libopencm3/lpc43xx/scu.h>
#endif
#include "delay.h"
#include "platform_detect.h"
#include "rffc5071.h"
#include "rffc5071_regs.def" // private register def macros
#include "selftest.h"
#if defined(PRALINE)
#if defined(IS_PRALINE)
#include <libopencm3/lpc43xx/scu.h>
#include "platform_scu.h"
#endif
@ -107,11 +105,13 @@ void rffc5071_setup(rffc5071_driver_t* const drv)
gpio_set(drv->gpio_reset);
gpio_output(drv->gpio_reset);
#ifdef PRALINE
/* Configure mixer PLL lock detect pin */
const platform_scu_t* scu = platform_scu();
scu_pinmux(scu->MIXER_LD, scu->MIXER_LD_PINCFG);
gpio_input(drv->gpio_ld);
#if defined(IS_PRALINE)
if (IS_PRALINE) {
/* Configure mixer PLL lock detect pin */
const platform_scu_t* scu = platform_scu();
scu_pinmux(scu->MIXER_LD, scu->MIXER_LD_PINCFG);
gpio_input(drv->gpio_ld);
}
#endif
rffc5071_init(drv);
@ -130,9 +130,10 @@ void rffc5071_setup(rffc5071_driver_t* const drv)
set_RFFC5071_FULLD(drv, 0);
set_RFFC5071_MODE(drv, 1);
#if defined(PRALINE) || defined(HACKRF_ONE)
/* Enable GPO Lock output signal */
set_RFFC5071_LOCK(drv, 1);
#if defined(IS_H1_OR_PRALINE)
if (IS_H1_OR_PRALINE) {
set_RFFC5071_LOCK(drv, 1);
}
#endif
/* Enable reference oscillator standby */
@ -176,13 +177,19 @@ void rffc5071_lock_test(rffc5071_driver_t* const drv)
bool rffc5071_check_lock(rffc5071_driver_t* const drv)
{
#ifdef PRALINE
return gpio_read(drv->gpio_ld);
#else
set_RFFC5071_READSEL(drv, 0b0001);
rffc5071_regs_commit(drv);
return !!(rffc5071_reg_read(drv, RFFC5071_READBACK_REG) & 0x8000);
#if defined(IS_PRALINE)
if (IS_PRALINE) {
return gpio_read(drv->gpio_ld);
}
#endif
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
set_RFFC5071_READSEL(drv, 0b0001);
rffc5071_regs_commit(drv);
return !!(rffc5071_reg_read(drv, RFFC5071_READBACK_REG) & 0x8000);
}
#endif
return false;
}
static uint16_t rffc5071_spi_read(rffc5071_driver_t* const drv, uint8_t r)
@ -344,9 +351,19 @@ void rffc5071_set_gpo(rffc5071_driver_t* const drv, uint8_t gpo)
rffc5071_regs_commit(drv);
}
#ifdef PRALINE
#if defined(IS_PRALINE)
bool rffc5071_poll_ld(rffc5071_driver_t* const drv, uint8_t* prelock_state)
{
// This is only supported on Praline hardware.
//
// For all other boards we'll just return true to avoid a situation where a
// a caller is waiting for a lock signal that will never be detected.
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
return true;
}
#endif
// The RFFC5072 can be configured to output PLL lock status on
// GPO4. The lock detect signal is produced by a window detector
// on the VCO tuning voltage. It goes high to show PLL lock when

View file

@ -26,6 +26,7 @@
#include <stdint.h>
#include "gpio.h"
#include "platform_detect.h"
#include "spi_bus.h"
/* 31 registers, each containing 16 bits of data. */
@ -34,7 +35,7 @@
typedef struct {
spi_bus_t* const bus;
gpio_t gpio_reset;
#ifdef PRALINE
#if defined(IS_PRALINE)
gpio_t gpio_ld;
#endif
uint16_t regs[RFFC5071_NUM_REGS];
@ -66,7 +67,7 @@ extern void rffc5071_enable(rffc5071_driver_t* const drv);
extern void rffc5071_disable(rffc5071_driver_t* const drv);
extern void rffc5071_set_gpo(rffc5071_driver_t* const drv, uint8_t);
#ifdef PRALINE
#if defined(IS_PRALINE)
extern bool rffc5071_poll_ld(rffc5071_driver_t* const drv, uint8_t* prelock_state);
#endif
extern bool rffc5071_check_lock(rffc5071_driver_t* const drv);

View file

@ -24,6 +24,8 @@
#include <stdbool.h>
#include <stdint.h>
#include "platform_detect.h"
#define NUM_LOCK_ATTEMPTS 3
enum {
@ -37,23 +39,22 @@ typedef uint8_t test_result_t;
typedef struct {
uint16_t mixer_id;
#ifndef RAD1O
#if defined(IS_NOT_RAD1O)
bool mixer_locks[NUM_LOCK_ATTEMPTS];
#endif
#ifdef PRALINE
#if defined(IS_PRALINE)
uint16_t max2831_mux_rssi_1;
uint16_t max2831_mux_temp;
uint16_t max2831_mux_rssi_2;
bool max2831_mux_test_ok;
#else
#endif
uint16_t max283x_readback_bad_value;
uint16_t max283x_readback_expected_value;
uint8_t max283x_readback_register_count;
uint8_t max283x_readback_total_registers;
#endif
uint8_t si5351_rev_id;
bool si5351_readback_ok;
#ifdef PRALINE
#if defined(IS_PRALINE)
test_result_t fpga_image_load;
test_result_t fpga_spi;
test_result_t sgpio_rx;

View file

@ -31,7 +31,7 @@
#include "platform_detect.h"
#include "platform_scu.h"
#include "sgpio.h"
#if !defined(PRALINE)
#ifdef IS_NOT_PRALINE
#include "hackrf_core.h"
#endif
@ -57,24 +57,29 @@ void sgpio_configure_pin_functions(sgpio_config_t* const config)
scu_pinmux(scu->PINMUX_SGPIO14, scu->PINMUX_SGPIO14_PINCFG); /* GPIO5[13] */
scu_pinmux(scu->PINMUX_SGPIO15, scu->PINMUX_SGPIO15_PINCFG); /* GPIO5[14] */
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
#if defined(HACKRF_ONE)
#if defined(IS_H1_R9)
if (IS_H1_R9) {
scu_pinmux(
scu->H1R9_TRIGGER_EN,
SCU_GPIO_FAST | SCU_CONF_FUNCTION4); /* GPIO5[5] */
}
#endif
} else {
#if defined(IS_NOT_H1_R9)
if (IS_NOT_H1_R9) {
scu_pinmux(
scu->TRIGGER_EN,
SCU_GPIO_FAST | SCU_CONF_FUNCTION4); /* GPIO5[12] */
}
#endif
sgpio_cpld_set_mixer_invert(config, 0);
gpio_output(config->gpio_q_invert);
#ifndef PRALINE
trigger_enable(false);
gpio_output(config->gpio_trigger_enable);
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
trigger_enable(false);
gpio_output(config->gpio_trigger_enable);
}
#endif
}
@ -157,11 +162,11 @@ void sgpio_configure(sgpio_config_t* const config, const sgpio_direction_t direc
SGPIO_OUT_MUX_CFG_P_OE_CFG(0) // gpio_oe (state set by GPIO_OEREG)
| SGPIO_OUT_MUX_CFG_P_OUT_CFG(0) // dout_doutm1 (1-bit mode)
;
SGPIO_OUT_MUX_CFG(10) = // GPIO10: Output: disable
SGPIO_OUT_MUX_CFG(10) = // GPIO10: Output: disable
SGPIO_OUT_MUX_CFG_P_OE_CFG(0) // gpio_oe (state set by GPIO_OEREG)
| SGPIO_OUT_MUX_CFG_P_OUT_CFG(4) // gpio_out (level set by GPIO_OUTREG)
;
SGPIO_OUT_MUX_CFG(11) = // GPIO11: Output: direction
SGPIO_OUT_MUX_CFG(11) = // GPIO11: Output: direction
SGPIO_OUT_MUX_CFG_P_OE_CFG(0) // gpio_oe (state set by GPIO_OEREG)
| SGPIO_OUT_MUX_CFG_P_OUT_CFG(4) // gpio_out (level set by GPIO_OUTREG)
;

View file

@ -26,6 +26,7 @@
#include <stdint.h>
#include "gpio.h"
#include "platform_detect.h"
typedef enum {
SGPIO_DIRECTION_RX,
@ -34,7 +35,7 @@ typedef enum {
typedef struct {
gpio_t gpio_q_invert;
#ifndef PRALINE
#if defined(IS_NOT_PRALINE)
gpio_t gpio_trigger_enable;
#endif
bool slice_mode_multislice;

View file

@ -23,16 +23,13 @@
#include <stdbool.h>
#include <stddef.h>
#if defined(HACKRF_ONE)
#include <libopencm3/lpc43xx/scu.h>
#endif
#include "clkin.h"
#include "delay.h"
#include "platform_detect.h"
#include "selftest.h"
#include "si5351c.h"
#if defined(HACKRF_ONE)
#if defined(IS_HACKRF_ONE)
#include <libopencm3/lpc43xx/scu.h>
#include "gpio.h"
#include "platform_gpio.h"
#include "platform_scu.h"
@ -269,7 +266,8 @@ void si5351c_configure_clock_control(si5351c_driver_t* const drv)
SI5351C_CLK_POWERDOWN |
SI5351C_CLK_INT_MODE /* not connected, but: PLL B int mode */
};
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
#if defined(IS_H1_R9)
if (IS_H1_R9) {
data[1] = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_6MA);
@ -281,34 +279,38 @@ void si5351c_configure_clock_control(si5351c_driver_t* const drv)
data[5] = SI5351C_CLK_POWERDOWN;
data[6] = SI5351C_CLK_POWERDOWN;
}
#ifdef PRALINE
/* CLK0: AFE_CLK */
data[1] = SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA);
/* CLK1: SCT_CLK and FPGA_CLK */
data[2] = SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA);
/* CLK3: CLKOUT */
clkout_ctrl = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_B) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA);
/* CLK4: XCVR_CLK */
data[5] = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_B) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA) | SI5351C_CLK_INV;
data[6] = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_B) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA);
if ((detected_revision() & ~BOARD_REV_GSG) < BOARD_REV_PRALINE_R1_1) {
/* CLK2: FPGA_CLK (not shared with SCT_CLK on older boards) */
data[3] = SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
#endif
#if defined(IS_PRALINE)
if (IS_PRALINE) {
/* CLK0: AFE_CLK */
data[1] = SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA);
/* CLK1: SCT_CLK and FPGA_CLK */
data[2] = SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA);
} else {
/* CLK2: MCU_CLK */
data[3] = SI5351C_CLK_POWERDOWN;
/* CLK3: CLKOUT */
clkout_ctrl = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_B) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA);
/* CLK4: XCVR_CLK */
data[5] = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_B) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA) | SI5351C_CLK_INV;
data[6] = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_PLL_B) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA);
if ((detected_revision() & ~BOARD_REV_GSG) < BOARD_REV_PRALINE_R1_1) {
/* CLK2: FPGA_CLK (not shared with SCT_CLK on older boards) */
data[3] = SI5351C_CLK_FRAC_MODE |
SI5351C_CLK_PLL_SRC(SI5351C_PLL_A) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA);
} else {
/* CLK2: MCU_CLK */
data[3] = SI5351C_CLK_POWERDOWN;
}
}
#endif
si5351c_write(drv, data, sizeof(data));
@ -325,31 +327,41 @@ void si5351c_enable_clock_outputs(si5351c_driver_t* const drv)
/* 7: Clock to CPU is deactivated as it is not used and creates noise */
/* 3: External clock output is deactivated by default */
#ifndef PRALINE
uint8_t value = SI5351C_CLK_ENABLE(0) | SI5351C_CLK_ENABLE(1) |
SI5351C_CLK_ENABLE(2) | SI5351C_CLK_ENABLE(4) | SI5351C_CLK_ENABLE(5) |
SI5351C_CLK_DISABLE(6) | SI5351C_CLK_DISABLE(7);
#else
uint8_t value = SI5351C_CLK_ENABLE(0) | SI5351C_CLK_ENABLE(1) |
SI5351C_CLK_ENABLE(4) | SI5351C_CLK_ENABLE(5) | SI5351C_CLK_DISABLE(6) |
SI5351C_CLK_DISABLE(7);
if ((detected_revision() & ~BOARD_REV_GSG) < BOARD_REV_PRALINE_R1_1) {
/* CLK2: FPGA_CLK (not shared with SCT_CLK on older boards) */
value |= SI5351C_CLK_ENABLE(2);
} else {
value |= SI5351C_CLK_DISABLE(2);
uint8_t clkout = 3;
uint8_t value = 0;
#if defined(IS_PRALINE)
if (IS_PRALINE) {
value = SI5351C_CLK_ENABLE(0) | SI5351C_CLK_ENABLE(1) |
SI5351C_CLK_ENABLE(4) | SI5351C_CLK_ENABLE(5) |
SI5351C_CLK_DISABLE(6) | SI5351C_CLK_DISABLE(7);
if ((detected_revision() & ~BOARD_REV_GSG) < BOARD_REV_PRALINE_R1_1) {
/* CLK2: FPGA_CLK (not shared with SCT_CLK on older boards) */
value |= SI5351C_CLK_ENABLE(2);
} else {
value |= SI5351C_CLK_DISABLE(2);
}
}
#endif
uint8_t clkout = 3;
/* HackRF One r9 has only three clock generator outputs. */
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
clkout = 2;
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
value = SI5351C_CLK_ENABLE(0) | SI5351C_CLK_ENABLE(1) |
SI5351C_CLK_DISABLE(3) | SI5351C_CLK_DISABLE(4) |
SI5351C_CLK_DISABLE(5) | SI5351C_CLK_DISABLE(6) |
SI5351C_CLK_ENABLE(2) | SI5351C_CLK_ENABLE(4) |
SI5351C_CLK_ENABLE(5) | SI5351C_CLK_DISABLE(6) |
SI5351C_CLK_DISABLE(7);
/* HackRF One r9 has only three clock generator outputs. */
#if defined(IS_H1_R9)
if (IS_H1_R9) {
clkout = 2;
value = SI5351C_CLK_ENABLE(0) | SI5351C_CLK_ENABLE(1) |
SI5351C_CLK_DISABLE(3) | SI5351C_CLK_DISABLE(4) |
SI5351C_CLK_DISABLE(5) | SI5351C_CLK_DISABLE(6) |
SI5351C_CLK_DISABLE(7);
}
#endif
}
#endif
value |= (clkout_enabled) ? SI5351C_CLK_ENABLE(clkout) :
SI5351C_CLK_DISABLE(clkout);
@ -357,8 +369,8 @@ void si5351c_enable_clock_outputs(si5351c_driver_t* const drv)
si5351c_write(drv, data, sizeof(data));
outputs_disabled = value;
#if defined(HACKRF_ONE)
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
#if defined(IS_H1_R9)
if (IS_H1_R9) {
const platform_gpio_t* gpio = platform_gpio();
if (clkout_enabled) {
gpio_set(gpio->h1r9_clkout_en);
@ -396,8 +408,8 @@ void si5351c_set_clock_source(si5351c_driver_t* const drv, const enum pll_source
return;
}
si5351c_disable_all_outputs(drv);
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
#if defined(HACKRF_ONE)
#if defined(IS_H1_R9)
if (IS_H1_R9) {
/*
* HackRF One r9 always uses PLL A on the XTAL input
* but externally switches that input to CLKIN.
@ -408,10 +420,13 @@ void si5351c_set_clock_source(si5351c_driver_t* const drv, const enum pll_source
} else {
gpio_clear(platform_gpio()->h1r9_clkin_en);
}
}
#endif
} else {
#if defined(IS_NOT_H1_R9)
if (IS_NOT_H1_R9) {
si5351c_configure_pll_sources(drv, source);
}
#endif
si5351c_configure_pll_multisynth(drv, source);
active_clock_source = source;
si5351c_reset_pll(drv, SI5351C_PLL_BOTH);
@ -466,8 +481,8 @@ void si5351c_init(si5351c_driver_t* const drv)
selftest.report.pass = false;
}
#if defined(HACKRF_ONE)
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
#if defined(IS_H1_R9)
if (IS_H1_R9) {
const platform_gpio_t* gpio = platform_gpio();
const platform_scu_t* scu = platform_scu();
@ -487,7 +502,6 @@ void si5351c_init(si5351c_driver_t* const drv)
gpio_output(gpio->h1r9_mcu_clk_en);
}
#endif
(void) drv;
}
/*

View file

@ -21,7 +21,9 @@
#pragma once
#ifdef PRALINE
#include "platform_detect.h"
#if defined(IS_PRALINE)
#include "fpga.h"
typedef struct {

View file

@ -27,52 +27,77 @@
#include "hackrf_ui.h"
#include "max283x.h"
#include "mixer.h"
#include "platform_detect.h"
#include "sgpio.h"
#include "transceiver_mode.h"
#if defined(PRALINE) || defined(HACKRF_ONE)
#if defined(IS_EXPANSION_COMPATIBLE)
#include "operacake.h"
#endif
#ifdef PRALINE
#if defined(IS_PRALINE)
#include "fpga.h"
#endif
#ifndef PRALINE
static uint64_t MIN_LP_FREQ_MHZ;
static uint64_t MAX_LP_FREQ_MHZ;
#define MIN_LP_FREQ_MHZ (0)
#define MAX_LP_FREQ_MHZ (2170ULL)
#define ABS_MIN_BYPASS_FREQ_MHZ (2000ULL)
#define MIN_BYPASS_FREQ_MHZ (MAX_LP_FREQ_MHZ)
#define MAX_BYPASS_FREQ_MHZ (2740ULL)
#define ABS_MAX_BYPASS_FREQ_MHZ (3000ULL)
#define MIN_HP_FREQ_MHZ (MAX_BYPASS_FREQ_MHZ)
#define MID1_HP_FREQ_MHZ (3600ULL)
#define MID2_HP_FREQ_MHZ (5100ULL)
#define MAX_HP_FREQ_MHZ (7250ULL)
#define MIN_LO_FREQ_HZ (84375000ULL)
#define MAX_LO_FREQ_HZ (5400000000ULL)
#else
#define MIN_LP_FREQ_MHZ (0)
#define MAX_LP_FREQ_MHZ (2320ULL)
#define ABS_MIN_BYPASS_FREQ_MHZ (2000ULL)
#define MIN_BYPASS_FREQ_MHZ (MAX_LP_FREQ_MHZ)
#define MAX_BYPASS_FREQ_MHZ (2580ULL)
#define ABS_MAX_BYPASS_FREQ_MHZ (3000ULL)
#define MIN_HP_FREQ_MHZ (MAX_BYPASS_FREQ_MHZ)
#define MAX_HP_FREQ_MHZ (7250ULL)
#define MIN_LO_FREQ_HZ (84375000ULL)
#define MAX_LO_FREQ_HZ (5400000000ULL)
static uint64_t ABS_MIN_BYPASS_FREQ_MHZ;
static uint64_t MIN_BYPASS_FREQ_MHZ;
static uint64_t MAX_BYPASS_FREQ_MHZ;
static uint64_t ABS_MAX_BYPASS_FREQ_MHZ;
static uint64_t MIN_HP_FREQ_MHZ;
#if defined(IS_NOT_PRALINE)
static uint64_t MID1_HP_FREQ_MHZ;
static uint64_t MID2_HP_FREQ_MHZ;
#endif
static uint64_t MAX_HP_FREQ_MHZ;
#ifndef PRALINE
static uint64_t MIN_LO_FREQ_HZ;
static uint64_t MAX_LO_FREQ_HZ;
void tuning_setup(void)
{
/* clang-format off */
#if defined(IS_PRALINE)
if (IS_PRALINE) {
MIN_LP_FREQ_MHZ = 0;
MAX_LP_FREQ_MHZ = 2320ULL;
ABS_MIN_BYPASS_FREQ_MHZ = 2000ULL;
MIN_BYPASS_FREQ_MHZ = MAX_LP_FREQ_MHZ;
MAX_BYPASS_FREQ_MHZ = 2580ULL;
ABS_MAX_BYPASS_FREQ_MHZ = 3000ULL;
MIN_HP_FREQ_MHZ = MAX_BYPASS_FREQ_MHZ;
MAX_HP_FREQ_MHZ = 7250ULL;
MIN_LO_FREQ_HZ = 84375000ULL;
MAX_LO_FREQ_HZ = 5400000000ULL;
}
#endif
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
MIN_LP_FREQ_MHZ = 0;
MAX_LP_FREQ_MHZ = 2170ULL;
ABS_MIN_BYPASS_FREQ_MHZ = 2000ULL;
MIN_BYPASS_FREQ_MHZ = MAX_LP_FREQ_MHZ;
MAX_BYPASS_FREQ_MHZ = 2740ULL;
ABS_MAX_BYPASS_FREQ_MHZ = 3000ULL;
MIN_HP_FREQ_MHZ = MAX_BYPASS_FREQ_MHZ;
MID1_HP_FREQ_MHZ = 3600ULL;
MID2_HP_FREQ_MHZ = 5100ULL;
MAX_HP_FREQ_MHZ = 7250ULL;
MIN_LO_FREQ_HZ = 84375000ULL;
MAX_LO_FREQ_HZ = 5400000000ULL;
}
#endif
/* clang-format on */
}
#if defined(IS_NOT_PRALINE)
static uint32_t max2837_freq_nominal_hz = 2560000000;
/*
@ -94,12 +119,17 @@ bool set_freq(const uint64_t freq, const transceiver_mode_t opmode)
max283x_set_mode(&max283x, MAX283x_MODE_STANDBY);
if (freq_mhz < MAX_LP_FREQ_MHZ) {
rf_path_set_filter(&rf_path, RF_PATH_FILTER_LOW_PASS, opmode);
#ifdef RAD1O
max2837_freq_nominal_hz = 2300 * FREQ_ONE_MHZ;
#else
/* IF is graduated from 2650 MHz to 2340 MHz */
max2837_freq_nominal_hz = (2650 * FREQ_ONE_MHZ) - (freq / 7);
#endif
#if defined(IS_RAD1O)
if (IS_RAD1O) {
max2837_freq_nominal_hz = 2300 * FREQ_ONE_MHZ;
}
#endif
#if defined(IS_NOT_RAD1O)
if (IS_NOT_RAD1O) {
/* IF is graduated from 2650 MHz to 2340 MHz */
max2837_freq_nominal_hz = (2650 * FREQ_ONE_MHZ) - (freq / 7);
}
#endif
mixer_freq_hz = max2837_freq_nominal_hz + freq;
/* Set Freq and read real freq */
real_mixer_freq_hz = mixer_set_frequency(&mixer, mixer_freq_hz);
@ -140,15 +170,17 @@ bool set_freq(const uint64_t freq, const transceiver_mode_t opmode)
if (opmode != TRANSCEIVER_MODE_RX_SWEEP) {
hackrf_ui()->set_frequency(freq);
}
#ifdef HACKRF_ONE
operacake_set_range(freq_mhz);
#endif
#if defined(IS_EXPANSION_COMPATIBLE)
if (IS_EXPANSION_COMPATIBLE) {
operacake_set_range(freq_mhz);
}
#endif
}
return success;
}
#endif
#else
#if defined(IS_PRALINE)
bool tuning_set_frequency(
const tune_config_t* cfg,
const uint64_t freq,

View file

@ -26,14 +26,17 @@
#include <stdbool.h>
#include <stdint.h>
#include "platform_detect.h"
#include "rf_path.h"
#include "transceiver_mode.h"
#if defined(PRALINE)
#if defined(IS_PRALINE)
#include "tune_config.h"
#endif
#define FREQ_ONE_MHZ (1000ULL * 1000)
void tuning_setup(void);
bool set_freq(const uint64_t freq, const transceiver_mode_t opmode);
bool set_freq_explicit(
const uint64_t if_freq_hz,
@ -41,7 +44,7 @@ bool set_freq_explicit(
const rf_path_filter_t path,
const transceiver_mode_t opmode);
#ifdef PRALINE
#if defined(IS_PRALINE)
bool tuning_set_frequency(
const tune_config_t* cfg,
const uint64_t freq,

View file

@ -27,10 +27,11 @@
* programming the flash.
*/
#include "w25q80bv.h"
#include <stddef.h>
#include <stdint.h>
#include <stddef.h>
#include "platform_detect.h"
#include "w25q80bv.h"
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
@ -59,13 +60,13 @@ void w25q80bv_setup(w25q80bv_driver_t* const drv)
uint8_t device_id;
drv->page_len = 256U;
#ifdef PRALINE
drv->num_pages = 16384U;
drv->num_bytes = 4194304U;
#else
drv->num_pages = 4096U;
drv->num_bytes = 1048576U;
#endif
if (detected_platform() == BOARD_ID_PRALINE) {
drv->num_pages = 16384U;
drv->num_bytes = 4194304U;
} else {
drv->num_pages = 4096U;
drv->num_bytes = 1048576U;
}
drv->target_init(drv);

View file

@ -74,7 +74,7 @@ if(NOT DEFINED BOARD)
set(BOARD HACKRF_ONE)
endif()
if(BOARD STREQUAL "HACKRF_ONE" OR BOARD STREQUAL "PRALINE")
if(BOARD STREQUAL "HACKRF_ONE" OR BOARD STREQUAL "PRALINE" OR BOARD STREQUAL "UNIVERSAL")
set(MCU_PARTNO LPC4320)
else()
set(MCU_PARTNO LPC4330)
@ -195,7 +195,8 @@ macro(DeclareTargets)
${PATH_HACKRF_FIRMWARE_COMMON}/m0_state.c
${PATH_HACKRF_FIRMWARE_COMMON}/adc.c
${PATH_HACKRF_FIRMWARE_COMMON}/da7219.c
)
${PATH_HACKRF_FIRMWARE_COMMON}/max283x.c
)
if(BOARD STREQUAL "RAD1O")
SET(SRC_M4
@ -216,14 +217,26 @@ macro(DeclareTargets)
${SRC_M4}
${PATH_HACKRF_FIRMWARE_COMMON}/fpga.c
${PATH_HACKRF_FIRMWARE_COMMON}/ice40_spi.c
${PATH_HACKRF_FIRMWARE_COMMON}/max283x.c
${PATH_HACKRF_FIRMWARE_COMMON}/max2831.c
${PATH_HACKRF_FIRMWARE_COMMON}/max2831_target.c
)
else()
SET(SRC_M4
${SRC_M4}
${PATH_HACKRF_FIRMWARE_COMMON}/max283x.c
${PATH_HACKRF_FIRMWARE_COMMON}/max2837.c
${PATH_HACKRF_FIRMWARE_COMMON}/max2837_target.c
${PATH_HACKRF_FIRMWARE_COMMON}/max2839.c
${PATH_HACKRF_FIRMWARE_COMMON}/max2839_target.c
)
endif()
if(BOARD STREQUAL "UNIVERSAL")
SET(SRC_M4
${SRC_M4}
${PATH_HACKRF_FIRMWARE_COMMON}/fpga.c
${PATH_HACKRF_FIRMWARE_COMMON}/ice40_spi.c
${PATH_HACKRF_FIRMWARE_COMMON}/max2831.c
${PATH_HACKRF_FIRMWARE_COMMON}/max2831_target.c
${PATH_HACKRF_FIRMWARE_COMMON}/max2837.c
${PATH_HACKRF_FIRMWARE_COMMON}/max2837_target.c
${PATH_HACKRF_FIRMWARE_COMMON}/max2839.c

View file

@ -35,7 +35,7 @@ add_custom_command(
OUTPUT ${PATH_PRALINE_FPGA_OBJ}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E copy ${PATH_PRALINE_FPGA_BIN} "fpga.bin"
COMMAND ${CMAKE_OBJCOPY}
COMMAND ${CMAKE_OBJCOPY}
-I binary
-O elf32-littlearm
-B arm
@ -75,6 +75,26 @@ set(SRC_M4
set(SRC_M0 sgpio_m0.s)
if(BOARD STREQUAL "UNIVERSAL")
SET(SRC_M4
${SRC_M4}
usb_api_cpld.c
"${PATH_HACKRF_FIRMWARE_COMMON}/cpld_xc2c.c"
"${PATH_HACKRF_CPLD_DATA_C}"
"${PATH_HACKRF_FIRMWARE_COMMON}/xapp058/lenval.c"
"${PATH_HACKRF_FIRMWARE_COMMON}/xapp058/micro.c"
"${PATH_HACKRF_FIRMWARE_COMMON}/xapp058/ports.c"
"${PATH_HACKRF_FIRMWARE_COMMON}/lz4_blk.c"
"${PATH_HACKRF_FIRMWARE_COMMON}/fpga_image.c"
"${PATH_HACKRF_FIRMWARE_COMMON}/fpga_selftest.c"
usb_api_praline.c
)
SET(OBJ_M4
${PATH_PRALINE_FPGA_OBJ}
)
endif()
if(BOARD STREQUAL "PRALINE")
SET(SRC_M4
${SRC_M4}
@ -98,7 +118,7 @@ else()
)
endif()
if(BOARD STREQUAL "HACKRF_ONE" OR BOARD STREQUAL "PRALINE")
if(BOARD STREQUAL "PRALINE" OR BOARD STREQUAL "HACKRF_ONE" OR BOARD STREQUAL "UNIVERSAL")
SET(SRC_M4
${SRC_M4}
"${PATH_HACKRF_FIRMWARE_COMMON}/portapack.c"

View file

@ -40,28 +40,28 @@
#include <rom_iap.h>
#include <selftest.h>
#include <transceiver_mode.h>
#include <tuning.h>
#include <usb.h>
#include <usb_queue.h>
#include <usb_request.h>
#include <usb_standard_request.h>
#include <usb_type.h>
#if defined(HACKRF_ONE)
#include <mixer.h>
#endif
#if defined(PRALINE) || defined(HACKRF_ONE)
#if defined(IS_EXPANSION_COMPATIBLE)
#include <portapack.h>
#endif
#if defined(PRALINE) || defined(HACKRF_ONE) || defined(JAWBREAKER)
#if defined(IS_NOT_RAD1O)
#include <mixer.h>
#include <rffc5071.h>
#endif
#if defined(PRALINE)
#if defined(IS_PRALINE)
#include <fpga.h>
#if !(defined(DFU_MODE) || defined(RAM_MODE))
#include <lz4_buf.h>
#include <spi_bus.h>
#include <w25q80bv.h>
#endif
#else
#endif
#if defined(IS_NOT_PRALINE)
#include <cpld_jtag.h>
#include <cpld_xc2c.h>
#endif
@ -79,9 +79,10 @@
#include "usb_descriptor.h"
#include "usb_device.h"
#include "usb_endpoint.h"
#if defined(PRALINE)
#if defined(IS_PRALINE)
#include "usb_api_praline.h"
#else
#endif
#if defined(IS_NOT_PRALINE)
#include "usb_api_cpld.h"
#endif
@ -99,12 +100,12 @@ static usb_request_handler_fn vendor_request_handler[] = {
usb_vendor_request_read_si5351c,
usb_vendor_request_set_sample_rate_frac,
usb_vendor_request_set_baseband_filter_bandwidth,
#ifdef RAD1O
NULL, // write_rffc5071 not used
NULL, // read_rffc5071 not used
#else
#if defined(IS_NOT_RAD1O)
usb_vendor_request_write_rffc5071,
usb_vendor_request_read_rffc5071,
#else
NULL, // write_rffc5071 not used
NULL, // read_rffc5071 not used
#endif
usb_vendor_request_erase_spiflash,
usb_vendor_request_write_spiflash,
@ -119,7 +120,7 @@ static usb_request_handler_fn vendor_request_handler[] = {
usb_vendor_request_set_vga_gain,
usb_vendor_request_set_txvga_gain,
NULL, // was set_if_freq
#if (defined HACKRF_ONE || defined PRALINE)
#if defined(IS_HACKRF_ONE) || defined(IS_PRALINE)
usb_vendor_request_set_antenna_enable,
#else
NULL,
@ -136,7 +137,7 @@ static usb_request_handler_fn vendor_request_handler[] = {
usb_vendor_request_spiflash_status,
usb_vendor_request_spiflash_clear_status,
usb_vendor_request_operacake_gpio_test,
#ifdef HACKRF_ONE
#if defined(IS_HACKRF_ONE)
usb_vendor_request_cpld_checksum,
#else
NULL,
@ -153,7 +154,7 @@ static usb_request_handler_fn vendor_request_handler[] = {
usb_vendor_request_read_supported_platform,
usb_vendor_request_set_leds,
usb_vendor_request_user_config_set_bias_t_opts,
#ifdef PRALINE
#if defined(IS_PRALINE)
usb_vendor_request_write_fpga_reg,
usb_vendor_request_read_fpga_reg,
usb_vendor_request_p2_ctrl,
@ -249,7 +250,7 @@ void usb_set_descriptor_by_serial_number(void)
}
}
#ifndef PRALINE
#if defined(IS_NOT_PRALINE)
static bool cpld_jtag_sram_load(jtag_t* const jtag)
{
cpld_jtag_take(jtag);
@ -277,7 +278,7 @@ static void m0_rom_to_ram(void)
memcpy(dest, (uint32_t*) (base + src), len);
}
#if defined(PRALINE) && !(defined(DFU_MODE) || defined(RAM_MODE))
#if defined(IS_PRALINE) && !(defined(DFU_MODE) || defined(RAM_MODE))
extern uint32_t _binary_fpga_bin_start;
void fpga_loader_setup(void)
@ -308,45 +309,62 @@ int main(void)
// This will be cleared if any self-test check fails.
selftest.report.pass = true;
// Detect hardware platform before we do anything else.
detect_hardware_platform();
board_id_t board_id = detected_platform();
pin_shutdown();
#ifndef RAD1O
clock_gen_shutdown();
#endif
if (board_id != BOARD_ID_RAD1O) {
clock_gen_shutdown();
}
delay_us_at_mhz(10000, 96);
pin_setup();
#ifndef PRALINE
enable_1v8_power();
#ifndef RAD1O
/*
* On rad1o, the clock generator power supply comes from the RF supply
* which is enabled later. On H1 and Jawbreaker, the clock generator is
* on the main 3V3 supply.
*/
clock_gen_init();
#endif
#else
enable_3v3aux_power();
#if defined(IS_PRALINE)
if (IS_PRALINE) {
enable_3v3aux_power();
#if !defined(DFU_MODE) && !defined(RAM_MODE)
enable_1v2_power();
enable_rf_power();
/*
* On Praline, the clock generator power supply comes from 3V3FPGA
* which is enabled when 1V2FPGA is turned on.
*/
clock_gen_init();
enable_1v2_power();
enable_rf_power();
/*
* On Praline, the clock generator power supply comes from 3V3FPGA
* which is enabled when 1V2FPGA is turned on.
*/
clock_gen_init();
#endif
}
#endif
#ifdef HACKRF_ONE
// Set up mixer before enabling RF power, because its
// GPO is used to control the antenna bias tee.
mixer_setup(&mixer);
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
enable_1v8_power();
#if defined(IS_NOT_RAD1O)
if (IS_NOT_RAD1O) {
/*
* On rad1o, the clock generator power supply comes from the RF supply
* which is enabled later. On H1 and Jawbreaker, the clock generator is
* on the main 3V3 supply.
*/
clock_gen_init();
}
#endif
}
#endif
#if (defined HACKRF_ONE || defined RAD1O)
enable_rf_power();
tuning_setup();
#if defined(IS_HACKRF_ONE)
if (IS_HACKRF_ONE) {
// Set up mixer before enabling RF power, because its
// GPO is used to control the antenna bias tee.
mixer_setup(&mixer, RFFC5071_VARIANT);
}
#endif
#ifdef RAD1O
clock_gen_init();
#if defined(IS_H1_OR_RAD1O)
if (IS_H1_OR_RAD1O) {
enable_rf_power();
}
#endif
#if defined(IS_RAD1O)
if (IS_RAD1O) {
clock_gen_init();
}
#endif
cpu_clock_init();
@ -354,25 +372,32 @@ int main(void)
ipc_halt_m0();
ipc_start_m0((uint32_t) &__ram_m0_start__);
#ifndef PRALINE
if (!cpld_jtag_sram_load(&jtag_cpld)) {
halt_and_flash(6000000);
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
if (!cpld_jtag_sram_load(&jtag_cpld)) {
halt_and_flash(6000000);
}
}
#else
#endif
#if defined(IS_PRALINE)
if (IS_PRALINE) {
#if defined(DFU_MODE) || defined(RAM_MODE)
selftest.fpga_image_load = SKIPPED;
selftest.report.pass = false;
selftest.fpga_image_load = SKIPPED;
selftest.report.pass = false;
#else
fpga_image_load(&fpga_loader, 0);
fpga_image_load(&fpga_loader, 0);
#endif
delay_us_at_mhz(100, 204);
fpga_spi_selftest();
fpga_sgpio_selftest();
delay_us_at_mhz(100, 204);
fpga_spi_selftest();
fpga_sgpio_selftest();
}
#endif
radio_init(&radio);
#if (defined HACKRF_ONE || defined PRALINE)
portapack_init();
#if defined(IS_EXPANSION_COMPATIBLE)
if (IS_EXPANSION_COMPATIBLE) {
portapack_init();
}
#endif
#ifndef DFU_MODE
@ -382,6 +407,30 @@ int main(void)
usb_set_configuration_changed_cb(usb_configuration_changed);
usb_peripheral_reset();
#if defined(IS_HACKRF_ONE)
if (IS_HACKRF_ONE) {
memcpy(&usb_device,
&usb_device_hackrf_one,
sizeof(usb_device_hackrf_one));
}
#endif
#if defined(IS_JAWBREAKER)
if (IS_JAWBREAKER) {
memcpy(&usb_device,
&usb_device_jawbreaker,
sizeof(usb_device_jawbreaker));
}
#endif
#if defined(IS_RAD1O)
if (IS_RAD1O) {
memcpy(&usb_device, &usb_device_rad1o, sizeof(usb_device_rad1o));
}
#endif
#if defined(IS_PRALINE)
if (IS_PRALINE) {
memcpy(&usb_device, &usb_device_praline, sizeof(usb_device_praline));
}
#endif
usb_device_init(0, &usb_device);
usb_queue_init(&usb_endpoint_control_out_queue);
@ -400,12 +449,14 @@ int main(void)
rf_path_init(&rf_path);
#ifndef RAD1O
rffc5071_lock_test(&mixer);
#if !defined(RAD1O)
rffc5071_lock_test(&mixer.rffc5071);
#endif
#ifdef PRALINE
fpga_if_xcvr_selftest();
#if defined(IS_PRALINE)
if (IS_PRALINE) {
fpga_if_xcvr_selftest();
}
#endif
if (da7219_detect()) {
@ -452,11 +503,13 @@ int main(void)
case TRANSCEIVER_MODE_RX_SWEEP:
sweep_mode(request.seq);
break;
#ifndef PRALINE
case TRANSCEIVER_MODE_CPLD_UPDATE:
cpld_update();
break;
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
cpld_update();
}
#endif
break;
default:
break;
}

View file

@ -20,7 +20,6 @@
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "usb_api_board_info.h"
#include <string.h>
@ -34,7 +33,7 @@
#include <usb_queue.h>
#include <usb_request.h>
#include <usb_type.h>
#ifdef HACKRF_ONE
#if defined(IS_HACKRF_ONE)
#include <gpio.h>
#include <platform_gpio.h>
#endif
@ -131,18 +130,19 @@ usb_request_status_t usb_vendor_request_reset(
if (stage == USB_TRANSFER_STAGE_SETUP) {
pin_shutdown();
clock_gen_shutdown();
#ifdef HACKRF_ONE
/*
* Set boot pins as inputs so that the bootloader reads them
* correctly after the reset.
*/
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
#if defined(IS_H1_R9)
if (IS_H1_R9) {
/*
* Set boot pins as inputs so that the bootloader reads them
* correctly after the reset.
*/
const platform_gpio_t* gpio = platform_gpio();
gpio_input(gpio->h1r9_mcu_clk_en);
gpio_input(gpio->h1r9_clkout_en);
gpio_input(gpio->h1r9_rx);
}
#endif
wwdt_reset(100000);
usb_transfer_schedule_ack(endpoint->in);

View file

@ -30,6 +30,7 @@
#include <cpld_jtag.h>
#include <cpld_xc2c.h>
#include <hackrf_core.h>
#include <platform_detect.h>
#include <usb_queue.h>
#include <usb_request.h>
#include <usb_type.h>
@ -90,6 +91,15 @@ usb_request_status_t usb_vendor_request_cpld_checksum(
static uint32_t cpld_crc;
uint8_t length;
switch (detected_platform()) {
case BOARD_ID_HACKRF1_OG:
case BOARD_ID_HACKRF1_R9:
// supported
break;
default:
return USB_REQUEST_STATUS_STALL;
}
if (stage == USB_TRANSFER_STAGE_SETUP) {
cpld_jtag_take(&jtag_cpld);
const bool checksum_success = cpld_xc2c64a_jtag_checksum(

View file

@ -24,6 +24,7 @@
#include "usb_api_praline.h"
#include <hackrf_core.h>
#include <platform_detect.h>
#include <usb_queue.h>
#include <usb_request.h>
#include <usb_type.h>
@ -35,6 +36,10 @@ usb_request_status_t usb_vendor_request_p1_ctrl(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
if (detected_platform() != BOARD_ID_PRALINE) {
return USB_REQUEST_STATUS_STALL;
}
if (stage == USB_TRANSFER_STAGE_SETUP) {
p1_ctrl_set(endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in);
@ -46,6 +51,10 @@ usb_request_status_t usb_vendor_request_p2_ctrl(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
if (detected_platform() != BOARD_ID_PRALINE) {
return USB_REQUEST_STATUS_STALL;
}
if (stage == USB_TRANSFER_STAGE_SETUP) {
p2_ctrl_set(endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in);
@ -57,6 +66,10 @@ usb_request_status_t usb_vendor_request_clkin_ctrl(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
if (detected_platform() != BOARD_ID_PRALINE) {
return USB_REQUEST_STATUS_STALL;
}
if (stage == USB_TRANSFER_STAGE_SETUP) {
clkin_ctrl_set(endpoint->setup.value & 1);
usb_transfer_schedule_ack(endpoint->in);
@ -68,6 +81,10 @@ usb_request_status_t usb_vendor_request_set_narrowband_filter(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
if (detected_platform() != BOARD_ID_PRALINE) {
return USB_REQUEST_STATUS_STALL;
}
if (stage == USB_TRANSFER_STAGE_SETUP) {
narrowband_filter_set(endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in);
@ -86,6 +103,10 @@ usb_request_status_t usb_vendor_request_set_fpga_bitstream(
#else
extern struct fpga_loader_t fpga_loader;
if (detected_platform() != BOARD_ID_PRALINE) {
return USB_REQUEST_STATUS_STALL;
}
if (stage == USB_TRANSFER_STAGE_SETUP) {
if (!fpga_image_load(&fpga_loader, endpoint->setup.value)) {
return USB_REQUEST_STATUS_STALL;

View file

@ -21,7 +21,6 @@
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "usb_api_register.h"
#include <stdbool.h>
@ -30,17 +29,19 @@
#include <hackrf_core.h>
#include <max283x.h>
#include <platform_detect.h>
#include <radio.h>
#include <si5351c.h>
#include <usb_queue.h>
#include <usb_request.h>
#include <usb_type.h>
#if defined(PRALINE) || defined(HACKRF_ONE) || defined(JAWBREAKER)
#include <rffc5071.h>
#endif
#if defined(PRALINE)
#if defined(IS_PRALINE)
#include <fpga.h>
#endif
#if defined(IS_NOT_RAD1O)
#include <mixer.h>
#include <rffc5071.h>
#endif
usb_request_status_t usb_vendor_request_write_max283x(
usb_endpoint_t* const endpoint,
@ -136,51 +137,73 @@ usb_request_status_t usb_vendor_request_read_si5351c(
}
}
#ifndef RAD1O
usb_request_status_t usb_vendor_request_write_rffc5071(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
if (stage == USB_TRANSFER_STAGE_SETUP) {
if (endpoint->setup.index < RFFC5071_NUM_REGS) {
rffc5071_reg_write(
&mixer,
endpoint->setup.index,
endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK;
}
#if defined(IS_RAD1O)
if (IS_RAD1O) {
(void) endpoint;
(void) stage;
return USB_REQUEST_STATUS_STALL;
} else {
}
#endif
#if defined(IS_NOT_RAD1O)
if (IS_NOT_RAD1O) {
if (stage == USB_TRANSFER_STAGE_SETUP) {
if (endpoint->setup.index < RFFC5071_NUM_REGS) {
rffc5071_reg_write(
&mixer.rffc5071,
endpoint->setup.index,
endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK;
}
return USB_REQUEST_STATUS_STALL;
}
return USB_REQUEST_STATUS_OK;
}
#endif
}
usb_request_status_t usb_vendor_request_read_rffc5071(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
uint16_t value;
if (stage == USB_TRANSFER_STAGE_SETUP) {
if (endpoint->setup.index < RFFC5071_NUM_REGS) {
value = rffc5071_reg_read(&mixer, endpoint->setup.index);
endpoint->buffer[0] = value & 0xff;
endpoint->buffer[1] = value >> 8;
usb_transfer_schedule_block(
endpoint->in,
&endpoint->buffer,
2,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out);
return USB_REQUEST_STATUS_OK;
}
#if defined(IS_RAD1O)
if (IS_RAD1O) {
(void) endpoint;
(void) stage;
return USB_REQUEST_STATUS_STALL;
} else {
}
#endif
#if defined(IS_NOT_RAD1O)
if (IS_NOT_RAD1O) {
uint16_t value;
if (stage == USB_TRANSFER_STAGE_SETUP) {
if (endpoint->setup.index < RFFC5071_NUM_REGS) {
value = rffc5071_reg_read(
&mixer.rffc5071,
endpoint->setup.index);
endpoint->buffer[0] = value & 0xff;
endpoint->buffer[1] = value >> 8;
usb_transfer_schedule_block(
endpoint->in,
&endpoint->buffer,
2,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out);
return USB_REQUEST_STATUS_OK;
}
return USB_REQUEST_STATUS_STALL;
}
return USB_REQUEST_STATUS_OK;
}
}
#endif
}
usb_request_status_t usb_vendor_request_set_clkout_enable(
usb_endpoint_t* const endpoint,
@ -266,35 +289,49 @@ usb_request_status_t usb_vendor_request_user_config_set_bias_t_opts(
return USB_REQUEST_STATUS_OK;
}
#ifdef PRALINE
#if defined(IS_PRALINE)
usb_request_status_t usb_vendor_request_write_fpga_reg(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
if (stage == USB_TRANSFER_STAGE_SETUP) {
fpga_reg_write(&fpga, endpoint->setup.index, endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in);
#if defined(IS_PRALINE)
if (IS_PRALINE) {
if (stage == USB_TRANSFER_STAGE_SETUP) {
fpga_reg_write(
&fpga,
endpoint->setup.index,
endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in);
}
return USB_REQUEST_STATUS_OK;
}
return USB_REQUEST_STATUS_OK;
#endif
return USB_REQUEST_STATUS_STALL;
}
usb_request_status_t usb_vendor_request_read_fpga_reg(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
if (stage == USB_TRANSFER_STAGE_SETUP) {
const uint8_t value = fpga_reg_read(&fpga, endpoint->setup.index);
endpoint->buffer[0] = value;
usb_transfer_schedule_block(
endpoint->in,
&endpoint->buffer,
1,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out);
#if defined(IS_PRALINE)
if (IS_PRALINE) {
if (stage == USB_TRANSFER_STAGE_SETUP) {
const uint8_t value = fpga_reg_read(&fpga, endpoint->setup.index);
endpoint->buffer[0] = value;
usb_transfer_schedule_block(
endpoint->in,
&endpoint->buffer,
1,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out);
}
return USB_REQUEST_STATUS_OK;
}
return USB_REQUEST_STATUS_OK;
#endif
return USB_REQUEST_STATUS_STALL;
}
#endif

View file

@ -23,6 +23,8 @@
#pragma once
#include "platform_detect.h"
#include <usb_request.h>
#include <usb_type.h>
@ -56,7 +58,7 @@ usb_request_status_t usb_vendor_request_set_leds(
usb_request_status_t usb_vendor_request_user_config_set_bias_t_opts(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
#ifdef PRALINE
#if defined(IS_PRALINE)
usb_request_status_t usb_vendor_request_write_fpga_reg(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);

View file

@ -19,24 +19,23 @@
* Boston, MA 02110-1301, USA.
*/
#include "usb_api_selftest.h"
#include <stddef.h>
#include <stdint.h>
#if defined(PRALINE) || defined(HACKRF_ONE) || defined(JAWBREAKER)
#include <stdbool.h>
#endif
#include <libopencm3/lpc43xx/cgu.h>
#include <libopencm3/lpc43xx/creg.h>
#include <platform_detect.h>
#include <selftest.h>
#include <usb_queue.h>
#include <usb_request.h>
#include <usb_type.h>
#if !defined(PRALINE)
#include <platform_detect.h>
#endif
#include "usb_api_selftest.h"
#if defined(IS_NOT_RAD1O)
#include <stdbool.h>
#endif
static char* itoa(int val, int base)
{
@ -63,7 +62,7 @@ void append(char** dest, size_t* capacity, const char* str)
}
}
#ifdef PRALINE
#if defined(IS_PRALINE)
static const char* test_result_to_str(test_result_t result)
{
switch (result) {
@ -84,89 +83,112 @@ void generate_selftest_report(void)
{
char* s = &selftest.report.msg[0];
size_t c = sizeof(selftest.report.msg);
#ifdef RAD1O
append(&s, &c, "Mixer: MAX2871, ID: ");
append(&s, &c, itoa(selftest.mixer_id, 10));
append(&s, &c, "\n");
#else
append(&s, &c, "Mixer: RFFC5072, ID: ");
append(&s, &c, itoa(selftest.mixer_id >> 3, 10));
append(&s, &c, ", Rev: ");
append(&s, &c, itoa(selftest.mixer_id & 0x7, 10));
append(&s, &c, ", Locks: ");
bool lock;
for (int i = 0; i < NUM_LOCK_ATTEMPTS; i++) {
lock = selftest.mixer_locks[i];
append(&s, &c, itoa(lock, 2));
#if defined(IS_RAD1O)
if (IS_RAD1O) {
append(&s, &c, "Mixer: MAX2871, ID: ");
append(&s, &c, itoa(selftest.mixer_id, 10));
append(&s, &c, "\n");
}
if (lock) {
append(&s, &c, " (PASS)");
} else {
append(&s, &c, " (FAIL)");
}
append(&s, &c, "\n");
#endif
#if defined(IS_NOT_RAD1O)
if (IS_NOT_RAD1O) {
append(&s, &c, "Mixer: RFFC5072, ID: ");
append(&s, &c, itoa(selftest.mixer_id >> 3, 10));
append(&s, &c, ", Rev: ");
append(&s, &c, itoa(selftest.mixer_id & 0x7, 10));
append(&s, &c, ", Locks: ");
bool lock;
for (int i = 0; i < NUM_LOCK_ATTEMPTS; i++) {
lock = selftest.mixer_locks[i];
append(&s, &c, itoa(lock, 2));
}
if (lock) {
append(&s, &c, " (PASS)");
} else {
append(&s, &c, " (FAIL)");
}
append(&s, &c, "\n");
}
#endif
append(&s, &c, "Clock: Si5351");
append(&s, &c, ", Rev: ");
append(&s, &c, itoa(selftest.si5351_rev_id, 10));
append(&s, &c, ", readback: ");
append(&s, &c, selftest.si5351_readback_ok ? "OK" : "FAIL");
append(&s, &c, "\n");
#ifdef PRALINE
append(&s, &c, "Transceiver: MAX2831, RSSI mux test: ");
append(&s, &c, selftest.max2831_mux_test_ok ? "PASS" : "FAIL");
append(&s, &c, "\n");
#else
append(&s, &c, "Transceiver: ");
append(&s,
&c,
(detected_platform() == BOARD_ID_HACKRF1_R9 ? "MAX2839" : "MAX2837"));
append(&s, &c, ", readback success: ");
append(&s, &c, itoa(selftest.max283x_readback_register_count, 10));
append(&s, &c, "/");
append(&s, &c, itoa(selftest.max283x_readback_total_registers, 10));
if (selftest.max283x_readback_register_count <
selftest.max283x_readback_total_registers) {
append(&s, &c, ", bad value: 0x");
append(&s, &c, itoa(selftest.max283x_readback_bad_value, 10));
append(&s, &c, ", expected: 0x");
append(&s, &c, itoa(selftest.max283x_readback_expected_value, 10));
}
append(&s, &c, "\n");
#endif
#ifdef PRALINE
append(&s, &c, "FPGA configuration: ");
append(&s, &c, test_result_to_str(selftest.fpga_image_load));
append(&s, &c, "\n");
append(&s, &c, "FPGA SPI: ");
append(&s, &c, test_result_to_str(selftest.fpga_spi));
append(&s, &c, "\n");
append(&s, &c, "SGPIO RX test: ");
append(&s, &c, test_result_to_str(selftest.sgpio_rx));
append(&s, &c, "\n");
append(&s, &c, "Loopback test: ");
append(&s, &c, test_result_to_str(selftest.xcvr_loopback));
append(&s, &c, "\n");
// Dump transceiver loopback measurements.
for (int i = 0; i < 4; ++i) {
struct xcvr_measurements* m = &selftest.xcvr_measurements[i];
append(&s, &c, " ");
append(&s, &c, itoa(i, 10));
append(&s, &c, ":");
append(&s, &c, itoa(m->zcs_i, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->zcs_q, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->max_mag_i, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->max_mag_q, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->avg_mag_sq_i, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->avg_mag_sq_q, 10));
#if defined(IS_PRALINE)
if (IS_PRALINE) {
append(&s, &c, "Transceiver: MAX2831, RSSI mux test: ");
append(&s, &c, selftest.max2831_mux_test_ok ? "PASS" : "FAIL");
append(&s, &c, "\n");
}
#endif
#if defined(IS_NOT_PRALINE)
if (IS_NOT_PRALINE) {
append(&s, &c, "Transceiver: ");
#if defined(IS_H1_R9)
if (IS_H1_R9) {
append(&s, &c, "MAX2839");
}
#endif
#if defined(IS_NOT_H1_R9)
if (IS_NOT_H1_R9) {
append(&s, &c, "MAX2837");
}
#endif
append(&s, &c, ", readback success: ");
append(&s, &c, itoa(selftest.max283x_readback_register_count, 10));
append(&s, &c, "/");
append(&s, &c, itoa(selftest.max283x_readback_total_registers, 10));
if (selftest.max283x_readback_register_count <
selftest.max283x_readback_total_registers) {
append(&s, &c, ", bad value: 0x");
append(&s, &c, itoa(selftest.max283x_readback_bad_value, 10));
append(&s, &c, ", expected: 0x");
append(&s,
&c,
itoa(selftest.max283x_readback_expected_value, 10));
}
append(&s, &c, "\n");
}
#endif
#if defined(IS_PRALINE)
if (IS_PRALINE) {
append(&s, &c, "FPGA configuration: ");
append(&s, &c, test_result_to_str(selftest.fpga_image_load));
append(&s, &c, "\n");
append(&s, &c, "FPGA SPI: ");
append(&s, &c, test_result_to_str(selftest.fpga_spi));
append(&s, &c, "\n");
append(&s, &c, "SGPIO RX test: ");
append(&s, &c, test_result_to_str(selftest.sgpio_rx));
append(&s, &c, "\n");
append(&s, &c, "Loopback test: ");
append(&s, &c, test_result_to_str(selftest.xcvr_loopback));
append(&s, &c, "\n");
// Dump transceiver loopback measurements.
for (int i = 0; i < 4; ++i) {
struct xcvr_measurements* m = &selftest.xcvr_measurements[i];
append(&s, &c, " ");
append(&s, &c, itoa(i, 10));
append(&s, &c, ":");
append(&s, &c, itoa(m->zcs_i, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->zcs_q, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->max_mag_i, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->max_mag_q, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->avg_mag_sq_i, 10));
append(&s, &c, ",");
append(&s, &c, itoa(m->avg_mag_sq_q, 10));
append(&s, &c, "\n");
}
}
#endif
}
usb_request_status_t usb_vendor_request_read_selftest(

View file

@ -29,6 +29,7 @@
#include <hackrf_core.h>
#include <hackrf_ui.h>
#include <m0_state.h>
#include <platform_detect.h>
#include <radio.h>
#include <rf_path.h>
#include <streaming.h>
@ -46,11 +47,6 @@
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#define FREQ_GRANULARITY 1000000
#define MAX_RANGES 10
#ifndef PRALINE
#define THROWAWAY_BUFFERS 2
#else
#define THROWAWAY_BUFFERS 1
#endif
static uint64_t sweep_freq;
static uint16_t frequencies[MAX_RANGES * 2];
@ -59,6 +55,7 @@ static uint16_t num_ranges = 0;
static uint32_t dwell_blocks = 0;
static uint32_t step_width = 0;
static uint32_t offset = 0;
static uint32_t throwaway_buffers = 0;
static enum sweep_style style = LINEAR;
static bool freq_ui_dirty = false;
static bool img_reject_ui_dirty = false;
@ -91,6 +88,12 @@ usb_request_status_t usb_vendor_request_init_sweep(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
if (detected_platform() == BOARD_ID_PRALINE) {
throwaway_buffers = 1;
} else {
throwaway_buffers = 2;
}
uint32_t num_bytes;
int i;
if (stage == USB_TRANSFER_STAGE_SETUP) {
@ -144,7 +147,7 @@ void sweep_bulk_transfer_complete(void* user_data, unsigned int bytes_transferre
// For each buffer transferred, we need to bump the count to allow
// for the buffer(s) that are to be discarded.
m0_state.m4_count += (THROWAWAY_BUFFERS + 1) * 0x4000;
m0_state.m4_count += (throwaway_buffers + 1) * 0x4000;
}
void sweep_mode(uint32_t seq)
@ -200,7 +203,7 @@ void sweep_mode(uint32_t seq)
// Set M0 to switch back to RX after we have received our
// discard buffers.
m0_state.threshold += (0x4000 * THROWAWAY_BUFFERS);
m0_state.threshold += (0x4000 * throwaway_buffers);
m0_state.next_mode = M0_MODE_RX;
// Write metadata to buffer.
@ -225,7 +228,7 @@ void sweep_mode(uint32_t seq)
NULL);
// Use other buffer next time.
phase = (phase + 1) % THROWAWAY_BUFFERS;
phase = (phase + 1) % throwaway_buffers;
if (++blocks_queued == dwell_blocks) {
// Calculate next sweep frequency.

View file

@ -31,6 +31,7 @@
#include <hackrf_ui.h>
#include <m0_state.h>
#include <operacake_sctimer.h>
#include <platform_detect.h>
#include <radio.h>
#include <streaming.h>
#include <transceiver_mode.h>
@ -287,6 +288,16 @@ usb_request_status_t usb_vendor_request_set_antenna_enable(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{
switch (detected_platform()) {
case BOARD_ID_HACKRF1_OG:
case BOARD_ID_HACKRF1_R9:
case BOARD_ID_PRALINE:
// supported
break;
default:
return USB_REQUEST_STATUS_STALL;
}
if (stage == USB_TRANSFER_STAGE_SETUP) {
radio_reg_write(
&radio,

View file

@ -26,17 +26,9 @@
#include <usb_type.h>
#define USB_VENDOR_ID (0x1D50)
#include "platform_detect.h"
#if (defined HACKRF_ONE || defined PRALINE)
#define USB_PRODUCT_ID (0x6089)
#elif JAWBREAKER
#define USB_PRODUCT_ID (0x604B)
#elif RAD1O
#define USB_PRODUCT_ID (0xCC15)
#else
#define USB_PRODUCT_ID (0xFFFF)
#endif
#define USB_VENDOR_ID (0x1D50)
#define USB_API_VERSION (0x0111)
@ -51,7 +43,8 @@
#define USB_STRING_LANGID (0x0409)
uint8_t usb_descriptor_device[] = {
#if defined(IS_HACKRF_ONE) || defined(IS_PRALINE)
uint8_t usb_descriptor_device_hackrf[] = {
18, // bLength
USB_DESCRIPTOR_TYPE_DEVICE, // bDescriptorType
USB_WORD(0x0200), // bcdUSB
@ -60,13 +53,50 @@ uint8_t usb_descriptor_device[] = {
0x00, // bDeviceProtocol
USB_MAX_PACKET0, // bMaxPacketSize0
USB_WORD(USB_VENDOR_ID), // idVendor
USB_WORD(USB_PRODUCT_ID), // idProduct
USB_WORD(0x6089), // idProduct
USB_WORD(USB_API_VERSION), // bcdDevice
0x01, // iManufacturer
0x02, // iProduct
0x04, // iSerialNumber
0x01 // bNumConfigurations
};
#endif
#if defined(IS_JAWBREAKER)
uint8_t usb_descriptor_device_jawbreaker[] = {
18, // bLength
USB_DESCRIPTOR_TYPE_DEVICE, // bDescriptorType
USB_WORD(0x0200), // bcdUSB
0x00, // bDeviceClass
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
USB_MAX_PACKET0, // bMaxPacketSize0
USB_WORD(USB_VENDOR_ID), // idVendor
USB_WORD(0x604B), // idProduct
USB_WORD(USB_API_VERSION), // bcdDevice
0x01, // iManufacturer
0x02, // iProduct
0x04, // iSerialNumber
0x01 // bNumConfigurations
};
#endif
#if defined(IS_RAD1O)
uint8_t usb_descriptor_device_rad1o[] = {
18, // bLength
USB_DESCRIPTOR_TYPE_DEVICE, // bDescriptorType
USB_WORD(0x0200), // bcdUSB
0x00, // bDeviceClass
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
USB_MAX_PACKET0, // bMaxPacketSize0
USB_WORD(USB_VENDOR_ID), // idVendor
USB_WORD(0xCC15), // idProduct
USB_WORD(USB_API_VERSION), // bcdDevice
0x01, // iManufacturer
0x02, // iProduct
0x04, // iSerialNumber
0x01 // bNumConfigurations
};
#endif
uint8_t usb_descriptor_device_qualifier[] = {
10, // bLength
@ -185,8 +215,8 @@ uint8_t usb_descriptor_string_manufacturer[] = {
's', 0x00,
};
uint8_t usb_descriptor_string_product[] = {
#ifdef HACKRF_ONE
#if defined(IS_HACKRF_ONE)
uint8_t usb_descriptor_string_product_hackrf_one[] = {
22, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'H', 0x00,
@ -199,7 +229,26 @@ uint8_t usb_descriptor_string_product[] = {
'O', 0x00,
'n', 0x00,
'e', 0x00,
#elif JAWBREAKER
};
#endif
#if defined(IS_PRALINE)
uint8_t usb_descriptor_string_product_praline[] = {
22, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'H', 0x00,
'a', 0x00,
'c', 0x00,
'k', 0x00,
'R', 0x00,
'F', 0x00,
' ', 0x00,
'P', 0x00,
'r', 0x00,
'o', 0x00,
};
#endif
#if defined(IS_JAWBREAKER)
uint8_t usb_descriptor_string_product_jawbreaker[] = {
36, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'H', 0x00,
@ -219,7 +268,10 @@ uint8_t usb_descriptor_string_product[] = {
'k', 0x00,
'e', 0x00,
'r', 0x00,
#elif RAD1O
};
#endif
#if defined(IS_RAD1O)
uint8_t usb_descriptor_string_product_rad1o[] = {
12, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'r', 0x00,
@ -227,30 +279,8 @@ uint8_t usb_descriptor_string_product[] = {
'd', 0x00,
'1', 0x00,
'o', 0x00,
#elif PRALINE
22, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'H', 0x00,
'a', 0x00,
'c', 0x00,
'k', 0x00,
'R', 0x00,
'F', 0x00,
' ', 0x00,
'P', 0x00,
'r', 0x00,
'o', 0x00,
#else
14, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'H', 0x00,
'a', 0x00,
'c', 0x00,
'k', 0x00,
'R', 0x00,
'F', 0x00,
#endif
};
#endif
uint8_t usb_descriptor_string_config_description[] = {
24, // bLength
@ -291,14 +321,46 @@ uint8_t usb_descriptor_string_serial_number[] = {
uint8_t usb_descriptor_string_serial_number[USB_DESCRIPTOR_STRING_SERIAL_BUF_LEN];
#endif
uint8_t* usb_descriptor_strings[] = {
#if defined(IS_HACKRF_ONE)
uint8_t* usb_descriptor_strings_hackrf_one[] = {
usb_descriptor_string_languages,
usb_descriptor_string_manufacturer,
usb_descriptor_string_product,
usb_descriptor_string_product_hackrf_one,
usb_descriptor_string_config_description,
usb_descriptor_string_serial_number,
0, // TERMINATOR
};
#endif
#if defined(IS_PRALINE)
uint8_t* usb_descriptor_strings_praline[] = {
usb_descriptor_string_languages,
usb_descriptor_string_manufacturer,
usb_descriptor_string_product_praline,
usb_descriptor_string_config_description,
usb_descriptor_string_serial_number,
0, // TERMINATOR
};
#endif
#if defined(IS_JAWBREAKER)
uint8_t* usb_descriptor_strings_jawbreaker[] = {
usb_descriptor_string_languages,
usb_descriptor_string_manufacturer,
usb_descriptor_string_product_jawbreaker,
usb_descriptor_string_config_description,
usb_descriptor_string_serial_number,
0, // TERMINATOR
};
#endif
#if defined(IS_RAD1O)
uint8_t* usb_descriptor_strings_rad1o[] = {
usb_descriptor_string_languages,
usb_descriptor_string_manufacturer,
usb_descriptor_string_product_rad1o,
usb_descriptor_string_config_description,
usb_descriptor_string_serial_number,
0, // TERMINATOR
};
#endif
uint8_t wcid_string_descriptor[] = {
18, // bLength

View file

@ -24,20 +24,44 @@
#include <stdint.h>
extern uint8_t usb_descriptor_device[];
#include "platform_detect.h"
#if defined(IS_HACKRF_ONE) || defined(IS_PRALINE)
extern uint8_t usb_descriptor_device_hackrf[];
#endif
#if defined(IS_JAWBREAKER)
extern uint8_t usb_descriptor_device_jawbreaker[];
#endif
#if defined(IS_RAD1O)
extern uint8_t usb_descriptor_device_rad1o[];
#endif
extern uint8_t usb_descriptor_device_qualifier[];
extern uint8_t usb_descriptor_configuration_full_speed[];
extern uint8_t usb_descriptor_configuration_high_speed[];
extern uint8_t usb_descriptor_string_languages[];
extern uint8_t usb_descriptor_string_manufacturer[];
extern uint8_t usb_descriptor_string_product[];
#if defined(IS_HACKRF_ONE)
extern uint8_t usb_descriptor_string_product_hackrf_one[];
#endif
#if defined(IS_PRALINE)
extern uint8_t usb_descriptor_string_product_praline[];
#endif
#if defined(IS_JAWBREAKER)
extern uint8_t usb_descriptor_string_product_jawbreaker[];
#endif
#if defined(IS_RAD1O)
extern uint8_t usb_descriptor_string_product_rad1o[];
#endif
#define USB_DESCRIPTOR_STRING_SERIAL_LEN 32
#define USB_DESCRIPTOR_STRING_SERIAL_BUF_LEN \
(USB_DESCRIPTOR_STRING_SERIAL_LEN * 2 + 2) /* UTF-16LE */
extern uint8_t usb_descriptor_string_serial_number[];
extern uint8_t* usb_descriptor_strings[];
extern uint8_t* usb_descriptor_strings_hackrf_one[];
extern uint8_t* usb_descriptor_strings_jawbreaker[];
extern uint8_t* usb_descriptor_strings_rad1o[];
extern uint8_t* usb_descriptor_strings_praline[];
#define USB_WCID_VENDOR_REQ 0x19
extern uint8_t wcid_string_descriptor[];

View file

@ -25,6 +25,7 @@
#include <usb_type.h>
#include "platform_detect.h"
#include "usb_descriptor.h"
usb_configuration_t usb_configuration_high_speed = {
@ -45,12 +46,49 @@ usb_configuration_t* usb_configurations[] = {
0,
};
usb_device_t usb_device = {
.descriptor = usb_descriptor_device,
.descriptor_strings = usb_descriptor_strings,
usb_device_t usb_device;
#if defined(IS_HACKRF_ONE)
const usb_device_t usb_device_hackrf_one = {
.descriptor = usb_descriptor_device_hackrf,
.descriptor_strings = usb_descriptor_strings_hackrf_one,
.qualifier_descriptor = usb_descriptor_device_qualifier,
.configurations = &usb_configurations,
.configuration = 0,
.wcid_string_descriptor = wcid_string_descriptor,
.wcid_feature_descriptor = wcid_feature_descriptor,
};
#endif
#if defined(IS_PRALINE)
const usb_device_t usb_device_praline = {
.descriptor = usb_descriptor_device_hackrf,
.descriptor_strings = usb_descriptor_strings_praline,
.qualifier_descriptor = usb_descriptor_device_qualifier,
.configurations = &usb_configurations,
.configuration = 0,
.wcid_string_descriptor = wcid_string_descriptor,
.wcid_feature_descriptor = wcid_feature_descriptor,
};
#endif
#if defined(IS_JAWBREAKER)
const usb_device_t usb_device_jawbreaker = {
.descriptor = usb_descriptor_device_jawbreaker,
.descriptor_strings = usb_descriptor_strings_jawbreaker,
.qualifier_descriptor = usb_descriptor_device_qualifier,
.configurations = &usb_configurations,
.configuration = 0,
.wcid_string_descriptor = wcid_string_descriptor,
.wcid_feature_descriptor = wcid_feature_descriptor,
};
#endif
#if defined(IS_RAD1O)
const usb_device_t usb_device_rad1o = {
.descriptor = usb_descriptor_device_rad1o,
.descriptor_strings = usb_descriptor_strings_rad1o,
.qualifier_descriptor = usb_descriptor_device_qualifier,
.configurations = &usb_configurations,
.configuration = 0,
.wcid_string_descriptor = wcid_string_descriptor,
.wcid_feature_descriptor = wcid_feature_descriptor,
};
#endif

View file

@ -25,4 +25,19 @@
#include <usb_type.h>
#include "platform_detect.h"
extern usb_device_t usb_device;
#if defined(IS_HACKRF_ONE)
extern const usb_device_t usb_device_hackrf_one;
#endif
#if defined(IS_PRALINE)
extern const usb_device_t usb_device_praline;
#endif
#if defined(IS_JAWBREAKER)
extern const usb_device_t usb_device_jawbreaker;
#endif
#if defined(IS_RAD1O)
extern const usb_device_t usb_device_rad1o;
#endif