diff --git a/firmware/common/max2837.c b/firmware/common/max2837.c index 62edaa52..4fc5f8fb 100644 --- a/firmware/common/max2837.c +++ b/firmware/common/max2837.c @@ -369,6 +369,57 @@ bool max2837_set_lpf_bandwidth(const uint32_t bandwidth_hz) { } } +bool max2837_set_lna_gain(const uint32_t gain_db) { + uint16_t val; + switch(gain_db){ + case 40: + val = MAX2837_LNAgain_MAX; + break; + case 32: + val = MAX2837_LNAgain_M8; + break; + case 24: + val = MAX2837_LNAgain_M16; + break; + case 16: + val = MAX2837_LNAgain_M24; + break; + case 8: + val = MAX2837_LNAgain_M32; + break; + case 0: + val = MAX2837_LNAgain_M40; + break; + default: + return false; + } + set_MAX2837_LNAgain(val); + max2837_reg_commit(1); + return true; +} + +bool max2837_set_vga_gain(const uint32_t gain_db) { + if( (gain_db & 0x1) || gain_db > 62)/* 0b11111*2 */ + return false; + + set_MAX2837_VGA( 31-(gain_db >> 1) ); + max2837_reg_commit(5); + return true; +} + +bool max2837_set_txvga_gain(const uint32_t gain_db, const uint32_t plus16) { + uint16_t val = 31-gain_db; + if(gain_db > 31)/* 0b111111 mind the bit 6 weigth*/ + return false; + + if(plus16) + val |= 0x20; /* +16db */ + + set_MAX2837_TXVGA_GAIN(val); + max2837_reg_commit(29); + return true; +} + #ifdef TEST int main(int ac, char **av) { diff --git a/firmware/common/max2837.h b/firmware/common/max2837.h index acfc59be..065f0959 100644 --- a/firmware/common/max2837.h +++ b/firmware/common/max2837.h @@ -45,7 +45,10 @@ extern void max2837_stop(void); * where order of register writes matters. */ extern void max2837_set_frequency(uint32_t freq); bool max2837_set_lpf_bandwidth(const uint32_t bandwidth_hz); - +bool max2837_set_lna_gain(const uint32_t gain_db); +bool max2837_set_vga_gain(const uint32_t gain_db); +bool max2837_set_txvga_gain(const uint32_t gain_db, const uint32_t plus16); + extern void max2837_tx(void); extern void max2837_rx(void); diff --git a/firmware/common/max2837_regs.def b/firmware/common/max2837_regs.def index 85dd71e6..0247afad 100644 --- a/firmware/common/max2837_regs.def +++ b/firmware/common/max2837_regs.def @@ -56,7 +56,7 @@ __MREG__(MAX2837_LNAgain,1,4,3) #define MAX2837_LNAgain_M8 0b100 #define MAX2837_LNAgain_M16 0b010 #define MAX2837_LNAgain_M24 0b110 -#define MAX2837_LNAgain_M32 0b001 +#define MAX2837_LNAgain_M32 0b011 #define MAX2837_LNAgain_M40 0b111 __MREG__(MAX2837_iqerr_trim,1,9,5) // 0b00000 = +4.0 degree phase error diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 4abfa7a3..14b16f5d 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -760,6 +760,47 @@ usb_request_status_t usb_vendor_request_read_partid_serialno( return USB_REQUEST_STATUS_OK; } +usb_request_status_t usb_vendor_request_set_lna_gain( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + if( stage == USB_TRANSFER_STAGE_SETUP ) { + const uint8_t value = max2837_set_lna_gain(endpoint->setup.index); + endpoint->buffer[0] = value; + usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); + usb_endpoint_schedule_ack(endpoint->out); + return USB_REQUEST_STATUS_OK; + } + return USB_REQUEST_STATUS_OK; +} + +usb_request_status_t usb_vendor_request_set_vga_gain( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + if( stage == USB_TRANSFER_STAGE_SETUP ) { + const uint8_t value = max2837_set_vga_gain(endpoint->setup.index); + endpoint->buffer[0] = value; + usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); + usb_endpoint_schedule_ack(endpoint->out); + return USB_REQUEST_STATUS_OK; + } + return USB_REQUEST_STATUS_OK; +} + +usb_request_status_t usb_vendor_request_set_txvga_gain( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + if( stage == USB_TRANSFER_STAGE_SETUP ) { + const uint8_t value = max2837_set_txvga_gain( + endpoint->setup.index, endpoint->setup.value); + + endpoint->buffer[0] = value; + usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); + usb_endpoint_schedule_ack(endpoint->out); + return USB_REQUEST_STATUS_OK; + } + return USB_REQUEST_STATUS_OK; +} + static const usb_request_handler_fn vendor_request_handler[] = { NULL, usb_vendor_request_set_transceiver_mode, @@ -779,7 +820,10 @@ static const usb_request_handler_fn vendor_request_handler[] = { usb_vendor_request_read_version_string, usb_vendor_request_set_freq, usb_vendor_request_set_amp_enable, - usb_vendor_request_read_partid_serialno + usb_vendor_request_read_partid_serialno, + usb_vendor_request_set_lna_gain, + usb_vendor_request_set_vga_gain, + usb_vendor_request_set_txvga_gain }; static const uint32_t vendor_request_handler_count =