Compare commits

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

26 commits

Author SHA1 Message Date
grvvy
e1dc052815 Jenkinsfile: ensure usb hub commands are wrapped in retry blocks
Some checks failed
Check code style / clang-format-2 (push) Failing after 19s
Check code style / clang-format-3 (push) Failing after 7s
Check includes / includes-check (HACKRF_ONE, 3.10.0) (push) Failing after 6s
Check includes / includes-check (HACKRF_ONE, latest) (push) Failing after 5s
Check includes / includes-check (JAWBREAKER, 3.10.0) (push) Failing after 5s
Check includes / includes-check (JAWBREAKER, latest) (push) Failing after 3s
Check includes / includes-check (PRALINE, 3.10.0) (push) Failing after 4s
Check includes / includes-check (PRALINE, latest) (push) Failing after 3s
Check includes / includes-check (RAD1O, 3.10.0) (push) Failing after 3s
Check includes / includes-check (RAD1O, latest) (push) Failing after 3s
Check includes / includes-check (UNIVERSAL, 3.10.0) (push) Failing after 4s
Check includes / includes-check (UNIVERSAL, latest) (push) Failing after 3s
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 (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 (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 (RAD1O, latest, windows) (push) Has been cancelled
Build / firmware (UNIVERSAL, 3.10.0, macos) (push) Has been cancelled
Build / firmware (UNIVERSAL, latest, macos) (push) Has been cancelled
Build / firmware (UNIVERSAL, latest, windows) (push) Has been cancelled
2026-04-15 23:22:21 -06:00
grvvy
f8c3856d7c Add temporary HIL CI fix - sleep 4s after programming the EUT 2026-04-15 23:19:05 -06:00
Martin Ling
9e1126d952 Use IS macros for all conditional compilation. 2026-04-15 22:53:42 +01:00
Martin Ling
8ce78cbc8f firmware: Separate compile-time and runtime platform checks. 2026-04-15 22:53:42 +01:00
Martin Ling
7938f93295 firmware: Use macros to simplify platform-specific code. 2026-04-15 22:53:41 +01:00
Martin Ling
7fa88d13e0 max283x: Add macros to simplify variant-specific dispatch. 2026-04-15 22:51:54 +01:00
Martin Ling
77569163a3 max283x: Move platform switch inside max283x_setup(). 2026-04-15 22:51:54 +01:00
Martin Ling
7fd2d4b86f Jenkinsfile: add tests with BOARD=UNIVERSAL. 2026-04-15 22:23:03 +01:00
Martin Ling
9d11652d62 Add UNIVERSAL firmware build to GitHub Actions. 2026-04-15 22:23:03 +01:00
Martin Ling
509249fe74 Add UNIVERSAL board target. 2026-04-15 22:23:03 +01:00
Martin Ling
e34393a1dd Universalize: firmware/hackrf_usb
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-15 22:23:03 +01:00
Martin Ling
d862545ce3 Universalize: hackrf_core.{c,h}, selftest.h
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-15 22:23:03 +01:00
Martin Ling
a14c4c85f8 Universalize: radio.c
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-15 22:22:04 +01:00
Martin Ling
7c78654afc Universalize: sgpio.{c,h}
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-15 22:22:04 +01:00
Martin Ling
85ada5ba48 Universalize: w25q80bv.c
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-15 22:22:04 +01:00
Martin Ling
547aa38294 Universalize: operacake_sctimer.c
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-15 22:22:04 +01:00
Martin Ling
8587964d32 Universalize: hackrf_ui.c
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-15 22:22:04 +01:00
Martin Ling
0b3ed0d43c Universalize: tuning.{c,h}, tune_config.h
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-15 22:22:04 +01:00
Martin Ling
52c9b4ac0a Universalize: mixer.{c,h}, usb_api_register.c
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-15 22:22:04 +01:00
Martin Ling
2a89ed7207 Universalize: rf_path.{c,h}
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-15 22:22:04 +01:00
Martin Ling
ccc144ad48 Universalize: si5351.c
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-15 22:22:04 +01:00
Martin Ling
dafa1349cc Universalize: rffc5071.{c,h}
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-15 22:22:04 +01:00
Martin Ling
25918e154a Universalize: max283x.{c,h}
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-15 22:22:04 +01:00
Martin Ling
bf7d47abf1 Universalize: cpld_jtag.{c,h}
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-15 22:22:04 +01:00
Martin Ling
7e03135d49 Universalize: platform_scu.{c,h}
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-15 22:22:04 +01:00
Martin Ling
697d10fa53 Universalize: platform_gpio.{c,h}
Co-authored-by: Antoine van Gelder <antoine@greatscottgadgets.com>
2026-04-15 22:22:04 +01:00
51 changed files with 2875 additions and 2054 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

225
Jenkinsfile vendored
View file

@ -1,100 +1,173 @@
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 {
stage('Build Docker Image') {
options {
timeout(time: 20, unit: 'MINUTES')
}
steps {
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
}
}
options {
timeout(time: 20, unit: 'MINUTES')
}
steps {
sh './ci-scripts/install_host.sh'
sh './ci-scripts/build_h1_firmware.sh'
sh './ci-scripts/build_firmware.sh HACKRF_ONE'
script {
allOff();
allOff()
reset('h1_eut')
}
sh 'sleep 1s'
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",
'''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'''
)
allOff()
}
script {
reset('h1_tester h1_eut')
}
sh 'sleep 1s'
script {
// Allow up to 3 retries 5 minutes each for the HIL test
runCommand(3, 5, 'MINUTES', "HackRF One Test", h1_test)
}
script {
allOff()
reset('h1_eut')
}
sh 'sleep 1s'
retry(3) {
script {
reset('h1_eut')
}
sh 'sleep 1s'
sh 'python3 ci-scripts/test_sgpio_debug.py'
}
}
}
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
}
}
options {
timeout(time: 20, unit: 'MINUTES')
}
steps {
sh './ci-scripts/install_host.sh'
sh './ci-scripts/build_hpro_firmware.sh'
sh './ci-scripts/build_firmware.sh UNIVERSAL'
script {
allOff();
allOff()
reset('h1_eut')
}
sh 'sleep 1s'
retry(3) {
script {
reset('hpro_eut')
}
sh 'sleep 1s'
sh './ci-scripts/test_host.sh'
}
script {
reset('h1_tester h1_eut')
}
sh 'sleep 1s'
script {
// Allow up to 3 retries 5 minutes each for the HIL test
runCommand(3, 5, 'MINUTES', "HackRF One Test", h1_test)
}
script {
allOff()
reset('h1_eut')
}
sh 'sleep 1s'
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",
'''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'''
)
}
sh 'python3 ci-scripts/test_sgpio_debug.py'
}
}
}
stage('Test HackRF Pro with BOARD=PRALINE') {
agent {
docker {
image 'hackrf'
reuseNode true
args "$docker_args"
}
}
options {
timeout(time: 20, unit: 'MINUTES')
}
steps {
sh './ci-scripts/install_host.sh'
sh './ci-scripts/build_firmware.sh PRALINE'
script {
allOff()
reset('hpro_eut')
}
sh 'sleep 1s'
retry(3) {
sh './ci-scripts/test_host.sh'
}
script {
reset('hpro_tester hpro_eut')
}
sh 'sleep 1s'
script {
// Allow up to 3 retries 5 minutes each for the HIL test
runCommand(3, 5, 'MINUTES', "HackRF Pro Test", hpro_test)
}
}
}
stage('Test HackRF Pro with BOARD=UNIVERSAL') {
agent {
docker {
image 'hackrf'
reuseNode true
args "$docker_args"
}
}
options {
timeout(time: 20, unit: 'MINUTES')
}
steps {
sh './ci-scripts/install_host.sh'
sh './ci-scripts/build_firmware.sh UNIVERSAL'
script {
allOff()
reset('hpro_eut')
}
sh 'sleep 1s'
retry(3) {
sh './ci-scripts/test_host.sh'
}
script {
reset('hpro_tester hpro_eut')
}
sh 'sleep 1s'
script {
// Allow up to 3 retries 5 minutes each for the HIL test
runCommand(3, 5, 'MINUTES', "HackRF Pro Test", hpro_test)
}
}
}
@ -110,32 +183,34 @@ pipeline {
}
def allOff() {
// Allow 20 seconds for the USB hub port power server to respond
runCommand(20, 'SECONDS', 'USB hub port power server command', "hubs all off")
// Allow up to 3 retries, 20 seconds each, for the USB hub port power server to respond appropriately
runCommand(3, 20, 'SECONDS', 'USB hub port power server command', "hubs all off")
}
def reset(devices) {
// Allow 20 seconds for the USB hub port power server to respond
runCommand(20, 'SECONDS', 'USB hub port power server command', "hubs ${devices} reset")
// Allow up to 3 retries, 20 seconds each, for the USB hub port power server to respond appropriately
runCommand(3, 20, 'SECONDS', 'USB hub port power server command', "hubs ${devices} reset")
}
def runCommand(time, unit, title, cmd) {
try {
timeout(time: time, unit: unit) {
sh "${cmd}"
def runCommand(retries, time, unit, title, cmd) {
retry(retries) {
try {
timeout(time: time, unit: unit) {
sh "${cmd}"
}
} catch (FlowInterruptedException err) {
// Check if the cause was specifically an exceeded timeout
def cause = err.getCauses().get(0)
if (cause instanceof org.jenkinsci.plugins.workflow.steps.TimeoutStepExecution.ExceededTimeout) {
echo "${title} timeout reached."
throw err // Re-throw the exception to fail the build
} else {
echo "Build interrupted for another reason."
throw err // Re-throw the exception to fail the build
}
} catch (Exception err) {
echo "An unrelated error occurred: ${err.getMessage()}"
throw err
}
} catch (FlowInterruptedException err) {
// Check if the cause was specifically an exceeded timeout
def cause = err.getCauses().get(0)
if (cause instanceof org.jenkinsci.plugins.workflow.steps.TimeoutStepExecution.ExceededTimeout) {
echo "${title} timeout reached."
throw err // Re-throw the exception to fail the build
} else {
echo "Build interrupted for another reason."
throw err // Re-throw the exception to fail the build
}
} catch (Exception err) {
echo "An unrelated error occurred: ${err.getMessage()}"
throw err
}
}

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

@ -1594,6 +1594,7 @@ def main():
# TODO: check if the provided firmware directory exists
if args.fwupdate:
program(eut_host_dir, args.fwupdate, eut_sn, args.unattended)
time.sleep(4)
eut_sn = find_sn("EUT", eut_host_dir, args.factory, [tester_sn])
if not args.rev:

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"
#ifdef IS_NOT_PRALINE
#include <stdint.h>
#include "xapp058/micro.h"
#endif
#ifndef PRALINE
#ifdef 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);
#ifdef 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);
#ifdef IS_NOT_PRALINE
if (IS_NOT_PRALINE) {
gpio_set(gpio->gpio_tms);
gpio_set(gpio->gpio_tdi);
}
#endif
#ifdef 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);
#ifdef 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);
#ifdef 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);
#ifdef 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
#ifdef 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
#ifdef IS_NOT_PRALINE
gpio_t gpio_tms;
gpio_t gpio_tdi;
gpio_t gpio_tdo;
#endif
#if (defined HACKRF_ONE || defined PRALINE)
#ifdef 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" // IWYU pragma: keep
#include "radio.h"
#include "rf_path.h"
#include "sgpio.h"
#include "si5351c.h"
#include "spi_ssp.h"
#include "w25q80bv.h"
#if defined(PRALINE)
#ifdef 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;
#ifdef 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
#ifdef IS_PRALINE
void ssp1_set_mode_ice40(void);
#endif
void pin_shutdown(void);
void pin_setup(void);
#ifdef PRALINE
#ifdef 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
#ifdef 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" // IWYU pragma: keep
#include "transceiver_mode.h"
#if defined(PRALINE) || defined(HACKRF_ONE)
#ifdef IS_EXPANSION_COMPATIBLE
#include "ui_portapack.h"
#endif
#if defined(RAD1O)
#ifdef 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();
#ifdef 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();
#ifdef IS_RAD1O
if (IS_RAD1O) {
if (rad1o_ui_setup) {
ui = rad1o_ui_setup();
}
}
#endif
}

View file

@ -27,33 +27,39 @@
#include <string.h>
#include "fixed_point.h"
#include "platform_detect.h"
#include "platform_gpio.h"
#include "spi_bus.h"
#if defined(PRALINE)
#include "max2831.h"
#ifdef IS_PRALINE
#include "max2831_target.h"
#else
#include "max2837.h"
#endif
#ifdef IS_NOT_PRALINE
#include "max2837_target.h"
#include "max2839.h"
#endif
#ifdef IS_H1_R9
#include "max2839_target.h"
#endif
extern spi_bus_t spi_bus_ssp1;
#ifdef PRALINE
#ifdef IS_PRALINE
max2831_driver_t max2831 = {
.bus = &spi_bus_ssp1,
.target_init = max2831_target_init,
.set_mode = max2831_target_set_mode,
};
#else
#endif
#ifdef IS_NOT_PRALINE
max2837_driver_t max2837 = {
.bus = &spi_bus_ssp1,
.target_init = max2837_target_init,
.set_mode = max2837_target_set_mode,
};
#endif
#ifdef IS_HACKRF_ONE
max2839_driver_t max2839 = {
.bus = &spi_bus_ssp1,
.target_init = max2839_target_init,
@ -62,132 +68,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:
#ifdef 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
#ifdef IS_NOT_PRALINE
if (IS_NOT_PRALINE) {
#ifdef 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
#ifdef 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 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 HACKRF_ONE
// HACKRF_ONE: MAX2837 and MAX2839 only
#define DISPATCH(_drv, _max2831, _max2837, _max2839) \
if (_drv->type == MAX2837_VARIANT) { \
_max2837; \
} else { \
_max2839; \
}
#elif 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
@ -195,99 +205,36 @@ 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 1/(2**24) Hz. */
@ -296,22 +243,7 @@ fp_40_24_t max283x_set_frequency(
fp_40_24_t freq,
bool program)
{
switch (drv->type) {
#ifdef PRALINE
case MAX2831_VARIANT:
return max2831_set_frequency(&drv->drv.max2831, freq, program);
break;
#else
case MAX2837_VARIANT:
return max2837_set_frequency(&drv->drv.max2837, freq, program);
break;
case MAX2839_VARIANT:
return max2839_set_frequency(&drv->drv.max2839, freq, program);
break;
#endif
}
return 0;
return RESULT(drv, fp_40_24_t, set_frequency, freq, program);
}
uint32_t max283x_set_lpf_bandwidth(
@ -319,194 +251,61 @@ uint32_t max283x_set_lpf_bandwidth(
const max283x_mode_t mode,
const uint32_t bandwidth_hz)
{
#ifndef 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
(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

@ -27,10 +27,15 @@
#include <stdint.h>
#include "fixed_point.h"
#if defined(PRALINE)
#include "platform_detect.h"
#ifdef IS_PRALINE
#include "max2831.h"
#else
#endif
#ifdef IS_NOT_PRALINE
#include "max2837.h"
#endif
#ifdef IS_H1_R9
#include "max2839.h"
#endif
@ -52,10 +57,13 @@ typedef enum {
} max283x_rx_hpf_freq_t;
typedef enum {
#ifdef PRALINE
#ifdef IS_PRALINE
MAX2831_VARIANT,
#else
#endif
#ifdef IS_NOT_PRALINE
MAX2837_VARIANT,
#endif
#ifdef IS_H1_R9
MAX2839_VARIANT,
#endif
} max283x_variant_t;
@ -64,17 +72,20 @@ typedef struct {
max283x_variant_t type;
union {
#ifdef PRALINE
#ifdef IS_PRALINE
max2831_driver_t max2831;
#else
#endif
#ifdef IS_NOT_PRALINE
max2837_driver_t max2837;
#endif
#ifdef 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,17 +24,18 @@
#include <stdbool.h>
#include <stdint.h>
#include <libopencm3/lpc43xx/scu.h>
#include "fixed_point.h"
#include "max2871_regs.h"
#include "selftest.h"
#include "platform_scu.h"
#include "selftest.h"
#if (defined DEBUG)
#include <stdio.h>
#define LOG printf
#else
#define LOG(x, ...)
#include <libopencm3/lpc43xx/scu.h>
#endif
#define MIN(x, y) ((x) < (y) ? (x) : (y))

View file

@ -24,102 +24,143 @@
#include <stdbool.h>
#include "fixed_point.h"
#include "platform_detect.h"
#include "platform_gpio.h"
#if defined(JAWBREAKER) || defined(HACKRF_ONE) || defined(PRALINE)
#ifdef IS_RAD1O
#include "max2871.h"
#endif
#ifdef 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)
#ifdef 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 = {};
#ifdef 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);
#ifdef 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 */
#ifdef IS_PRALINE
if (IS_PRALINE) {
mixer->rffc5071.gpio_ld = gpio->rffc5072_ld;
}
#endif
#ifdef IS_NOT_RAD1O
if (IS_NOT_RAD1O) {
mixer->rffc5071.gpio_reset = gpio->rffc5072_reset;
rffc5071_setup(&mixer->rffc5071);
}
#endif
#ifdef 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
}
fp_40_24_t mixer_set_frequency(mixer_driver_t* const mixer, fp_40_24_t lo, bool program)
{
#if defined(JAWBREAKER) || defined(HACKRF_ONE) || defined(PRALINE)
return rffc5071_set_frequency(mixer, lo, program);
#elif defined(RAD1O)
return max2871_set_frequency(mixer, lo, program);
#ifdef IS_NOT_RAD1O
if (IS_NOT_RAD1O) {
return rffc5071_set_frequency(&mixer->rffc5071, lo, program);
}
#endif
#ifdef IS_RAD1O
if (IS_RAD1O) {
return max2871_set_frequency(&mixer->max2871, lo, program);
}
#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);
#ifdef IS_NOT_RAD1O
if (IS_NOT_RAD1O) {
rffc5071_enable(&mixer->rffc5071);
}
#endif
#ifdef 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);
#ifdef IS_NOT_RAD1O
if (IS_NOT_RAD1O) {
rffc5071_disable(&mixer->rffc5071);
}
#endif
#ifdef 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;
#ifdef IS_NOT_RAD1O
if (IS_NOT_RAD1O) {
rffc5071_set_gpo(&mixer->rffc5071, gpo);
}
#endif
#ifdef IS_RAD1O
if (IS_RAD1O) {
(void) mixer;
(void) gpo;
}
#endif
}

View file

@ -23,20 +23,38 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "fixed_point.h"
#include "platform_detect.h"
#if defined(JAWBREAKER) || defined(HACKRF_ONE) || defined(PRALINE)
#include "rffc5071.h"
typedef rffc5071_driver_t mixer_driver_t;
#elif defined(RAD1O)
#ifdef IS_RAD1O
#include "max2871.h"
typedef max2871_driver_t mixer_driver_t;
#endif
#ifdef 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 {
#ifdef IS_RAD1O
max2871_driver_t max2871;
#endif
#ifdef 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 fp_40_24_t mixer_set_frequency(

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"
#ifdef 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;
#ifdef 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
#ifdef 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,189 +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;
#ifdef IS_RAD1O
if (IS_RAD1O) {
gpio.led[3] = &GPIO5_26;
}
#endif
#ifdef 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;
#ifdef IS_PRALINE
if (IS_PRALINE) {
gpio.gpio_1v2_enable = &GPIO4_7;
gpio.gpio_3v3aux_enable_n = &GPIO5_15;
}
#endif
#ifdef 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;
#ifdef 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
#ifdef 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;
#ifdef IS_PRALINE
if (IS_PRALINE) {
gpio.max5864_select = &GPIO6_30;
}
#endif
#ifdef 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;
#ifdef IS_HACKRF_ONE
if (IS_HACKRF_ONE) {
gpio.vaa_disable = &GPIO2_9;
}
#endif
#ifdef IS_PRALINE
if (IS_PRALINE) {
gpio.vaa_disable = &GPIO4_1;
}
#endif
#ifdef 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;
#ifdef 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;
#ifdef IS_H1_R9
if (IS_H1_R9) {
gpio.h1r9_rx = &GPIO0_7;
gpio.h1r9_no_ant_pwr = &GPIO2_4;
}
#endif
}
#endif
#ifdef 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
#ifdef 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;
#else
gpio.cpld_tdo = &GPIO5_18;
gpio.cpld_tck = &GPIO3_0;
#ifdef 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_tms = &GPIO3_4;
gpio.cpld_tdi = &GPIO3_1;
#ifdef IS_NOT_PRALINE
if (IS_NOT_PRALINE) {
gpio.cpld_tdo = &GPIO5_18;
}
#endif
#if defined(JAWBREAKER)
gpio.cpld_tms = &GPIO3_1;
gpio.cpld_tdi = &GPIO3_4;
#ifdef 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;
#ifdef IS_JAWBREAKER
if (IS_JAWBREAKER) {
gpio.cpld_tms = &GPIO3_1;
gpio.cpld_tdi = &GPIO3_4;
}
#endif
#ifdef 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;
#ifdef 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;
#ifdef 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
#ifdef 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
#ifdef 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;
#ifdef 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 */
#ifdef 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 */
#ifdef 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 */
#ifdef 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)
#ifdef 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)
#ifdef 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)
#ifdef 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)
#ifdef IS_RAD1O
gpio_t vaa_enable;
#endif
@ -68,7 +69,7 @@ typedef struct {
gpio_t w25q80bv_select;
/* RF switch control */
#if defined(HACKRF_ONE)
#ifdef 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)
#ifdef 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)
#ifdef 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) || defined(JAWBREAKER)
#ifdef IS_NOT_PRALINE
gpio_t cpld_tdo;
gpio_t cpld_tms;
gpio_t cpld_tdi;
#endif
#if defined(HACKRF_ONE) || defined(PRALINE)
#ifdef IS_EXPANSION_COMPATIBLE
gpio_t cpld_pp_tms;
gpio_t cpld_pp_tdo;
#endif
#if defined(PRALINE)
#ifdef 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)
#ifdef 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)
#ifdef 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)
#ifdef 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)
#ifdef IS_RAD1O
gpio_t lcd_cs;
gpio_t lcd_bl_en;
gpio_t lcd_reset;
#endif
/* Portapack */
#if defined(HACKRF_ONE) || defined(PRALINE)
#ifdef 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 */
#ifdef IS_RAD1O
if (IS_RAD1O) {
scu.PINMUX_LED4 = (PB_6); /* GPIO5[26] on PB_6 */
}
#endif
#ifdef 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 */
#ifdef 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 */
#ifdef 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);
#ifdef IS_JAWBREAKER
if (IS_JAWBREAKER) {
scu.PINMUX_USB_LED0 = (P6_8);
scu.PINMUX_USB_LED1 = (P6_7);
}
#endif
/* SSP1 Peripheral PinMux */
@ -80,171 +88,216 @@ 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] */
#else
scu.PINMUX_CPLD_TDO = (P9_5); /* GPIO5[18] */
scu.PINMUX_CPLD_TCK = (P6_1); /* GPIO3[ 0] */
#ifdef 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
#if defined(RAD1O) || defined(HACKRF_ONE)
scu.PINMUX_CPLD_TMS = (P6_5); /* GPIO3[ 4] */
scu.PINMUX_CPLD_TDI = (P6_2); /* GPIO3[ 1] */
#ifdef IS_NOT_PRALINE
if (IS_NOT_PRALINE) {
scu.PINMUX_CPLD_TDO = (P9_5); /* GPIO5[18] */
}
#endif
#if defined(JAWBREAKER)
scu.PINMUX_CPLD_TMS = (P6_2); /* GPIO3[ 1] */
scu.PINMUX_CPLD_TDI = (P6_5); /* GPIO3[ 4] */
#ifdef IS_H1_OR_RAD1O
if (IS_H1_OR_RAD1O) {
scu.PINMUX_CPLD_TMS = (P6_5); /* GPIO3[ 4] */
scu.PINMUX_CPLD_TDI = (P6_2); /* GPIO3[ 1] */
}
#endif
#ifdef 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);
#ifdef 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
#ifdef 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 */
#ifdef 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
#ifdef 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
#ifdef 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);
#ifdef 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
#ifdef 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 */
#ifdef 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
#ifdef 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
#ifdef 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 */
#ifdef 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 */
#ifdef IS_HACKRF_ONE
if (IS_HACKRF_ONE) {
scu.NO_VAA_ENABLE = P5_0; /* GPIO2[9] on P5_0 */
}
#endif
#ifdef IS_PRALINE
if (IS_PRALINE) {
scu.NO_VAA_ENABLE = P8_1; /* GPIO4[1] on P8_1 */
}
#endif
#ifdef IS_RAD1O
if (IS_RAD1O) {
scu.VAA_ENABLE = P5_0; /* GPIO2[9] on P5_0 */
}
#endif
/* SPI flash */
@ -256,114 +309,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 */
#ifdef 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
#ifdef 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
#ifdef 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 */
#ifdef 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 */
#ifdef 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 */
#ifdef 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)
#ifdef 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)
#ifdef 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)
#ifdef 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)
#ifdef 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)
#ifdef 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;
#ifdef 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
#ifdef 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 */
#ifdef 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
#ifdef IS_PRALINE
scu_grp_pin_t MIXER_LD;
uint32_t MIXER_LD_PINCFG;
#elif defined(RAD1O)
#endif
#ifdef 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)
#ifdef 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
#ifdef 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)
#ifdef 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
#ifdef 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
#ifdef 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)
#ifdef 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)
#ifdef 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

@ -35,11 +35,11 @@
#include "sgpio.h"
#include "transceiver_mode.h"
#include "tuning.h"
#if defined(PRALINE)
#ifdef IS_PRALINE
#include "fpga.h"
#include "tune_config.h"
#endif
#if defined(HACKRF_ONE) || defined(PRALINE)
#ifdef IS_EXPANSION_COMPATIBLE
#include "operacake.h"
#endif
@ -200,8 +200,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);
#ifdef IS_PRALINE
if (IS_PRALINE) {
fpga_set_tx_interpolation_ratio(&fpga, n);
}
#endif
radio->config[RADIO_BANK_APPLIED][RADIO_RESAMPLE_TX] = n;
}
@ -209,8 +211,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);
#ifdef IS_PRALINE
if (IS_PRALINE) {
fpga_set_rx_decimation_ratio(&fpga, n);
}
#endif
radio->config[RADIO_BANK_APPLIED][RADIO_RESAMPLE_RX] = n;
}
@ -301,7 +305,7 @@ static fp_40_24_t digital_from_analog_rf(
return drf;
}
#ifdef PRALINE
#ifdef IS_PRALINE
/*
* Convert center frequency of digital baseband (as seen by MCU) to center
* frequency of analog baseband (as seen by ADC/DAC).
@ -362,7 +366,9 @@ static bool radio_update_frequency(radio_t* const radio, uint64_t* bank)
const uint64_t requested_if = bank[RADIO_FREQUENCY_IF];
const uint64_t requested_lo = bank[RADIO_FREQUENCY_LO];
const uint64_t requested_img_reject = bank[RADIO_IMAGE_REJECT];
#ifdef IS_PRALINE
const uint64_t requested_rotation = bank[RADIO_ROTATION];
#endif
const uint64_t applied_rf = radio->config[RADIO_BANK_APPLIED][RADIO_FREQUENCY_RF];
const uint64_t applied_if = radio->config[RADIO_BANK_APPLIED][RADIO_FREQUENCY_IF];
@ -401,7 +407,8 @@ static bool radio_update_frequency(radio_t* const radio, uint64_t* bank)
if (requested_lo != RADIO_UNSET) {
freq_lo = mixer_set_frequency(&mixer, freq_lo, false);
}
if (detected_platform() == BOARD_ID_PRALINE) {
#ifdef IS_PRALINE
if (IS_PRALINE) {
if (requested_rotation != RADIO_UNSET) {
rotation = requested_rotation;
}
@ -417,9 +424,13 @@ static bool radio_update_frequency(radio_t* const radio, uint64_t* bank)
default:
rotation = 0;
}
} else {
}
#endif
#ifdef IS_NOT_PRALINE
if (IS_NOT_PRALINE) {
rotation = 0;
}
#endif
/* Handle requested RF (auto-tune). */
if (requested_rf != RADIO_UNSET) {
@ -429,8 +440,8 @@ static bool radio_update_frequency(radio_t* const radio, uint64_t* bank)
freq_rf = restrict_rf(requested_rf, img_reject);
/* Look up settings appropriate for requested RF. */
if (detected_platform() == BOARD_ID_PRALINE) {
#ifdef PRALINE
#ifdef IS_PRALINE
if (IS_PRALINE) {
const tune_config_t* tune_config =
select_tune_config(opmode, freq_rf);
if (requested_rotation == RADIO_UNSET) {
@ -446,8 +457,10 @@ static bool radio_update_frequency(radio_t* const radio, uint64_t* bank)
}
}
high_lo = tune_config->high_lo;
}
#endif
} else {
#ifdef IS_NOT_PRALINE
if (IS_NOT_PRALINE) {
/* Use graduated or fixed IF on older platforms. */
if (requested_if == RADIO_UNSET) {
freq_if = select_graduated_if(freq_rf, img_reject);
@ -455,6 +468,7 @@ static bool radio_update_frequency(radio_t* const radio, uint64_t* bank)
high_lo = (img_reject == RF_PATH_FILTER_LOW_PASS);
analog_rf = freq_rf;
}
#endif
/* Compute precise LO. This is done first because the mixer LO is set in coarse steps. */
if (requested_lo == RADIO_UNSET) {
@ -510,8 +524,10 @@ static bool radio_update_frequency(radio_t* const radio, uint64_t* bank)
new_freq = true;
}
if ((rotation != applied_rotation) && (rotation != RADIO_UNSET)) {
#ifdef PRALINE
fpga_set_rx_quarter_shift_mode(&fpga, rotation >> 30);
#ifdef IS_PRALINE
if (IS_PRALINE) {
fpga_set_rx_quarter_shift_mode(&fpga, rotation >> 30);
}
#endif
radio->config[RADIO_BANK_APPLIED][RADIO_ROTATION] = rotation;
new_freq = true;
@ -548,8 +564,10 @@ static bool radio_update_frequency(radio_t* const radio, uint64_t* bank)
if (opmode != TRANSCEIVER_MODE_RX_SWEEP) {
hackrf_ui()->set_frequency(freq_rf / FP_ONE_MHZ);
}
#if defined(PRALINE) || defined(HACKRF_ONE)
operacake_set_range(freq_rf / FP_ONE_MHZ);
#ifdef IS_EXPANSION_COMPATIBLE
if (IS_EXPANSION_COMPATIBLE) {
operacake_set_range(freq_rf / FP_ONE_MHZ);
}
#endif
}
return new_freq;
@ -587,66 +605,92 @@ static bool radio_update_bandwidth(radio_t* const radio, uint64_t* bank)
opmode = radio->config[RADIO_BANK_APPLIED][RADIO_OPMODE];
}
#ifdef PRALINE
/* Praline legacy mode always sets baseband bandwidth automatically. */
(void) bank;
uint32_t lpf_bandwidth = auto_bandwidth(radio, opmode);
#ifdef IS_PRALINE
if (IS_PRALINE) {
/* Praline legacy mode always sets baseband bandwidth automatically. */
(void) bank;
uint32_t lpf_bandwidth = auto_bandwidth(radio, opmode);
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, opmode);
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
#ifdef 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, opmode);
}
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;
@ -784,26 +828,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
#ifdef 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,19 +23,18 @@
#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"
#include "max5864.h"
#include "mixer.h"
#include "platform_detect.h"
#include "sgpio.h"
#include "platform_detect.h"
#include "transceiver_mode.h"
#if defined(HACKRF_ONE) || defined(RAD1O) || defined(PRALINE)
#ifdef IS_NOT_JAWBREAKER
#include <libopencm3/lpc43xx/scu.h>
#include "gpio.h"
#include "platform_scu.h"
#endif
@ -95,17 +94,18 @@
#define SWITCHCTRL_ANT_PWR (1 << 6) /* turn on antenna port power */
#ifdef HACKRF_ONE
#ifdef 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 +168,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 +188,7 @@ static void switchctrl_set_hackrf_one(rf_path_t* const rf_path, uint8_t ctrl)
}
#endif
#ifdef PRALINE
#ifdef IS_PRALINE
static void switchctrl_set_praline(rf_path_t* const rf_path, uint8_t ctrl)
{
if (ctrl & SWITCHCTRL_TX) {
@ -229,7 +229,7 @@ static void switchctrl_set_praline(rf_path_t* const rf_path, uint8_t ctrl)
}
#endif
#ifdef RAD1O
#ifdef IS_RAD1O
static void switchctrl_set_rad1o(rf_path_t* const rf_path, uint8_t ctrl)
{
if (ctrl & SWITCHCTRL_TX) {
@ -296,142 +296,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;
#ifdef IS_JAWBREAKER
if (IS_JAWBREAKER) {
(void) rf_path;
mixer_set_gpo(&mixer, gpo);
}
#endif
#ifdef IS_HACKRF_ONE
if (IS_HACKRF_ONE) {
switchctrl_set_hackrf_one(rf_path, gpo);
}
#endif
#ifdef IS_PRALINE
if (IS_PRALINE) {
switchctrl_set_praline(rf_path, gpo);
}
#endif
#ifdef 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)
#ifdef 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);
#ifdef 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
#ifdef 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
#ifdef 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
#ifdef 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
#ifdef 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 +470,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);
#ifdef IS_RAD1O
if (IS_RAD1O) {
mixer_setup(&mixer, MAX2871_VARIANT);
}
#endif
#ifdef IS_NOT_RAD1O
if (IS_NOT_RAD1O) {
#ifdef IS_NOT_HACKRF_ONE
if (IS_NOT_HACKRF_ONE) {
mixer_setup(&mixer, RFFC5071_VARIANT);
}
#endif
}
#endif
rf_path->switchctrl = SWITCHCTRL_SAFE;
}
@ -502,7 +532,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
#ifdef 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" // IWYU pragma: keep
#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
#ifdef 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 {
#ifdef 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;
#ifdef 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;
#ifdef 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

@ -35,16 +35,14 @@
#include <stdint.h>
#include <string.h>
#if defined(PRALINE)
#include <libopencm3/lpc43xx/scu.h>
#endif
#include "delay.h"
#include "fixed_point.h"
#include "platform_detect.h"
#include "rffc5071.h"
#include "rffc5071_regs.def" // private register def macros
#include "selftest.h"
#if defined(PRALINE)
#ifdef IS_PRALINE
#include <libopencm3/lpc43xx/scu.h>
#include "platform_scu.h"
#endif
@ -112,11 +110,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);
#ifdef 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);
@ -135,9 +135,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);
#ifdef IS_H1_OR_PRALINE
if (IS_H1_OR_PRALINE) {
set_RFFC5071_LOCK(drv, 1);
}
#endif
/* Enable reference oscillator standby */
@ -181,13 +182,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);
#ifdef IS_PRALINE
if (IS_PRALINE) {
return gpio_read(drv->gpio_ld);
}
#endif
#ifdef 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)
@ -360,9 +367,19 @@ void rffc5071_set_gpo(rffc5071_driver_t* const drv, uint8_t gpo)
rffc5071_regs_commit(drv);
}
#ifdef PRALINE
#ifdef 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.
#ifdef 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

@ -27,6 +27,7 @@
#include "fixed_point.h"
#include "gpio.h"
#include "platform_detect.h" // IWYU pragma: keep
#include "spi_bus.h"
/* 31 registers, each containing 16 bits of data. */
@ -35,7 +36,7 @@
typedef struct {
spi_bus_t* const bus;
gpio_t gpio_reset;
#ifdef PRALINE
#ifdef IS_PRALINE
gpio_t gpio_ld;
#endif
uint16_t regs[RFFC5071_NUM_REGS];
@ -70,7 +71,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
#ifdef 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" // IWYU pragma: keep
#define NUM_LOCK_ATTEMPTS 3
enum {
@ -37,23 +39,22 @@ typedef uint8_t test_result_t;
typedef struct {
uint16_t mixer_id;
#ifndef RAD1O
#ifdef IS_NOT_RAD1O
bool mixer_locks[NUM_LOCK_ATTEMPTS];
#endif
#ifdef PRALINE
#ifdef 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
#ifdef 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)
#ifdef IS_H1_R9
if (IS_H1_R9) {
scu_pinmux(
scu->H1R9_TRIGGER_EN,
SCU_GPIO_FAST | SCU_CONF_FUNCTION4); /* GPIO5[5] */
}
#endif
} else {
#ifdef 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);
#ifdef 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" // IWYU pragma: keep
typedef enum {
SGPIO_DIRECTION_RX,
@ -34,7 +35,7 @@ typedef enum {
typedef struct {
gpio_t gpio_q_invert;
#ifndef PRALINE
#ifdef 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)
#ifdef 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) {
#ifdef 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
#ifdef 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;
#ifdef 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;
#ifdef 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. */
#ifdef 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) {
#ifdef 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)
#ifdef 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 {
#ifdef 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) {
#ifdef 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"
#ifdef IS_PRALINE
#include "fpga.h"
typedef struct {

View file

@ -29,36 +29,46 @@
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#ifdef PRALINE
#define MIN_BYPASS_FREQ FP_MHZ(2320)
#define MAX_BYPASS_FREQ FP_MHZ(2580)
#else
#define MIN_BYPASS_FREQ FP_MHZ(2170)
#define MAX_BYPASS_FREQ FP_MHZ(2740)
#endif
#define MID1_HP_FREQ FP_MHZ(3600)
#define MID2_HP_FREQ FP_MHZ(5100)
#define MAX_HP_FREQ FP_MHZ(7250)
static fp_40_24_t min_bypass_freq = FP_MHZ(2170);
static fp_40_24_t max_bypass_freq = FP_MHZ(2740);
void tuning_setup(void)
{
#ifdef IS_PRALINE
if (IS_PRALINE) {
min_bypass_freq = FP_MHZ(2320);
max_bypass_freq = FP_MHZ(2580);
}
#endif
}
fp_40_24_t select_graduated_if(fp_40_24_t freq_rf, rf_path_filter_t img_reject)
{
fp_40_24_t freq_if;
switch (img_reject) {
case RF_PATH_FILTER_LOW_PASS:
if (detected_platform() == BOARD_ID_RAD1O) {
#ifdef IS_RAD1O
if (IS_RAD1O) {
freq_if = FP_MHZ(2300);
} else {
}
#endif
#ifdef IS_NOT_RAD1O
if (IS_NOT_RAD1O) {
/* IF is graduated from 2650 MHz to 2340 MHz */
freq_if = FP_MHZ(2650) - (freq_rf / 7);
}
#endif
break;
case RF_PATH_FILTER_HIGH_PASS:
if (freq_rf < MID1_HP_FREQ) {
/* IF is graduated from 2170 MHz to 2740 MHz */
freq_if = MIN_BYPASS_FREQ +
(((freq_rf - (MAX_BYPASS_FREQ)) * 57) / 86);
freq_if = min_bypass_freq +
(((freq_rf - (max_bypass_freq)) * 57) / 86);
} else if (freq_rf < MID2_HP_FREQ) {
/* IF is graduated from 2350 MHz to 2650 MHz */
freq_if = FP_MHZ(2350) + ((freq_rf - (MID1_HP_FREQ)) / 5);
@ -75,9 +85,9 @@ fp_40_24_t select_graduated_if(fp_40_24_t freq_rf, rf_path_filter_t img_reject)
rf_path_filter_t select_img_reject(fp_40_24_t freq_rf)
{
if (freq_rf > MAX_BYPASS_FREQ) {
if (freq_rf > max_bypass_freq) {
return RF_PATH_FILTER_HIGH_PASS;
} else if (freq_rf >= MIN_BYPASS_FREQ) {
} else if (freq_rf >= min_bypass_freq) {
return RF_PATH_FILTER_BYPASS;
} else {
return RF_PATH_FILTER_LOW_PASS;
@ -91,14 +101,14 @@ fp_40_24_t restrict_rf(fp_40_24_t freq_rf, rf_path_filter_t img_reject)
switch (img_reject) {
case RF_PATH_FILTER_LOW_PASS:
max_rf = MIN_BYPASS_FREQ;
max_rf = min_bypass_freq;
break;
case RF_PATH_FILTER_HIGH_PASS:
min_rf = MAX_BYPASS_FREQ;
min_rf = max_bypass_freq;
break;
default:
min_rf = MIN_BYPASS_FREQ;
max_rf = MAX_BYPASS_FREQ;
min_rf = min_bypass_freq;
max_rf = max_bypass_freq;
}
freq_rf = MIN(freq_rf, max_rf);
freq_rf = MAX(freq_rf, min_rf);

View file

@ -26,6 +26,8 @@
#include "fixed_point.h"
#include "rf_path.h"
void tuning_setup(void);
/**
* Select fixed or graduated IF for a given RF and image reject filter.
*/

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)
#ifdef IS_EXPANSION_COMPATIBLE
#include <portapack.h>
#endif
#if defined(PRALINE) || defined(HACKRF_ONE) || defined(JAWBREAKER)
#ifdef IS_NOT_RAD1O
#include <mixer.h>
#include <rffc5071.h>
#endif
#if defined(PRALINE)
#ifdef 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
#ifdef 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)
#ifdef IS_PRALINE
#include "usb_api_praline.h"
#else
#endif
#ifdef 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
#ifdef 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
#ifdef 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
#ifdef 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
#ifdef 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();
#ifdef 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);
#ifdef IS_NOT_PRALINE
if (IS_NOT_PRALINE) {
enable_1v8_power();
#ifdef 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();
#ifdef 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();
#ifdef IS_H1_OR_RAD1O
if (IS_H1_OR_RAD1O) {
enable_rf_power();
}
#endif
#ifdef 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);
#ifdef IS_NOT_PRALINE
if (IS_NOT_PRALINE) {
if (!cpld_jtag_sram_load(&jtag_cpld)) {
halt_and_flash(6000000);
}
}
#else
#endif
#ifdef 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();
#ifdef 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();
#ifdef IS_HACKRF_ONE
if (IS_HACKRF_ONE) {
memcpy(&usb_device,
&usb_device_hackrf_one,
sizeof(usb_device_hackrf_one));
}
#endif
#ifdef IS_JAWBREAKER
if (IS_JAWBREAKER) {
memcpy(&usb_device,
&usb_device_jawbreaker,
sizeof(usb_device_jawbreaker));
}
#endif
#ifdef IS_RAD1O
if (IS_RAD1O) {
memcpy(&usb_device, &usb_device_rad1o, sizeof(usb_device_rad1o));
}
#endif
#ifdef 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);
#ifdef IS_NOT_RAD1O
rffc5071_lock_test(&mixer.rffc5071);
#endif
#ifdef PRALINE
fpga_if_xcvr_selftest();
#ifdef 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;
#ifdef 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
#ifdef 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) {
#ifdef 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)
#ifdef IS_PRALINE
#include <fpga.h>
#endif
#ifdef 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;
}
#ifdef IS_RAD1O
if (IS_RAD1O) {
(void) endpoint;
(void) stage;
return USB_REQUEST_STATUS_STALL;
} else {
}
#endif
#ifdef 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;
}
#ifdef IS_RAD1O
if (IS_RAD1O) {
(void) endpoint;
(void) stage;
return USB_REQUEST_STATUS_STALL;
} else {
}
#endif
#ifdef 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
#ifdef 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);
#ifdef 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);
#ifdef 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" // IWYU pragma: keep
#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
#ifdef 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"
#ifdef 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
#ifdef 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));
#ifdef 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
#ifdef 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));
#ifdef 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
#ifdef IS_NOT_PRALINE
if (IS_NOT_PRALINE) {
append(&s, &c, "Transceiver: ");
#ifdef IS_H1_R9
if (IS_H1_R9) {
append(&s, &c, "MAX2839");
}
#endif
#ifdef 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
#ifdef 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
#ifdef 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
#ifdef 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
#ifdef 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
#ifdef 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
#ifdef 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
#ifdef 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[] = {
#ifdef 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
#ifdef 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
#ifdef 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
#ifdef 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
#ifdef IS_JAWBREAKER
extern uint8_t usb_descriptor_device_jawbreaker[];
#endif
#ifdef 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[];
#ifdef IS_HACKRF_ONE
extern uint8_t usb_descriptor_string_product_hackrf_one[];
#endif
#ifdef IS_PRALINE
extern uint8_t usb_descriptor_string_product_praline[];
#endif
#ifdef IS_JAWBREAKER
extern uint8_t usb_descriptor_string_product_jawbreaker[];
#endif
#ifdef 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;
#ifdef 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
#ifdef 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
#ifdef 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
#ifdef 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;
#ifdef IS_HACKRF_ONE
extern const usb_device_t usb_device_hackrf_one;
#endif
#ifdef IS_PRALINE
extern const usb_device_t usb_device_praline;
#endif
#ifdef IS_JAWBREAKER
extern const usb_device_t usb_device_jawbreaker;
#endif
#ifdef IS_RAD1O
extern const usb_device_t usb_device_rad1o;
#endif