Add USB control of LPF baseband filter.
Add max2837_set_lpf_bandwidth() function to choose available LPF filter bandwidth based on bandwidth in Hz. Change configuration of MAX2837 to set LPF_EN and FT at max2837_setup(), not in max2837_rx() or max2837_tx() (which was overriding prior filter configuration).
This commit is contained in:
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "hackrf_core.h"
|
#include "hackrf_core.h"
|
||||||
#include "si5351c.h"
|
#include "si5351c.h"
|
||||||
|
#include "max2837.h"
|
||||||
#include <libopencm3/lpc43xx/i2c.h>
|
#include <libopencm3/lpc43xx/i2c.h>
|
||||||
#include <libopencm3/lpc43xx/cgu.h>
|
#include <libopencm3/lpc43xx/cgu.h>
|
||||||
#include <libopencm3/lpc43xx/gpio.h>
|
#include <libopencm3/lpc43xx/gpio.h>
|
||||||
@ -126,6 +127,10 @@ bool sample_rate_set(const uint32_t sample_rate_hz) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz) {
|
||||||
|
return max2837_set_lpf_bandwidth(bandwidth_hz);
|
||||||
|
}
|
||||||
|
|
||||||
/* clock startup for Jellybean with Lemondrop attached */
|
/* clock startup for Jellybean with Lemondrop attached */
|
||||||
void cpu_clock_init(void)
|
void cpu_clock_init(void)
|
||||||
{
|
{
|
||||||
|
@ -218,6 +218,7 @@ void pin_setup(void);
|
|||||||
void enable_1v8_power(void);
|
void enable_1v8_power(void);
|
||||||
|
|
||||||
bool sample_rate_set(const uint32_t sampling_rate_hz);
|
bool sample_rate_set(const uint32_t sampling_rate_hz);
|
||||||
|
bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -115,6 +115,11 @@ void max2837_setup(void)
|
|||||||
/* maximum rx output common-mode voltage */
|
/* maximum rx output common-mode voltage */
|
||||||
set_MAX2837_BUFF_VCM(MAX2837_BUFF_VCM_1_25);
|
set_MAX2837_BUFF_VCM(MAX2837_BUFF_VCM_1_25);
|
||||||
|
|
||||||
|
/* configure baseband filter for 8 MHz TX */
|
||||||
|
set_MAX2837_LPF_EN(1);
|
||||||
|
set_MAX2837_ModeCtrl(MAX2837_ModeCtrl_RxLPF);
|
||||||
|
set_MAX2837_FT(MAX2837_FT_5M);
|
||||||
|
|
||||||
max2837_regs_commit();
|
max2837_regs_commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,10 +197,7 @@ void max2837_tx(void)
|
|||||||
LOG("# max2837_tx\n");
|
LOG("# max2837_tx\n");
|
||||||
#if !defined TEST
|
#if !defined TEST
|
||||||
|
|
||||||
/* configure baseband filter for 8 MHz TX */
|
|
||||||
set_MAX2837_LPF_EN(1);
|
|
||||||
set_MAX2837_ModeCtrl(MAX2837_ModeCtrl_TxLPF);
|
set_MAX2837_ModeCtrl(MAX2837_ModeCtrl_TxLPF);
|
||||||
set_MAX2837_FT(MAX2837_FT_8M);
|
|
||||||
max2837_regs_commit();
|
max2837_regs_commit();
|
||||||
|
|
||||||
gpio_set(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE);
|
gpio_set(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE);
|
||||||
@ -206,10 +208,7 @@ void max2837_rx(void)
|
|||||||
{
|
{
|
||||||
LOG("# max2837_rx\n");
|
LOG("# max2837_rx\n");
|
||||||
|
|
||||||
/* configure baseband filter for 8 MHz RX */
|
|
||||||
set_MAX2837_LPF_EN(1);
|
|
||||||
set_MAX2837_ModeCtrl(MAX2837_ModeCtrl_RxLPF);
|
set_MAX2837_ModeCtrl(MAX2837_ModeCtrl_RxLPF);
|
||||||
set_MAX2837_FT(MAX2837_FT_8M);
|
|
||||||
max2837_regs_commit();
|
max2837_regs_commit();
|
||||||
|
|
||||||
#if !defined TEST
|
#if !defined TEST
|
||||||
@ -290,6 +289,49 @@ void max2837_set_frequency(uint32_t freq)
|
|||||||
max2837_regs_commit();
|
max2837_regs_commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t bandwidth_hz;
|
||||||
|
uint32_t ft;
|
||||||
|
} max2837_ft_t;
|
||||||
|
|
||||||
|
static const max2837_ft_t max2837_ft[] = {
|
||||||
|
{ 1750000, MAX2837_FT_1_75M },
|
||||||
|
{ 2500000, MAX2837_FT_2_5M },
|
||||||
|
{ 3500000, MAX2837_FT_3_5M },
|
||||||
|
{ 5000000, MAX2837_FT_5M },
|
||||||
|
{ 5500000, MAX2837_FT_5_5M },
|
||||||
|
{ 6000000, MAX2837_FT_6M },
|
||||||
|
{ 7000000, MAX2837_FT_7M },
|
||||||
|
{ 8000000, MAX2837_FT_8M },
|
||||||
|
{ 9000000, MAX2837_FT_9M },
|
||||||
|
{ 10000000, MAX2837_FT_10M },
|
||||||
|
{ 12000000, MAX2837_FT_12M },
|
||||||
|
{ 14000000, MAX2837_FT_14M },
|
||||||
|
{ 15000000, MAX2837_FT_15M },
|
||||||
|
{ 20000000, MAX2837_FT_20M },
|
||||||
|
{ 24000000, MAX2837_FT_24M },
|
||||||
|
{ 28000000, MAX2837_FT_28M },
|
||||||
|
{ 0, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
bool max2837_set_lpf_bandwidth(const uint32_t bandwidth_hz) {
|
||||||
|
const max2837_ft_t* p = max2837_ft;
|
||||||
|
while( p->bandwidth_hz != 0 ) {
|
||||||
|
if( p->bandwidth_hz >= bandwidth_hz ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( p->bandwidth_hz != 0 ) {
|
||||||
|
set_MAX2837_FT(p->ft);
|
||||||
|
max2837_regs_commit();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
int main(int ac, char **av)
|
int main(int ac, char **av)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#ifndef __MAX2837_H
|
#ifndef __MAX2837_H
|
||||||
#define __MAX2837_H
|
#define __MAX2837_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
/* TODO - make this a private header for max2837.c only, make new max2837.h */
|
/* TODO - make this a private header for max2837.c only, make new max2837.h */
|
||||||
|
|
||||||
/* 32 registers, each containing 10 bits of data. */
|
/* 32 registers, each containing 10 bits of data. */
|
||||||
@ -40,6 +43,7 @@ extern void max2837_stop(void);
|
|||||||
/* 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(uint32_t freq);
|
extern void max2837_set_frequency(uint32_t freq);
|
||||||
|
bool max2837_set_lpf_bandwidth(const uint32_t bandwidth_hz);
|
||||||
|
|
||||||
extern void max2837_tx(void);
|
extern void max2837_tx(void);
|
||||||
extern void max2837_rx(void);
|
extern void max2837_rx(void);
|
||||||
|
@ -309,6 +309,22 @@ bool usb_vendor_request_set_sample_rate(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool usb_vendor_request_set_baseband_filter_bandwidth(
|
||||||
|
usb_endpoint_t* const endpoint,
|
||||||
|
const usb_transfer_stage_t stage
|
||||||
|
) {
|
||||||
|
if( stage == USB_TRANSFER_STAGE_SETUP ) {
|
||||||
|
const uint32_t bandwidth = (endpoint->setup.index << 16) | endpoint->setup.value;
|
||||||
|
if( baseband_filter_bandwidth_set(bandwidth) ) {
|
||||||
|
usb_endpoint_schedule_ack(endpoint->in);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void usb_vendor_request(
|
void 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
|
||||||
@ -340,6 +356,10 @@ void usb_vendor_request(
|
|||||||
success = usb_vendor_request_set_sample_rate(endpoint, stage);
|
success = usb_vendor_request_set_sample_rate(endpoint, stage);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
success = usb_vendor_request_set_baseband_filter_bandwidth(endpoint, stage);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -171,6 +171,12 @@ int main(int argc, char** argv) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = hackrf_baseband_filter_bandwidth_set(device, 5000000);
|
||||||
|
if( result != HACKRF_SUCCESS ) {
|
||||||
|
printf("hackrf_baseband_filter_bandwidth_set() failed: %s (%d)\n", hackrf_error_name(result), result);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if( transceiver_mode == TRANSCEIVER_MODE_RX ) {
|
if( transceiver_mode == TRANSCEIVER_MODE_RX ) {
|
||||||
result = hackrf_start_rx(device, rx_callback);
|
result = hackrf_start_rx(device, rx_callback);
|
||||||
} else {
|
} else {
|
||||||
|
@ -35,6 +35,7 @@ typedef enum {
|
|||||||
HACKRF_VENDOR_REQUEST_SI5351C_WRITE = 4,
|
HACKRF_VENDOR_REQUEST_SI5351C_WRITE = 4,
|
||||||
HACKRF_VENDOR_REQUEST_SI5351C_READ = 5,
|
HACKRF_VENDOR_REQUEST_SI5351C_READ = 5,
|
||||||
HACKRF_VENDOR_REQUEST_SAMPLE_RATE_SET = 6,
|
HACKRF_VENDOR_REQUEST_SAMPLE_RATE_SET = 6,
|
||||||
|
HACKRF_VENDOR_REQUEST_BASEBAND_FILTER_BANDWIDTH_SET = 7,
|
||||||
} hackrf_vendor_request;
|
} hackrf_vendor_request;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -353,6 +354,25 @@ int hackrf_sample_rate_set(hackrf_device* device, const uint32_t sampling_rate_h
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hackrf_baseband_filter_bandwidth_set(hackrf_device* device, const uint32_t bandwidth_hz) {
|
||||||
|
int result = libusb_control_transfer(
|
||||||
|
device->usb_device,
|
||||||
|
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
|
||||||
|
HACKRF_VENDOR_REQUEST_BASEBAND_FILTER_BANDWIDTH_SET,
|
||||||
|
bandwidth_hz & 0xffff,
|
||||||
|
bandwidth_hz >> 16,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
if( result != 0 ) {
|
||||||
|
return HACKRF_ERROR_LIBUSB;
|
||||||
|
} else {
|
||||||
|
return HACKRF_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void* transfer_threadproc(void* arg) {
|
static void* transfer_threadproc(void* arg) {
|
||||||
hackrf_device* device = (hackrf_device*)arg;
|
hackrf_device* device = (hackrf_device*)arg;
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ int hackrf_si5351c_read(hackrf_device* device, uint16_t register_number, uint16_
|
|||||||
int hackrf_si5351c_write(hackrf_device* device, uint16_t register_number, uint16_t value);
|
int hackrf_si5351c_write(hackrf_device* device, uint16_t register_number, uint16_t value);
|
||||||
|
|
||||||
int hackrf_sample_rate_set(hackrf_device* device, const uint32_t sampling_rate_hz);
|
int hackrf_sample_rate_set(hackrf_device* device, const uint32_t sampling_rate_hz);
|
||||||
|
int hackrf_baseband_filter_bandwidth_set(hackrf_device* device, const uint32_t bandwidth_hz);
|
||||||
|
|
||||||
const char* hackrf_error_name(enum hackrf_error errcode);
|
const char* hackrf_error_name(enum hackrf_error errcode);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user