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:
Jared Boone
2012-10-17 17:00:36 -07:00
parent 9c4a0e94b0
commit 549c943979
8 changed files with 105 additions and 6 deletions

View File

@ -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)
{

View File

@ -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
}

View File

@ -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)
{

View File

@ -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);

View File

@ -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;
}

View File

@ -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 {

View File

@ -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;

View File

@ -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);