Reformat all code to new clang-format standard.

This commit is contained in:
Martin Ling
2022-07-06 12:50:08 +01:00
parent 7d6a524795
commit c3fdf402d7
122 changed files with 6113 additions and 4930 deletions

View File

@ -21,7 +21,10 @@
#include "bitband.h" #include "bitband.h"
volatile uint32_t* peripheral_bitband_address(volatile void* const address, const uint_fast8_t bit_number) { volatile uint32_t* peripheral_bitband_address(
volatile void* const address,
const uint_fast8_t bit_number)
{
const uint32_t bit_band_base = 0x42000000; const uint32_t bit_band_base = 0x42000000;
const uint32_t byte_offset = (uint32_t) address - 0x40000000; const uint32_t byte_offset = (uint32_t) address - 0x40000000;
const uint32_t bit_word_offset = (byte_offset * 32) + (bit_number * 4); const uint32_t bit_word_offset = (byte_offset * 32) + (bit_number * 4);
@ -29,17 +32,29 @@ volatile uint32_t* peripheral_bitband_address(volatile void* const address, cons
return (volatile uint32_t*) bit_word_address; return (volatile uint32_t*) bit_word_address;
} }
void peripheral_bitband_set(volatile void* const peripheral_address, const uint_fast8_t bit_number) { void peripheral_bitband_set(
volatile uint32_t* const bitband_address = peripheral_bitband_address(peripheral_address, bit_number); volatile void* const peripheral_address,
const uint_fast8_t bit_number)
{
volatile uint32_t* const bitband_address =
peripheral_bitband_address(peripheral_address, bit_number);
*bitband_address = 1; *bitband_address = 1;
} }
void peripheral_bitband_clear(volatile void* const peripheral_address, const uint_fast8_t bit_number) { void peripheral_bitband_clear(
volatile uint32_t* const bitband_address = peripheral_bitband_address(peripheral_address, bit_number); volatile void* const peripheral_address,
const uint_fast8_t bit_number)
{
volatile uint32_t* const bitband_address =
peripheral_bitband_address(peripheral_address, bit_number);
*bitband_address = 0; *bitband_address = 0;
} }
uint32_t peripheral_bitband_get(volatile void* const peripheral_address, const uint_fast8_t bit_number) { uint32_t peripheral_bitband_get(
volatile uint32_t* const bitband_address = peripheral_bitband_address(peripheral_address, bit_number); volatile void* const peripheral_address,
const uint_fast8_t bit_number)
{
volatile uint32_t* const bitband_address =
peripheral_bitband_address(peripheral_address, bit_number);
return *bitband_address; return *bitband_address;
} }

View File

@ -24,9 +24,17 @@
#include <stdint.h> #include <stdint.h>
volatile uint32_t* peripheral_bitband_address(volatile void* const address, const uint_fast8_t bit_number); volatile uint32_t* peripheral_bitband_address(
void peripheral_bitband_set(volatile void* const peripheral_address, const uint_fast8_t bit_number); volatile void* const address,
void peripheral_bitband_clear(volatile void* const peripheral_address, const uint_fast8_t bit_number); const uint_fast8_t bit_number);
uint32_t peripheral_bitband_get(volatile void* const peripheral_address, const uint_fast8_t bit_number); void peripheral_bitband_set(
volatile void* const peripheral_address,
const uint_fast8_t bit_number);
void peripheral_bitband_clear(
volatile void* const peripheral_address,
const uint_fast8_t bit_number);
uint32_t peripheral_bitband_get(
volatile void* const peripheral_address,
const uint_fast8_t bit_number);
#endif //__BITBAND_H__ #endif //__BITBAND_H__

View File

@ -29,7 +29,8 @@ static refill_buffer_cb refill_buffer;
static uint32_t xsvf_buffer_len, xsvf_pos; static uint32_t xsvf_buffer_len, xsvf_pos;
static unsigned char* xsvf_buffer; static unsigned char* xsvf_buffer;
void cpld_jtag_take(jtag_t* const jtag) { void cpld_jtag_take(jtag_t* const jtag)
{
const jtag_gpio_t* const gpio = jtag->gpio; const jtag_gpio_t* const gpio = jtag->gpio;
/* Set initial GPIO state to the voltages of the internal or external pull-ups/downs, /* Set initial GPIO state to the voltages of the internal or external pull-ups/downs,
@ -53,7 +54,8 @@ void cpld_jtag_take(jtag_t* const jtag) {
gpio_input(gpio->gpio_tdo); gpio_input(gpio->gpio_tdo);
} }
void cpld_jtag_release(jtag_t* const jtag) { void cpld_jtag_release(jtag_t* const jtag)
{
const jtag_gpio_t* const gpio = jtag->gpio; const jtag_gpio_t* const gpio = jtag->gpio;
/* Make all pins inputs when JTAG interface not active. /* Make all pins inputs when JTAG interface not active.
@ -75,8 +77,8 @@ int cpld_jtag_program(
jtag_t* const jtag, jtag_t* const jtag,
const uint32_t buffer_length, const uint32_t buffer_length,
unsigned char* const buffer, unsigned char* const buffer,
refill_buffer_cb refill refill_buffer_cb refill)
) { {
int error; int error;
cpld_jtag_take(jtag); cpld_jtag_take(jtag);
xsvf_buffer = buffer; xsvf_buffer = buffer;
@ -89,7 +91,8 @@ int cpld_jtag_program(
} }
/* this gets called by the XAPP058 code */ /* this gets called by the XAPP058 code */
unsigned char cpld_jtag_get_next_byte(void) { unsigned char cpld_jtag_get_next_byte(void)
{
if (xsvf_pos == xsvf_buffer_len) { if (xsvf_pos == xsvf_buffer_len) {
refill_buffer(); refill_buffer();
xsvf_pos = 0; xsvf_pos = 0;

View File

@ -55,8 +55,7 @@ int cpld_jtag_program(
jtag_t* const jtag, jtag_t* const jtag,
const uint32_t buffer_length, const uint32_t buffer_length,
unsigned char* const buffer, unsigned char* const buffer,
refill_buffer_cb refill refill_buffer_cb refill);
);
unsigned char cpld_jtag_get_next_byte(void); unsigned char cpld_jtag_get_next_byte(void);
#endif //__CPLD_JTAG_H__ #endif //__CPLD_JTAG_H__

View File

@ -53,9 +53,14 @@ typedef enum {
CPLD_XC2C_IR_STCTEST = 0b00010110, CPLD_XC2C_IR_STCTEST = 0b00010110,
CPLD_XC2C_IR_ISC_NOOP = 0b11100000, CPLD_XC2C_IR_ISC_NOOP = 0b11100000,
} cpld_xc2c_ir_t; } cpld_xc2c_ir_t;
// clang-format on // clang-format on
static bool cpld_xc2c_jtag_clock(const jtag_t* const jtag, const uint32_t tms, const uint32_t tdi) { static bool cpld_xc2c_jtag_clock(
const jtag_t* const jtag,
const uint32_t tms,
const uint32_t tdi)
{
// 8 ns TMS/TDI to TCK setup // 8 ns TMS/TDI to TCK setup
gpio_write(jtag->gpio->gpio_tdi, tdi); gpio_write(jtag->gpio->gpio_tdi, tdi);
gpio_write(jtag->gpio->gpio_tms, tms); gpio_write(jtag->gpio->gpio_tms, tms);
@ -90,27 +95,43 @@ static bool cpld_xc2c_jtag_clock(const jtag_t* const jtag, const uint32_t tms, c
return gpio_read(jtag->gpio->gpio_tdo); return gpio_read(jtag->gpio->gpio_tdo);
} }
static void cpld_xc2c_jtag_shift_ptr_tms(const jtag_t* const jtag, uint8_t* const tdi_tdo, const size_t start, const size_t end, const bool tms) { static void cpld_xc2c_jtag_shift_ptr_tms(
const jtag_t* const jtag,
uint8_t* const tdi_tdo,
const size_t start,
const size_t end,
const bool tms)
{
for (size_t i = start; i < end; i++) { for (size_t i = start; i < end; i++) {
const size_t byte_n = i >> 3; const size_t byte_n = i >> 3;
const size_t bit_n = i & 7; const size_t bit_n = i & 7;
const uint32_t mask = (1U << bit_n); const uint32_t mask = (1U << bit_n);
const uint32_t tdo = cpld_xc2c_jtag_clock(jtag, tms, tdi_tdo[byte_n] & mask) ? 1 : 0; const uint32_t tdo =
cpld_xc2c_jtag_clock(jtag, tms, tdi_tdo[byte_n] & mask) ? 1 : 0;
tdi_tdo[byte_n] &= ~mask; tdi_tdo[byte_n] &= ~mask;
tdi_tdo[byte_n] |= (tdo << bit_n); tdi_tdo[byte_n] |= (tdo << bit_n);
} }
} }
static void cpld_xc2c_jtag_shift_ptr(const jtag_t* const jtag, uint8_t* const tdi_tdo, const size_t count) { static void cpld_xc2c_jtag_shift_ptr(
const jtag_t* const jtag,
uint8_t* const tdi_tdo,
const size_t count)
{
if (count > 0) { if (count > 0) {
cpld_xc2c_jtag_shift_ptr_tms(jtag, tdi_tdo, 0, count - 1, false); cpld_xc2c_jtag_shift_ptr_tms(jtag, tdi_tdo, 0, count - 1, false);
cpld_xc2c_jtag_shift_ptr_tms(jtag, tdi_tdo, count - 1, count, true); cpld_xc2c_jtag_shift_ptr_tms(jtag, tdi_tdo, count - 1, count, true);
} }
} }
static uint32_t cpld_xc2c_jtag_shift_u32(const jtag_t* const jtag, const uint32_t tms, const uint32_t tdi, const size_t count) { static uint32_t cpld_xc2c_jtag_shift_u32(
const jtag_t* const jtag,
const uint32_t tms,
const uint32_t tdi,
const size_t count)
{
uint32_t tdo = 0; uint32_t tdo = 0;
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
@ -121,19 +142,26 @@ static uint32_t cpld_xc2c_jtag_shift_u32(const jtag_t* const jtag, const uint32_
return tdo; return tdo;
} }
static void cpld_xc2c_jtag_clocks(const jtag_t* const jtag, const size_t count) { static void cpld_xc2c_jtag_clocks(const jtag_t* const jtag, const size_t count)
{
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
cpld_xc2c_jtag_clock(jtag, 0, 0); cpld_xc2c_jtag_clock(jtag, 0, 0);
} }
} }
static void cpld_xc2c_jtag_pause(const jtag_t* const jtag, const size_t count) { static void cpld_xc2c_jtag_pause(const jtag_t* const jtag, const size_t count)
{
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
cpld_xc2c_jtag_clock(jtag, (i == (count - 1)), 0); cpld_xc2c_jtag_clock(jtag, (i == (count - 1)), 0);
} }
} }
static void cpld_xc2c_jtag_shift_dr_ir(const jtag_t* const jtag, uint8_t* const tdi_tdo, const size_t bit_count, const size_t pause_count) { static void cpld_xc2c_jtag_shift_dr_ir(
const jtag_t* const jtag,
uint8_t* const tdi_tdo,
const size_t bit_count,
const size_t pause_count)
{
/* Run-Test/Idle or Select-DR-Scan -> Shift-DR or Shift-IR */ /* Run-Test/Idle or Select-DR-Scan -> Shift-DR or Shift-IR */
cpld_xc2c_jtag_shift_u32(jtag, 0b001, 0b000, 3); cpld_xc2c_jtag_shift_u32(jtag, 0b001, 0b000, 3);
/* Shift-[DI]R -> Exit1-[DI]R */ /* Shift-[DI]R -> Exit1-[DI]R */
@ -148,11 +176,20 @@ static void cpld_xc2c_jtag_shift_dr_ir(const jtag_t* const jtag, uint8_t* const
cpld_xc2c_jtag_shift_u32(jtag, 0b01, 0, 2); cpld_xc2c_jtag_shift_u32(jtag, 0b01, 0, 2);
} }
static void cpld_xc2c_jtag_shift_dr(const jtag_t* const jtag, uint8_t* const tdi_tdo, const size_t bit_count, const size_t pause_count) { static void cpld_xc2c_jtag_shift_dr(
const jtag_t* const jtag,
uint8_t* const tdi_tdo,
const size_t bit_count,
const size_t pause_count)
{
cpld_xc2c_jtag_shift_dr_ir(jtag, tdi_tdo, bit_count, pause_count); cpld_xc2c_jtag_shift_dr_ir(jtag, tdi_tdo, bit_count, pause_count);
} }
static uint8_t cpld_xc2c_jtag_shift_ir_pause(const jtag_t* const jtag, const cpld_xc2c_ir_t ir, const size_t pause_count) { static uint8_t cpld_xc2c_jtag_shift_ir_pause(
const jtag_t* const jtag,
const cpld_xc2c_ir_t ir,
const size_t pause_count)
{
/* Run-Test/Idle -> Select-DR-Scan */ /* Run-Test/Idle -> Select-DR-Scan */
cpld_xc2c_jtag_shift_u32(jtag, 0b1, 0b0, 1); cpld_xc2c_jtag_shift_u32(jtag, 0b1, 0b0, 1);
uint8_t value = ir; uint8_t value = ir;
@ -160,17 +197,20 @@ static uint8_t cpld_xc2c_jtag_shift_ir_pause(const jtag_t* const jtag, const cpl
return value; return value;
} }
static uint8_t cpld_xc2c_jtag_shift_ir(const jtag_t* const jtag, const cpld_xc2c_ir_t ir) { static uint8_t cpld_xc2c_jtag_shift_ir(const jtag_t* const jtag, const cpld_xc2c_ir_t ir)
{
return cpld_xc2c_jtag_shift_ir_pause(jtag, ir, 0); return cpld_xc2c_jtag_shift_ir_pause(jtag, ir, 0);
} }
static void cpld_xc2c_jtag_reset(const jtag_t* const jtag) { static void cpld_xc2c_jtag_reset(const jtag_t* const jtag)
{
/* Five TMS=1 to reach Test-Logic-Reset from any point in the TAP state diagram. /* Five TMS=1 to reach Test-Logic-Reset from any point in the TAP state diagram.
*/ */
cpld_xc2c_jtag_shift_u32(jtag, 0b11111, 0, 5); cpld_xc2c_jtag_shift_u32(jtag, 0b11111, 0, 5);
} }
static void cpld_xc2c_jtag_reset_and_idle(const jtag_t* const jtag) { static void cpld_xc2c_jtag_reset_and_idle(const jtag_t* const jtag)
{
/* Five TMS=1 to reach Test-Logic-Reset from any point in the TAP state diagram. /* Five TMS=1 to reach Test-Logic-Reset from any point in the TAP state diagram.
* One TMS=0 to move from Test-Logic-Reset to Run-Test-Idle. * One TMS=0 to move from Test-Logic-Reset to Run-Test-Idle.
*/ */
@ -178,7 +218,8 @@ static void cpld_xc2c_jtag_reset_and_idle(const jtag_t* const jtag) {
cpld_xc2c_jtag_shift_u32(jtag, 0, 0, 1); cpld_xc2c_jtag_shift_u32(jtag, 0, 0, 1);
} }
static uint32_t cpld_xc2c_jtag_idcode(const jtag_t* const jtag) { static uint32_t cpld_xc2c_jtag_idcode(const jtag_t* const jtag)
{
/* Enter and end at Run-Test-Idle state. */ /* Enter and end at Run-Test-Idle state. */
cpld_xc2c_jtag_shift_ir(jtag, CPLD_XC2C_IR_IDCODE); cpld_xc2c_jtag_shift_ir(jtag, CPLD_XC2C_IR_IDCODE);
uint32_t result = 0; uint32_t result = 0;
@ -186,34 +227,41 @@ static uint32_t cpld_xc2c_jtag_idcode(const jtag_t* const jtag) {
return result; return result;
} }
static bool cpld_xc2c64a_jtag_idcode_ok(const jtag_t* const jtag) { static bool cpld_xc2c64a_jtag_idcode_ok(const jtag_t* const jtag)
{
return ((cpld_xc2c_jtag_idcode(jtag) ^ 0xf6e5f093) & 0x0fff8fff) == 0; return ((cpld_xc2c_jtag_idcode(jtag) ^ 0xf6e5f093) & 0x0fff8fff) == 0;
} }
static void cpld_xc2c_jtag_conld(const jtag_t* const jtag) { static void cpld_xc2c_jtag_conld(const jtag_t* const jtag)
{
cpld_xc2c_jtag_shift_ir(jtag, CPLD_XC2C_IR_ISC_DISABLE); cpld_xc2c_jtag_shift_ir(jtag, CPLD_XC2C_IR_ISC_DISABLE);
cpld_xc2c_jtag_clocks(jtag, 100); cpld_xc2c_jtag_clocks(jtag, 100);
} }
static void cpld_xc2c_jtag_enable(const jtag_t* const jtag) { static void cpld_xc2c_jtag_enable(const jtag_t* const jtag)
{
cpld_xc2c_jtag_shift_ir(jtag, CPLD_XC2C_IR_ISC_ENABLE); cpld_xc2c_jtag_shift_ir(jtag, CPLD_XC2C_IR_ISC_ENABLE);
cpld_xc2c_jtag_clocks(jtag, 800); cpld_xc2c_jtag_clocks(jtag, 800);
} }
static void cpld_xc2c_jtag_disable(const jtag_t* const jtag) { static void cpld_xc2c_jtag_disable(const jtag_t* const jtag)
{
cpld_xc2c_jtag_shift_ir(jtag, CPLD_XC2C_IR_ISC_DISABLE); cpld_xc2c_jtag_shift_ir(jtag, CPLD_XC2C_IR_ISC_DISABLE);
cpld_xc2c_jtag_clocks(jtag, 100); cpld_xc2c_jtag_clocks(jtag, 100);
} }
static void cpld_xc2c_jtag_sram_write(const jtag_t* const jtag) { static void cpld_xc2c_jtag_sram_write(const jtag_t* const jtag)
{
cpld_xc2c_jtag_shift_ir(jtag, CPLD_XC2C_IR_ISC_WRITE); cpld_xc2c_jtag_shift_ir(jtag, CPLD_XC2C_IR_ISC_WRITE);
} }
static void cpld_xc2c_jtag_sram_read(const jtag_t* const jtag) { static void cpld_xc2c_jtag_sram_read(const jtag_t* const jtag)
{
cpld_xc2c_jtag_shift_ir(jtag, CPLD_XC2C_IR_ISC_SRAM_READ); cpld_xc2c_jtag_shift_ir(jtag, CPLD_XC2C_IR_ISC_SRAM_READ);
} }
static uint32_t cpld_xc2c_jtag_bypass(const jtag_t* const jtag, const bool shift_dr) { static uint32_t cpld_xc2c_jtag_bypass(const jtag_t* const jtag, const bool shift_dr)
{
const uint8_t result = cpld_xc2c_jtag_shift_ir(jtag, CPLD_XC2C_IR_BYPASS); const uint8_t result = cpld_xc2c_jtag_shift_ir(jtag, CPLD_XC2C_IR_BYPASS);
if (shift_dr) { if (shift_dr) {
uint8_t dr = 0; uint8_t dr = 0;
@ -222,16 +270,19 @@ static uint32_t cpld_xc2c_jtag_bypass(const jtag_t* const jtag, const bool shift
return result; return result;
} }
static bool cpld_xc2c_jtag_read_write_protect(const jtag_t* const jtag) { static bool cpld_xc2c_jtag_read_write_protect(const jtag_t* const jtag)
{
/* Enter and end at Run-Test-Idle state. */ /* Enter and end at Run-Test-Idle state. */
return ((cpld_xc2c_jtag_bypass(jtag, false) ^ 0x01) & 0x03) == 0; return ((cpld_xc2c_jtag_bypass(jtag, false) ^ 0x01) & 0x03) == 0;
} }
static bool cpld_xc2c_jtag_is_done(const jtag_t* const jtag) { static bool cpld_xc2c_jtag_is_done(const jtag_t* const jtag)
{
return ((cpld_xc2c_jtag_bypass(jtag, false) ^ 0x05) & 0x07) == 0; return ((cpld_xc2c_jtag_bypass(jtag, false) ^ 0x05) & 0x07) == 0;
} }
static void cpld_xc2c_jtag_init_special(const jtag_t* const jtag) { static void cpld_xc2c_jtag_init_special(const jtag_t* const jtag)
{
cpld_xc2c_jtag_shift_ir(jtag, CPLD_XC2C_IR_ISC_INIT); cpld_xc2c_jtag_shift_ir(jtag, CPLD_XC2C_IR_ISC_INIT);
cpld_xc2c_jtag_clocks(jtag, 20); cpld_xc2c_jtag_clocks(jtag, 20);
/* Run-Test/Idle -> Shift-IR */ /* Run-Test/Idle -> Shift-IR */
@ -245,11 +296,16 @@ static void cpld_xc2c_jtag_init_special(const jtag_t* const jtag) {
cpld_xc2c_jtag_clocks(jtag, 800); cpld_xc2c_jtag_clocks(jtag, 800);
} }
static void cpld_xc2c_jtag_read(const jtag_t* const jtag) { static void cpld_xc2c_jtag_read(const jtag_t* const jtag)
{
cpld_xc2c_jtag_shift_ir_pause(jtag, CPLD_XC2C_IR_ISC_READ, 1); cpld_xc2c_jtag_shift_ir_pause(jtag, CPLD_XC2C_IR_ISC_READ, 1);
} }
static void cpld_xc2c64a_jtag_read_row(const jtag_t* const jtag, uint8_t address, uint8_t* const dr) { static void cpld_xc2c64a_jtag_read_row(
const jtag_t* const jtag,
uint8_t address,
uint8_t* const dr)
{
cpld_xc2c_jtag_shift_dr(jtag, &address, 7, 20); cpld_xc2c_jtag_shift_dr(jtag, &address, 7, 20);
cpld_xc2c_jtag_clocks(jtag, 100); cpld_xc2c_jtag_clocks(jtag, 100);
@ -264,13 +320,14 @@ static void cpld_xc2c64a_jtag_read_row(const jtag_t* const jtag, uint8_t address
bool cpld_xc2c64a_jtag_checksum( bool cpld_xc2c64a_jtag_checksum(
const jtag_t* const jtag, const jtag_t* const jtag,
const cpld_xc2c64a_verify_t* const verify, const cpld_xc2c64a_verify_t* const verify,
uint32_t* const crc_value uint32_t* const crc_value)
) { {
cpld_xc2c_jtag_reset_and_idle(jtag); cpld_xc2c_jtag_reset_and_idle(jtag);
if( cpld_xc2c64a_jtag_idcode_ok(jtag) && cpld_xc2c_jtag_read_write_protect(jtag) && if (cpld_xc2c64a_jtag_idcode_ok(jtag) &&
cpld_xc2c64a_jtag_idcode_ok(jtag) && cpld_xc2c_jtag_read_write_protect(jtag) ) { cpld_xc2c_jtag_read_write_protect(jtag) &&
cpld_xc2c64a_jtag_idcode_ok(jtag) &&
cpld_xc2c_jtag_read_write_protect(jtag)) {
cpld_xc2c_jtag_bypass(jtag, false); cpld_xc2c_jtag_bypass(jtag, false);
cpld_xc2c_jtag_enable(jtag); cpld_xc2c_jtag_enable(jtag);
@ -319,7 +376,11 @@ bool cpld_xc2c64a_jtag_checksum(
return false; return false;
} }
static void cpld_xc2c64a_jtag_sram_write_row(const jtag_t* const jtag, uint8_t address, const uint8_t* const data) { static void cpld_xc2c64a_jtag_sram_write_row(
const jtag_t* const jtag,
uint8_t address,
const uint8_t* const data)
{
uint8_t write[CPLD_XC2C64A_BYTES_IN_ROW]; uint8_t write[CPLD_XC2C64A_BYTES_IN_ROW];
memcpy(&write[0], data, sizeof(write)); memcpy(&write[0], data, sizeof(write));
@ -336,7 +397,11 @@ static void cpld_xc2c64a_jtag_sram_write_row(const jtag_t* const jtag, uint8_t a
cpld_xc2c_jtag_shift_u32(jtag, 0b01, 0b00, 2); cpld_xc2c_jtag_shift_u32(jtag, 0b01, 0b00, 2);
} }
static void cpld_xc2c64a_jtag_sram_read_row(const jtag_t* const jtag, uint8_t* const data, const uint8_t next_address) { static void cpld_xc2c64a_jtag_sram_read_row(
const jtag_t* const jtag,
uint8_t* const data,
const uint8_t next_address)
{
/* Run-Test/Idle -> Shift-DR */ /* Run-Test/Idle -> Shift-DR */
cpld_xc2c_jtag_shift_u32(jtag, 0b001, 0b000, 3); cpld_xc2c_jtag_shift_u32(jtag, 0b001, 0b000, 3);
@ -353,7 +418,12 @@ static void cpld_xc2c64a_jtag_sram_read_row(const jtag_t* const jtag, uint8_t* c
cpld_xc2c_jtag_shift_u32(jtag, 0b0110, 0b0000, 4); cpld_xc2c_jtag_shift_u32(jtag, 0b0110, 0b0000, 4);
} }
static bool cpld_xc2c64a_jtag_sram_compare_row(const jtag_t* const jtag, const uint8_t* const expected, const uint8_t* const mask, const uint8_t next_address) { static bool cpld_xc2c64a_jtag_sram_compare_row(
const jtag_t* const jtag,
const uint8_t* const expected,
const uint8_t* const mask,
const uint8_t next_address)
{
/* Run-Test/Idle -> Shift-DR */ /* Run-Test/Idle -> Shift-DR */
uint8_t read[CPLD_XC2C64A_BYTES_IN_ROW]; uint8_t read[CPLD_XC2C64A_BYTES_IN_ROW];
memset(read, 0xff, sizeof(read)); memset(read, 0xff, sizeof(read));
@ -362,7 +432,8 @@ static bool cpld_xc2c64a_jtag_sram_compare_row(const jtag_t* const jtag, const u
bool matched = true; bool matched = true;
if ((expected != NULL) && (mask != NULL)) { if ((expected != NULL) && (mask != NULL)) {
for (size_t i = 0; i < CPLD_XC2C64A_BYTES_IN_ROW; i++) { for (size_t i = 0; i < CPLD_XC2C64A_BYTES_IN_ROW; i++) {
const uint8_t significant_differences = (read[i] ^ expected[i]) & mask[i]; const uint8_t significant_differences =
(read[i] ^ expected[i]) & mask[i];
matched &= (significant_differences == 0); matched &= (significant_differences == 0);
} }
} }
@ -372,8 +443,8 @@ static bool cpld_xc2c64a_jtag_sram_compare_row(const jtag_t* const jtag, const u
void cpld_xc2c64a_jtag_sram_write( void cpld_xc2c64a_jtag_sram_write(
const jtag_t* const jtag, const jtag_t* const jtag,
const cpld_xc2c64a_program_t* const program const cpld_xc2c64a_program_t* const program)
) { {
cpld_xc2c_jtag_reset_and_idle(jtag); cpld_xc2c_jtag_reset_and_idle(jtag);
cpld_xc2c_jtag_enable(jtag); cpld_xc2c_jtag_enable(jtag);
@ -381,7 +452,10 @@ void cpld_xc2c64a_jtag_sram_write(
for (size_t row = 0; row < CPLD_XC2C64A_ROWS; row++) { for (size_t row = 0; row < CPLD_XC2C64A_ROWS; row++) {
const uint8_t address = cpld_hackrf_row_addresses.address[row]; const uint8_t address = cpld_hackrf_row_addresses.address[row];
cpld_xc2c64a_jtag_sram_write_row(jtag, address, &program->row[row].data[0]); cpld_xc2c64a_jtag_sram_write_row(
jtag,
address,
&program->row[row].data[0]);
} }
cpld_xc2c_jtag_disable(jtag); cpld_xc2c_jtag_disable(jtag);
@ -392,8 +466,8 @@ void cpld_xc2c64a_jtag_sram_write(
bool cpld_xc2c64a_jtag_sram_verify( bool cpld_xc2c64a_jtag_sram_verify(
const jtag_t* const jtag, const jtag_t* const jtag,
const cpld_xc2c64a_program_t* const program, const cpld_xc2c64a_program_t* const program,
const cpld_xc2c64a_verify_t* const verify const cpld_xc2c64a_verify_t* const verify)
) { {
cpld_xc2c_jtag_reset_and_idle(jtag); cpld_xc2c_jtag_reset_and_idle(jtag);
cpld_xc2c_jtag_enable(jtag); cpld_xc2c_jtag_enable(jtag);
@ -405,11 +479,20 @@ bool cpld_xc2c64a_jtag_sram_verify(
bool matched = true; bool matched = true;
for (size_t address_row = 0; address_row <= CPLD_XC2C64A_ROWS; address_row++) { for (size_t address_row = 0; address_row <= CPLD_XC2C64A_ROWS; address_row++) {
const int data_row = (int) address_row - 1; const int data_row = (int) address_row - 1;
const size_t mask_index = (data_row >= 0) ? verify->mask_index[data_row] : 0; const size_t mask_index =
const uint8_t* const expected = (data_row >= 0) ? &program->row[data_row].data[0] : NULL; (data_row >= 0) ? verify->mask_index[data_row] : 0;
const uint8_t* const mask = (data_row >= 0) ? &verify->mask[mask_index].value[0] : NULL; const uint8_t* const expected =
const uint8_t next_address = (address_row < CPLD_XC2C64A_ROWS) ? cpld_hackrf_row_addresses.address[address_row] : 0; (data_row >= 0) ? &program->row[data_row].data[0] : NULL;
matched &= cpld_xc2c64a_jtag_sram_compare_row(jtag, expected, mask, next_address); const uint8_t* const mask =
(data_row >= 0) ? &verify->mask[mask_index].value[0] : NULL;
const uint8_t next_address = (address_row < CPLD_XC2C64A_ROWS) ?
cpld_hackrf_row_addresses.address[address_row] :
0;
matched &= cpld_xc2c64a_jtag_sram_compare_row(
jtag,
expected,
mask,
next_address);
} }
cpld_xc2c_jtag_disable(jtag); cpld_xc2c_jtag_disable(jtag);

View File

@ -56,17 +56,14 @@ typedef struct {
bool cpld_xc2c64a_jtag_checksum( bool cpld_xc2c64a_jtag_checksum(
const jtag_t* const jtag, const jtag_t* const jtag,
const cpld_xc2c64a_verify_t* const verify, const cpld_xc2c64a_verify_t* const verify,
uint32_t* const crc_value uint32_t* const crc_value);
);
void cpld_xc2c64a_jtag_sram_write( void cpld_xc2c64a_jtag_sram_write(
const jtag_t* const jtag, const jtag_t* const jtag,
const cpld_xc2c64a_program_t* const program const cpld_xc2c64a_program_t* const program);
);
bool cpld_xc2c64a_jtag_sram_verify( bool cpld_xc2c64a_jtag_sram_verify(
const jtag_t* const jtag, const jtag_t* const jtag,
const cpld_xc2c64a_program_t* const program, const cpld_xc2c64a_program_t* const program,
const cpld_xc2c64a_verify_t* const verify const cpld_xc2c64a_verify_t* const verify);
);
extern const cpld_xc2c64a_program_t cpld_hackrf_program_sram; extern const cpld_xc2c64a_program_t cpld_hackrf_program_sram;
extern const cpld_xc2c64a_verify_t cpld_hackrf_verify; extern const cpld_xc2c64a_verify_t cpld_hackrf_verify;

View File

@ -23,13 +23,15 @@
#include <stdbool.h> #include <stdbool.h>
void crc32_init(crc32_t* const crc) { void crc32_init(crc32_t* const crc)
{
crc->remainder = 0xffffffff; crc->remainder = 0xffffffff;
crc->reversed_polynomial = 0xedb88320; crc->reversed_polynomial = 0xedb88320;
crc->final_xor = 0xffffffff; crc->final_xor = 0xffffffff;
} }
void crc32_update(crc32_t* const crc, const uint8_t* const data, const size_t byte_count) { void crc32_update(crc32_t* const crc, const uint8_t* const data, const size_t byte_count)
{
uint32_t remainder = crc->remainder; uint32_t remainder = crc->remainder;
const size_t bit_count = byte_count * 8; const size_t bit_count = byte_count * 8;
for (size_t bit_n = 0; bit_n < bit_count; bit_n++) { for (size_t bit_n = 0; bit_n < bit_count; bit_n++) {
@ -44,6 +46,7 @@ void crc32_update(crc32_t* const crc, const uint8_t* const data, const size_t by
crc->remainder = remainder; crc->remainder = remainder;
} }
uint32_t crc32_digest(const crc32_t* const crc) { uint32_t crc32_digest(const crc32_t* const crc)
{
return crc->remainder ^ crc->final_xor; return crc->remainder ^ crc->final_xor;
} }

View File

@ -24,8 +24,7 @@
#include "fault_handler.h" #include "fault_handler.h"
typedef struct typedef struct {
{
uint32_t r0; uint32_t r0;
uint32_t r1; uint32_t r1;
uint32_t r2; uint32_t r2;
@ -36,8 +35,8 @@ typedef struct
uint32_t psr; /* Program Status Register. */ uint32_t psr; /* Program Status Register. */
} hard_fault_stack_t; } hard_fault_stack_t;
__attribute__((naked)) __attribute__((naked)) void hard_fault_handler(void)
void hard_fault_handler(void) { {
__asm__("TST LR, #4"); __asm__("TST LR, #4");
__asm__("ITE EQ"); __asm__("ITE EQ");
__asm__("MRSEQ R0, MSP"); __asm__("MRSEQ R0, MSP");
@ -73,14 +72,17 @@ __attribute__((used)) void hard_fault_handler_c(uint32_t* args)
while (1) {} while (1) {}
} }
void mem_manage_handler() { void mem_manage_handler()
{
while (1) {} while (1) {}
} }
void bus_fault_handler() { void bus_fault_handler()
{
while (1) {} while (1) {}
} }
void usage_fault_handler() { void usage_fault_handler()
{
while (1) {} while (1) {}
} }

View File

@ -30,6 +30,7 @@
// structures are supposedly the same between processors (to an // structures are supposedly the same between processors (to an
// undetermined extent). // undetermined extent).
typedef struct armv7m_scb_t armv7m_scb_t; typedef struct armv7m_scb_t armv7m_scb_t;
struct armv7m_scb_t { struct armv7m_scb_t {
volatile const uint32_t CPUID; volatile const uint32_t CPUID;
volatile uint32_t ICSR; volatile uint32_t ICSR;

View File

@ -23,40 +23,49 @@
#include <libopencm3/lpc43xx/gpdma.h> #include <libopencm3/lpc43xx/gpdma.h>
void gpdma_controller_enable() { void gpdma_controller_enable()
{
GPDMA_CONFIG |= GPDMA_CONFIG_E(1); GPDMA_CONFIG |= GPDMA_CONFIG_E(1);
while ((GPDMA_CONFIG & GPDMA_CONFIG_E_MASK) == 0) {} while ((GPDMA_CONFIG & GPDMA_CONFIG_E_MASK) == 0) {}
} }
void gpdma_channel_enable(const uint_fast8_t channel) { void gpdma_channel_enable(const uint_fast8_t channel)
{
GPDMA_CCONFIG(channel) |= GPDMA_CCONFIG_E(1); GPDMA_CCONFIG(channel) |= GPDMA_CCONFIG_E(1);
} }
void gpdma_channel_disable(const uint_fast8_t channel) { void gpdma_channel_disable(const uint_fast8_t channel)
{
GPDMA_CCONFIG(channel) &= ~GPDMA_CCONFIG_E_MASK; GPDMA_CCONFIG(channel) &= ~GPDMA_CCONFIG_E_MASK;
while (GPDMA_ENBLDCHNS & GPDMA_ENBLDCHNS_ENABLEDCHANNELS(1 << channel)) {} while (GPDMA_ENBLDCHNS & GPDMA_ENBLDCHNS_ENABLEDCHANNELS(1 << channel)) {}
} }
void gpdma_channel_interrupt_tc_clear(const uint_fast8_t channel) { void gpdma_channel_interrupt_tc_clear(const uint_fast8_t channel)
{
GPDMA_INTTCCLEAR = GPDMA_INTTCCLEAR_INTTCCLEAR(1 << channel); GPDMA_INTTCCLEAR = GPDMA_INTTCCLEAR_INTTCCLEAR(1 << channel);
} }
void gpdma_channel_interrupt_error_clear(const uint_fast8_t channel) { void gpdma_channel_interrupt_error_clear(const uint_fast8_t channel)
{
GPDMA_INTERRCLR = GPDMA_INTERRCLR_INTERRCLR(1 << channel); GPDMA_INTERRCLR = GPDMA_INTERRCLR_INTERRCLR(1 << channel);
} }
void gpdma_lli_enable_interrupt(gpdma_lli_t* const lli) { void gpdma_lli_enable_interrupt(gpdma_lli_t* const lli)
{
lli->ccontrol |= GPDMA_CCONTROL_I(1); lli->ccontrol |= GPDMA_CCONTROL_I(1);
} }
void gpdma_lli_create_loop(gpdma_lli_t* const lli, const size_t lli_count) { void gpdma_lli_create_loop(gpdma_lli_t* const lli, const size_t lli_count)
{
for (size_t i = 0; i < lli_count; i++) { for (size_t i = 0; i < lli_count; i++) {
gpdma_lli_t* const next_lli = &lli[(i + 1) % lli_count]; gpdma_lli_t* const next_lli = &lli[(i + 1) % lli_count];
lli[i].clli = (lli[i].clli & ~GPDMA_CLLI_LLI_MASK) | GPDMA_CLLI_LLI((uint32_t)next_lli >> 2); lli[i].clli = (lli[i].clli & ~GPDMA_CLLI_LLI_MASK) |
GPDMA_CLLI_LLI((uint32_t) next_lli >> 2);
} }
} }
void gpdma_lli_create_oneshot(gpdma_lli_t* const lli, const size_t lli_count) { void gpdma_lli_create_oneshot(gpdma_lli_t* const lli, const size_t lli_count)
{
gpdma_lli_create_loop(lli, lli_count); gpdma_lli_create_loop(lli, lli_count);
lli[lli_count - 1].clli &= ~GPDMA_CLLI_LLI_MASK; lli[lli_count - 1].clli &= ~GPDMA_CLLI_LLI_MASK;
} }

View File

@ -23,36 +23,44 @@
#include <stddef.h> #include <stddef.h>
void gpio_init() { void gpio_init()
{
for (size_t i = 0; i < 8; i++) { for (size_t i = 0; i < 8; i++) {
GPIO_LPC_PORT(i)->dir = 0; GPIO_LPC_PORT(i)->dir = 0;
} }
} }
void gpio_set(gpio_t gpio) { void gpio_set(gpio_t gpio)
{
gpio->port->set = gpio->mask; gpio->port->set = gpio->mask;
} }
void gpio_clear(gpio_t gpio) { void gpio_clear(gpio_t gpio)
{
gpio->port->clr = gpio->mask; gpio->port->clr = gpio->mask;
} }
void gpio_toggle(gpio_t gpio) { void gpio_toggle(gpio_t gpio)
{
gpio->port->not = gpio->mask; gpio->port->not = gpio->mask;
} }
void gpio_output(gpio_t gpio) { void gpio_output(gpio_t gpio)
{
gpio->port->dir |= gpio->mask; gpio->port->dir |= gpio->mask;
} }
void gpio_input(gpio_t gpio) { void gpio_input(gpio_t gpio)
{
gpio->port->dir &= ~gpio->mask; gpio->port->dir &= ~gpio->mask;
} }
void gpio_write(gpio_t gpio, const bool value) { void gpio_write(gpio_t gpio, const bool value)
{
*gpio->gpio_w = value; *gpio->gpio_w = value;
} }
bool gpio_read(gpio_t gpio) { bool gpio_read(gpio_t gpio)
{
return *gpio->gpio_w; return *gpio->gpio_w;
} }

View File

@ -58,8 +58,10 @@ struct gpio_t {
#define GPIO_LPC_W_OFFSET (0x1000) #define GPIO_LPC_W_OFFSET (0x1000)
#define GPIO_LPC_PORT_OFFSET (0x2000) #define GPIO_LPC_PORT_OFFSET (0x2000)
#define GPIO_LPC_PORT(_n) ((gpio_port_t*)((GPIO_LPC_BASE + GPIO_LPC_PORT_OFFSET) + (_n) * 4)) #define GPIO_LPC_PORT(_n) \
#define GPIO_LPC_W(_port_num, _pin_num) (volatile uint32_t*)((GPIO_LPC_BASE + GPIO_LPC_W_OFFSET) + ((_port_num) * 0x80) + ((_pin_num) * 4)) ((gpio_port_t*) ((GPIO_LPC_BASE + GPIO_LPC_PORT_OFFSET) + (_n) *4))
#define GPIO_LPC_W(_port_num, _pin_num) \
(volatile uint32_t*) ((GPIO_LPC_BASE + GPIO_LPC_W_OFFSET) + ((_port_num) *0x80) + ((_pin_num) *4))
// clang-format off // clang-format off
#define GPIO(_port_num, _pin_num) { \ #define GPIO(_port_num, _pin_num) { \

View File

@ -304,19 +304,16 @@ void delay_us_at_mhz(uint32_t us, uint32_t mhz)
{ {
// The loop below takes 4 cycles per iteration. // The loop below takes 4 cycles per iteration.
uint32_t loop_iterations = (us * mhz) / 4; uint32_t loop_iterations = (us * mhz) / 4;
asm volatile ( asm volatile("start%=:\n"
"start%=:\n"
" subs %[ITERATIONS], #1\n" // 1 cycle " subs %[ITERATIONS], #1\n" // 1 cycle
" bpl start%=\n" // 3 cycles " bpl start%=\n" // 3 cycles
: :
: [ITERATIONS] "r" (loop_iterations) : [ITERATIONS] "r"(loop_iterations));
);
} }
/* GCD algo from wikipedia */ /* GCD algo from wikipedia */
/* http://en.wikipedia.org/wiki/Greatest_common_divisor */ /* http://en.wikipedia.org/wiki/Greatest_common_divisor */
static uint32_t static uint32_t gcd(uint32_t u, uint32_t v)
gcd(uint32_t u, uint32_t v)
{ {
int s; int s;
@ -343,8 +340,7 @@ gcd(uint32_t u, uint32_t v)
} }
v = v - u; v = v - u;
} } while (v);
while (v);
return u << s; return u << s;
} }
@ -421,7 +417,8 @@ bool sample_rate_frac_set(uint32_t rate_num, uint32_t rate_denom)
return true; return true;
} }
bool sample_rate_set(const uint32_t sample_rate_hz) { bool sample_rate_set(const uint32_t sample_rate_hz)
{
uint32_t p1 = 4608; uint32_t p1 = 4608;
uint32_t p2 = 0; uint32_t p2 = 0;
uint32_t p3 = 0; uint32_t p3 = 0;
@ -484,10 +481,12 @@ bool sample_rate_set(const uint32_t sample_rate_hz) {
return true; return true;
} }
bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz) { bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz)
{
uint32_t bandwidth_hz_real = max2837_set_lpf_bandwidth(&max2837, bandwidth_hz); uint32_t bandwidth_hz_real = max2837_set_lpf_bandwidth(&max2837, bandwidth_hz);
if(bandwidth_hz_real) hackrf_ui()->set_filter_bw(bandwidth_hz_real); if (bandwidth_hz_real)
hackrf_ui()->set_filter_bw(bandwidth_hz_real);
return bandwidth_hz_real != 0; return bandwidth_hz_real != 0;
} }
@ -507,8 +506,7 @@ static void cpu_clock_pll1_max_speed(void)
/* 1. Select the IRC as BASE_M4_CLK source. */ /* 1. Select the IRC as BASE_M4_CLK source. */
reg_val = CGU_BASE_M4_CLK; reg_val = CGU_BASE_M4_CLK;
reg_val &= ~CGU_BASE_M4_CLK_CLK_SEL_MASK; reg_val &= ~CGU_BASE_M4_CLK_CLK_SEL_MASK;
reg_val |= CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_IRC) | reg_val |= CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_IRC) | CGU_BASE_M4_CLK_AUTOBLOCK(1);
CGU_BASE_M4_CLK_AUTOBLOCK(1);
CGU_BASE_M4_CLK = reg_val; CGU_BASE_M4_CLK = reg_val;
/* 2. Enable the crystal oscillator. */ /* 2. Enable the crystal oscillator. */
@ -595,9 +593,21 @@ void cpu_clock_init(void)
*/ */
/* MS4/CLK4 is the source for the RFFC5071 mixer (MAX2837 on rad1o). */ /* MS4/CLK4 is the source for the RFFC5071 mixer (MAX2837 on rad1o). */
si5351c_configure_multisynth(&clock_gen, 4, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */ si5351c_configure_multisynth(
&clock_gen,
4,
20 * 128 - 512,
0,
1,
0); /* 800/20 = 40MHz */
/* MS5/CLK5 is the source for the MAX2837 clock input (MAX2871 on rad1o). */ /* MS5/CLK5 is the source for the MAX2837 clock input (MAX2871 on rad1o). */
si5351c_configure_multisynth(&clock_gen, 5, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */ si5351c_configure_multisynth(
&clock_gen,
5,
20 * 128 - 512,
0,
1,
0); /* 800/20 = 40MHz */
/* MS6/CLK6 is unused. */ /* MS6/CLK6 is unused. */
/* MS7/CLK7 is unused. */ /* MS7/CLK7 is unused. */
@ -628,53 +638,51 @@ void cpu_clock_init(void)
cpu_clock_pll1_max_speed(); cpu_clock_pll1_max_speed();
/* use XTAL_OSC as clock source for APB1 */ /* use XTAL_OSC as clock source for APB1 */
CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_AUTOBLOCK(1) CGU_BASE_APB1_CLK =
| CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_XTAL); CGU_BASE_APB1_CLK_AUTOBLOCK(1) | CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_XTAL);
/* use XTAL_OSC as clock source for APB3 */ /* use XTAL_OSC as clock source for APB3 */
CGU_BASE_APB3_CLK = CGU_BASE_APB3_CLK_AUTOBLOCK(1) CGU_BASE_APB3_CLK =
| CGU_BASE_APB3_CLK_CLK_SEL(CGU_SRC_XTAL); CGU_BASE_APB3_CLK_AUTOBLOCK(1) | CGU_BASE_APB3_CLK_CLK_SEL(CGU_SRC_XTAL);
/* use XTAL_OSC as clock source for PLL0USB */ /* use XTAL_OSC as clock source for PLL0USB */
CGU_PLL0USB_CTRL = CGU_PLL0USB_CTRL_PD(1) CGU_PLL0USB_CTRL = CGU_PLL0USB_CTRL_PD(1) | CGU_PLL0USB_CTRL_AUTOBLOCK(1) |
| CGU_PLL0USB_CTRL_AUTOBLOCK(1) CGU_PLL0USB_CTRL_CLK_SEL(CGU_SRC_XTAL);
| CGU_PLL0USB_CTRL_CLK_SEL(CGU_SRC_XTAL);
while (CGU_PLL0USB_STAT & CGU_PLL0USB_STAT_LOCK_MASK) {} while (CGU_PLL0USB_STAT & CGU_PLL0USB_STAT_LOCK_MASK) {}
/* configure PLL0USB to produce 480 MHz clock from 12 MHz XTAL_OSC */ /* configure PLL0USB to produce 480 MHz clock from 12 MHz XTAL_OSC */
/* Values from User Manual v1.4 Table 94, for 12MHz oscillator. */ /* Values from User Manual v1.4 Table 94, for 12MHz oscillator. */
CGU_PLL0USB_MDIV = 0x06167FFA; CGU_PLL0USB_MDIV = 0x06167FFA;
CGU_PLL0USB_NP_DIV = 0x00302062; CGU_PLL0USB_NP_DIV = 0x00302062;
CGU_PLL0USB_CTRL |= (CGU_PLL0USB_CTRL_PD(1) CGU_PLL0USB_CTRL |=
| CGU_PLL0USB_CTRL_DIRECTI(1) (CGU_PLL0USB_CTRL_PD(1) | CGU_PLL0USB_CTRL_DIRECTI(1) |
| CGU_PLL0USB_CTRL_DIRECTO(1) CGU_PLL0USB_CTRL_DIRECTO(1) | CGU_PLL0USB_CTRL_CLKEN(1));
| CGU_PLL0USB_CTRL_CLKEN(1));
/* power on PLL0USB and wait until stable */ /* power on PLL0USB and wait until stable */
CGU_PLL0USB_CTRL &= ~CGU_PLL0USB_CTRL_PD_MASK; CGU_PLL0USB_CTRL &= ~CGU_PLL0USB_CTRL_PD_MASK;
while (!(CGU_PLL0USB_STAT & CGU_PLL0USB_STAT_LOCK_MASK)) {} while (!(CGU_PLL0USB_STAT & CGU_PLL0USB_STAT_LOCK_MASK)) {}
/* use PLL0USB as clock source for USB0 */ /* use PLL0USB as clock source for USB0 */
CGU_BASE_USB0_CLK = CGU_BASE_USB0_CLK_AUTOBLOCK(1) CGU_BASE_USB0_CLK = CGU_BASE_USB0_CLK_AUTOBLOCK(1) |
| CGU_BASE_USB0_CLK_CLK_SEL(CGU_SRC_PLL0USB); CGU_BASE_USB0_CLK_CLK_SEL(CGU_SRC_PLL0USB);
/* Switch peripheral clock over to use PLL1 (204MHz) */ /* Switch peripheral clock over to use PLL1 (204MHz) */
CGU_BASE_PERIPH_CLK = CGU_BASE_PERIPH_CLK_AUTOBLOCK(1) CGU_BASE_PERIPH_CLK = CGU_BASE_PERIPH_CLK_AUTOBLOCK(1) |
| CGU_BASE_PERIPH_CLK_CLK_SEL(CGU_SRC_PLL1); CGU_BASE_PERIPH_CLK_CLK_SEL(CGU_SRC_PLL1);
/* Switch APB1 clock over to use PLL1 (204MHz) */ /* Switch APB1 clock over to use PLL1 (204MHz) */
CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_AUTOBLOCK(1) CGU_BASE_APB1_CLK =
| CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_PLL1); CGU_BASE_APB1_CLK_AUTOBLOCK(1) | CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_PLL1);
/* Switch APB3 clock over to use PLL1 (204MHz) */ /* Switch APB3 clock over to use PLL1 (204MHz) */
CGU_BASE_APB3_CLK = CGU_BASE_APB3_CLK_AUTOBLOCK(1) CGU_BASE_APB3_CLK =
| CGU_BASE_APB3_CLK_CLK_SEL(CGU_SRC_PLL1); CGU_BASE_APB3_CLK_AUTOBLOCK(1) | CGU_BASE_APB3_CLK_CLK_SEL(CGU_SRC_PLL1);
CGU_BASE_SSP0_CLK = CGU_BASE_SSP0_CLK_AUTOBLOCK(1) CGU_BASE_SSP0_CLK =
| CGU_BASE_SSP0_CLK_CLK_SEL(CGU_SRC_PLL1); CGU_BASE_SSP0_CLK_AUTOBLOCK(1) | CGU_BASE_SSP0_CLK_CLK_SEL(CGU_SRC_PLL1);
CGU_BASE_SSP1_CLK = CGU_BASE_SSP1_CLK_AUTOBLOCK(1) CGU_BASE_SSP1_CLK =
| CGU_BASE_SSP1_CLK_CLK_SEL(CGU_SRC_PLL1); CGU_BASE_SSP1_CLK_AUTOBLOCK(1) | CGU_BASE_SSP1_CLK_CLK_SEL(CGU_SRC_PLL1);
#if (defined JAWBREAKER || defined HACKRF_ONE) #if (defined JAWBREAKER || defined HACKRF_ONE)
/* Disable unused clocks */ /* Disable unused clocks */
@ -775,7 +783,9 @@ clock_source_t activate_best_clock_source(void)
/* No external or PortaPack clock was found. Use HackRF Si5351C crystal. */ /* No external or PortaPack clock was found. Use HackRF Si5351C crystal. */
} }
si5351c_set_clock_source(&clock_gen, (source == CLOCK_SOURCE_HACKRF) ? PLL_SOURCE_XTAL : PLL_SOURCE_CLKIN); si5351c_set_clock_source(
&clock_gen,
(source == CLOCK_SOURCE_HACKRF) ? PLL_SOURCE_XTAL : PLL_SOURCE_CLKIN);
hackrf_ui()->set_clock_source(source); hackrf_ui()->set_clock_source(source);
return source; return source;
} }
@ -790,7 +800,8 @@ void ssp1_set_mode_max5864(void)
spi_bus_start(max5864.bus, &ssp_config_max5864); spi_bus_start(max5864.bus, &ssp_config_max5864);
} }
void pin_setup(void) { void pin_setup(void)
{
/* Configure all GPIO as Input (safe state) */ /* Configure all GPIO as Input (safe state) */
gpio_init(); gpio_init();
@ -881,16 +892,19 @@ void pin_setup(void) {
sgpio_configure_pin_functions(&sgpio_config); sgpio_configure_pin_functions(&sgpio_config);
} }
void enable_1v8_power(void) { void enable_1v8_power(void)
{
gpio_set(&gpio_1v8_enable); gpio_set(&gpio_1v8_enable);
} }
void disable_1v8_power(void) { void disable_1v8_power(void)
{
gpio_clear(&gpio_1v8_enable); gpio_clear(&gpio_1v8_enable);
} }
#ifdef HACKRF_ONE #ifdef HACKRF_ONE
void enable_rf_power(void) { void enable_rf_power(void)
{
uint32_t i; uint32_t i;
/* many short pulses to avoid one big voltage glitch */ /* many short pulses to avoid one big voltage glitch */
@ -901,41 +915,48 @@ void enable_rf_power(void) {
gpio_clear(&gpio_vaa_disable); gpio_clear(&gpio_vaa_disable);
} }
void disable_rf_power(void) { void disable_rf_power(void)
{
gpio_set(&gpio_vaa_disable); gpio_set(&gpio_vaa_disable);
} }
#endif #endif
#ifdef RAD1O #ifdef RAD1O
void enable_rf_power(void) { void enable_rf_power(void)
{
gpio_set(&gpio_vaa_enable); gpio_set(&gpio_vaa_enable);
} }
void disable_rf_power(void) { void disable_rf_power(void)
{
gpio_clear(&gpio_vaa_enable); gpio_clear(&gpio_vaa_enable);
} }
#endif #endif
void led_on(const led_t led) { void led_on(const led_t led)
{
gpio_set(&gpio_led[led]); gpio_set(&gpio_led[led]);
} }
void led_off(const led_t led) { void led_off(const led_t led)
{
gpio_clear(&gpio_led[led]); gpio_clear(&gpio_led[led]);
} }
void led_toggle(const led_t led) { void led_toggle(const led_t led)
{
gpio_toggle(&gpio_led[led]); gpio_toggle(&gpio_led[led]);
} }
void hw_sync_enable(const hw_sync_mode_t hw_sync_mode){ void hw_sync_enable(const hw_sync_mode_t hw_sync_mode)
{
gpio_write(&gpio_hw_sync_enable, hw_sync_mode == 1); gpio_write(&gpio_hw_sync_enable, hw_sync_mode == 1);
} }
void halt_and_flash(const uint32_t duration) { void halt_and_flash(const uint32_t duration)
/* blink LED1, LED2, and LED3 */
while (1)
{ {
/* blink LED1, LED2, and LED3 */
while (1) {
led_on(LED1); led_on(LED1);
led_on(LED2); led_on(LED2);
led_on(LED3); led_on(LED3);

View File

@ -25,8 +25,7 @@
#define __HACKRF_CORE_H #define __HACKRF_CORE_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C" {
{
#endif #endif
#include <stdint.h> #include <stdint.h>
@ -175,7 +174,6 @@ extern "C"
#define SCU_VAA_ENABLE (P5_0) /* GPIO2[9] on P5_0 */ #define SCU_VAA_ENABLE (P5_0) /* GPIO2[9] on P5_0 */
#endif #endif
/* SPI flash */ /* SPI flash */
#define SCU_SSP0_CIPO (P3_6) #define SCU_SSP0_CIPO (P3_6)
#define SCU_SSP0_COPI (P3_7) #define SCU_SSP0_COPI (P3_7)

View File

@ -46,6 +46,7 @@ void hackrf_ui_set_antenna_bias_null(bool antenna_bias) { UNUSED(antenna_bias);
void hackrf_ui_set_clock_source_null(clock_source_t source) { UNUSED(source); } void hackrf_ui_set_clock_source_null(clock_source_t source) { UNUSED(source); }
void hackrf_ui_set_transceiver_mode_null(transceiver_mode_t mode) { UNUSED(mode); } void hackrf_ui_set_transceiver_mode_null(transceiver_mode_t mode) { UNUSED(mode); }
bool hackrf_ui_operacake_gpio_compatible_null(void) { return true; } bool hackrf_ui_operacake_gpio_compatible_null(void) { return true; }
// clang-format on // clang-format on
/* Null UI function table, used if there's no hardware UI detected. Eliminates the /* Null UI function table, used if there's no hardware UI detected. Eliminates the
@ -67,13 +68,13 @@ static const hackrf_ui_t hackrf_ui_null = {
&hackrf_ui_set_antenna_bias_null, &hackrf_ui_set_antenna_bias_null,
&hackrf_ui_set_clock_source_null, &hackrf_ui_set_clock_source_null,
&hackrf_ui_set_transceiver_mode_null, &hackrf_ui_set_transceiver_mode_null,
&hackrf_ui_operacake_gpio_compatible_null &hackrf_ui_operacake_gpio_compatible_null};
};
static const hackrf_ui_t* ui = NULL; static const hackrf_ui_t* ui = NULL;
static bool ui_enabled = true; static bool ui_enabled = true;
const hackrf_ui_t* hackrf_ui(void) { const hackrf_ui_t* hackrf_ui(void)
{
/* Detect on first use. If no UI hardware is detected, use a stub function table. */ /* Detect on first use. If no UI hardware is detected, use a stub function table. */
if (ui == NULL && ui_enabled) { if (ui == NULL && ui_enabled) {
#ifdef HACKRF_ONE #ifdef HACKRF_ONE
@ -94,7 +95,8 @@ const hackrf_ui_t* hackrf_ui(void) {
return ui; return ui;
} }
void hackrf_ui_set_enable(bool enabled) { void hackrf_ui_set_enable(bool enabled)
{
if (ui_enabled != enabled) { if (ui_enabled != enabled) {
ui_enabled = enabled; ui_enabled = enabled;
hackrf_ui()->deinit(); hackrf_ui()->deinit();

View File

@ -21,19 +21,23 @@
#include "i2c_bus.h" #include "i2c_bus.h"
void i2c_bus_start(i2c_bus_t* const bus, const void* const config) { void i2c_bus_start(i2c_bus_t* const bus, const void* const config)
{
bus->start(bus, config); bus->start(bus, config);
} }
void i2c_bus_stop(i2c_bus_t* const bus) { void i2c_bus_stop(i2c_bus_t* const bus)
{
bus->stop(bus); bus->stop(bus);
} }
void i2c_bus_transfer( void i2c_bus_transfer(
i2c_bus_t* const bus, i2c_bus_t* const bus,
const uint_fast8_t peripheral_address, const uint_fast8_t peripheral_address,
const uint8_t* const tx, const size_t tx_count, const uint8_t* const tx,
uint8_t* const rx, const size_t rx_count const size_t tx_count,
) { uint8_t* const rx,
const size_t rx_count)
{
bus->transfer(bus, peripheral_address, tx, tx_count, rx, rx_count); bus->transfer(bus, peripheral_address, tx, tx_count, rx, rx_count);
} }

View File

@ -35,9 +35,10 @@ struct i2c_bus_t {
void (*transfer)( void (*transfer)(
i2c_bus_t* const bus, i2c_bus_t* const bus,
const uint_fast8_t peripheral_address, const uint_fast8_t peripheral_address,
const uint8_t* const tx, const size_t tx_count, const uint8_t* const tx,
uint8_t* const rx, const size_t rx_count const size_t tx_count,
); uint8_t* const rx,
const size_t rx_count);
}; };
void i2c_bus_start(i2c_bus_t* const bus, const void* const config); void i2c_bus_start(i2c_bus_t* const bus, const void* const config);
@ -45,8 +46,9 @@ void i2c_bus_stop(i2c_bus_t* const bus);
void i2c_bus_transfer( void i2c_bus_transfer(
i2c_bus_t* const bus, i2c_bus_t* const bus,
const uint_fast8_t peripheral_address, const uint_fast8_t peripheral_address,
const uint8_t* const tx, const size_t tx_count, const uint8_t* const tx,
uint8_t* const rx, const size_t rx_count const size_t tx_count,
); uint8_t* const rx,
const size_t rx_count);
#endif /*__I2C_BUS_H__*/ #endif /*__I2C_BUS_H__*/

View File

@ -26,23 +26,28 @@
/* FIXME return i2c0 status from each function */ /* FIXME return i2c0 status from each function */
void i2c_lpc_start(i2c_bus_t* const bus, const void* const _config) { void i2c_lpc_start(i2c_bus_t* const bus, const void* const _config)
{
const i2c_lpc_config_t* const config = _config; const i2c_lpc_config_t* const config = _config;
const uint32_t port = (uint32_t) bus->obj; const uint32_t port = (uint32_t) bus->obj;
i2c_init(port, config->duty_cycle_count); i2c_init(port, config->duty_cycle_count);
} }
void i2c_lpc_stop(i2c_bus_t* const bus) { void i2c_lpc_stop(i2c_bus_t* const bus)
{
const uint32_t port = (uint32_t) bus->obj; const uint32_t port = (uint32_t) bus->obj;
i2c_disable(port); i2c_disable(port);
} }
void i2c_lpc_transfer(i2c_bus_t* const bus, void i2c_lpc_transfer(
i2c_bus_t* const bus,
const uint_fast8_t peripheral_address, const uint_fast8_t peripheral_address,
const uint8_t* const data_tx, const size_t count_tx, const uint8_t* const data_tx,
uint8_t* const data_rx, const size_t count_rx const size_t count_tx,
) { uint8_t* const data_rx,
const size_t count_rx)
{
const uint32_t port = (uint32_t) bus->obj; const uint32_t port = (uint32_t) bus->obj;
size_t i; size_t i;
bool ack = false; bool ack = false;
@ -67,7 +72,8 @@ void i2c_lpc_transfer(i2c_bus_t* const bus,
i2c_stop(port); i2c_stop(port);
} }
bool i2c_probe(i2c_bus_t* const bus, const uint_fast8_t device_address) { bool i2c_probe(i2c_bus_t* const bus, const uint_fast8_t device_address)
{
const uint32_t port = (uint32_t) bus->obj; const uint32_t port = (uint32_t) bus->obj;
i2c_tx_start(port); i2c_tx_start(port);

View File

@ -34,11 +34,13 @@ typedef struct i2c_lpc_config_t {
void i2c_lpc_start(i2c_bus_t* const bus, const void* const config); void i2c_lpc_start(i2c_bus_t* const bus, const void* const config);
void i2c_lpc_stop(i2c_bus_t* const bus); void i2c_lpc_stop(i2c_bus_t* const bus);
void i2c_lpc_transfer(i2c_bus_t* const bus, void i2c_lpc_transfer(
i2c_bus_t* const bus,
const uint_fast8_t peripheral_address, const uint_fast8_t peripheral_address,
const uint8_t* const data_tx, const size_t count_tx, const uint8_t* const data_tx,
uint8_t* const data_rx, const size_t count_rx const size_t count_tx,
); uint8_t* const data_rx,
const size_t count_rx);
bool i2c_probe(i2c_bus_t* const bus, const uint_fast8_t device_address); bool i2c_probe(i2c_bus_t* const bus, const uint_fast8_t device_address);
#endif /*__I2C_LPC_H__*/ #endif /*__I2C_LPC_H__*/

View File

@ -19,8 +19,7 @@
* Boston, MA 02110-1301, USA. * Boston, MA 02110-1301, USA.
*/ */
int main() { int main()
while(1) { {
while (1) {}
}
} }

View File

@ -119,13 +119,15 @@ void max2837_setup(max2837_driver_t* const drv)
max2837_regs_commit(drv); max2837_regs_commit(drv);
} }
static uint16_t max2837_read(max2837_driver_t* const drv, uint8_t r) { static uint16_t max2837_read(max2837_driver_t* const drv, uint8_t r)
{
uint16_t value = (1 << 15) | (r << 10); uint16_t value = (1 << 15) | (r << 10);
spi_bus_transfer(drv->bus, &value, 1); spi_bus_transfer(drv->bus, &value, 1);
return value & 0x3ff; return value & 0x3ff;
} }
static void max2837_write(max2837_driver_t* const drv, uint8_t r, uint16_t v) { static void max2837_write(max2837_driver_t* const drv, uint8_t r, uint16_t v)
{
uint16_t value = (r << 10) | (v & 0x3ff); uint16_t value = (r << 10) | (v & 0x3ff);
spi_bus_transfer(drv->bus, &value, 1); spi_bus_transfer(drv->bus, &value, 1);
} }
@ -160,11 +162,13 @@ void max2837_regs_commit(max2837_driver_t* const drv)
} }
} }
void max2837_set_mode(max2837_driver_t* const drv, const max2837_mode_t new_mode) { void max2837_set_mode(max2837_driver_t* const drv, const max2837_mode_t new_mode)
{
drv->set_mode(drv, new_mode); drv->set_mode(drv, new_mode);
} }
max2837_mode_t max2837_mode(max2837_driver_t* const drv) { max2837_mode_t max2837_mode(max2837_driver_t* const drv)
{
return drv->mode; return drv->mode;
} }
@ -210,16 +214,13 @@ void max2837_set_frequency(max2837_driver_t* const drv, uint32_t freq)
if (freq < 2400000000U) { if (freq < 2400000000U) {
band = MAX2837_LOGEN_BSW_2_3; band = MAX2837_LOGEN_BSW_2_3;
lna_band = MAX2837_LNAband_2_4; lna_band = MAX2837_LNAband_2_4;
} } else if (freq < 2500000000U) {
else if (freq < 2500000000U) {
band = MAX2837_LOGEN_BSW_2_4; band = MAX2837_LOGEN_BSW_2_4;
lna_band = MAX2837_LNAband_2_4; lna_band = MAX2837_LNAband_2_4;
} } else if (freq < 2600000000U) {
else if (freq < 2600000000U) {
band = MAX2837_LOGEN_BSW_2_5; band = MAX2837_LOGEN_BSW_2_5;
lna_band = MAX2837_LNAband_2_6; lna_band = MAX2837_LNAband_2_6;
} } else {
else {
band = MAX2837_LOGEN_BSW_2_6; band = MAX2837_LOGEN_BSW_2_6;
lna_band = MAX2837_LNAband_2_6; lna_band = MAX2837_LNAband_2_6;
} }

View File

@ -81,7 +81,9 @@ extern void max2837_stop(max2837_driver_t* const drv);
/* Set frequency in Hz. Frequency setting is a multi-step function /* Set frequency in Hz. Frequency setting is a multi-step function
* where order of register writes matters. */ * where order of register writes matters. */
extern void max2837_set_frequency(max2837_driver_t* const drv, uint32_t freq); extern void max2837_set_frequency(max2837_driver_t* const drv, uint32_t freq);
uint32_t max2837_set_lpf_bandwidth(max2837_driver_t* const drv, const uint32_t bandwidth_hz); uint32_t max2837_set_lpf_bandwidth(
max2837_driver_t* const drv,
const uint32_t bandwidth_hz);
bool max2837_set_lna_gain(max2837_driver_t* const drv, const uint32_t gain_db); bool max2837_set_lna_gain(max2837_driver_t* const drv, const uint32_t gain_db);
bool max2837_set_vga_gain(max2837_driver_t* const drv, const uint32_t gain_db); bool max2837_set_vga_gain(max2837_driver_t* const drv, const uint32_t gain_db);
bool max2837_set_txvga_gain(max2837_driver_t* const drv, const uint32_t gain_db); bool max2837_set_txvga_gain(max2837_driver_t* const drv, const uint32_t gain_db);

View File

@ -25,7 +25,8 @@
#include <libopencm3/lpc43xx/scu.h> #include <libopencm3/lpc43xx/scu.h>
#include "hackrf_core.h" #include "hackrf_core.h"
void max2837_target_init(max2837_driver_t* const drv) { void max2837_target_init(max2837_driver_t* const drv)
{
/* Configure SSP1 Peripheral (to be moved later in SSP driver) */ /* Configure SSP1 Peripheral (to be moved later in SSP driver) */
scu_pinmux(SCU_SSP1_CIPO, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); scu_pinmux(SCU_SSP1_CIPO, (SCU_SSP_IO | SCU_CONF_FUNCTION5));
scu_pinmux(SCU_SSP1_COPI, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); scu_pinmux(SCU_SSP1_COPI, (SCU_SSP_IO | SCU_CONF_FUNCTION5));
@ -44,7 +45,8 @@ void max2837_target_init(max2837_driver_t* const drv) {
gpio_output(drv->gpio_tx_enable); gpio_output(drv->gpio_tx_enable);
} }
void max2837_target_set_mode(max2837_driver_t* const drv, const max2837_mode_t new_mode) { void max2837_target_set_mode(max2837_driver_t* const drv, const max2837_mode_t new_mode)
{
/* MAX2837_MODE_SHUTDOWN: /* MAX2837_MODE_SHUTDOWN:
* All circuit blocks are powered down, except the 4-wire serial bus * All circuit blocks are powered down, except the 4-wire serial bus
* and its internal programmable registers. * and its internal programmable registers.

View File

@ -115,7 +115,6 @@ static void delay_ms(int ms)
} }
} }
static void serial_delay(void) static void serial_delay(void)
{ {
uint32_t i; uint32_t i;
@ -124,13 +123,13 @@ static void serial_delay(void)
__asm__("nop"); __asm__("nop");
} }
/* SPI register write /* SPI register write
* *
* Send 32 bits: * Send 32 bits:
* First 29 bits are data * First 29 bits are data
* Last 3 bits are register number */ * Last 3 bits are register number */
static void max2871_spi_write(max2871_driver_t* const drv, uint8_t r, uint32_t v) { static void max2871_spi_write(max2871_driver_t* const drv, uint8_t r, uint32_t v)
{
#if DEBUG #if DEBUG
LOG("0x%04x -> reg%d\n", v, r); LOG("0x%04x -> reg%d\n", v, r);
#else #else
@ -229,8 +228,8 @@ void max2871_enable(max2871_driver_t* const drv)
{ {
gpio_set(drv->gpio_vco_ce); gpio_set(drv->gpio_vco_ce);
} }
void max2871_disable(max2871_driver_t* const drv) void max2871_disable(max2871_driver_t* const drv)
{ {
gpio_clear(drv->gpio_vco_ce); gpio_clear(drv->gpio_vco_ce);
} }

View File

@ -23,15 +23,18 @@
#include "max5864.h" #include "max5864.h"
static void max5864_write(max5864_driver_t* const drv, uint8_t value) { static void max5864_write(max5864_driver_t* const drv, uint8_t value)
{
spi_bus_transfer(drv->bus, &value, 1); spi_bus_transfer(drv->bus, &value, 1);
} }
static void max5864_init(max5864_driver_t* const drv) { static void max5864_init(max5864_driver_t* const drv)
{
drv->target_init(drv); drv->target_init(drv);
} }
void max5864_setup(max5864_driver_t* const drv) { void max5864_setup(max5864_driver_t* const drv)
{
max5864_init(drv); max5864_init(drv);
} }

View File

@ -24,7 +24,8 @@
#include <libopencm3/lpc43xx/scu.h> #include <libopencm3/lpc43xx/scu.h>
#include "hackrf_core.h" #include "hackrf_core.h"
void max5864_target_init(max5864_driver_t* const drv) { void max5864_target_init(max5864_driver_t* const drv)
{
(void) drv; (void) drv;
/* Configure SSP1 Peripheral (to be moved later in SSP driver) */ /* Configure SSP1 Peripheral (to be moved later in SSP driver) */

View File

@ -60,9 +60,9 @@
#define OPERACAKE_REG_POLARITY 0x02 #define OPERACAKE_REG_POLARITY 0x02
#define OPERACAKE_REG_CONFIG 0x03 #define OPERACAKE_REG_CONFIG 0x03
#define OPERACAKE_DEFAULT_OUTPUT (OPERACAKE_GPIO_DISABLE | OPERACAKE_SAMESIDE \ #define OPERACAKE_DEFAULT_OUTPUT \
| OPERACAKE_PORT_A1 | OPERACAKE_PORT_B1 \ (OPERACAKE_GPIO_DISABLE | OPERACAKE_SAMESIDE | OPERACAKE_PORT_A1 | \
| OPERACAKE_EN_LEDS) OPERACAKE_PORT_B1 | OPERACAKE_EN_LEDS)
#define OPERACAKE_CONFIG_ALL_OUTPUT (0x00) #define OPERACAKE_CONFIG_ALL_OUTPUT (0x00)
// Leave LED bits as outputs // Leave LED bits as outputs
#define OPERACAKE_CONFIG_GPIO_INPUTS (0x7C) #define OPERACAKE_CONFIG_GPIO_INPUTS (0x7C)
@ -96,7 +96,8 @@ struct operacake_state operacake_boards[OPERACAKE_MAX_BOARDS];
bool allow_gpio_mode = true; bool allow_gpio_mode = true;
/* read single register */ /* read single register */
uint8_t operacake_read_reg(i2c_bus_t* const bus, uint8_t address, uint8_t reg) { uint8_t operacake_read_reg(i2c_bus_t* const bus, uint8_t address, uint8_t reg)
{
// Convert from Opera Cake address (0-7) to I2C address // Convert from Opera Cake address (0-7) to I2C address
address += OPERACAKE_ADDRESS_DEFAULT; address += OPERACAKE_ADDRESS_DEFAULT;
@ -107,7 +108,8 @@ uint8_t operacake_read_reg(i2c_bus_t* const bus, uint8_t address, uint8_t reg) {
} }
/* Write to one of the PCA9557 registers */ /* Write to one of the PCA9557 registers */
void operacake_write_reg(i2c_bus_t* const bus, uint8_t address, uint8_t reg, uint8_t value) { void operacake_write_reg(i2c_bus_t* const bus, uint8_t address, uint8_t reg, uint8_t value)
{
// Convert from Opera Cake address (0-7) to I2C address // Convert from Opera Cake address (0-7) to I2C address
address += OPERACAKE_ADDRESS_DEFAULT; address += OPERACAKE_ADDRESS_DEFAULT;
@ -115,12 +117,19 @@ void operacake_write_reg(i2c_bus_t* const bus, uint8_t address, uint8_t reg, uin
i2c_bus_transfer(bus, address, data, 2, NULL, 0); i2c_bus_transfer(bus, address, data, 2, NULL, 0);
} }
uint8_t operacake_init(bool allow_gpio) { uint8_t operacake_init(bool allow_gpio)
{
/* Find connected operacakes */ /* Find connected operacakes */
for (int addr = 0; addr < 8; addr++) { for (int addr = 0; addr < 8; addr++) {
operacake_write_reg(oc_bus, addr, OPERACAKE_REG_OUTPUT, operacake_write_reg(
oc_bus,
addr,
OPERACAKE_REG_OUTPUT,
OPERACAKE_DEFAULT_OUTPUT); OPERACAKE_DEFAULT_OUTPUT);
operacake_write_reg(oc_bus, addr, OPERACAKE_REG_CONFIG, operacake_write_reg(
oc_bus,
addr,
OPERACAKE_REG_CONFIG,
OPERACAKE_CONFIG_ALL_OUTPUT); OPERACAKE_CONFIG_ALL_OUTPUT);
uint8_t reg = operacake_read_reg(oc_bus, addr, OPERACAKE_REG_CONFIG); uint8_t reg = operacake_read_reg(oc_bus, addr, OPERACAKE_REG_CONFIG);
@ -136,14 +145,16 @@ uint8_t operacake_init(bool allow_gpio) {
return 0; return 0;
} }
bool operacake_is_board_present(uint8_t address) { bool operacake_is_board_present(uint8_t address)
{
if (address >= OPERACAKE_MAX_BOARDS) if (address >= OPERACAKE_MAX_BOARDS)
return false; return false;
return operacake_boards[address].present; return operacake_boards[address].present;
} }
void operacake_get_boards(uint8_t *addresses) { void operacake_get_boards(uint8_t* addresses)
{
int count = 0; int count = 0;
for (int i = 0; i < OPERACAKE_MAX_BOARDS; i++) { for (int i = 0; i < OPERACAKE_MAX_BOARDS; i++) {
addresses[i] = OPERACAKE_ADDRESS_INVALID; addresses[i] = OPERACAKE_ADDRESS_INVALID;
@ -154,7 +165,8 @@ void operacake_get_boards(uint8_t *addresses) {
} }
} }
uint8_t port_to_pins(uint8_t port) { uint8_t port_to_pins(uint8_t port)
{
switch (port) { switch (port) {
case OPERACAKE_PA1: case OPERACAKE_PA1:
return OPERACAKE_PORT_A1; return OPERACAKE_PORT_A1;
@ -188,8 +200,8 @@ uint8_t operacake_activate_ports(uint8_t address, uint8_t PA, uint8_t PB)
return 1; return 1;
} }
/* Ensure PA and PB are on opposite sides. */ /* Ensure PA and PB are on opposite sides. */
if (((PA <= OPERACAKE_PA4) && (PB <= OPERACAKE_PA4)) if (((PA <= OPERACAKE_PA4) && (PB <= OPERACAKE_PA4)) ||
|| ((PA > OPERACAKE_PA4) && (PB > OPERACAKE_PA4))) { ((PA > OPERACAKE_PA4) && (PB > OPERACAKE_PA4))) {
return 1; return 1;
} }
@ -207,7 +219,8 @@ uint8_t operacake_activate_ports(uint8_t address, uint8_t PA, uint8_t PB)
return 0; return 0;
} }
void operacake_set_mode(uint8_t address, uint8_t mode) { void operacake_set_mode(uint8_t address, uint8_t mode)
{
if (address >= OPERACAKE_MAX_BOARDS) if (address >= OPERACAKE_MAX_BOARDS)
return; return;
@ -216,12 +229,25 @@ void operacake_set_mode(uint8_t address, uint8_t mode) {
if (mode == MODE_TIME) { if (mode == MODE_TIME) {
// Switch Opera Cake to pin-control mode // Switch Opera Cake to pin-control mode
uint8_t config_pins = (uint8_t)~(OPERACAKE_PIN_OE(1) | OPERACAKE_PIN_LEDEN(1) | OPERACAKE_PIN_LEDEN2(1)); uint8_t config_pins = (uint8_t) ~(
OPERACAKE_PIN_OE(1) | OPERACAKE_PIN_LEDEN(1) |
OPERACAKE_PIN_LEDEN2(1));
operacake_write_reg(oc_bus, address, OPERACAKE_REG_CONFIG, config_pins); operacake_write_reg(oc_bus, address, OPERACAKE_REG_CONFIG, config_pins);
operacake_write_reg(oc_bus, address, OPERACAKE_REG_OUTPUT, OPERACAKE_GPIO_ENABLE | OPERACAKE_EN_LEDS); operacake_write_reg(
oc_bus,
address,
OPERACAKE_REG_OUTPUT,
OPERACAKE_GPIO_ENABLE | OPERACAKE_EN_LEDS);
} else { } else {
operacake_write_reg(oc_bus, address, OPERACAKE_REG_CONFIG, OPERACAKE_CONFIG_ALL_OUTPUT); operacake_write_reg(
operacake_activate_ports(address, operacake_boards[address].PA, operacake_boards[address].PB); oc_bus,
address,
OPERACAKE_REG_CONFIG,
OPERACAKE_CONFIG_ALL_OUTPUT);
operacake_activate_ports(
address,
operacake_boards[address].PA,
operacake_boards[address].PB);
} }
// If any boards are in MODE_TIME, enable the sctimer events. // If any boards are in MODE_TIME, enable the sctimer events.
@ -233,7 +259,8 @@ void operacake_set_mode(uint8_t address, uint8_t mode) {
operacake_sctimer_enable(enable_sctimer); operacake_sctimer_enable(enable_sctimer);
} }
uint8_t operacake_get_mode(uint8_t address) { uint8_t operacake_get_mode(uint8_t address)
{
if (address >= OPERACAKE_MAX_BOARDS) if (address >= OPERACAKE_MAX_BOARDS)
return 0; return 0;
@ -250,8 +277,8 @@ uint8_t operacake_set_ports(uint8_t address, uint8_t PA, uint8_t PB)
return 1; return 1;
} }
/* Ensure PA and PB are on opposite sides. */ /* Ensure PA and PB are on opposite sides. */
if (((PA <= OPERACAKE_PA4) && (PB <= OPERACAKE_PA4)) if (((PA <= OPERACAKE_PA4) && (PB <= OPERACAKE_PA4)) ||
|| ((PA > OPERACAKE_PA4) && (PB > OPERACAKE_PA4))) { ((PA > OPERACAKE_PA4) && (PB > OPERACAKE_PA4))) {
return 1; return 1;
} }
@ -280,7 +307,8 @@ typedef struct {
static operacake_range ranges[MAX_OPERACAKE_RANGES * sizeof(operacake_range)]; static operacake_range ranges[MAX_OPERACAKE_RANGES * sizeof(operacake_range)];
static uint8_t range_idx = 0; static uint8_t range_idx = 0;
uint8_t operacake_add_range(uint16_t freq_min, uint16_t freq_max, uint8_t port) { uint8_t operacake_add_range(uint16_t freq_min, uint16_t freq_max, uint8_t port)
{
if (range_idx >= MAX_OPERACAKE_RANGES) { if (range_idx >= MAX_OPERACAKE_RANGES) {
return 1; return 1;
} }
@ -301,15 +329,16 @@ void operacake_clear_ranges(void)
#define FREQ_ONE_MHZ (1000000ull) #define FREQ_ONE_MHZ (1000000ull)
uint8_t operacake_set_range(uint32_t freq_mhz) { uint8_t operacake_set_range(uint32_t freq_mhz)
{
if (range_idx == 0) { if (range_idx == 0) {
return 1; return 1;
} }
int range; int range;
for (range = 0; range < range_idx; range++) { for (range = 0; range < range_idx; range++) {
if((freq_mhz >= ranges[range].freq_min) if ((freq_mhz >= ranges[range].freq_min) &&
&& (freq_mhz <= ranges[range].freq_max)) { (freq_mhz <= ranges[range].freq_max)) {
break; break;
} }
} }
@ -322,8 +351,12 @@ uint8_t operacake_set_range(uint32_t freq_mhz) {
} }
for (int i = 0; i < OPERACAKE_MAX_BOARDS; i++) { for (int i = 0; i < OPERACAKE_MAX_BOARDS; i++) {
if (operacake_is_board_present(i) && operacake_get_mode(i) == MODE_FREQUENCY) { if (operacake_is_board_present(i) &&
operacake_activate_ports(i, ranges[range].portA, ranges[range].portB); operacake_get_mode(i) == MODE_FREQUENCY) {
operacake_activate_ports(
i,
ranges[range].portA,
ranges[range].portB);
break; break;
} }
} }
@ -358,9 +391,15 @@ uint16_t gpio_test(uint8_t address)
// Setup I2C to put it in GPIO mode // Setup I2C to put it in GPIO mode
reg = (OPERACAKE_GPIO_ENABLE | OPERACAKE_EN_LEDS); reg = (OPERACAKE_GPIO_ENABLE | OPERACAKE_EN_LEDS);
operacake_write_reg(oc_bus, address, OPERACAKE_REG_OUTPUT, reg); operacake_write_reg(oc_bus, address, OPERACAKE_REG_OUTPUT, reg);
operacake_write_reg(oc_bus, address, OPERACAKE_REG_CONFIG, operacake_write_reg(
oc_bus,
address,
OPERACAKE_REG_CONFIG,
OPERACAKE_CONFIG_GPIO_INPUTS); OPERACAKE_CONFIG_GPIO_INPUTS);
operacake_write_reg(oc_bus, address, OPERACAKE_REG_POLARITY, operacake_write_reg(
oc_bus,
address,
OPERACAKE_REG_POLARITY,
OPERACAKE_POLARITY_NORMAL); OPERACAKE_POLARITY_NORMAL);
// clear state // clear state
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
@ -406,9 +445,15 @@ uint16_t gpio_test(uint8_t address)
} }
// Put it back in to I2C mode and set default pins // Put it back in to I2C mode and set default pins
operacake_write_reg(oc_bus, address, OPERACAKE_REG_CONFIG, operacake_write_reg(
oc_bus,
address,
OPERACAKE_REG_CONFIG,
OPERACAKE_CONFIG_ALL_OUTPUT); OPERACAKE_CONFIG_ALL_OUTPUT);
operacake_write_reg(oc_bus, address, OPERACAKE_REG_OUTPUT, operacake_write_reg(
oc_bus,
address,
OPERACAKE_REG_OUTPUT,
OPERACAKE_DEFAULT_OUTPUT); OPERACAKE_DEFAULT_OUTPUT);
return result; return result;
} }

View File

@ -23,8 +23,7 @@
#define __OPERACAKE_H #define __OPERACAKE_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C" {
{
#endif #endif
#include <stdint.h> #include <stdint.h>

View File

@ -30,7 +30,6 @@
#include <libopencm3/lpc43xx/gima.h> #include <libopencm3/lpc43xx/gima.h>
#include "sct.h" #include "sct.h"
#define U1CTRL_SET SCT_OUT14_SET #define U1CTRL_SET SCT_OUT14_SET
#define U1CTRL_CLR SCT_OUT14_CLR #define U1CTRL_CLR SCT_OUT14_CLR
#define U2CTRL0_SET SCT_OUT13_SET #define U2CTRL0_SET SCT_OUT13_SET
@ -53,7 +52,8 @@ static uint32_t default_output = 0;
* To trigger the antenna switching synchronously with the sample clock, the * To trigger the antenna switching synchronously with the sample clock, the
* SGPIO is configured to output its clock (f=2 * sample clock) to the SCTimer. * SGPIO is configured to output its clock (f=2 * sample clock) to the SCTimer.
*/ */
void operacake_sctimer_init() { void operacake_sctimer_init()
{
// We start by resetting the SCTimer // We start by resetting the SCTimer
RESET_CTRL1 = RESET_CTRL1_SCT_RST; RESET_CTRL1 = RESET_CTRL1_SCT_RST;
@ -67,23 +67,30 @@ void operacake_sctimer_init() {
// this delay may need to be increased. // this delay may need to be increased.
delay(8); delay(8);
// Pin definitions for the HackRF // Pin definitions for the HackRF
// U2CTRL0 // U2CTRL0
scu_pinmux(P7_4, SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_FUNCTION1); scu_pinmux(
P7_4,
SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_FUNCTION1);
// U2CTRL1 // U2CTRL1
scu_pinmux(P7_5, SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_FUNCTION1); scu_pinmux(
P7_5,
SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_FUNCTION1);
// U3CTRL0 // U3CTRL0
scu_pinmux(P7_6, SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_FUNCTION1); scu_pinmux(
P7_6,
SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_FUNCTION1);
// U3CTRL1 // U3CTRL1
scu_pinmux(P7_7, SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_FUNCTION1); scu_pinmux(
P7_7,
SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_FUNCTION1);
// U1CTRL // U1CTRL
scu_pinmux(P7_0, SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_FUNCTION1); scu_pinmux(
P7_0,
SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_FUNCTION1);
// Configure the SGPIO to output the clock (f=2 * sample clock) on pin 12 // Configure the SGPIO to output the clock (f=2 * sample clock) on pin 12
SGPIO_OUT_MUX_CFG12 = SGPIO_OUT_MUX_CFG12 = SGPIO_OUT_MUX_CFG_P_OUT_CFG(0x08) | // clkout output mode
SGPIO_OUT_MUX_CFG_P_OUT_CFG(0x08) | // clkout output mode
SGPIO_OUT_MUX_CFG_P_OE_CFG(0); // gpio_oe SGPIO_OUT_MUX_CFG_P_OE_CFG(0); // gpio_oe
SGPIO_GPIO_OENREG |= BIT12; SGPIO_GPIO_OENREG |= BIT12;
@ -91,9 +98,8 @@ void operacake_sctimer_init() {
GIMA_CTIN_1_IN = 0x2 << 4; // Route SGPIO12 to SCTIN1 GIMA_CTIN_1_IN = 0x2 << 4; // Route SGPIO12 to SCTIN1
// We configure this register first, because the user manual says to // We configure this register first, because the user manual says to
SCT_CONFIG |= SCT_CONFIG_UNIFY_32_BIT SCT_CONFIG |= SCT_CONFIG_UNIFY_32_BIT | SCT_CONFIG_CLKMODE_PRESCALED_BUS_CLOCK |
| SCT_CONFIG_CLKMODE_PRESCALED_BUS_CLOCK SCT_CONFIG_CKSEL_RISING_EDGES_ON_INPUT_1;
| SCT_CONFIG_CKSEL_RISING_EDGES_ON_INPUT_1;
// Halt the SCTimer to enable it to be configured // Halt the SCTimer to enable it to be configured
SCT_CTRL = SCT_CTRL_HALT_L(1); SCT_CTRL = SCT_CTRL_HALT_L(1);
@ -108,28 +114,30 @@ void operacake_sctimer_init() {
SCT_CTRL &= ~SCT_CTRL_HALT_L(1); SCT_CTRL &= ~SCT_CTRL_HALT_L(1);
} }
static uint32_t operacake_sctimer_port_to_output(uint8_t port) { static uint32_t operacake_sctimer_port_to_output(uint8_t port)
{
int bit0 = (port >> 0) & 1; int bit0 = (port >> 0) & 1;
int bit1 = (port >> 1) & 1; int bit1 = (port >> 1) & 1;
int bit2 = (port >> 2) & 1; int bit2 = (port >> 2) & 1;
return (bit0 << 11) | (bit0 << 13) | return (bit0 << 11) | (bit0 << 13) | (bit1 << 8) | (bit1 << 12) |
(bit1 << 8) | (bit1 << 12) |
(((~bit2) & 1) << 14); (((~bit2) & 1) << 14);
} }
void operacake_sctimer_enable(bool enable) { void operacake_sctimer_enable(bool enable)
{
SCT_CTRL = SCT_CTRL_HALT_L(1); SCT_CTRL = SCT_CTRL_HALT_L(1);
SCT_STATE = enable; SCT_STATE = enable;
SCT_CTRL &= ~SCT_CTRL_HALT_L(1); SCT_CTRL &= ~SCT_CTRL_HALT_L(1);
} }
void operacake_sctimer_set_dwell_times(struct operacake_dwell_times *times, int n) { void operacake_sctimer_set_dwell_times(struct operacake_dwell_times* times, int n)
{
SCT_CTRL = SCT_CTRL_HALT_L(1); SCT_CTRL = SCT_CTRL_HALT_L(1);
uint32_t counter = 0; uint32_t counter = 0;
uint32_t bit0_set = 0, bit0_clr = 0, bit1_set = 0, bit1_clr = 0, bit2_set = 0, bit2_clr = 0; uint32_t bit0_set = 0, bit0_clr = 0, bit1_set = 0, bit1_clr = 0, bit2_set = 0,
bit2_clr = 0;
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
// Enable event i in state 1, set to match on match register i // Enable event i in state 1, set to match on match register i
SCT_EVn_STATE(i) = SCT_EVn_STATE_STATEMSK1(1); SCT_EVn_STATE(i) = SCT_EVn_STATE_STATEMSK1(1);
@ -192,7 +200,8 @@ void operacake_sctimer_set_dwell_times(struct operacake_dwell_times *times, int
SCT_CTRL &= ~SCT_CTRL_HALT_L(1); SCT_CTRL &= ~SCT_CTRL_HALT_L(1);
} }
void operacake_sctimer_stop() { void operacake_sctimer_stop()
{
// Halt timer // Halt timer
SCT_CTRL |= SCT_CTRL_HALT_L(1); SCT_CTRL |= SCT_CTRL_HALT_L(1);
} }
@ -203,7 +212,8 @@ void operacake_sctimer_stop() {
* called by set_transceiver_mode so the HackRF starts capturing with the * called by set_transceiver_mode so the HackRF starts capturing with the
* same antenna selected each time. * same antenna selected each time.
*/ */
void operacake_sctimer_reset_state() { void operacake_sctimer_reset_state()
{
SCT_CTRL |= SCT_CTRL_HALT_L(1); SCT_CTRL |= SCT_CTRL_HALT_L(1);
// Clear the counter value // Clear the counter value

View File

@ -26,7 +26,8 @@
#include <libopencm3/lpc43xx/scu.h> #include <libopencm3/lpc43xx/scu.h>
static void portapack_sleep_milliseconds(const uint32_t milliseconds) { static void portapack_sleep_milliseconds(const uint32_t milliseconds)
{
/* NOTE: Naively assumes 204 MHz instruction cycle clock and five instructions per count */ /* NOTE: Naively assumes 204 MHz instruction cycle clock and five instructions per count */
delay(milliseconds * 40800); delay(milliseconds * 40800);
} }
@ -41,6 +42,7 @@ static struct gpio_t gpio_unused = GPIO(5, 7); /* P2_8 */
static struct gpio_t gpio_lcd_rdx = GPIO(5, 4); /* P2_4 */ static struct gpio_t gpio_lcd_rdx = GPIO(5, 4); /* P2_4 */
static struct gpio_t gpio_lcd_wrx = GPIO(1, 10); /* P2_9 */ static struct gpio_t gpio_lcd_wrx = GPIO(1, 10); /* P2_9 */
static struct gpio_t gpio_dir = GPIO(1, 13); /* P2_13 */ static struct gpio_t gpio_dir = GPIO(1, 13); /* P2_13 */
// clang-format on // clang-format on
typedef struct portapack_if_t { typedef struct portapack_if_t {
@ -67,26 +69,31 @@ static portapack_if_t portapack_if = {
#define GPIO_DATA_SHIFT (8) #define GPIO_DATA_SHIFT (8)
static const uint32_t gpio_data_mask = 0xFFU << GPIO_DATA_SHIFT; static const uint32_t gpio_data_mask = 0xFFU << GPIO_DATA_SHIFT;
static void portapack_data_mask_set() { static void portapack_data_mask_set()
{
portapack_if.gpio_port_data->mask = ~gpio_data_mask; portapack_if.gpio_port_data->mask = ~gpio_data_mask;
} }
static void portapack_data_write_low(const uint32_t value) { static void portapack_data_write_low(const uint32_t value)
{
portapack_if.gpio_port_data->mpin = (value << GPIO_DATA_SHIFT); portapack_if.gpio_port_data->mpin = (value << GPIO_DATA_SHIFT);
} }
static void portapack_data_write_high(const uint32_t value) { static void portapack_data_write_high(const uint32_t value)
{
/* NOTE: Assumes no other bits in the port are masked. */ /* NOTE: Assumes no other bits in the port are masked. */
/* NOTE: Assumes that bits 15 through 8 are masked. */ /* NOTE: Assumes that bits 15 through 8 are masked. */
portapack_if.gpio_port_data->mpin = value; portapack_if.gpio_port_data->mpin = value;
} }
static void portapack_dir_read() { static void portapack_dir_read()
{
portapack_if.gpio_port_data->dir &= ~gpio_data_mask; portapack_if.gpio_port_data->dir &= ~gpio_data_mask;
gpio_set(portapack_if.gpio_dir); gpio_set(portapack_if.gpio_dir);
} }
static void portapack_dir_write() { static void portapack_dir_write()
{
gpio_clear(portapack_if.gpio_dir); gpio_clear(portapack_if.gpio_dir);
portapack_if.gpio_port_data->dir |= gpio_data_mask; portapack_if.gpio_port_data->dir |= gpio_data_mask;
/* TODO: Manipulating DIR[3] makes me queasy. The RFFC5072 DATA pin /* TODO: Manipulating DIR[3] makes me queasy. The RFFC5072 DATA pin
@ -97,35 +104,43 @@ static void portapack_dir_write() {
*/ */
} }
__attribute__((unused)) static void portapack_lcd_rd_assert() { __attribute__((unused)) static void portapack_lcd_rd_assert()
{
gpio_clear(portapack_if.gpio_lcd_rdx); gpio_clear(portapack_if.gpio_lcd_rdx);
} }
static void portapack_lcd_rd_deassert() { static void portapack_lcd_rd_deassert()
{
gpio_set(portapack_if.gpio_lcd_rdx); gpio_set(portapack_if.gpio_lcd_rdx);
} }
static void portapack_lcd_wr_assert() { static void portapack_lcd_wr_assert()
{
gpio_clear(portapack_if.gpio_lcd_wrx); gpio_clear(portapack_if.gpio_lcd_wrx);
} }
static void portapack_lcd_wr_deassert() { static void portapack_lcd_wr_deassert()
{
gpio_set(portapack_if.gpio_lcd_wrx); gpio_set(portapack_if.gpio_lcd_wrx);
} }
static void portapack_io_stb_assert() { static void portapack_io_stb_assert()
{
gpio_clear(portapack_if.gpio_io_stbx); gpio_clear(portapack_if.gpio_io_stbx);
} }
static void portapack_io_stb_deassert() { static void portapack_io_stb_deassert()
{
gpio_set(portapack_if.gpio_io_stbx); gpio_set(portapack_if.gpio_io_stbx);
} }
static void portapack_addr(const bool value) { static void portapack_addr(const bool value)
{
gpio_write(portapack_if.gpio_addr, value); gpio_write(portapack_if.gpio_addr, value);
} }
static void portapack_lcd_command(const uint32_t value) { static void portapack_lcd_command(const uint32_t value)
{
portapack_data_write_high(0); /* Drive high byte (with zero -- don't care) */ portapack_data_write_high(0); /* Drive high byte (with zero -- don't care) */
portapack_dir_write(); /* Turn around data bus, MCU->CPLD */ portapack_dir_write(); /* Turn around data bus, MCU->CPLD */
portapack_addr(0); /* Indicate command */ portapack_addr(0); /* Indicate command */
@ -143,7 +158,8 @@ static void portapack_lcd_command(const uint32_t value) {
portapack_addr(1); /* Set up for data phase (most likely after a command) */ portapack_addr(1); /* Set up for data phase (most likely after a command) */
} }
static void portapack_lcd_write_data(const uint32_t value) { static void portapack_lcd_write_data(const uint32_t value)
{
// NOTE: Assumes and DIR=0 and ADDR=1 from command phase. // NOTE: Assumes and DIR=0 and ADDR=1 from command phase.
portapack_data_write_high(value); /* Drive high byte */ portapack_data_write_high(value); /* Drive high byte */
__asm__("nop"); __asm__("nop");
@ -156,7 +172,8 @@ static void portapack_lcd_write_data(const uint32_t value) {
portapack_lcd_wr_deassert(); /* Complete write operation */ portapack_lcd_wr_deassert(); /* Complete write operation */
} }
static void portapack_io_write(const bool address, const uint_fast16_t value) { static void portapack_io_write(const bool address, const uint_fast16_t value)
{
portapack_data_write_low(value); portapack_data_write_low(value);
portapack_dir_write(); portapack_dir_write();
portapack_addr(address); portapack_addr(address);
@ -170,7 +187,8 @@ static void portapack_io_write(const bool address, const uint_fast16_t value) {
portapack_io_stb_deassert(); portapack_io_stb_deassert();
} }
static void portapack_if_init() { static void portapack_if_init()
{
portapack_data_mask_set(); portapack_data_mask_set();
portapack_data_write_high(0); portapack_data_write_high(0);
@ -206,7 +224,8 @@ static void portapack_if_init() {
/* scu_pinmux(SCU_PINMUX_PP_UNUSED, SCU_CONF_FUNCTION4 | SCU_GPIO_NOPULL); */ /* scu_pinmux(SCU_PINMUX_PP_UNUSED, SCU_CONF_FUNCTION4 | SCU_GPIO_NOPULL); */
} }
static void portapack_lcd_reset_state(const bool active) { static void portapack_lcd_reset_state(const bool active)
{
portapack_if.io_reg = (portapack_if.io_reg & 0xfe) | (active ? (1 << 0) : 0); portapack_if.io_reg = (portapack_if.io_reg & 0xfe) | (active ? (1 << 0) : 0);
portapack_io_write(1, portapack_if.io_reg); portapack_io_write(1, portapack_if.io_reg);
} }
@ -214,15 +233,16 @@ static void portapack_lcd_reset_state(const bool active) {
static void portapack_lcd_data_write_command_and_data( static void portapack_lcd_data_write_command_and_data(
const uint_fast8_t command, const uint_fast8_t command,
const uint8_t* data, const uint8_t* data,
const size_t data_count const size_t data_count)
) { {
portapack_lcd_command(command); portapack_lcd_command(command);
for (size_t i = 0; i < data_count; i++) { for (size_t i = 0; i < data_count; i++) {
portapack_lcd_write_data(data[i]); portapack_lcd_write_data(data[i]);
} }
} }
static void portapack_lcd_sleep_out() { static void portapack_lcd_sleep_out()
{
const uint8_t cmd_11[] = {}; const uint8_t cmd_11[] = {};
portapack_lcd_data_write_command_and_data(0x11, cmd_11, ARRAY_SIZEOF(cmd_11)); portapack_lcd_data_write_command_and_data(0x11, cmd_11, ARRAY_SIZEOF(cmd_11));
// "It will be necessary to wait 120msec after sending Sleep Out // "It will be necessary to wait 120msec after sending Sleep Out
@ -231,56 +251,68 @@ static void portapack_lcd_sleep_out() {
portapack_sleep_milliseconds(120); portapack_sleep_milliseconds(120);
} }
static void portapack_lcd_display_on() { static void portapack_lcd_display_on()
{
const uint8_t cmd_29[] = {}; const uint8_t cmd_29[] = {};
portapack_lcd_data_write_command_and_data(0x29, cmd_29, ARRAY_SIZEOF(cmd_29)); portapack_lcd_data_write_command_and_data(0x29, cmd_29, ARRAY_SIZEOF(cmd_29));
} }
static void portapack_lcd_ramwr_start() { static void portapack_lcd_ramwr_start()
{
const uint8_t cmd_2c[] = {}; const uint8_t cmd_2c[] = {};
portapack_lcd_data_write_command_and_data(0x2c, cmd_2c, ARRAY_SIZEOF(cmd_2c)); portapack_lcd_data_write_command_and_data(0x2c, cmd_2c, ARRAY_SIZEOF(cmd_2c));
} }
static void portapack_lcd_set(const uint_fast8_t command, const uint_fast16_t start, const uint_fast16_t end) { static void portapack_lcd_set(
const uint8_t data[] = { const uint_fast8_t command,
(start >> 8), (start & 0xff), const uint_fast16_t start,
(end >> 8), (end & 0xff) const uint_fast16_t end)
}; {
const uint8_t data[] = {(start >> 8), (start & 0xff), (end >> 8), (end & 0xff)};
portapack_lcd_data_write_command_and_data(command, data, ARRAY_SIZEOF(data)); portapack_lcd_data_write_command_and_data(command, data, ARRAY_SIZEOF(data));
} }
static void portapack_lcd_caset(const uint_fast16_t start_column, const uint_fast16_t end_column) { static void portapack_lcd_caset(
const uint_fast16_t start_column,
const uint_fast16_t end_column)
{
portapack_lcd_set(0x2a, start_column, end_column); portapack_lcd_set(0x2a, start_column, end_column);
} }
static void portapack_lcd_paset(const uint_fast16_t start_page, const uint_fast16_t end_page) { static void portapack_lcd_paset(
const uint_fast16_t start_page,
const uint_fast16_t end_page)
{
portapack_lcd_set(0x2b, start_page, end_page); portapack_lcd_set(0x2b, start_page, end_page);
} }
static void portapack_lcd_start_ram_write( static void portapack_lcd_start_ram_write(const ui_rect_t rect)
const ui_rect_t rect {
) {
portapack_lcd_caset(rect.point.x, rect.point.x + rect.size.width - 1); portapack_lcd_caset(rect.point.x, rect.point.x + rect.size.width - 1);
portapack_lcd_paset(rect.point.y, rect.point.y + rect.size.height - 1); portapack_lcd_paset(rect.point.y, rect.point.y + rect.size.height - 1);
portapack_lcd_ramwr_start(); portapack_lcd_ramwr_start();
} }
static void portapack_lcd_write_pixel(const ui_color_t pixel) { static void portapack_lcd_write_pixel(const ui_color_t pixel)
{
portapack_lcd_write_data(pixel.v); portapack_lcd_write_data(pixel.v);
} }
static void portapack_lcd_write_pixels_color(const ui_color_t c, size_t n) { static void portapack_lcd_write_pixels_color(const ui_color_t c, size_t n)
{
while (n--) { while (n--) {
portapack_lcd_write_data(c.v); portapack_lcd_write_data(c.v);
} }
} }
static void portapack_lcd_wake() { static void portapack_lcd_wake()
{
portapack_lcd_sleep_out(); portapack_lcd_sleep_out();
portapack_lcd_display_on(); portapack_lcd_display_on();
} }
static void portapack_lcd_reset() { static void portapack_lcd_reset()
{
portapack_lcd_reset_state(false); portapack_lcd_reset_state(false);
portapack_sleep_milliseconds(1); portapack_sleep_milliseconds(1);
portapack_lcd_reset_state(true); portapack_lcd_reset_state(true);
@ -289,7 +321,8 @@ static void portapack_lcd_reset() {
portapack_sleep_milliseconds(120); portapack_sleep_milliseconds(120);
} }
static void portapack_lcd_init() { static void portapack_lcd_init()
{
// LCDs are configured for IM[2:0] = 001 // LCDs are configured for IM[2:0] = 001
// 8080-I system, 16-bit parallel bus // 8080-I system, 16-bit parallel bus
@ -403,16 +436,40 @@ static void portapack_lcd_init() {
// Set Gamma // Set Gamma
const uint8_t cmd_e0[] = { const uint8_t cmd_e0[] = {
0x0F, 0x1D, 0x19, 0x0E, 0x10, 0x07, 0x4C, 0x63, 0x0F,
0x3F, 0x03, 0x0D, 0x00, 0x26, 0x24, 0x04 0x1D,
}; 0x19,
0x0E,
0x10,
0x07,
0x4C,
0x63,
0x3F,
0x03,
0x0D,
0x00,
0x26,
0x24,
0x04};
portapack_lcd_data_write_command_and_data(0xE0, cmd_e0, ARRAY_SIZEOF(cmd_e0)); portapack_lcd_data_write_command_and_data(0xE0, cmd_e0, ARRAY_SIZEOF(cmd_e0));
// Set Gamma // Set Gamma
const uint8_t cmd_e1[] = { const uint8_t cmd_e1[] = {
0x00, 0x1C, 0x1F, 0x02, 0x0F, 0x03, 0x35, 0x25, 0x00,
0x47, 0x04, 0x0C, 0x0B, 0x29, 0x2F, 0x05 0x1C,
}; 0x1F,
0x02,
0x0F,
0x03,
0x35,
0x25,
0x47,
0x04,
0x0C,
0x0B,
0x29,
0x2F,
0x05};
portapack_lcd_data_write_command_and_data(0xE1, cmd_e1, ARRAY_SIZEOF(cmd_e1)); portapack_lcd_data_write_command_and_data(0xE1, cmd_e1, ARRAY_SIZEOF(cmd_e1));
portapack_lcd_wake(); portapack_lcd_wake();
@ -422,26 +479,27 @@ static void portapack_lcd_init() {
portapack_lcd_data_write_command_and_data(0x35, cmd_35, ARRAY_SIZEOF(cmd_35)); portapack_lcd_data_write_command_and_data(0x35, cmd_35, ARRAY_SIZEOF(cmd_35));
} }
void portapack_backlight(const bool on) { void portapack_backlight(const bool on)
{
portapack_if.io_reg = (portapack_if.io_reg & 0x7f) | (on ? (1 << 7) : 0); portapack_if.io_reg = (portapack_if.io_reg & 0x7f) | (on ? (1 << 7) : 0);
portapack_io_write(1, portapack_if.io_reg); portapack_io_write(1, portapack_if.io_reg);
} }
void portapack_reference_oscillator(const bool on) { void portapack_reference_oscillator(const bool on)
{
const uint8_t mask = 1 << 6; const uint8_t mask = 1 << 6;
portapack_if.io_reg = (portapack_if.io_reg & ~mask) | (on ? mask : 0); portapack_if.io_reg = (portapack_if.io_reg & ~mask) | (on ? mask : 0);
portapack_io_write(1, portapack_if.io_reg); portapack_io_write(1, portapack_if.io_reg);
} }
void portapack_fill_rectangle( void portapack_fill_rectangle(const ui_rect_t rect, const ui_color_t color)
const ui_rect_t rect, {
const ui_color_t color
) {
portapack_lcd_start_ram_write(rect); portapack_lcd_start_ram_write(rect);
portapack_lcd_write_pixels_color(color, rect.size.width * rect.size.height); portapack_lcd_write_pixels_color(color, rect.size.width * rect.size.height);
} }
void portapack_clear_display(const ui_color_t color) { void portapack_clear_display(const ui_color_t color)
{
const ui_rect_t rect_screen = {{0, 0}, {240, 320}}; const ui_rect_t rect_screen = {{0, 0}, {240, 320}};
portapack_fill_rectangle(rect_screen, color); portapack_fill_rectangle(rect_screen, color);
} }
@ -450,12 +508,9 @@ void portapack_draw_bitmap(
const ui_point_t point, const ui_point_t point,
const ui_bitmap_t bitmap, const ui_bitmap_t bitmap,
const ui_color_t foreground, const ui_color_t foreground,
const ui_color_t background const ui_color_t background)
) { {
const ui_rect_t rect = { const ui_rect_t rect = {.point = point, .size = bitmap.size};
.point = point,
.size = bitmap.size
};
portapack_lcd_start_ram_write(rect); portapack_lcd_start_ram_write(rect);
@ -466,17 +521,14 @@ void portapack_draw_bitmap(
} }
} }
ui_bitmap_t portapack_font_glyph( ui_bitmap_t portapack_font_glyph(const ui_font_t* const font, const char c)
const ui_font_t* const font, {
const char c
) {
if (c >= font->c_start) { if (c >= font->c_start) {
const uint_fast8_t index = c - font->c_start; const uint_fast8_t index = c - font->c_start;
if (index < font->c_count) { if (index < font->c_count) {
const ui_bitmap_t bitmap = { const ui_bitmap_t bitmap = {
.size = font->glyph_size, .size = font->glyph_size,
.data = &font->data[index * font->data_stride] .data = &font->data[index * font->data_stride]};
};
return bitmap; return bitmap;
} }
} }
@ -488,7 +540,8 @@ ui_bitmap_t portapack_font_glyph(
return bitmap; return bitmap;
} }
static bool jtag_pp_tck(const bool tms_value) { static bool jtag_pp_tck(const bool tms_value)
{
gpio_write(jtag_cpld.gpio->gpio_pp_tms, tms_value); gpio_write(jtag_cpld.gpio->gpio_pp_tms, tms_value);
// 8 ns TMS/TDI to TCK setup // 8 ns TMS/TDI to TCK setup
@ -521,7 +574,8 @@ static bool jtag_pp_tck(const bool tms_value) {
return gpio_read(jtag_cpld.gpio->gpio_pp_tdo); return gpio_read(jtag_cpld.gpio->gpio_pp_tdo);
} }
static uint32_t jtag_pp_shift(const uint32_t tms_bits, const size_t count) { static uint32_t jtag_pp_shift(const uint32_t tms_bits, const size_t count)
{
uint32_t result = 0; uint32_t result = 0;
size_t bit_in_index = count - 1; size_t bit_in_index = count - 1;
size_t bit_out_index = 0; size_t bit_out_index = 0;
@ -536,7 +590,8 @@ static uint32_t jtag_pp_shift(const uint32_t tms_bits, const size_t count) {
return result; return result;
} }
static uint32_t jtag_pp_idcode(void) { static uint32_t jtag_pp_idcode(void)
{
cpld_jtag_take(&jtag_cpld); cpld_jtag_take(&jtag_cpld);
/* TODO: Check if PortaPack TMS is floating or driven by an external device. */ /* TODO: Check if PortaPack TMS is floating or driven by an external device. */
@ -556,20 +611,22 @@ static uint32_t jtag_pp_idcode(void) {
return idcode; return idcode;
} }
static bool portapack_detect(void) { static bool portapack_detect(void)
{
return jtag_pp_idcode() == 0x020A50DD; return jtag_pp_idcode() == 0x020A50DD;
} }
static const portapack_t portapack_instance = { static const portapack_t portapack_instance = {};
};
static const portapack_t* portapack_pointer = NULL; static const portapack_t* portapack_pointer = NULL;
const portapack_t* portapack(void) { const portapack_t* portapack(void)
{
return portapack_pointer; return portapack_pointer;
} }
void portapack_init(void) { void portapack_init(void)
{
if (portapack_detect()) { if (portapack_detect()) {
portapack_if_init(); portapack_if_init();
portapack_lcd_reset(); portapack_lcd_reset();

View File

@ -73,10 +73,7 @@ void portapack_backlight(const bool on);
void portapack_reference_oscillator(const bool on) __attribute__((weak)); void portapack_reference_oscillator(const bool on) __attribute__((weak));
void portapack_fill_rectangle( void portapack_fill_rectangle(const ui_rect_t rect, const ui_color_t color);
const ui_rect_t rect,
const ui_color_t color
);
void portapack_clear_display(const ui_color_t color); void portapack_clear_display(const ui_color_t color);
@ -84,12 +81,8 @@ void portapack_draw_bitmap(
const ui_point_t point, const ui_point_t point,
const ui_bitmap_t bitmap, const ui_bitmap_t bitmap,
const ui_color_t foreground, const ui_color_t foreground,
const ui_color_t background const ui_color_t background);
);
ui_bitmap_t portapack_font_glyph( ui_bitmap_t portapack_font_glyph(const ui_font_t* const font, const char c);
const ui_font_t* const font,
const char c
);
#endif /*__PORTAPACK_H__*/ #endif /*__PORTAPACK_H__*/

View File

@ -104,13 +104,10 @@ uint8_t *rad1o_pk_decode(const uint8_t *ldata, int *len)
if (pos == 8) { if (pos == 8) {
bufptr++; bufptr++;
if ((bufptr - charBuf) % height == if ((bufptr - charBuf) % height == 0) { // End of column?
0) { // End of column?
while (repeat > 0) { while (repeat > 0) {
for (int y = 0; y < height; for (int y = 0; y < height; y++) {
y++) { bufptr[0] = bufptr[-height];
bufptr[0] =
bufptr[-height];
bufptr++; bufptr++;
}; };
repeat--; repeat--;

View File

@ -44,9 +44,16 @@ static void select()
uint8_t serial_clock_rate = 1; uint8_t serial_clock_rate = 1;
uint8_t clock_prescale_rate = 12; uint8_t clock_prescale_rate = 12;
ssp_init(LCD_SSP, SSP_DATA_9BITS, SSP_FRAME_SPI, SSP_CPOL_0_CPHA_0, ssp_init(
serial_clock_rate, clock_prescale_rate, SSP_MODE_NORMAL, LCD_SSP,
SSP_MASTER, SSP_SLAVE_OUT_ENABLE); SSP_DATA_9BITS,
SSP_FRAME_SPI,
SSP_CPOL_0_CPHA_0,
serial_clock_rate,
clock_prescale_rate,
SSP_MODE_NORMAL,
SSP_MASTER,
SSP_SLAVE_OUT_ENABLE);
gpio_clear(&gpio_lcd_cs); gpio_clear(&gpio_lcd_cs);
} }
@ -87,17 +94,24 @@ void rad1o_lcdInit(void)
/* The controller is a PCF8833 - documentation can be found online. */ /* The controller is a PCF8833 - documentation can be found online. */
static uint8_t initseq_d[] = { static uint8_t initseq_d[] = {
0x11, // SLEEP_OUT (wake up) 0x11, // SLEEP_OUT (wake up)
0x3A, 2, // mode 8bpp (2= 8bpp, 3= 12bpp, 5= 16bpp) 0x3A,
0x36, 0b11000000, // my,mx,v,lao,rgb,x,x,x 2, // mode 8bpp (2= 8bpp, 3= 12bpp, 5= 16bpp)
0x25, 0x3a, // set contrast 0x36,
0b11000000, // my,mx,v,lao,rgb,x,x,x
0x25,
0x3a, // set contrast
0x29, // display on 0x29, // display on
0x03, // BSTRON (booster voltage) 0x03, // BSTRON (booster voltage)
0x2A, 1, RESX, 0x2B, 1, RESY 0x2A,
}; 1,
uint16_t initseq_c = ~(/* commands: 1, data: 0 */ RESX,
(1 << 0) | (1 << 1) | (0 << 2) | (1 << 3) | 0x2B,
(0 << 4) | (1 << 5) | (0 << 6) | (1 << 7) | 1,
(1 << 8) | (1 << 9) | (0 << 10) | (0 << 11) | RESY};
uint16_t initseq_c =
~(/* commands: 1, data: 0 */
(1 << 0) | (1 << 1) | (0 << 2) | (1 << 3) | (0 << 4) | (1 << 5) |
(0 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (0 << 10) | (0 << 11) |
(1 << 12) | (0 << 13) | (0 << 14) | 0); (1 << 12) | (0 << 13) | (0 << 14) | 0);
write(0, 0x01); /* most color displays need the pause */ write(0, 0x01); /* most color displays need the pause */

View File

@ -98,8 +98,7 @@ int rad1o_DoChar(int sx, int sy, int c)
data = &font->au8FontTable[toff + 3]; data = &font->au8FontTable[toff + 3];
width = (width - 3 / height); width = (width - 3 / height);
} else { } else {
data = rad1o_pk_decode( data = rad1o_pk_decode(&font->au8FontTable[toff], &width);
&font->au8FontTable[toff], &width);
} }
} else { } else {
toff = (c) *font->u8Width * 1; toff = (c) *font->u8Width * 1;
@ -109,8 +108,7 @@ int rad1o_DoChar(int sx, int sy, int c)
} while (0); } while (0);
#define xy_(x, y) \ #define xy_(x, y) ((x < 0 || y < 0 || x >= RESX || y >= RESY) ? 0 : (y) *RESX + (x))
((x < 0 || y < 0 || x >= RESX || y >= RESY) ? 0 : (y)*RESX + (x))
#define gPx(x, y) (data[x * height + (height - y / 8 - 1)] & (1 << (y % 8))) #define gPx(x, y) (data[x * height + (height - y / 8 - 1)] & (1 << (y % 8)))
int x = 0; int x = 0;

View File

@ -3399,11 +3399,11 @@ const FONT_CHAR_INFO Ubuntu18ptLengths[] = {
{30}, /* € */ {30}, /* € */
}; };
const uint16_t Ubuntu18ptExtra[] = { 196, 214, 220, 223, 228, const uint16_t Ubuntu18ptExtra[] = {196, 214, 220, 223, 228, 246, 252, 8364, 65535};
246, 252, 8364, 65535 };
/* Font info */ /* Font info */
const struct FONT_DEF Font_Ubuntu18pt = { 1, /* width (1 == comressed) */ const struct FONT_DEF Font_Ubuntu18pt = {
1, /* width (1 == comressed) */
26, /* character height */ 26, /* character height */
32, /* first char */ 32, /* first char */
126, /* last char */ 126, /* last char */

View File

@ -74,7 +74,9 @@
* Safe (initial) switch settings turn off both amplifiers and enable both amp * Safe (initial) switch settings turn off both amplifiers and enable both amp
* bypass and mixer bypass. * bypass and mixer bypass.
*/ */
#define SWITCHCTRL_SAFE (SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_TX | SWITCHCTRL_MIX_BYPASS | SWITCHCTRL_HP | SWITCHCTRL_NO_RX_AMP_PWR) #define SWITCHCTRL_SAFE \
(SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_TX | \
SWITCHCTRL_MIX_BYPASS | SWITCHCTRL_HP | SWITCHCTRL_NO_RX_AMP_PWR)
#endif #endif
uint8_t switchctrl = SWITCHCTRL_SAFE; uint8_t switchctrl = SWITCHCTRL_SAFE;
@ -88,7 +90,8 @@ uint8_t switchctrl = SWITCHCTRL_SAFE;
#define SWITCHCTRL_ANT_PWR (1 << 6) /* turn on antenna port power */ #define SWITCHCTRL_ANT_PWR (1 << 6) /* turn on antenna port power */
#ifdef HACKRF_ONE #ifdef HACKRF_ONE
static void switchctrl_set_hackrf_one(rf_path_t* const rf_path, uint8_t ctrl) { static void switchctrl_set_hackrf_one(rf_path_t* const rf_path, uint8_t ctrl)
{
if (ctrl & SWITCHCTRL_TX) { if (ctrl & SWITCHCTRL_TX) {
gpio_set(rf_path->gpio_tx); gpio_set(rf_path->gpio_tx);
gpio_clear(rf_path->gpio_rx); gpio_clear(rf_path->gpio_rx);
@ -161,7 +164,8 @@ static void switchctrl_set_hackrf_one(rf_path_t* const rf_path, uint8_t ctrl) {
#endif #endif
#ifdef RAD1O #ifdef RAD1O
static void switchctrl_set_rad1o(rf_path_t* const rf_path, uint8_t ctrl) { static void switchctrl_set_rad1o(rf_path_t* const rf_path, uint8_t ctrl)
{
if (ctrl & SWITCHCTRL_TX) { if (ctrl & SWITCHCTRL_TX) {
gpio_set(rf_path->gpio_tx_rx_n); gpio_set(rf_path->gpio_tx_rx_n);
gpio_clear(rf_path->gpio_tx_rx); gpio_clear(rf_path->gpio_tx_rx);
@ -224,7 +228,8 @@ static void switchctrl_set_rad1o(rf_path_t* const rf_path, uint8_t ctrl) {
} }
#endif #endif
static void switchctrl_set(rf_path_t* const rf_path, const uint8_t gpo) { static void switchctrl_set(rf_path_t* const rf_path, const uint8_t gpo)
{
#ifdef JAWBREAKER #ifdef JAWBREAKER
(void) rf_path; /* silence unused param warning */ (void) rf_path; /* silence unused param warning */
mixer_set_gpo(&mixer, gpo); mixer_set_gpo(&mixer, gpo);
@ -237,7 +242,8 @@ static void switchctrl_set(rf_path_t* const rf_path, const uint8_t gpo) {
#endif #endif
} }
void rf_path_pin_setup(rf_path_t* const rf_path) { void rf_path_pin_setup(rf_path_t* const rf_path)
{
#ifdef HACKRF_ONE #ifdef HACKRF_ONE
/* Configure RF switch control signals */ /* Configure RF switch control signals */
// clang-format off // clang-format off
@ -321,7 +327,8 @@ void rf_path_pin_setup(rf_path_t* const rf_path) {
#endif #endif
} }
void rf_path_init(rf_path_t* const rf_path) { void rf_path_init(rf_path_t* const rf_path)
{
ssp1_set_mode_max5864(); ssp1_set_mode_max5864();
max5864_setup(&max5864); max5864_setup(&max5864);
max5864_shutdown(&max5864); max5864_shutdown(&max5864);
@ -334,7 +341,8 @@ void rf_path_init(rf_path_t* const rf_path) {
switchctrl_set(rf_path, switchctrl); switchctrl_set(rf_path, switchctrl);
} }
void rf_path_set_direction(rf_path_t* const rf_path, const rf_path_direction_t direction) { void rf_path_set_direction(rf_path_t* const rf_path, const rf_path_direction_t direction)
{
/* Turn off TX and RX amplifiers, then enable based on direction and bypass state. */ /* Turn off TX and RX amplifiers, then enable based on direction and bypass state. */
rf_path->switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR; rf_path->switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR;
switch (direction) { switch (direction) {
@ -398,7 +406,8 @@ void rf_path_set_direction(rf_path_t* const rf_path, const rf_path_direction_t d
hackrf_ui()->set_direction(direction); hackrf_ui()->set_direction(direction);
} }
void rf_path_set_filter(rf_path_t* const rf_path, const rf_path_filter_t filter) { void rf_path_set_filter(rf_path_t* const rf_path, const rf_path_filter_t filter)
{
switch (filter) { switch (filter) {
default: default:
case RF_PATH_FILTER_BYPASS: case RF_PATH_FILTER_BYPASS:
@ -423,20 +432,24 @@ void rf_path_set_filter(rf_path_t* const rf_path, const rf_path_filter_t filter)
hackrf_ui()->set_filter(filter); hackrf_ui()->set_filter(filter);
} }
void rf_path_set_lna(rf_path_t* const rf_path, const uint_fast8_t enable) { void rf_path_set_lna(rf_path_t* const rf_path, const uint_fast8_t enable)
{
if (enable) { if (enable) {
if (rf_path->switchctrl & SWITCHCTRL_TX) { if (rf_path->switchctrl & SWITCHCTRL_TX) {
/* AMP_BYPASS=0, NO_RX_AMP_PWR=1, NO_TX_AMP_PWR=0 */ /* AMP_BYPASS=0, NO_RX_AMP_PWR=1, NO_TX_AMP_PWR=0 */
rf_path->switchctrl |= SWITCHCTRL_NO_RX_AMP_PWR; rf_path->switchctrl |= SWITCHCTRL_NO_RX_AMP_PWR;
rf_path->switchctrl &= ~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR); rf_path->switchctrl &=
~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR);
} else { } else {
/* AMP_BYPASS=0, NO_RX_AMP_PWR=0, NO_TX_AMP_PWR=1 */ /* AMP_BYPASS=0, NO_RX_AMP_PWR=0, NO_TX_AMP_PWR=1 */
rf_path->switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR; rf_path->switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR;
rf_path->switchctrl &= ~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_RX_AMP_PWR); rf_path->switchctrl &=
~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_RX_AMP_PWR);
} }
} else { } else {
/* AMP_BYPASS=1, NO_RX_AMP_PWR=1, NO_TX_AMP_PWR=1 */ /* AMP_BYPASS=1, NO_RX_AMP_PWR=1, NO_TX_AMP_PWR=1 */
rf_path->switchctrl |= SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR; rf_path->switchctrl |= SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR |
SWITCHCTRL_NO_RX_AMP_PWR;
} }
switchctrl_set(rf_path, rf_path->switchctrl); switchctrl_set(rf_path, rf_path->switchctrl);
@ -445,7 +458,8 @@ void rf_path_set_lna(rf_path_t* const rf_path, const uint_fast8_t enable) {
} }
/* antenna port power control */ /* antenna port power control */
void rf_path_set_antenna(rf_path_t* const rf_path, const uint_fast8_t enable) { void rf_path_set_antenna(rf_path_t* const rf_path, const uint_fast8_t enable)
{
if (enable) { if (enable) {
rf_path->switchctrl |= SWITCHCTRL_ANT_PWR; rf_path->switchctrl |= SWITCHCTRL_ANT_PWR;
} else { } else {

View File

@ -70,7 +70,8 @@ static const uint16_t rffc5071_regs_default[RFFC5071_NUM_REGS] = {
0x0000, /* 1B */ 0x0000, /* 1B */
0xc840, /* 1C */ 0xc840, /* 1C */
0x1000, /* 1D */ 0x1000, /* 1D */
0x0005, /* 1E */ }; 0x0005,
/* 1E */};
/* Set up all registers according to defaults specified in docs. */ /* Set up all registers according to defaults specified in docs. */
void rffc5071_init(rffc5071_driver_t* const drv) void rffc5071_init(rffc5071_driver_t* const drv)
@ -120,7 +121,8 @@ void rffc5071_setup(rffc5071_driver_t* const drv)
rffc5071_regs_commit(drv); rffc5071_regs_commit(drv);
} }
static uint16_t rffc5071_spi_read(rffc5071_driver_t* const drv, uint8_t r) { static uint16_t rffc5071_spi_read(rffc5071_driver_t* const drv, uint8_t r)
{
(void) drv; (void) drv;
uint16_t data[] = {0x80 | (r & 0x7f), 0xffff}; uint16_t data[] = {0x80 | (r & 0x7f), 0xffff};
@ -128,7 +130,8 @@ static uint16_t rffc5071_spi_read(rffc5071_driver_t* const drv, uint8_t r) {
return data[1]; return data[1];
} }
static void rffc5071_spi_write(rffc5071_driver_t* const drv, uint8_t r, uint16_t v) { static void rffc5071_spi_write(rffc5071_driver_t* const drv, uint8_t r, uint16_t v)
{
(void) drv; (void) drv;
uint16_t data[] = {0x00 | (r & 0x7f), v}; uint16_t data[] = {0x00 | (r & 0x7f), v};
@ -171,14 +174,16 @@ void rffc5071_regs_commit(rffc5071_driver_t* const drv)
} }
} }
void rffc5071_tx(rffc5071_driver_t* const drv) { void rffc5071_tx(rffc5071_driver_t* const drv)
{
set_RFFC5071_ENBL(drv, 0); set_RFFC5071_ENBL(drv, 0);
set_RFFC5071_FULLD(drv, 0); set_RFFC5071_FULLD(drv, 0);
set_RFFC5071_MODE(drv, 1); /* mixer 2 used for both RX and TX */ set_RFFC5071_MODE(drv, 1); /* mixer 2 used for both RX and TX */
rffc5071_regs_commit(drv); rffc5071_regs_commit(drv);
} }
void rffc5071_rx(rffc5071_driver_t* const drv) { void rffc5071_rx(rffc5071_driver_t* const drv)
{
set_RFFC5071_ENBL(drv, 0); set_RFFC5071_ENBL(drv, 0);
set_RFFC5071_FULLD(drv, 0); set_RFFC5071_FULLD(drv, 0);
set_RFFC5071_MODE(drv, 1); /* mixer 2 used for both RX and TX */ set_RFFC5071_MODE(drv, 1); /* mixer 2 used for both RX and TX */
@ -189,7 +194,8 @@ void rffc5071_rx(rffc5071_driver_t* const drv) {
* This function turns on both mixer (full-duplex) on the RFFC5071, but our * This function turns on both mixer (full-duplex) on the RFFC5071, but our
* current hardware designs do not support full-duplex operation. * current hardware designs do not support full-duplex operation.
*/ */
void rffc5071_rxtx(rffc5071_driver_t* const drv) { void rffc5071_rxtx(rffc5071_driver_t* const drv)
{
set_RFFC5071_ENBL(drv, 0); set_RFFC5071_ENBL(drv, 0);
set_RFFC5071_FULLD(drv, 1); /* mixer 1 and mixer 2 (RXTX) */ set_RFFC5071_FULLD(drv, 1); /* mixer 1 and mixer 2 (RXTX) */
rffc5071_regs_commit(drv); rffc5071_regs_commit(drv);
@ -197,12 +203,14 @@ void rffc5071_rxtx(rffc5071_driver_t* const drv) {
rffc5071_enable(drv); rffc5071_enable(drv);
} }
void rffc5071_disable(rffc5071_driver_t* const drv) { void rffc5071_disable(rffc5071_driver_t* const drv)
{
set_RFFC5071_ENBL(drv, 0); set_RFFC5071_ENBL(drv, 0);
rffc5071_regs_commit(drv); rffc5071_regs_commit(drv);
} }
void rffc5071_enable(rffc5071_driver_t* const drv) { void rffc5071_enable(rffc5071_driver_t* const drv)
{
set_RFFC5071_ENBL(drv, 1); set_RFFC5071_ENBL(drv, 1);
rffc5071_regs_commit(drv); rffc5071_regs_commit(drv);
} }
@ -212,7 +220,8 @@ void rffc5071_enable(rffc5071_driver_t* const drv) {
#define FREQ_ONE_MHZ (1000 * 1000) #define FREQ_ONE_MHZ (1000 * 1000)
/* configure frequency synthesizer in integer mode (lo in MHz) */ /* configure frequency synthesizer in integer mode (lo in MHz) */
uint64_t rffc5071_config_synth_int(rffc5071_driver_t* const drv, uint16_t lo) { uint64_t rffc5071_config_synth_int(rffc5071_driver_t* const drv, uint16_t lo)
{
uint8_t lodiv; uint8_t lodiv;
uint16_t fvco; uint16_t fvco;
uint8_t fbkdiv; uint8_t fbkdiv;
@ -251,8 +260,8 @@ uint64_t rffc5071_config_synth_int(rffc5071_driver_t* const drv, uint16_t lo) {
p1nmsb = (tmp_n >> 13ULL) & 0xffff; p1nmsb = (tmp_n >> 13ULL) & 0xffff;
p1nlsb = (tmp_n >> 5ULL) & 0xff; p1nlsb = (tmp_n >> 5ULL) & 0xff;
tune_freq_hz = (REF_FREQ * (tmp_n >> 5ULL) * fbkdiv * FREQ_ONE_MHZ) tune_freq_hz = (REF_FREQ * (tmp_n >> 5ULL) * fbkdiv * FREQ_ONE_MHZ) /
/ (lodiv * (1 << 24ULL)); (lodiv * (1 << 24ULL));
/* Path 2 */ /* Path 2 */
set_RFFC5071_P2LODIV(drv, n_lo); set_RFFC5071_P2LODIV(drv, n_lo);
@ -267,7 +276,8 @@ uint64_t rffc5071_config_synth_int(rffc5071_driver_t* const drv, uint16_t lo) {
} }
/* !!!!!!!!!!! hz is currently ignored !!!!!!!!!!! */ /* !!!!!!!!!!! hz is currently ignored !!!!!!!!!!! */
uint64_t rffc5071_set_frequency(rffc5071_driver_t* const drv, uint16_t mhz) { uint64_t rffc5071_set_frequency(rffc5071_driver_t* const drv, uint16_t mhz)
{
uint32_t tune_freq; uint32_t tune_freq;
rffc5071_disable(drv); rffc5071_disable(drv);

View File

@ -25,37 +25,44 @@
#include "rffc5071_spi.h" #include "rffc5071_spi.h"
static void rffc5071_spi_target_select(spi_bus_t* const bus) { static void rffc5071_spi_target_select(spi_bus_t* const bus)
{
const rffc5071_spi_config_t* const config = bus->config; const rffc5071_spi_config_t* const config = bus->config;
gpio_clear(config->gpio_select); gpio_clear(config->gpio_select);
} }
static void rffc5071_spi_target_unselect(spi_bus_t* const bus) { static void rffc5071_spi_target_unselect(spi_bus_t* const bus)
{
const rffc5071_spi_config_t* const config = bus->config; const rffc5071_spi_config_t* const config = bus->config;
gpio_set(config->gpio_select); gpio_set(config->gpio_select);
} }
static void rffc5071_spi_direction_out(spi_bus_t* const bus) { static void rffc5071_spi_direction_out(spi_bus_t* const bus)
{
const rffc5071_spi_config_t* const config = bus->config; const rffc5071_spi_config_t* const config = bus->config;
gpio_output(config->gpio_data); gpio_output(config->gpio_data);
} }
static void rffc5071_spi_direction_in(spi_bus_t* const bus) { static void rffc5071_spi_direction_in(spi_bus_t* const bus)
{
const rffc5071_spi_config_t* const config = bus->config; const rffc5071_spi_config_t* const config = bus->config;
gpio_input(config->gpio_data); gpio_input(config->gpio_data);
} }
static void rffc5071_spi_data_out(spi_bus_t* const bus, const bool bit) { static void rffc5071_spi_data_out(spi_bus_t* const bus, const bool bit)
{
const rffc5071_spi_config_t* const config = bus->config; const rffc5071_spi_config_t* const config = bus->config;
gpio_write(config->gpio_data, bit); gpio_write(config->gpio_data, bit);
} }
static bool rffc5071_spi_data_in(spi_bus_t* const bus) { static bool rffc5071_spi_data_in(spi_bus_t* const bus)
{
const rffc5071_spi_config_t* const config = bus->config; const rffc5071_spi_config_t* const config = bus->config;
return gpio_read(config->gpio_data); return gpio_read(config->gpio_data);
} }
static void rffc5071_spi_bus_init(spi_bus_t* const bus) { static void rffc5071_spi_bus_init(spi_bus_t* const bus)
{
const rffc5071_spi_config_t* const config = bus->config; const rffc5071_spi_config_t* const config = bus->config;
scu_pinmux(SCU_MIXER_SCLK, SCU_GPIO_FAST | SCU_CONF_FUNCTION4); scu_pinmux(SCU_MIXER_SCLK, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
@ -68,7 +75,8 @@ static void rffc5071_spi_bus_init(spi_bus_t* const bus) {
gpio_clear(config->gpio_data); gpio_clear(config->gpio_data);
} }
static void rffc5071_spi_target_init(spi_bus_t* const bus) { static void rffc5071_spi_target_init(spi_bus_t* const bus)
{
const rffc5071_spi_config_t* const config = bus->config; const rffc5071_spi_config_t* const config = bus->config;
/* Configure GPIO pins. */ /* Configure GPIO pins. */
@ -82,22 +90,26 @@ static void rffc5071_spi_target_init(spi_bus_t* const bus) {
rffc5071_spi_target_unselect(bus); rffc5071_spi_target_unselect(bus);
} }
void rffc5071_spi_start(spi_bus_t* const bus, const void* const config) { void rffc5071_spi_start(spi_bus_t* const bus, const void* const config)
{
bus->config = config; bus->config = config;
rffc5071_spi_bus_init(bus); rffc5071_spi_bus_init(bus);
rffc5071_spi_target_init(bus); rffc5071_spi_target_init(bus);
} }
void rffc5071_spi_stop(spi_bus_t* const bus) { void rffc5071_spi_stop(spi_bus_t* const bus)
{
(void) bus; (void) bus;
} }
static void rffc5071_spi_serial_delay(spi_bus_t* const bus) { static void rffc5071_spi_serial_delay(spi_bus_t* const bus)
{
(void) bus; (void) bus;
__asm__("nop"); __asm__("nop");
} }
static void rffc5071_spi_sck(spi_bus_t* const bus) { static void rffc5071_spi_sck(spi_bus_t* const bus)
{
const rffc5071_spi_config_t* const config = bus->config; const rffc5071_spi_config_t* const config = bus->config;
rffc5071_spi_serial_delay(bus); rffc5071_spi_serial_delay(bus);
@ -107,13 +119,18 @@ static void rffc5071_spi_sck(spi_bus_t* const bus) {
gpio_clear(config->gpio_clock); gpio_clear(config->gpio_clock);
} }
static uint32_t rffc5071_spi_exchange_bit(spi_bus_t* const bus, const uint32_t bit) { static uint32_t rffc5071_spi_exchange_bit(spi_bus_t* const bus, const uint32_t bit)
{
rffc5071_spi_data_out(bus, bit); rffc5071_spi_data_out(bus, bit);
rffc5071_spi_sck(bus); rffc5071_spi_sck(bus);
return rffc5071_spi_data_in(bus) ? 1 : 0; return rffc5071_spi_data_in(bus) ? 1 : 0;
} }
static uint32_t rffc5071_spi_exchange_word(spi_bus_t* const bus, const uint32_t data, const size_t count) { static uint32_t rffc5071_spi_exchange_word(
spi_bus_t* const bus,
const uint32_t data,
const size_t count)
{
size_t bits = count; size_t bits = count;
const uint32_t msb = 1UL << (count - 1); const uint32_t msb = 1UL << (count - 1);
uint32_t t = data; uint32_t t = data;
@ -141,7 +158,8 @@ static uint32_t rffc5071_spi_exchange_word(spi_bus_t* const bus, const uint32_t
* next 7 bits are register address, * next 7 bits are register address,
* next 16 bits are register value. * next 16 bits are register value.
*/ */
void rffc5071_spi_transfer(spi_bus_t* const bus, void* const _data, const size_t count) { void rffc5071_spi_transfer(spi_bus_t* const bus, void* const _data, const size_t count)
{
if (count != 2) { if (count != 2) {
return; return;
} }
@ -177,7 +195,11 @@ void rffc5071_spi_transfer(spi_bus_t* const bus, void* const _data, const size_t
rffc5071_spi_sck(bus); rffc5071_spi_sck(bus);
} }
void rffc5071_spi_transfer_gather(spi_bus_t* const bus, const spi_transfer_t* const transfer, const size_t count) { void rffc5071_spi_transfer_gather(
spi_bus_t* const bus,
const spi_transfer_t* const transfer,
const size_t count)
{
if (count == 1) { if (count == 1) {
rffc5071_spi_transfer(bus, transfer[0].data, transfer[0].count); rffc5071_spi_transfer(bus, transfer[0].data, transfer[0].count);
} }

View File

@ -36,6 +36,9 @@ typedef struct rffc5071_spi_config_t {
void rffc5071_spi_start(spi_bus_t* const bus, const void* const config); void rffc5071_spi_start(spi_bus_t* const bus, const void* const config);
void rffc5071_spi_stop(spi_bus_t* const bus); void rffc5071_spi_stop(spi_bus_t* const bus);
void rffc5071_spi_transfer(spi_bus_t* const bus, void* const data, const size_t count); void rffc5071_spi_transfer(spi_bus_t* const bus, void* const data, const size_t count);
void rffc5071_spi_transfer_gather(spi_bus_t* const bus, const spi_transfer_t* const transfer, const size_t count); void rffc5071_spi_transfer_gather(
spi_bus_t* const bus,
const spi_transfer_t* const transfer,
const size_t count);
#endif // __RFFC5071_SPI_H #endif // __RFFC5071_SPI_H

View File

@ -36,6 +36,7 @@ typedef struct {
const IAP_t IAP; /* If equal to 0x12345678 IAP not implemented */ const IAP_t IAP; /* If equal to 0x12345678 IAP not implemented */
/* Other TBD */ /* Other TBD */
} * pENTRY_ROM_API_t; } * pENTRY_ROM_API_t;
#define pROM_API ((pENTRY_ROM_API_t) ROM_IAP_ADDR) #define pROM_API ((pENTRY_ROM_API_t) ROM_IAP_ADDR)
/* /*
@ -54,11 +55,9 @@ typedef struct {
bool iap_is_implemented(void) bool iap_is_implemented(void)
{ {
bool res; bool res;
if( *((uint32_t*)ROM_IAP_ADDR) != ROM_IAP_UNDEF_ADDR ) if (*((uint32_t*) ROM_IAP_ADDR) != ROM_IAP_UNDEF_ADDR) {
{
res = true; res = true;
}else } else {
{
res = false; res = false;
} }
return res; return res;
@ -68,11 +67,11 @@ isp_iap_ret_code_t iap_cmd_call(iap_cmd_res_t* iap_cmd_res)
{ {
uint32_t* p_u32_data; uint32_t* p_u32_data;
if( iap_is_implemented() ) if (iap_is_implemented()) {
{ pROM_API->IAP(
pROM_API->IAP( (uint32_t*)&iap_cmd_res->cmd_param, (uint32_t*)&iap_cmd_res->status_res); (uint32_t*) &iap_cmd_res->cmd_param,
}else (uint32_t*) &iap_cmd_res->status_res);
{ } else {
/* /*
Alternative way to retrieve Part Id on MCU with no IAP Alternative way to retrieve Part Id on MCU with no IAP
Read Serial No => Read Unique ID in SPIFI (only compatible with W25Q80BV Read Serial No => Read Unique ID in SPIFI (only compatible with W25Q80BV
@ -80,8 +79,7 @@ isp_iap_ret_code_t iap_cmd_call(iap_cmd_res_t* iap_cmd_res)
spi_bus_start(spi_flash.bus, &ssp_config_w25q80bv); spi_bus_start(spi_flash.bus, &ssp_config_w25q80bv);
w25q80bv_setup(&spi_flash); w25q80bv_setup(&spi_flash);
switch(iap_cmd_res->cmd_param.command_code) switch (iap_cmd_res->cmd_param.command_code) {
{
case IAP_CMD_READ_PART_ID_NO: case IAP_CMD_READ_PART_ID_NO:
p_u32_data = (uint32_t*) ROM_OTP_PART_ID_ADDR; p_u32_data = (uint32_t*) ROM_OTP_PART_ID_ADDR;
iap_cmd_res->status_res.iap_result[0] = p_u32_data[0]; iap_cmd_res->status_res.iap_result[0] = p_u32_data[0];
@ -93,7 +91,10 @@ isp_iap_ret_code_t iap_cmd_call(iap_cmd_res_t* iap_cmd_res)
/* Only 64bits used */ /* Only 64bits used */
iap_cmd_res->status_res.iap_result[0] = 0; iap_cmd_res->status_res.iap_result[0] = 0;
iap_cmd_res->status_res.iap_result[1] = 0; iap_cmd_res->status_res.iap_result[1] = 0;
w25q80bv_get_unique_id(&spi_flash, (w25q80bv_unique_id_t*)&iap_cmd_res->status_res.iap_result[2] ); w25q80bv_get_unique_id(
&spi_flash,
(w25q80bv_unique_id_t*) &iap_cmd_res->status_res
.iap_result[2]);
iap_cmd_res->status_res.status_ret = CMD_SUCCESS; iap_cmd_res->status_res.status_ret = CMD_SUCCESS;
break; break;

View File

@ -95,20 +95,18 @@ typedef enum
/* Special Error */ /* Special Error */
ERROR_IAP_NOT_IMPLEMENTED = 0x00000100 /* IAP is not implemented in this part */ ERROR_IAP_NOT_IMPLEMENTED = 0x00000100 /* IAP is not implemented in this part */
} isp_iap_ret_code_t; } isp_iap_ret_code_t;
// clang-format on // clang-format on
typedef struct typedef struct {
{
/* Input Command/Param */ /* Input Command/Param */
struct struct {
{
iap_cmd_code_t command_code; iap_cmd_code_t command_code;
uint32_t iap_param[5]; uint32_t iap_param[5];
} cmd_param; } cmd_param;
/* Output Status/Result */ /* Output Status/Result */
struct struct {
{
isp_iap_ret_code_t status_ret; isp_iap_ret_code_t status_ret;
uint32_t iap_result[4]; uint32_t iap_result[4];
} status_res; } status_res;

View File

@ -630,8 +630,7 @@ EV[0:15]_CTRL[MATCHMEM, DIRECTION]
/* -- SCT_OUTPUTDIRCTRL_SETCLR10: Set/clear operation on output 5. Value 0x3 is /* -- SCT_OUTPUTDIRCTRL_SETCLR10: Set/clear operation on output 5. Value 0x3 is
* reserved. Do not program this value. */ * reserved. Do not program this value. */
#define SCT_OUTPUTDIRCTRL_SETCLR10_SHIFT (20) #define SCT_OUTPUTDIRCTRL_SETCLR10_SHIFT (20)
#define SCT_OUTPUTDIRCTRL_SETCLR10_MASK \ #define SCT_OUTPUTDIRCTRL_SETCLR10_MASK (0x03 << SCT_OUTPUTDIRCTRL_SETCLR10_SHIFT)
(0x03 << SCT_OUTPUTDIRCTRL_SETCLR10_SHIFT)
#define SCT_OUTPUTDIRCTRL_SETCLR10(x) ((x) << SCT_OUTPUTDIRCTRL_SETCLR10_SHIFT) #define SCT_OUTPUTDIRCTRL_SETCLR10(x) ((x) << SCT_OUTPUTDIRCTRL_SETCLR10_SHIFT)
/* SCT_OUTPUTDIRCTRL_SETCLR10_SETCLR10 values */ /* SCT_OUTPUTDIRCTRL_SETCLR10_SETCLR10 values */
@ -647,8 +646,7 @@ EV[0:15]_CTRL[MATCHMEM, DIRECTION]
/* -- SCT_OUTPUTDIRCTRL_SETCLR11: Set/clear operation on output 11. Value 0x3 is /* -- SCT_OUTPUTDIRCTRL_SETCLR11: Set/clear operation on output 11. Value 0x3 is
* reserved. Do not program this value. */ * reserved. Do not program this value. */
#define SCT_OUTPUTDIRCTRL_SETCLR11_SHIFT (22) #define SCT_OUTPUTDIRCTRL_SETCLR11_SHIFT (22)
#define SCT_OUTPUTDIRCTRL_SETCLR11_MASK \ #define SCT_OUTPUTDIRCTRL_SETCLR11_MASK (0x03 << SCT_OUTPUTDIRCTRL_SETCLR11_SHIFT)
(0x03 << SCT_OUTPUTDIRCTRL_SETCLR11_SHIFT)
#define SCT_OUTPUTDIRCTRL_SETCLR11(x) ((x) << SCT_OUTPUTDIRCTRL_SETCLR11_SHIFT) #define SCT_OUTPUTDIRCTRL_SETCLR11(x) ((x) << SCT_OUTPUTDIRCTRL_SETCLR11_SHIFT)
/* SCT_OUTPUTDIRCTRL_SETCLR11_SETCLR11 values */ /* SCT_OUTPUTDIRCTRL_SETCLR11_SETCLR11 values */
@ -664,8 +662,7 @@ EV[0:15]_CTRL[MATCHMEM, DIRECTION]
/* -- SCT_OUTPUTDIRCTRL_SETCLR12: Set/clear operation on output 12. Value 0x3 is /* -- SCT_OUTPUTDIRCTRL_SETCLR12: Set/clear operation on output 12. Value 0x3 is
* reserved. Do not program this value. */ * reserved. Do not program this value. */
#define SCT_OUTPUTDIRCTRL_SETCLR12_SHIFT (24) #define SCT_OUTPUTDIRCTRL_SETCLR12_SHIFT (24)
#define SCT_OUTPUTDIRCTRL_SETCLR12_MASK \ #define SCT_OUTPUTDIRCTRL_SETCLR12_MASK (0x03 << SCT_OUTPUTDIRCTRL_SETCLR12_SHIFT)
(0x03 << SCT_OUTPUTDIRCTRL_SETCLR12_SHIFT)
#define SCT_OUTPUTDIRCTRL_SETCLR12(x) ((x) << SCT_OUTPUTDIRCTRL_SETCLR12_SHIFT) #define SCT_OUTPUTDIRCTRL_SETCLR12(x) ((x) << SCT_OUTPUTDIRCTRL_SETCLR12_SHIFT)
/* SCT_OUTPUTDIRCTRL_SETCLR12_SETCLR12 values */ /* SCT_OUTPUTDIRCTRL_SETCLR12_SETCLR12 values */
@ -681,8 +678,7 @@ EV[0:15]_CTRL[MATCHMEM, DIRECTION]
/* -- SCT_OUTPUTDIRCTRL_SETCLR13: Set/clear operation on output 13. Value 0x3 is /* -- SCT_OUTPUTDIRCTRL_SETCLR13: Set/clear operation on output 13. Value 0x3 is
* reserved. Do not program this value. */ * reserved. Do not program this value. */
#define SCT_OUTPUTDIRCTRL_SETCLR13_SHIFT (26) #define SCT_OUTPUTDIRCTRL_SETCLR13_SHIFT (26)
#define SCT_OUTPUTDIRCTRL_SETCLR13_MASK \ #define SCT_OUTPUTDIRCTRL_SETCLR13_MASK (0x03 << SCT_OUTPUTDIRCTRL_SETCLR13_SHIFT)
(0x03 << SCT_OUTPUTDIRCTRL_SETCLR13_SHIFT)
#define SCT_OUTPUTDIRCTRL_SETCLR13(x) ((x) << SCT_OUTPUTDIRCTRL_SETCLR13_SHIFT) #define SCT_OUTPUTDIRCTRL_SETCLR13(x) ((x) << SCT_OUTPUTDIRCTRL_SETCLR13_SHIFT)
/* SCT_OUTPUTDIRCTRL_SETCLR13_SETCLR13 values */ /* SCT_OUTPUTDIRCTRL_SETCLR13_SETCLR13 values */
@ -698,8 +694,7 @@ EV[0:15]_CTRL[MATCHMEM, DIRECTION]
/* -- SCT_OUTPUTDIRCTRL_SETCLR14: Set/clear operation on output 14. Value 0x3 is /* -- SCT_OUTPUTDIRCTRL_SETCLR14: Set/clear operation on output 14. Value 0x3 is
* reserved. Do not program this value. */ * reserved. Do not program this value. */
#define SCT_OUTPUTDIRCTRL_SETCLR14_SHIFT (28) #define SCT_OUTPUTDIRCTRL_SETCLR14_SHIFT (28)
#define SCT_OUTPUTDIRCTRL_SETCLR14_MASK \ #define SCT_OUTPUTDIRCTRL_SETCLR14_MASK (0x03 << SCT_OUTPUTDIRCTRL_SETCLR14_SHIFT)
(0x03 << SCT_OUTPUTDIRCTRL_SETCLR14_SHIFT)
#define SCT_OUTPUTDIRCTRL_SETCLR14(x) ((x) << SCT_OUTPUTDIRCTRL_SETCLR14_SHIFT) #define SCT_OUTPUTDIRCTRL_SETCLR14(x) ((x) << SCT_OUTPUTDIRCTRL_SETCLR14_SHIFT)
/* SCT_OUTPUTDIRCTRL_SETCLR14_SETCLR14 values */ /* SCT_OUTPUTDIRCTRL_SETCLR14_SETCLR14 values */
@ -715,8 +710,7 @@ EV[0:15]_CTRL[MATCHMEM, DIRECTION]
/* -- SCT_OUTPUTDIRCTRL_SETCLR15: Set/clear operation on output 15. Value 0x3 is /* -- SCT_OUTPUTDIRCTRL_SETCLR15: Set/clear operation on output 15. Value 0x3 is
* reserved. Do not program this value. */ * reserved. Do not program this value. */
#define SCT_OUTPUTDIRCTRL_SETCLR15_SHIFT (30) #define SCT_OUTPUTDIRCTRL_SETCLR15_SHIFT (30)
#define SCT_OUTPUTDIRCTRL_SETCLR15_MASK \ #define SCT_OUTPUTDIRCTRL_SETCLR15_MASK (0x03 << SCT_OUTPUTDIRCTRL_SETCLR15_SHIFT)
(0x03 << SCT_OUTPUTDIRCTRL_SETCLR15_SHIFT)
#define SCT_OUTPUTDIRCTRL_SETCLR15(x) ((x) << SCT_OUTPUTDIRCTRL_SETCLR15_SHIFT) #define SCT_OUTPUTDIRCTRL_SETCLR15(x) ((x) << SCT_OUTPUTDIRCTRL_SETCLR15_SHIFT)
/* SCT_OUTPUTDIRCTRL_SETCLR15_SETCLR15 values */ /* SCT_OUTPUTDIRCTRL_SETCLR15_SETCLR15 values */

View File

@ -32,7 +32,8 @@
static void update_q_invert(sgpio_config_t* const config); static void update_q_invert(sgpio_config_t* const config);
#endif #endif
void sgpio_configure_pin_functions(sgpio_config_t* const config) { void sgpio_configure_pin_functions(sgpio_config_t* const config)
{
scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3);
scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3);
scu_pinmux(SCU_PINMUX_SGPIO2, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); scu_pinmux(SCU_PINMUX_SGPIO2, SCU_GPIO_FAST | SCU_CONF_FUNCTION2);
@ -57,10 +58,8 @@ void sgpio_configure_pin_functions(sgpio_config_t* const config) {
gpio_output(config->gpio_hw_sync_enable); gpio_output(config->gpio_hw_sync_enable);
} }
void sgpio_set_slice_mode( void sgpio_set_slice_mode(sgpio_config_t* const config, const bool multi_slice)
sgpio_config_t* const config, {
const bool multi_slice
) {
config->slice_mode_multislice = multi_slice; config->slice_mode_multislice = multi_slice;
} }
@ -95,16 +94,13 @@ void sgpio_set_slice_mode(
SGPIO10 Disable Output (1/High=Disable codec data stream, 0/Low=Enable codec data stream) SGPIO10 Disable Output (1/High=Disable codec data stream, 0/Low=Enable codec data stream)
SGPIO11 Direction Output (1/High=TX mode LPC43xx=>CPLD=>DAC, 0/Low=RX mode LPC43xx<=CPLD<=ADC) SGPIO11 Direction Output (1/High=TX mode LPC43xx=>CPLD=>DAC, 0/Low=RX mode LPC43xx<=CPLD<=ADC)
*/ */
void sgpio_configure( void sgpio_configure(sgpio_config_t* const config, const sgpio_direction_t direction)
sgpio_config_t* const config, {
const sgpio_direction_t direction
) {
// Disable all counters during configuration // Disable all counters during configuration
SGPIO_CTRL_ENABLE = 0; SGPIO_CTRL_ENABLE = 0;
// Set SGPIO output values. // Set SGPIO output values.
const uint_fast8_t cpld_direction = const uint_fast8_t cpld_direction = (direction == SGPIO_DIRECTION_TX) ? 1 : 0;
(direction == SGPIO_DIRECTION_TX) ? 1 : 0;
// clang-format off // clang-format off
SGPIO_GPIO_OUTREG = SGPIO_GPIO_OUTREG =
@ -123,9 +119,7 @@ void sgpio_configure(
// Enable SGPIO pin outputs. // Enable SGPIO pin outputs.
const uint_fast16_t sgpio_gpio_data_direction = const uint_fast16_t sgpio_gpio_data_direction =
(direction == SGPIO_DIRECTION_TX) (direction == SGPIO_DIRECTION_TX) ? (0xFF << 0) : (0x00 << 0);
? (0xFF << 0)
: (0x00 << 0);
// clang-format off // clang-format off
SGPIO_GPIO_OENREG = SGPIO_GPIO_OENREG =
@ -190,8 +184,7 @@ void sgpio_configure(
uint32_t slice_enable_mask = BIT3; uint32_t slice_enable_mask = BIT3;
/* Configure Slice A, I, E, J, C, K, F, L (sgpio_slice_mode_multislice mode) */ /* Configure Slice A, I, E, J, C, K, F, L (sgpio_slice_mode_multislice mode) */
for(uint_fast8_t i=0; i<slice_count; i++) for (uint_fast8_t i = 0; i < slice_count; i++) {
{
const uint_fast8_t slice_index = slice_indices[i]; const uint_fast8_t slice_index = slice_indices[i];
/* Only for slice0/A and RX mode set input_slice to 1 */ /* Only for slice0/A and RX mode set input_slice to 1 */
const bool input_slice = (i == 0) && (direction != SGPIO_DIRECTION_TX); const bool input_slice = (i == 0) && (direction != SGPIO_DIRECTION_TX);
@ -224,10 +217,7 @@ void sgpio_configure(
SGPIO_PRESET(slice_index) = 0; // External clock, don't care SGPIO_PRESET(slice_index) = 0; // External clock, don't care
SGPIO_COUNT(slice_index) = 0; // External clock, don't care SGPIO_COUNT(slice_index) = 0; // External clock, don't care
SGPIO_POS(slice_index) = SGPIO_POS(slice_index) = SGPIO_POS_POS_RESET(pos) | SGPIO_POS_POS(pos);
SGPIO_POS_POS_RESET(pos)
| SGPIO_POS_POS(pos)
;
SGPIO_REG(slice_index) = 0x00000000; // Primary output data register SGPIO_REG(slice_index) = 0x00000000; // Primary output data register
SGPIO_REG_SS(slice_index) = 0x00000000; // Shadow output data register SGPIO_REG_SS(slice_index) = 0x00000000; // Shadow output data register
// clang-format on // clang-format on
@ -260,12 +250,11 @@ void sgpio_configure(
SGPIO_PRESET(slice_gpdma) = 0; // External clock, don't care SGPIO_PRESET(slice_gpdma) = 0; // External clock, don't care
SGPIO_COUNT(slice_gpdma) = 0; // External clock, don't care SGPIO_COUNT(slice_gpdma) = 0; // External clock, don't care
SGPIO_POS(slice_gpdma) = SGPIO_POS(slice_gpdma) = SGPIO_POS_POS_RESET(0x1f) | SGPIO_POS_POS(0x1f);
SGPIO_POS_POS_RESET(0x1f) SGPIO_REG(slice_gpdma) =
| SGPIO_POS_POS(0x1f) 0x11111111; // Primary output data register, LSB -> out
; SGPIO_REG_SS(slice_gpdma) =
SGPIO_REG(slice_gpdma) = 0x11111111; // Primary output data register, LSB -> out 0x11111111; // Shadow output data register, LSB -> out1
SGPIO_REG_SS(slice_gpdma) = 0x11111111; // Shadow output data register, LSB -> out1
slice_enable_mask |= (1 << slice_gpdma); slice_enable_mask |= (1 << slice_gpdma);
} }
@ -274,24 +263,26 @@ void sgpio_configure(
SGPIO_CTRL_ENABLE = slice_enable_mask; SGPIO_CTRL_ENABLE = slice_enable_mask;
} }
void sgpio_cpld_stream_enable(sgpio_config_t* const config) { void sgpio_cpld_stream_enable(sgpio_config_t* const config)
{
(void) config; (void) config;
// Enable codec data stream. // Enable codec data stream.
SGPIO_GPIO_OUTREG &= ~(1L << 10); /* SGPIO10 */ SGPIO_GPIO_OUTREG &= ~(1L << 10); /* SGPIO10 */
} }
void sgpio_cpld_stream_disable(sgpio_config_t* const config) { void sgpio_cpld_stream_disable(sgpio_config_t* const config)
{
(void) config; (void) config;
// Disable codec data stream. // Disable codec data stream.
SGPIO_GPIO_OUTREG |= (1L << 10); /* SGPIO10 */ SGPIO_GPIO_OUTREG |= (1L << 10); /* SGPIO10 */
} }
bool sgpio_cpld_stream_is_enabled(sgpio_config_t* const config) { bool sgpio_cpld_stream_is_enabled(sgpio_config_t* const config)
{
(void) config; (void) config;
return (SGPIO_GPIO_OUTREG & (1L << 10)) == 0; /* SGPIO10 */ return (SGPIO_GPIO_OUTREG & (1L << 10)) == 0; /* SGPIO10 */
} }
#ifdef RAD1O #ifdef RAD1O
/* The rad1o hardware has a bug which makes it /* The rad1o hardware has a bug which makes it
* necessary to also switch between the two options based * necessary to also switch between the two options based
@ -306,7 +297,8 @@ static bool sgpio_invert = false;
/* Called when TX/RX changes od sgpio_cpld_stream_rx_set_q_invert /* Called when TX/RX changes od sgpio_cpld_stream_rx_set_q_invert
* gets called. */ * gets called. */
static void update_q_invert(sgpio_config_t* const config) { static void update_q_invert(sgpio_config_t* const config)
{
/* 1=Output SGPIO11 High(TX mode), 0=Output SGPIO11 Low(RX mode) */ /* 1=Output SGPIO11 High(TX mode), 0=Output SGPIO11 Low(RX mode) */
bool tx_mode = (SGPIO_GPIO_OUTREG & (1 << 11)) > 0; bool tx_mode = (SGPIO_GPIO_OUTREG & (1 << 11)) > 0;
@ -322,7 +314,10 @@ static void update_q_invert(sgpio_config_t* const config) {
} }
} }
void sgpio_cpld_stream_rx_set_q_invert(sgpio_config_t* const config, const uint_fast8_t invert) { void sgpio_cpld_stream_rx_set_q_invert(
sgpio_config_t* const config,
const uint_fast8_t invert)
{
if (invert) { if (invert) {
sgpio_invert = true; sgpio_invert = true;
} else { } else {
@ -333,7 +328,10 @@ void sgpio_cpld_stream_rx_set_q_invert(sgpio_config_t* const config, const uint_
} }
#else #else
void sgpio_cpld_stream_rx_set_q_invert(sgpio_config_t* const config, const uint_fast8_t invert) { void sgpio_cpld_stream_rx_set_q_invert(
sgpio_config_t* const config,
const uint_fast8_t invert)
{
gpio_write(config->gpio_rx_q_invert, invert); gpio_write(config->gpio_rx_q_invert, invert);
} }
#endif #endif

View File

@ -42,18 +42,14 @@ typedef struct sgpio_config_t {
void sgpio_configure_pin_functions(sgpio_config_t* const config); void sgpio_configure_pin_functions(sgpio_config_t* const config);
void sgpio_test_interface(sgpio_config_t* const config); void sgpio_test_interface(sgpio_config_t* const config);
void sgpio_set_slice_mode( void sgpio_set_slice_mode(sgpio_config_t* const config, const bool multi_slice);
sgpio_config_t* const config, void sgpio_configure(sgpio_config_t* const config, const sgpio_direction_t direction);
const bool multi_slice
);
void sgpio_configure(
sgpio_config_t* const config,
const sgpio_direction_t direction
);
void sgpio_cpld_stream_enable(sgpio_config_t* const config); void sgpio_cpld_stream_enable(sgpio_config_t* const config);
void sgpio_cpld_stream_disable(sgpio_config_t* const config); void sgpio_cpld_stream_disable(sgpio_config_t* const config);
bool sgpio_cpld_stream_is_enabled(sgpio_config_t* const config); bool sgpio_cpld_stream_is_enabled(sgpio_config_t* const config);
void sgpio_cpld_stream_rx_set_q_invert(sgpio_config_t* const config, const uint_fast8_t invert); void sgpio_cpld_stream_rx_set_q_invert(
sgpio_config_t* const config,
const uint_fast8_t invert);
#endif //__SGPIO_H__ #endif //__SGPIO_H__

View File

@ -46,7 +46,10 @@ uint8_t si5351c_read_single(si5351c_driver_t* const drv, uint8_t reg)
* Write to one or more contiguous registers. data[0] should be the first * Write to one or more contiguous registers. data[0] should be the first
* register number, one or more values follow. * register number, one or more values follow.
*/ */
void si5351c_write(si5351c_driver_t* const drv, const uint8_t* const data, const size_t data_count) void si5351c_write(
si5351c_driver_t* const drv,
const uint8_t* const data,
const size_t data_count)
{ {
i2c_bus_transfer(drv->bus, drv->i2c_address, data, data_count, NULL, 0); i2c_bus_transfer(drv->bus, drv->i2c_address, data, data_count, NULL, 0);
} }
@ -68,16 +71,16 @@ void si5351c_disable_oeb_pin_control(si5351c_driver_t* const drv)
/* Power down all CLKx */ /* Power down all CLKx */
void si5351c_power_down_all_clocks(si5351c_driver_t* const drv) void si5351c_power_down_all_clocks(si5351c_driver_t* const drv)
{ {
uint8_t data[] = { 16 uint8_t data[] = {
, SI5351C_CLK_POWERDOWN 16,
, SI5351C_CLK_POWERDOWN SI5351C_CLK_POWERDOWN,
, SI5351C_CLK_POWERDOWN SI5351C_CLK_POWERDOWN,
, SI5351C_CLK_POWERDOWN SI5351C_CLK_POWERDOWN,
, SI5351C_CLK_POWERDOWN SI5351C_CLK_POWERDOWN,
, SI5351C_CLK_POWERDOWN SI5351C_CLK_POWERDOWN,
, SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE SI5351C_CLK_POWERDOWN,
, SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE,
}; SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE};
si5351c_write(drv, data, sizeof(data)); si5351c_write(drv, data, sizeof(data));
} }
@ -135,9 +138,12 @@ void si5351c_reset_pll(si5351c_driver_t* const drv)
si5351c_write(drv, data, sizeof(data)); si5351c_write(drv, data, sizeof(data));
} }
void si5351c_configure_multisynth(si5351c_driver_t* const drv, void si5351c_configure_multisynth(
si5351c_driver_t* const drv,
const uint_fast8_t ms_number, const uint_fast8_t ms_number,
const uint32_t p1, const uint32_t p2, const uint32_t p3, const uint32_t p1,
const uint32_t p2,
const uint32_t p3,
const uint_fast8_t r_div) const uint_fast8_t r_div)
{ {
/* /*
@ -166,7 +172,9 @@ void si5351c_configure_multisynth(si5351c_driver_t* const drv,
si5351c_write(drv, data, sizeof(data)); si5351c_write(drv, data, sizeof(data));
} }
void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll_sources source) void si5351c_configure_clock_control(
si5351c_driver_t* const drv,
const enum pll_sources source)
{ {
uint8_t pll; uint8_t pll;
#ifdef RAD1O #ifdef RAD1O
@ -186,15 +194,29 @@ void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll
#endif #endif
/* Clock to CPU is deactivated as it is not used and creates noise */ /* Clock to CPU is deactivated as it is not used and creates noise */
/* External clock output is kept in current state */ /* External clock output is kept in current state */
uint8_t data[] = {16 uint8_t data[] = {
,SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA) 16,
,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA) | SI5351C_CLK_INV SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(pll) |
,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA) SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
,clk3_ctrl SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA),
,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_6MA) | SI5351C_CLK_INV SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) |
,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA) SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) |
,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/ SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA) | SI5351C_CLK_INV,
,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/ SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA),
clk3_ctrl,
SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_6MA) | SI5351C_CLK_INV,
SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA),
SI5351C_CLK_POWERDOWN |
SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/
,
SI5351C_CLK_POWERDOWN |
SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/
}; };
si5351c_write(drv, data, sizeof(data)); si5351c_write(drv, data, sizeof(data));
} }
@ -210,20 +232,20 @@ void si5351c_enable_clock_outputs(si5351c_driver_t* const drv)
/* 7: Clock to CPU is deactivated as it is not used and creates noise */ /* 7: Clock to CPU is deactivated as it is not used and creates noise */
/* 3: External clock output is deactivated by default */ /* 3: External clock output is deactivated by default */
// uint8_t data[] = { 3, ~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4) | (1 << 5))}; // uint8_t data[] = { 3, ~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4) | (1 << 5))};
uint8_t data[] = { SI5351C_REG_OUTPUT_EN, uint8_t data[] = {
SI5351C_CLK_ENABLE(0) | SI5351C_REG_OUTPUT_EN,
SI5351C_CLK_ENABLE(1) | SI5351C_CLK_ENABLE(0) | SI5351C_CLK_ENABLE(1) | SI5351C_CLK_ENABLE(2) |
SI5351C_CLK_ENABLE(2) | SI5351C_CLK_DISABLE(3) | SI5351C_CLK_ENABLE(4) |
SI5351C_CLK_DISABLE(3) | SI5351C_CLK_ENABLE(5) | SI5351C_CLK_DISABLE(6) |
SI5351C_CLK_ENABLE(4) | SI5351C_CLK_DISABLE(7)};
SI5351C_CLK_ENABLE(5) |
SI5351C_CLK_DISABLE(6) |
SI5351C_CLK_DISABLE(7)
};
si5351c_write(drv, data, sizeof(data)); si5351c_write(drv, data, sizeof(data));
} }
void si5351c_set_int_mode(si5351c_driver_t* const drv, const uint_fast8_t ms_number, const uint_fast8_t on){ void si5351c_set_int_mode(
si5351c_driver_t* const drv,
const uint_fast8_t ms_number,
const uint_fast8_t on)
{
uint8_t data[] = {16, 0}; uint8_t data[] = {16, 0};
if (ms_number < 8) { if (ms_number < 8) {
@ -247,7 +269,8 @@ void si5351c_set_clock_source(si5351c_driver_t* const drv, const enum pll_source
} }
} }
bool si5351c_clkin_signal_valid(si5351c_driver_t* const drv) { bool si5351c_clkin_signal_valid(si5351c_driver_t* const drv)
{
return (si5351c_read_single(drv, 0) & SI5351C_LOS) == 0; return (si5351c_read_single(drv, 0) & SI5351C_LOS) == 0;
} }
@ -283,7 +306,9 @@ void si5351c_clkout_enable(si5351c_driver_t* const drv, uint8_t enable)
} }
#endif #endif
if (enable) if (enable)
clk3_ctrl = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA); clk3_ctrl = SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) |
SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) |
SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA);
else else
clk3_ctrl = SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE; clk3_ctrl = SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE;
uint8_t clk3_data[] = {SI5351C_REG_CLK3_CTRL, clk3_ctrl}; uint8_t clk3_data[] = {SI5351C_REG_CLK3_CTRL, clk3_ctrl};

View File

@ -24,8 +24,7 @@
#define __SI5351C_H #define __SI5351C_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C" {
{
#endif #endif
#include <stdint.h> #include <stdint.h>
@ -78,19 +77,30 @@ void si5351c_enable_xo_and_ms_fanout(si5351c_driver_t* const drv);
void si5351c_configure_pll_sources(si5351c_driver_t* const drv); void si5351c_configure_pll_sources(si5351c_driver_t* const drv);
void si5351c_configure_pll_multisynth(si5351c_driver_t* const drv); void si5351c_configure_pll_multisynth(si5351c_driver_t* const drv);
void si5351c_reset_pll(si5351c_driver_t* const drv); void si5351c_reset_pll(si5351c_driver_t* const drv);
void si5351c_configure_multisynth(si5351c_driver_t* const drv, void si5351c_configure_multisynth(
si5351c_driver_t* const drv,
const uint_fast8_t ms_number, const uint_fast8_t ms_number,
const uint32_t p1, const uint32_t p2, const uint32_t p3, const uint32_t p1,
const uint32_t p2,
const uint32_t p3,
const uint_fast8_t r_div); const uint_fast8_t r_div);
void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll_sources source); void si5351c_configure_clock_control(
si5351c_driver_t* const drv,
const enum pll_sources source);
void si5351c_enable_clock_outputs(si5351c_driver_t* const drv); void si5351c_enable_clock_outputs(si5351c_driver_t* const drv);
void si5351c_set_int_mode(si5351c_driver_t* const drv, const uint_fast8_t ms_number, const uint_fast8_t on); void si5351c_set_int_mode(
si5351c_driver_t* const drv,
const uint_fast8_t ms_number,
const uint_fast8_t on);
void si5351c_set_clock_source(si5351c_driver_t* const drv, const enum pll_sources source); void si5351c_set_clock_source(si5351c_driver_t* const drv, const enum pll_sources source);
bool si5351c_clkin_signal_valid(si5351c_driver_t* const drv); bool si5351c_clkin_signal_valid(si5351c_driver_t* const drv);
void si5351c_write_single(si5351c_driver_t* const drv, uint8_t reg, uint8_t val); void si5351c_write_single(si5351c_driver_t* const drv, uint8_t reg, uint8_t val);
uint8_t si5351c_read_single(si5351c_driver_t* const drv, uint8_t reg); uint8_t si5351c_read_single(si5351c_driver_t* const drv, uint8_t reg);
void si5351c_write(si5351c_driver_t* const drv, const uint8_t* const data, const size_t data_count); void si5351c_write(
si5351c_driver_t* const drv,
const uint8_t* const data,
const size_t data_count);
void si5351c_clkout_enable(si5351c_driver_t* const drv, uint8_t enable); void si5351c_clkout_enable(si5351c_driver_t* const drv, uint8_t enable);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -21,18 +21,25 @@
#include "spi_bus.h" #include "spi_bus.h"
void spi_bus_start(spi_bus_t* const bus, const void* const config) { void spi_bus_start(spi_bus_t* const bus, const void* const config)
{
bus->start(bus, config); bus->start(bus, config);
} }
void spi_bus_stop(spi_bus_t* const bus) { void spi_bus_stop(spi_bus_t* const bus)
{
bus->stop(bus); bus->stop(bus);
} }
void spi_bus_transfer(spi_bus_t* const bus, void* const data, const size_t count) { void spi_bus_transfer(spi_bus_t* const bus, void* const data, const size_t count)
{
bus->transfer(bus, data, count); bus->transfer(bus, data, count);
} }
void spi_bus_transfer_gather(spi_bus_t* const bus, const spi_transfer_t* const transfers, const size_t count) { void spi_bus_transfer_gather(
spi_bus_t* const bus,
const spi_transfer_t* const transfers,
const size_t count)
{
bus->transfer_gather(bus, transfers, count); bus->transfer_gather(bus, transfers, count);
} }

View File

@ -38,12 +38,18 @@ struct spi_bus_t {
void (*start)(spi_bus_t* const bus, const void* const config); void (*start)(spi_bus_t* const bus, const void* const config);
void (*stop)(spi_bus_t* const bus); void (*stop)(spi_bus_t* const bus);
void (*transfer)(spi_bus_t* const bus, void* const data, const size_t count); void (*transfer)(spi_bus_t* const bus, void* const data, const size_t count);
void (*transfer_gather)(spi_bus_t* const bus, const spi_transfer_t* const transfers, const size_t count); void (*transfer_gather)(
spi_bus_t* const bus,
const spi_transfer_t* const transfers,
const size_t count);
}; };
void spi_bus_start(spi_bus_t* const bus, const void* const config); void spi_bus_start(spi_bus_t* const bus, const void* const config);
void spi_bus_stop(spi_bus_t* const bus); void spi_bus_stop(spi_bus_t* const bus);
void spi_bus_transfer(spi_bus_t* const bus, void* const data, const size_t count); void spi_bus_transfer(spi_bus_t* const bus, void* const data, const size_t count);
void spi_bus_transfer_gather(spi_bus_t* const bus, const spi_transfer_t* const transfers, const size_t count); void spi_bus_transfer_gather(
spi_bus_t* const bus,
const spi_transfer_t* const transfers,
const size_t count);
#endif /*__SPI_BUS_H__*/ #endif /*__SPI_BUS_H__*/

View File

@ -24,7 +24,8 @@
#include <libopencm3/lpc43xx/rgu.h> #include <libopencm3/lpc43xx/rgu.h>
#include <libopencm3/lpc43xx/ssp.h> #include <libopencm3/lpc43xx/ssp.h>
void spi_ssp_start(spi_bus_t* const bus, const void* const _config) { void spi_ssp_start(spi_bus_t* const bus, const void* const _config)
{
const ssp_config_t* const config = _config; const ssp_config_t* const config = _config;
if (bus->obj == (void*) SSP0_BASE) { if (bus->obj == (void*) SSP0_BASE) {
@ -37,39 +38,36 @@ void spi_ssp_start(spi_bus_t* const bus, const void* const _config) {
SSP_CR1(bus->obj) = 0; SSP_CR1(bus->obj) = 0;
SSP_CPSR(bus->obj) = config->clock_prescale_rate; SSP_CPSR(bus->obj) = config->clock_prescale_rate;
SSP_CR0(bus->obj) = SSP_CR0(bus->obj) = (config->serial_clock_rate << 8) | SSP_CPOL_0_CPHA_0 |
(config->serial_clock_rate << 8) SSP_FRAME_SPI | config->data_bits;
| SSP_CPOL_0_CPHA_0
| SSP_FRAME_SPI
| config->data_bits
;
SSP_CR1(bus->obj) = SSP_CR1(bus->obj) =
SSP_SLAVE_OUT_ENABLE SSP_SLAVE_OUT_ENABLE | SSP_MASTER | SSP_ENABLE | SSP_MODE_NORMAL;
| SSP_MASTER
| SSP_ENABLE
| SSP_MODE_NORMAL
;
bus->config = config; bus->config = config;
} }
void spi_ssp_stop(spi_bus_t* const bus) { void spi_ssp_stop(spi_bus_t* const bus)
{
SSP_CR1(bus->obj) = 0; SSP_CR1(bus->obj) = 0;
} }
static void spi_ssp_wait_for_tx_fifo_not_full(spi_bus_t* const bus) { static void spi_ssp_wait_for_tx_fifo_not_full(spi_bus_t* const bus)
{
while ((SSP_SR(bus->obj) & SSP_SR_TNF) == 0) {} while ((SSP_SR(bus->obj) & SSP_SR_TNF) == 0) {}
} }
static void spi_ssp_wait_for_rx_fifo_not_empty(spi_bus_t* const bus) { static void spi_ssp_wait_for_rx_fifo_not_empty(spi_bus_t* const bus)
{
while ((SSP_SR(bus->obj) & SSP_SR_RNE) == 0) {} while ((SSP_SR(bus->obj) & SSP_SR_RNE) == 0) {}
} }
static void spi_ssp_wait_for_not_busy(spi_bus_t* const bus) { static void spi_ssp_wait_for_not_busy(spi_bus_t* const bus)
{
while (SSP_SR(bus->obj) & SSP_SR_BSY) {} while (SSP_SR(bus->obj) & SSP_SR_BSY) {}
} }
static uint32_t spi_ssp_transfer_word(spi_bus_t* const bus, const uint32_t data) { static uint32_t spi_ssp_transfer_word(spi_bus_t* const bus, const uint32_t data)
{
spi_ssp_wait_for_tx_fifo_not_full(bus); spi_ssp_wait_for_tx_fifo_not_full(bus);
SSP_DR(bus->obj) = data; SSP_DR(bus->obj) = data;
spi_ssp_wait_for_not_busy(bus); spi_ssp_wait_for_not_busy(bus);
@ -77,7 +75,11 @@ static uint32_t spi_ssp_transfer_word(spi_bus_t* const bus, const uint32_t data)
return SSP_DR(bus->obj); return SSP_DR(bus->obj);
} }
void spi_ssp_transfer_gather(spi_bus_t* const bus, const spi_transfer_t* const transfers, const size_t count) { void spi_ssp_transfer_gather(
spi_bus_t* const bus,
const spi_transfer_t* const transfers,
const size_t count)
{
const ssp_config_t* const config = bus->config; const ssp_config_t* const config = bus->config;
const bool word_size_u16 = (SSP_CR0(bus->obj) & 0xf) > SSP_DATA_8BITS; const bool word_size_u16 = (SSP_CR0(bus->obj) & 0xf) > SSP_DATA_8BITS;
@ -101,7 +103,8 @@ void spi_ssp_transfer_gather(spi_bus_t* const bus, const spi_transfer_t* const t
gpio_set(config->gpio_select); gpio_set(config->gpio_select);
} }
void spi_ssp_transfer(spi_bus_t* const bus, void* const data, const size_t count) { void spi_ssp_transfer(spi_bus_t* const bus, void* const data, const size_t count)
{
const spi_transfer_t transfers[] = { const spi_transfer_t transfers[] = {
{data, count}, {data, count},
}; };

View File

@ -41,6 +41,9 @@ typedef struct ssp_config_t {
void spi_ssp_start(spi_bus_t* const bus, const void* const config); void spi_ssp_start(spi_bus_t* const bus, const void* const config);
void spi_ssp_stop(spi_bus_t* const bus); void spi_ssp_stop(spi_bus_t* const bus);
void spi_ssp_transfer(spi_bus_t* const bus, void* const data, const size_t count); void spi_ssp_transfer(spi_bus_t* const bus, void* const data, const size_t count);
void spi_ssp_transfer_gather(spi_bus_t* const bus, const spi_transfer_t* const transfers, const size_t count); void spi_ssp_transfer_gather(
spi_bus_t* const bus,
const spi_transfer_t* const transfers,
const size_t count);
#endif /*__SPI_SSP_H__*/ #endif /*__SPI_SSP_H__*/

View File

@ -25,12 +25,14 @@
#include <libopencm3/lpc43xx/m4/nvic.h> #include <libopencm3/lpc43xx/m4/nvic.h>
#include <libopencm3/lpc43xx/sgpio.h> #include <libopencm3/lpc43xx/sgpio.h>
void baseband_streaming_enable(sgpio_config_t* const sgpio_config) { void baseband_streaming_enable(sgpio_config_t* const sgpio_config)
{
SGPIO_SET_EN_1 = (1 << SGPIO_SLICE_A); SGPIO_SET_EN_1 = (1 << SGPIO_SLICE_A);
sgpio_cpld_stream_enable(sgpio_config); sgpio_cpld_stream_enable(sgpio_config);
} }
void baseband_streaming_disable(sgpio_config_t* const sgpio_config) { void baseband_streaming_disable(sgpio_config_t* const sgpio_config)
{
sgpio_cpld_stream_disable(sgpio_config); sgpio_cpld_stream_disable(sgpio_config);
} }

View File

@ -49,6 +49,7 @@
static uint32_t max2837_freq_nominal_hz = 2560000000; static uint32_t max2837_freq_nominal_hz = 2560000000;
uint64_t freq_cache = 100000000; uint64_t freq_cache = 100000000;
/* /*
* Set freq/tuning between 0MHz to 7250 MHz (less than 16bits really used) * Set freq/tuning between 0MHz to 7250 MHz (less than 16bits really used)
* hz between 0 to 999999 Hz (not checked) * hz between 0 to 999999 Hz (not checked)
@ -68,8 +69,7 @@ bool set_freq(const uint64_t freq)
const max2837_mode_t prior_max2837_mode = max2837_mode(&max2837); const max2837_mode_t prior_max2837_mode = max2837_mode(&max2837);
max2837_set_mode(&max2837, MAX2837_MODE_STANDBY); max2837_set_mode(&max2837, MAX2837_MODE_STANDBY);
if(freq_mhz < MAX_LP_FREQ_MHZ) if (freq_mhz < MAX_LP_FREQ_MHZ) {
{
rf_path_set_filter(&rf_path, RF_PATH_FILTER_LOW_PASS); rf_path_set_filter(&rf_path, RF_PATH_FILTER_LOW_PASS);
#ifdef RAD1O #ifdef RAD1O
max2837_freq_nominal_hz = 2300000000; max2837_freq_nominal_hz = 2300000000;
@ -82,18 +82,17 @@ bool set_freq(const uint64_t freq)
real_mixer_freq_hz = mixer_set_frequency(&mixer, mixer_freq_mhz); real_mixer_freq_hz = mixer_set_frequency(&mixer, mixer_freq_mhz);
max2837_set_frequency(&max2837, real_mixer_freq_hz - freq); max2837_set_frequency(&max2837, real_mixer_freq_hz - freq);
sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 1); sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 1);
}else if( (freq_mhz >= MIN_BYPASS_FREQ_MHZ) && (freq_mhz < MAX_BYPASS_FREQ_MHZ) ) } else if ((freq_mhz >= MIN_BYPASS_FREQ_MHZ) && (freq_mhz < MAX_BYPASS_FREQ_MHZ)) {
{
rf_path_set_filter(&rf_path, RF_PATH_FILTER_BYPASS); rf_path_set_filter(&rf_path, RF_PATH_FILTER_BYPASS);
MAX2837_freq_hz = (freq_mhz * FREQ_ONE_MHZ) + freq_hz; MAX2837_freq_hz = (freq_mhz * FREQ_ONE_MHZ) + freq_hz;
/* mixer_freq_mhz <= not used in Bypass mode */ /* mixer_freq_mhz <= not used in Bypass mode */
max2837_set_frequency(&max2837, MAX2837_freq_hz); max2837_set_frequency(&max2837, MAX2837_freq_hz);
sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 0); sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 0);
}else if( (freq_mhz >= MIN_HP_FREQ_MHZ) && (freq_mhz <= MAX_HP_FREQ_MHZ) ) } else if ((freq_mhz >= MIN_HP_FREQ_MHZ) && (freq_mhz <= MAX_HP_FREQ_MHZ)) {
{
if (freq_mhz < MID1_HP_FREQ_MHZ) { if (freq_mhz < MID1_HP_FREQ_MHZ) {
/* IF is graduated from 2150 MHz to 2750 MHz */ /* IF is graduated from 2150 MHz to 2750 MHz */
max2837_freq_nominal_hz = 2150000000 + (((freq - 2750000000) * 60) / 85); max2837_freq_nominal_hz =
2150000000 + (((freq - 2750000000) * 60) / 85);
} else if (freq_mhz < MID2_HP_FREQ_MHZ) { } else if (freq_mhz < MID2_HP_FREQ_MHZ) {
/* IF is graduated from 2350 MHz to 2650 MHz */ /* IF is graduated from 2350 MHz to 2650 MHz */
max2837_freq_nominal_hz = 2350000000 + ((freq - 3600000000) / 5); max2837_freq_nominal_hz = 2350000000 + ((freq - 3600000000) / 5);
@ -107,8 +106,7 @@ bool set_freq(const uint64_t freq)
real_mixer_freq_hz = mixer_set_frequency(&mixer, mixer_freq_mhz); real_mixer_freq_hz = mixer_set_frequency(&mixer, mixer_freq_mhz);
max2837_set_frequency(&max2837, freq - real_mixer_freq_hz); max2837_set_frequency(&max2837, freq - real_mixer_freq_hz);
sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 0); sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 0);
}else } else {
{
/* Error freq_mhz too high */ /* Error freq_mhz too high */
success = false; success = false;
} }
@ -123,11 +121,13 @@ bool set_freq(const uint64_t freq)
return success; return success;
} }
bool set_freq_explicit(const uint64_t if_freq_hz, const uint64_t lo_freq_hz, bool set_freq_explicit(
const uint64_t if_freq_hz,
const uint64_t lo_freq_hz,
const rf_path_filter_t path) const rf_path_filter_t path)
{ {
if ((if_freq_hz < ((uint64_t)MIN_BYPASS_FREQ_MHZ * FREQ_ONE_MHZ)) if ((if_freq_hz < ((uint64_t) MIN_BYPASS_FREQ_MHZ * FREQ_ONE_MHZ)) ||
|| (if_freq_hz > ((uint64_t)MAX_BYPASS_FREQ_MHZ * FREQ_ONE_MHZ))) { (if_freq_hz > ((uint64_t) MAX_BYPASS_FREQ_MHZ * FREQ_ONE_MHZ))) {
return false; return false;
} }

View File

@ -29,7 +29,9 @@
#include <stdbool.h> #include <stdbool.h>
bool set_freq(const uint64_t freq); bool set_freq(const uint64_t freq);
bool set_freq_explicit(const uint64_t if_freq_hz, const uint64_t lo_freq_hz, bool set_freq_explicit(
const uint64_t if_freq_hz,
const uint64_t lo_freq_hz,
const rf_path_filter_t path); const rf_path_filter_t path);
#endif /*__TUNING_H__*/ #endif /*__TUNING_H__*/

View File

@ -26,265 +26,336 @@
/* Pixel data within a font or bitmap byte is "reversed": LSB is left-most pixel. */ /* Pixel data within a font or bitmap byte is "reversed": LSB is left-most pixel. */
static const uint8_t font_fixed_8x16_glyph_data[] = { static const uint8_t font_fixed_8x16_glyph_data[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0x00, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x24, 0x24,
0x00, 0x00, 0x00, 0x48, 0x48, 0x48, 0xff, 0x24, 0x24, 0xff, 0x12, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
0x00, 0x00, 0x10, 0x78, 0x14, 0x14, 0x14, 0x18, 0x30, 0x50, 0x50, 0x50, 0x3c, 0x10, 0x00, 0x00, 0x48, 0x48, 0xff, 0x24, 0x24, 0xff, 0x12, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x46, 0x29, 0x29, 0x19, 0x16, 0x68, 0x98, 0x94, 0x94, 0x62, 0x00, 0x00, 0x00, 0x00, 0x10, 0x78, 0x14, 0x14, 0x14, 0x18, 0x30, 0x50, 0x50, 0x50, 0x3c, 0x10,
0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x14, 0x88, 0x54, 0x72, 0x22, 0x62, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x29, 0x29, 0x19, 0x16, 0x68, 0x98, 0x94,
0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x14, 0x88,
0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x00, 0x54, 0x72, 0x22, 0x62, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
0x00, 0x00, 0x00, 0x02, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x02, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x08, 0x2a, 0x1c, 0x2a, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0xfe, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2a, 0x1c, 0x2a, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x10, 0x10, 0xfe, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x5a, 0x5a, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0c, 0x0a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1e, 0x20, 0x20, 0x20, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x10, 0x10,
0x00, 0x00, 0x00, 0x1e, 0x20, 0x20, 0x10, 0x0c, 0x10, 0x20, 0x20, 0x10, 0x0e, 0x00, 0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
0x00, 0x00, 0x00, 0x30, 0x30, 0x28, 0x28, 0x24, 0x24, 0x22, 0x7e, 0x20, 0x20, 0x00, 0x00, 0x00, 0x24, 0x42, 0x42, 0x5a, 0x5a, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7c, 0x04, 0x04, 0x04, 0x3c, 0x40, 0x40, 0x40, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00,
0x00, 0x00, 0x00, 0x38, 0x04, 0x02, 0x02, 0x3a, 0x46, 0x42, 0x42, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x20, 0x20, 0x20, 0x20, 0x10, 0x08, 0x04,
0x00, 0x00, 0x00, 0x7e, 0x40, 0x20, 0x20, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x00, 0x00, 0x00, 0x02, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x20, 0x20, 0x10, 0x0c,
0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x24, 0x18, 0x24, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x10, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30,
0x00, 0x00, 0x00, 0x1c, 0x22, 0x42, 0x42, 0x62, 0x5c, 0x40, 0x40, 0x20, 0x1c, 0x00, 0x00, 0x00, 0x28, 0x28, 0x24, 0x24, 0x22, 0x7e, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x04, 0x04, 0x04, 0x3c, 0x40, 0x40, 0x40, 0x40, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x04, 0x02, 0x02, 0x3a, 0x46, 0x42, 0x42, 0x44,
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x04, 0x18, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x20, 0x20, 0x10, 0x10,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42,
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x30, 0x40, 0x30, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x24, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x44, 0x40, 0x40, 0x30, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x42, 0x42, 0x62, 0x5c, 0x40, 0x40, 0x20, 0x1c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1c, 0x22, 0x41, 0x59, 0x55, 0x55, 0x55, 0x39, 0x01, 0x02, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08,
0x00, 0x00, 0x00, 0x08, 0x14, 0x14, 0x14, 0x14, 0x22, 0x3e, 0x22, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3e, 0x42, 0x42, 0x42, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20,
0x00, 0x00, 0x00, 0x38, 0x44, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x44, 0x38, 0x00, 0x00, 0x00, 0x18, 0x04, 0x18, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1e, 0x22, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x22, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x02, 0x7e, 0x02, 0x02, 0x02, 0x02, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x30, 0x40, 0x30, 0x08, 0x04, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x02, 0x7e, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x40, 0x40, 0x30, 0x08, 0x08, 0x00,
0x00, 0x00, 0x00, 0x38, 0x44, 0x02, 0x02, 0x02, 0x72, 0x42, 0x42, 0x44, 0x38, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x41, 0x59, 0x55,
0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x55, 0x55, 0x39, 0x01, 0x02, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14,
0x00, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x14, 0x14, 0x14, 0x22, 0x3e, 0x22, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x42, 0x42, 0x42, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00,
0x00, 0x00, 0x00, 0x82, 0x42, 0x22, 0x12, 0x0a, 0x0e, 0x12, 0x22, 0x42, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x44,
0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x7e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x42, 0x42, 0x42, 0x42,
0x00, 0x00, 0x00, 0x42, 0x66, 0x66, 0x5a, 0x5a, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x42, 0x42, 0x22, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x02,
0x00, 0x00, 0x00, 0x42, 0x46, 0x46, 0x4a, 0x4a, 0x52, 0x52, 0x62, 0x62, 0x42, 0x00, 0x00, 0x00, 0x02, 0x7e, 0x02, 0x02, 0x02, 0x02, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x02, 0x7e, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3e, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x02, 0x02, 0x02, 0x72, 0x42, 0x42, 0x44, 0x38,
0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x18, 0x10, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42,
0x00, 0x00, 0x00, 0x3e, 0x42, 0x42, 0x42, 0x3e, 0x12, 0x22, 0x22, 0x42, 0x82, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08,
0x00, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x02, 0x0c, 0x30, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
0x00, 0x00, 0x00, 0x7f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x42, 0x22, 0x12, 0x0a, 0x0e, 0x12, 0x22, 0x42, 0x82, 0x00,
0x00, 0x00, 0x00, 0x41, 0x41, 0x22, 0x22, 0x22, 0x14, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x49, 0x49, 0x55, 0x55, 0x55, 0x22, 0x22, 0x00, 0x00, 0x00, 0x02, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x66, 0x66, 0x5a, 0x5a,
0x00, 0x00, 0x00, 0x41, 0x22, 0x22, 0x14, 0x08, 0x08, 0x14, 0x22, 0x22, 0x41, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x46,
0x00, 0x00, 0x00, 0x41, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x46, 0x4a, 0x4a, 0x52, 0x52, 0x62, 0x62, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7e, 0x40, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x02, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x02, 0x02, 0x02,
0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42,
0x00, 0x00, 0x00, 0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e, 0x00, 0x42, 0x42, 0x24, 0x18, 0x10, 0x60, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x42, 0x42,
0x00, 0x00, 0x00, 0x10, 0x28, 0x44, 0x44, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x3e, 0x12, 0x22, 0x22, 0x42, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x3c, 0x42, 0x02, 0x02, 0x0c, 0x30, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x7c, 0x42, 0x62, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x1a, 0x26, 0x42, 0x42, 0x42, 0x26, 0x1a, 0x00, 0x00, 0x00, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x22, 0x22,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x04, 0x02, 0x02, 0x02, 0x04, 0x78, 0x00, 0x00, 0x00, 0x22, 0x14, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x58, 0x64, 0x42, 0x42, 0x42, 0x64, 0x58, 0x00, 0x00, 0x00, 0x41, 0x41, 0x49, 0x49, 0x55, 0x55, 0x55, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x7e, 0x02, 0x04, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x22, 0x22, 0x14, 0x08, 0x08, 0x14, 0x22, 0x22, 0x41, 0x00,
0x00, 0x00, 0x00, 0x70, 0x08, 0x08, 0x7e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x22, 0x22, 0x22, 0x1c, 0x02, 0x3e, 0x42, 0x42, 0x3c, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x20, 0x10, 0x10,
0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x08, 0x08, 0x04, 0x02, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x08,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0e, 0x00, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x22, 0x12, 0x0a, 0x0e, 0x12, 0x22, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0x00, 0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x44, 0x44, 0x82, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x26, 0x42, 0x42, 0x42, 0x26, 0x1a, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x7c, 0x42, 0x62, 0x5c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x64, 0x42, 0x42, 0x42, 0x64, 0x58, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x1a, 0x26, 0x42, 0x42,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x42, 0x26, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x02, 0x02, 0x3c, 0x40, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x3c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x70, 0x00, 0x00, 0x00, 0x40, 0x40, 0x58, 0x64, 0x42, 0x42, 0x42, 0x64, 0x58, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x62, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x7e, 0x02, 0x04, 0x78, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x22, 0x22, 0x36, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0x08, 0x7e, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x49, 0x55, 0x55, 0x22, 0x22, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x22,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x24, 0x18, 0x18, 0x18, 0x24, 0x42, 0x00, 0x00, 0x00, 0x22, 0x22, 0x1c, 0x02, 0x3e, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x02, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x22, 0x22, 0x14, 0x14, 0x14, 0x08, 0x08, 0x04, 0x03, 0x02, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x20, 0x10, 0x08, 0x08, 0x04, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, 0x10,
0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x10, 0x10, 0x10, 0x0e, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x22, 0x12, 0x0a,
0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x10, 0x10, 0x20, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x00, 0x0e, 0x12, 0x22, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x08, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}; 0x00, 0x00, 0x00, 0x37, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x42,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42,
0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a,
0x26, 0x42, 0x42, 0x42, 0x26, 0x1a, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x58, 0x64, 0x42, 0x42, 0x42, 0x64, 0x58, 0x40, 0x40, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x02, 0x02, 0x3c, 0x40,
0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x3c, 0x08,
0x08, 0x08, 0x08, 0x08, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x62, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x41, 0x22, 0x22, 0x36, 0x14, 0x14, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x49, 0x55, 0x55, 0x22,
0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x24, 0x18,
0x18, 0x18, 0x24, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x41, 0x22, 0x22, 0x14, 0x14, 0x14, 0x08, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7e, 0x20, 0x10, 0x08, 0x08, 0x04, 0x7e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x08, 0x08, 0x08, 0x08,
0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x10,
0x10, 0x20, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x8e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static const ui_font_t font_fixed_8x16 = { static const ui_font_t font_fixed_8x16 =
{ 8, 16 }, {{8, 16}, font_fixed_8x16_glyph_data, 0x20, 95, (8 * 16 + 7U) >> 3};
font_fixed_8x16_glyph_data,
0x20, 95,
(8 * 16 + 7U) >> 3
};
static const uint8_t font_fixed_24x19_glyph_data[] = { static const uint8_t font_fixed_24x19_glyph_data[] = {
0xe0, 0xff, 0x07, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0x3c, 0x00, 0x3c, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x3c, 0x00, 0x3c, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0xe0, 0xff, 0x07, 0xe0, 0xff, 0x07, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0x3c, 0x00, 0x3c, 0x1c,
0x00, 0x78, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7f, 0x00, 0x80, 0x77, 0x00, 0xc0, 0x73, 0x00, 0xc0, 0x71, 0x00, 0xc0, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00,
0xe0, 0xff, 0x07, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0x3c, 0x00, 0x3c, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x3c, 0x00, 0xfc, 0x1f, 0xe0, 0xff, 0x1f, 0xf8, 0xff, 0x07, 0xfc, 0x07, 0x00, 0x3c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38,
0xe0, 0xff, 0x07, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x3f, 0x3c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0xfe, 0x3f, 0x00, 0xfe, 0x1f, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x3c, 0x00, 0x38, 0xf8, 0xff, 0x3f, 0xf8, 0xff, 0x1f, 0xe0, 0xff, 0x07, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x3c, 0x00, 0x3c, 0xf8, 0xff, 0x1f, 0xf8,
0x00, 0x80, 0x0f, 0x00, 0xc0, 0x0f, 0x00, 0xe0, 0x0f, 0x00, 0xf8, 0x0f, 0x00, 0x7c, 0x0f, 0x00, 0x1e, 0x0f, 0x00, 0x0f, 0x0f, 0xc0, 0x07, 0x0f, 0xe0, 0x01, 0x0f, 0xf0, 0x00, 0x0f, 0x7c, 0x00, 0x0f, 0x1e, 0x00, 0x0f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0x1f, 0xe0, 0xff, 0x07, 0x00, 0x78, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x7e,
0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0xdc, 0xff, 0x07, 0xfc, 0xff, 0x1f, 0xfc, 0xff, 0x1f, 0x3c, 0x00, 0x3c, 0x1c, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x3c, 0x00, 0x3c, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0xe0, 0xff, 0x07, 0x00, 0x00, 0x7f, 0x00, 0x80, 0x77, 0x00, 0xc0, 0x73, 0x00, 0xc0, 0x71, 0x00,
0xe0, 0xff, 0x07, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0x3c, 0x00, 0x3c, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x00, 0xdc, 0xff, 0x07, 0xfc, 0xff, 0x1f, 0xfc, 0xff, 0x1f, 0x3c, 0x00, 0x3c, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x3c, 0x00, 0x3c, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0xe0, 0xff, 0x07, 0xc0, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00,
0xfc, 0xff, 0x7f, 0xfc, 0xff, 0x7f, 0xfc, 0xff, 0x7f, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0f, 0x00, 0x80, 0x07, 0x00, 0xc0, 0x03, 0x00, 0xe0, 0x01, 0x00, 0xf0, 0x01, 0x00, 0xf0, 0x00, 0x00, 0x78, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0x80, 0x07, 0x00, 0xc0, 0x03, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70,
0xe0, 0xff, 0x07, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0x3c, 0x00, 0x3c, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x3c, 0x00, 0x3c, 0xf8, 0xff, 0x1f, 0xf0, 0xff, 0x0f, 0xf8, 0xff, 0x1f, 0x3c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x3c, 0x00, 0x3c, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0xe0, 0xff, 0x07, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0xe0, 0xff, 0x07,
0xe0, 0xff, 0x07, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0x3c, 0x00, 0x3c, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x3c, 0x00, 0x3c, 0xf8, 0xff, 0x3f, 0xf8, 0xff, 0x3f, 0xe0, 0xff, 0x3b, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x3c, 0x00, 0x3c, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0xe0, 0xff, 0x07, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0x3c, 0x00, 0x3c, 0x1c, 0x00, 0x38, 0x1c,
0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x3c, 0x00, 0xfc,
0x1f, 0xe0, 0xff, 0x1f, 0xf8, 0xff, 0x07, 0xfc, 0x07, 0x00, 0x3c, 0x00, 0x00,
0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xfc,
0xff, 0x3f, 0xe0, 0xff, 0x07, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x3f, 0x3c, 0x00,
0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38,
0x00, 0xfe, 0x3f, 0x00, 0xfe, 0x1f, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x38, 0x00,
0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x3c, 0x00, 0x38, 0xf8, 0xff,
0x3f, 0xf8, 0xff, 0x1f, 0xe0, 0xff, 0x07, 0x00, 0x80, 0x0f, 0x00, 0xc0, 0x0f,
0x00, 0xe0, 0x0f, 0x00, 0xf8, 0x0f, 0x00, 0x7c, 0x0f, 0x00, 0x1e, 0x0f, 0x00,
0x0f, 0x0f, 0xc0, 0x07, 0x0f, 0xe0, 0x01, 0x0f, 0xf0, 0x00, 0x0f, 0x7c, 0x00,
0x0f, 0x1e, 0x00, 0x0f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f,
0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0xfc,
0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0x1c, 0x00, 0x00, 0x1c, 0x00,
0x00, 0x1c, 0x00, 0x00, 0xdc, 0xff, 0x07, 0xfc, 0xff, 0x1f, 0xfc, 0xff, 0x1f,
0x3c, 0x00, 0x3c, 0x1c, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x1c,
0x00, 0x38, 0x1c, 0x00, 0x38, 0x3c, 0x00, 0x3c, 0xf8, 0xff, 0x1f, 0xf8, 0xff,
0x1f, 0xe0, 0xff, 0x07, 0xe0, 0xff, 0x07, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f,
0x3c, 0x00, 0x3c, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x00, 0xdc,
0xff, 0x07, 0xfc, 0xff, 0x1f, 0xfc, 0xff, 0x1f, 0x3c, 0x00, 0x3c, 0x1c, 0x00,
0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x3c, 0x00, 0x3c,
0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0xe0, 0xff, 0x07, 0xfc, 0xff, 0x7f, 0xfc,
0xff, 0x7f, 0xfc, 0xff, 0x7f, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00,
0x1e, 0x00, 0x00, 0x0f, 0x00, 0x80, 0x07, 0x00, 0xc0, 0x03, 0x00, 0xe0, 0x01,
0x00, 0xf0, 0x01, 0x00, 0xf0, 0x00, 0x00, 0x78, 0x00, 0x00, 0x3c, 0x00, 0x00,
0x1e, 0x00, 0x00, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0x80, 0x07, 0x00, 0xc0, 0x03,
0x00, 0xe0, 0xff, 0x07, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0x3c, 0x00, 0x3c,
0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x3c, 0x00, 0x3c, 0xf8,
0xff, 0x1f, 0xf0, 0xff, 0x0f, 0xf8, 0xff, 0x1f, 0x3c, 0x00, 0x38, 0x1c, 0x00,
0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x3c, 0x00, 0x3c, 0xf8, 0xff, 0x1f,
0xf8, 0xff, 0x1f, 0xe0, 0xff, 0x07, 0xe0, 0xff, 0x07, 0xf8, 0xff, 0x1f, 0xf8,
0xff, 0x1f, 0x3c, 0x00, 0x3c, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00,
0x38, 0x1c, 0x00, 0x38, 0x3c, 0x00, 0x3c, 0xf8, 0xff, 0x3f, 0xf8, 0xff, 0x3f,
0xe0, 0xff, 0x3b, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x1c, 0x00, 0x38, 0x3c,
0x00, 0x3c, 0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0xe0, 0xff, 0x07,
}; };
static const ui_font_t font_fixed_24x19 = { static const ui_font_t font_fixed_24x19 =
{ 24, 19 }, {{24, 19}, font_fixed_24x19_glyph_data, 0x30, 10, (24 * 19 + 7U) >> 3};
font_fixed_24x19_glyph_data,
0x30, 10,
(24 * 19 + 7U) >> 3
};
static const uint8_t font_fixed_16x14_glyph_data[] = { static const uint8_t font_fixed_16x14_glyph_data[] = {
0xf8, 0x1f, 0xfc, 0x3f, 0x0e, 0x70, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x0e, 0x70, 0xfc, 0x3f, 0xf8, 0x1f, 0xf8, 0x1f, 0xfc, 0x3f, 0x0e, 0x70, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06,
0x00, 0x03, 0x80, 0x03, 0xc0, 0x03, 0xe0, 0x03, 0x70, 0x03, 0x20, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x0e, 0x70, 0xfc, 0x3f,
0xf8, 0x1f, 0xfc, 0x3f, 0x0e, 0x70, 0x06, 0x60, 0x00, 0x60, 0x00, 0x70, 0x80, 0x3f, 0xf8, 0x1f, 0xfc, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x06, 0x00, 0xfe, 0x7f, 0xfe, 0x7f, 0xf8, 0x1f, 0x00, 0x03, 0x80, 0x03, 0xc0, 0x03, 0xe0, 0x03, 0x70, 0x03, 0x20,
0xf8, 0x1f, 0xfc, 0x3f, 0x0e, 0x70, 0x06, 0x60, 0x00, 0x60, 0x00, 0x60, 0xc0, 0x3f, 0xc0, 0x7f, 0x00, 0x60, 0x00, 0x60, 0x06, 0x60, 0x0e, 0x70, 0xfc, 0x3f, 0xf8, 0x1f, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
0x00, 0x1c, 0x00, 0x1e, 0x00, 0x1f, 0x80, 0x1b, 0xc0, 0x19, 0xe0, 0x18, 0x70, 0x18, 0x38, 0x18, 0x1c, 0x18, 0xfe, 0x7f, 0xfe, 0x7f, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x03, 0x00, 0x03, 0xf8, 0x1f, 0xfc, 0x3f, 0x0e, 0x70, 0x06, 0x60, 0x00,
0xfe, 0x7f, 0xfe, 0x7f, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0xf6, 0x1f, 0xfe, 0x3f, 0x0e, 0x70, 0x00, 0x60, 0x00, 0x60, 0x06, 0x60, 0x0e, 0x70, 0xfc, 0x3f, 0xf8, 0x1f, 0x60, 0x00, 0x70, 0x80, 0x3f, 0xf8, 0x1f, 0xfc, 0x00, 0x0e, 0x00, 0x06, 0x00,
0xf8, 0x1f, 0xfc, 0x3f, 0x0e, 0x70, 0x06, 0x60, 0x06, 0x00, 0xf6, 0x1f, 0xfe, 0x3f, 0x0e, 0x70, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x0e, 0x70, 0xfc, 0x3f, 0xf8, 0x1f, 0x06, 0x00, 0xfe, 0x7f, 0xfe, 0x7f, 0xf8, 0x1f, 0xfc, 0x3f, 0x0e, 0x70, 0x06,
0xfe, 0x7f, 0xfe, 0x7f, 0x00, 0x70, 0x00, 0x30, 0x00, 0x18, 0x00, 0x1c, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x07, 0x80, 0x03, 0x80, 0x01, 0xc0, 0x00, 0xe0, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0xc0, 0x3f, 0xc0, 0x7f, 0x00, 0x60, 0x00, 0x60,
0xf8, 0x1f, 0xfc, 0x3f, 0x0e, 0x70, 0x06, 0x60, 0x06, 0x60, 0x0e, 0x70, 0xfc, 0x3f, 0xfc, 0x3f, 0x0e, 0x70, 0x06, 0x60, 0x06, 0x60, 0x0e, 0x70, 0xfc, 0x3f, 0xf8, 0x1f, 0x06, 0x60, 0x0e, 0x70, 0xfc, 0x3f, 0xf8, 0x1f, 0x00, 0x1c, 0x00, 0x1e, 0x00,
0xf8, 0x1f, 0xfc, 0x3f, 0x0e, 0x70, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x0e, 0x70, 0xfc, 0x7f, 0xf8, 0x6f, 0x00, 0x60, 0x06, 0x60, 0x0e, 0x70, 0xfc, 0x3f, 0xf8, 0x1f, 0x1f, 0x80, 0x1b, 0xc0, 0x19, 0xe0, 0x18, 0x70, 0x18, 0x38, 0x18, 0x1c, 0x18,
0xfe, 0x7f, 0xfe, 0x7f, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0xfe, 0x7f, 0xfe,
0x7f, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0xf6, 0x1f, 0xfe, 0x3f, 0x0e, 0x70,
0x00, 0x60, 0x00, 0x60, 0x06, 0x60, 0x0e, 0x70, 0xfc, 0x3f, 0xf8, 0x1f, 0xf8,
0x1f, 0xfc, 0x3f, 0x0e, 0x70, 0x06, 0x60, 0x06, 0x00, 0xf6, 0x1f, 0xfe, 0x3f,
0x0e, 0x70, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x0e, 0x70, 0xfc, 0x3f, 0xf8,
0x1f, 0xfe, 0x7f, 0xfe, 0x7f, 0x00, 0x70, 0x00, 0x30, 0x00, 0x18, 0x00, 0x1c,
0x00, 0x0c, 0x00, 0x06, 0x00, 0x07, 0x80, 0x03, 0x80, 0x01, 0xc0, 0x00, 0xe0,
0x00, 0x60, 0x00, 0xf8, 0x1f, 0xfc, 0x3f, 0x0e, 0x70, 0x06, 0x60, 0x06, 0x60,
0x0e, 0x70, 0xfc, 0x3f, 0xfc, 0x3f, 0x0e, 0x70, 0x06, 0x60, 0x06, 0x60, 0x0e,
0x70, 0xfc, 0x3f, 0xf8, 0x1f, 0xf8, 0x1f, 0xfc, 0x3f, 0x0e, 0x70, 0x06, 0x60,
0x06, 0x60, 0x06, 0x60, 0x0e, 0x70, 0xfc, 0x7f, 0xf8, 0x6f, 0x00, 0x60, 0x06,
0x60, 0x0e, 0x70, 0xfc, 0x3f, 0xf8, 0x1f,
}; };
static const ui_font_t font_fixed_16x14 = { static const ui_font_t font_fixed_16x14 =
{ 16, 14 }, {{16, 14}, font_fixed_16x14_glyph_data, 0x30, 10, (16 * 14 + 7U) >> 3};
font_fixed_16x14_glyph_data,
0x30, 10,
(16 * 14 + 7U) >> 3
};
static const uint8_t bitmap_amp_rx_data[] = { static const uint8_t bitmap_amp_rx_data[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x0c, 0x00, 0x30, 0x0c, 0x00, 0x30, 0x18, 0x00, 0x18, 0x18, 0x00, 0x18, 0x30, 0x00, 0x0c, 0x30, 0x00, 0x0c, 0x60, 0x00, 0x06, 0x60, 0x00, 0x06, 0xc0, 0x00, 0x03, 0xc0, 0x00, 0x03, 0x80, 0x81, 0x01, 0x80, 0x81, 0x01, 0x00, 0xc3, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60,
}; 0x0c, 0x00, 0x30, 0x0c, 0x00, 0x30, 0x18, 0x00, 0x18, 0x18, 0x00, 0x18,
0x30, 0x00, 0x0c, 0x30, 0x00, 0x0c, 0x60, 0x00, 0x06, 0x60, 0x00, 0x06,
0xc0, 0x00, 0x03, 0xc0, 0x00, 0x03, 0x80, 0x81, 0x01, 0x80, 0x81, 0x01,
0x00, 0xc3, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00,
0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00};
static const ui_bitmap_t bitmap_amp_rx = { static const ui_bitmap_t bitmap_amp_rx = {{24, 24}, bitmap_amp_rx_data};
{ 24, 24 }, bitmap_amp_rx_data
};
static const uint8_t bitmap_amp_tx_data[] = { static const uint8_t bitmap_amp_tx_data[] = {
0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0xc3, 0x00, 0x00, 0xc3, 0x00, 0x80, 0x81, 0x01, 0x80, 0x81, 0x01, 0xc0, 0x00, 0x03, 0xc0, 0x00, 0x03, 0x60, 0x00, 0x06, 0x60, 0x00, 0x06, 0x30, 0x00, 0x0c, 0x30, 0x00, 0x0c, 0x18, 0x00, 0x18, 0x18, 0x00, 0x18, 0x0c, 0x00, 0x30, 0x0c, 0x00, 0x30, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
}; 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0xc3, 0x00, 0x00, 0xc3, 0x00,
0x80, 0x81, 0x01, 0x80, 0x81, 0x01, 0xc0, 0x00, 0x03, 0xc0, 0x00, 0x03,
0x60, 0x00, 0x06, 0x60, 0x00, 0x06, 0x30, 0x00, 0x0c, 0x30, 0x00, 0x0c,
0x18, 0x00, 0x18, 0x18, 0x00, 0x18, 0x0c, 0x00, 0x30, 0x0c, 0x00, 0x30,
0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const ui_bitmap_t bitmap_amp_tx = { static const ui_bitmap_t bitmap_amp_tx = {{24, 24}, bitmap_amp_tx_data};
{ 24, 24 }, bitmap_amp_tx_data
};
static const uint8_t bitmap_antenna_data[] = { static const uint8_t bitmap_antenna_data[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x06, 0x18, 0x60, 0x06, 0x18, 0x60, 0x0c, 0x18, 0x30, 0x0c, 0x18, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0x18, 0x0c, 0x30, 0x18, 0x0c, 0x60, 0x18, 0x06, 0x60, 0x18, 0x06, 0xc0, 0x18, 0x03, 0xc0, 0x18, 0x03, 0x80, 0x99, 0x01, 0x80, 0x99, 0x01, 0x00, 0xdb, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x06, 0x18, 0x60, 0x06, 0x18, 0x60,
}; 0x0c, 0x18, 0x30, 0x0c, 0x18, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x30, 0x18, 0x0c, 0x30, 0x18, 0x0c, 0x60, 0x18, 0x06, 0x60, 0x18, 0x06,
0xc0, 0x18, 0x03, 0xc0, 0x18, 0x03, 0x80, 0x99, 0x01, 0x80, 0x99, 0x01,
0x00, 0xdb, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00,
0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00};
static const ui_bitmap_t bitmap_antenna = { static const ui_bitmap_t bitmap_antenna = {{24, 24}, bitmap_antenna_data};
{ 24, 24 }, bitmap_antenna_data
};
static const uint8_t bitmap_filter_hp_data[] = { static const uint8_t bitmap_filter_hp_data[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0xf8, 0xc7, 0x03, 0xfc, 0xc7, 0x03, 0x0e, 0xc0, 0x03, 0x06, 0xc0, 0x03, 0x03, 0xc0, 0x03, 0x03, 0xc0, 0x83, 0x01, 0xc0, 0x83, 0x01, 0xc0, 0xc3, 0x00, 0xc0, 0xc3, 0x00, 0xc0, 0x63, 0x00, 0xc0, 0x63, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0,
}; 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0xf8, 0xc7, 0x03, 0xfc, 0xc7,
0x03, 0x0e, 0xc0, 0x03, 0x06, 0xc0, 0x03, 0x03, 0xc0, 0x03, 0x03, 0xc0,
0x83, 0x01, 0xc0, 0x83, 0x01, 0xc0, 0xc3, 0x00, 0xc0, 0xc3, 0x00, 0xc0,
0x63, 0x00, 0xc0, 0x63, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0,
0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const ui_bitmap_t bitmap_filter_hp = { static const ui_bitmap_t bitmap_filter_hp = {{24, 24}, bitmap_filter_hp_data};
{ 24, 24 }, bitmap_filter_hp_data
};
static const uint8_t bitmap_filter_lp_data[] = { static const uint8_t bitmap_filter_lp_data[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0xe3, 0x1f, 0xc0, 0xe3, 0x3f, 0xc0, 0x03, 0x70, 0xc0, 0x03, 0x60, 0xc0, 0x03, 0xc0, 0xc0, 0x03, 0xc0, 0xc0, 0x03, 0x80, 0xc1, 0x03, 0x80, 0xc1, 0x03, 0x00, 0xc3, 0x03, 0x00, 0xc3, 0x03, 0x00, 0xc6, 0x03, 0x00, 0xc6, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0,
}; 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0xe3, 0x1f, 0xc0, 0xe3, 0x3f, 0xc0,
0x03, 0x70, 0xc0, 0x03, 0x60, 0xc0, 0x03, 0xc0, 0xc0, 0x03, 0xc0, 0xc0,
0x03, 0x80, 0xc1, 0x03, 0x80, 0xc1, 0x03, 0x00, 0xc3, 0x03, 0x00, 0xc3,
0x03, 0x00, 0xc6, 0x03, 0x00, 0xc6, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0,
0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const ui_bitmap_t bitmap_filter_lp = { static const ui_bitmap_t bitmap_filter_lp = {{24, 24}, bitmap_filter_lp_data};
{ 24, 24 }, bitmap_filter_lp_data
};
static const uint8_t bitmap_mixer_data[] = { static const uint8_t bitmap_mixer_data[] = {
0x00, 0x7e, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0x81, 0x07, 0x70, 0x00, 0x0e, 0x38, 0x00, 0x1c, 0x7c, 0x00, 0x3e, 0xee, 0x00, 0x77, 0xc6, 0x81, 0x63, 0x86, 0xc3, 0x61, 0x03, 0xe7, 0xc0, 0x03, 0x7e, 0xc0, 0x03, 0x3c, 0xc0, 0x03, 0x3c, 0xc0, 0x03, 0x7e, 0xc0, 0x03, 0xe7, 0xc0, 0x86, 0xc3, 0x61, 0xc6, 0x81, 0x63, 0xee, 0x00, 0x77, 0x7c, 0x00, 0x3e, 0x38, 0x00, 0x1c, 0x70, 0x00, 0x0e, 0xe0, 0x81, 0x07, 0xc0, 0xff, 0x03, 0x00, 0x7e, 0x00 0x00, 0x7e, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0x81, 0x07, 0x70, 0x00, 0x0e,
}; 0x38, 0x00, 0x1c, 0x7c, 0x00, 0x3e, 0xee, 0x00, 0x77, 0xc6, 0x81, 0x63,
0x86, 0xc3, 0x61, 0x03, 0xe7, 0xc0, 0x03, 0x7e, 0xc0, 0x03, 0x3c, 0xc0,
0x03, 0x3c, 0xc0, 0x03, 0x7e, 0xc0, 0x03, 0xe7, 0xc0, 0x86, 0xc3, 0x61,
0xc6, 0x81, 0x63, 0xee, 0x00, 0x77, 0x7c, 0x00, 0x3e, 0x38, 0x00, 0x1c,
0x70, 0x00, 0x0e, 0xe0, 0x81, 0x07, 0xc0, 0xff, 0x03, 0x00, 0x7e, 0x00};
static const ui_bitmap_t bitmap_mixer = { static const ui_bitmap_t bitmap_mixer = {{24, 24}, bitmap_mixer_data};
{ 24, 24 }, bitmap_mixer_data
};
static const uint8_t bitmap_oscillator_data[] = { static const uint8_t bitmap_oscillator_data[] = {
0x00, 0x7e, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0x81, 0x07, 0x70, 0x00, 0x0e, 0x38, 0x00, 0x1c, 0x1c, 0x00, 0x38, 0x0e, 0x03, 0x70, 0x86, 0x07, 0x60, 0xc6, 0x0f, 0x60, 0xc3, 0x0c, 0xc0, 0xe3, 0x1c, 0xc0, 0x63, 0x18, 0xc6, 0x63, 0x18, 0xc6, 0x03, 0x38, 0xc7, 0x03, 0x30, 0xc3, 0x06, 0xf0, 0x63, 0x06, 0xe0, 0x61, 0x0e, 0xc0, 0x70, 0x1c, 0x00, 0x38, 0x38, 0x00, 0x1c, 0x70, 0x00, 0x0e, 0xe0, 0x81, 0x07, 0xc0, 0xff, 0x03, 0x00, 0x7e, 0x00 0x00, 0x7e, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0x81, 0x07, 0x70, 0x00, 0x0e,
}; 0x38, 0x00, 0x1c, 0x1c, 0x00, 0x38, 0x0e, 0x03, 0x70, 0x86, 0x07, 0x60,
0xc6, 0x0f, 0x60, 0xc3, 0x0c, 0xc0, 0xe3, 0x1c, 0xc0, 0x63, 0x18, 0xc6,
0x63, 0x18, 0xc6, 0x03, 0x38, 0xc7, 0x03, 0x30, 0xc3, 0x06, 0xf0, 0x63,
0x06, 0xe0, 0x61, 0x0e, 0xc0, 0x70, 0x1c, 0x00, 0x38, 0x38, 0x00, 0x1c,
0x70, 0x00, 0x0e, 0xe0, 0x81, 0x07, 0xc0, 0xff, 0x03, 0x00, 0x7e, 0x00};
static const ui_bitmap_t bitmap_oscillator = { static const ui_bitmap_t bitmap_oscillator = {{24, 24}, bitmap_oscillator_data};
{ 24, 24 }, bitmap_oscillator_data
};
static const uint8_t bitmap_wire_8_data[] = { static const uint8_t bitmap_wire_8_data[] = {0xff, 0xff};
0xff, 0xff
};
static const ui_bitmap_t bitmap_wire_8 = { static const ui_bitmap_t bitmap_wire_8 = {{2, 8}, bitmap_wire_8_data};
{ 2, 8 }, bitmap_wire_8_data
};
static const uint8_t bitmap_wire_24_data[] = { static const uint8_t bitmap_wire_24_data[] = {
0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00,
}; 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00,
0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00,
0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00,
0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00,
0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00};
static const ui_bitmap_t bitmap_wire_24 = { static const ui_bitmap_t bitmap_wire_24 = {{24, 24}, bitmap_wire_24_data};
{ 24, 24 }, bitmap_wire_24_data
};
static const uint8_t bitmap_blank_24_data[] = { static const uint8_t bitmap_blank_24_data[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}; 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static const ui_bitmap_t bitmap_blank_24 = { static const ui_bitmap_t bitmap_blank_24 = {{24, 24}, bitmap_blank_24_data};
{ 24, 24 }, bitmap_blank_24_data
};
static const uint8_t bitmap_waves_rx_data[] = { static const uint8_t bitmap_waves_rx_data[] = {
0xc0, 0x00, 0x60, 0x00, 0x70, 0x06, 0x30, 0x07, 0x38, 0x03, 0x98, 0x33, 0x98, 0x39, 0x98, 0x19, 0xcc, 0x18, 0xcc, 0x0c, 0xcc, 0x0c, 0xcc, 0x0c, 0xcc, 0x0c, 0xcc, 0x0c, 0xcc, 0x0c, 0xcc, 0x18, 0x98, 0x19, 0x98, 0x39, 0x98, 0x33, 0x38, 0x03, 0x30, 0x07, 0x70, 0x06, 0x60, 0x00, 0xc0, 0x00 0xc0, 0x00, 0x60, 0x00, 0x70, 0x06, 0x30, 0x07, 0x38, 0x03, 0x98, 0x33,
}; 0x98, 0x39, 0x98, 0x19, 0xcc, 0x18, 0xcc, 0x0c, 0xcc, 0x0c, 0xcc, 0x0c,
0xcc, 0x0c, 0xcc, 0x0c, 0xcc, 0x0c, 0xcc, 0x18, 0x98, 0x19, 0x98, 0x39,
0x98, 0x33, 0x38, 0x03, 0x30, 0x07, 0x70, 0x06, 0x60, 0x00, 0xc0, 0x00};
static const ui_bitmap_t bitmap_waves_rx = { static const ui_bitmap_t bitmap_waves_rx = {{16, 24}, bitmap_waves_rx_data};
{ 16, 24 }, bitmap_waves_rx_data
};
static const uint8_t bitmap_waves_tx_data[] = { static const uint8_t bitmap_waves_tx_data[] = {
0x00, 0x03, 0x00, 0x06, 0x60, 0x0e, 0xe0, 0x0c, 0xc0, 0x1c, 0xcc, 0x19, 0x9c, 0x19, 0x98, 0x19, 0x18, 0x33, 0x30, 0x33, 0x30, 0x33, 0x30, 0x33, 0x30, 0x33, 0x30, 0x33, 0x30, 0x33, 0x18, 0x33, 0x98, 0x19, 0x9c, 0x19, 0xcc, 0x19, 0xc0, 0x1c, 0xe0, 0x0c, 0x60, 0x0e, 0x00, 0x06, 0x00, 0x03 0x00, 0x03, 0x00, 0x06, 0x60, 0x0e, 0xe0, 0x0c, 0xc0, 0x1c, 0xcc, 0x19,
}; 0x9c, 0x19, 0x98, 0x19, 0x18, 0x33, 0x30, 0x33, 0x30, 0x33, 0x30, 0x33,
0x30, 0x33, 0x30, 0x33, 0x30, 0x33, 0x18, 0x33, 0x98, 0x19, 0x9c, 0x19,
0xcc, 0x19, 0xc0, 0x1c, 0xe0, 0x0c, 0x60, 0x0e, 0x00, 0x06, 0x00, 0x03};
static const ui_bitmap_t bitmap_waves_tx = { static const ui_bitmap_t bitmap_waves_tx = {{16, 24}, bitmap_waves_tx_data};
{ 16, 24 }, bitmap_waves_tx_data
};
__attribute__((unused)) static ui_color_t portapack_color_rgb( __attribute__((unused)) static ui_color_t portapack_color_rgb(
const uint_fast8_t r, const uint_fast8_t r,
const uint_fast8_t g, const uint_fast8_t g,
const uint_fast8_t b const uint_fast8_t b)
) { {
const ui_color_t result = { const ui_color_t result = {
.v = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3) .v = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3)};
};
return result; return result;
} }
static const ui_color_t color_background = {0x001f}; static const ui_color_t color_background = {0x001f};
static const ui_color_t color_foreground = {0xffff}; static const ui_color_t color_foreground = {0xffff};
static ui_point_t portapack_lcd_draw_int(const ui_point_t point, uint64_t value, size_t field_width) { static ui_point_t portapack_lcd_draw_int(
const ui_point_t point,
uint64_t value,
size_t field_width)
{
const ui_point_t point_done = { const ui_point_t point_done = {
.x = point.x + font_fixed_8x16.glyph_size.width * field_width, .x = point.x + font_fixed_8x16.glyph_size.width * field_width,
.y = point.y .y = point.y};
};
ui_point_t point_next = point_done; ui_point_t point_next = point_done;
for (size_t i = 0; i < field_width; i++) { for (size_t i = 0; i < field_width; i++) {
@ -293,13 +364,18 @@ static ui_point_t portapack_lcd_draw_int(const ui_point_t point, uint64_t value,
const ui_bitmap_t glyph = portapack_font_glyph(&font_fixed_8x16, c); const ui_bitmap_t glyph = portapack_font_glyph(&font_fixed_8x16, c);
point_next.x -= glyph.size.width; point_next.x -= glyph.size.width;
portapack_draw_bitmap(point_next, glyph, color_foreground, color_background); portapack_draw_bitmap(
point_next,
glyph,
color_foreground,
color_background);
} }
return point_done; return point_done;
} }
static ui_point_t portapack_lcd_draw_string(ui_point_t point, const char* s) { static ui_point_t portapack_lcd_draw_string(ui_point_t point, const char* s)
{
while (*s) { while (*s) {
const char c = *(s++); const char c = *(s++);
const ui_bitmap_t glyph = portapack_font_glyph(&font_fixed_8x16, c); const ui_bitmap_t glyph = portapack_font_glyph(&font_fixed_8x16, c);
@ -349,23 +425,33 @@ typedef enum {
RADIO_DRAW_LIST_ITEM_WAVES = 17, RADIO_DRAW_LIST_ITEM_WAVES = 17,
} radio_draw_list_item_t; } radio_draw_list_item_t;
static ui_point_t portapack_ui_label_point(const radio_draw_list_item_t item) { static ui_point_t portapack_ui_label_point(const radio_draw_list_item_t item)
{
const uint8_t VALUES_X = 72; const uint8_t VALUES_X = 72;
ui_point_t point = {VALUES_X, radio_draw_list[item].point.y + 4}; ui_point_t point = {VALUES_X, radio_draw_list[item].point.y + 4};
return point; return point;
} }
static ui_point_t portapack_ui_draw_string(const radio_draw_list_item_t item, const char* s) { static ui_point_t portapack_ui_draw_string(
const radio_draw_list_item_t item,
const char* s)
{
return portapack_lcd_draw_string(portapack_ui_label_point(item), s); return portapack_lcd_draw_string(portapack_ui_label_point(item), s);
} }
static ui_point_t portapack_ui_draw_db(const radio_draw_list_item_t item, const uint32_t db) { static ui_point_t portapack_ui_draw_db(
const radio_draw_list_item_t item,
const uint32_t db)
{
ui_point_t point = portapack_ui_label_point(item); ui_point_t point = portapack_ui_label_point(item);
point = portapack_lcd_draw_int(point, db, 2); point = portapack_lcd_draw_int(point, db, 2);
return portapack_lcd_draw_string(point, " dB"); return portapack_lcd_draw_string(point, " dB");
} }
static ui_point_t portapack_ui_draw_bw_mhz(const radio_draw_list_item_t item, const uint64_t hz) { static ui_point_t portapack_ui_draw_bw_mhz(
const radio_draw_list_item_t item,
const uint64_t hz)
{
const uint32_t lsd = 1000000 / 100; const uint32_t lsd = 1000000 / 100;
const uint32_t round_offset = lsd / 2; const uint32_t round_offset = lsd / 2;
@ -380,11 +466,19 @@ static ui_point_t portapack_ui_draw_bw_mhz(const radio_draw_list_item_t item, co
return portapack_lcd_draw_string(point, " MHz"); return portapack_lcd_draw_string(point, " MHz");
} }
static void portapack_draw_radio_path_item(const radio_draw_list_item_t item) { static void portapack_draw_radio_path_item(const radio_draw_list_item_t item)
portapack_draw_bitmap(radio_draw_list[item].point, *radio_draw_list[item].bitmap, color_foreground, color_background); {
portapack_draw_bitmap(
radio_draw_list[item].point,
*radio_draw_list[item].bitmap,
color_foreground,
color_background);
} }
static void portapack_radio_path_item_update(const radio_draw_list_item_t item, const ui_bitmap_t* const bitmap) { static void portapack_radio_path_item_update(
const radio_draw_list_item_t item,
const ui_bitmap_t* const bitmap)
{
if (bitmap != radio_draw_list[item].bitmap) { if (bitmap != radio_draw_list[item].bitmap) {
radio_draw_list[item].bitmap = bitmap; radio_draw_list[item].bitmap = bitmap;
portapack_draw_radio_path_item(item); portapack_draw_radio_path_item(item);
@ -394,24 +488,28 @@ static void portapack_radio_path_item_update(const radio_draw_list_item_t item,
static rf_path_direction_t portapack_direction = RF_PATH_DIRECTION_OFF; static rf_path_direction_t portapack_direction = RF_PATH_DIRECTION_OFF;
static bool portapack_lna_on = false; static bool portapack_lna_on = false;
static void portapack_radio_path_redraw() { static void portapack_radio_path_redraw()
{
for (size_t i = 0; i < ARRAY_SIZEOF(radio_draw_list); i++) { for (size_t i = 0; i < ARRAY_SIZEOF(radio_draw_list); i++) {
portapack_draw_radio_path_item(i); portapack_draw_radio_path_item(i);
} }
} }
static void portapack_ui_init(void) { static void portapack_ui_init(void)
{
portapack_clear_display(color_background); portapack_clear_display(color_background);
portapack_backlight(true); portapack_backlight(true);
portapack_radio_path_redraw(); portapack_radio_path_redraw();
} }
static void portapack_ui_deinit(void) { static void portapack_ui_deinit(void)
{
portapack_clear_display(color_background); portapack_clear_display(color_background);
portapack_backlight(false); portapack_backlight(false);
} }
static void portapack_ui_set_frequency(uint64_t frequency) { static void portapack_ui_set_frequency(uint64_t frequency)
{
static char last[10] = " "; static char last[10] = " ";
ui_point_t point = {240 - 20, 16}; ui_point_t point = {240 - 20, 16};
@ -427,7 +525,8 @@ static void portapack_ui_set_frequency(uint64_t frequency) {
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
const char c = s[i]; const char c = s[i];
const ui_font_t* const font = (i > 5) ? &font_fixed_24x19 : &font_fixed_16x14; const ui_font_t* const font =
(i > 5) ? &font_fixed_24x19 : &font_fixed_16x14;
point.x -= font->glyph_size.width; point.x -= font->glyph_size.width;
if ((i == 3) || (i == 6) || (i == 9)) { if ((i == 3) || (i == 6) || (i == 9)) {
point.x -= 4; point.x -= 4;
@ -441,14 +540,19 @@ static void portapack_ui_set_frequency(uint64_t frequency) {
const ui_rect_t rect = {point, glyph.size}; const ui_rect_t rect = {point, glyph.size};
portapack_fill_rectangle(rect, color_background); portapack_fill_rectangle(rect, color_background);
} else { } else {
portapack_draw_bitmap(point, glyph, color_foreground, color_background); portapack_draw_bitmap(
point,
glyph,
color_foreground,
color_background);
} }
last[i] = c; last[i] = c;
} }
} }
} }
static void portapack_ui_set_sample_rate(uint32_t sample_rate) { static void portapack_ui_set_sample_rate(uint32_t sample_rate)
{
#if 0 #if 0
ui_point_t point = { VALUES_X, 320 - 1 * 16 }; ui_point_t point = { VALUES_X, 320 - 1 * 16 };
portapack_lcd_draw_int(point, sample_rate, 8); portapack_lcd_draw_int(point, sample_rate, 8);
@ -457,54 +561,81 @@ static void portapack_ui_set_sample_rate(uint32_t sample_rate) {
#endif #endif
} }
static void portapack_ui_set_direction(const rf_path_direction_t direction) { static void portapack_ui_set_direction(const rf_path_direction_t direction)
{
switch (direction) { switch (direction) {
case RF_PATH_DIRECTION_TX: case RF_PATH_DIRECTION_TX:
portapack_radio_path_item_update(RADIO_DRAW_LIST_ITEM_WAVES, &bitmap_waves_tx); portapack_radio_path_item_update(
portapack_radio_path_item_update(RADIO_DRAW_LIST_ITEM_RF_AMP, portapack_lna_on ? &bitmap_amp_tx : &bitmap_wire_24); RADIO_DRAW_LIST_ITEM_WAVES,
portapack_radio_path_item_update(RADIO_DRAW_LIST_ITEM_BB_LNA_AMP, &bitmap_amp_tx); &bitmap_waves_tx);
portapack_radio_path_item_update(RADIO_DRAW_LIST_ITEM_BB_VGA_AMP, &bitmap_wire_24); portapack_radio_path_item_update(
RADIO_DRAW_LIST_ITEM_RF_AMP,
portapack_lna_on ? &bitmap_amp_tx : &bitmap_wire_24);
portapack_radio_path_item_update(
RADIO_DRAW_LIST_ITEM_BB_LNA_AMP,
&bitmap_amp_tx);
portapack_radio_path_item_update(
RADIO_DRAW_LIST_ITEM_BB_VGA_AMP,
&bitmap_wire_24);
portapack_ui_draw_string(RADIO_DRAW_LIST_ITEM_BB_VGA_AMP, " "); portapack_ui_draw_string(RADIO_DRAW_LIST_ITEM_BB_VGA_AMP, " ");
break; break;
case RF_PATH_DIRECTION_RX: case RF_PATH_DIRECTION_RX:
portapack_radio_path_item_update(RADIO_DRAW_LIST_ITEM_WAVES, &bitmap_waves_rx); portapack_radio_path_item_update(
portapack_radio_path_item_update(RADIO_DRAW_LIST_ITEM_RF_AMP, portapack_lna_on ? &bitmap_amp_rx : &bitmap_wire_24); RADIO_DRAW_LIST_ITEM_WAVES,
portapack_radio_path_item_update(RADIO_DRAW_LIST_ITEM_BB_LNA_AMP, &bitmap_amp_rx); &bitmap_waves_rx);
portapack_radio_path_item_update(RADIO_DRAW_LIST_ITEM_BB_VGA_AMP, &bitmap_amp_rx); portapack_radio_path_item_update(
RADIO_DRAW_LIST_ITEM_RF_AMP,
portapack_lna_on ? &bitmap_amp_rx : &bitmap_wire_24);
portapack_radio_path_item_update(
RADIO_DRAW_LIST_ITEM_BB_LNA_AMP,
&bitmap_amp_rx);
portapack_radio_path_item_update(
RADIO_DRAW_LIST_ITEM_BB_VGA_AMP,
&bitmap_amp_rx);
break; break;
case RF_PATH_DIRECTION_OFF: case RF_PATH_DIRECTION_OFF:
default: default:
portapack_radio_path_item_update(RADIO_DRAW_LIST_ITEM_WAVES, &bitmap_blank_24); portapack_radio_path_item_update(
RADIO_DRAW_LIST_ITEM_WAVES,
&bitmap_blank_24);
break; break;
} }
portapack_direction = direction; portapack_direction = direction;
} }
static void portapack_ui_set_filter_bw(uint32_t bandwidth) { static void portapack_ui_set_filter_bw(uint32_t bandwidth)
{
portapack_ui_draw_bw_mhz(RADIO_DRAW_LIST_ITEM_BB_FILTER, bandwidth); portapack_ui_draw_bw_mhz(RADIO_DRAW_LIST_ITEM_BB_FILTER, bandwidth);
} }
static void portapack_ui_set_lna_power(bool lna_on) { static void portapack_ui_set_lna_power(bool lna_on)
{
portapack_lna_on = lna_on; portapack_lna_on = lna_on;
portapack_radio_path_item_update(RADIO_DRAW_LIST_ITEM_RF_AMP, lna_on portapack_radio_path_item_update(
? ((portapack_direction == RF_PATH_DIRECTION_TX) ? &bitmap_amp_tx : &bitmap_amp_rx) RADIO_DRAW_LIST_ITEM_RF_AMP,
: &bitmap_wire_24); lna_on ?
((portapack_direction == RF_PATH_DIRECTION_TX) ? &bitmap_amp_tx :
&bitmap_amp_rx) :
&bitmap_wire_24);
const char* const label = lna_on ? "14 dB" : " "; const char* const label = lna_on ? "14 dB" : " ";
portapack_ui_draw_string(RADIO_DRAW_LIST_ITEM_RF_AMP, label); portapack_ui_draw_string(RADIO_DRAW_LIST_ITEM_RF_AMP, label);
} }
static void portapack_ui_set_bb_lna_gain(const uint32_t gain_db) { static void portapack_ui_set_bb_lna_gain(const uint32_t gain_db)
{
portapack_ui_draw_db(RADIO_DRAW_LIST_ITEM_BB_LNA_AMP, gain_db); portapack_ui_draw_db(RADIO_DRAW_LIST_ITEM_BB_LNA_AMP, gain_db);
} }
static void portapack_ui_set_bb_vga_gain(const uint32_t gain_db) { static void portapack_ui_set_bb_vga_gain(const uint32_t gain_db)
{
portapack_ui_draw_db(RADIO_DRAW_LIST_ITEM_BB_VGA_AMP, gain_db); portapack_ui_draw_db(RADIO_DRAW_LIST_ITEM_BB_VGA_AMP, gain_db);
} }
static void portapack_ui_set_bb_tx_vga_gain(const uint32_t gain_db) { static void portapack_ui_set_bb_tx_vga_gain(const uint32_t gain_db)
{
/* TODO: This function (and code throughout the HackRF project) is mis-labeled? /* TODO: This function (and code throughout the HackRF project) is mis-labeled?
* According to the MAX2837 datasheet diagram, there is no baseband gain in the TX path. * According to the MAX2837 datasheet diagram, there is no baseband gain in the TX path.
* This gets called when the TX IF gain is changed. * This gets called when the TX IF gain is changed.
@ -512,53 +643,76 @@ static void portapack_ui_set_bb_tx_vga_gain(const uint32_t gain_db) {
portapack_ui_draw_db(RADIO_DRAW_LIST_ITEM_BB_LNA_AMP, gain_db); portapack_ui_draw_db(RADIO_DRAW_LIST_ITEM_BB_LNA_AMP, gain_db);
} }
static void portapack_ui_set_first_if_frequency(const uint64_t frequency) { static void portapack_ui_set_first_if_frequency(const uint64_t frequency)
{
(void) frequency; (void) frequency;
} }
static void portapack_ui_set_filter(const rf_path_filter_t filter) { static void portapack_ui_set_filter(const rf_path_filter_t filter)
portapack_radio_path_item_update(RADIO_DRAW_LIST_ITEM_RF_MIXER, (filter == RF_PATH_FILTER_BYPASS) ? &bitmap_wire_24 : &bitmap_mixer); {
portapack_radio_path_item_update(
RADIO_DRAW_LIST_ITEM_RF_MIXER,
(filter == RF_PATH_FILTER_BYPASS) ? &bitmap_wire_24 : &bitmap_mixer);
switch (filter) { switch (filter) {
default: default:
portapack_radio_path_item_update(RADIO_DRAW_LIST_ITEM_IMAGE_FILTER, &bitmap_wire_24); portapack_radio_path_item_update(
RADIO_DRAW_LIST_ITEM_IMAGE_FILTER,
&bitmap_wire_24);
break; break;
case RF_PATH_FILTER_LOW_PASS: case RF_PATH_FILTER_LOW_PASS:
portapack_radio_path_item_update(RADIO_DRAW_LIST_ITEM_IMAGE_FILTER, &bitmap_filter_lp); portapack_radio_path_item_update(
RADIO_DRAW_LIST_ITEM_IMAGE_FILTER,
&bitmap_filter_lp);
break; break;
case RF_PATH_FILTER_HIGH_PASS: case RF_PATH_FILTER_HIGH_PASS:
portapack_radio_path_item_update(RADIO_DRAW_LIST_ITEM_IMAGE_FILTER, &bitmap_filter_hp); portapack_radio_path_item_update(
RADIO_DRAW_LIST_ITEM_IMAGE_FILTER,
&bitmap_filter_hp);
break; break;
} }
} }
static void portapack_ui_set_antenna_bias(bool antenna_bias) { static void portapack_ui_set_antenna_bias(bool antenna_bias)
{
(void) antenna_bias; (void) antenna_bias;
} }
static void portapack_ui_set_clock_source(clock_source_t source) { static void portapack_ui_set_clock_source(clock_source_t source)
{
ui_point_t label_point = radio_draw_list[RADIO_DRAW_LIST_ITEM_CLOCK].point; ui_point_t label_point = radio_draw_list[RADIO_DRAW_LIST_ITEM_CLOCK].point;
label_point.x -= 0; label_point.x -= 0;
label_point.y -= 16; label_point.y -= 16;
const char* s = "HRF"; const char* s = "HRF";
switch (source) { switch (source) {
case CLOCK_SOURCE_EXTERNAL: { s = "EXT"; break; } case CLOCK_SOURCE_EXTERNAL: {
case CLOCK_SOURCE_PORTAPACK: { s = "PPK"; break; } s = "EXT";
break;
}
case CLOCK_SOURCE_PORTAPACK: {
s = "PPK";
break;
}
default: default:
case CLOCK_SOURCE_HACKRF: { s = "HRF"; break; } case CLOCK_SOURCE_HACKRF: {
s = "HRF";
break;
}
} }
portapack_lcd_draw_string(label_point, s); portapack_lcd_draw_string(label_point, s);
} }
static void portapack_ui_set_transceiver_mode(transceiver_mode_t mode) { static void portapack_ui_set_transceiver_mode(transceiver_mode_t mode)
{
(void) mode; (void) mode;
} }
static bool portapack_ui_operacake_gpio_compatible(void) { static bool portapack_ui_operacake_gpio_compatible(void)
{
return false; return false;
} }
@ -581,7 +735,8 @@ const hackrf_ui_t portapack_hackrf_ui = {
&portapack_ui_operacake_gpio_compatible, &portapack_ui_operacake_gpio_compatible,
}; };
const hackrf_ui_t* portapack_hackrf_ui_init() { const hackrf_ui_t* portapack_hackrf_ui_init()
{
if (portapack()) { if (portapack()) {
return &portapack_hackrf_ui; return &portapack_hackrf_ui;
} else { } else {

View File

@ -277,8 +277,7 @@ static void rad1o_ui_set_first_if_frequency(const uint64_t frequency
// Not implemented // Not implemented
} }
static void rad1o_ui_set_filter(const rf_path_filter_t filter static void rad1o_ui_set_filter(const rf_path_filter_t filter __attribute__((unused)))
__attribute__((unused)))
{ {
// Not implemented // Not implemented
} }
@ -288,8 +287,7 @@ static void rad1o_ui_set_antenna_bias(bool antenna_bias __attribute__((unused)))
// Not implemented // Not implemented
} }
static void rad1o_ui_set_clock_source(clock_source_t source static void rad1o_ui_set_clock_source(clock_source_t source __attribute__((unused)))
__attribute__((unused)))
{ {
// Not implemented // Not implemented
} }

View File

@ -36,47 +36,51 @@ usb_device_t* usb_device_usb0 = 0;
usb_queue_head_t usb_qh[12] ATTR_ALIGNED(2048); usb_queue_head_t usb_qh[12] ATTR_ALIGNED(2048);
#define USB_QH_INDEX(endpoint_address) (((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1)) #define USB_QH_INDEX(endpoint_address) \
(((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1))
usb_queue_head_t* usb_queue_head( usb_queue_head_t* usb_queue_head(const uint_fast8_t endpoint_address)
const uint_fast8_t endpoint_address {
) {
return &usb_qh[USB_QH_INDEX(endpoint_address)]; return &usb_qh[USB_QH_INDEX(endpoint_address)];
} }
usb_endpoint_t* usb_endpoint_from_address( usb_endpoint_t* usb_endpoint_from_address(const uint_fast8_t endpoint_address)
const uint_fast8_t endpoint_address {
) {
return (usb_endpoint_t*) usb_queue_head(endpoint_address)->_reserved_0; return (usb_endpoint_t*) usb_queue_head(endpoint_address)->_reserved_0;
} }
static uint_fast8_t usb_endpoint_address( static uint_fast8_t usb_endpoint_address(
const usb_transfer_direction_t direction, const usb_transfer_direction_t direction,
const uint_fast8_t number const uint_fast8_t number)
) { {
return ((direction == USB_TRANSFER_DIRECTION_IN) ? 0x80 : 0x00) + number; return ((direction == USB_TRANSFER_DIRECTION_IN) ? 0x80 : 0x00) + number;
} }
static bool usb_endpoint_is_in(const uint_fast8_t endpoint_address) { static bool usb_endpoint_is_in(const uint_fast8_t endpoint_address)
{
return (endpoint_address & 0x80) ? true : false; return (endpoint_address & 0x80) ? true : false;
} }
static uint_fast8_t usb_endpoint_number(const uint_fast8_t endpoint_address) { static uint_fast8_t usb_endpoint_number(const uint_fast8_t endpoint_address)
{
return (endpoint_address & 0xF); return (endpoint_address & 0xF);
} }
void usb_peripheral_reset() { void usb_peripheral_reset()
{
RESET_CTRL0 = RESET_CTRL0_USB0_RST; RESET_CTRL0 = RESET_CTRL0_USB0_RST;
RESET_CTRL0 = 0; RESET_CTRL0 = 0;
while ((RESET_ACTIVE_STATUS0 & RESET_CTRL0_USB0_RST) == 0) {} while ((RESET_ACTIVE_STATUS0 & RESET_CTRL0_USB0_RST) == 0) {}
} }
void usb_phy_enable() { void usb_phy_enable()
{
CREG_CREG0 &= ~CREG_CREG0_USB0PHY; CREG_CREG0 &= ~CREG_CREG0_USB0PHY;
} }
static void usb_clear_pending_interrupts(const uint32_t mask) { static void usb_clear_pending_interrupts(const uint32_t mask)
{
USB0_ENDPTNAK = mask; USB0_ENDPTNAK = mask;
USB0_ENDPTNAKEN = mask; USB0_ENDPTNAKEN = mask;
USB0_USBSTS_D = mask; USB0_USBSTS_D = mask;
@ -84,80 +88,85 @@ static void usb_clear_pending_interrupts(const uint32_t mask) {
USB0_ENDPTCOMPLETE = USB0_ENDPTCOMPLETE & mask; USB0_ENDPTCOMPLETE = USB0_ENDPTCOMPLETE & mask;
} }
static void usb_clear_all_pending_interrupts() { static void usb_clear_all_pending_interrupts()
{
usb_clear_pending_interrupts(0xFFFFFFFF); usb_clear_pending_interrupts(0xFFFFFFFF);
} }
static void usb_wait_for_endpoint_priming_to_finish(const uint32_t mask) { static void usb_wait_for_endpoint_priming_to_finish(const uint32_t mask)
{
// Wait until controller has parsed new transfer descriptors and prepared // Wait until controller has parsed new transfer descriptors and prepared
// receive buffers. // receive buffers.
while (USB0_ENDPTPRIME & mask) {} while (USB0_ENDPTPRIME & mask) {}
} }
static void usb_flush_endpoints(const uint32_t mask) { static void usb_flush_endpoints(const uint32_t mask)
{
// Clear any primed buffers. If a packet is in progress, that transfer // Clear any primed buffers. If a packet is in progress, that transfer
// will continue until completion. // will continue until completion.
USB0_ENDPTFLUSH = mask; USB0_ENDPTFLUSH = mask;
} }
static void usb_wait_for_endpoint_flushing_to_finish(const uint32_t mask) { static void usb_wait_for_endpoint_flushing_to_finish(const uint32_t mask)
{
// Wait until controller has flushed all endpoints / cleared any primed // Wait until controller has flushed all endpoints / cleared any primed
// buffers. // buffers.
while (USB0_ENDPTFLUSH & mask) {} while (USB0_ENDPTFLUSH & mask) {}
} }
static void usb_flush_primed_endpoints(const uint32_t mask) { static void usb_flush_primed_endpoints(const uint32_t mask)
{
usb_wait_for_endpoint_priming_to_finish(mask); usb_wait_for_endpoint_priming_to_finish(mask);
usb_flush_endpoints(mask); usb_flush_endpoints(mask);
usb_wait_for_endpoint_flushing_to_finish(mask); usb_wait_for_endpoint_flushing_to_finish(mask);
} }
static void usb_flush_all_primed_endpoints() { static void usb_flush_all_primed_endpoints()
{
usb_flush_primed_endpoints(0xFFFFFFFF); usb_flush_primed_endpoints(0xFFFFFFFF);
} }
static void usb_endpoint_set_type( static void usb_endpoint_set_type(
const usb_endpoint_t* const endpoint, const usb_endpoint_t* const endpoint,
const usb_transfer_type_t transfer_type const usb_transfer_type_t transfer_type)
) { {
// NOTE: UM10503 section 23.6.24 "Endpoint 1 to 5 control registers" says // NOTE: UM10503 section 23.6.24 "Endpoint 1 to 5 control registers" says
// that the disabled side of an endpoint must be set to a non-control type // that the disabled side of an endpoint must be set to a non-control type
// (e.g. bulk, interrupt, or iso). // (e.g. bulk, interrupt, or iso).
const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address);
USB0_ENDPTCTRL(endpoint_number) USB0_ENDPTCTRL(endpoint_number) =
= ( USB0_ENDPTCTRL(endpoint_number) (USB0_ENDPTCTRL(endpoint_number) &
& ~(USB0_ENDPTCTRL_TXT1_0_MASK | USB0_ENDPTCTRL_RXT_MASK) ~(USB0_ENDPTCTRL_TXT1_0_MASK | USB0_ENDPTCTRL_RXT_MASK)) |
) (USB0_ENDPTCTRL_TXT1_0(transfer_type) |
| ( USB0_ENDPTCTRL_TXT1_0(transfer_type) USB0_ENDPTCTRL_RXT(transfer_type));
| USB0_ENDPTCTRL_RXT(transfer_type)
);
} }
static void usb_endpoint_enable( static void usb_endpoint_enable(const usb_endpoint_t* const endpoint)
const usb_endpoint_t* const endpoint {
) {
const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address);
if (usb_endpoint_is_in(endpoint->address)) { if (usb_endpoint_is_in(endpoint->address)) {
USB0_ENDPTCTRL(endpoint_number) |= (USB0_ENDPTCTRL_TXE | USB0_ENDPTCTRL_TXR); USB0_ENDPTCTRL(endpoint_number) |=
(USB0_ENDPTCTRL_TXE | USB0_ENDPTCTRL_TXR);
} else { } else {
USB0_ENDPTCTRL(endpoint_number) |= (USB0_ENDPTCTRL_RXE | USB0_ENDPTCTRL_RXR); USB0_ENDPTCTRL(endpoint_number) |=
(USB0_ENDPTCTRL_RXE | USB0_ENDPTCTRL_RXR);
} }
} }
static void usb_endpoint_clear_pending_interrupts( static void usb_endpoint_clear_pending_interrupts(const usb_endpoint_t* const endpoint)
const usb_endpoint_t* const endpoint {
) {
const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address);
if (usb_endpoint_is_in(endpoint->address)) { if (usb_endpoint_is_in(endpoint->address)) {
usb_clear_pending_interrupts(USB0_ENDPTCOMPLETE_ETCE(1 << endpoint_number)); usb_clear_pending_interrupts(
USB0_ENDPTCOMPLETE_ETCE(1 << endpoint_number));
} else { } else {
usb_clear_pending_interrupts(USB0_ENDPTCOMPLETE_ERCE(1 << endpoint_number)); usb_clear_pending_interrupts(
USB0_ENDPTCOMPLETE_ERCE(1 << endpoint_number));
} }
} }
void usb_endpoint_disable( void usb_endpoint_disable(const usb_endpoint_t* const endpoint)
const usb_endpoint_t* const endpoint {
) {
const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address);
if (usb_endpoint_is_in(endpoint->address)) { if (usb_endpoint_is_in(endpoint->address)) {
USB0_ENDPTCTRL(endpoint_number) &= ~(USB0_ENDPTCTRL_TXE); USB0_ENDPTCTRL(endpoint_number) &= ~(USB0_ENDPTCTRL_TXE);
@ -171,16 +180,13 @@ void usb_endpoint_disable(
void usb_endpoint_prime( void usb_endpoint_prime(
const usb_endpoint_t* const endpoint, const usb_endpoint_t* const endpoint,
usb_transfer_descriptor_t* const first_td usb_transfer_descriptor_t* const first_td)
) { {
usb_queue_head_t* const qh = usb_queue_head(endpoint->address); usb_queue_head_t* const qh = usb_queue_head(endpoint->address);
qh->next_dtd_pointer = first_td; qh->next_dtd_pointer = first_td;
qh->total_bytes qh->total_bytes &=
&= ~( USB_TD_DTD_TOKEN_STATUS_ACTIVE ~(USB_TD_DTD_TOKEN_STATUS_ACTIVE | USB_TD_DTD_TOKEN_STATUS_HALTED);
| USB_TD_DTD_TOKEN_STATUS_HALTED
)
;
const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address);
if (usb_endpoint_is_in(endpoint->address)) { if (usb_endpoint_is_in(endpoint->address)) {
@ -190,9 +196,8 @@ void usb_endpoint_prime(
} }
} }
static bool usb_endpoint_is_priming( static bool usb_endpoint_is_priming(const usb_endpoint_t* const endpoint)
const usb_endpoint_t* const endpoint {
) {
const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address);
if (usb_endpoint_is_in(endpoint->address)) { if (usb_endpoint_is_in(endpoint->address)) {
return USB0_ENDPTPRIME & USB0_ENDPTPRIME_PETB(1 << endpoint_number); return USB0_ENDPTPRIME & USB0_ENDPTPRIME_PETB(1 << endpoint_number);
@ -205,8 +210,8 @@ static bool usb_endpoint_is_priming(
// the given endpoint, waiting until the endpoint has finished. // the given endpoint, waiting until the endpoint has finished.
void usb_endpoint_schedule_wait( void usb_endpoint_schedule_wait(
const usb_endpoint_t* const endpoint, const usb_endpoint_t* const endpoint,
usb_transfer_descriptor_t* const td usb_transfer_descriptor_t* const td)
) { {
// Ensure that endpoint is ready to be primed. // Ensure that endpoint is ready to be primed.
// It may have been flushed due to an aborted transaction. // It may have been flushed due to an aborted transaction.
// TODO: This should be preceded by a flush? // TODO: This should be preceded by a flush?
@ -225,8 +230,8 @@ void usb_endpoint_schedule_wait(
void usb_endpoint_schedule_append( void usb_endpoint_schedule_append(
const usb_endpoint_t* const endpoint, const usb_endpoint_t* const endpoint,
usb_transfer_descriptor_t* const tail_td, usb_transfer_descriptor_t* const tail_td,
usb_transfer_descriptor_t* const new_td usb_transfer_descriptor_t* const new_td)
) { {
bool done; bool done;
tail_td->next_dtd_pointer = new_td; tail_td->next_dtd_pointer = new_td;
@ -246,9 +251,8 @@ void usb_endpoint_schedule_append(
} }
} }
void usb_endpoint_flush( void usb_endpoint_flush(const usb_endpoint_t* const endpoint)
const usb_endpoint_t* const endpoint {
) {
const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address);
usb_queue_flush_endpoint(endpoint); usb_queue_flush_endpoint(endpoint);
if (usb_endpoint_is_in(endpoint->address)) { if (usb_endpoint_is_in(endpoint->address)) {
@ -257,6 +261,7 @@ void usb_endpoint_flush(
usb_flush_primed_endpoints(USB0_ENDPTFLUSH_FERB(1 << endpoint_number)); usb_flush_primed_endpoints(USB0_ENDPTFLUSH_FERB(1 << endpoint_number));
} }
} }
/* /*
static bool usb_endpoint_is_flushing( static bool usb_endpoint_is_flushing(
const usb_endpoint_t* const endpoint const usb_endpoint_t* const endpoint
@ -269,9 +274,8 @@ static bool usb_endpoint_is_flushing(
} }
} }
*/ */
bool usb_endpoint_is_ready( bool usb_endpoint_is_ready(const usb_endpoint_t* const endpoint)
const usb_endpoint_t* const endpoint {
) {
const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address);
if (usb_endpoint_is_in(endpoint->address)) { if (usb_endpoint_is_in(endpoint->address)) {
return USB0_ENDPTSTAT & USB0_ENDPTSTAT_ETBR(1 << endpoint_number); return USB0_ENDPTSTAT & USB0_ENDPTSTAT_ETBR(1 << endpoint_number);
@ -280,9 +284,8 @@ bool usb_endpoint_is_ready(
} }
} }
bool usb_endpoint_is_complete( bool usb_endpoint_is_complete(const usb_endpoint_t* const endpoint)
const usb_endpoint_t* const endpoint {
) {
const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address);
if (usb_endpoint_is_in(endpoint->address)) { if (usb_endpoint_is_in(endpoint->address)) {
return USB0_ENDPTCOMPLETE & USB0_ENDPTCOMPLETE_ETCE(1 << endpoint_number); return USB0_ENDPTCOMPLETE & USB0_ENDPTCOMPLETE_ETCE(1 << endpoint_number);
@ -291,9 +294,8 @@ bool usb_endpoint_is_complete(
} }
} }
void usb_endpoint_stall( void usb_endpoint_stall(const usb_endpoint_t* const endpoint)
const usb_endpoint_t* const endpoint {
) {
// Endpoint is to be stalled as a pair -- both OUT and IN. // Endpoint is to be stalled as a pair -- both OUT and IN.
// See UM10503 section 23.10.5.2 "Stalling" // See UM10503 section 23.10.5.2 "Stalling"
const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address);
@ -302,9 +304,8 @@ void usb_endpoint_stall(
// TODO: Also need to reset data toggle in both directions? // TODO: Also need to reset data toggle in both directions?
} }
void usb_endpoint_reset_data_toggle( void usb_endpoint_reset_data_toggle(const usb_endpoint_t* const endpoint)
const usb_endpoint_t* const endpoint {
) {
const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address);
if (usb_endpoint_is_in(endpoint->address)) { if (usb_endpoint_is_in(endpoint->address)) {
USB0_ENDPTCTRL(endpoint_number) |= USB0_ENDPTCTRL_TXR; USB0_ENDPTCTRL(endpoint_number) |= USB0_ENDPTCTRL_TXR;
@ -313,19 +314,23 @@ void usb_endpoint_reset_data_toggle(
} }
} }
static void usb_controller_run() { static void usb_controller_run()
{
USB0_USBCMD_D |= USB0_USBCMD_D_RS; USB0_USBCMD_D |= USB0_USBCMD_D_RS;
} }
static void usb_controller_stop() { static void usb_controller_stop()
{
USB0_USBCMD_D &= ~USB0_USBCMD_D_RS; USB0_USBCMD_D &= ~USB0_USBCMD_D_RS;
} }
static uint_fast8_t usb_controller_is_resetting() { static uint_fast8_t usb_controller_is_resetting()
{
return (USB0_USBCMD_D & USB0_USBCMD_D_RST) != 0; return (USB0_USBCMD_D & USB0_USBCMD_D_RST) != 0;
} }
static void usb_controller_set_device_mode() { static void usb_controller_set_device_mode()
{
// Set USB0 peripheral mode // Set USB0 peripheral mode
USB0_USBMODE_D = USB0_USBMODE_D_CM1_0(2); USB0_USBMODE_D = USB0_USBMODE_D_CM1_0(2);
@ -334,9 +339,8 @@ static void usb_controller_set_device_mode() {
USB0_OTGSC = USB0_OTGSC_OT; USB0_OTGSC = USB0_OTGSC_OT;
} }
usb_speed_t usb_speed( usb_speed_t usb_speed(const usb_device_t* const device)
const usb_device_t* const device {
) {
if (device == usb_device_usb0) { if (device == usb_device_usb0) {
switch (USB0_PORTSC1_D & USB0_PORTSC1_D_PSPD_MASK) { switch (USB0_PORTSC1_D & USB0_PORTSC1_D_PSPD_MASK) {
case USB0_PORTSC1_D_PSPD(0): case USB0_PORTSC1_D_PSPD(0):
@ -356,11 +360,13 @@ usb_speed_t usb_speed(
} }
} }
static void usb_clear_status(const uint32_t status) { static void usb_clear_status(const uint32_t status)
{
USB0_USBSTS_D = status; USB0_USBSTS_D = status;
} }
static uint32_t usb_get_status() { static uint32_t usb_get_status()
{
// Mask status flags with enabled flag interrupts. // Mask status flags with enabled flag interrupts.
const uint32_t status = USB0_USBSTS_D & USB0_USBINTR_D; const uint32_t status = USB0_USBSTS_D & USB0_USBINTR_D;
@ -372,23 +378,28 @@ static uint32_t usb_get_status() {
return status; return status;
} }
static void usb_clear_endpoint_setup_status(const uint32_t endpoint_setup_status) { static void usb_clear_endpoint_setup_status(const uint32_t endpoint_setup_status)
{
USB0_ENDPTSETUPSTAT = endpoint_setup_status; USB0_ENDPTSETUPSTAT = endpoint_setup_status;
} }
static uint32_t usb_get_endpoint_setup_status() { static uint32_t usb_get_endpoint_setup_status()
{
return USB0_ENDPTSETUPSTAT; return USB0_ENDPTSETUPSTAT;
} }
static void usb_clear_endpoint_complete(const uint32_t endpoint_complete) { static void usb_clear_endpoint_complete(const uint32_t endpoint_complete)
{
USB0_ENDPTCOMPLETE = endpoint_complete; USB0_ENDPTCOMPLETE = endpoint_complete;
} }
static uint32_t usb_get_endpoint_complete() { static uint32_t usb_get_endpoint_complete()
{
return USB0_ENDPTCOMPLETE; return USB0_ENDPTCOMPLETE;
} }
static void usb_disable_all_endpoints() { static void usb_disable_all_endpoints()
{
// Endpoint 0 is always enabled. TODO: So why set ENDPTCTRL0? // Endpoint 0 is always enabled. TODO: So why set ENDPTCTRL0?
USB0_ENDPTCTRL0 &= ~(USB0_ENDPTCTRL0_RXE | USB0_ENDPTCTRL0_TXE); USB0_ENDPTCTRL0 &= ~(USB0_ENDPTCTRL0_RXE | USB0_ENDPTCTRL0_TXE);
USB0_ENDPTCTRL1 &= ~(USB0_ENDPTCTRL1_RXE | USB0_ENDPTCTRL1_TXE); USB0_ENDPTCTRL1 &= ~(USB0_ENDPTCTRL1_RXE | USB0_ENDPTCTRL1_TXE);
@ -400,32 +411,30 @@ static void usb_disable_all_endpoints() {
void usb_set_address_immediate( void usb_set_address_immediate(
const usb_device_t* const device, const usb_device_t* const device,
const uint_fast8_t address const uint_fast8_t address)
) { {
if (device == usb_device_usb0) { if (device == usb_device_usb0) {
USB0_DEVICEADDR = USB0_DEVICEADDR_USBADR(address); USB0_DEVICEADDR = USB0_DEVICEADDR_USBADR(address);
} }
} }
void usb_set_address_deferred( void usb_set_address_deferred(const usb_device_t* const device, const uint_fast8_t address)
const usb_device_t* const device, {
const uint_fast8_t address
) {
if (device == usb_device_usb0) { if (device == usb_device_usb0) {
USB0_DEVICEADDR USB0_DEVICEADDR =
= USB0_DEVICEADDR_USBADR(address) USB0_DEVICEADDR_USBADR(address) | USB0_DEVICEADDR_USBADRA;
| USB0_DEVICEADDR_USBADRA
;
} }
} }
static void usb_reset_all_endpoints() { static void usb_reset_all_endpoints()
{
usb_disable_all_endpoints(); usb_disable_all_endpoints();
usb_clear_all_pending_interrupts(); usb_clear_all_pending_interrupts();
usb_flush_all_primed_endpoints(); usb_flush_all_primed_endpoints();
} }
static void usb_controller_reset() { static void usb_controller_reset()
{
// TODO: Good to disable some USB interrupts to avoid priming new // TODO: Good to disable some USB interrupts to avoid priming new
// new endpoints before the controller is reset? // new endpoints before the controller is reset?
usb_reset_all_endpoints(); usb_reset_all_endpoints();
@ -440,7 +449,8 @@ static void usb_controller_reset() {
while (usb_controller_is_resetting()) {} while (usb_controller_is_resetting()) {}
} }
static void usb_bus_reset(usb_device_t* const device) { static void usb_bus_reset(usb_device_t* const device)
{
// According to UM10503 v1.4 section 23.10.3 "Bus reset": // According to UM10503 v1.4 section 23.10.3 "Bus reset":
usb_reset_all_endpoints(); usb_reset_all_endpoints();
usb_set_address_immediate(device, 0); usb_set_address_immediate(device, 0);
@ -458,18 +468,15 @@ static void usb_bus_reset(usb_device_t* const device) {
//} //}
} }
static void usb_interrupt_enable( static void usb_interrupt_enable(usb_device_t* const device)
usb_device_t* const device {
) {
if (device == usb_device_usb0) { if (device == usb_device_usb0) {
nvic_enable_irq(NVIC_USB0_IRQ); nvic_enable_irq(NVIC_USB0_IRQ);
} }
} }
void usb_device_init( void usb_device_init(const uint_fast8_t device_ordinal, usb_device_t* const device)
const uint_fast8_t device_ordinal, {
usb_device_t* const device
) {
if (device_ordinal == 0) { if (device_ordinal == 0) {
usb_device_usb0 = device; usb_device_usb0 = device;
@ -484,11 +491,9 @@ void usb_device_init(
USB0_ENDPOINTLISTADDR = (uint32_t) usb_qh; USB0_ENDPOINTLISTADDR = (uint32_t) usb_qh;
// Enable interrupts // Enable interrupts
USB0_USBINTR_D = USB0_USBINTR_D = USB0_USBINTR_D_UE | USB0_USBINTR_D_UEE |
USB0_USBINTR_D_UE USB0_USBINTR_D_PCE |
| USB0_USBINTR_D_UEE USB0_USBINTR_D_URE
| USB0_USBINTR_D_PCE
| USB0_USBINTR_D_URE
//| USB0_USBINTR_D_SRE //| USB0_USBINTR_D_SRE
| USB0_USBINTR_D_SLE | USB0_USBINTR_D_SLE
//| USB0_USBINTR_D_NAKE //| USB0_USBINTR_D_NAKE
@ -496,14 +501,14 @@ void usb_device_init(
} }
} }
void usb_run( void usb_run(usb_device_t* const device)
usb_device_t* const device {
) {
usb_interrupt_enable(device); usb_interrupt_enable(device);
usb_controller_run(device); usb_controller_run(device);
} }
static void copy_setup(usb_setup_t* const dst, const volatile uint8_t* const src) { static void copy_setup(usb_setup_t* const dst, const volatile uint8_t* const src)
{
dst->request_type = src[0]; dst->request_type = src[0];
dst->request = src[1]; dst->request = src[1];
dst->value_l = src[2]; dst->value_l = src[2];
@ -514,34 +519,30 @@ static void copy_setup(usb_setup_t* const dst, const volatile uint8_t* const src
dst->length_h = src[7]; dst->length_h = src[7];
} }
void usb_endpoint_init( void usb_endpoint_init(const usb_endpoint_t* const endpoint)
const usb_endpoint_t* const endpoint {
) {
usb_endpoint_flush(endpoint); usb_endpoint_flush(endpoint);
uint_fast16_t max_packet_size = endpoint->device->descriptor[7]; uint_fast16_t max_packet_size = endpoint->device->descriptor[7];
usb_transfer_type_t transfer_type = USB_TRANSFER_TYPE_CONTROL; usb_transfer_type_t transfer_type = USB_TRANSFER_TYPE_CONTROL;
const uint8_t* const endpoint_descriptor = usb_endpoint_descriptor(endpoint); const uint8_t* const endpoint_descriptor = usb_endpoint_descriptor(endpoint);
if (endpoint_descriptor) { if (endpoint_descriptor) {
max_packet_size = usb_endpoint_descriptor_max_packet_size(endpoint_descriptor); max_packet_size =
transfer_type = usb_endpoint_descriptor_transfer_type(endpoint_descriptor); usb_endpoint_descriptor_max_packet_size(endpoint_descriptor);
transfer_type =
usb_endpoint_descriptor_transfer_type(endpoint_descriptor);
} }
// TODO: There are more capabilities to adjust based on the endpoint // TODO: There are more capabilities to adjust based on the endpoint
// descriptor. // descriptor.
usb_queue_head_t* const qh = usb_queue_head(endpoint->address); usb_queue_head_t* const qh = usb_queue_head(endpoint->address);
qh->capabilities qh->capabilities = USB_QH_CAPABILITIES_MULT(0) | USB_QH_CAPABILITIES_ZLT |
= USB_QH_CAPABILITIES_MULT(0) USB_QH_CAPABILITIES_MPL(max_packet_size) |
| USB_QH_CAPABILITIES_ZLT ((transfer_type == USB_TRANSFER_TYPE_CONTROL) ? USB_QH_CAPABILITIES_IOS :
| USB_QH_CAPABILITIES_MPL(max_packet_size) 0);
| ((transfer_type == USB_TRANSFER_TYPE_CONTROL) ? USB_QH_CAPABILITIES_IOS : 0)
;
qh->current_dtd_pointer = 0; qh->current_dtd_pointer = 0;
qh->next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; qh->next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE;
qh->total_bytes qh->total_bytes = USB_TD_DTD_TOKEN_TOTAL_BYTES(0) | USB_TD_DTD_TOKEN_MULTO(0);
= USB_TD_DTD_TOKEN_TOTAL_BYTES(0)
| USB_TD_DTD_TOKEN_MULTO(0)
;
qh->buffer_pointer_page[0] = 0; qh->buffer_pointer_page[0] = 0;
qh->buffer_pointer_page[1] = 0; qh->buffer_pointer_page[1] = 0;
qh->buffer_pointer_page[2] = 0; qh->buffer_pointer_page[2] = 0;
@ -560,55 +561,65 @@ void usb_endpoint_init(
usb_endpoint_enable(endpoint); usb_endpoint_enable(endpoint);
} }
static void usb_check_for_setup_events() { static void usb_check_for_setup_events()
{
const uint32_t endptsetupstat = usb_get_endpoint_setup_status(); const uint32_t endptsetupstat = usb_get_endpoint_setup_status();
if (endptsetupstat) { if (endptsetupstat) {
for (uint_fast8_t i = 0; i < 6; i++) { for (uint_fast8_t i = 0; i < 6; i++) {
const uint32_t endptsetupstat_bit = USB0_ENDPTSETUPSTAT_ENDPTSETUPSTAT(1 << i); const uint32_t endptsetupstat_bit =
USB0_ENDPTSETUPSTAT_ENDPTSETUPSTAT(1 << i);
if (endptsetupstat & endptsetupstat_bit) { if (endptsetupstat & endptsetupstat_bit) {
usb_endpoint_t* const endpoint = usb_endpoint_t* const endpoint =
usb_endpoint_from_address( usb_endpoint_from_address(usb_endpoint_address(
usb_endpoint_address(USB_TRANSFER_DIRECTION_OUT, i) USB_TRANSFER_DIRECTION_OUT,
); i));
if (endpoint && endpoint->setup_complete) { if (endpoint && endpoint->setup_complete) {
copy_setup(&endpoint->setup, usb_queue_head(endpoint->address)->setup); copy_setup(
&endpoint->setup,
usb_queue_head(endpoint->address)->setup);
// TODO: Clean up this duplicated effort by providing // TODO: Clean up this duplicated effort by providing
// a cleaner way to get the SETUP data. // a cleaner way to get the SETUP data.
copy_setup(&endpoint->in->setup, usb_queue_head(endpoint->address)->setup); copy_setup(
usb_clear_endpoint_setup_status(endptsetupstat_bit); &endpoint->in->setup,
usb_queue_head(endpoint->address)->setup);
usb_clear_endpoint_setup_status(
endptsetupstat_bit);
endpoint->setup_complete(endpoint); endpoint->setup_complete(endpoint);
} else { } else {
usb_clear_endpoint_setup_status(endptsetupstat_bit); usb_clear_endpoint_setup_status(
endptsetupstat_bit);
} }
} }
} }
} }
} }
static void usb_check_for_transfer_events() { static void usb_check_for_transfer_events()
{
const uint32_t endptcomplete = usb_get_endpoint_complete(); const uint32_t endptcomplete = usb_get_endpoint_complete();
if (endptcomplete) { if (endptcomplete) {
for (uint_fast8_t i = 0; i < 6; i++) { for (uint_fast8_t i = 0; i < 6; i++) {
const uint32_t endptcomplete_out_bit =
const uint32_t endptcomplete_out_bit = USB0_ENDPTCOMPLETE_ERCE(1 << i); USB0_ENDPTCOMPLETE_ERCE(1 << i);
if (endptcomplete & endptcomplete_out_bit) { if (endptcomplete & endptcomplete_out_bit) {
usb_clear_endpoint_complete(endptcomplete_out_bit); usb_clear_endpoint_complete(endptcomplete_out_bit);
usb_endpoint_t* const endpoint = usb_endpoint_t* const endpoint =
usb_endpoint_from_address( usb_endpoint_from_address(usb_endpoint_address(
usb_endpoint_address(USB_TRANSFER_DIRECTION_OUT, i) USB_TRANSFER_DIRECTION_OUT,
); i));
if (endpoint && endpoint->transfer_complete) { if (endpoint && endpoint->transfer_complete) {
endpoint->transfer_complete(endpoint); endpoint->transfer_complete(endpoint);
} }
} }
const uint32_t endptcomplete_in_bit = USB0_ENDPTCOMPLETE_ETCE(1 << i); const uint32_t endptcomplete_in_bit =
USB0_ENDPTCOMPLETE_ETCE(1 << i);
if (endptcomplete & endptcomplete_in_bit) { if (endptcomplete & endptcomplete_in_bit) {
usb_clear_endpoint_complete(endptcomplete_in_bit); usb_clear_endpoint_complete(endptcomplete_in_bit);
usb_endpoint_t* const endpoint = usb_endpoint_t* const endpoint =
usb_endpoint_from_address( usb_endpoint_from_address(usb_endpoint_address(
usb_endpoint_address(USB_TRANSFER_DIRECTION_IN, i) USB_TRANSFER_DIRECTION_IN,
); i));
if (endpoint && endpoint->transfer_complete) { if (endpoint && endpoint->transfer_complete) {
endpoint->transfer_complete(endpoint); endpoint->transfer_complete(endpoint);
} }
@ -617,7 +628,8 @@ static void usb_check_for_transfer_events() {
} }
} }
void usb0_isr() { void usb0_isr()
{
const uint32_t status = usb_get_status(); const uint32_t status = usb_get_status();
if (status == 0) { if (status == 0) {

View File

@ -31,75 +31,47 @@
void usb_peripheral_reset(); void usb_peripheral_reset();
void usb_phy_enable(); void usb_phy_enable();
void usb_device_init( void usb_device_init(const uint_fast8_t device_ordinal, usb_device_t* const device);
const uint_fast8_t device_ordinal,
usb_device_t* const device
);
void usb_run( void usb_run(usb_device_t* const device);
usb_device_t* const device
);
void usb_run_tasks( void usb_run_tasks(const usb_device_t* const device);
const usb_device_t* const device
);
usb_speed_t usb_speed( usb_speed_t usb_speed(const usb_device_t* const device);
const usb_device_t* const device
);
void usb_set_address_immediate( void usb_set_address_immediate(
const usb_device_t* const device, const usb_device_t* const device,
const uint_fast8_t address const uint_fast8_t address);
);
void usb_set_address_deferred( void usb_set_address_deferred(
const usb_device_t* const device, const usb_device_t* const device,
const uint_fast8_t address const uint_fast8_t address);
);
usb_endpoint_t* usb_endpoint_from_address( usb_endpoint_t* usb_endpoint_from_address(const uint_fast8_t endpoint_address);
const uint_fast8_t endpoint_address
);
void usb_endpoint_init( void usb_endpoint_init(const usb_endpoint_t* const endpoint);
const usb_endpoint_t* const endpoint
);
void usb_endpoint_stall( void usb_endpoint_stall(const usb_endpoint_t* const endpoint);
const usb_endpoint_t* const endpoint
);
void usb_endpoint_disable( void usb_endpoint_disable(const usb_endpoint_t* const endpoint);
const usb_endpoint_t* const endpoint
);
void usb_endpoint_reset_data_toggle( void usb_endpoint_reset_data_toggle(const usb_endpoint_t* const endpoint);
const usb_endpoint_t* const endpoint
);
void usb_endpoint_flush( void usb_endpoint_flush(const usb_endpoint_t* const endpoint);
const usb_endpoint_t* const endpoint
);
bool usb_endpoint_is_ready( bool usb_endpoint_is_ready(const usb_endpoint_t* const endpoint);
const usb_endpoint_t* const endpoint
);
void usb_endpoint_prime( void usb_endpoint_prime(
const usb_endpoint_t* const endpoint, const usb_endpoint_t* const endpoint,
usb_transfer_descriptor_t* const first_td usb_transfer_descriptor_t* const first_td);
);
void usb_endpoint_schedule_wait( void usb_endpoint_schedule_wait(
const usb_endpoint_t* const endpoint, const usb_endpoint_t* const endpoint,
usb_transfer_descriptor_t* const td usb_transfer_descriptor_t* const td);
);
void usb_endpoint_schedule_append( void usb_endpoint_schedule_append(
const usb_endpoint_t* const endpoint, const usb_endpoint_t* const endpoint,
usb_transfer_descriptor_t* const tail_td, usb_transfer_descriptor_t* const tail_td,
usb_transfer_descriptor_t* const new_td usb_transfer_descriptor_t* const new_td);
);
#endif //__USB_H__ #endif //__USB_H__

View File

@ -33,20 +33,19 @@
usb_queue_t* endpoint_queues[12] = {}; usb_queue_t* endpoint_queues[12] = {};
#define USB_ENDPOINT_INDEX(endpoint_address) (((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1)) #define USB_ENDPOINT_INDEX(endpoint_address) \
(((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1))
static usb_queue_t* endpoint_queue( static usb_queue_t* endpoint_queue(const usb_endpoint_t* const endpoint)
const usb_endpoint_t* const endpoint {
) {
uint32_t index = USB_ENDPOINT_INDEX(endpoint->address); uint32_t index = USB_ENDPOINT_INDEX(endpoint->address);
if (endpoint_queues[index] == NULL) if (endpoint_queues[index] == NULL)
while (1) {} while (1) {}
return endpoint_queues[index]; return endpoint_queues[index];
} }
void usb_queue_init( void usb_queue_init(usb_queue_t* const queue)
usb_queue_t* const queue {
) {
uint32_t index = USB_ENDPOINT_INDEX(queue->endpoint->address); uint32_t index = USB_ENDPOINT_INDEX(queue->endpoint->address);
if (endpoint_queues[index] != NULL) if (endpoint_queues[index] != NULL)
while (1) {} while (1) {}
@ -62,9 +61,8 @@ void usb_queue_init(
} }
/* Allocate a transfer */ /* Allocate a transfer */
static usb_transfer_t* allocate_transfer( static usb_transfer_t* allocate_transfer(usb_queue_t* const queue)
usb_queue_t* const queue {
) {
bool aborted; bool aborted;
usb_transfer_t* transfer; usb_transfer_t* transfer;
if (queue->free_transfers == NULL) if (queue->free_transfers == NULL)
@ -72,7 +70,9 @@ static usb_transfer_t* allocate_transfer(
do { do {
transfer = (void*) __ldrex((uint32_t*) &queue->free_transfers); transfer = (void*) __ldrex((uint32_t*) &queue->free_transfers);
aborted = __strex((uint32_t) transfer->next, (uint32_t *) &queue->free_transfers); aborted =
__strex((uint32_t) transfer->next,
(uint32_t*) &queue->free_transfers);
} while (aborted); } while (aborted);
transfer->next = NULL; transfer->next = NULL;
return transfer; return transfer;
@ -85,21 +85,22 @@ static void free_transfer(usb_transfer_t* const transfer)
bool aborted; bool aborted;
do { do {
transfer->next = (void*) __ldrex((uint32_t*) &queue->free_transfers); transfer->next = (void*) __ldrex((uint32_t*) &queue->free_transfers);
aborted = __strex((uint32_t) transfer, (uint32_t *) &queue->free_transfers); aborted =
__strex((uint32_t) transfer, (uint32_t*) &queue->free_transfers);
} while (aborted); } while (aborted);
} }
/* Add a transfer to the end of an endpoint's queue. Returns the old /* Add a transfer to the end of an endpoint's queue. Returns the old
* tail or NULL is the queue was empty * tail or NULL is the queue was empty
*/ */
static usb_transfer_t* endpoint_queue_transfer( static usb_transfer_t* endpoint_queue_transfer(usb_transfer_t* const transfer)
usb_transfer_t* const transfer {
) {
usb_queue_t* const queue = transfer->queue; usb_queue_t* const queue = transfer->queue;
transfer->next = NULL; transfer->next = NULL;
if (queue->active != NULL) { if (queue->active != NULL) {
usb_transfer_t* t = queue->active; usb_transfer_t* t = queue->active;
while (t->next != NULL) t = t->next; while (t->next != NULL)
t = t->next;
t->next = transfer; t->next = transfer;
return t; return t;
} else { } else {
@ -129,21 +130,19 @@ int usb_transfer_schedule(
void* const data, void* const data,
const uint32_t maximum_length, const uint32_t maximum_length,
const transfer_completion_cb completion_cb, const transfer_completion_cb completion_cb,
void* const user_data void* const user_data)
) { {
usb_queue_t* const queue = endpoint_queue(endpoint); usb_queue_t* const queue = endpoint_queue(endpoint);
usb_transfer_t* const transfer = allocate_transfer(queue); usb_transfer_t* const transfer = allocate_transfer(queue);
if (transfer == NULL) return -1; if (transfer == NULL)
return -1;
usb_transfer_descriptor_t* const td = &transfer->td; usb_transfer_descriptor_t* const td = &transfer->td;
// Configure the transfer descriptor // Configure the transfer descriptor
td->next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; td->next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE;
td->total_bytes = td->total_bytes = USB_TD_DTD_TOKEN_TOTAL_BYTES(maximum_length) |
USB_TD_DTD_TOKEN_TOTAL_BYTES(maximum_length) USB_TD_DTD_TOKEN_IOC | USB_TD_DTD_TOKEN_MULTO(0) |
| USB_TD_DTD_TOKEN_IOC USB_TD_DTD_TOKEN_STATUS_ACTIVE;
| USB_TD_DTD_TOKEN_MULTO(0)
| USB_TD_DTD_TOKEN_STATUS_ACTIVE
;
td->buffer_pointer_page[0] = (uint32_t) data; td->buffer_pointer_page[0] = (uint32_t) data;
td->buffer_pointer_page[1] = ((uint32_t) data + 0x1000) & 0xfffff000; td->buffer_pointer_page[1] = ((uint32_t) data + 0x1000) & 0xfffff000;
td->buffer_pointer_page[2] = ((uint32_t) data + 0x2000) & 0xfffff000; td->buffer_pointer_page[2] = ((uint32_t) data + 0x2000) & 0xfffff000;
@ -173,19 +172,22 @@ int usb_transfer_schedule_block(
void* const data, void* const data,
const uint32_t maximum_length, const uint32_t maximum_length,
const transfer_completion_cb completion_cb, const transfer_completion_cb completion_cb,
void* const user_data void* const user_data)
) { {
int ret; int ret;
do { do {
ret = usb_transfer_schedule(endpoint, data, maximum_length, ret = usb_transfer_schedule(
completion_cb, user_data); endpoint,
data,
maximum_length,
completion_cb,
user_data);
} while (ret == -1); } while (ret == -1);
return 0; return 0;
} }
int usb_transfer_schedule_ack( int usb_transfer_schedule_ack(const usb_endpoint_t* const endpoint)
const usb_endpoint_t* const endpoint {
) {
return usb_transfer_schedule_block(endpoint, 0, 0, NULL, NULL); return usb_transfer_schedule_block(endpoint, 0, 0, NULL, NULL);
} }
@ -201,9 +203,9 @@ void usb_queue_transfer_complete(usb_endpoint_t* const endpoint)
uint8_t status = transfer->td.total_bytes; uint8_t status = transfer->td.total_bytes;
// Check for failures // Check for failures
if ( status & USB_TD_DTD_TOKEN_STATUS_HALTED if (status & USB_TD_DTD_TOKEN_STATUS_HALTED ||
|| status & USB_TD_DTD_TOKEN_STATUS_BUFFER_ERROR status & USB_TD_DTD_TOKEN_STATUS_BUFFER_ERROR ||
|| status & USB_TD_DTD_TOKEN_STATUS_TRANSACTION_ERROR) { status & USB_TD_DTD_TOKEN_STATUS_TRANSACTION_ERROR) {
// TODO: Uh oh, do something useful here // TODO: Uh oh, do something useful here
while (1) {} while (1) {}
} }
@ -218,7 +220,9 @@ void usb_queue_transfer_complete(usb_endpoint_t* const endpoint)
usb_transfer_t* next = transfer->next; usb_transfer_t* next = transfer->next;
// Invoke completion callback // Invoke completion callback
unsigned int total_bytes = (transfer->td.total_bytes & USB_TD_DTD_TOKEN_TOTAL_BYTES_MASK) >> USB_TD_DTD_TOKEN_TOTAL_BYTES_SHIFT; unsigned int total_bytes =
(transfer->td.total_bytes & USB_TD_DTD_TOKEN_TOTAL_BYTES_MASK) >>
USB_TD_DTD_TOKEN_TOTAL_BYTES_SHIFT;
unsigned int transferred = transfer->maximum_length - total_bytes; unsigned int transferred = transfer->maximum_length - total_bytes;
if (transfer->completion_cb) if (transfer->completion_cb)
transfer->completion_cb(transfer->user_data, transferred); transfer->completion_cb(transfer->user_data, transferred);

View File

@ -49,15 +49,13 @@ struct _usb_queue_t {
usb_transfer_t* volatile active; usb_transfer_t* volatile active;
}; };
#define USB_DECLARE_QUEUE(endpoint_name) \ #define USB_DECLARE_QUEUE(endpoint_name) struct _usb_queue_t endpoint_name##_queue;
struct _usb_queue_t endpoint_name##_queue;
#define USB_DEFINE_QUEUE(endpoint_name, _pool_size) \ #define USB_DEFINE_QUEUE(endpoint_name, _pool_size) \
struct _usb_transfer_t endpoint_name##_transfers[_pool_size]; \ struct _usb_transfer_t endpoint_name##_transfers[_pool_size]; \
struct _usb_queue_t endpoint_name##_queue = { \ struct _usb_queue_t endpoint_name##_queue = { \
.endpoint = &endpoint_name, \ .endpoint = &endpoint_name, \
.free_transfers = endpoint_name##_transfers, \ .free_transfers = endpoint_name##_transfers, \
.pool_size = _pool_size \ .pool_size = _pool_size};
};
void usb_queue_flush_endpoint(const usb_endpoint_t* const endpoint); void usb_queue_flush_endpoint(const usb_endpoint_t* const endpoint);
@ -66,27 +64,19 @@ int usb_transfer_schedule(
void* const data, void* const data,
const uint32_t maximum_length, const uint32_t maximum_length,
const transfer_completion_cb completion_cb, const transfer_completion_cb completion_cb,
void* const user_data void* const user_data);
);
int usb_transfer_schedule_block( int usb_transfer_schedule_block(
const usb_endpoint_t* const endpoint, const usb_endpoint_t* const endpoint,
void* const data, void* const data,
const uint32_t maximum_length, const uint32_t maximum_length,
const transfer_completion_cb completion_cb, const transfer_completion_cb completion_cb,
void* const user_data void* const user_data);
);
int usb_transfer_schedule_ack( int usb_transfer_schedule_ack(const usb_endpoint_t* const endpoint);
const usb_endpoint_t* const endpoint
);
void usb_queue_init( void usb_queue_init(usb_queue_t* const queue);
usb_queue_t* const queue
);
void usb_queue_transfer_complete( void usb_queue_transfer_complete(usb_endpoint_t* const endpoint);
usb_endpoint_t* const endpoint
);
#endif //__USB_QUEUE_H__ #endif //__USB_QUEUE_H__

View File

@ -25,10 +25,8 @@
#include <stdbool.h> #include <stdbool.h>
static void usb_request( static void usb_request(usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
usb_endpoint_t* const endpoint, {
const usb_transfer_stage_t stage
) {
usb_request_status_t status = USB_REQUEST_STATUS_STALL; usb_request_status_t status = USB_REQUEST_STATUS_STALL;
usb_request_handler_fn handler = 0; usb_request_handler_fn handler = 0;
@ -60,17 +58,15 @@ static void usb_request(
} }
} }
void usb_setup_complete( void usb_setup_complete(usb_endpoint_t* const endpoint)
usb_endpoint_t* const endpoint {
) {
usb_request(endpoint, USB_TRANSFER_STAGE_SETUP); usb_request(endpoint, USB_TRANSFER_STAGE_SETUP);
} }
void usb_control_out_complete( void usb_control_out_complete(usb_endpoint_t* const endpoint)
usb_endpoint_t* const endpoint {
) { const bool device_to_host = endpoint->setup.request_type >>
const bool device_to_host = USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift;
endpoint->setup.request_type >> USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift;
if (device_to_host) { if (device_to_host) {
usb_request(endpoint, USB_TRANSFER_STAGE_STATUS); usb_request(endpoint, USB_TRANSFER_STAGE_STATUS);
} else { } else {
@ -79,11 +75,10 @@ void usb_control_out_complete(
usb_queue_transfer_complete(endpoint); usb_queue_transfer_complete(endpoint);
} }
void usb_control_in_complete( void usb_control_in_complete(usb_endpoint_t* const endpoint)
usb_endpoint_t* const endpoint {
) { const bool device_to_host = endpoint->setup.request_type >>
const bool device_to_host = USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift;
endpoint->setup.request_type >> USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift;
if (device_to_host) { if (device_to_host) {
usb_request(endpoint, USB_TRANSFER_STAGE_DATA); usb_request(endpoint, USB_TRANSFER_STAGE_DATA);
} else { } else {
@ -91,4 +86,3 @@ void usb_control_in_complete(
} }
usb_queue_transfer_complete(endpoint); usb_queue_transfer_complete(endpoint);
} }

View File

@ -44,8 +44,7 @@ typedef enum {
typedef usb_request_status_t (*usb_request_handler_fn)( typedef usb_request_status_t (*usb_request_handler_fn)(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage);
);
typedef struct { typedef struct {
usb_request_handler_fn standard; usb_request_handler_fn standard;
@ -56,16 +55,10 @@ typedef struct {
extern const usb_request_handlers_t usb_request_handlers; extern const usb_request_handlers_t usb_request_handlers;
void usb_setup_complete( void usb_setup_complete(usb_endpoint_t* const endpoint);
usb_endpoint_t* const endpoint
);
void usb_control_in_complete( void usb_control_in_complete(usb_endpoint_t* const endpoint);
usb_endpoint_t* const endpoint
);
void usb_control_out_complete( void usb_control_out_complete(usb_endpoint_t* const endpoint);
usb_endpoint_t* const endpoint
);
#endif //__USB_REQUEST_H__ #endif //__USB_REQUEST_H__

View File

@ -28,9 +28,8 @@
#include "usb_type.h" #include "usb_type.h"
#include "usb_queue.h" #include "usb_queue.h"
const uint8_t* usb_endpoint_descriptor( const uint8_t* usb_endpoint_descriptor(const usb_endpoint_t* const endpoint)
const usb_endpoint_t* const endpoint {
) {
const usb_configuration_t* const configuration = endpoint->device->configuration; const usb_configuration_t* const configuration = endpoint->device->configuration;
if (configuration) { if (configuration) {
const uint8_t* descriptor = configuration->descriptor; const uint8_t* descriptor = configuration->descriptor;
@ -48,33 +47,30 @@ const uint8_t* usb_endpoint_descriptor(
} }
uint_fast16_t usb_endpoint_descriptor_max_packet_size( uint_fast16_t usb_endpoint_descriptor_max_packet_size(
const uint8_t* const endpoint_descriptor const uint8_t* const endpoint_descriptor)
) { {
return (endpoint_descriptor[5] << 8) | endpoint_descriptor[4]; return (endpoint_descriptor[5] << 8) | endpoint_descriptor[4];
} }
usb_transfer_type_t usb_endpoint_descriptor_transfer_type( usb_transfer_type_t usb_endpoint_descriptor_transfer_type(
const uint8_t* const endpoint_descriptor const uint8_t* const endpoint_descriptor)
) { {
return (endpoint_descriptor[3] & 0x3); return (endpoint_descriptor[3] & 0x3);
} }
void (*usb_configuration_changed_cb)(usb_device_t* const) = NULL; void (*usb_configuration_changed_cb)(usb_device_t* const) = NULL;
void usb_set_configuration_changed_cb( void usb_set_configuration_changed_cb(void (*callback)(usb_device_t* const))
void (*callback)(usb_device_t* const) {
) {
usb_configuration_changed_cb = callback; usb_configuration_changed_cb = callback;
} }
bool usb_set_configuration( bool usb_set_configuration(
usb_device_t* const device, usb_device_t* const device,
const uint_fast8_t configuration_number const uint_fast8_t configuration_number)
) { {
const usb_configuration_t* new_configuration = 0; const usb_configuration_t* new_configuration = 0;
if (configuration_number != 0) { if (configuration_number != 0) {
// Locate requested configuration. // Locate requested configuration.
if (device->configurations) { if (device->configurations) {
usb_configuration_t** configurations = *(device->configurations); usb_configuration_t** configurations = *(device->configurations);
@ -109,8 +105,8 @@ bool usb_set_configuration(
static usb_request_status_t usb_send_descriptor( static usb_request_status_t usb_send_descriptor(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const uint8_t* const descriptor_data const uint8_t* const descriptor_data)
) { {
const uint32_t setup_length = endpoint->setup.length; const uint32_t setup_length = endpoint->setup.length;
uint32_t descriptor_length = descriptor_data[0]; uint32_t descriptor_length = descriptor_data[0];
if (descriptor_data[1] == USB_DESCRIPTOR_TYPE_CONFIGURATION) { if (descriptor_data[1] == USB_DESCRIPTOR_TYPE_CONFIGURATION) {
@ -121,23 +117,27 @@ static usb_request_status_t usb_send_descriptor(
endpoint->in, endpoint->in,
(uint8_t* const) descriptor_data, (uint8_t* const) descriptor_data,
(setup_length > descriptor_length) ? descriptor_length : setup_length, (setup_length > descriptor_length) ? descriptor_length : setup_length,
NULL, NULL NULL,
); NULL);
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
static usb_request_status_t usb_send_descriptor_string( static usb_request_status_t usb_send_descriptor_string(usb_endpoint_t* const endpoint)
usb_endpoint_t* const endpoint {
) {
if ((endpoint->setup.value_l == 0xee) && if ((endpoint->setup.value_l == 0xee) &&
(endpoint->device->wcid_string_descriptor != NULL)) { /* MS WCID string */ (endpoint->device->wcid_string_descriptor != NULL)) { /* MS WCID string */
return usb_send_descriptor(endpoint, endpoint->device->wcid_string_descriptor); return usb_send_descriptor(
endpoint,
endpoint->device->wcid_string_descriptor);
} else { } else {
uint_fast8_t index = endpoint->setup.value_l; uint_fast8_t index = endpoint->setup.value_l;
for( uint_fast8_t i=0; endpoint->device->descriptor_strings[i] != 0; i++ ) { for (uint_fast8_t i = 0; endpoint->device->descriptor_strings[i] != 0;
i++) {
if (i == index) { if (i == index) {
return usb_send_descriptor(endpoint, endpoint->device->descriptor_strings[i]); return usb_send_descriptor(
endpoint,
endpoint->device->descriptor_strings[i]);
} }
} }
} }
@ -147,14 +147,16 @@ static usb_request_status_t usb_send_descriptor_string(
static usb_request_status_t usb_send_descriptor_config( static usb_request_status_t usb_send_descriptor_config(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
usb_speed_t speed, usb_speed_t speed,
const uint8_t config_num const uint8_t config_num)
) { {
usb_configuration_t** config = *(endpoint->device->configurations); usb_configuration_t** config = *(endpoint->device->configurations);
unsigned int i = 0; unsigned int i = 0;
for (; *config != NULL; config++) { for (; *config != NULL; config++) {
if ((*config)->speed == speed) { if ((*config)->speed == speed) {
if (i == config_num) { if (i == config_num) {
return usb_send_descriptor(endpoint, (*config)->descriptor); return usb_send_descriptor(
endpoint,
(*config)->descriptor);
} else { } else {
i++; i++;
} }
@ -164,8 +166,8 @@ static usb_request_status_t usb_send_descriptor_config(
} }
static usb_request_status_t usb_standard_request_get_descriptor_setup( static usb_request_status_t usb_standard_request_get_descriptor_setup(
usb_endpoint_t* const endpoint usb_endpoint_t* const endpoint)
) { {
switch (endpoint->setup.value_h) { switch (endpoint->setup.value_h) {
case USB_DESCRIPTOR_TYPE_DEVICE: case USB_DESCRIPTOR_TYPE_DEVICE:
return usb_send_descriptor(endpoint, endpoint->device->descriptor); return usb_send_descriptor(endpoint, endpoint->device->descriptor);
@ -173,20 +175,34 @@ static usb_request_status_t usb_standard_request_get_descriptor_setup(
case USB_DESCRIPTOR_TYPE_CONFIGURATION: case USB_DESCRIPTOR_TYPE_CONFIGURATION:
// TODO: Duplicated code. Refactor. // TODO: Duplicated code. Refactor.
if (usb_speed(endpoint->device) == USB_SPEED_HIGH) { if (usb_speed(endpoint->device) == USB_SPEED_HIGH) {
return usb_send_descriptor_config(endpoint, USB_SPEED_HIGH, endpoint->setup.value_l); return usb_send_descriptor_config(
endpoint,
USB_SPEED_HIGH,
endpoint->setup.value_l);
} else { } else {
return usb_send_descriptor_config(endpoint, USB_SPEED_FULL, endpoint->setup.value_l); return usb_send_descriptor_config(
endpoint,
USB_SPEED_FULL,
endpoint->setup.value_l);
} }
case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER: case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
return usb_send_descriptor(endpoint, endpoint->device->qualifier_descriptor); return usb_send_descriptor(
endpoint,
endpoint->device->qualifier_descriptor);
case USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION: case USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION:
// TODO: Duplicated code. Refactor. // TODO: Duplicated code. Refactor.
if (usb_speed(endpoint->device) == USB_SPEED_HIGH) { if (usb_speed(endpoint->device) == USB_SPEED_HIGH) {
return usb_send_descriptor_config(endpoint, USB_SPEED_FULL, endpoint->setup.value_l); return usb_send_descriptor_config(
endpoint,
USB_SPEED_FULL,
endpoint->setup.value_l);
} else { } else {
return usb_send_descriptor_config(endpoint, USB_SPEED_HIGH, endpoint->setup.value_l); return usb_send_descriptor_config(
endpoint,
USB_SPEED_HIGH,
endpoint->setup.value_l);
} }
case USB_DESCRIPTOR_TYPE_STRING: case USB_DESCRIPTOR_TYPE_STRING:
@ -201,8 +217,8 @@ static usb_request_status_t usb_standard_request_get_descriptor_setup(
static usb_request_status_t usb_standard_request_get_descriptor( static usb_request_status_t usb_standard_request_get_descriptor(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
switch (stage) { switch (stage) {
case USB_TRANSFER_STAGE_SETUP: case USB_TRANSFER_STAGE_SETUP:
return usb_standard_request_get_descriptor_setup(endpoint); return usb_standard_request_get_descriptor_setup(endpoint);
@ -218,17 +234,21 @@ static usb_request_status_t usb_standard_request_get_descriptor(
usb_request_status_t usb_vendor_request_read_wcid( usb_request_status_t usb_vendor_request_read_wcid(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
if ((endpoint->setup.index == 0x04) && if ((endpoint->setup.index == 0x04) &&
(endpoint->device->wcid_feature_descriptor != NULL)) { (endpoint->device->wcid_feature_descriptor != NULL)) {
usb_send_descriptor(endpoint, endpoint->device->wcid_feature_descriptor); usb_send_descriptor(
endpoint,
endpoint->device->wcid_feature_descriptor);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
if ((endpoint->setup.index == 0x05) && if ((endpoint->setup.index == 0x05) &&
(endpoint->device->wcid_extended_properties_descriptor != NULL)) { (endpoint->device->wcid_extended_properties_descriptor != NULL)) {
usb_send_descriptor(endpoint, endpoint->device->wcid_extended_properties_descriptor); usb_send_descriptor(
endpoint,
endpoint->device->wcid_extended_properties_descriptor);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
return USB_REQUEST_STATUS_STALL; return USB_REQUEST_STATUS_STALL;
@ -239,8 +259,8 @@ usb_request_status_t usb_vendor_request_read_wcid(
/*********************************************************************/ /*********************************************************************/
static usb_request_status_t usb_standard_request_set_address_setup( static usb_request_status_t usb_standard_request_set_address_setup(
usb_endpoint_t* const endpoint usb_endpoint_t* const endpoint)
) { {
usb_set_address_deferred(endpoint->device, endpoint->setup.value_l); usb_set_address_deferred(endpoint->device, endpoint->setup.value_l);
usb_transfer_schedule_ack(endpoint->in); usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
@ -248,8 +268,8 @@ static usb_request_status_t usb_standard_request_set_address_setup(
static usb_request_status_t usb_standard_request_set_address( static usb_request_status_t usb_standard_request_set_address(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
switch (stage) { switch (stage) {
case USB_TRANSFER_STAGE_SETUP: case USB_TRANSFER_STAGE_SETUP:
return usb_standard_request_set_address_setup(endpoint); return usb_standard_request_set_address_setup(endpoint);
@ -270,8 +290,8 @@ static usb_request_status_t usb_standard_request_set_address(
/*********************************************************************/ /*********************************************************************/
static usb_request_status_t usb_standard_request_set_configuration_setup( static usb_request_status_t usb_standard_request_set_configuration_setup(
usb_endpoint_t* const endpoint usb_endpoint_t* const endpoint)
) { {
const uint8_t usb_configuration = endpoint->setup.value_l; const uint8_t usb_configuration = endpoint->setup.value_l;
if (usb_set_configuration(endpoint->device, usb_configuration)) { if (usb_set_configuration(endpoint->device, usb_configuration)) {
usb_transfer_schedule_ack(endpoint->in); usb_transfer_schedule_ack(endpoint->in);
@ -283,8 +303,8 @@ static usb_request_status_t usb_standard_request_set_configuration_setup(
static usb_request_status_t usb_standard_request_set_configuration( static usb_request_status_t usb_standard_request_set_configuration(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
switch (stage) { switch (stage) {
case USB_TRANSFER_STAGE_SETUP: case USB_TRANSFER_STAGE_SETUP:
return usb_standard_request_set_configuration_setup(endpoint); return usb_standard_request_set_configuration_setup(endpoint);
@ -301,14 +321,19 @@ static usb_request_status_t usb_standard_request_set_configuration(
/*********************************************************************/ /*********************************************************************/
static usb_request_status_t usb_standard_request_get_configuration_setup( static usb_request_status_t usb_standard_request_get_configuration_setup(
usb_endpoint_t* const endpoint usb_endpoint_t* const endpoint)
) { {
if (endpoint->setup.length == 1) { if (endpoint->setup.length == 1) {
endpoint->buffer[0] = 0; endpoint->buffer[0] = 0;
if (endpoint->device->configuration) { if (endpoint->device->configuration) {
endpoint->buffer[0] = endpoint->device->configuration->number; endpoint->buffer[0] = endpoint->device->configuration->number;
} }
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, NULL, NULL); usb_transfer_schedule_block(
endpoint->in,
&endpoint->buffer,
1,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} else { } else {
@ -318,8 +343,8 @@ static usb_request_status_t usb_standard_request_get_configuration_setup(
static usb_request_status_t usb_standard_request_get_configuration( static usb_request_status_t usb_standard_request_get_configuration(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
switch (stage) { switch (stage) {
case USB_TRANSFER_STAGE_SETUP: case USB_TRANSFER_STAGE_SETUP:
return usb_standard_request_get_configuration_setup(endpoint); return usb_standard_request_get_configuration_setup(endpoint);
@ -334,13 +359,18 @@ static usb_request_status_t usb_standard_request_get_configuration(
} }
static usb_request_status_t usb_standard_request_get_status_setup( static usb_request_status_t usb_standard_request_get_status_setup(
usb_endpoint_t* const endpoint usb_endpoint_t* const endpoint)
) { {
if (endpoint->setup.length == 2) { if (endpoint->setup.length == 2) {
endpoint->buffer[0] = 0; endpoint->buffer[0] = 0;
endpoint->buffer[1] = 0; endpoint->buffer[1] = 0;
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2, NULL, NULL); usb_transfer_schedule_block(
endpoint->in,
&endpoint->buffer,
2,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} else { } else {
@ -348,11 +378,10 @@ static usb_request_status_t usb_standard_request_get_status_setup(
} }
} }
static usb_request_status_t usb_standard_request_get_status( static usb_request_status_t usb_standard_request_get_status(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
switch (stage) { switch (stage) {
case USB_TRANSFER_STAGE_SETUP: case USB_TRANSFER_STAGE_SETUP:
return usb_standard_request_get_status_setup(endpoint); return usb_standard_request_get_status_setup(endpoint);
@ -369,12 +398,10 @@ static usb_request_status_t usb_standard_request_get_status(
static usb_request_status_t usb_standard_request_clear_feature_setup( static usb_request_status_t usb_standard_request_clear_feature_setup(
usb_endpoint_t* const endpoint) usb_endpoint_t* const endpoint)
{ {
switch (endpoint->setup.value) { switch (endpoint->setup.value) {
case USB_FEATURE_SELECTOR_ENDPOINT_HALT: case USB_FEATURE_SELECTOR_ENDPOINT_HALT:
usb_endpoint_reset_data_toggle( usb_endpoint_reset_data_toggle(
usb_endpoint_from_address(endpoint->setup.index) usb_endpoint_from_address(endpoint->setup.index));
);
usb_transfer_schedule_ack(endpoint->in); usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
default: default:
@ -403,8 +430,8 @@ static usb_request_status_t usb_standard_request_clear_feature(
usb_request_status_t usb_standard_request( usb_request_status_t usb_standard_request(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
switch (endpoint->setup.request) { switch (endpoint->setup.request) {
case USB_STANDARD_REQUEST_GET_STATUS: case USB_STANDARD_REQUEST_GET_STATUS:
return usb_standard_request_get_status(endpoint, stage); return usb_standard_request_get_status(endpoint, stage);

View File

@ -25,35 +25,26 @@
#include "usb_type.h" #include "usb_type.h"
#include "usb_request.h" #include "usb_request.h"
void usb_set_configuration_changed_cb( void usb_set_configuration_changed_cb(void (*callback)(usb_device_t* const));
void (*callback)(usb_device_t* const)
);
usb_request_status_t usb_vendor_request_read_wcid( usb_request_status_t usb_vendor_request_read_wcid(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage);
);
usb_request_status_t usb_standard_request( usb_request_status_t usb_standard_request(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage);
);
const uint8_t* usb_endpoint_descriptor( const uint8_t* usb_endpoint_descriptor(const usb_endpoint_t* const endpoint);
const usb_endpoint_t* const endpoint
);
uint_fast16_t usb_endpoint_descriptor_max_packet_size( uint_fast16_t usb_endpoint_descriptor_max_packet_size(
const uint8_t* const endpoint_descriptor const uint8_t* const endpoint_descriptor);
);
usb_transfer_type_t usb_endpoint_descriptor_transfer_type( usb_transfer_type_t usb_endpoint_descriptor_transfer_type(
const uint8_t* const endpoint_descriptor const uint8_t* const endpoint_descriptor);
);
bool usb_set_configuration( bool usb_set_configuration(
usb_device_t* const device, usb_device_t* const device,
const uint_fast8_t configuration_number const uint_fast8_t configuration_number);
);
#endif //__USB_STANDARD_REQUEST_H__ #endif //__USB_STANDARD_REQUEST_H__

View File

@ -33,25 +33,31 @@
typedef struct ATTR_PACKED { typedef struct ATTR_PACKED {
uint8_t request_type; uint8_t request_type;
uint8_t request; uint8_t request;
union { union {
struct { struct {
uint8_t value_l; uint8_t value_l;
uint8_t value_h; uint8_t value_h;
}; };
uint16_t value; uint16_t value;
}; };
union { union {
struct { struct {
uint8_t index_l; uint8_t index_l;
uint8_t index_h; uint8_t index_h;
}; };
uint16_t index; uint16_t index;
}; };
union { union {
struct { struct {
uint8_t length_l; uint8_t length_l;
uint8_t length_h; uint8_t length_h;
}; };
uint16_t length; uint16_t length;
}; };
} usb_setup_t; } usb_setup_t;
@ -84,9 +90,12 @@ typedef enum {
USB_SETUP_REQUEST_TYPE_RESERVED = 3 << USB_SETUP_REQUEST_TYPE_shift, USB_SETUP_REQUEST_TYPE_RESERVED = 3 << USB_SETUP_REQUEST_TYPE_shift,
USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift = 7, USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift = 7,
USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_mask = 1 << USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift, USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_mask =
USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_HOST_TO_DEVICE = 0 << USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift, 1 << USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift,
USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_DEVICE_TO_HOST = 1 << USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift, USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_HOST_TO_DEVICE =
0 << USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift,
USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_DEVICE_TO_HOST =
1 << USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift,
} usb_setup_request_type_t; } usb_setup_request_type_t;
typedef enum { typedef enum {
@ -137,6 +146,7 @@ typedef struct {
} usb_device_t; } usb_device_t;
typedef struct usb_endpoint_t usb_endpoint_t; typedef struct usb_endpoint_t usb_endpoint_t;
struct usb_endpoint_t { struct usb_endpoint_t {
usb_setup_t setup; usb_setup_t setup;
uint8_t buffer[8]; // Buffer for use during IN stage. uint8_t buffer[8]; // Buffer for use during IN stage.

View File

@ -80,10 +80,7 @@ uint8_t w25q80bv_get_status(w25q80bv_driver_t* const drv)
/* Release power down / Device ID */ /* Release power down / Device ID */
uint8_t w25q80bv_get_device_id(w25q80bv_driver_t* const drv) uint8_t w25q80bv_get_device_id(w25q80bv_driver_t* const drv)
{ {
uint8_t data[] = { uint8_t data[] = {W25Q80BV_DEVICE_ID, 0xFF, 0xFF, 0xFF, 0xFF};
W25Q80BV_DEVICE_ID,
0xFF, 0xFF, 0xFF, 0xFF
};
spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data)); spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data));
return data[4]; return data[4];
} }
@ -92,9 +89,18 @@ void w25q80bv_get_unique_id(w25q80bv_driver_t* const drv, w25q80bv_unique_id_t*
{ {
uint8_t data[] = { uint8_t data[] = {
W25Q80BV_UNIQUE_ID, W25Q80BV_UNIQUE_ID,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 0xFF,
}; 0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF};
spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data)); spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data));
for (size_t i = 0; i < 8; i++) { for (size_t i = 0; i < 8; i++) {
@ -133,7 +139,11 @@ void w25q80bv_chip_erase(w25q80bv_driver_t* const drv)
} }
/* write up a 256 byte page or partial page */ /* write up a 256 byte page or partial page */
static void w25q80bv_page_program(w25q80bv_driver_t* const drv, const uint32_t addr, const uint16_t len, uint8_t* data) static void w25q80bv_page_program(
w25q80bv_driver_t* const drv,
const uint32_t addr,
const uint16_t len,
uint8_t* data)
{ {
/* do nothing if asked to write beyond a page boundary */ /* do nothing if asked to write beyond a page boundary */
if (((addr & 0xFF) + len) > drv->page_len) if (((addr & 0xFF) + len) > drv->page_len)
@ -150,19 +160,19 @@ static void w25q80bv_page_program(w25q80bv_driver_t* const drv, const uint32_t a
W25Q80BV_PAGE_PROGRAM, W25Q80BV_PAGE_PROGRAM,
(addr & 0xFF0000) >> 16, (addr & 0xFF0000) >> 16,
(addr & 0xFF00) >> 8, (addr & 0xFF00) >> 8,
addr & 0xFF addr & 0xFF};
};
const spi_transfer_t transfers[] = { const spi_transfer_t transfers[] = {{header, ARRAY_SIZE(header)}, {data, len}};
{ header, ARRAY_SIZE(header) },
{ data, len }
};
spi_bus_transfer_gather(drv->bus, transfers, ARRAY_SIZE(transfers)); spi_bus_transfer_gather(drv->bus, transfers, ARRAY_SIZE(transfers));
} }
/* write an arbitrary number of bytes */ /* write an arbitrary number of bytes */
void w25q80bv_program(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len, uint8_t* data) void w25q80bv_program(
w25q80bv_driver_t* const drv,
uint32_t addr,
uint32_t len,
uint8_t* data)
{ {
uint16_t first_block_len; uint16_t first_block_len;
uint8_t device_id; uint8_t device_id;
@ -173,8 +183,8 @@ void w25q80bv_program(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len,
device_id != W25Q16DV_DEVICE_ID_RES); device_id != W25Q16DV_DEVICE_ID_RES);
/* do nothing if we would overflow the flash */ /* do nothing if we would overflow the flash */
if ((len > drv->num_bytes) || (addr > drv->num_bytes) if ((len > drv->num_bytes) || (addr > drv->num_bytes) ||
|| ((addr + len) > drv->num_bytes)) ((addr + len) > drv->num_bytes))
return; return;
/* handle start not at page boundary */ /* handle start not at page boundary */
@ -203,11 +213,15 @@ void w25q80bv_program(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len,
} }
/* write an arbitrary number of bytes */ /* write an arbitrary number of bytes */
void w25q80bv_read(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len, uint8_t* const data) void w25q80bv_read(
w25q80bv_driver_t* const drv,
uint32_t addr,
uint32_t len,
uint8_t* const data)
{ {
/* do nothing if we would overflow the flash */ /* do nothing if we would overflow the flash */
if ((len > drv->num_bytes) || (addr > drv->num_bytes) if ((len > drv->num_bytes) || (addr > drv->num_bytes) ||
|| ((addr + len) > drv->num_bytes)) ((addr + len) > drv->num_bytes))
return; return;
w25q80bv_wait_while_busy(drv); w25q80bv_wait_while_busy(drv);
@ -217,13 +231,9 @@ void w25q80bv_read(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len, ui
(addr & 0xFF0000) >> 16, (addr & 0xFF0000) >> 16,
(addr & 0xFF00) >> 8, (addr & 0xFF00) >> 8,
addr & 0xFF, addr & 0xFF,
0x00 0x00};
};
const spi_transfer_t transfers[] = { const spi_transfer_t transfers[] = {{header, ARRAY_SIZE(header)}, {data, len}};
{ header, ARRAY_SIZE(header) },
{ data, len }
};
spi_bus_transfer_gather(drv->bus, transfers, ARRAY_SIZE(transfers)); spi_bus_transfer_gather(drv->bus, transfers, ARRAY_SIZE(transfers));
} }

View File

@ -32,8 +32,7 @@
#include "spi_bus.h" #include "spi_bus.h"
#include "gpio.h" #include "gpio.h"
typedef union typedef union {
{
uint64_t id_64b; uint64_t id_64b;
uint32_t id_32b[2]; /* 2*32bits 64bits Unique ID */ uint32_t id_32b[2]; /* 2*32bits 64bits Unique ID */
uint8_t id_8b[8]; /* 8*8bits 64bits Unique ID */ uint8_t id_8b[8]; /* 8*8bits 64bits Unique ID */
@ -55,10 +54,18 @@ struct w25q80bv_driver_t {
void w25q80bv_setup(w25q80bv_driver_t* const drv); void w25q80bv_setup(w25q80bv_driver_t* const drv);
void w25q80bv_get_full_status(w25q80bv_driver_t* const drv, uint8_t* data); void w25q80bv_get_full_status(w25q80bv_driver_t* const drv, uint8_t* data);
void w25q80bv_chip_erase(w25q80bv_driver_t* const drv); void w25q80bv_chip_erase(w25q80bv_driver_t* const drv);
void w25q80bv_program(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len, uint8_t* data); void w25q80bv_program(
w25q80bv_driver_t* const drv,
uint32_t addr,
uint32_t len,
uint8_t* data);
uint8_t w25q80bv_get_device_id(w25q80bv_driver_t* const drv); uint8_t w25q80bv_get_device_id(w25q80bv_driver_t* const drv);
void w25q80bv_get_unique_id(w25q80bv_driver_t* const drv, w25q80bv_unique_id_t* unique_id); void w25q80bv_get_unique_id(w25q80bv_driver_t* const drv, w25q80bv_unique_id_t* unique_id);
void w25q80bv_read(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len, uint8_t* const data); void w25q80bv_read(
w25q80bv_driver_t* const drv,
uint32_t addr,
uint32_t len,
uint8_t* const data);
void w25q80bv_clear_status(w25q80bv_driver_t* const drv); void w25q80bv_clear_status(w25q80bv_driver_t* const drv);
#endif //__W25Q80BV_H__ #endif //__W25Q80BV_H__

View File

@ -28,7 +28,8 @@
* automatically? * automatically?
*/ */
void w25q80bv_target_init(w25q80bv_driver_t* const drv) { void w25q80bv_target_init(w25q80bv_driver_t* const drv)
{
(void) drv; (void) drv;
/* Init SPIFI GPIO to Normal GPIO */ /* Init SPIFI GPIO to Normal GPIO */

View File

@ -125,12 +125,13 @@ static const uint32_t vendor_request_handler_count =
usb_request_status_t usb_vendor_request( usb_request_status_t usb_vendor_request(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
usb_request_status_t status = USB_REQUEST_STATUS_STALL; usb_request_status_t status = USB_REQUEST_STATUS_STALL;
if (endpoint->setup.request < vendor_request_handler_count) { if (endpoint->setup.request < vendor_request_handler_count) {
usb_request_handler_fn handler = vendor_request_handler[endpoint->setup.request]; usb_request_handler_fn handler =
vendor_request_handler[endpoint->setup.request];
if (handler) { if (handler) {
status = handler(endpoint, stage); status = handler(endpoint, stage);
} }
@ -146,9 +147,8 @@ const usb_request_handlers_t usb_request_handlers = {
.reserved = 0, .reserved = 0,
}; };
void usb_configuration_changed( void usb_configuration_changed(usb_device_t* const device)
usb_device_t* const device {
) {
/* Reset transceiver to idle state until other commands are received */ /* Reset transceiver to idle state until other commands are received */
request_transceiver_mode(TRANSCEIVER_MODE_OFF); request_transceiver_mode(TRANSCEIVER_MODE_OFF);
if (device->configuration->number == 1) { if (device->configuration->number == 1) {
@ -171,13 +171,18 @@ void usb_set_descriptor_by_serial_number(void)
iap_cmd_call(&iap_cmd_res); iap_cmd_call(&iap_cmd_res);
if (iap_cmd_res.status_res.status_ret == CMD_SUCCESS) { if (iap_cmd_res.status_res.status_ret == CMD_SUCCESS) {
usb_descriptor_string_serial_number[0] = USB_DESCRIPTOR_STRING_SERIAL_BUF_LEN; usb_descriptor_string_serial_number[0] =
USB_DESCRIPTOR_STRING_SERIAL_BUF_LEN;
usb_descriptor_string_serial_number[1] = USB_DESCRIPTOR_TYPE_STRING; usb_descriptor_string_serial_number[1] = USB_DESCRIPTOR_TYPE_STRING;
/* 32 characters of serial number, convert to UTF-16LE */ /* 32 characters of serial number, convert to UTF-16LE */
for (size_t i = 0; i < USB_DESCRIPTOR_STRING_SERIAL_LEN; i++) { for (size_t i = 0; i < USB_DESCRIPTOR_STRING_SERIAL_LEN; i++) {
const uint_fast8_t nibble = (iap_cmd_res.status_res.iap_result[i >> 3] >> (28 - (i & 7) * 4)) & 0xf; const uint_fast8_t nibble =
const char c = (nibble > 9) ? ('a' + nibble - 10) : ('0' + nibble); (iap_cmd_res.status_res.iap_result[i >> 3] >>
(28 - (i & 7) * 4)) &
0xf;
const char c =
(nibble > 9) ? ('a' + nibble - 10) : ('0' + nibble);
usb_descriptor_string_serial_number[2 + i * 2] = c; usb_descriptor_string_serial_number[2 + i * 2] = c;
usb_descriptor_string_serial_number[3 + i * 2] = 0x00; usb_descriptor_string_serial_number[3 + i * 2] = 0x00;
} }
@ -187,15 +192,20 @@ void usb_set_descriptor_by_serial_number(void)
} }
} }
static bool cpld_jtag_sram_load(jtag_t* const jtag) { static bool cpld_jtag_sram_load(jtag_t* const jtag)
{
cpld_jtag_take(jtag); cpld_jtag_take(jtag);
cpld_xc2c64a_jtag_sram_write(jtag, &cpld_hackrf_program_sram); cpld_xc2c64a_jtag_sram_write(jtag, &cpld_hackrf_program_sram);
const bool success = cpld_xc2c64a_jtag_sram_verify(jtag, &cpld_hackrf_program_sram, &cpld_hackrf_verify); const bool success = cpld_xc2c64a_jtag_sram_verify(
jtag,
&cpld_hackrf_program_sram,
&cpld_hackrf_verify);
cpld_jtag_release(jtag); cpld_jtag_release(jtag);
return success; return success;
} }
static void m0_rom_to_ram() { static void m0_rom_to_ram()
{
uint32_t* dest = &__ram_m0_start__; uint32_t* dest = &__ram_m0_start__;
// Calculate the base address of ROM // Calculate the base address of ROM
@ -208,7 +218,8 @@ static void m0_rom_to_ram() {
memcpy(dest, (uint32_t*) (base + src), len); memcpy(dest, (uint32_t*) (base + src), len);
} }
int main(void) { int main(void)
{
// Copy M0 image from ROM before SPIFI is disabled // Copy M0 image from ROM before SPIFI is disabled
m0_rom_to_ram(); m0_rom_to_ram();

View File

@ -33,38 +33,51 @@
char version_string[] = VERSION_STRING; char version_string[] = VERSION_STRING;
usb_request_status_t usb_vendor_request_read_board_id( usb_request_status_t usb_vendor_request_read_board_id(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
endpoint->buffer[0] = BOARD_ID; endpoint->buffer[0] = BOARD_ID;
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, NULL, NULL); usb_transfer_schedule_block(
endpoint->in,
&endpoint->buffer,
1,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
} }
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
usb_request_status_t usb_vendor_request_read_version_string( usb_request_status_t usb_vendor_request_read_version_string(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
uint8_t length; uint8_t length;
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
length = (uint8_t) strlen(version_string); length = (uint8_t) strlen(version_string);
usb_transfer_schedule_block(endpoint->in, version_string, length, NULL, NULL); usb_transfer_schedule_block(
endpoint->in,
version_string,
length,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
} }
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
static read_partid_serialno_t read_partid_serialno; static read_partid_serialno_t read_partid_serialno;
usb_request_status_t usb_vendor_request_read_partid_serialno( usb_request_status_t usb_vendor_request_read_partid_serialno(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
uint8_t length; uint8_t length;
iap_cmd_res_t iap_cmd_res; iap_cmd_res_t iap_cmd_res;
if (stage == USB_TRANSFER_STAGE_SETUP) if (stage == USB_TRANSFER_STAGE_SETUP) {
{
/* Read IAP Part Number Identification */ /* Read IAP Part Number Identification */
iap_cmd_res.cmd_param.command_code = IAP_CMD_READ_PART_ID_NO; iap_cmd_res.cmd_param.command_code = IAP_CMD_READ_PART_ID_NO;
iap_cmd_call(&iap_cmd_res); iap_cmd_call(&iap_cmd_res);
@ -86,15 +99,20 @@ usb_request_status_t usb_vendor_request_read_partid_serialno(
read_partid_serialno.serial_no[3] = iap_cmd_res.status_res.iap_result[3]; read_partid_serialno.serial_no[3] = iap_cmd_res.status_res.iap_result[3];
length = (uint8_t) sizeof(read_partid_serialno_t); length = (uint8_t) sizeof(read_partid_serialno_t);
usb_transfer_schedule_block(endpoint->in, &read_partid_serialno, length, usb_transfer_schedule_block(
NULL, NULL); endpoint->in,
&read_partid_serialno,
length,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
} }
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
usb_request_status_t usb_vendor_request_reset( usb_request_status_t usb_vendor_request_reset(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
wwdt_reset(100000); wwdt_reset(100000);

View File

@ -34,12 +34,16 @@ typedef struct {
} read_partid_serialno_t; } read_partid_serialno_t;
usb_request_status_t usb_vendor_request_read_board_id( usb_request_status_t usb_vendor_request_read_board_id(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_read_version_string( usb_request_status_t usb_vendor_request_read_version_string(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_read_partid_serialno( usb_request_status_t usb_vendor_request_read_partid_serialno(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_reset( usb_request_status_t usb_vendor_request_reset(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
#endif /* end of include guard: __USB_API_BOARD_INFO_H__ */ #endif /* end of include guard: __USB_API_BOARD_INFO_H__ */

View File

@ -52,8 +52,7 @@ static void refill_cpld_buffer(void)
cpld_xsvf_buffer, cpld_xsvf_buffer,
sizeof(cpld_xsvf_buffer), sizeof(cpld_xsvf_buffer),
cpld_buffer_refilled, cpld_buffer_refilled,
NULL NULL);
);
// Wait until transfer finishes // Wait until transfer finishes
while (cpld_wait) {} while (cpld_wait) {}
@ -68,14 +67,14 @@ void cpld_update(void)
refill_cpld_buffer(); refill_cpld_buffer();
error = cpld_jtag_program(&jtag_cpld, sizeof(cpld_xsvf_buffer), error = cpld_jtag_program(
&jtag_cpld,
sizeof(cpld_xsvf_buffer),
cpld_xsvf_buffer, cpld_xsvf_buffer,
refill_cpld_buffer); refill_cpld_buffer);
if(error == 0) if (error == 0) {
{
halt_and_flash(6000000); halt_and_flash(6000000);
}else } else {
{
/* LED3 (Red) steady on error */ /* LED3 (Red) steady on error */
led_on(LED3); led_on(LED3);
while (1) {} while (1) {}
@ -83,15 +82,18 @@ void cpld_update(void)
} }
usb_request_status_t usb_vendor_request_cpld_checksum( usb_request_status_t usb_vendor_request_cpld_checksum(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
static uint32_t cpld_crc; static uint32_t cpld_crc;
uint8_t length; uint8_t length;
if (stage == USB_TRANSFER_STAGE_SETUP) if (stage == USB_TRANSFER_STAGE_SETUP) {
{
cpld_jtag_take(&jtag_cpld); cpld_jtag_take(&jtag_cpld);
const bool checksum_success = cpld_xc2c64a_jtag_checksum(&jtag_cpld, &cpld_hackrf_verify, &cpld_crc); const bool checksum_success = cpld_xc2c64a_jtag_checksum(
&jtag_cpld,
&cpld_hackrf_verify,
&cpld_crc);
cpld_jtag_release(&jtag_cpld); cpld_jtag_release(&jtag_cpld);
if (!checksum_success) { if (!checksum_success) {
@ -100,8 +102,12 @@ usb_request_status_t usb_vendor_request_cpld_checksum(
length = (uint8_t) sizeof(cpld_crc); length = (uint8_t) sizeof(cpld_crc);
memcpy(endpoint->buffer, &cpld_crc, length); memcpy(endpoint->buffer, &cpld_crc, length);
usb_transfer_schedule_block(endpoint->in, endpoint->buffer, length, usb_transfer_schedule_block(
NULL, NULL); endpoint->in,
endpoint->buffer,
length,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
} }
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;

View File

@ -31,6 +31,7 @@
void cpld_update(void); void cpld_update(void);
usb_request_status_t usb_vendor_request_cpld_checksum( usb_request_status_t usb_vendor_request_cpld_checksum(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
#endif /* end of include guard: __USB_API_CPLD_H__ */ #endif /* end of include guard: __USB_API_CPLD_H__ */

View File

@ -43,15 +43,15 @@ void m0_set_mode(enum m0_mode mode)
usb_request_status_t usb_vendor_request_get_m0_state( usb_request_status_t usb_vendor_request_get_m0_state(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) {
if( stage == USB_TRANSFER_STAGE_SETUP )
{ {
if (stage == USB_TRANSFER_STAGE_SETUP) {
usb_transfer_schedule_block( usb_transfer_schedule_block(
endpoint->in, endpoint->in,
(void*) &m0_state, (void*) &m0_state,
sizeof(m0_state), sizeof(m0_state),
NULL, NULL); NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} else { } else {

View File

@ -63,6 +63,7 @@ extern volatile struct m0_state m0_state;
void m0_set_mode(enum m0_mode mode); void m0_set_mode(enum m0_mode mode);
usb_request_status_t usb_vendor_request_get_m0_state( usb_request_status_t usb_vendor_request_get_m0_state(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
#endif /*__M0_STATE_H__*/ #endif /*__M0_STATE_H__*/

View File

@ -28,7 +28,8 @@
#include <sct.h> #include <sct.h>
usb_request_status_t usb_vendor_request_operacake_get_boards( usb_request_status_t usb_vendor_request_operacake_get_boards(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
operacake_get_boards(endpoint->buffer); operacake_get_boards(endpoint->buffer);
@ -39,7 +40,8 @@ usb_request_status_t usb_vendor_request_operacake_get_boards(
} }
usb_request_status_t usb_vendor_request_operacake_set_ports( usb_request_status_t usb_vendor_request_operacake_set_ports(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
uint8_t address, port_a, port_b; uint8_t address, port_a, port_b;
address = endpoint->setup.value & 0xFF; address = endpoint->setup.value & 0xFF;
@ -53,8 +55,10 @@ usb_request_status_t usb_vendor_request_operacake_set_ports(
} }
static unsigned char data[MAX_OPERACAKE_RANGES * 5]; static unsigned char data[MAX_OPERACAKE_RANGES * 5];
usb_request_status_t usb_vendor_request_operacake_set_ranges( usb_request_status_t usb_vendor_request_operacake_set_ranges(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
uint16_t i, freq_min, freq_max, num_ranges = 0; uint16_t i, freq_min, freq_max, num_ranges = 0;
uint8_t port; uint8_t port;
@ -65,10 +69,13 @@ usb_request_status_t usb_vendor_request_operacake_set_ranges(
return USB_REQUEST_STATUS_STALL; return USB_REQUEST_STATUS_STALL;
} }
operacake_clear_ranges(); operacake_clear_ranges();
usb_transfer_schedule_block(endpoint->out, &data, usb_transfer_schedule_block(
endpoint->setup.length, NULL, NULL); endpoint->out,
&data,
endpoint->setup.length,
NULL,
NULL);
} else if (stage == USB_TRANSFER_STAGE_DATA) { } else if (stage == USB_TRANSFER_STAGE_DATA) {
for (i = 0; i < endpoint->setup.length; i += 5) { for (i = 0; i < endpoint->setup.length; i += 5) {
freq_min = data[i] << 8 | data[i + 1]; freq_min = data[i] << 8 | data[i + 1];
freq_max = data[i + 2] << 8 | data[i + 3]; freq_max = data[i + 2] << 8 | data[i + 3];
@ -81,7 +88,8 @@ usb_request_status_t usb_vendor_request_operacake_set_ranges(
} }
usb_request_status_t usb_vendor_request_operacake_gpio_test( usb_request_status_t usb_vendor_request_operacake_gpio_test(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
uint16_t test_result; uint16_t test_result;
uint8_t address = endpoint->setup.value & 0xFF; uint8_t address = endpoint->setup.value & 0xFF;
@ -89,14 +97,20 @@ usb_request_status_t usb_vendor_request_operacake_gpio_test(
test_result = gpio_test(address); test_result = gpio_test(address);
endpoint->buffer[0] = test_result & 0xff; endpoint->buffer[0] = test_result & 0xff;
endpoint->buffer[1] = test_result >> 8; endpoint->buffer[1] = test_result >> 8;
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2, NULL, NULL); usb_transfer_schedule_block(
endpoint->in,
&endpoint->buffer,
2,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
} }
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
usb_request_status_t usb_vendor_request_operacake_set_mode( usb_request_status_t usb_vendor_request_operacake_set_mode(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
uint8_t address, mode; uint8_t address, mode;
address = endpoint->setup.value & 0xFF; address = endpoint->setup.value & 0xFF;
@ -109,7 +123,8 @@ usb_request_status_t usb_vendor_request_operacake_set_mode(
} }
usb_request_status_t usb_vendor_request_operacake_get_mode( usb_request_status_t usb_vendor_request_operacake_get_mode(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
uint8_t address; uint8_t address;
address = endpoint->setup.value & 0xFF; address = endpoint->setup.value & 0xFF;
@ -122,8 +137,10 @@ usb_request_status_t usb_vendor_request_operacake_get_mode(
} }
static struct operacake_dwell_times dwell_times[SCT_EVENT_COUNT]; static struct operacake_dwell_times dwell_times[SCT_EVENT_COUNT];
usb_request_status_t usb_vendor_request_operacake_set_dwell_times( usb_request_status_t usb_vendor_request_operacake_set_dwell_times(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
uint16_t count; uint16_t count;
uint32_t dwell; uint32_t dwell;
@ -134,13 +151,18 @@ usb_request_status_t usb_vendor_request_operacake_set_dwell_times(
if ((count == 0) || (count > SCT_EVENT_COUNT)) { if ((count == 0) || (count > SCT_EVENT_COUNT)) {
return USB_REQUEST_STATUS_STALL; return USB_REQUEST_STATUS_STALL;
} }
usb_transfer_schedule_block(endpoint->out, &data, usb_transfer_schedule_block(
endpoint->setup.length, NULL, NULL); endpoint->out,
&data,
endpoint->setup.length,
NULL,
NULL);
} else if (stage == USB_TRANSFER_STAGE_DATA) { } else if (stage == USB_TRANSFER_STAGE_DATA) {
count = endpoint->setup.length / 5; count = endpoint->setup.length / 5;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
dwell = data[(i*5)+0] | (data[(i*5)+1] << 8) | (data[(i*5)+2] << 16) | (data[(i*5)+3] << 24); dwell = data[(i * 5) + 0] | (data[(i * 5) + 1] << 8) |
(data[(i * 5) + 2] << 16) | (data[(i * 5) + 3] << 24);
port = data[(i * 5) + 4]; port = data[(i * 5) + 4];
dwell_times[i].dwell = dwell; dwell_times[i].dwell = dwell;
dwell_times[i].port = port; dwell_times[i].port = port;

View File

@ -26,24 +26,31 @@
#include <usb_request.h> #include <usb_request.h>
usb_request_status_t usb_vendor_request_operacake_get_boards( usb_request_status_t usb_vendor_request_operacake_get_boards(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_operacake_set_ports( usb_request_status_t usb_vendor_request_operacake_set_ports(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_operacake_set_ranges( usb_request_status_t usb_vendor_request_operacake_set_ranges(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_operacake_gpio_test( usb_request_status_t usb_vendor_request_operacake_gpio_test(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_operacake_set_mode( usb_request_status_t usb_vendor_request_operacake_set_mode(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_operacake_get_mode( usb_request_status_t usb_vendor_request_operacake_get_mode(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_operacake_set_dwell_times( usb_request_status_t usb_vendor_request_operacake_set_dwell_times(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
#endif /* end of include guard: __USB_API_OPERACAKE_H__ */ #endif /* end of include guard: __USB_API_OPERACAKE_H__ */

View File

@ -34,12 +34,15 @@
usb_request_status_t usb_vendor_request_write_max2837( usb_request_status_t usb_vendor_request_write_max2837(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
if (endpoint->setup.index < MAX2837_NUM_REGS) { if (endpoint->setup.index < MAX2837_NUM_REGS) {
if (endpoint->setup.value < MAX2837_DATA_REGS_MAX_VALUE) { if (endpoint->setup.value < MAX2837_DATA_REGS_MAX_VALUE) {
max2837_reg_write(&max2837, endpoint->setup.index, endpoint->setup.value); max2837_reg_write(
&max2837,
endpoint->setup.index,
endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in); usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
@ -52,15 +55,20 @@ usb_request_status_t usb_vendor_request_write_max2837(
usb_request_status_t usb_vendor_request_read_max2837( usb_request_status_t usb_vendor_request_read_max2837(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
if (endpoint->setup.index < MAX2837_NUM_REGS) { if (endpoint->setup.index < MAX2837_NUM_REGS) {
const uint16_t value = max2837_reg_read(&max2837, endpoint->setup.index); const uint16_t value =
max2837_reg_read(&max2837, endpoint->setup.index);
endpoint->buffer[0] = value & 0xff; endpoint->buffer[0] = value & 0xff;
endpoint->buffer[1] = value >> 8; endpoint->buffer[1] = value >> 8;
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2, usb_transfer_schedule_block(
NULL, NULL); endpoint->in,
&endpoint->buffer,
2,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
@ -72,12 +80,15 @@ usb_request_status_t usb_vendor_request_read_max2837(
usb_request_status_t usb_vendor_request_write_si5351c( usb_request_status_t usb_vendor_request_write_si5351c(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
if (endpoint->setup.index < 256) { if (endpoint->setup.index < 256) {
if (endpoint->setup.value < 256) { if (endpoint->setup.value < 256) {
si5351c_write_single(&clock_gen, endpoint->setup.index, endpoint->setup.value); si5351c_write_single(
&clock_gen,
endpoint->setup.index,
endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in); usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
@ -90,14 +101,19 @@ usb_request_status_t usb_vendor_request_write_si5351c(
usb_request_status_t usb_vendor_request_read_si5351c( usb_request_status_t usb_vendor_request_read_si5351c(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
if (endpoint->setup.index < 256) { if (endpoint->setup.index < 256) {
const uint8_t value = si5351c_read_single(&clock_gen, endpoint->setup.index); const uint8_t value =
si5351c_read_single(&clock_gen, endpoint->setup.index);
endpoint->buffer[0] = value; endpoint->buffer[0] = value;
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, usb_transfer_schedule_block(
NULL, NULL); endpoint->in,
&endpoint->buffer,
1,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
@ -110,13 +126,14 @@ usb_request_status_t usb_vendor_request_read_si5351c(
#ifndef RAD1O #ifndef RAD1O
usb_request_status_t usb_vendor_request_write_rffc5071( usb_request_status_t usb_vendor_request_write_rffc5071(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) {
if( stage == USB_TRANSFER_STAGE_SETUP )
{ {
if( endpoint->setup.index < RFFC5071_NUM_REGS ) if (stage == USB_TRANSFER_STAGE_SETUP) {
{ if (endpoint->setup.index < RFFC5071_NUM_REGS) {
rffc5071_reg_write(&mixer, endpoint->setup.index, endpoint->setup.value); rffc5071_reg_write(
&mixer,
endpoint->setup.index,
endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in); usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
@ -128,18 +145,20 @@ usb_request_status_t usb_vendor_request_write_rffc5071(
usb_request_status_t usb_vendor_request_read_rffc5071( usb_request_status_t usb_vendor_request_read_rffc5071(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
uint16_t value; uint16_t value;
if( stage == USB_TRANSFER_STAGE_SETUP ) if (stage == USB_TRANSFER_STAGE_SETUP) {
{ if (endpoint->setup.index < RFFC5071_NUM_REGS) {
if( endpoint->setup.index < RFFC5071_NUM_REGS )
{
value = rffc5071_reg_read(&mixer, endpoint->setup.index); value = rffc5071_reg_read(&mixer, endpoint->setup.index);
endpoint->buffer[0] = value & 0xff; endpoint->buffer[0] = value & 0xff;
endpoint->buffer[1] = value >> 8; endpoint->buffer[1] = value >> 8;
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2, usb_transfer_schedule_block(
NULL, NULL); endpoint->in,
&endpoint->buffer,
2,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
@ -152,8 +171,8 @@ usb_request_status_t usb_vendor_request_read_rffc5071(
usb_request_status_t usb_vendor_request_set_clkout_enable( usb_request_status_t usb_vendor_request_set_clkout_enable(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
si5351c_clkout_enable(&clock_gen, endpoint->setup.value); si5351c_clkout_enable(&clock_gen, endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in); usb_transfer_schedule_ack(endpoint->in);

View File

@ -28,31 +28,24 @@
usb_request_status_t usb_vendor_request_write_max2837( usb_request_status_t usb_vendor_request_write_max2837(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage);
);
usb_request_status_t usb_vendor_request_read_max2837( usb_request_status_t usb_vendor_request_read_max2837(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage);
);
usb_request_status_t usb_vendor_request_write_si5351c( usb_request_status_t usb_vendor_request_write_si5351c(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage);
);
usb_request_status_t usb_vendor_request_read_si5351c( usb_request_status_t usb_vendor_request_read_si5351c(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage);
);
usb_request_status_t usb_vendor_request_write_rffc5071( usb_request_status_t usb_vendor_request_write_rffc5071(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage);
);
usb_request_status_t usb_vendor_request_read_rffc5071( usb_request_status_t usb_vendor_request_read_rffc5071(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage);
);
usb_request_status_t usb_vendor_request_set_clkout_enable( usb_request_status_t usb_vendor_request_set_clkout_enable(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage);
);
#endif /* end of include guard: __USB_API_REGISTER_H__ */ #endif /* end of include guard: __USB_API_REGISTER_H__ */

View File

@ -34,7 +34,8 @@
uint8_t spiflash_buffer[256U]; uint8_t spiflash_buffer[256U];
usb_request_status_t usb_vendor_request_erase_spiflash( usb_request_status_t usb_vendor_request_erase_spiflash(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
spi_bus_start(spi_flash.bus, &ssp_config_w25q80bv); spi_bus_start(spi_flash.bus, &ssp_config_w25q80bv);
@ -47,7 +48,8 @@ usb_request_status_t usb_vendor_request_erase_spiflash(
} }
usb_request_status_t usb_vendor_request_write_spiflash( usb_request_status_t usb_vendor_request_write_spiflash(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
uint32_t addr = 0; uint32_t addr = 0;
uint16_t len = 0; uint16_t len = 0;
@ -55,12 +57,16 @@ usb_request_status_t usb_vendor_request_write_spiflash(
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
addr = (endpoint->setup.value << 16) | endpoint->setup.index; addr = (endpoint->setup.value << 16) | endpoint->setup.index;
len = endpoint->setup.length; len = endpoint->setup.length;
if ((len > spi_flash.page_len) || (addr > spi_flash.num_bytes) if ((len > spi_flash.page_len) || (addr > spi_flash.num_bytes) ||
|| ((addr + len) > spi_flash.num_bytes)) { ((addr + len) > spi_flash.num_bytes)) {
return USB_REQUEST_STATUS_STALL; return USB_REQUEST_STATUS_STALL;
} else { } else {
usb_transfer_schedule_block(endpoint->out, &spiflash_buffer[0], len, usb_transfer_schedule_block(
NULL, NULL); endpoint->out,
&spiflash_buffer[0],
len,
NULL,
NULL);
spi_bus_start(spi_flash.bus, &ssp_config_w25q80bv); spi_bus_start(spi_flash.bus, &ssp_config_w25q80bv);
w25q80bv_setup(&spi_flash); w25q80bv_setup(&spi_flash);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
@ -69,8 +75,8 @@ usb_request_status_t usb_vendor_request_write_spiflash(
addr = (endpoint->setup.value << 16) | endpoint->setup.index; addr = (endpoint->setup.value << 16) | endpoint->setup.index;
len = endpoint->setup.length; len = endpoint->setup.length;
/* This check is redundant but makes me feel better. */ /* This check is redundant but makes me feel better. */
if ((len > spi_flash.page_len) || (addr > spi_flash.num_bytes) if ((len > spi_flash.page_len) || (addr > spi_flash.num_bytes) ||
|| ((addr + len) > spi_flash.num_bytes)) { ((addr + len) > spi_flash.num_bytes)) {
return USB_REQUEST_STATUS_STALL; return USB_REQUEST_STATUS_STALL;
} else { } else {
w25q80bv_program(&spi_flash, addr, len, &spiflash_buffer[0]); w25q80bv_program(&spi_flash, addr, len, &spiflash_buffer[0]);
@ -83,50 +89,56 @@ usb_request_status_t usb_vendor_request_write_spiflash(
} }
usb_request_status_t usb_vendor_request_read_spiflash( usb_request_status_t usb_vendor_request_read_spiflash(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
uint32_t addr; uint32_t addr;
uint16_t len; uint16_t len;
if (stage == USB_TRANSFER_STAGE_SETUP) if (stage == USB_TRANSFER_STAGE_SETUP) {
{
addr = (endpoint->setup.value << 16) | endpoint->setup.index; addr = (endpoint->setup.value << 16) | endpoint->setup.index;
len = endpoint->setup.length; len = endpoint->setup.length;
if ((len > spi_flash.page_len) || (addr > spi_flash.num_bytes) if ((len > spi_flash.page_len) || (addr > spi_flash.num_bytes) ||
|| ((addr + len) > spi_flash.num_bytes)) { ((addr + len) > spi_flash.num_bytes)) {
return USB_REQUEST_STATUS_STALL; return USB_REQUEST_STATUS_STALL;
} else { } else {
w25q80bv_read(&spi_flash, addr, len, &spiflash_buffer[0]); w25q80bv_read(&spi_flash, addr, len, &spiflash_buffer[0]);
usb_transfer_schedule_block(endpoint->in, &spiflash_buffer[0], len, usb_transfer_schedule_block(
NULL, NULL); endpoint->in,
&spiflash_buffer[0],
len,
NULL,
NULL);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
} else if (stage == USB_TRANSFER_STAGE_DATA) } else if (stage == USB_TRANSFER_STAGE_DATA) {
{
addr = (endpoint->setup.value << 16) | endpoint->setup.index; addr = (endpoint->setup.value << 16) | endpoint->setup.index;
len = endpoint->setup.length; len = endpoint->setup.length;
/* This check is redundant but makes me feel better. */ /* This check is redundant but makes me feel better. */
if ((len > spi_flash.page_len) || (addr > spi_flash.num_bytes) if ((len > spi_flash.page_len) || (addr > spi_flash.num_bytes) ||
|| ((addr + len) > spi_flash.num_bytes)) ((addr + len) > spi_flash.num_bytes)) {
{
return USB_REQUEST_STATUS_STALL; return USB_REQUEST_STATUS_STALL;
} else } else {
{
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
} else } else {
{
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
} }
usb_request_status_t usb_vendor_request_spiflash_status( usb_request_status_t usb_vendor_request_spiflash_status(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
w25q80bv_get_full_status(&spi_flash, endpoint->buffer); w25q80bv_get_full_status(&spi_flash, endpoint->buffer);
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2, NULL, NULL); usb_transfer_schedule_block(
endpoint->in,
&endpoint->buffer,
2,
NULL,
NULL);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} else if (stage == USB_TRANSFER_STAGE_DATA) { } else if (stage == USB_TRANSFER_STAGE_DATA) {
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
@ -137,7 +149,8 @@ usb_request_status_t usb_vendor_request_spiflash_status(
} }
usb_request_status_t usb_vendor_request_spiflash_clear_status( usb_request_status_t usb_vendor_request_spiflash_clear_status(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
w25q80bv_clear_status(&spi_flash); w25q80bv_clear_status(&spi_flash);

View File

@ -27,14 +27,19 @@
#include <usb_request.h> #include <usb_request.h>
usb_request_status_t usb_vendor_request_erase_spiflash( usb_request_status_t usb_vendor_request_erase_spiflash(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_write_spiflash( usb_request_status_t usb_vendor_request_write_spiflash(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_read_spiflash( usb_request_status_t usb_vendor_request_read_spiflash(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_spiflash_status( usb_request_status_t usb_vendor_request_spiflash_status(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_spiflash_clear_status( usb_request_status_t usb_vendor_request_spiflash_clear_status(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
#endif /* end of include guard: __USB_API_SPIFLASH_H__ */ #endif /* end of include guard: __USB_API_SPIFLASH_H__ */

View File

@ -49,7 +49,8 @@ static enum sweep_style style = LINEAR;
/* Do this before starting sweep mode with request_transceiver_mode(). */ /* Do this before starting sweep mode with request_transceiver_mode(). */
usb_request_status_t usb_vendor_request_init_sweep( usb_request_status_t usb_vendor_request_init_sweep(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
uint32_t num_bytes; uint32_t num_bytes;
int i; int i;
@ -63,22 +64,27 @@ usb_request_status_t usb_vendor_request_init_sweep(
if ((1 > num_ranges) || (MAX_RANGES < num_ranges)) { if ((1 > num_ranges) || (MAX_RANGES < num_ranges)) {
return USB_REQUEST_STATUS_STALL; return USB_REQUEST_STATUS_STALL;
} }
usb_transfer_schedule_block(endpoint->out, &data, usb_transfer_schedule_block(
endpoint->setup.length, NULL, NULL); endpoint->out,
&data,
endpoint->setup.length,
NULL,
NULL);
} else if (stage == USB_TRANSFER_STAGE_DATA) { } else if (stage == USB_TRANSFER_STAGE_DATA) {
step_width = ((uint32_t)(data[3]) << 24) | ((uint32_t)(data[2]) << 16) step_width = ((uint32_t) (data[3]) << 24) | ((uint32_t) (data[2]) << 16) |
| ((uint32_t)(data[1]) << 8) | data[0]; ((uint32_t) (data[1]) << 8) | data[0];
if (1 > step_width) { if (1 > step_width) {
return USB_REQUEST_STATUS_STALL; return USB_REQUEST_STATUS_STALL;
} }
offset = ((uint32_t)(data[7]) << 24) | ((uint32_t)(data[6]) << 16) offset = ((uint32_t) (data[7]) << 24) | ((uint32_t) (data[6]) << 16) |
| ((uint32_t)(data[5]) << 8) | data[4]; ((uint32_t) (data[5]) << 8) | data[4];
style = data[8]; style = data[8];
if (INTERLEAVED < style) { if (INTERLEAVED < style) {
return USB_REQUEST_STATUS_STALL; return USB_REQUEST_STATUS_STALL;
} }
for (i = 0; i < (num_ranges * 2); i++) { for (i = 0; i < (num_ranges * 2); i++) {
frequencies[i] = ((uint16_t)(data[10+i*2]) << 8) + data[9+i*2]; frequencies[i] =
((uint16_t) (data[10 + i * 2]) << 8) + data[9 + i * 2];
} }
sweep_freq = (uint64_t) frequencies[0] * FREQ_GRANULARITY; sweep_freq = (uint64_t) frequencies[0] * FREQ_GRANULARITY;
set_freq(sweep_freq + offset); set_freq(sweep_freq + offset);
@ -97,7 +103,8 @@ void sweep_bulk_transfer_complete(void *user_data, unsigned int bytes_transferre
m0_state.m4_count += 3 * 0x4000; m0_state.m4_count += 3 * 0x4000;
} }
void sweep_mode(uint32_t seq) { void sweep_mode(uint32_t seq)
{
// Sweep mode is implemented using timed M0 operations, as follows: // Sweep mode is implemented using timed M0 operations, as follows:
// //
// 0. M4 initially puts the M0 into RX mode, with an m0_count threshold // 0. M4 initially puts the M0 into RX mode, with an m0_count threshold
@ -137,7 +144,6 @@ void sweep_mode(uint32_t seq) {
baseband_streaming_enable(&sgpio_config); baseband_streaming_enable(&sgpio_config);
while (transceiver_request.seq == seq) { while (transceiver_request.seq == seq) {
// Wait for M0 to finish receiving a buffer. // Wait for M0 to finish receiving a buffer.
while (m0_state.active_mode != M0_MODE_WAIT) while (m0_state.active_mode != M0_MODE_WAIT)
if (transceiver_request.seq != seq) if (transceiver_request.seq != seq)
@ -165,8 +171,8 @@ void sweep_mode(uint32_t seq) {
&usb_endpoint_bulk_in, &usb_endpoint_bulk_in,
buffer, buffer,
0x4000, 0x4000,
sweep_bulk_transfer_complete, NULL sweep_bulk_transfer_complete,
); NULL);
// Use other buffer next time. // Use other buffer next time.
phase = (phase + 1) % 2; phase = (phase + 1) % 2;
@ -174,9 +180,13 @@ void sweep_mode(uint32_t seq) {
if (++blocks_queued == dwell_blocks) { if (++blocks_queued == dwell_blocks) {
// Calculate next sweep frequency. // Calculate next sweep frequency.
if (INTERLEAVED == style) { if (INTERLEAVED == style) {
if(!odd && ((sweep_freq + step_width) >= ((uint64_t)frequencies[1+range*2] * FREQ_GRANULARITY))) { if (!odd &&
((sweep_freq + step_width) >=
((uint64_t) frequencies[1 + range * 2] *
FREQ_GRANULARITY))) {
range = (range + 1) % num_ranges; range = (range + 1) % num_ranges;
sweep_freq = (uint64_t)frequencies[range*2] * FREQ_GRANULARITY; sweep_freq = (uint64_t) frequencies[range * 2] *
FREQ_GRANULARITY;
} else { } else {
if (odd) { if (odd) {
sweep_freq += step_width / 4; sweep_freq += step_width / 4;
@ -186,9 +196,12 @@ void sweep_mode(uint32_t seq) {
} }
odd = !odd; odd = !odd;
} else { } else {
if((sweep_freq + step_width) >= ((uint64_t)frequencies[1+range*2] * FREQ_GRANULARITY)) { if ((sweep_freq + step_width) >=
((uint64_t) frequencies[1 + range * 2] *
FREQ_GRANULARITY)) {
range = (range + 1) % num_ranges; range = (range + 1) % num_ranges;
sweep_freq = (uint64_t)frequencies[range*2] * FREQ_GRANULARITY; sweep_freq = (uint64_t) frequencies[range * 2] *
FREQ_GRANULARITY;
} else { } else {
sweep_freq += step_width; sweep_freq += step_width;
} }

View File

@ -32,7 +32,8 @@ enum sweep_style {
}; };
usb_request_status_t usb_vendor_request_init_sweep( usb_request_status_t usb_vendor_request_init_sweep(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
void sweep_mode(uint32_t seq); void sweep_mode(uint32_t seq);

View File

@ -70,10 +70,11 @@ set_sample_r_params_t set_sample_r_params;
usb_request_status_t usb_vendor_request_set_baseband_filter_bandwidth( usb_request_status_t usb_vendor_request_set_baseband_filter_bandwidth(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
const uint32_t bandwidth = (endpoint->setup.index << 16) | endpoint->setup.value; const uint32_t bandwidth =
(endpoint->setup.index << 16) | endpoint->setup.value;
if (baseband_filter_bandwidth_set(bandwidth)) { if (baseband_filter_bandwidth_set(bandwidth)) {
usb_transfer_schedule_ack(endpoint->in); usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
@ -88,22 +89,23 @@ usb_request_status_t usb_vendor_request_set_freq(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage) const usb_transfer_stage_t stage)
{ {
if (stage == USB_TRANSFER_STAGE_SETUP) if (stage == USB_TRANSFER_STAGE_SETUP) {
{ usb_transfer_schedule_block(
usb_transfer_schedule_block(endpoint->out, &set_freq_params, sizeof(set_freq_params_t), endpoint->out,
NULL, NULL); &set_freq_params,
sizeof(set_freq_params_t),
NULL,
NULL);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} else if (stage == USB_TRANSFER_STAGE_DATA) } else if (stage == USB_TRANSFER_STAGE_DATA) {
{ const uint64_t freq =
const uint64_t freq = set_freq_params.freq_mhz * 1000000ULL + set_freq_params.freq_hz; set_freq_params.freq_mhz * 1000000ULL + set_freq_params.freq_hz;
if( set_freq(freq) ) if (set_freq(freq)) {
{
usb_transfer_schedule_ack(endpoint->in); usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
return USB_REQUEST_STATUS_STALL; return USB_REQUEST_STATUS_STALL;
} else } else {
{
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
} }
@ -112,27 +114,30 @@ usb_request_status_t usb_vendor_request_set_sample_rate_frac(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage) const usb_transfer_stage_t stage)
{ {
if (stage == USB_TRANSFER_STAGE_SETUP) if (stage == USB_TRANSFER_STAGE_SETUP) {
{ usb_transfer_schedule_block(
usb_transfer_schedule_block(endpoint->out, &set_sample_r_params, sizeof(set_sample_r_params_t), endpoint->out,
NULL, NULL); &set_sample_r_params,
sizeof(set_sample_r_params_t),
NULL,
NULL);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} else if (stage == USB_TRANSFER_STAGE_DATA) } else if (stage == USB_TRANSFER_STAGE_DATA) {
{ if (sample_rate_frac_set(
if( sample_rate_frac_set(set_sample_r_params.freq_hz * 2, set_sample_r_params.divider ) ) set_sample_r_params.freq_hz * 2,
{ set_sample_r_params.divider)) {
usb_transfer_schedule_ack(endpoint->in); usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
return USB_REQUEST_STATUS_STALL; return USB_REQUEST_STATUS_STALL;
} else } else {
{
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
} }
usb_request_status_t usb_vendor_request_set_amp_enable( usb_request_status_t usb_vendor_request_set_amp_enable(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
switch (endpoint->setup.value) { switch (endpoint->setup.value) {
@ -157,11 +162,17 @@ usb_request_status_t usb_vendor_request_set_lna_gain(
const usb_transfer_stage_t stage) const usb_transfer_stage_t stage)
{ {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
const uint8_t value = max2837_set_lna_gain(&max2837, endpoint->setup.index); const uint8_t value =
max2837_set_lna_gain(&max2837, endpoint->setup.index);
endpoint->buffer[0] = value; endpoint->buffer[0] = value;
if(value) hackrf_ui()->set_bb_lna_gain(endpoint->setup.index); if (value)
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, hackrf_ui()->set_bb_lna_gain(endpoint->setup.index);
NULL, NULL); usb_transfer_schedule_block(
endpoint->in,
&endpoint->buffer,
1,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
@ -169,14 +180,21 @@ usb_request_status_t usb_vendor_request_set_lna_gain(
} }
usb_request_status_t usb_vendor_request_set_vga_gain( usb_request_status_t usb_vendor_request_set_vga_gain(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
const uint8_t value = max2837_set_vga_gain(&max2837, endpoint->setup.index); const uint8_t value =
max2837_set_vga_gain(&max2837, endpoint->setup.index);
endpoint->buffer[0] = value; endpoint->buffer[0] = value;
if(value) hackrf_ui()->set_bb_vga_gain(endpoint->setup.index); if (value)
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, hackrf_ui()->set_bb_vga_gain(endpoint->setup.index);
NULL, NULL); usb_transfer_schedule_block(
endpoint->in,
&endpoint->buffer,
1,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
@ -184,14 +202,21 @@ usb_request_status_t usb_vendor_request_set_vga_gain(
} }
usb_request_status_t usb_vendor_request_set_txvga_gain( usb_request_status_t usb_vendor_request_set_txvga_gain(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
const uint8_t value = max2837_set_txvga_gain(&max2837, endpoint->setup.index); const uint8_t value =
max2837_set_txvga_gain(&max2837, endpoint->setup.index);
endpoint->buffer[0] = value; endpoint->buffer[0] = value;
if(value) hackrf_ui()->set_bb_tx_vga_gain(endpoint->setup.index); if (value)
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, hackrf_ui()->set_bb_tx_vga_gain(endpoint->setup.index);
NULL, NULL); usb_transfer_schedule_block(
endpoint->in,
&endpoint->buffer,
1,
NULL,
NULL);
usb_transfer_schedule_ack(endpoint->out); usb_transfer_schedule_ack(endpoint->out);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
@ -199,7 +224,8 @@ usb_request_status_t usb_vendor_request_set_txvga_gain(
} }
usb_request_status_t usb_vendor_request_set_antenna_enable( usb_request_status_t usb_vendor_request_set_antenna_enable(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
{ {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
switch (endpoint->setup.value) { switch (endpoint->setup.value) {
@ -224,12 +250,18 @@ usb_request_status_t usb_vendor_request_set_freq_explicit(
const usb_transfer_stage_t stage) const usb_transfer_stage_t stage)
{ {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
usb_transfer_schedule_block(endpoint->out, &explicit_params, usb_transfer_schedule_block(
sizeof(struct set_freq_explicit_params), NULL, NULL); endpoint->out,
&explicit_params,
sizeof(struct set_freq_explicit_params),
NULL,
NULL);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} else if (stage == USB_TRANSFER_STAGE_DATA) { } else if (stage == USB_TRANSFER_STAGE_DATA) {
if (set_freq_explicit(explicit_params.if_freq_hz, if (set_freq_explicit(
explicit_params.lo_freq_hz, explicit_params.path)) { explicit_params.if_freq_hz,
explicit_params.lo_freq_hz,
explicit_params.path)) {
usb_transfer_schedule_ack(endpoint->in); usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK; return USB_REQUEST_STATUS_OK;
} }
@ -243,7 +275,8 @@ static volatile hw_sync_mode_t _hw_sync_mode = HW_SYNC_MODE_OFF;
static volatile uint32_t _tx_underrun_limit; static volatile uint32_t _tx_underrun_limit;
static volatile uint32_t _rx_overrun_limit; static volatile uint32_t _rx_overrun_limit;
void set_hw_sync_mode(const hw_sync_mode_t new_hw_sync_mode) { void set_hw_sync_mode(const hw_sync_mode_t new_hw_sync_mode)
{
_hw_sync_mode = new_hw_sync_mode; _hw_sync_mode = new_hw_sync_mode;
} }
@ -276,8 +309,8 @@ void transceiver_shutdown(void)
m0_set_mode(M0_MODE_IDLE); m0_set_mode(M0_MODE_IDLE);
} }
void transceiver_startup(const transceiver_mode_t mode) { void transceiver_startup(const transceiver_mode_t mode)
{
hackrf_ui()->set_transceiver_mode(mode); hackrf_ui()->set_transceiver_mode(mode);
switch (mode) { switch (mode) {
@ -341,8 +374,8 @@ usb_request_status_t usb_vendor_request_set_hw_sync_mode(
usb_request_status_t usb_vendor_request_set_tx_underrun_limit( usb_request_status_t usb_vendor_request_set_tx_underrun_limit(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
uint32_t value = (endpoint->setup.index << 16) + endpoint->setup.value; uint32_t value = (endpoint->setup.index << 16) + endpoint->setup.value;
_tx_underrun_limit = value; _tx_underrun_limit = value;
@ -353,8 +386,8 @@ usb_request_status_t usb_vendor_request_set_tx_underrun_limit(
usb_request_status_t usb_vendor_request_set_rx_overrun_limit( usb_request_status_t usb_vendor_request_set_rx_overrun_limit(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
uint32_t value = (endpoint->setup.index << 16) + endpoint->setup.value; uint32_t value = (endpoint->setup.index << 16) + endpoint->setup.value;
_rx_overrun_limit = value; _rx_overrun_limit = value;
@ -369,7 +402,8 @@ void transceiver_bulk_transfer_complete(void *user_data, unsigned int bytes_tran
m0_state.m4_count += bytes_transferred; m0_state.m4_count += bytes_transferred;
} }
void rx_mode(uint32_t seq) { void rx_mode(uint32_t seq)
{
uint32_t usb_count = 0; uint32_t usb_count = 0;
transceiver_startup(TRANSCEIVER_MODE_RX); transceiver_startup(TRANSCEIVER_MODE_RX);
@ -383,8 +417,7 @@ void rx_mode(uint32_t seq) {
&usb_bulk_buffer[usb_count & USB_BULK_BUFFER_MASK], &usb_bulk_buffer[usb_count & USB_BULK_BUFFER_MASK],
USB_TRANSFER_SIZE, USB_TRANSFER_SIZE,
transceiver_bulk_transfer_complete, transceiver_bulk_transfer_complete,
NULL NULL);
);
usb_count += USB_TRANSFER_SIZE; usb_count += USB_TRANSFER_SIZE;
} }
} }
@ -392,7 +425,8 @@ void rx_mode(uint32_t seq) {
transceiver_shutdown(); transceiver_shutdown();
} }
void tx_mode(uint32_t seq) { void tx_mode(uint32_t seq)
{
unsigned int usb_count = 0; unsigned int usb_count = 0;
transceiver_startup(TRANSCEIVER_MODE_TX); transceiver_startup(TRANSCEIVER_MODE_TX);
@ -403,8 +437,7 @@ void tx_mode(uint32_t seq) {
&usb_bulk_buffer[0x0000], &usb_bulk_buffer[0x0000],
USB_TRANSFER_SIZE, USB_TRANSFER_SIZE,
transceiver_bulk_transfer_complete, transceiver_bulk_transfer_complete,
NULL NULL);
);
usb_count += USB_TRANSFER_SIZE; usb_count += USB_TRANSFER_SIZE;
// Enable streaming. The M0 is in TX_START mode, and will automatically // Enable streaming. The M0 is in TX_START mode, and will automatically
@ -420,8 +453,7 @@ void tx_mode(uint32_t seq) {
&usb_bulk_buffer[usb_count & USB_BULK_BUFFER_MASK], &usb_bulk_buffer[usb_count & USB_BULK_BUFFER_MASK],
USB_TRANSFER_SIZE, USB_TRANSFER_SIZE,
transceiver_bulk_transfer_complete, transceiver_bulk_transfer_complete,
NULL NULL);
);
usb_count += USB_TRANSFER_SIZE; usb_count += USB_TRANSFER_SIZE;
} }
} }

View File

@ -48,24 +48,32 @@ usb_request_status_t usb_vendor_request_set_sample_rate_frac(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage); const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_set_amp_enable( usb_request_status_t usb_vendor_request_set_amp_enable(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_set_lna_gain( usb_request_status_t usb_vendor_request_set_lna_gain(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage); const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_set_vga_gain( usb_request_status_t usb_vendor_request_set_vga_gain(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_set_txvga_gain( usb_request_status_t usb_vendor_request_set_txvga_gain(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_set_antenna_enable( usb_request_status_t usb_vendor_request_set_antenna_enable(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_set_freq_explicit( usb_request_status_t usb_vendor_request_set_freq_explicit(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_set_hw_sync_mode( usb_request_status_t usb_vendor_request_set_hw_sync_mode(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_set_tx_underrun_limit( usb_request_status_t usb_vendor_request_set_tx_underrun_limit(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
usb_request_status_t usb_vendor_request_set_rx_overrun_limit( usb_request_status_t usb_vendor_request_set_rx_overrun_limit(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage);
void request_transceiver_mode(transceiver_mode_t mode); void request_transceiver_mode(transceiver_mode_t mode);
void transceiver_startup(transceiver_mode_t mode); void transceiver_startup(transceiver_mode_t mode);

View File

@ -30,8 +30,8 @@
usb_request_status_t usb_vendor_request_set_ui_enable( usb_request_status_t usb_vendor_request_set_ui_enable(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage)
) { {
if (stage == USB_TRANSFER_STAGE_SETUP) { if (stage == USB_TRANSFER_STAGE_SETUP) {
hackrf_ui_set_enable(endpoint->setup.value); hackrf_ui_set_enable(endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in); usb_transfer_schedule_ack(endpoint->in);

View File

@ -27,7 +27,6 @@
usb_request_status_t usb_vendor_request_set_ui_enable( usb_request_status_t usb_vendor_request_set_ui_enable(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage);
);
#endif /* end of include guard: __USB_API_UI_H__ */ #endif /* end of include guard: __USB_API_UI_H__ */

View File

@ -152,7 +152,6 @@ uint8_t usb_descriptor_configuration_high_speed[] = {
0, // TERMINATOR 0, // TERMINATOR
}; };
uint8_t usb_descriptor_string_languages[] = { uint8_t usb_descriptor_string_languages[] = {
0x04, // bLength 0x04, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType

View File

@ -30,7 +30,8 @@ extern uint8_t usb_descriptor_string_manufacturer[];
extern uint8_t usb_descriptor_string_product[]; extern uint8_t usb_descriptor_string_product[];
#define USB_DESCRIPTOR_STRING_SERIAL_LEN 32 #define USB_DESCRIPTOR_STRING_SERIAL_LEN 32
#define USB_DESCRIPTOR_STRING_SERIAL_BUF_LEN (USB_DESCRIPTOR_STRING_SERIAL_LEN*2 + 2) /* UTF-16LE */ #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_string_serial_number[];
extern uint8_t* usb_descriptor_strings[]; extern uint8_t* usb_descriptor_strings[];

View File

@ -38,7 +38,6 @@ usb_configuration_t usb_configuration_full_speed = {
.descriptor = usb_descriptor_configuration_full_speed, .descriptor = usb_descriptor_configuration_full_speed,
}; };
usb_configuration_t* usb_configurations[] = { usb_configuration_t* usb_configurations[] = {
&usb_configuration_high_speed, &usb_configuration_high_speed,
&usb_configuration_full_speed, &usb_configuration_full_speed,

View File

@ -56,8 +56,7 @@ usb_endpoint_t usb_endpoint_bulk_in = {
.in = &usb_endpoint_bulk_in, .in = &usb_endpoint_bulk_in,
.out = 0, .out = 0,
.setup_complete = 0, .setup_complete = 0,
.transfer_complete = usb_queue_transfer_complete .transfer_complete = usb_queue_transfer_complete};
};
static USB_DEFINE_QUEUE(usb_endpoint_bulk_in, 1); static USB_DEFINE_QUEUE(usb_endpoint_bulk_in, 1);
usb_endpoint_t usb_endpoint_bulk_out = { usb_endpoint_t usb_endpoint_bulk_out = {
@ -66,8 +65,5 @@ usb_endpoint_t usb_endpoint_bulk_out = {
.in = 0, .in = 0,
.out = &usb_endpoint_bulk_out, .out = &usb_endpoint_bulk_out,
.setup_complete = 0, .setup_complete = 0,
.transfer_complete = usb_queue_transfer_complete .transfer_complete = usb_queue_transfer_complete};
};
static USB_DEFINE_QUEUE(usb_endpoint_bulk_out, 1); static USB_DEFINE_QUEUE(usb_endpoint_bulk_out, 1);

View File

@ -35,7 +35,8 @@ typedef int bool;
#define CLOCK_UNDEFINED 0xFF #define CLOCK_UNDEFINED 0xFF
#define REGISTER_INVALID 32767 #define REGISTER_INVALID 32767
int parse_int(char* s, uint8_t* const value) { int parse_int(char* s, uint8_t* const value)
{
uint_fast8_t base = 10; uint_fast8_t base = 10;
char* s_end; char* s_end;
long long_value; long long_value;
@ -62,14 +63,17 @@ int parse_int(char* s, uint8_t* const value) {
} }
} }
int si5351c_read_register(hackrf_device* device, const uint16_t register_number) { int si5351c_read_register(hackrf_device* device, const uint16_t register_number)
{
uint16_t register_value; uint16_t register_value;
int result = hackrf_si5351c_read(device, register_number, &register_value); int result = hackrf_si5351c_read(device, register_number, &register_value);
if (result == HACKRF_SUCCESS) { if (result == HACKRF_SUCCESS) {
printf("[%3d] -> 0x%02x\n", register_number, register_value); printf("[%3d] -> 0x%02x\n", register_number, register_value);
} else { } else {
printf("hackrf_si5351c_read() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_si5351c_read() failed: %s (%d)\n",
hackrf_error_name(result),
result);
} }
return result; return result;
@ -78,15 +82,17 @@ int si5351c_read_register(hackrf_device* device, const uint16_t register_number)
int si5351c_write_register( int si5351c_write_register(
hackrf_device* device, hackrf_device* device,
const uint16_t register_number, const uint16_t register_number,
const uint16_t register_value const uint16_t register_value)
) { {
int result = HACKRF_SUCCESS; int result = HACKRF_SUCCESS;
result = hackrf_si5351c_write(device, register_number, register_value); result = hackrf_si5351c_write(device, register_number, register_value);
if (result == HACKRF_SUCCESS) { if (result == HACKRF_SUCCESS) {
printf("0x%2x -> [%3d]\n", register_value, register_number); printf("0x%2x -> [%3d]\n", register_value, register_number);
} else { } else {
printf("hackrf_max2837_write() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_max2837_write() failed: %s (%d)\n",
hackrf_error_name(result),
result);
} }
return result; return result;
@ -101,7 +107,8 @@ int si5351c_write_register(
#define SI5351C_CLK_SRC_MULTISYNTH_0_4 2 #define SI5351C_CLK_SRC_MULTISYNTH_0_4 2
#define SI5351C_CLK_SRC_MULTISYNTH_SELF 3 #define SI5351C_CLK_SRC_MULTISYNTH_SELF 3
void print_clk_control(uint16_t clk_ctrl) { void print_clk_control(uint16_t clk_ctrl)
{
uint8_t clk_src, clk_pwr; uint8_t clk_src, clk_pwr;
printf("\tclock control = "); printf("\tclock control = ");
if (clk_ctrl & SI5351C_CLK_POWERDOWN) if (clk_ctrl & SI5351C_CLK_POWERDOWN)
@ -150,7 +157,8 @@ void print_clk_control(uint16_t clk_ctrl) {
} }
} }
int si5351c_read_multisynth_config(hackrf_device* device, const uint_fast8_t ms_number) { int si5351c_read_multisynth_config(hackrf_device* device, const uint_fast8_t ms_number)
{
uint_fast8_t i, reg_base, reg_number; uint_fast8_t i, reg_base, reg_number;
uint16_t parameters[8], clk_control; uint16_t parameters[8], clk_control;
uint32_t p1, p2, p3, r_div; uint32_t p1, p2, p3, r_div;
@ -173,22 +181,22 @@ int si5351c_read_multisynth_config(hackrf_device* device, const uint_fast8_t ms_
} }
} }
p1 = ((parameters[2] & 0x03) << 16) p1 = ((parameters[2] & 0x03) << 16) | (parameters[3] << 8) |
| (parameters[3] << 8) parameters[4];
| parameters[4]; p2 = ((parameters[5] & 0x0F) << 16) | (parameters[6] << 8) |
p2 = ((parameters[5] & 0x0F) << 16) parameters[7];
| (parameters[6] << 8) p3 = ((parameters[5] & 0xF0) << 12) | (parameters[0] << 8) |
| parameters[7]; parameters[1];
p3 = ((parameters[5] & 0xF0) << 12)
| (parameters[0] << 8)
| parameters[1];
r_div = (parameters[2] >> 4) & 0x7; r_div = (parameters[2] >> 4) & 0x7;
printf("\tp1 = %u\n", p1); printf("\tp1 = %u\n", p1);
printf("\tp2 = %u\n", p2); printf("\tp2 = %u\n", p2);
printf("\tp3 = %u\n", p3); printf("\tp3 = %u\n", p3);
if (p3) if (p3)
printf("\tOutput (800Mhz PLL): %#.10f Mhz\n", ((double)800 / (double)(((double)p1*p3 + p2 + 512*p3)/(double)(128*p3))) / div_lut[r_div] ); printf("\tOutput (800Mhz PLL): %#.10f Mhz\n",
((double) 800 /
(double) (((double) p1 * p3 + p2 + 512 * p3) / (double) (128 * p3))) /
div_lut[r_div]);
} else { } else {
// MS6 and 7 are integer only // MS6 and 7 are integer only
unsigned int parms; unsigned int parms;
@ -196,22 +204,26 @@ int si5351c_read_multisynth_config(hackrf_device* device, const uint_fast8_t ms_
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
uint_fast8_t reg_number = reg_base + i; uint_fast8_t reg_number = reg_base + i;
int result = hackrf_si5351c_read(device, reg_number, &parameters[i]); int result =
hackrf_si5351c_read(device, reg_number, &parameters[i]);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
return result; return result;
} }
} }
r_div = (ms_number == 6) ? parameters[2] & 0x7 : (parameters[2] & 0x70) >> 4 ; r_div = (ms_number == 6) ? parameters[2] & 0x7 :
(parameters[2] & 0x70) >> 4;
parms = (ms_number == 6) ? parameters[0] : parameters[1]; parms = (ms_number == 6) ? parameters[0] : parameters[1];
printf("\tp1_int = %u\n", parms); printf("\tp1_int = %u\n", parms);
if (parms) if (parms)
printf("\tOutput (800Mhz PLL): %#.10f Mhz\n", (800.0f / parms) / div_lut[r_div] ); printf("\tOutput (800Mhz PLL): %#.10f Mhz\n",
(800.0f / parms) / div_lut[r_div]);
} }
printf("\toutput divider = %u\n", div_lut[r_div]); printf("\toutput divider = %u\n", div_lut[r_div]);
return HACKRF_SUCCESS; return HACKRF_SUCCESS;
} }
int si5351c_read_configuration(hackrf_device* device) { int si5351c_read_configuration(hackrf_device* device)
{
uint_fast8_t ms_number; uint_fast8_t ms_number;
int result; int result;
@ -224,7 +236,8 @@ int si5351c_read_configuration(hackrf_device* device) {
return HACKRF_SUCCESS; return HACKRF_SUCCESS;
} }
static void usage() { static void usage()
{
printf("hackrf_clock - HackRF clock configuration utility\n"); printf("hackrf_clock - HackRF clock configuration utility\n");
printf("Usage:\n"); printf("Usage:\n");
printf("\t-h, --help: this help\n"); printf("\t-h, --help: this help\n");
@ -245,7 +258,8 @@ static struct option long_options[] = {
{0, 0, 0, 0}, {0, 0, 0, 0},
}; };
int main(int argc, char** argv) { int main(int argc, char** argv)
{
hackrf_device* device = NULL; hackrf_device* device = NULL;
int opt, option_index = 0; int opt, option_index = 0;
bool read = false; bool read = false;
@ -256,11 +270,14 @@ int main(int argc, char** argv) {
int result = hackrf_init(); int result = hackrf_init();
if (result) { if (result) {
printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_init() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
while( (opt = getopt_long(argc, argv, "r:ao:d:h?", long_options, &option_index)) != EOF ) { while ((opt = getopt_long(argc, argv, "r:ao:d:h?", long_options, &option_index)) !=
EOF) {
switch (opt) { switch (opt) {
case 'r': case 'r':
read = true; read = true;
@ -291,28 +308,35 @@ int main(int argc, char** argv) {
} }
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
printf("argument error: %s (%d)\n", hackrf_error_name(result), result); printf("argument error: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
if (!clkout && !read) { if (!clkout && !read) {
fprintf(stderr, "Either read or enable CLKOUT option must be specified.\n"); fprintf(stderr,
"Either read or enable CLKOUT option must be specified.\n");
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
result = hackrf_open_by_serial(serial_number, &device); result = hackrf_open_by_serial(serial_number, &device);
if (result) { if (result) {
printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_open() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (clkout) { if (clkout) {
result = hackrf_set_clkout_enable(device, clkout_enable); result = hackrf_set_clkout_enable(device, clkout_enable);
if (result) { if (result) {
printf("hackrf_set_clkout_enable() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_set_clkout_enable() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
@ -328,7 +352,9 @@ int main(int argc, char** argv) {
result = hackrf_close(device); result = hackrf_close(device);
if (result) { if (result) {
printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_close() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View File

@ -100,8 +100,8 @@ int main(int argc, char** argv)
ssize_t bytes_read; ssize_t bytes_read;
uint8_t* pdata = &data[0]; uint8_t* pdata = &data[0];
while ((opt = getopt_long(argc, argv, "x:d:h?", long_options, while ((opt = getopt_long(argc, argv, "x:d:h?", long_options, &option_index)) !=
&option_index)) != EOF) { EOF) {
switch (opt) { switch (opt) {
case 'x': case 'x':
path = optarg; path = optarg;
@ -129,8 +129,7 @@ int main(int argc, char** argv)
} }
infile = fopen(path, "rb"); infile = fopen(path, "rb");
if (infile == NULL) if (infile == NULL) {
{
fprintf(stderr, "Failed to open file: %s\n", path); fprintf(stderr, "Failed to open file: %s\n", path);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -150,10 +149,11 @@ int main(int argc, char** argv)
total_length = length; total_length = length;
bytes_read = fread(data, 1, total_length, infile); bytes_read = fread(data, 1, total_length, infile);
if (bytes_read != total_length) if (bytes_read != total_length) {
{ fprintf(stderr,
fprintf(stderr, "Failed to read all bytes (read %d bytes instead of %d bytes).\n", "Failed to read all bytes (read %d bytes instead of %d bytes).\n",
(int)bytes_read, total_length); (int) bytes_read,
total_length);
fclose(infile); fclose(infile);
infile = NULL; infile = NULL;
return EXIT_FAILURE; return EXIT_FAILURE;
@ -161,25 +161,30 @@ int main(int argc, char** argv)
result = hackrf_init(); result = hackrf_init();
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_init() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_init() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
result = hackrf_open_by_serial(serial_number, &device); result = hackrf_open_by_serial(serial_number, &device);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_open() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_open() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
printf("LED1/2/3 blinking means CPLD program success.\nLED3/RED steady means error.\n"); printf("LED1/2/3 blinking means CPLD program success.\nLED3/RED steady means error.\n");
printf("Wait message 'Write finished' or in case of LED3/RED steady, Power OFF/Disconnect the HackRF.\n"); printf("Wait message 'Write finished' or in case of LED3/RED steady, Power OFF/Disconnect the HackRF.\n");
result = hackrf_cpld_write(device, pdata, total_length); result = hackrf_cpld_write(device, pdata, total_length);
if (result != HACKRF_SUCCESS) if (result != HACKRF_SUCCESS) {
{ fprintf(stderr,
fprintf(stderr, "hackrf_cpld_write() failed: %s (%d)\n", "hackrf_cpld_write() failed: %s (%d)\n",
hackrf_error_name(result), result); hackrf_error_name(result),
result);
fclose(infile); fclose(infile);
infile = NULL; infile = NULL;
return EXIT_FAILURE; return EXIT_FAILURE;
@ -190,10 +195,11 @@ int main(int argc, char** argv)
fflush(stdout); fflush(stdout);
result = hackrf_close(device); result = hackrf_close(device);
if( result != HACKRF_SUCCESS ) if (result != HACKRF_SUCCESS) {
{ fprintf(stderr,
fprintf(stderr, "hackrf_close() failed: %s (%d)\n", "hackrf_close() failed: %s (%d)\n",
hackrf_error_name(result), result); hackrf_error_name(result),
result);
fclose(infile); fclose(infile);
infile = NULL; infile = NULL;
return EXIT_FAILURE; return EXIT_FAILURE;

View File

@ -36,7 +36,8 @@ typedef int bool;
#define REGISTER_INVALID 32767 #define REGISTER_INVALID 32767
int parse_int(char* s, uint32_t* const value) { int parse_int(char* s, uint32_t* const value)
{
uint_fast8_t base = 10; uint_fast8_t base = 10;
char* s_end; char* s_end;
long long_value; long long_value;
@ -63,19 +64,24 @@ int parse_int(char* s, uint32_t* const value) {
} }
} }
int max2837_read_register(hackrf_device* device, const uint16_t register_number) { int max2837_read_register(hackrf_device* device, const uint16_t register_number)
{
uint16_t register_value; uint16_t register_value;
int result = hackrf_max2837_read(device, (uint8_t)register_number, &register_value); int result =
hackrf_max2837_read(device, (uint8_t) register_number, &register_value);
if (result == HACKRF_SUCCESS) { if (result == HACKRF_SUCCESS) {
printf("[%2d] -> 0x%03x\n", register_number, register_value); printf("[%2d] -> 0x%03x\n", register_number, register_value);
} else { } else {
printf("hackrf_max2837_read() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_max2837_read() failed: %s (%d)\n",
hackrf_error_name(result),
result);
} }
return result; return result;
} }
int max2837_read_registers(hackrf_device* device) { int max2837_read_registers(hackrf_device* device)
{
uint16_t register_number; uint16_t register_number;
int result = HACKRF_SUCCESS; int result = HACKRF_SUCCESS;
@ -91,33 +97,39 @@ int max2837_read_registers(hackrf_device* device) {
int max2837_write_register( int max2837_write_register(
hackrf_device* device, hackrf_device* device,
const uint16_t register_number, const uint16_t register_number,
const uint16_t register_value const uint16_t register_value)
) { {
int result = HACKRF_SUCCESS; int result = HACKRF_SUCCESS;
result = hackrf_max2837_write(device, (uint8_t) register_number, register_value); result = hackrf_max2837_write(device, (uint8_t) register_number, register_value);
if (result == HACKRF_SUCCESS) { if (result == HACKRF_SUCCESS) {
printf("0x%03x -> [%2d]\n", register_value, register_number); printf("0x%03x -> [%2d]\n", register_value, register_number);
} else { } else {
printf("hackrf_max2837_write() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_max2837_write() failed: %s (%d)\n",
hackrf_error_name(result),
result);
} }
return result; return result;
} }
int si5351c_read_register(hackrf_device* device, const uint16_t register_number) { int si5351c_read_register(hackrf_device* device, const uint16_t register_number)
{
uint16_t register_value; uint16_t register_value;
int result = hackrf_si5351c_read(device, register_number, &register_value); int result = hackrf_si5351c_read(device, register_number, &register_value);
if (result == HACKRF_SUCCESS) { if (result == HACKRF_SUCCESS) {
printf("[%3d] -> 0x%02x\n", register_number, register_value); printf("[%3d] -> 0x%02x\n", register_number, register_value);
} else { } else {
printf("hackrf_si5351c_read() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_si5351c_read() failed: %s (%d)\n",
hackrf_error_name(result),
result);
} }
return result; return result;
} }
int si5351c_read_registers(hackrf_device* device) { int si5351c_read_registers(hackrf_device* device)
{
uint16_t register_number; uint16_t register_number;
int result = HACKRF_SUCCESS; int result = HACKRF_SUCCESS;
@ -134,15 +146,17 @@ int si5351c_read_registers(hackrf_device* device) {
int si5351c_write_register( int si5351c_write_register(
hackrf_device* device, hackrf_device* device,
const uint16_t register_number, const uint16_t register_number,
const uint16_t register_value const uint16_t register_value)
) { {
int result = HACKRF_SUCCESS; int result = HACKRF_SUCCESS;
result = hackrf_si5351c_write(device, register_number, register_value); result = hackrf_si5351c_write(device, register_number, register_value);
if (result == HACKRF_SUCCESS) { if (result == HACKRF_SUCCESS) {
printf("0x%2x -> [%3d]\n", register_value, register_number); printf("0x%2x -> [%3d]\n", register_value, register_number);
} else { } else {
printf("hackrf_max2837_write() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_max2837_write() failed: %s (%d)\n",
hackrf_error_name(result),
result);
} }
return result; return result;
@ -157,7 +171,8 @@ int si5351c_write_register(
#define SI5351C_CLK_SRC_MULTISYNTH_0_4 2 #define SI5351C_CLK_SRC_MULTISYNTH_0_4 2
#define SI5351C_CLK_SRC_MULTISYNTH_SELF 3 #define SI5351C_CLK_SRC_MULTISYNTH_SELF 3
void print_clk_control(uint16_t clk_ctrl) { void print_clk_control(uint16_t clk_ctrl)
{
uint8_t clk_src, clk_pwr; uint8_t clk_src, clk_pwr;
printf("\tclock control = \n"); printf("\tclock control = \n");
if (clk_ctrl & SI5351C_CLK_POWERDOWN) if (clk_ctrl & SI5351C_CLK_POWERDOWN)
@ -206,7 +221,8 @@ void print_clk_control(uint16_t clk_ctrl) {
} }
} }
int si5351c_read_multisynth_config(hackrf_device* device, const uint_fast8_t ms_number) { int si5351c_read_multisynth_config(hackrf_device* device, const uint_fast8_t ms_number)
{
uint_fast8_t i, reg_base, reg_number; uint_fast8_t i, reg_base, reg_number;
uint16_t parameters[8], clk_control; uint16_t parameters[8], clk_control;
uint32_t p1, p2, p3, r_div; uint32_t p1, p2, p3, r_div;
@ -229,22 +245,22 @@ int si5351c_read_multisynth_config(hackrf_device* device, const uint_fast8_t ms_
} }
} }
p1 = ((parameters[2] & 0x03) << 16) p1 = ((parameters[2] & 0x03) << 16) | (parameters[3] << 8) |
| (parameters[3] << 8) parameters[4];
| parameters[4]; p2 = ((parameters[5] & 0x0F) << 16) | (parameters[6] << 8) |
p2 = ((parameters[5] & 0x0F) << 16) parameters[7];
| (parameters[6] << 8) p3 = ((parameters[5] & 0xF0) << 12) | (parameters[0] << 8) |
| parameters[7]; parameters[1];
p3 = ((parameters[5] & 0xF0) << 12)
| (parameters[0] << 8)
| parameters[1];
r_div = (parameters[2] >> 4) & 0x7; r_div = (parameters[2] >> 4) & 0x7;
printf("\tp1 = %u\n", p1); printf("\tp1 = %u\n", p1);
printf("\tp2 = %u\n", p2); printf("\tp2 = %u\n", p2);
printf("\tp3 = %u\n", p3); printf("\tp3 = %u\n", p3);
if (p3) if (p3)
printf("\tOutput (800Mhz PLL): %#.10f Mhz\n", ((double)800 / (double)(((double)p1*p3 + p2 + 512*p3)/(double)(128*p3))) / div_lut[r_div] ); printf("\tOutput (800Mhz PLL): %#.10f Mhz\n",
((double) 800 /
(double) (((double) p1 * p3 + p2 + 512 * p3) / (double) (128 * p3))) /
div_lut[r_div]);
} else { } else {
// MS6 and 7 are integer only // MS6 and 7 are integer only
unsigned int parms; unsigned int parms;
@ -252,22 +268,26 @@ int si5351c_read_multisynth_config(hackrf_device* device, const uint_fast8_t ms_
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
uint_fast8_t reg_number = reg_base + i; uint_fast8_t reg_number = reg_base + i;
int result = hackrf_si5351c_read(device, reg_number, &parameters[i]); int result =
hackrf_si5351c_read(device, reg_number, &parameters[i]);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
return result; return result;
} }
} }
r_div = (ms_number == 6) ? parameters[2] & 0x7 : (parameters[2] & 0x70) >> 4 ; r_div = (ms_number == 6) ? parameters[2] & 0x7 :
(parameters[2] & 0x70) >> 4;
parms = (ms_number == 6) ? parameters[0] : parameters[1]; parms = (ms_number == 6) ? parameters[0] : parameters[1];
printf("\tp1_int = %u\n", parms); printf("\tp1_int = %u\n", parms);
if (parms) if (parms)
printf("\tOutput (800Mhz PLL): %#.10f Mhz\n", (800.0f / parms) / div_lut[r_div] ); printf("\tOutput (800Mhz PLL): %#.10f Mhz\n",
(800.0f / parms) / div_lut[r_div]);
} }
printf("\toutput divider = %u\n", div_lut[r_div]); printf("\toutput divider = %u\n", div_lut[r_div]);
return HACKRF_SUCCESS; return HACKRF_SUCCESS;
} }
int si5351c_read_configuration(hackrf_device* device) { int si5351c_read_configuration(hackrf_device* device)
{
uint_fast8_t ms_number; uint_fast8_t ms_number;
int result; int result;
@ -287,20 +307,25 @@ int si5351c_read_configuration(hackrf_device* device) {
* we use that name here and present it to the user. * we use that name here and present it to the user.
*/ */
int rffc5072_read_register(hackrf_device* device, const uint16_t register_number) { int rffc5072_read_register(hackrf_device* device, const uint16_t register_number)
{
uint16_t register_value; uint16_t register_value;
int result = hackrf_rffc5071_read(device, (uint8_t)register_number, &register_value); int result =
hackrf_rffc5071_read(device, (uint8_t) register_number, &register_value);
if (result == HACKRF_SUCCESS) { if (result == HACKRF_SUCCESS) {
printf("[%2d] -> 0x%03x\n", register_number, register_value); printf("[%2d] -> 0x%03x\n", register_number, register_value);
} else { } else {
printf("hackrf_rffc5071_read() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_rffc5071_read() failed: %s (%d)\n",
hackrf_error_name(result),
result);
} }
return result; return result;
} }
int rffc5072_read_registers(hackrf_device* device) { int rffc5072_read_registers(hackrf_device* device)
{
uint16_t register_number; uint16_t register_number;
int result = HACKRF_SUCCESS; int result = HACKRF_SUCCESS;
@ -317,15 +342,17 @@ int rffc5072_read_registers(hackrf_device* device) {
int rffc5072_write_register( int rffc5072_write_register(
hackrf_device* device, hackrf_device* device,
const uint16_t register_number, const uint16_t register_number,
const uint16_t register_value const uint16_t register_value)
) { {
int result = HACKRF_SUCCESS; int result = HACKRF_SUCCESS;
result = hackrf_rffc5071_write(device, (uint8_t) register_number, register_value); result = hackrf_rffc5071_write(device, (uint8_t) register_number, register_value);
if (result == HACKRF_SUCCESS) { if (result == HACKRF_SUCCESS) {
printf("0x%03x -> [%2d]\n", register_value, register_number); printf("0x%03x -> [%2d]\n", register_value, register_number);
} else { } else {
printf("hackrf_rffc5071_write() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_rffc5071_write() failed: %s (%d)\n",
hackrf_error_name(result),
result);
} }
return result; return result;
@ -338,8 +365,8 @@ enum parts {
PART_RFFC5072 = 3, PART_RFFC5072 = 3,
}; };
int read_register(hackrf_device* device, uint8_t part, int read_register(hackrf_device* device, uint8_t part, const uint16_t register_number)
const uint16_t register_number) { {
switch (part) { switch (part) {
case PART_MAX2837: case PART_MAX2837:
return max2837_read_register(device, register_number); return max2837_read_register(device, register_number);
@ -351,7 +378,8 @@ int read_register(hackrf_device* device, uint8_t part,
return HACKRF_ERROR_INVALID_PARAM; return HACKRF_ERROR_INVALID_PARAM;
} }
int read_registers(hackrf_device* device, uint8_t part) { int read_registers(hackrf_device* device, uint8_t part)
{
switch (part) { switch (part) {
case PART_MAX2837: case PART_MAX2837:
return max2837_read_registers(device); return max2837_read_registers(device);
@ -363,9 +391,12 @@ int read_registers(hackrf_device* device, uint8_t part) {
return HACKRF_ERROR_INVALID_PARAM; return HACKRF_ERROR_INVALID_PARAM;
} }
int write_register(hackrf_device* device, uint8_t part, int write_register(
hackrf_device* device,
uint8_t part,
const uint16_t register_number, const uint16_t register_number,
const uint16_t register_value) { const uint16_t register_value)
{
switch (part) { switch (part) {
case PART_MAX2837: case PART_MAX2837:
return max2837_write_register(device, register_number, register_value); return max2837_write_register(device, register_number, register_value);
@ -377,7 +408,8 @@ int write_register(hackrf_device* device, uint8_t part,
return HACKRF_ERROR_INVALID_PARAM; return HACKRF_ERROR_INVALID_PARAM;
} }
static const char * mode_name(uint32_t mode) { static const char* mode_name(uint32_t mode)
{
const char* mode_names[] = {"IDLE", "WAIT", "RX", "TX_START", "TX_RUN"}; const char* mode_names[] = {"IDLE", "WAIT", "RX", "TX_START", "TX_RUN"};
const uint32_t num_modes = sizeof(mode_names) / sizeof(mode_names[0]); const uint32_t num_modes = sizeof(mode_names) / sizeof(mode_names[0]);
if (mode < num_modes) if (mode < num_modes)
@ -386,7 +418,8 @@ static const char * mode_name(uint32_t mode) {
return "UNKNOWN"; return "UNKNOWN";
} }
static const char * error_name(uint32_t error) { static const char* error_name(uint32_t error)
{
const char* error_names[] = {"NONE", "RX_TIMEOUT", "TX_TIMEOUT"}; const char* error_names[] = {"NONE", "RX_TIMEOUT", "TX_TIMEOUT"};
const uint32_t num_errors = sizeof(error_names) / sizeof(error_names[0]); const uint32_t num_errors = sizeof(error_names) / sizeof(error_names[0]);
if (error < num_errors) if (error < num_errors)
@ -395,12 +428,16 @@ static const char * error_name(uint32_t error) {
return "UNKNOWN"; return "UNKNOWN";
} }
static void print_state(hackrf_m0_state *state) { static void print_state(hackrf_m0_state* state)
{
printf("M0 state:\n"); printf("M0 state:\n");
printf("Requested mode: %u (%s) [%s]\n", printf("Requested mode: %u (%s) [%s]\n",
state->requested_mode, mode_name(state->requested_mode), state->requested_mode,
mode_name(state->requested_mode),
state->request_flag ? "pending" : "complete"); state->request_flag ? "pending" : "complete");
printf("Active mode: %u (%s)\n", state->active_mode, mode_name(state->active_mode)); printf("Active mode: %u (%s)\n",
state->active_mode,
mode_name(state->active_mode));
printf("M0 count: %u bytes\n", state->m0_count); printf("M0 count: %u bytes\n", state->m0_count);
printf("M4 count: %u bytes\n", state->m4_count); printf("M4 count: %u bytes\n", state->m4_count);
printf("Number of shortfalls: %u\n", state->num_shortfalls); printf("Number of shortfalls: %u\n", state->num_shortfalls);
@ -411,7 +448,8 @@ static void print_state(hackrf_m0_state *state) {
printf("Error: %u (%s)\n", state->error, error_name(state->error)); printf("Error: %u (%s)\n", state->error, error_name(state->error));
} }
static void usage() { static void usage()
{
printf("\nUsage:\n"); printf("\nUsage:\n");
printf("\t-h, --help: this help\n"); printf("\t-h, --help: this help\n");
printf("\t-n, --register <n>: set register number for read/write operations\n"); printf("\t-n, --register <n>: set register number for read/write operations\n");
@ -451,7 +489,8 @@ static struct option long_options[] = {
{0, 0, 0, 0}, {0, 0, 0, 0},
}; };
int main(int argc, char** argv) { int main(int argc, char** argv)
{
int opt; int opt;
uint32_t register_number = REGISTER_INVALID; uint32_t register_number = REGISTER_INVALID;
uint32_t register_value; uint32_t register_value;
@ -472,11 +511,18 @@ int main(int argc, char** argv) {
int result = hackrf_init(); int result = hackrf_init();
if (result) { if (result) {
printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_init() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
while( (opt = getopt_long(argc, argv, "n:rw:d:cmsfST:R:h?u:", long_options, &option_index)) != EOF ) { while ((opt = getopt_long(
argc,
argv,
"n:rw:d:cmsfST:R:h?u:",
long_options,
&option_index)) != EOF) {
switch (opt) { switch (opt) {
case 'n': case 'n':
result = parse_int(optarg, &register_number); result = parse_int(optarg, &register_number);
@ -552,7 +598,9 @@ int main(int argc, char** argv) {
} }
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
printf("argument error: %s (%d)\n", hackrf_error_name(result), result); printf("argument error: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -576,13 +624,15 @@ int main(int argc, char** argv) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if(!(write || read || dump_config || dump_state || set_tx_limit || set_rx_limit || set_ui)) { if (!(write || read || dump_config || dump_state || set_tx_limit ||
set_rx_limit || set_ui)) {
fprintf(stderr, "Specify read, write, or config option.\n"); fprintf(stderr, "Specify read, write, or config option.\n");
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if(part == PART_NONE && !set_ui && !dump_state && !set_tx_limit && !set_rx_limit) { if (part == PART_NONE && !set_ui && !dump_state && !set_tx_limit &&
!set_rx_limit) {
fprintf(stderr, "Specify a part to read, write, or print config from.\n"); fprintf(stderr, "Specify a part to read, write, or print config from.\n");
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
@ -590,7 +640,9 @@ int main(int argc, char** argv) {
result = hackrf_open_by_serial(serial_number, &device); result = hackrf_open_by_serial(serial_number, &device);
if (result) { if (result) {
printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_open() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -613,7 +665,9 @@ int main(int argc, char** argv) {
if (set_tx_limit) { if (set_tx_limit) {
result = hackrf_set_tx_underrun_limit(device, tx_limit); result = hackrf_set_tx_underrun_limit(device, tx_limit);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
printf("hackrf_set_tx_underrun_limit() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_set_tx_underrun_limit() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
@ -621,7 +675,9 @@ int main(int argc, char** argv) {
if (set_rx_limit) { if (set_rx_limit) {
result = hackrf_set_rx_overrun_limit(device, rx_limit); result = hackrf_set_rx_overrun_limit(device, rx_limit);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
printf("hackrf_set_rx_overrun_limit() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_set_rx_overrun_limit() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
@ -630,7 +686,9 @@ int main(int argc, char** argv) {
hackrf_m0_state state; hackrf_m0_state state;
result = hackrf_get_m0_state(device, &state); result = hackrf_get_m0_state(device, &state);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
printf("hackrf_get_m0_state() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_get_m0_state() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
print_state(&state); print_state(&state);
@ -642,7 +700,9 @@ int main(int argc, char** argv) {
result = hackrf_close(device); result = hackrf_close(device);
if (result) { if (result) {
printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_close() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View File

@ -40,13 +40,16 @@ int main(void)
result = hackrf_init(); result = hackrf_init();
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_init() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_init() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
printf("hackrf_info version: %s\n", TOOL_RELEASE); printf("hackrf_info version: %s\n", TOOL_RELEASE);
printf("libhackrf version: %s (%s)\n", hackrf_library_release(), printf("libhackrf version: %s (%s)\n",
hackrf_library_release(),
hackrf_library_version()); hackrf_library_version());
list = hackrf_device_list(); list = hackrf_device_list();
@ -69,8 +72,10 @@ int main(void)
device = NULL; device = NULL;
result = hackrf_device_list_open(list, i, &device); result = hackrf_device_list_open(list, i, &device);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_open() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_open() failed: %s (%d)\n",
hackrf_error_name(result),
result);
if (result == HACKRF_ERROR_LIBUSB) { if (result == HACKRF_ERROR_LIBUSB) {
continue; continue;
} }
@ -79,33 +84,44 @@ int main(void)
result = hackrf_board_id_read(device, &board_id); result = hackrf_board_id_read(device, &board_id);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_board_id_read() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_board_id_read() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
printf("Board ID Number: %d (%s)\n", board_id, printf("Board ID Number: %d (%s)\n",
board_id,
hackrf_board_id_name(board_id)); hackrf_board_id_name(board_id));
result = hackrf_version_string_read(device, &version[0], 255); result = hackrf_version_string_read(device, &version[0], 255);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_version_string_read() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_version_string_read() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
result = hackrf_usb_api_version_read(device, &usb_version); result = hackrf_usb_api_version_read(device, &usb_version);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_usb_api_version_read() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_usb_api_version_read() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
printf("Firmware Version: %s (API:%x.%02x)\n", version, printf("Firmware Version: %s (API:%x.%02x)\n",
(usb_version>>8)&0xFF, usb_version&0xFF); version,
(usb_version >> 8) & 0xFF,
usb_version & 0xFF);
result = hackrf_board_partid_serialno_read(device, &read_partid_serialno); result = hackrf_board_partid_serialno_read(device, &read_partid_serialno);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_board_partid_serialno_read() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_board_partid_serialno_read() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
printf("Part ID Number: 0x%08x 0x%08x\n", printf("Part ID Number: 0x%08x 0x%08x\n",
@ -113,9 +129,12 @@ int main(void)
read_partid_serialno.part_id[1]); read_partid_serialno.part_id[1]);
result = hackrf_get_operacake_boards(device, &operacakes[0]); result = hackrf_get_operacake_boards(device, &operacakes[0]);
if ((result != HACKRF_SUCCESS) && (result != HACKRF_ERROR_USB_API_VERSION)) { if ((result != HACKRF_SUCCESS) &&
fprintf(stderr, "hackrf_get_operacake_boards() failed: %s (%d)\n", (result != HACKRF_ERROR_USB_API_VERSION)) {
hackrf_error_name(result), result); fprintf(stderr,
"hackrf_get_operacake_boards() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (result == HACKRF_SUCCESS) { if (result == HACKRF_SUCCESS) {
@ -129,9 +148,12 @@ int main(void)
#ifdef HACKRF_ISSUE_609_IS_FIXED #ifdef HACKRF_ISSUE_609_IS_FIXED
uint32_t cpld_crc = 0; uint32_t cpld_crc = 0;
result = hackrf_cpld_checksum(device, &cpld_crc); result = hackrf_cpld_checksum(device, &cpld_crc);
if ((result != HACKRF_SUCCESS) && (result != HACKRF_ERROR_USB_API_VERSION)) { if ((result != HACKRF_SUCCESS) &&
fprintf(stderr, "hackrf_cpld_checksum() failed: %s (%d)\n", (result != HACKRF_ERROR_USB_API_VERSION)) {
hackrf_error_name(result), result); fprintf(stderr,
"hackrf_cpld_checksum() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (result == HACKRF_SUCCESS) { if (result == HACKRF_SUCCESS) {
@ -141,8 +163,10 @@ int main(void)
result = hackrf_close(device); result = hackrf_close(device);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_close() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_close() failed: %s (%d)\n",
hackrf_error_name(result),
result);
} }
} }

View File

@ -41,7 +41,8 @@ typedef int bool;
#define GPIO_TEST_DISABLED 0xFFFF #define GPIO_TEST_DISABLED 0xFFFF
static void usage() { static void usage()
{
printf("\nUsage:\n"); printf("\nUsage:\n");
printf("\t-h, --help: this help\n"); printf("\t-h, --help: this help\n");
printf("\t-d, --device <n>: specify a particular device by serial number\n"); printf("\t-d, --device <n>: specify a particular device by serial number\n");
@ -66,7 +67,8 @@ static struct option long_options[] = {
{0, 0, 0, 0}, {0, 0, 0, 0},
}; };
int parse_uint16(char* const s, uint16_t* const value) { int parse_uint16(char* const s, uint16_t* const value)
{
char* s_end = s; char* s_end = s;
const long long_value = strtol(s, &s_end, 10); const long long_value = strtol(s, &s_end, 10);
if ((s != s_end) && (*s_end == 0)) { if ((s != s_end) && (*s_end == 0)) {
@ -77,7 +79,8 @@ int parse_uint16(char* const s, uint16_t* const value) {
} }
} }
int parse_uint32(char* const s, uint32_t* const value) { int parse_uint32(char* const s, uint32_t* const value)
{
char* s_end = s; char* s_end = s;
const long long_value = strtol(s, &s_end, 10); const long long_value = strtol(s, &s_end, 10);
if ((s != s_end) && (*s_end == 0)) { if ((s != s_end) && (*s_end == 0)) {
@ -88,7 +91,8 @@ int parse_uint32(char* const s, uint32_t* const value) {
} }
} }
int parse_port(char* str, uint8_t* port) { int parse_port(char* str, uint8_t* port)
{
uint16_t tmp_port; uint16_t tmp_port;
int result; int result;
@ -122,7 +126,8 @@ int parse_port(char* str, uint8_t* port) {
return HACKRF_SUCCESS; return HACKRF_SUCCESS;
} }
int parse_range(char* s, hackrf_operacake_freq_range* range) { int parse_range(char* s, hackrf_operacake_freq_range* range)
{
char port[16]; char port[16];
float min; float min;
float max; float max;
@ -141,7 +146,8 @@ int parse_range(char* s, hackrf_operacake_freq_range* range) {
return HACKRF_ERROR_INVALID_PARAM; return HACKRF_ERROR_INVALID_PARAM;
} }
int parse_dwell(char* s, hackrf_operacake_dwell_time* dwell_time) { int parse_dwell(char* s, hackrf_operacake_dwell_time* dwell_time)
{
int result; int result;
char port[16]; char port[16];
float dwell; float dwell;
@ -170,7 +176,8 @@ int parse_dwell(char* s, hackrf_operacake_dwell_time* dwell_time) {
return HACKRF_ERROR_INVALID_PARAM; return HACKRF_ERROR_INVALID_PARAM;
} }
int main(int argc, char** argv) { int main(int argc, char** argv)
{
int opt; int opt;
const char* serial_number = NULL; const char* serial_number = NULL;
uint8_t operacake_address = 0; uint8_t operacake_address = 0;
@ -194,11 +201,18 @@ int main(int argc, char** argv) {
int result = hackrf_init(); int result = hackrf_init();
if (result) { if (result) {
printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_init() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return -1; return -1;
} }
while( (opt = getopt_long(argc, argv, "d:o:a:m:b:lf:t:w:hg?", long_options, &option_index)) != EOF ) { while ((opt = getopt_long(
argc,
argv,
"d:o:a:m:b:lf:t:w:hg?",
long_options,
&option_index)) != EOF) {
switch (opt) { switch (opt) {
case 'd': case 'd':
serial_number = optarg; serial_number = optarg;
@ -325,16 +339,20 @@ int main(int argc, char** argv) {
result = hackrf_open_by_serial(serial_number, &device); result = hackrf_open_by_serial(serial_number, &device);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_open() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_open() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (set_mode) { if (set_mode) {
result = hackrf_set_operacake_mode(device, operacake_address, mode); result = hackrf_set_operacake_mode(device, operacake_address, mode);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_set_operacake_mode() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_set_operacake_mode() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
@ -342,8 +360,10 @@ int main(int argc, char** argv) {
if (list) { if (list) {
result = hackrf_get_operacake_boards(device, operacakes); result = hackrf_get_operacake_boards(device, operacakes);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_get_operacake_boards() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_get_operacake_boards() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
printf("Opera Cakes found: "); printf("Opera Cakes found: ");
@ -373,10 +393,15 @@ int main(int argc, char** argv) {
if (gpio_test) { if (gpio_test) {
uint16_t test_result; uint16_t test_result;
uint8_t reg, mask = 0x7; uint8_t reg, mask = 0x7;
result = hackrf_operacake_gpio_test(device, operacake_address, &test_result); result = hackrf_operacake_gpio_test(
device,
operacake_address,
&test_result);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_operacake_gpio_test() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_operacake_gpio_test() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -387,31 +412,36 @@ int main(int argc, char** argv) {
fprintf(stderr, "GPIO test failed\n"); fprintf(stderr, "GPIO test failed\n");
fprintf(stderr, "Pin\tHigh\tShorts\tLow\n"); fprintf(stderr, "Pin\tHigh\tShorts\tLow\n");
reg = test_result & mask; reg = test_result & mask;
fprintf(stderr, "u2ctrl1\t%d\t%d\t%d\n", fprintf(stderr,
"u2ctrl1\t%d\t%d\t%d\n",
(reg >> 2) & 1, (reg >> 2) & 1,
(reg >> 1) & 1, (reg >> 1) & 1,
reg & 1); reg & 1);
test_result >>= 3; test_result >>= 3;
reg = test_result & mask; reg = test_result & mask;
fprintf(stderr, "u2ctrl0\t%d\t%d\t%d\n", fprintf(stderr,
"u2ctrl0\t%d\t%d\t%d\n",
(reg >> 2) & 1, (reg >> 2) & 1,
(reg >> 1) & 1, (reg >> 1) & 1,
reg & 1); reg & 1);
test_result >>= 3; test_result >>= 3;
reg = test_result & mask; reg = test_result & mask;
fprintf(stderr, "u3ctrl1\t%d\t%d\t%d\n", fprintf(stderr,
"u3ctrl1\t%d\t%d\t%d\n",
(reg >> 2) & 1, (reg >> 2) & 1,
(reg >> 1) & 1, (reg >> 1) & 1,
reg & 1); reg & 1);
test_result >>= 3; test_result >>= 3;
reg = test_result & mask; reg = test_result & mask;
fprintf(stderr, "u3ctrl0\t%d\t%d\t%d\n", fprintf(stderr,
"u3ctrl0\t%d\t%d\t%d\n",
(reg >> 2) & 1, (reg >> 2) & 1,
(reg >> 1) & 1, (reg >> 1) & 1,
reg & 1); reg & 1);
test_result >>= 3; test_result >>= 3;
reg = test_result & mask; reg = test_result & mask;
fprintf(stderr, "u1ctrl \t%d\t%d\t%d\n", fprintf(stderr,
"u1ctrl \t%d\t%d\t%d\n",
(reg >> 2) & 1, (reg >> 2) & 1,
(reg >> 1) & 1, (reg >> 1) & 1,
reg & 1); reg & 1);
@ -436,13 +466,21 @@ int main(int argc, char** argv) {
port_b = 4; port_b = 4;
} }
} }
if(((port_a<=3) && (port_b<=3)) || ((port_a>=4) && (port_b>=4))) { if (((port_a <= 3) && (port_b <= 3)) ||
fprintf(stderr, "Port A and B cannot be connected to the same side\n"); ((port_a >= 4) && (port_b >= 4))) {
fprintf(stderr,
"Port A and B cannot be connected to the same side\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
result = hackrf_set_operacake_ports(device, operacake_address, port_a, port_b); result = hackrf_set_operacake_ports(
device,
operacake_address,
port_a,
port_b);
if (result) { if (result) {
printf("hackrf_set_operacake_ports() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_set_operacake_ports() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
@ -450,7 +488,9 @@ int main(int argc, char** argv) {
if (range_idx) { if (range_idx) {
result = hackrf_set_operacake_freq_ranges(device, ranges, range_idx); result = hackrf_set_operacake_freq_ranges(device, ranges, range_idx);
if (result) { if (result) {
printf("hackrf_set_operacake_freq_ranges() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_set_operacake_freq_ranges() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return -1; return -1;
} }
} }
@ -459,7 +499,8 @@ int main(int argc, char** argv) {
for (i = 0; i < dwell_idx; i++) { for (i = 0; i < dwell_idx; i++) {
if (dwell_times[i].dwell == 0) { if (dwell_times[i].dwell == 0) {
if (default_dwell == 0) { if (default_dwell == 0) {
fprintf(stderr, "port '%u' set to use default dwell time, but default dwell time is not set. Use -w argument to set default dwell time.\n", fprintf(stderr,
"port '%u' set to use default dwell time, but default dwell time is not set. Use -w argument to set default dwell time.\n",
dwell_times[i].port); dwell_times[i].port);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -468,14 +509,18 @@ int main(int argc, char** argv) {
} }
result = hackrf_set_operacake_dwell_times(device, dwell_times, dwell_idx); result = hackrf_set_operacake_dwell_times(device, dwell_times, dwell_idx);
if (result) { if (result) {
printf("hackrf_set_operacake_dwell_times() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_set_operacake_dwell_times() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return -1; return -1;
} }
} }
result = hackrf_close(device); result = hackrf_close(device);
if (result) { if (result) {
printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_close() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return -1; return -1;
} }
hackrf_exit(); hackrf_exit();

View File

@ -73,8 +73,7 @@ int compatibility_check(uint8_t* data, int length, hackrf_device* device)
uint8_t board_id; uint8_t board_id;
char* dev_str; char* dev_str;
hackrf_board_id_read(device, &board_id); hackrf_board_id_read(device, &board_id);
switch(board_id) switch (board_id) {
{
case BOARD_ID_JAWBREAKER: case BOARD_ID_JAWBREAKER:
dev_str = "HackRF Jawbreaker"; dev_str = "HackRF Jawbreaker";
str_len = 17; str_len = 17;
@ -178,7 +177,11 @@ int main(int argc, char** argv)
bool clear_status = false; bool clear_status = false;
uint16_t usb_api; uint16_t usb_api;
while ((opt = getopt_long(argc, argv, "a:l:r:w:id:scvRh?", long_options, while ((opt = getopt_long(
argc,
argv,
"a:l:r:w:id:scvRh?",
long_options,
&option_index)) != EOF) { &option_index)) != EOF) {
switch (opt) { switch (opt) {
case 'a': case 'a':
@ -235,8 +238,10 @@ int main(int argc, char** argv)
} }
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "argument error: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "argument error: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -254,16 +259,16 @@ int main(int argc, char** argv)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if( write ) if (write) {
{
infile = fopen(path, "rb"); infile = fopen(path, "rb");
if(infile == NULL) if (infile == NULL) {
{
printf("Error opening file %s\n", path); printf("Error opening file %s\n", path);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* Get size of the file */ /* Get size of the file */
fseek(infile, 0, SEEK_END); /* Not really portable but work on major OS Linux/Win32 */ fseek(infile,
0,
SEEK_END); /* Not really portable but work on major OS Linux/Win32 */
length = ftell(infile); length = ftell(infile);
/* Move to start */ /* Move to start */
rewind(infile); rewind(infile);
@ -278,8 +283,8 @@ int main(int argc, char** argv)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if ((length > MAX_LENGTH) || (address > MAX_LENGTH) if ((length > MAX_LENGTH) || (address > MAX_LENGTH) ||
|| ((address + length) > MAX_LENGTH)) { ((address + length) > MAX_LENGTH)) {
fprintf(stderr, "Request exceeds size of flash memory.\n"); fprintf(stderr, "Request exceeds size of flash memory.\n");
if (infile != NULL) if (infile != NULL)
fclose(infile); fclose(infile);
@ -289,8 +294,7 @@ int main(int argc, char** argv)
if (read) { if (read) {
infile = fopen(path, "wb"); infile = fopen(path, "wb");
if(infile == NULL) if (infile == NULL) {
{
printf("Error to open file %s\n", path); printf("Error to open file %s\n", path);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -298,23 +302,29 @@ int main(int argc, char** argv)
result = hackrf_init(); result = hackrf_init();
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_init() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_init() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
result = hackrf_open_by_serial(serial_number, &device); result = hackrf_open_by_serial(serial_number, &device);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_open() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_open() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (read_status) { if (read_status) {
result = hackrf_spiflash_status(device, status); result = hackrf_spiflash_status(device, status);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_spiflash_status() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_spiflash_status() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (!verbose) { if (!verbose) {
@ -340,8 +350,10 @@ int main(int argc, char** argv)
if (clear_status) { if (clear_status) {
result = hackrf_spiflash_clear_status(device); result = hackrf_spiflash_clear_status(device);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_spiflash_clear_status() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_spiflash_clear_status() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
@ -349,14 +361,18 @@ int main(int argc, char** argv)
if (read) { if (read) {
ssize_t bytes_written; ssize_t bytes_written;
tmp_length = length; tmp_length = length;
while (tmp_length) while (tmp_length) {
{
xfer_len = (tmp_length > 256) ? 256 : tmp_length; xfer_len = (tmp_length > 256) ? 256 : tmp_length;
if( verbose ) printf("Reading %d bytes from 0x%06x.\n", xfer_len, address); if (verbose)
printf("Reading %d bytes from 0x%06x.\n",
xfer_len,
address);
result = hackrf_spiflash_read(device, address, xfer_len, pdata); result = hackrf_spiflash_read(device, address, xfer_len, pdata);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_spiflash_read() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_spiflash_read() failed: %s (%d)\n",
hackrf_error_name(result),
result);
fclose(infile); fclose(infile);
infile = NULL; infile = NULL;
return EXIT_FAILURE; return EXIT_FAILURE;
@ -367,7 +383,8 @@ int main(int argc, char** argv)
} }
bytes_written = fwrite(data, 1, length, infile); bytes_written = fwrite(data, 1, length, infile);
if (bytes_written != length) { if (bytes_written != length) {
fprintf(stderr, "Failed write to file (wrote %d bytes).\n", fprintf(stderr,
"Failed write to file (wrote %d bytes).\n",
(int) bytes_written); (int) bytes_written);
fclose(infile); fclose(infile);
infile = NULL; infile = NULL;
@ -378,7 +395,8 @@ int main(int argc, char** argv)
if (write) { if (write) {
ssize_t bytes_read = fread(data, 1, length, infile); ssize_t bytes_read = fread(data, 1, length, infile);
if (bytes_read != length) { if (bytes_read != length) {
fprintf(stderr, "Failed read file (read %d bytes).\n", fprintf(stderr,
"Failed read file (read %d bytes).\n",
(int) bytes_read); (int) bytes_read);
fclose(infile); fclose(infile);
infile = NULL; infile = NULL;
@ -397,20 +415,28 @@ int main(int argc, char** argv)
printf("Erasing SPI flash.\n"); printf("Erasing SPI flash.\n");
result = hackrf_spiflash_erase(device); result = hackrf_spiflash_erase(device);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_spiflash_erase() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_spiflash_erase() failed: %s (%d)\n",
hackrf_error_name(result),
result);
fclose(infile); fclose(infile);
infile = NULL; infile = NULL;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if( !verbose ) printf("Writing %d bytes at 0x%06x.\n", length, address); if (!verbose)
printf("Writing %d bytes at 0x%06x.\n", length, address);
while (length) { while (length) {
xfer_len = (length > 256) ? 256 : length; xfer_len = (length > 256) ? 256 : length;
if( verbose ) printf("Writing %d bytes at 0x%06x.\n", xfer_len, address); if (verbose)
printf("Writing %d bytes at 0x%06x.\n",
xfer_len,
address);
result = hackrf_spiflash_write(device, address, xfer_len, pdata); result = hackrf_spiflash_write(device, address, xfer_len, pdata);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_spiflash_write() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_spiflash_write() failed: %s (%d)\n",
hackrf_error_name(result),
result);
fclose(infile); fclose(infile);
infile = NULL; infile = NULL;
return EXIT_FAILURE; return EXIT_FAILURE;
@ -431,11 +457,15 @@ int main(int argc, char** argv)
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
if (result == HACKRF_ERROR_USB_API_VERSION) { if (result == HACKRF_ERROR_USB_API_VERSION) {
hackrf_usb_api_version_read(device, &usb_api); hackrf_usb_api_version_read(device, &usb_api);
fprintf(stderr, "Reset is not supported by firmware API %x.%02x\n", fprintf(stderr,
(usb_api>>8)&0xFF, usb_api&0xFF); "Reset is not supported by firmware API %x.%02x\n",
(usb_api >> 8) & 0xFF,
usb_api & 0xFF);
} else { } else {
fprintf(stderr, "hackrf_reset() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_reset() failed: %s (%d)\n",
hackrf_error_name(result),
result);
} }
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -443,8 +473,10 @@ int main(int argc, char** argv)
result = hackrf_close(device); result = hackrf_close(device);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_close() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_close() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View File

@ -58,7 +58,8 @@ typedef int32_t ssize_t;
#define strtoull _strtoui64 #define strtoull _strtoui64
#define snprintf _snprintf #define snprintf _snprintf
int gettimeofday(struct timeval *tv, void* ignored) { int gettimeofday(struct timeval* tv, void* ignored)
{
FILETIME ft; FILETIME ft;
unsigned __int64 tmp = 0; unsigned __int64 tmp = 0;
if (NULL != tv) { if (NULL != tv) {
@ -112,11 +113,13 @@ int num_ranges = 0;
uint16_t frequencies[MAX_SWEEP_RANGES * 2]; uint16_t frequencies[MAX_SWEEP_RANGES * 2];
int step_count; int step_count;
static float TimevalDiff(const struct timeval *a, const struct timeval *b) { static float TimevalDiff(const struct timeval* a, const struct timeval* b)
{
return (a->tv_sec - b->tv_sec) + 1e-6f * (a->tv_usec - b->tv_usec); return (a->tv_sec - b->tv_sec) + 1e-6f * (a->tv_usec - b->tv_usec);
} }
int parse_u32(char* s, uint32_t* const value) { int parse_u32(char* s, uint32_t* const value)
{
uint_fast8_t base = 10; uint_fast8_t base = 10;
char* s_end; char* s_end;
uint64_t ulong_value; uint64_t ulong_value;
@ -143,7 +146,8 @@ int parse_u32(char* s, uint32_t* const value) {
} }
} }
int parse_u32_range(char* s, uint32_t* const value_min, uint32_t* const value_max) { int parse_u32_range(char* s, uint32_t* const value_min, uint32_t* const value_max)
{
int result; int result;
char* sep = strchr(s, ':'); char* sep = strchr(s, ':');
@ -203,7 +207,8 @@ float logPower(fftwf_complex in, float scale)
return (float) (log2(magsq) * 10.0f / log2(10.0f)); return (float) (log2(magsq) * 10.0f / log2(10.0f));
} }
int rx_callback(hackrf_transfer* transfer) { int rx_callback(hackrf_transfer* transfer)
{
int8_t* buf; int8_t* buf;
uint8_t* ubuf; uint8_t* ubuf;
uint64_t frequency; /* in Hz */ uint64_t frequency; /* in Hz */
@ -228,9 +233,13 @@ int rx_callback(hackrf_transfer* transfer) {
for (j = 0; j < BLOCKS_PER_TRANSFER; j++) { for (j = 0; j < BLOCKS_PER_TRANSFER; j++) {
ubuf = (uint8_t*) buf; ubuf = (uint8_t*) buf;
if (ubuf[0] == 0x7F && ubuf[1] == 0x7F) { if (ubuf[0] == 0x7F && ubuf[1] == 0x7F) {
frequency = ((uint64_t)(ubuf[9]) << 56) | ((uint64_t)(ubuf[8]) << 48) | ((uint64_t)(ubuf[7]) << 40) frequency = ((uint64_t) (ubuf[9]) << 56) |
| ((uint64_t)(ubuf[6]) << 32) | ((uint64_t)(ubuf[5]) << 24) | ((uint64_t)(ubuf[4]) << 16) ((uint64_t) (ubuf[8]) << 48) |
| ((uint64_t)(ubuf[3]) << 8) | ubuf[2]; ((uint64_t) (ubuf[7]) << 40) |
((uint64_t) (ubuf[6]) << 32) |
((uint64_t) (ubuf[5]) << 24) |
((uint64_t) (ubuf[4]) << 16) |
((uint64_t) (ubuf[3]) << 8) | ubuf[2];
} else { } else {
buf += BYTES_PER_BLOCK; buf += BYTES_PER_BLOCK;
continue; continue;
@ -242,15 +251,20 @@ int rx_callback(hackrf_transfer* transfer) {
for (i = 0; i < ifft_bins; i++) { for (i = 0; i < ifft_bins; i++) {
ifftwOut[i][0] *= 1.0f / ifft_bins; ifftwOut[i][0] *= 1.0f / ifft_bins;
ifftwOut[i][1] *= 1.0f / ifft_bins; ifftwOut[i][1] *= 1.0f / ifft_bins;
fwrite(&ifftwOut[i][0], sizeof(float), 1, outfile); fwrite(&ifftwOut[i][0],
fwrite(&ifftwOut[i][1], sizeof(float), 1, outfile); sizeof(float),
1,
outfile);
fwrite(&ifftwOut[i][1],
sizeof(float),
1,
outfile);
} }
} }
sweep_count++; sweep_count++;
if (one_shot) { if (one_shot) {
do_exit = true; do_exit = true;
} } else if (finite_mode && sweep_count == num_sweeps) {
else if(finite_mode && sweep_count == num_sweeps) {
do_exit = true; do_exit = true;
} }
} }
@ -279,15 +293,18 @@ int rx_callback(hackrf_transfer* transfer) {
pwr[i] = logPower(fftwOut[i], 1.0f / fftSize); pwr[i] = logPower(fftwOut[i], 1.0f / fftSize);
} }
if (binary_output) { if (binary_output) {
record_length = 2 * sizeof(band_edge) record_length =
+ (fftSize/4) * sizeof(float); 2 * sizeof(band_edge) + (fftSize / 4) * sizeof(float);
fwrite(&record_length, sizeof(record_length), 1, outfile); fwrite(&record_length, sizeof(record_length), 1, outfile);
band_edge = frequency; band_edge = frequency;
fwrite(&band_edge, sizeof(band_edge), 1, outfile); fwrite(&band_edge, sizeof(band_edge), 1, outfile);
band_edge = frequency + DEFAULT_SAMPLE_RATE_HZ / 4; band_edge = frequency + DEFAULT_SAMPLE_RATE_HZ / 4;
fwrite(&band_edge, sizeof(band_edge), 1, outfile); fwrite(&band_edge, sizeof(band_edge), 1, outfile);
fwrite(&pwr[1+(fftSize*5)/8], sizeof(float), fftSize/4, outfile); fwrite(&pwr[1 + (fftSize * 5) / 8],
sizeof(float),
fftSize / 4,
outfile);
fwrite(&record_length, sizeof(record_length), 1, outfile); fwrite(&record_length, sizeof(record_length), 1, outfile);
band_edge = frequency + DEFAULT_SAMPLE_RATE_HZ / 2; band_edge = frequency + DEFAULT_SAMPLE_RATE_HZ / 2;
@ -296,24 +313,30 @@ int rx_callback(hackrf_transfer* transfer) {
fwrite(&band_edge, sizeof(band_edge), 1, outfile); fwrite(&band_edge, sizeof(band_edge), 1, outfile);
fwrite(&pwr[1 + fftSize / 8], sizeof(float), fftSize / 4, outfile); fwrite(&pwr[1 + fftSize / 8], sizeof(float), fftSize / 4, outfile);
} else if (ifft_output) { } else if (ifft_output) {
ifft_idx = (uint32_t) round((frequency - (uint64_t)(FREQ_ONE_MHZ*frequencies[0])) ifft_idx = (uint32_t) round(
/ fft_bin_width); (frequency - (uint64_t) (FREQ_ONE_MHZ * frequencies[0])) /
fft_bin_width);
ifft_idx = (ifft_idx + ifft_bins / 2) % ifft_bins; ifft_idx = (ifft_idx + ifft_bins / 2) % ifft_bins;
for (i = 0; (fftSize / 4) > i; i++) { for (i = 0; (fftSize / 4) > i; i++) {
ifftwIn[ifft_idx + i][0] = fftwOut[i + 1 + (fftSize*5)/8][0]; ifftwIn[ifft_idx + i][0] =
ifftwIn[ifft_idx + i][1] = fftwOut[i + 1 + (fftSize*5)/8][1]; fftwOut[i + 1 + (fftSize * 5) / 8][0];
ifftwIn[ifft_idx + i][1] =
fftwOut[i + 1 + (fftSize * 5) / 8][1];
} }
ifft_idx += fftSize / 2; ifft_idx += fftSize / 2;
ifft_idx %= ifft_bins; ifft_idx %= ifft_bins;
for (i = 0; (fftSize / 4) > i; i++) { for (i = 0; (fftSize / 4) > i; i++) {
ifftwIn[ifft_idx + i][0] = fftwOut[i + 1 + (fftSize/8)][0]; ifftwIn[ifft_idx + i][0] =
ifftwIn[ifft_idx + i][1] = fftwOut[i + 1 + (fftSize/8)][1]; fftwOut[i + 1 + (fftSize / 8)][0];
ifftwIn[ifft_idx + i][1] =
fftwOut[i + 1 + (fftSize / 8)][1];
} }
} else { } else {
time_t time_stamp_seconds = usb_transfer_time.tv_sec; time_t time_stamp_seconds = usb_transfer_time.tv_sec;
fft_time = localtime(&time_stamp_seconds); fft_time = localtime(&time_stamp_seconds);
strftime(time_str, 50, "%Y-%m-%d, %H:%M:%S", fft_time); strftime(time_str, 50, "%Y-%m-%d, %H:%M:%S", fft_time);
fprintf(outfile, "%s.%06ld, %" PRIu64 ", %" PRIu64 ", %.2f, %u", fprintf(outfile,
"%s.%06ld, %" PRIu64 ", %" PRIu64 ", %.2f, %u",
time_str, time_str,
(long int) usb_transfer_time.tv_usec, (long int) usb_transfer_time.tv_usec,
(uint64_t) (frequency), (uint64_t) (frequency),
@ -321,10 +344,13 @@ int rx_callback(hackrf_transfer* transfer) {
fft_bin_width, fft_bin_width,
fftSize); fftSize);
for (i = 0; (fftSize / 4) > i; i++) { for (i = 0; (fftSize / 4) > i; i++) {
fprintf(outfile, ", %.2f", pwr[i + 1 + (fftSize*5)/8]); fprintf(outfile,
", %.2f",
pwr[i + 1 + (fftSize * 5) / 8]);
} }
fprintf(outfile, "\n"); fprintf(outfile, "\n");
fprintf(outfile, "%s.%06ld, %" PRIu64 ", %" PRIu64 ", %.2f, %u", fprintf(outfile,
"%s.%06ld, %" PRIu64 ", %" PRIu64 ", %.2f, %u",
time_str, time_str,
(long int) usb_transfer_time.tv_usec, (long int) usb_transfer_time.tv_usec,
(uint64_t) (frequency + (DEFAULT_SAMPLE_RATE_HZ / 2)), (uint64_t) (frequency + (DEFAULT_SAMPLE_RATE_HZ / 2)),
@ -340,16 +366,20 @@ int rx_callback(hackrf_transfer* transfer) {
return 0; return 0;
} }
static void usage() { static void usage()
{
fprintf(stderr, "Usage:\n"); fprintf(stderr, "Usage:\n");
fprintf(stderr, "\t[-h] # this help\n"); fprintf(stderr, "\t[-h] # this help\n");
fprintf(stderr, "\t[-d serial_number] # Serial number of desired HackRF\n"); fprintf(stderr, "\t[-d serial_number] # Serial number of desired HackRF\n");
fprintf(stderr, "\t[-a amp_enable] # RX RF amplifier 1=Enable, 0=Disable\n"); fprintf(stderr, "\t[-a amp_enable] # RX RF amplifier 1=Enable, 0=Disable\n");
fprintf(stderr, "\t[-f freq_min:freq_max] # minimum and maximum frequencies in MHz\n"); fprintf(stderr,
fprintf(stderr, "\t[-p antenna_enable] # Antenna port power, 1=Enable, 0=Disable\n"); "\t[-f freq_min:freq_max] # minimum and maximum frequencies in MHz\n");
fprintf(stderr,
"\t[-p antenna_enable] # Antenna port power, 1=Enable, 0=Disable\n");
fprintf(stderr, "\t[-l gain_db] # RX LNA (IF) gain, 0-40dB, 8dB steps\n"); fprintf(stderr, "\t[-l gain_db] # RX LNA (IF) gain, 0-40dB, 8dB steps\n");
fprintf(stderr, "\t[-g gain_db] # RX VGA (baseband) gain, 0-62dB, 2dB steps\n"); fprintf(stderr, "\t[-g gain_db] # RX VGA (baseband) gain, 0-62dB, 2dB steps\n");
fprintf(stderr, "\t[-w bin_width] # FFT bin width (frequency resolution) in Hz, 2445-5000000\n"); fprintf(stderr,
"\t[-w bin_width] # FFT bin width (frequency resolution) in Hz, 2445-5000000\n");
fprintf(stderr, "\t[-1] # one shot mode\n"); fprintf(stderr, "\t[-1] # one shot mode\n");
fprintf(stderr, "\t[-N num_sweeps] # Number of sweeps to perform\n"); fprintf(stderr, "\t[-N num_sweeps] # Number of sweeps to perform\n");
fprintf(stderr, "\t[-B] # binary output\n"); fprintf(stderr, "\t[-B] # binary output\n");
@ -357,14 +387,15 @@ static void usage() {
fprintf(stderr, "\t-r filename # output file\n"); fprintf(stderr, "\t-r filename # output file\n");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, "Output fields:\n"); fprintf(stderr, "Output fields:\n");
fprintf(stderr, "\tdate, time, hz_low, hz_high, hz_bin_width, num_samples, dB, dB, . . .\n"); fprintf(stderr,
"\tdate, time, hz_low, hz_high, hz_bin_width, num_samples, dB, dB, . . .\n");
} }
static hackrf_device* device = NULL; static hackrf_device* device = NULL;
#ifdef _MSC_VER #ifdef _MSC_VER
BOOL WINAPI BOOL WINAPI sighandler(int signum)
sighandler(int signum) { {
if (CTRL_C_EVENT == signum) { if (CTRL_C_EVENT == signum) {
fprintf(stderr, "Caught signal %d\n", signum); fprintf(stderr, "Caught signal %d\n", signum);
do_exit = true; do_exit = true;
@ -373,13 +404,15 @@ sighandler(int signum) {
return FALSE; return FALSE;
} }
#else #else
void sigint_callback_handler(int signum) { void sigint_callback_handler(int signum)
{
fprintf(stderr, "Caught signal %d\n", signum); fprintf(stderr, "Caught signal %d\n", signum);
do_exit = true; do_exit = true;
} }
#endif #endif
int main(int argc, char** argv) { int main(int argc, char** argv)
{
int opt, i, result = 0; int opt, i, result = 0;
const char* path = NULL; const char* path = NULL;
const char* serial_number = NULL; const char* serial_number = NULL;
@ -393,11 +426,9 @@ int main(int argc, char** argv) {
uint32_t freq_max = 6000; uint32_t freq_max = 6000;
uint32_t requested_fft_bin_width; uint32_t requested_fft_bin_width;
while ((opt = getopt(argc, argv, "a:f:p:l:g:d:n:N:w:1BIr:h?")) != EOF) { while ((opt = getopt(argc, argv, "a:f:p:l:g:d:n:N:w:1BIr:h?")) != EOF) {
result = HACKRF_SUCCESS; result = HACKRF_SUCCESS;
switch( opt ) switch (opt) {
{
case 'd': case 'd':
serial_number = optarg; serial_number = optarg;
break; break;
@ -485,7 +516,12 @@ int main(int argc, char** argv) {
} }
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "argument error: '-%c %s' %s (%d)\n", opt, optarg, hackrf_error_name(result), result); fprintf(stderr,
"argument error: '-%c %s' %s (%d)\n",
opt,
optarg,
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -507,7 +543,8 @@ int main(int argc, char** argv) {
if (antenna) { if (antenna) {
if (antenna_enable > 1) { if (antenna_enable > 1) {
fprintf(stderr, "argument error: antenna_enable shall be 0 or 1.\n"); fprintf(stderr,
"argument error: antenna_enable shall be 0 or 1.\n");
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -520,12 +557,14 @@ int main(int argc, char** argv) {
} }
if (binary_output && ifft_output) { if (binary_output && ifft_output) {
fprintf(stderr, "argument error: binary output (-B) and IFFT output (-I) are mutually exclusive.\n"); fprintf(stderr,
"argument error: binary output (-B) and IFFT output (-I) are mutually exclusive.\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (ifft_output && (1 < num_ranges)) { if (ifft_output && (1 < num_ranges)) {
fprintf(stderr, "argument error: only one frequency range is supported in IFFT output (-I) mode.\n"); fprintf(stderr,
"argument error: only one frequency range is supported in IFFT output (-I) mode.\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -565,7 +604,8 @@ int main(int argc, char** argv) {
fft_bin_width = (double) DEFAULT_SAMPLE_RATE_HZ / fftSize; fft_bin_width = (double) DEFAULT_SAMPLE_RATE_HZ / fftSize;
fftwIn = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize); fftwIn = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize);
fftwOut = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize); fftwOut = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize);
fftwPlan = fftwf_plan_dft_1d(fftSize, fftwIn, fftwOut, FFTW_FORWARD, FFTW_MEASURE); fftwPlan =
fftwf_plan_dft_1d(fftSize, fftwIn, fftwOut, FFTW_FORWARD, FFTW_MEASURE);
pwr = (float*) fftwf_malloc(sizeof(float) * fftSize); pwr = (float*) fftwf_malloc(sizeof(float) * fftSize);
window = (float*) fftwf_malloc(sizeof(float) * fftSize); window = (float*) fftwf_malloc(sizeof(float) * fftSize);
for (i = 0; i < fftSize; i++) { for (i = 0; i < fftSize; i++) {
@ -580,14 +620,20 @@ int main(int argc, char** argv) {
result = hackrf_init(); result = hackrf_init();
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"hackrf_init() failed: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
result = hackrf_open_by_serial(serial_number, &device); result = hackrf_open_by_serial(serial_number, &device);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"hackrf_open() failed: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -620,22 +666,30 @@ int main(int argc, char** argv) {
signal(SIGTERM, &sigint_callback_handler); signal(SIGTERM, &sigint_callback_handler);
signal(SIGABRT, &sigint_callback_handler); signal(SIGABRT, &sigint_callback_handler);
#endif #endif
fprintf(stderr, "call hackrf_sample_rate_set(%.03f MHz)\n", fprintf(stderr,
"call hackrf_sample_rate_set(%.03f MHz)\n",
((float) DEFAULT_SAMPLE_RATE_HZ / (float) FREQ_ONE_MHZ)); ((float) DEFAULT_SAMPLE_RATE_HZ / (float) FREQ_ONE_MHZ));
result = hackrf_set_sample_rate_manual(device, DEFAULT_SAMPLE_RATE_HZ, 1); result = hackrf_set_sample_rate_manual(device, DEFAULT_SAMPLE_RATE_HZ, 1);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_sample_rate_set() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_sample_rate_set() failed: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
fprintf(stderr, "call hackrf_baseband_filter_bandwidth_set(%.03f MHz)\n", fprintf(stderr,
"call hackrf_baseband_filter_bandwidth_set(%.03f MHz)\n",
((float) DEFAULT_BASEBAND_FILTER_BANDWIDTH / (float) FREQ_ONE_MHZ)); ((float) DEFAULT_BASEBAND_FILTER_BANDWIDTH / (float) FREQ_ONE_MHZ));
result = hackrf_set_baseband_filter_bandwidth(device, DEFAULT_BASEBAND_FILTER_BANDWIDTH); result = hackrf_set_baseband_filter_bandwidth(
device,
DEFAULT_BASEBAND_FILTER_BANDWIDTH);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_baseband_filter_bandwidth_set() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_baseband_filter_bandwidth_set() failed: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -649,30 +703,51 @@ int main(int argc, char** argv) {
* whole number of steps, minimum 1. * whole number of steps, minimum 1.
*/ */
for (i = 0; i < num_ranges; i++) { for (i = 0; i < num_ranges; i++) {
step_count = 1 + (frequencies[2*i+1] - frequencies[2*i] - 1) step_count =
/ TUNE_STEP; 1 + (frequencies[2 * i + 1] - frequencies[2 * i] - 1) / TUNE_STEP;
frequencies[2*i+1] = (uint16_t) (frequencies[2*i] + step_count * TUNE_STEP); frequencies[2 * i + 1] =
fprintf(stderr, "Sweeping from %u MHz to %u MHz\n", (uint16_t) (frequencies[2 * i] + step_count * TUNE_STEP);
frequencies[2*i], frequencies[2*i+1]); fprintf(stderr,
"Sweeping from %u MHz to %u MHz\n",
frequencies[2 * i],
frequencies[2 * i + 1]);
} }
if (ifft_output) { if (ifft_output) {
ifftwIn = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize * step_count); ifftwIn = (fftwf_complex*) fftwf_malloc(
ifftwOut = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize * step_count); sizeof(fftwf_complex) * fftSize * step_count);
ifftwPlan = fftwf_plan_dft_1d(fftSize * step_count, ifftwIn, ifftwOut, FFTW_BACKWARD, FFTW_MEASURE); ifftwOut = (fftwf_complex*) fftwf_malloc(
sizeof(fftwf_complex) * fftSize * step_count);
ifftwPlan = fftwf_plan_dft_1d(
fftSize * step_count,
ifftwIn,
ifftwOut,
FFTW_BACKWARD,
FFTW_MEASURE);
} }
result = hackrf_init_sweep(device, frequencies, num_ranges, BYTES_PER_BLOCK, result = hackrf_init_sweep(
TUNE_STEP * FREQ_ONE_MHZ, OFFSET, INTERLEAVED); device,
frequencies,
num_ranges,
BYTES_PER_BLOCK,
TUNE_STEP * FREQ_ONE_MHZ,
OFFSET,
INTERLEAVED);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_init_sweep() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_init_sweep() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
result |= hackrf_start_rx_sweep(device, rx_callback, NULL); result |= hackrf_start_rx_sweep(device, rx_callback, NULL);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_start_rx_sweep() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"hackrf_start_rx_sweep() failed: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -681,8 +756,10 @@ int main(int argc, char** argv) {
fprintf(stderr, "call hackrf_set_amp_enable(%u)\n", amp_enable); fprintf(stderr, "call hackrf_set_amp_enable(%u)\n", amp_enable);
result = hackrf_set_amp_enable(device, (uint8_t) amp_enable); result = hackrf_set_amp_enable(device, (uint8_t) amp_enable);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_set_amp_enable() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_set_amp_enable() failed: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -692,8 +769,10 @@ int main(int argc, char** argv) {
fprintf(stderr, "call hackrf_set_antenna_enable(%u)\n", antenna_enable); fprintf(stderr, "call hackrf_set_antenna_enable(%u)\n", antenna_enable);
result = hackrf_set_antenna_enable(device, (uint8_t) antenna_enable); result = hackrf_set_antenna_enable(device, (uint8_t) antenna_enable);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_set_antenna_enable() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_set_antenna_enable() failed: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -711,12 +790,16 @@ int main(int argc, char** argv) {
if (TimevalDiff(&time_now, &time_prev) >= 1.0f) { if (TimevalDiff(&time_now, &time_prev) >= 1.0f) {
time_difference = TimevalDiff(&time_now, &t_start); time_difference = TimevalDiff(&time_now, &t_start);
sweep_rate = (float) sweep_count / time_difference; sweep_rate = (float) sweep_count / time_difference;
fprintf(stderr, "%" PRIu64 " total sweeps completed, %.2f sweeps/second\n", fprintf(stderr,
sweep_count, sweep_rate); "%" PRIu64
" total sweeps completed, %.2f sweeps/second\n",
sweep_count,
sweep_rate);
if (byte_count == 0) { if (byte_count == 0) {
exit_code = EXIT_FAILURE; exit_code = EXIT_FAILURE;
fprintf(stderr, "\nCouldn't transfer any data for one second.\n"); fprintf(stderr,
"\nCouldn't transfer any data for one second.\n");
break; break;
} }
byte_count = 0; byte_count = 0;
@ -729,22 +812,29 @@ int main(int argc, char** argv) {
if (do_exit) { if (do_exit) {
fprintf(stderr, "\nExiting...\n"); fprintf(stderr, "\nExiting...\n");
} else { } else {
fprintf(stderr, "\nExiting... hackrf_is_streaming() result: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "\nExiting... hackrf_is_streaming() result: %s (%d)\n",
hackrf_error_name(result),
result);
} }
gettimeofday(&time_now, NULL); gettimeofday(&time_now, NULL);
time_diff = TimevalDiff(&time_now, &t_start); time_diff = TimevalDiff(&time_now, &t_start);
if ((sweep_rate == 0) && (time_diff > 0)) if ((sweep_rate == 0) && (time_diff > 0))
sweep_rate = sweep_count / time_diff; sweep_rate = sweep_count / time_diff;
fprintf(stderr, "Total sweeps: %" PRIu64 " in %.5f seconds (%.2f sweeps/second)\n", fprintf(stderr,
sweep_count, time_diff, sweep_rate); "Total sweeps: %" PRIu64 " in %.5f seconds (%.2f sweeps/second)\n",
sweep_count,
time_diff,
sweep_rate);
if (device != NULL) { if (device != NULL) {
result = hackrf_close(device); result = hackrf_close(device);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_close() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_close() failed: %s (%d)\n",
hackrf_error_name(result),
result);
} else { } else {
fprintf(stderr, "hackrf_close() done\n"); fprintf(stderr, "hackrf_close() done\n");
} }

View File

@ -128,14 +128,14 @@ typedef struct {
} stats_t; } stats_t;
/* WAVE or RIFF WAVE file format containing IQ 2x8bits data for HackRF compatible with SDR# Wav IQ file */ /* WAVE or RIFF WAVE file format containing IQ 2x8bits data for HackRF compatible with SDR# Wav IQ file */
typedef struct typedef struct {
{
char groupID[4]; /* 'RIFF' */ char groupID[4]; /* 'RIFF' */
uint32_t size; /* File size + 8bytes */ uint32_t size; /* File size + 8bytes */
char riffType[4]; /* 'WAVE'*/ char riffType[4]; /* 'WAVE'*/
} t_WAVRIFF_hdr; } t_WAVRIFF_hdr;
#define FormatID "fmt " /* chunkID for Format Chunk. NOTE: There is a space at the end of this ID. */ #define FormatID \
"fmt " /* chunkID for Format Chunk. NOTE: There is a space at the end of this ID. */
typedef struct { typedef struct {
char chunkID[4]; /* 'fmt ' */ char chunkID[4]; /* 'fmt ' */
@ -163,12 +163,10 @@ typedef struct {
t_wav_file_hdr wave_file_hdr = { t_wav_file_hdr wave_file_hdr = {
/* t_WAVRIFF_hdr */ /* t_WAVRIFF_hdr */
{ {/* groupID */
/* groupID */
{'R', 'I', 'F', 'F'}, {'R', 'I', 'F', 'F'},
0, /* size to update later */ 0, /* size to update later */
{ 'W', 'A', 'V', 'E' } {'W', 'A', 'V', 'E'}},
},
/* t_FormatChunk */ /* t_FormatChunk */
{ {
/* char chunkID[4]; */ /* char chunkID[4]; */
@ -186,27 +184,26 @@ t_wav_file_hdr wave_file_hdr = {
/* char chunkID[4]; */ /* char chunkID[4]; */
{'d', 'a', 't', 'a'}, {'d', 'a', 't', 'a'},
0, /* uint32_t chunkSize; to update later */ 0, /* uint32_t chunkSize; to update later */
} }};
};
static transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_RX; static transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_RX;
#define U64TOA_MAX_DIGIT (31) #define U64TOA_MAX_DIGIT (31)
typedef struct
{ typedef struct {
char data[U64TOA_MAX_DIGIT + 1]; char data[U64TOA_MAX_DIGIT + 1];
} t_u64toa; } t_u64toa;
t_u64toa ascii_u64_data1; t_u64toa ascii_u64_data1;
t_u64toa ascii_u64_data2; t_u64toa ascii_u64_data2;
static float static float TimevalDiff(const struct timeval* a, const struct timeval* b)
TimevalDiff(const struct timeval *a, const struct timeval *b)
{ {
return (a->tv_sec - b->tv_sec) + 1e-6f * (a->tv_usec - b->tv_usec); return (a->tv_sec - b->tv_sec) + 1e-6f * (a->tv_usec - b->tv_usec);
} }
int parse_u64(char* s, uint64_t* const value) { int parse_u64(char* s, uint64_t* const value)
{
uint_fast8_t base = 10; uint_fast8_t base = 10;
char* s_end; char* s_end;
uint64_t u64_value; uint64_t u64_value;
@ -233,7 +230,8 @@ int parse_u64(char* s, uint64_t* const value) {
} }
} }
int parse_u32(char* s, uint32_t* const value) { int parse_u32(char* s, uint32_t* const value)
{
uint_fast8_t base = 10; uint_fast8_t base = 10;
char* s_end; char* s_end;
uint64_t ulong_value; uint64_t ulong_value;
@ -261,7 +259,8 @@ int parse_u32(char* s, uint32_t* const value) {
} }
/* Parse frequencies as doubles to take advantage of notation parsing */ /* Parse frequencies as doubles to take advantage of notation parsing */
int parse_frequency_i64(char* optarg, char* endptr, int64_t* value) { int parse_frequency_i64(char* optarg, char* endptr, int64_t* value)
{
*value = (int64_t) strtod(optarg, &endptr); *value = (int64_t) strtod(optarg, &endptr);
if (optarg == endptr) { if (optarg == endptr) {
return HACKRF_ERROR_INVALID_PARAM; return HACKRF_ERROR_INVALID_PARAM;
@ -269,7 +268,8 @@ int parse_frequency_i64(char* optarg, char* endptr, int64_t* value) {
return HACKRF_SUCCESS; return HACKRF_SUCCESS;
} }
int parse_frequency_u32(char* optarg, char* endptr, uint32_t* value) { int parse_frequency_u32(char* optarg, char* endptr, uint32_t* value)
{
*value = (uint32_t) strtod(optarg, &endptr); *value = (uint32_t) strtod(optarg, &endptr);
if (optarg == endptr) { if (optarg == endptr) {
return HACKRF_ERROR_INVALID_PARAM; return HACKRF_ERROR_INVALID_PARAM;
@ -284,8 +284,7 @@ static char *stringrev(char *str)
if (!str || !*str) if (!str || !*str)
return str; return str;
for(p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2) for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2) {
{
*p1 ^= *p2; *p1 ^= *p2;
*p2 ^= *p1; *p2 ^= *p1;
*p1 ^= *p2; *p1 ^= *p2;
@ -306,8 +305,7 @@ char* u64toa(uint64_t val, t_u64toa* str)
max_len = U64TOA_MAX_DIGIT; max_len = U64TOA_MAX_DIGIT;
pos = 0; pos = 0;
do do {
{
digit = (sum % BASE); digit = (sum % BASE);
str->data[pos] = digit + '0'; str->data[pos] = digit + '0';
pos++; pos++;
@ -352,7 +350,8 @@ uint8_t *stream_buf = NULL;
* Clamping would produce a sigmoid curve, so with a signal of variable intensity you're * Clamping would produce a sigmoid curve, so with a signal of variable intensity you're
* probably getting substantial overload anytime this reports more than about -6dBfs. * probably getting substantial overload anytime this reports more than about -6dBfs.
*/ */
uint64_t stream_amplitude = 0; /* sum of magnitudes of all I&Q samples, reset on the periodic report */ uint64_t stream_amplitude =
0; /* sum of magnitudes of all I&Q samples, reset on the periodic report */
bool transmit = false; bool transmit = false;
struct timeval time_start; struct timeval time_start;
@ -395,13 +394,13 @@ uint32_t crystal_correct_ppm ;
int requested_mode_count = 0; int requested_mode_count = 0;
int rx_callback(hackrf_transfer* transfer) { int rx_callback(hackrf_transfer* transfer)
{
size_t bytes_to_write; size_t bytes_to_write;
size_t bytes_written; size_t bytes_written;
unsigned int i; unsigned int i;
if( file != NULL ) if (file != NULL) {
{
byte_count += transfer->valid_length; byte_count += transfer->valid_length;
bytes_to_write = transfer->valid_length; bytes_to_write = transfer->valid_length;
if (limit_num_samples) { if (limit_num_samples) {
@ -424,23 +423,35 @@ int rx_callback(hackrf_transfer* transfer) {
} }
if (stream_size > 0) { if (stream_size > 0) {
#ifndef _WIN32 #ifndef _WIN32
if ((stream_size-1+stream_head-stream_tail)%stream_size <bytes_to_write) { if ((stream_size - 1 + stream_head - stream_tail) % stream_size <
bytes_to_write) {
stream_drop++; stream_drop++;
} else { } else {
if (stream_tail + bytes_to_write <= stream_size) { if (stream_tail + bytes_to_write <= stream_size) {
memcpy(stream_buf+stream_tail,transfer->buffer,bytes_to_write); memcpy(stream_buf + stream_tail,
transfer->buffer,
bytes_to_write);
} else { } else {
memcpy(stream_buf+stream_tail,transfer->buffer,(stream_size-stream_tail)); memcpy(stream_buf + stream_tail,
memcpy(stream_buf,transfer->buffer+(stream_size-stream_tail),bytes_to_write-(stream_size-stream_tail)); transfer->buffer,
(stream_size - stream_tail));
memcpy(stream_buf,
transfer->buffer +
(stream_size - stream_tail),
bytes_to_write -
(stream_size - stream_tail));
}; };
__atomic_store_n(&stream_tail,(stream_tail+bytes_to_write)%stream_size,__ATOMIC_RELEASE); __atomic_store_n(
&stream_tail,
(stream_tail + bytes_to_write) % stream_size,
__ATOMIC_RELEASE);
} }
#endif #endif
return 0; return 0;
} else { } else {
bytes_written = fwrite(transfer->buffer, 1, bytes_to_write, file); bytes_written = fwrite(transfer->buffer, 1, bytes_to_write, file);
if ((bytes_written != bytes_to_write) if ((bytes_written != bytes_to_write) ||
|| (limit_num_samples && (bytes_to_xfer == 0))) { (limit_num_samples && (bytes_to_xfer == 0))) {
return -1; return -1;
} else { } else {
return 0; return 0;
@ -451,7 +462,8 @@ int rx_callback(hackrf_transfer* transfer) {
} }
} }
int tx_callback(hackrf_transfer* transfer) { int tx_callback(hackrf_transfer* transfer)
{
size_t bytes_to_read; size_t bytes_to_read;
size_t bytes_read; size_t bytes_read;
unsigned int i; unsigned int i;
@ -465,8 +477,7 @@ int tx_callback(hackrf_transfer* transfer) {
stream_amplitude += abs((signed char) transfer->buffer[i]); stream_amplitude += abs((signed char) transfer->buffer[i]);
} }
if( file != NULL ) if (file != NULL) {
{
if (limit_num_samples) { if (limit_num_samples) {
if (bytes_to_read >= bytes_to_xfer) { if (bytes_to_read >= bytes_to_xfer) {
/* /*
@ -483,9 +494,13 @@ int tx_callback(hackrf_transfer* transfer) {
} }
if (bytes_read != bytes_to_read) { if (bytes_read != bytes_to_read) {
if (repeat) { if (repeat) {
fprintf(stderr, "Input file end reached. Rewind to beginning.\n"); fprintf(stderr,
"Input file end reached. Rewind to beginning.\n");
rewind(file); rewind(file);
fread(transfer->buffer + bytes_read, 1, bytes_to_read - bytes_read, file); fread(transfer->buffer + bytes_read,
1,
bytes_to_read - bytes_read,
file);
return 0; return 0;
} else { } else {
return -1; /* not repeat mode, end of file */ return -1; /* not repeat mode, end of file */
@ -543,14 +558,17 @@ static int update_stats(hackrf_device *device, hackrf_m0_state *state, stats_t *
stats->m0_total += 0x100000000; stats->m0_total += 0x100000000;
if (state->m4_count < (stats->m4_total & 0xFFFFFFFF)) if (state->m4_count < (stats->m4_total & 0xFFFFFFFF))
stats->m4_total += 0x100000000; stats->m4_total += 0x100000000;
stats->m0_total = (stats->m0_total & 0xFFFFFFFF00000000) | state->m0_count; stats->m0_total =
stats->m4_total = (stats->m4_total & 0xFFFFFFFF00000000) | state->m4_count; (stats->m0_total & 0xFFFFFFFF00000000) | state->m0_count;
stats->m4_total =
(stats->m4_total & 0xFFFFFFFF00000000) | state->m4_count;
} }
return result; return result;
} }
static void usage() { static void usage()
{
printf("Usage:\n"); printf("Usage:\n");
printf("\t-h # this help\n"); printf("\t-h # this help\n");
printf("\t[-d serial_number] # Serial number of desired HackRF.\n"); printf("\t[-d serial_number] # Serial number of desired HackRF.\n");
@ -592,8 +610,7 @@ static void usage() {
static hackrf_device* device = NULL; static hackrf_device* device = NULL;
#ifdef _MSC_VER #ifdef _MSC_VER
BOOL WINAPI BOOL WINAPI sighandler(int signum)
sighandler(int signum)
{ {
if (CTRL_C_EVENT == signum) { if (CTRL_C_EVENT == signum) {
fprintf(stderr, "Caught signal %d\n", signum); fprintf(stderr, "Caught signal %d\n", signum);
@ -613,7 +630,8 @@ void sigint_callback_handler(int signum)
#define PATH_FILE_MAX_LEN (FILENAME_MAX) #define PATH_FILE_MAX_LEN (FILENAME_MAX)
#define DATE_TIME_MAX_LEN (32) #define DATE_TIME_MAX_LEN (32)
int main(int argc, char** argv) { int main(int argc, char** argv)
{
int opt; int opt;
char path_file[PATH_FILE_MAX_LEN]; char path_file[PATH_FILE_MAX_LEN];
char date_time[DATE_TIME_MAX_LEN]; char date_time[DATE_TIME_MAX_LEN];
@ -631,11 +649,10 @@ int main(int argc, char** argv) {
hackrf_m0_state state; hackrf_m0_state state;
stats_t stats = {0, 0}; stats_t stats = {0, 0};
while( (opt = getopt(argc, argv, "H:wr:t:f:i:o:m:a:p:s:n:b:l:g:x:c:d:C:RS:Bh?")) != EOF ) while ((opt = getopt(argc, argv, "H:wr:t:f:i:o:m:a:p:s:n:b:l:g:x:c:d:C:RS:Bh?")) !=
{ EOF) {
result = HACKRF_SUCCESS; result = HACKRF_SUCCESS;
switch( opt ) switch (opt) {
{
case 'H': case 'H':
hw_sync = true; hw_sync = true;
result = parse_u32(optarg, &hw_sync_enable); result = parse_u32(optarg, &hw_sync_enable);
@ -724,7 +741,10 @@ int main(int argc, char** argv) {
break; break;
case 'b': case 'b':
result = parse_frequency_u32(optarg, endptr, &baseband_filter_bw_hz); result = parse_frequency_u32(
optarg,
endptr,
&baseband_filter_bw_hz);
baseband_filter_bw = true; baseband_filter_bw = true;
break; break;
@ -755,7 +775,12 @@ int main(int argc, char** argv) {
} }
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "argument error: '-%c %s' %s (%d)\n", opt, optarg, hackrf_error_name(result), result); fprintf(stderr,
"argument error: '-%c %s' %s (%d)\n",
opt,
optarg,
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -768,7 +793,8 @@ int main(int argc, char** argv) {
fprintf(stderr, "warning: vga_gain (-g) must be a multiple of 2\n"); fprintf(stderr, "warning: vga_gain (-g) must be a multiple of 2\n");
if (samples_to_xfer >= SAMPLES_TO_XFER_MAX) { if (samples_to_xfer >= SAMPLES_TO_XFER_MAX) {
fprintf(stderr, "argument error: num_samples must be less than %s/%sMio\n", fprintf(stderr,
"argument error: num_samples must be less than %s/%sMio\n",
u64toa(SAMPLES_TO_XFER_MAX, &ascii_u64_data1), u64toa(SAMPLES_TO_XFER_MAX, &ascii_u64_data1),
u64toa((SAMPLES_TO_XFER_MAX / FREQ_ONE_MHZ), &ascii_u64_data2)); u64toa((SAMPLES_TO_XFER_MAX / FREQ_ONE_MHZ), &ascii_u64_data2));
usage(); usage();
@ -778,41 +804,48 @@ int main(int argc, char** argv) {
if (if_freq || lo_freq || image_reject) { if (if_freq || lo_freq || image_reject) {
/* explicit tuning selected */ /* explicit tuning selected */
if (!if_freq) { if (!if_freq) {
fprintf(stderr, "argument error: if_freq_hz must be specified for explicit tuning.\n"); fprintf(stderr,
"argument error: if_freq_hz must be specified for explicit tuning.\n");
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (!image_reject) { if (!image_reject) {
fprintf(stderr, "argument error: image_reject must be specified for explicit tuning.\n"); fprintf(stderr,
"argument error: image_reject must be specified for explicit tuning.\n");
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (!lo_freq && (image_reject_selection != RF_PATH_FILTER_BYPASS)) { if (!lo_freq && (image_reject_selection != RF_PATH_FILTER_BYPASS)) {
fprintf(stderr, "argument error: lo_freq_hz must be specified for explicit tuning unless image_reject is set to bypass.\n"); fprintf(stderr,
"argument error: lo_freq_hz must be specified for explicit tuning unless image_reject is set to bypass.\n");
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if ((if_freq_hz > IF_MAX_HZ) || (if_freq_hz < IF_MIN_HZ)) { if ((if_freq_hz > IF_MAX_HZ) || (if_freq_hz < IF_MIN_HZ)) {
fprintf(stderr, "argument error: if_freq_hz shall be between %s and %s.\n", fprintf(stderr,
"argument error: if_freq_hz shall be between %s and %s.\n",
u64toa(IF_MIN_HZ, &ascii_u64_data1), u64toa(IF_MIN_HZ, &ascii_u64_data1),
u64toa(IF_MAX_HZ, &ascii_u64_data2)); u64toa(IF_MAX_HZ, &ascii_u64_data2));
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if ((lo_freq_hz > LO_MAX_HZ) || (lo_freq_hz < LO_MIN_HZ)) { if ((lo_freq_hz > LO_MAX_HZ) || (lo_freq_hz < LO_MIN_HZ)) {
fprintf(stderr, "argument error: lo_freq_hz shall be between %s and %s.\n", fprintf(stderr,
"argument error: lo_freq_hz shall be between %s and %s.\n",
u64toa(LO_MIN_HZ, &ascii_u64_data1), u64toa(LO_MIN_HZ, &ascii_u64_data1),
u64toa(LO_MAX_HZ, &ascii_u64_data2)); u64toa(LO_MAX_HZ, &ascii_u64_data2));
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (image_reject_selection > 2) { if (image_reject_selection > 2) {
fprintf(stderr, "argument error: image_reject must be 0, 1, or 2 .\n"); fprintf(stderr,
"argument error: image_reject must be 0, 1, or 2 .\n");
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (automatic_tuning) { if (automatic_tuning) {
fprintf(stderr, "warning: freq_hz ignored by explicit tuning selection.\n"); fprintf(stderr,
"warning: freq_hz ignored by explicit tuning selection.\n");
automatic_tuning = false; automatic_tuning = false;
} }
switch (image_reject_selection) { switch (image_reject_selection) {
@ -829,13 +862,14 @@ int main(int argc, char** argv) {
freq_hz = DEFAULT_FREQ_HZ; freq_hz = DEFAULT_FREQ_HZ;
break; break;
} }
fprintf(stderr, "explicit tuning specified for %s Hz.\n", fprintf(stderr,
"explicit tuning specified for %s Hz.\n",
u64toa(freq_hz, &ascii_u64_data1)); u64toa(freq_hz, &ascii_u64_data1));
} else if (automatic_tuning) { } else if (automatic_tuning) {
if(freq_hz > FREQ_MAX_HZ) if (freq_hz > FREQ_MAX_HZ) {
{ fprintf(stderr,
fprintf(stderr, "argument error: freq_hz shall be between %s and %s.\n", "argument error: freq_hz shall be between %s and %s.\n",
u64toa(FREQ_MIN_HZ, &ascii_u64_data1), u64toa(FREQ_MIN_HZ, &ascii_u64_data1),
u64toa(FREQ_MAX_HZ, &ascii_u64_data2)); u64toa(FREQ_MAX_HZ, &ascii_u64_data2));
usage(); usage();
@ -848,8 +882,7 @@ int main(int argc, char** argv) {
} }
if (amp) { if (amp) {
if( amp_enable > 1 ) if (amp_enable > 1) {
{
fprintf(stderr, "argument error: amp_enable shall be 0 or 1.\n"); fprintf(stderr, "argument error: amp_enable shall be 0 or 1.\n");
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
@ -858,35 +891,39 @@ int main(int argc, char** argv) {
if (antenna) { if (antenna) {
if (antenna_enable > 1) { if (antenna_enable > 1) {
fprintf(stderr, "argument error: antenna_enable shall be 0 or 1.\n"); fprintf(stderr,
"argument error: antenna_enable shall be 0 or 1.\n");
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
if( sample_rate == false ) if (sample_rate == false) {
{
sample_rate_hz = DEFAULT_SAMPLE_RATE_HZ; sample_rate_hz = DEFAULT_SAMPLE_RATE_HZ;
} }
if( baseband_filter_bw ) if (baseband_filter_bw) {
{
if (baseband_filter_bw_hz > BASEBAND_FILTER_BW_MAX) { if (baseband_filter_bw_hz > BASEBAND_FILTER_BW_MAX) {
fprintf(stderr, "argument error: baseband_filter_bw_hz must be less or equal to %u Hz/%.03f MHz\n", fprintf(stderr,
BASEBAND_FILTER_BW_MAX, (float)(BASEBAND_FILTER_BW_MAX/FREQ_ONE_MHZ)); "argument error: baseband_filter_bw_hz must be less or equal to %u Hz/%.03f MHz\n",
BASEBAND_FILTER_BW_MAX,
(float) (BASEBAND_FILTER_BW_MAX / FREQ_ONE_MHZ));
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (baseband_filter_bw_hz < BASEBAND_FILTER_BW_MIN) { if (baseband_filter_bw_hz < BASEBAND_FILTER_BW_MIN) {
fprintf(stderr, "argument error: baseband_filter_bw_hz must be greater or equal to %u Hz/%.03f MHz\n", fprintf(stderr,
BASEBAND_FILTER_BW_MIN, (float)(BASEBAND_FILTER_BW_MIN/FREQ_ONE_MHZ)); "argument error: baseband_filter_bw_hz must be greater or equal to %u Hz/%.03f MHz\n",
BASEBAND_FILTER_BW_MIN,
(float) (BASEBAND_FILTER_BW_MIN / FREQ_ONE_MHZ));
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* Compute nearest freq for bw filter */ /* Compute nearest freq for bw filter */
baseband_filter_bw_hz = hackrf_compute_baseband_filter_bw(baseband_filter_bw_hz); baseband_filter_bw_hz =
hackrf_compute_baseband_filter_bw(baseband_filter_bw_hz);
} }
if (requested_mode_count > 1) { if (requested_mode_count > 1) {
@ -912,20 +949,25 @@ int main(int argc, char** argv) {
if (signalsource) { if (signalsource) {
transceiver_mode = TRANSCEIVER_MODE_SS; transceiver_mode = TRANSCEIVER_MODE_SS;
if (amplitude > 127) { if (amplitude > 127) {
fprintf(stderr, "argument error: amplitude shall be in between 0 and 127.\n"); fprintf(stderr,
"argument error: amplitude shall be in between 0 and 127.\n");
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
if( receive_wav ) if (receive_wav) {
{
time(&rawtime); time(&rawtime);
timeinfo = localtime(&rawtime); timeinfo = localtime(&rawtime);
transceiver_mode = TRANSCEIVER_MODE_RX; transceiver_mode = TRANSCEIVER_MODE_RX;
/* File format HackRF Year(2013), Month(11), Day(28), Hour Min Sec+Z, Freq kHz, IQ.wav */ /* File format HackRF Year(2013), Month(11), Day(28), Hour Min Sec+Z, Freq kHz, IQ.wav */
strftime(date_time, DATE_TIME_MAX_LEN, "%Y%m%d_%H%M%S", timeinfo); strftime(date_time, DATE_TIME_MAX_LEN, "%Y%m%d_%H%M%S", timeinfo);
snprintf(path_file, PATH_FILE_MAX_LEN, "HackRF_%sZ_%ukHz_IQ.wav", date_time, (uint32_t)(freq_hz/(1000ull)) ); snprintf(
path_file,
PATH_FILE_MAX_LEN,
"HackRF_%sZ_%ukHz_IQ.wav",
date_time,
(uint32_t) (freq_hz / (1000ull)));
path = path_file; path = path_file;
fprintf(stderr, "Receive wav file: %s\n", path); fprintf(stderr, "Receive wav file: %s\n", path);
} }
@ -941,29 +983,33 @@ int main(int argc, char** argv) {
// Change the freq and sample rate to correct the crystal clock error. // Change the freq and sample rate to correct the crystal clock error.
if (crystal_correct) { if (crystal_correct) {
sample_rate_hz =
sample_rate_hz = (uint32_t)((double)sample_rate_hz * (1000000 - crystal_correct_ppm)/1000000+0.5); (uint32_t) ((double) sample_rate_hz * (1000000 - crystal_correct_ppm) / 1000000 + 0.5);
freq_hz = freq_hz * (1000000 - crystal_correct_ppm) / 1000000; freq_hz = freq_hz * (1000000 - crystal_correct_ppm) / 1000000;
} }
result = hackrf_init(); result = hackrf_init();
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"hackrf_init() failed: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
result = hackrf_open_by_serial(serial_number, &device); result = hackrf_open_by_serial(serial_number, &device);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"hackrf_open() failed: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (transceiver_mode != TRANSCEIVER_MODE_SS) { if (transceiver_mode != TRANSCEIVER_MODE_SS) {
if( transceiver_mode == TRANSCEIVER_MODE_RX ) if (transceiver_mode == TRANSCEIVER_MODE_RX) {
{
if (strcmp(path, "-") == 0) { if (strcmp(path, "-") == 0) {
file = stdout; file = stdout;
} else { } else {
@ -991,8 +1037,7 @@ int main(int argc, char** argv) {
} }
/* Write Wav header */ /* Write Wav header */
if( receive_wav ) if (receive_wav) {
{
fwrite(&wave_file_hdr, 1, sizeof(t_wav_file_hdr), file); fwrite(&wave_file_hdr, 1, sizeof(t_wav_file_hdr), file);
} }
@ -1006,29 +1051,47 @@ int main(int argc, char** argv) {
signal(SIGTERM, &sigint_callback_handler); signal(SIGTERM, &sigint_callback_handler);
signal(SIGABRT, &sigint_callback_handler); signal(SIGABRT, &sigint_callback_handler);
#endif #endif
fprintf(stderr, "call hackrf_set_sample_rate(%u Hz/%.03f MHz)\n", sample_rate_hz,((float)sample_rate_hz/(float)FREQ_ONE_MHZ)); fprintf(stderr,
"call hackrf_set_sample_rate(%u Hz/%.03f MHz)\n",
sample_rate_hz,
((float) sample_rate_hz / (float) FREQ_ONE_MHZ));
result = hackrf_set_sample_rate(device, sample_rate_hz); result = hackrf_set_sample_rate(device, sample_rate_hz);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_set_sample_rate() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"hackrf_set_sample_rate() failed: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (baseband_filter_bw) { if (baseband_filter_bw) {
fprintf(stderr, "call hackrf_baseband_filter_bandwidth_set(%d Hz/%.03f MHz)\n", fprintf(stderr,
baseband_filter_bw_hz, ((float)baseband_filter_bw_hz/(float)FREQ_ONE_MHZ)); "call hackrf_baseband_filter_bandwidth_set(%d Hz/%.03f MHz)\n",
result = hackrf_set_baseband_filter_bandwidth(device, baseband_filter_bw_hz); baseband_filter_bw_hz,
((float) baseband_filter_bw_hz / (float) FREQ_ONE_MHZ));
result = hackrf_set_baseband_filter_bandwidth(
device,
baseband_filter_bw_hz);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_baseband_filter_bandwidth_set() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"hackrf_baseband_filter_bandwidth_set() failed: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
fprintf(stderr, "call hackrf_set_hw_sync_mode(%d)\n", hw_sync_enable); fprintf(stderr, "call hackrf_set_hw_sync_mode(%d)\n", hw_sync_enable);
result = hackrf_set_hw_sync_mode(device, hw_sync_enable ? HW_SYNC_MODE_ON : HW_SYNC_MODE_OFF); result = hackrf_set_hw_sync_mode(
device,
hw_sync_enable ? HW_SYNC_MODE_ON : HW_SYNC_MODE_OFF);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_set_hw_sync_mode() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"hackrf_set_hw_sync_mode() failed: %s (%d)\n",
hackrf_error_name(result),
result);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -1041,30 +1104,44 @@ int main(int argc, char** argv) {
result |= hackrf_start_tx(device, tx_callback, NULL); result |= hackrf_start_tx(device, tx_callback, NULL);
} }
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_start_?x() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"hackrf_start_?x() failed: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (automatic_tuning) { if (automatic_tuning) {
fprintf(stderr, "call hackrf_set_freq(%s Hz/%.03f MHz)\n", fprintf(stderr,
u64toa(freq_hz, &ascii_u64_data1),((double)freq_hz/(double)FREQ_ONE_MHZ) ); "call hackrf_set_freq(%s Hz/%.03f MHz)\n",
u64toa(freq_hz, &ascii_u64_data1),
((double) freq_hz / (double) FREQ_ONE_MHZ));
result = hackrf_set_freq(device, freq_hz); result = hackrf_set_freq(device, freq_hz);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_set_freq() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"hackrf_set_freq() failed: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} else { } else {
fprintf(stderr, "call hackrf_set_freq_explicit() with %s Hz IF, %s Hz LO, %s\n", fprintf(stderr,
"call hackrf_set_freq_explicit() with %s Hz IF, %s Hz LO, %s\n",
u64toa(if_freq_hz, &ascii_u64_data1), u64toa(if_freq_hz, &ascii_u64_data1),
u64toa(lo_freq_hz, &ascii_u64_data2), u64toa(lo_freq_hz, &ascii_u64_data2),
hackrf_filter_path_name(image_reject_selection)); hackrf_filter_path_name(image_reject_selection));
result = hackrf_set_freq_explicit(device, if_freq_hz, lo_freq_hz, result = hackrf_set_freq_explicit(
device,
if_freq_hz,
lo_freq_hz,
image_reject_selection); image_reject_selection);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_set_freq_explicit() failed: %s (%d)\n", fprintf(stderr,
hackrf_error_name(result), result); "hackrf_set_freq_explicit() failed: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -1074,7 +1151,10 @@ int main(int argc, char** argv) {
fprintf(stderr, "call hackrf_set_amp_enable(%u)\n", amp_enable); fprintf(stderr, "call hackrf_set_amp_enable(%u)\n", amp_enable);
result = hackrf_set_amp_enable(device, (uint8_t) amp_enable); result = hackrf_set_amp_enable(device, (uint8_t) amp_enable);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_set_amp_enable() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"hackrf_set_amp_enable() failed: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -1084,14 +1164,18 @@ int main(int argc, char** argv) {
fprintf(stderr, "call hackrf_set_antenna_enable(%u)\n", antenna_enable); fprintf(stderr, "call hackrf_set_antenna_enable(%u)\n", antenna_enable);
result = hackrf_set_antenna_enable(device, (uint8_t) antenna_enable); result = hackrf_set_antenna_enable(device, (uint8_t) antenna_enable);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_set_antenna_enable() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"hackrf_set_antenna_enable() failed: %s (%d)\n",
hackrf_error_name(result),
result);
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
if (limit_num_samples) { if (limit_num_samples) {
fprintf(stderr, "samples_to_xfer %s/%sMio\n", fprintf(stderr,
"samples_to_xfer %s/%sMio\n",
u64toa(samples_to_xfer, &ascii_u64_data1), u64toa(samples_to_xfer, &ascii_u64_data1),
u64toa((samples_to_xfer / FREQ_ONE_MHZ), &ascii_u64_data2)); u64toa((samples_to_xfer / FREQ_ONE_MHZ), &ascii_u64_data2));
} }
@ -1100,9 +1184,7 @@ int main(int argc, char** argv) {
gettimeofday(&time_start, NULL); gettimeofday(&time_start, NULL);
fprintf(stderr, "Stop with Ctrl-C\n"); fprintf(stderr, "Stop with Ctrl-C\n");
while( (hackrf_is_streaming(device) == HACKRF_TRUE) && while ((hackrf_is_streaming(device) == HACKRF_TRUE) && (do_exit == false)) {
(do_exit == false) )
{
uint32_t byte_count_now; uint32_t byte_count_now;
struct timeval time_now; struct timeval time_now;
float time_difference, rate; float time_difference, rate;
@ -1113,12 +1195,14 @@ int main(int argc, char** argv) {
} else { } else {
ssize_t len; ssize_t len;
ssize_t bytes_written; ssize_t bytes_written;
uint32_t _st= __atomic_load_n(&stream_tail,__ATOMIC_ACQUIRE); uint32_t _st =
__atomic_load_n(&stream_tail, __ATOMIC_ACQUIRE);
if (stream_head < _st) if (stream_head < _st)
len = _st - stream_head; len = _st - stream_head;
else else
len = stream_size - stream_head; len = stream_size - stream_head;
bytes_written = fwrite(stream_buf+stream_head, 1, len, file); bytes_written =
fwrite(stream_buf + stream_head, 1, len, file);
if (len != bytes_written) { if (len != bytes_written) {
fprintf(stderr, "write failed"); fprintf(stderr, "write failed");
do_exit = true; do_exit = true;
@ -1126,7 +1210,10 @@ int main(int argc, char** argv) {
stream_head = (stream_head + len) % stream_size; stream_head = (stream_head + len) % stream_size;
} }
if (stream_drop > 0) { if (stream_drop > 0) {
uint32_t drops= __atomic_exchange_n (&stream_drop,0,__ATOMIC_SEQ_CST); uint32_t drops = __atomic_exchange_n(
&stream_drop,
0,
__ATOMIC_SEQ_CST);
fprintf(stderr, "dropped frames: [%d]\n", drops); fprintf(stderr, "dropped frames: [%d]\n", drops);
} }
#endif #endif
@ -1139,34 +1226,46 @@ int main(int argc, char** argv) {
byte_count = 0; byte_count = 0;
stream_amplitude_now = stream_amplitude; stream_amplitude_now = stream_amplitude;
stream_amplitude = 0; stream_amplitude = 0;
if (byte_count_now < sample_rate_hz/20) // Don't report on very short frames if (byte_count_now <
sample_rate_hz / 20) // Don't report on very short frames
stream_amplitude_now = 0; stream_amplitude_now = 0;
time_difference = TimevalDiff(&time_now, &time_start); time_difference = TimevalDiff(&time_now, &time_start);
rate = (float) byte_count_now / time_difference; rate = (float) byte_count_now / time_difference;
if (byte_count_now == 0 && hw_sync == true && hw_sync_enable != 0) { if (byte_count_now == 0 && hw_sync == true &&
hw_sync_enable != 0) {
fprintf(stderr, "Waiting for sync...\n"); fprintf(stderr, "Waiting for sync...\n");
} else { } else {
// This is only an approximate measure, to assist getting receive levels right: // This is only an approximate measure, to assist getting receive levels right:
double full_scale_ratio = ((double)stream_amplitude_now / (byte_count_now ? byte_count_now : 1))/128; double full_scale_ratio =
((double) stream_amplitude_now /
(byte_count_now ? byte_count_now : 1)) /
128;
double dB_full_scale_ratio = 10 * log10(full_scale_ratio); double dB_full_scale_ratio = 10 * log10(full_scale_ratio);
// Guard against ridiculous reports // Guard against ridiculous reports
if (dB_full_scale_ratio > 1) if (dB_full_scale_ratio > 1)
dB_full_scale_ratio = -0.0; dB_full_scale_ratio = -0.0;
fprintf(stderr, "%4.1f MiB / %5.3f sec = %4.1f MiB/second, amplitude %3.1f dBfs", fprintf(stderr,
"%4.1f MiB / %5.3f sec = %4.1f MiB/second, amplitude %3.1f dBfs",
(byte_count_now / 1e6f), (byte_count_now / 1e6f),
time_difference, time_difference,
(rate / 1e6f), (rate / 1e6f),
dB_full_scale_ratio dB_full_scale_ratio);
);
if (display_stats) { if (display_stats) {
bool tx = transmit || signalsource; bool tx = transmit || signalsource;
result = update_stats(device, &state, &stats); result = update_stats(device, &state, &stats);
if (result != HACKRF_SUCCESS) if (result != HACKRF_SUCCESS)
fprintf(stderr, "\nhackrf_get_m0_state() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"\nhackrf_get_m0_state() failed: %s (%d)\n",
hackrf_error_name(result),
result);
else else
fprintf(stderr, ", %d bytes %s in buffer, %u %s, longest %u bytes\n", fprintf(stderr,
tx ? state.m4_count - state.m0_count : state.m0_count - state.m4_count, ", %d bytes %s in buffer, %u %s, longest %u bytes\n",
tx ? state.m4_count -
state.m0_count :
state.m0_count -
state.m4_count,
tx ? "filled" : "free", tx ? "filled" : "free",
state.num_shortfalls, state.num_shortfalls,
tx ? "underruns" : "overruns", tx ? "underruns" : "overruns",
@ -1178,20 +1277,24 @@ int main(int argc, char** argv) {
time_start = time_now; time_start = time_now;
if (byte_count_now == 0 && (hw_sync == false || hw_sync_enable == 0)) { if (byte_count_now == 0 &&
(hw_sync == false || hw_sync_enable == 0)) {
exit_code = EXIT_FAILURE; exit_code = EXIT_FAILURE;
fprintf(stderr, "\nCouldn't transfer any bytes for one second.\n"); fprintf(stderr,
"\nCouldn't transfer any bytes for one second.\n");
break; break;
} }
} }
} }
result = hackrf_is_streaming(device); result = hackrf_is_streaming(device);
if (do_exit) if (do_exit) {
{
fprintf(stderr, "\nExiting...\n"); fprintf(stderr, "\nExiting...\n");
} else { } else {
fprintf(stderr, "\nExiting... hackrf_is_streaming() result: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"\nExiting... hackrf_is_streaming() result: %s (%d)\n",
hackrf_error_name(result),
result);
} }
gettimeofday(&t_end, NULL); gettimeofday(&t_end, NULL);
@ -1202,7 +1305,10 @@ int main(int argc, char** argv) {
if (receive || receive_wav) { if (receive || receive_wav) {
result = hackrf_stop_rx(device); result = hackrf_stop_rx(device);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_stop_rx() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"hackrf_stop_rx() failed: %s (%d)\n",
hackrf_error_name(result),
result);
} else { } else {
fprintf(stderr, "hackrf_stop_rx() done\n"); fprintf(stderr, "hackrf_stop_rx() done\n");
} }
@ -1211,7 +1317,10 @@ int main(int argc, char** argv) {
if (transmit || signalsource) { if (transmit || signalsource) {
result = hackrf_stop_tx(device); result = hackrf_stop_tx(device);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_stop_tx() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"hackrf_stop_tx() failed: %s (%d)\n",
hackrf_error_name(result),
result);
} else { } else {
fprintf(stderr, "hackrf_stop_tx() done\n"); fprintf(stderr, "hackrf_stop_tx() done\n");
} }
@ -1220,7 +1329,10 @@ int main(int argc, char** argv) {
if (display_stats) { if (display_stats) {
result = update_stats(device, &state, &stats); result = update_stats(device, &state, &stats);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_get_m0_state() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"hackrf_get_m0_state() failed: %s (%d)\n",
hackrf_error_name(result),
result);
} else { } else {
fprintf(stderr, fprintf(stderr,
"Transfer statistics:\n" "Transfer statistics:\n"
@ -1230,14 +1342,18 @@ int main(int argc, char** argv) {
stats.m0_total, stats.m0_total,
stats.m4_total, stats.m4_total,
state.num_shortfalls, state.num_shortfalls,
(transmit || signalsource) ? "underruns" : "overruns", (transmit || signalsource) ? "underruns" :
"overruns",
state.longest_shortfall); state.longest_shortfall);
} }
} }
result = hackrf_close(device); result = hackrf_close(device);
if (result != HACKRF_SUCCESS) { if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); fprintf(stderr,
"hackrf_close() failed: %s (%d)\n",
hackrf_error_name(result),
result);
} else { } else {
fprintf(stderr, "hackrf_close() done\n"); fprintf(stderr, "hackrf_close() done\n");
} }
@ -1246,17 +1362,17 @@ int main(int argc, char** argv) {
fprintf(stderr, "hackrf_exit() done\n"); fprintf(stderr, "hackrf_exit() done\n");
} }
if(file != NULL) if (file != NULL) {
{ if (receive_wav) {
if( receive_wav )
{
/* Get size of file */ /* Get size of file */
file_pos = ftell(file); file_pos = ftell(file);
/* Update Wav Header */ /* Update Wav Header */
wave_file_hdr.hdr.size = file_pos - 8; wave_file_hdr.hdr.size = file_pos - 8;
wave_file_hdr.fmt_chunk.dwSamplesPerSec = sample_rate_hz; wave_file_hdr.fmt_chunk.dwSamplesPerSec = sample_rate_hz;
wave_file_hdr.fmt_chunk.dwAvgBytesPerSec = wave_file_hdr.fmt_chunk.dwSamplesPerSec*2; wave_file_hdr.fmt_chunk.dwAvgBytesPerSec =
wave_file_hdr.data_chunk.chunkSize = file_pos - sizeof(t_wav_file_hdr); wave_file_hdr.fmt_chunk.dwSamplesPerSec * 2;
wave_file_hdr.data_chunk.chunkSize =
file_pos - sizeof(t_wav_file_hdr);
/* Overwrite header with updated data */ /* Overwrite header with updated data */
rewind(file); rewind(file);
fwrite(&wave_file_hdr, 1, sizeof(t_wav_file_hdr), file); fwrite(&wave_file_hdr, 1, sizeof(t_wav_file_hdr), file);

File diff suppressed because it is too large Load Diff

View File

@ -196,8 +196,7 @@ typedef struct hackrf_device_list hackrf_device_list_t;
typedef int (*hackrf_sample_block_cb_fn)(hackrf_transfer* transfer); typedef int (*hackrf_sample_block_cb_fn)(hackrf_transfer* transfer);
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C" {
{
#endif #endif
extern ADDAPI int ADDCALL hackrf_init(); extern ADDAPI int ADDCALL hackrf_init();
@ -207,64 +206,127 @@ extern ADDAPI const char* ADDCALL hackrf_library_version();
extern ADDAPI const char* ADDCALL hackrf_library_release(); extern ADDAPI const char* ADDCALL hackrf_library_release();
extern ADDAPI hackrf_device_list_t* ADDCALL hackrf_device_list(); extern ADDAPI hackrf_device_list_t* ADDCALL hackrf_device_list();
extern ADDAPI int ADDCALL hackrf_device_list_open(hackrf_device_list_t *list, int idx, hackrf_device** device); extern ADDAPI int ADDCALL hackrf_device_list_open(
hackrf_device_list_t* list,
int idx,
hackrf_device** device);
extern ADDAPI void ADDCALL hackrf_device_list_free(hackrf_device_list_t* list); extern ADDAPI void ADDCALL hackrf_device_list_free(hackrf_device_list_t* list);
extern ADDAPI int ADDCALL hackrf_open(hackrf_device** device); extern ADDAPI int ADDCALL hackrf_open(hackrf_device** device);
extern ADDAPI int ADDCALL hackrf_open_by_serial(const char* const desired_serial_number, hackrf_device** device); extern ADDAPI int ADDCALL hackrf_open_by_serial(
const char* const desired_serial_number,
hackrf_device** device);
extern ADDAPI int ADDCALL hackrf_close(hackrf_device* device); extern ADDAPI int ADDCALL hackrf_close(hackrf_device* device);
extern ADDAPI int ADDCALL hackrf_start_rx(hackrf_device* device, hackrf_sample_block_cb_fn callback, void* rx_ctx); extern ADDAPI int ADDCALL hackrf_start_rx(
hackrf_device* device,
hackrf_sample_block_cb_fn callback,
void* rx_ctx);
extern ADDAPI int ADDCALL hackrf_stop_rx(hackrf_device* device); extern ADDAPI int ADDCALL hackrf_stop_rx(hackrf_device* device);
extern ADDAPI int ADDCALL hackrf_start_tx(hackrf_device* device, hackrf_sample_block_cb_fn callback, void* tx_ctx); extern ADDAPI int ADDCALL hackrf_start_tx(
hackrf_device* device,
hackrf_sample_block_cb_fn callback,
void* tx_ctx);
extern ADDAPI int ADDCALL hackrf_stop_tx(hackrf_device* device); extern ADDAPI int ADDCALL hackrf_stop_tx(hackrf_device* device);
extern ADDAPI int ADDCALL hackrf_get_m0_state(hackrf_device* device, hackrf_m0_state* value); extern ADDAPI int ADDCALL hackrf_get_m0_state(
extern ADDAPI int ADDCALL hackrf_set_tx_underrun_limit(hackrf_device* device, uint32_t value); hackrf_device* device,
extern ADDAPI int ADDCALL hackrf_set_rx_overrun_limit(hackrf_device* device, uint32_t value); hackrf_m0_state* value);
extern ADDAPI int ADDCALL hackrf_set_tx_underrun_limit(
hackrf_device* device,
uint32_t value);
extern ADDAPI int ADDCALL hackrf_set_rx_overrun_limit(
hackrf_device* device,
uint32_t value);
/* return HACKRF_TRUE if success */ /* return HACKRF_TRUE if success */
extern ADDAPI int ADDCALL hackrf_is_streaming(hackrf_device* device); extern ADDAPI int ADDCALL hackrf_is_streaming(hackrf_device* device);
extern ADDAPI int ADDCALL hackrf_max2837_read(hackrf_device* device, uint8_t register_number, uint16_t* value); extern ADDAPI int ADDCALL hackrf_max2837_read(
extern ADDAPI int ADDCALL hackrf_max2837_write(hackrf_device* device, uint8_t register_number, uint16_t value); hackrf_device* device,
uint8_t register_number,
uint16_t* value);
extern ADDAPI int ADDCALL hackrf_max2837_write(
hackrf_device* device,
uint8_t register_number,
uint16_t value);
extern ADDAPI int ADDCALL hackrf_si5351c_read(hackrf_device* device, uint16_t register_number, uint16_t* value); extern ADDAPI int ADDCALL hackrf_si5351c_read(
extern ADDAPI int ADDCALL hackrf_si5351c_write(hackrf_device* device, uint16_t register_number, uint16_t value); hackrf_device* device,
uint16_t register_number,
uint16_t* value);
extern ADDAPI int ADDCALL hackrf_si5351c_write(
hackrf_device* device,
uint16_t register_number,
uint16_t value);
extern ADDAPI int ADDCALL hackrf_set_baseband_filter_bandwidth(hackrf_device* device, const uint32_t bandwidth_hz); extern ADDAPI int ADDCALL hackrf_set_baseband_filter_bandwidth(
hackrf_device* device,
const uint32_t bandwidth_hz);
extern ADDAPI int ADDCALL hackrf_rffc5071_read(hackrf_device* device, uint8_t register_number, uint16_t* value); extern ADDAPI int ADDCALL hackrf_rffc5071_read(
extern ADDAPI int ADDCALL hackrf_rffc5071_write(hackrf_device* device, uint8_t register_number, uint16_t value); hackrf_device* device,
uint8_t register_number,
uint16_t* value);
extern ADDAPI int ADDCALL hackrf_rffc5071_write(
hackrf_device* device,
uint8_t register_number,
uint16_t value);
extern ADDAPI int ADDCALL hackrf_spiflash_erase(hackrf_device* device); extern ADDAPI int ADDCALL hackrf_spiflash_erase(hackrf_device* device);
extern ADDAPI int ADDCALL hackrf_spiflash_write(hackrf_device* device, const uint32_t address, const uint16_t length, unsigned char* const data); extern ADDAPI int ADDCALL hackrf_spiflash_write(
extern ADDAPI int ADDCALL hackrf_spiflash_read(hackrf_device* device, const uint32_t address, const uint16_t length, unsigned char* data); hackrf_device* device,
const uint32_t address,
const uint16_t length,
unsigned char* const data);
extern ADDAPI int ADDCALL hackrf_spiflash_read(
hackrf_device* device,
const uint32_t address,
const uint16_t length,
unsigned char* data);
extern ADDAPI int ADDCALL hackrf_spiflash_status(hackrf_device* device, uint8_t* data); extern ADDAPI int ADDCALL hackrf_spiflash_status(hackrf_device* device, uint8_t* data);
extern ADDAPI int ADDCALL hackrf_spiflash_clear_status(hackrf_device* device); extern ADDAPI int ADDCALL hackrf_spiflash_clear_status(hackrf_device* device);
/* device will need to be reset after hackrf_cpld_write */ /* device will need to be reset after hackrf_cpld_write */
extern ADDAPI int ADDCALL hackrf_cpld_write(hackrf_device* device, extern ADDAPI int ADDCALL hackrf_cpld_write(
unsigned char* const data, const unsigned int total_length); hackrf_device* device,
unsigned char* const data,
const unsigned int total_length);
extern ADDAPI int ADDCALL hackrf_board_id_read(hackrf_device* device, uint8_t* value); extern ADDAPI int ADDCALL hackrf_board_id_read(hackrf_device* device, uint8_t* value);
extern ADDAPI int ADDCALL hackrf_version_string_read(hackrf_device* device, char* version, uint8_t length); extern ADDAPI int ADDCALL hackrf_version_string_read(
extern ADDAPI int ADDCALL hackrf_usb_api_version_read(hackrf_device* device, uint16_t* version); hackrf_device* device,
char* version,
uint8_t length);
extern ADDAPI int ADDCALL hackrf_usb_api_version_read(
hackrf_device* device,
uint16_t* version);
extern ADDAPI int ADDCALL hackrf_set_freq(hackrf_device* device, const uint64_t freq_hz); extern ADDAPI int ADDCALL hackrf_set_freq(hackrf_device* device, const uint64_t freq_hz);
extern ADDAPI int ADDCALL hackrf_set_freq_explicit(hackrf_device* device, extern ADDAPI int ADDCALL hackrf_set_freq_explicit(
const uint64_t if_freq_hz, const uint64_t lo_freq_hz, hackrf_device* device,
const uint64_t if_freq_hz,
const uint64_t lo_freq_hz,
const enum rf_path_filter path); const enum rf_path_filter path);
/* 2-20Mhz - either as a fraction, i.e. freq 20000000hz divider 2 -> 10Mhz or as plain old 10000000hz (double) */ /* 2-20Mhz - either as a fraction, i.e. freq 20000000hz divider 2 -> 10Mhz or as plain old 10000000hz (double) */
extern ADDAPI int ADDCALL hackrf_set_sample_rate_manual(hackrf_device* device, const uint32_t freq_hz, const uint32_t divider); extern ADDAPI int ADDCALL hackrf_set_sample_rate_manual(
extern ADDAPI int ADDCALL hackrf_set_sample_rate(hackrf_device* device, const double freq_hz); hackrf_device* device,
const uint32_t freq_hz,
const uint32_t divider);
extern ADDAPI int ADDCALL hackrf_set_sample_rate(
hackrf_device* device,
const double freq_hz);
/* external amp, bool on/off */ /* external amp, bool on/off */
extern ADDAPI int ADDCALL hackrf_set_amp_enable(hackrf_device* device, const uint8_t value); extern ADDAPI int ADDCALL hackrf_set_amp_enable(
hackrf_device* device,
const uint8_t value);
extern ADDAPI int ADDCALL hackrf_board_partid_serialno_read(hackrf_device* device, read_partid_serialno_t* read_partid_serialno); extern ADDAPI int ADDCALL hackrf_board_partid_serialno_read(
hackrf_device* device,
read_partid_serialno_t* read_partid_serialno);
/* range 0-40 step 8d, IF gain in osmosdr */ /* range 0-40 step 8d, IF gain in osmosdr */
extern ADDAPI int ADDCALL hackrf_set_lna_gain(hackrf_device* device, uint32_t value); extern ADDAPI int ADDCALL hackrf_set_lna_gain(hackrf_device* device, uint32_t value);
@ -276,58 +338,90 @@ extern ADDAPI int ADDCALL hackrf_set_vga_gain(hackrf_device* device, uint32_t va
extern ADDAPI int ADDCALL hackrf_set_txvga_gain(hackrf_device* device, uint32_t value); extern ADDAPI int ADDCALL hackrf_set_txvga_gain(hackrf_device* device, uint32_t value);
/* antenna port power control */ /* antenna port power control */
extern ADDAPI int ADDCALL hackrf_set_antenna_enable(hackrf_device* device, const uint8_t value); extern ADDAPI int ADDCALL hackrf_set_antenna_enable(
hackrf_device* device,
const uint8_t value);
extern ADDAPI const char* ADDCALL hackrf_error_name(enum hackrf_error errcode); extern ADDAPI const char* ADDCALL hackrf_error_name(enum hackrf_error errcode);
extern ADDAPI const char* ADDCALL hackrf_board_id_name(enum hackrf_board_id board_id); extern ADDAPI const char* ADDCALL hackrf_board_id_name(enum hackrf_board_id board_id);
extern ADDAPI const char* ADDCALL hackrf_usb_board_id_name(enum hackrf_usb_board_id usb_board_id); extern ADDAPI const char* ADDCALL hackrf_usb_board_id_name(
enum hackrf_usb_board_id usb_board_id);
extern ADDAPI const char* ADDCALL hackrf_filter_path_name(const enum rf_path_filter path); extern ADDAPI const char* ADDCALL hackrf_filter_path_name(const enum rf_path_filter path);
/* Compute nearest freq for bw filter (manual filter) */ /* Compute nearest freq for bw filter (manual filter) */
extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw_round_down_lt(const uint32_t bandwidth_hz); extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw_round_down_lt(
const uint32_t bandwidth_hz);
/* Compute best default value depending on sample rate (auto filter) */ /* Compute best default value depending on sample rate (auto filter) */
extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw(const uint32_t bandwidth_hz); extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw(
const uint32_t bandwidth_hz);
/* All features below require USB API version 0x1002 or higher) */ /* All features below require USB API version 0x1002 or higher) */
/* set hardware sync mode */ /* set hardware sync mode */
extern ADDAPI int ADDCALL hackrf_set_hw_sync_mode(hackrf_device* device, const uint8_t value); extern ADDAPI int ADDCALL hackrf_set_hw_sync_mode(
hackrf_device* device,
const uint8_t value);
/* Start sweep mode */ /* Start sweep mode */
extern ADDAPI int ADDCALL hackrf_init_sweep(hackrf_device* device, extern ADDAPI int ADDCALL hackrf_init_sweep(
const uint16_t* frequency_list, const int num_ranges, hackrf_device* device,
const uint32_t num_bytes, const uint32_t step_width, const uint16_t* frequency_list,
const uint32_t offset, const enum sweep_style style); const int num_ranges,
const uint32_t num_bytes,
const uint32_t step_width,
const uint32_t offset,
const enum sweep_style style);
/* Operacake functions */ /* Operacake functions */
extern ADDAPI int ADDCALL hackrf_get_operacake_boards(hackrf_device* device, uint8_t* boards); extern ADDAPI int ADDCALL hackrf_get_operacake_boards(
extern ADDAPI int ADDCALL hackrf_set_operacake_mode(hackrf_device* device, uint8_t address, enum operacake_switching_mode mode); hackrf_device* device,
extern ADDAPI int ADDCALL hackrf_get_operacake_mode(hackrf_device* device, uint8_t address, enum operacake_switching_mode *mode); uint8_t* boards);
extern ADDAPI int ADDCALL hackrf_set_operacake_ports(hackrf_device* device, extern ADDAPI int ADDCALL hackrf_set_operacake_mode(
hackrf_device* device,
uint8_t address,
enum operacake_switching_mode mode);
extern ADDAPI int ADDCALL hackrf_get_operacake_mode(
hackrf_device* device,
uint8_t address,
enum operacake_switching_mode* mode);
extern ADDAPI int ADDCALL hackrf_set_operacake_ports(
hackrf_device* device,
uint8_t address, uint8_t address,
uint8_t port_a, uint8_t port_a,
uint8_t port_b); uint8_t port_b);
extern ADDAPI int ADDCALL hackrf_set_operacake_dwell_times(hackrf_device* device, hackrf_operacake_dwell_time *dwell_times, uint8_t count); extern ADDAPI int ADDCALL hackrf_set_operacake_dwell_times(
extern ADDAPI int ADDCALL hackrf_set_operacake_freq_ranges(hackrf_device* device, hackrf_operacake_freq_range *freq_ranges, uint8_t count); hackrf_device* device,
hackrf_operacake_dwell_time* dwell_times,
uint8_t count);
extern ADDAPI int ADDCALL hackrf_set_operacake_freq_ranges(
hackrf_device* device,
hackrf_operacake_freq_range* freq_ranges,
uint8_t count);
extern ADDAPI int ADDCALL hackrf_reset(hackrf_device* device); extern ADDAPI int ADDCALL hackrf_reset(hackrf_device* device);
extern ADDAPI int ADDCALL hackrf_set_operacake_ranges(hackrf_device* device, extern ADDAPI int ADDCALL hackrf_set_operacake_ranges(
hackrf_device* device,
uint8_t* ranges, uint8_t* ranges,
uint8_t num_ranges); uint8_t num_ranges);
extern ADDAPI int ADDCALL hackrf_set_clkout_enable(hackrf_device* device, const uint8_t value); extern ADDAPI int ADDCALL hackrf_set_clkout_enable(
hackrf_device* device,
const uint8_t value);
extern ADDAPI int ADDCALL hackrf_operacake_gpio_test(hackrf_device* device, extern ADDAPI int ADDCALL hackrf_operacake_gpio_test(
hackrf_device* device,
uint8_t address, uint8_t address,
uint16_t* test_result); uint16_t* test_result);
#ifdef HACKRF_ISSUE_609_IS_FIXED #ifdef HACKRF_ISSUE_609_IS_FIXED
extern ADDAPI int ADDCALL hackrf_cpld_checksum(hackrf_device* device, extern ADDAPI int ADDCALL hackrf_cpld_checksum(hackrf_device* device, uint32_t* crc);
uint32_t* crc);
#endif /* HACKRF_ISSUE_609_IS_FIXED */ #endif /* HACKRF_ISSUE_609_IS_FIXED */
extern ADDAPI int ADDCALL hackrf_set_ui_enable(hackrf_device* device, const uint8_t value); extern ADDAPI int ADDCALL hackrf_set_ui_enable(hackrf_device* device, const uint8_t value);
extern ADDAPI int ADDCALL hackrf_start_rx_sweep(hackrf_device* device, hackrf_sample_block_cb_fn callback, void* rx_ctx); extern ADDAPI int ADDCALL hackrf_start_rx_sweep(
hackrf_device* device,
hackrf_sample_block_cb_fn callback,
void* rx_ctx);
#ifdef __cplusplus #ifdef __cplusplus
} // __cplusplus defined. } // __cplusplus defined.