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 "si5351c.h"
|
||||
#include "max2837.h"
|
||||
#include <libopencm3/lpc43xx/i2c.h>
|
||||
#include <libopencm3/lpc43xx/cgu.h>
|
||||
#include <libopencm3/lpc43xx/gpio.h>
|
||||
@ -126,6 +127,10 @@ bool sample_rate_set(const uint32_t sample_rate_hz) {
|
||||
#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 */
|
||||
void cpu_clock_init(void)
|
||||
{
|
||||
|
@ -218,6 +218,7 @@ void pin_setup(void);
|
||||
void enable_1v8_power(void);
|
||||
|
||||
bool sample_rate_set(const uint32_t sampling_rate_hz);
|
||||
bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -115,6 +115,11 @@ void max2837_setup(void)
|
||||
/* maximum rx output common-mode voltage */
|
||||
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();
|
||||
}
|
||||
|
||||
@ -192,10 +197,7 @@ void max2837_tx(void)
|
||||
LOG("# max2837_tx\n");
|
||||
#if !defined TEST
|
||||
|
||||
/* configure baseband filter for 8 MHz TX */
|
||||
set_MAX2837_LPF_EN(1);
|
||||
set_MAX2837_ModeCtrl(MAX2837_ModeCtrl_TxLPF);
|
||||
set_MAX2837_FT(MAX2837_FT_8M);
|
||||
max2837_regs_commit();
|
||||
|
||||
gpio_set(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE);
|
||||
@ -206,10 +208,7 @@ void max2837_rx(void)
|
||||
{
|
||||
LOG("# max2837_rx\n");
|
||||
|
||||
/* configure baseband filter for 8 MHz RX */
|
||||
set_MAX2837_LPF_EN(1);
|
||||
set_MAX2837_ModeCtrl(MAX2837_ModeCtrl_RxLPF);
|
||||
set_MAX2837_FT(MAX2837_FT_8M);
|
||||
max2837_regs_commit();
|
||||
|
||||
#if !defined TEST
|
||||
@ -290,6 +289,49 @@ void max2837_set_frequency(uint32_t freq)
|
||||
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
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
|
@ -1,6 +1,9 @@
|
||||
#ifndef __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 */
|
||||
|
||||
/* 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
|
||||
* where order of register writes matters. */
|
||||
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_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(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage
|
||||
@ -340,6 +356,10 @@ void usb_vendor_request(
|
||||
success = usb_vendor_request_set_sample_rate(endpoint, stage);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
success = usb_vendor_request_set_baseband_filter_bandwidth(endpoint, stage);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -171,6 +171,12 @@ int main(int argc, char** argv) {
|
||||
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 ) {
|
||||
result = hackrf_start_rx(device, rx_callback);
|
||||
} else {
|
||||
|
@ -35,6 +35,7 @@ typedef enum {
|
||||
HACKRF_VENDOR_REQUEST_SI5351C_WRITE = 4,
|
||||
HACKRF_VENDOR_REQUEST_SI5351C_READ = 5,
|
||||
HACKRF_VENDOR_REQUEST_SAMPLE_RATE_SET = 6,
|
||||
HACKRF_VENDOR_REQUEST_BASEBAND_FILTER_BANDWIDTH_SET = 7,
|
||||
} hackrf_vendor_request;
|
||||
|
||||
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) {
|
||||
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_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);
|
||||
|
||||
|
Reference in New Issue
Block a user