Merge branches 'wbx_usrp2' and 'wbx_usrp1' of git://gnuradio.org/jabele
authorJohnathan Corgan <jcorgan@corganenterprises.com>
Sun, 21 Feb 2010 18:32:22 +0000 (10:32 -0800)
committerJohnathan Corgan <jcorgan@corganenterprises.com>
Sun, 21 Feb 2010 18:41:11 +0000 (10:41 -0800)
1  2  3 
usrp2/firmware/lib/adf4350.c
usrp2/firmware/lib/adf4350.h
usrp2/firmware/lib/adf4350_regs.c
usrp2/firmware/lib/db_wbxng.c
usrp2/firmware/lib/db_wbxng.h

index 0000000000000000000000000000000000000000,b2e8db8e231f0098062aecb7564fe2cc9ed5140e,0000000000000000000000000000000000000000..0725c93379533e123f0439196fe015b42b8d0b2f
mode 000000,100644,000000..100644
--- /dev/null
--- /dev/null
@@@@ -1,0 -1,211 -1,0 +1,209 @@@@
 -  * Copyright 2010 Ettus Research LLC
 -  *
+ +/*
+ + * Copyright 2010 Free Software Foundation, Inc.
+ + *
+ + * This program is free software: you can redistribute it and/or modify
+ + * it under the terms of the GNU General Public License as published by
+ + * the Free Software Foundation, either version 3 of the License, or
+ + * (at your option) any later version.
+ + *
+ + * This program is distributed in the hope that it will be useful,
+ + * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ + * GNU General Public License for more details.
+ + *
+ + * You should have received a copy of the GNU General Public License
+ + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ + *
+ + */
+ +
+ +#include "adf4350.h"
+ +#include "adf4350_regs.h"
+ +#include "db_wbxng.h"
+ +#include <spi.h>
+ +#include <hal_io.h>
+ +#include <stdio.h>
+ +#include <stdint.h>
+ +
+ +#define INPUT_REF_FREQ U2_DOUBLE_TO_FXPT_FREQ(50e6)
+ +#define INPUT_REF_FREQ_2X (2*INPUT_REF_FREQ)                            /* input ref freq with doubler turned on */
+ +#define MAX_RF_DIV UINT8_C(16)                                          /* max rf divider, divides rf output */
+ +#define MIN_VCO_FREQ U2_DOUBLE_TO_FXPT_FREQ(2.2e9)                      /* minimum vco freq */
+ +#define MAX_VCO_FREQ U2_DOUBLE_TO_FXPT_FREQ(4.4e9)                      /* minimum vco freq */
+ +#define MAX_FREQ MAX_VCO_FREQ                                           /* upper bound freq (rf div = 1) */
+ +#define MIN_FREQ DIV_ROUND(MIN_VCO_FREQ, MAX_RF_DIV)                    /* calculated lower bound freq */
+ +
+ +u2_fxpt_freq_t adf4350_get_max_freq(void){
+ +     return MAX_FREQ;
+ +}
+ +
+ +u2_fxpt_freq_t adf4350_get_min_freq(void){
+ +     return MIN_FREQ;
+ +}
+ +
+ +void adf4350_init(struct db_base *dbb){
+ +     struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+ +
+ +     /* Initialize the pin levels. */
+ +     hal_gpio_write( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK, PLL_CE, PLL_CE );
+ +     adf4350_enable(true, dbb);
+ +     /* Initialize the registers. */
+ +     adf4350_load_register(5, dbb);
+ +     adf4350_load_register(4, dbb);
+ +     adf4350_load_register(3, dbb);
+ +     adf4350_load_register(2, dbb);
+ +     adf4350_load_register(1, dbb);
+ +     adf4350_load_register(0, dbb);
+ +}
+ +
+ +/*
+ +void adf4350_update(void){
+ +     // mirror the lock detect pin to the led debug
+ +     if (adf4350_get_locked()){
+ +             io_set_pin(led_pin);
+ +     }else{
+ +             io_clear_pin(led_pin);
+ +     }
+ +}
+ +*/
+ +
+ +bool adf4350_get_locked(struct db_base *dbb){
+ +     struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+ +
+ +     int pins;
+ +     pins = hal_gpio_read( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK );
+ +     if(pins & PLL_LOCK_DETECT)
+ +             return true;
+ +     return false;
+ +}
+ +
+ +void adf4350_enable(bool enable, struct db_base *dbb){
+ +     struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+ +
+ +     if (enable){ /* chip enable */
+ +             hal_gpio_write( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK, PLL_PDBRF, PLL_PDBRF );
+ +     }else{
+ +             hal_gpio_write( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK, 0, PLL_PDBRF );
+ +     }
+ +}
+ +
+ +void adf4350_write(uint8_t addr, uint32_t data, struct db_base *dbb){
+ +     struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+ +
+ +     //printf("SPI write ADDR 0x%x, WORD 0x%x\n", (int) (addr), (int) (data));
+ +     data |= addr;
+ +     spi_transact(SPI_TXONLY,db->common.spi_mask,data,32,SPIF_PUSH_FALL);
+ +     //spi_read_write(clk_pin, data_pin, ld_pin, &data, 32);
+ +     /* pulse latch */
+ +     //io_set_pin(le_pin);
+ +     //io_clear_pin(le_pin);
+ +}
+ +
+ +bool adf4350_set_freq(u2_fxpt_freq_t freq, struct db_base *dbb){
+ +     struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+ +
+ +     /* Set the frequency by setting int, frac, mod, r, div */
+ +     if (freq > MAX_FREQ || freq < MIN_FREQ) return false;
+ +
+ +     /* Set the prescaler and the min N based on the freq. */
+ +     uint16_t min_int_div;
+ +     if (freq > U2_DOUBLE_TO_FXPT_FREQ(3e9) ){
+ +             db->common.adf4350_regs_prescaler = (uint8_t) 1;
+ +             min_int_div = UINT16_C(75);
+ +     }else{
+ +             db->common.adf4350_regs_prescaler = (uint8_t) 0;
+ +             min_int_div = UINT16_C(23);
+ +     }
+ +
+ +     /* Ramp up the RF divider until the VCO is within range. */
+ +     db->common.adf4350_regs_divider_select = (uint8_t) 0;
+ +     while (freq < MIN_VCO_FREQ){
+ +             freq <<= 1; //double the freq
+ +             db->common.adf4350_regs_divider_select++; //double the divider
+ +     }
+ +
+ +     /* Ramp up the R divider until the N divider is at least the minimum. */
+ +     db->common.adf4350_regs_10_bit_r_counter = (uint16_t) (DIV_ROUND((INPUT_REF_FREQ*min_int_div), freq));
+ +     //printf("Initial R setting: %u, MIN_INT: %u\n", db->common.adf4350_regs_10_bit_r_counter, min_int_div);
+ +     if (db->common.adf4350_regs_10_bit_r_counter * U2_DOUBLE_TO_FXPT_FREQ(32e6) < INPUT_REF_FREQ){
+ +             db->common.adf4350_regs_10_bit_r_counter = (uint16_t) (DIV_ROUND(INPUT_REF_FREQ, U2_DOUBLE_TO_FXPT_FREQ(32e6)));
+ +             //printf("Updating R setting: %u, MIN_INT: %u\n", db->common.adf4350_regs_10_bit_r_counter, min_int_div);
+ +     }
+ +
+ +     db->common.adf4350_regs_10_bit_r_counter--;
+ +     //db->common.adf4350_regs_10_bit_r_counter=1;
+ +
+ +     do{
+ +             db->common.adf4350_regs_10_bit_r_counter++;
+ +             /* throw out some fractional bits in freq to avoid overflow */
+ +             u2_fxpt_freq_t some_frac_freq = (U2_DOUBLE_TO_FXPT_FREQ(1.0)/db->common.adf4350_regs_mod);
+ +             uint64_t n_mod = DIV_ROUND(freq, some_frac_freq);
+ +             n_mod *= db->common.adf4350_regs_10_bit_r_counter;
+ +             n_mod *= db->common.adf4350_regs_mod;
+ +             n_mod = DIV_ROUND(n_mod, DIV_ROUND(INPUT_REF_FREQ, some_frac_freq));
+ +             /* calculate int and frac: regs_mod is a power of 2, this will optimize to a bitwise operation */
+ +             db->common.adf4350_regs_int = (uint16_t) (n_mod/db->common.adf4350_regs_mod);
+ +             db->common.adf4350_regs_frac = (uint16_t) (n_mod%db->common.adf4350_regs_mod);
+ +             //printf("Int %u < Min %u\n", db->common.adf4350_regs_int, min_int_div);
+ +     }while(db->common.adf4350_regs_int < min_int_div);
+ +
+ +     /* calculate the band select so PFD is under 125 KHz */
+ +     db->common.adf4350_regs_8_bit_band_select_clock_divider_value = \
+ +             (uint8_t) (INPUT_REF_FREQ/(U2_DOUBLE_TO_FXPT_FREQ(30e3)*db->common.adf4350_regs_10_bit_r_counter)) + 1;
+ +
+ +     /*
+ +     printf(
+ +             "VCO %u KHz, Int %u, Frac %u, Mod %u, R %u, Div %u, BandSelect %u\n",
+ +             (uint32_t) ((freq >> U2_FPF_RP)/1000),
+ +             (uint32_t) db->common.adf4350_regs_int,
+ +             (uint32_t) db->common.adf4350_regs_frac,
+ +             (uint32_t) db->common.adf4350_regs_mod,
+ +             (uint32_t) db->common.adf4350_regs_10_bit_r_counter,
+ +             (uint32_t) (1 << db->common.adf4350_regs_divider_select),
+ +             (uint32_t) db->common.adf4350_regs_8_bit_band_select_clock_divider_value
+ +     );
+ +     */
+ +
+ +     /* load involved registers */
+ +     adf4350_load_register(5, dbb);
+ +     adf4350_load_register(3, dbb);
+ +     adf4350_load_register(1, dbb);
+ +     adf4350_load_register(2, dbb);
+ +     adf4350_load_register(4, dbb);
+ +     adf4350_load_register(0, dbb); /* register 0 must be last */
+ +     return true;
+ +}
+ +
+ +u2_fxpt_freq_t adf4350_get_freq(struct db_base *dbb){
+ +     struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+ +
+ +     /* Calculate the freq from int, frac, mod, ref, r, div:
+ +      *  freq = (int + frac/mod) * (ref/r)
+ +      * Keep precision by doing multiplies first:
+ +      *  freq = (((((((int)*mod) + frac)*ref)/mod)/r)/div)
+ +      */
+ +     uint64_t temp;
+ +     temp = (uint64_t) db->common.adf4350_regs_int;
+ +     temp *= (uint64_t) db->common.adf4350_regs_mod;
+ +     temp += (uint64_t) db->common.adf4350_regs_frac;
+ +     temp *= (uint64_t) (INPUT_REF_FREQ >> U2_FPF_RP);
+ +     temp /= (uint64_t) db->common.adf4350_regs_mod;
+ +     temp /= (uint64_t) db->common.adf4350_regs_10_bit_r_counter;
+ +     temp /= (uint64_t) (1 << db->common.adf4350_regs_divider_select);
+ +
+ +     /* Shift 1Hz Radix Point for u2_fxpt_freq_t */
+ +     temp = temp << U2_FPF_RP;
+ +
+ +     /*
+ +     printf(
+ +             "Got Freq %u KHz, Int %u, Frac %u, Mod %u, R %u, Div %u\n",
+ +             (uint32_t) ((temp >> U2_FPF_RP)/1000),
+ +             (uint32_t) db->common.adf4350_regs_int,
+ +             (uint32_t) db->common.adf4350_regs_frac,
+ +             (uint32_t) db->common.adf4350_regs_mod,
+ +             (uint32_t) db->common.adf4350_regs_10_bit_r_counter,
+ +             (uint32_t) (1 << db->common.adf4350_regs_divider_select)
+ +     );
+ +     */
+ +
+ +     return (u2_fxpt_freq_t) (temp);
+ +}
index 0000000000000000000000000000000000000000,5ee13ddbb9e61e946a7c2e11b9a0244c897f2126,0000000000000000000000000000000000000000..3c66ec3448cc80a9a8dca8a332f99bbf8870038e
mode 000000,100644,000000..100644
--- /dev/null
--- /dev/null
@@@@ -1,0 -1,42 -1,0 +1,40 @@@@
 -  * Copyright 2010 Ettus Research LLC
 -  *
+ +/*
+ + * Copyright 2010 Free Software Foundation, Inc.
+ + *
+ + * This program is free software: you can redistribute it and/or modify
+ + * it under the terms of the GNU General Public License as published by
+ + * the Free Software Foundation, either version 3 of the License, or
+ + * (at your option) any later version.
+ + *
+ + * This program is distributed in the hope that it will be useful,
+ + * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ + * GNU General Public License for more details.
+ + *
+ + * You should have received a copy of the GNU General Public License
+ + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ + *
+ + */
+ +
+ +#ifndef ADF4350_H
+ +#define ADF4350_H
+ +
+ +#include <db_base.h>
+ +#include <stdbool.h>
+ +#include <stdint.h>
+ +
+ +#define DIV_ROUND(num, denom) (((num) + ((denom)/2))/(denom))
+ +#define UINT8_C(num) ((uint8_t) (num))
+ +#define UINT16_C(num) ((uint16_t) (num))
+ +
+ +void adf4350_init(struct db_base *dbb);
+ +//void adf4350_update(void);
+ +bool adf4350_get_locked(struct db_base *dbb);
+ +void adf4350_enable(bool enable, struct db_base *dbb);
+ +void adf4350_write(uint8_t addr, uint32_t data, struct db_base *dbb);
+ +bool adf4350_set_freq(u2_fxpt_freq_t freq, struct db_base *dbb);
+ +u2_fxpt_freq_t adf4350_get_freq(struct db_base *dbb);
+ +u2_fxpt_freq_t adf4350_get_max_freq(void);
+ +u2_fxpt_freq_t adf4350_get_min_freq(void);
+ +
+ +#endif /* ADF4350_H */
index 0000000000000000000000000000000000000000,196a97c5b98b565215989da518cf50f9c30edc97,0000000000000000000000000000000000000000..e2740d3ab8970698411a72f0e788320bdd3a236d
mode 000000,100644,000000..100644
--- /dev/null
--- /dev/null
@@@@ -1,0 -1,105 -1,0 +1,103 @@@@
 -  * Copyright 2010 Ettus Research LLC
 -  *
+ +/*
+ + * Copyright 2010 Free Software Foundation, Inc.
+ + *
+ + * This program is free software: you can redistribute it and/or modify
+ + * it under the terms of the GNU General Public License as published by
+ + * the Free Software Foundation, either version 3 of the License, or
+ + * (at your option) any later version.
+ + *
+ + * This program is distributed in the hope that it will be useful,
+ + * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ + * GNU General Public License for more details.
+ + *
+ + * You should have received a copy of the GNU General Public License
+ + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ + *
+ + */
+ +
+ +#include "adf4350_regs.h"
+ +#include "adf4350.h"
+ +#include "db_wbxng.h"
+ +
+ +#define _REG_SHIFT(reg, shift) (((uint32_t)(reg)) << (shift))
+ +
+ +/* reg 0 */
+ +/* reg 1 */
+ +static const uint16_t adf4350_regs_phase = 0;                           /* 0 */
+ +/* reg 2 */
+ +static const uint8_t adf4350_regs_low_noise_and_low_spur_modes = 3;     /* low noise mode */
+ +static const uint8_t adf4350_regs_muxout = 3;                           /* digital lock detect */
+ +static const uint8_t adf4350_regs_reference_doubler = 0;                /* disabled */
+ +static const uint8_t adf4350_regs_rdiv2 = 1;                            /* disabled */
+ +static const uint8_t adf4350_regs_double_buff = 0;                      /* disabled */
+ +static const uint8_t adf4350_regs_charge_pump_setting = 5;              /* 2.50 mA */
+ +static const uint8_t adf4350_regs_ldf = 0;                              /* frac-n */
+ +static const uint8_t adf4350_regs_ldp = 0;                              /* 10 ns */
+ +static const uint8_t adf4350_regs_pd_polarity = 1;                      /* positive */
+ +static const uint8_t adf4350_regs_power_down = 0;                       /* disabled */
+ +static const uint8_t adf4350_regs_cp_three_state = 0;                   /* disabled */
+ +static const uint8_t adf4350_regs_counter_reset = 0;                    /* disabled */
+ +/* reg 3 */
+ +static const uint8_t adf4350_regs_csr = 0;                              /* disabled */
+ +static const uint8_t adf4350_regs_clk_div_mode = 0;                     /* clock divider off */
+ +static const uint16_t adf4350_regs_12_bit_clock_divider_value = 0;      /* 0 */
+ +/* reg 4 */
+ +static const uint8_t adf4350_regs_feedback_select = 1;                  /* fundamental */
+ +static const uint8_t adf4350_regs_vco_power_down = 0;                   /* vco powered up */
+ +static const uint8_t adf4350_regs_mtld = 0;                             /* mute disabled */
+ +static const uint8_t adf4350_regs_aux_output_select = 1;                /* divided output */
+ +static const uint8_t adf4350_regs_aux_output_enable = 1;                /* disabled */
+ +static const uint8_t adf4350_regs_aux_output_power = 0;                 /* -4 */
+ +static const uint8_t adf4350_regs_rf_output_enable = 1;                 /* enabled */
+ +static const uint8_t adf4350_regs_output_power = 3;                     /* -1 */
+ +/* reg 5 */
+ +static const uint8_t adf4350_regs_ld_pin_mode = 1;                      /* digital lock detect */
+ +
+ +void adf4350_load_register(uint8_t addr, struct db_base *dbb){
+ +     struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+ +     uint32_t data;
+ +     switch (addr){
+ +             case 0: data = (
+ +                     _REG_SHIFT(db->common.adf4350_regs_int, 15)                |
+ +                     _REG_SHIFT(db->common.adf4350_regs_frac, 3)); break;
+ +             case 1: data = (
+ +                     _REG_SHIFT(db->common.adf4350_regs_prescaler, 27)          |
+ +                     _REG_SHIFT(adf4350_regs_phase, 15)                         |
+ +                     _REG_SHIFT(db->common.adf4350_regs_mod, 3)); break;
+ +             case 2: data = (
+ +                     _REG_SHIFT(adf4350_regs_low_noise_and_low_spur_modes, 29)  |
+ +                     _REG_SHIFT(adf4350_regs_muxout, 26)                        |
+ +                     _REG_SHIFT(adf4350_regs_reference_doubler, 25)             |
+ +                     _REG_SHIFT(adf4350_regs_rdiv2, 24)                         |
+ +                     _REG_SHIFT(db->common.adf4350_regs_10_bit_r_counter, 14)   |
+ +                     _REG_SHIFT(adf4350_regs_double_buff, 13)                   |
+ +                     _REG_SHIFT(adf4350_regs_charge_pump_setting, 9)            |
+ +                     _REG_SHIFT(adf4350_regs_ldf, 8)                            |
+ +                     _REG_SHIFT(adf4350_regs_ldp, 7)                            |
+ +                     _REG_SHIFT(adf4350_regs_pd_polarity, 6)                    |
+ +                     _REG_SHIFT(adf4350_regs_power_down, 5)                     |
+ +                     _REG_SHIFT(adf4350_regs_cp_three_state, 4)                 |
+ +                     _REG_SHIFT(adf4350_regs_counter_reset, 3)); break;
+ +             case 3: data = (
+ +                     _REG_SHIFT(adf4350_regs_csr, 18)                           |
+ +                     _REG_SHIFT(adf4350_regs_clk_div_mode, 15)                  |
+ +                     _REG_SHIFT(adf4350_regs_12_bit_clock_divider_value, 3)); break;
+ +             case 4: data = (
+ +                     _REG_SHIFT(adf4350_regs_feedback_select, 23)               |
+ +                     _REG_SHIFT(db->common.adf4350_regs_divider_select, 20)     |
+ +                     _REG_SHIFT(db->common.adf4350_regs_8_bit_band_select_clock_divider_value, 12) |
+ +                     _REG_SHIFT(adf4350_regs_vco_power_down, 11)                |
+ +                     _REG_SHIFT(adf4350_regs_mtld, 10)                          |
+ +                     _REG_SHIFT(adf4350_regs_aux_output_select, 9)              |
+ +                     _REG_SHIFT(adf4350_regs_aux_output_enable, 8)              |
+ +                     _REG_SHIFT(adf4350_regs_aux_output_power, 6)               |
+ +                     _REG_SHIFT(adf4350_regs_rf_output_enable, 5)               |
+ +                     _REG_SHIFT(adf4350_regs_output_power, 3)); break;
+ +             case 5: data = (
+ +                     _REG_SHIFT(adf4350_regs_ld_pin_mode, 22)); break;
+ +             default: return;
+ +     }
+ +     /* write the data out to spi */
+ +     adf4350_write(addr, data, dbb);
+ +}
index 0000000000000000000000000000000000000000,1620c6629eb3c3ca66f0d5b01bb5b761e14ccf26,0000000000000000000000000000000000000000..c02a5bdaa95ac2af3e431872d595584d425fe3bf
mode 000000,100644,000000..100644
--- /dev/null
--- /dev/null
@@@@ -1,0 -1,216 -1,0 +1,214 @@@@
 -  * Copyright 2010 Ettus Research LLC
 -  *
+ +/*
+ + * Copyright 2010 Free Software Foundation, Inc.
+ + *
+ + * This program is free software: you can redistribute it and/or modify
+ + * it under the terms of the GNU General Public License as published by
+ + * the Free Software Foundation, either version 3 of the License, or
+ + * (at your option) any later version.
+ + *
+ + * This program is distributed in the hope that it will be useful,
+ + * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ + * GNU General Public License for more details.
+ + *
+ + * You should have received a copy of the GNU General Public License
+ + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ + *
+ + */
+ +
+ +
+ +#include "db_wbxng.h"
+ +#include "adf4350.h"
+ +#include <spi.h>
+ +#include <memory_map.h>
+ +#include <db_base.h>
+ +#include <hal_io.h>
+ +#include <mdelay.h>
+ +#include <lsdac.h>
+ +#include <clocks.h>
+ +#include <stdio.h>
+ +#include <stdint.h>
+ +
+ +bool wbxng_init_rx(struct db_base *dbb);
+ +bool wbxng_init_tx(struct db_base *dbb);
+ +bool wbxng_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc);
+ +bool wbxng_set_gain_rx(struct db_base *dbb, u2_fxpt_gain_t gain);
+ +bool wbxng_set_gain_tx(struct db_base *dbb, u2_fxpt_gain_t gain);
+ +bool wbxng_set_tx_enable(struct db_base *dbb, bool on);
+ +
+ +
+ +/*
+ + * The class instances
+ + */
+ +struct db_wbxng_rx db_wbxng_rx = {
+ +  .base.dbid = 0x0053,
+ +  .base.is_tx = false,
+ +  .base.output_enables = RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5|PLL_CE|PLL_PDBRF|ATTN_MASK,
+ +  .base.used_pins = 0xFFFF,
+ +  .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(67.5e6),
+ +  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2200e6),
+ +  .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
+ +  .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(31.5),
+ +  .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(0.5),
+ +  .base.is_quadrature = true,
+ +  .base.i_and_q_swapped = false,
+ +  .base.spectrum_inverted = false,
+ +  .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0),
+ +  .base.init = wbxng_init_rx,
+ +  .base.set_freq = wbxng_set_freq,
+ +  .base.set_gain = wbxng_set_gain_rx,
+ +  .base.set_tx_enable = 0,
+ +  .base.atr_mask = RXBB_EN | RX2_RX1N,
+ +  .base.atr_txval = RX2_RX1N,
+ +  .base.atr_rxval = RXBB_EN,
+ +  // .base.atr_tx_delay =
+ +  // .base.atr_rx_delay =
+ +  .common.adf4350_regs_int = UINT16_C(100),
+ +  .common.adf4350_regs_frac = 0,
+ +  .common.adf4350_regs_prescaler = 1,
+ +  .common.adf4350_regs_mod = UINT16_C(0xfff),
+ +  .common.adf4350_regs_10_bit_r_counter = UINT16_C(1),
+ +  .common.adf4350_regs_divider_select = 0,
+ +  .common.adf4350_regs_8_bit_band_select_clock_divider_value = 0,
+ +  .common.spi_mask = SPI_SS_RX_DB,
+ +  .common.freq_mult = 2
+ +};
+ +
+ +
+ +struct db_wbxng_tx db_wbxng_tx = {
+ +  .base.dbid = 0x0052,
+ +  .base.is_tx = true,
+ +  .base.output_enables = RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5|PLL_CE|PLL_PDBRF,
+ +  .base.used_pins = 0xFFFF,
+ +  .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(67.5e6),
+ +  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2200e6),
+ +  .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
+ +  .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(25),
+ +  .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(0.1),
+ +  .base.is_quadrature = true,
+ +  .base.i_and_q_swapped = false,
+ +  .base.spectrum_inverted = false,
+ +  .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0),
+ +  .base.init = wbxng_init_tx,
+ +  .base.set_freq = wbxng_set_freq,
+ +  .base.set_gain = wbxng_set_gain_tx,
+ +  .base.set_tx_enable = wbxng_set_tx_enable,
+ +  .base.atr_mask = RX_TXN | TXMOD_EN,
+ +  .base.atr_txval = TXMOD_EN,
+ +  .base.atr_rxval = RX_TXN,
+ +  // .base.atr_tx_delay =
+ +  // .base.atr_rx_delay =
+ +  .common.adf4350_regs_int = UINT16_C(100),
+ +  .common.adf4350_regs_frac = 0,
+ +  .common.adf4350_regs_prescaler = 1,
+ +  .common.adf4350_regs_mod = UINT16_C(0xfff),
+ +  .common.adf4350_regs_10_bit_r_counter = UINT16_C(1),
+ +  .common.adf4350_regs_divider_select = 0,
+ +  .common.adf4350_regs_8_bit_band_select_clock_divider_value = 0,
+ +  .common.spi_mask = SPI_SS_TX_DB,
+ +  .common.freq_mult = 2
+ +};
+ +
+ +
+ +bool
+ +wbxng_init_tx(struct db_base *dbb)
+ +{
+ +  //struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+ +  clocks_enable_tx_dboard(true, 0);
+ +  hal_gpio_write( GPIO_TX_BANK, ENABLE_5|ENABLE_33, ENABLE_5|ENABLE_33 );
+ +
+ +  adf4350_init(dbb);
+ +
+ +  // Set the freq now to get the one time 10ms delay out of the way.
+ +  u2_fxpt_freq_t     dc;
+ +  dbb->set_freq(dbb, dbb->freq_min, &dc);
+ +  return true;
+ +}
+ +
+ +bool
+ +wbxng_init_rx(struct db_base *dbb)
+ +{
+ +  //struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+ +  clocks_enable_rx_dboard(true, 0);
+ +  hal_gpio_write( GPIO_RX_BANK, ENABLE_5|ENABLE_33, ENABLE_5|ENABLE_33 );
+ +
+ +  adf4350_init(dbb);
+ +
+ +  // test gain
+ +  dbb->set_gain(dbb,U2_DOUBLE_TO_FXPT_GAIN(20.0));
+ +
+ +  // Set the freq now to get the one time 10ms delay out of the way.
+ +  u2_fxpt_freq_t     dc;
+ +  dbb->set_freq(dbb, dbb->freq_min, &dc);
+ +
+ +  return true;
+ +}
+ +
+ +bool
+ +wbxng_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc)
+ +{
+ +  bool ok = adf4350_set_freq(2*freq,dbb);
+ +  *dc = adf4350_get_freq(dbb)/2;
+ +
+ +  return ok;
+ +}
+ +
+ +bool
+ +wbxng_set_gain_tx(struct db_base *dbb, u2_fxpt_gain_t gain)
+ +{
+ +  struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+ +
+ +  // clamp gain
+ +  //gain = max(db->gain_min, min(gain, db->gain_max));
+ +
+ +  int offset_q8 = (int)(1.4/3.3*4096*(1<<15));
+ +  int range_q15 = (int)(-0.9*4096/3.3*256*128);
+ +  int slope_q8 = range_q15/db->base.gain_max;
+ +
+ +  int dacword = ((slope_q8 * gain) + offset_q8)>>15;
+ +  //printf("DACWORD 0x%x\n",dacword);
+ +  lsdac_write_tx(0,dacword);
+ +  return true;
+ +}
+ +
+ +bool
+ +wbxng_set_gain_rx(struct db_base *dbb, u2_fxpt_gain_t gain)
+ +{
+ +  struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+ +
+ +  // clamp gain
+ +  //gain = max(db->gain_min, min(gain, db->gain_max));
+ +
+ +  int iobits = (int) ((~((db->base.gain_max - gain) << 2)) & ATTN_MASK);
+ +  //printf("gain %d, gainmax %d, RX_ATTN_MASK = 0x%x, RX_ATTN_WORD = 0x%x\n", gain, db->base.gain_max, (int) (ATTN_MASK), (int) (iobits));
+ +
+ +  hal_gpio_write( GPIO_RX_BANK, (int) (iobits), ATTN_MASK );
+ +  return true;
+ +}
+ +
+ +
+ +bool
+ +wbxng_set_tx_enable(struct db_base *dbb, bool on)
+ +{
+ +  struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+ +
+ +  // FIXME
+ +
+ +  return false;
+ +}
+ +
+ +bool
+ +wbxng_lock_detect(struct db_base *dbb)
+ +{
+ +  struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+ +
+ +  int pins;
+ +  pins = hal_gpio_read( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK );
+ +  if(pins & PLL_LOCK_DETECT)
+ +    //printf("Got Locked Status from Synth");
+ +    return true;
+ +
+ +  //printf("Got Unlocked Status from Synth");
+ +  return false;
+ +}
+ +
index 0000000000000000000000000000000000000000,b2437cbccd09f218227aaa1666b3e0c2de7efa4b,0000000000000000000000000000000000000000..3756e6c241d43e46137cb1301242e134a4bee1bc
mode 000000,100644,000000..100644
--- /dev/null
--- /dev/null
@@@@ -1,0 -1,76 -1,0 +1,74 @@@@
 -  * Copyright 2010 Ettus Research LLC
 -  *
+ +/*
+ + * Copyright 2010 Free Software Foundation, Inc.
+ + *
+ + * This program is free software: you can redistribute it and/or modify
+ + * it under the terms of the GNU General Public License as published by
+ + * the Free Software Foundation, either version 3 of the License, or
+ + * (at your option) any later version.
+ + *
+ + * This program is distributed in the hope that it will be useful,
+ + * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ + * GNU General Public License for more details.
+ + *
+ + * You should have received a copy of the GNU General Public License
+ + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ + *
+ + */
+ +
+ +#ifndef DB_WBXNG_H
+ +#define DB_WBXNG_H
+ +
+ +#include <db_base.h>
+ +
+ +// IO Pin functions
+ +// Tx and Rx have shared defs, but different i/o regs
+ +#define ENABLE_5        (1 << 7)              // enables 5.0V power supply
+ +#define ENABLE_33       (1 << 6)              // enables 3.3V supply
+ +//#define RX_TXN          (1 << 15)             // Tx only: T/R antenna switch for TX/RX port
+ +//#define RX2_RX1N        (1 << 15)             // Rx only: antenna switch between RX2 and TX/RX port
+ +#define RX_TXN          ((1 << 5)|(1 << 15))  // Tx only: T/R antenna switch for TX/RX port
+ +#define RX2_RX1N        ((1 << 5)|(1 << 15))  // Rx only: antenna switch between RX2 and TX/RX port
+ +#define RXBB_EN         (1 << 4)
+ +#define TXMOD_EN        (1 << 4)
+ +#define PLL_CE          (1 << 3)
+ +#define PLL_PDBRF       (1 << 2)
+ +#define PLL_MUXOUT      (1 << 1)
+ +#define PLL_LOCK_DETECT (1 << 0)
+ +
+ +// RX Attenuator constants
+ +#define ATTN_SHIFT   8
+ +#define ATTN_MASK    (63 << ATTN_SHIFT)
+ +
+ +struct db_wbxng_common {
+ +  // RFX common stuff
+ +  uint16_t adf4350_regs_int;
+ +  uint16_t adf4350_regs_frac;
+ +  uint8_t adf4350_regs_prescaler;
+ +  uint16_t adf4350_regs_mod;
+ +  uint16_t adf4350_regs_10_bit_r_counter;
+ +  uint8_t adf4350_regs_divider_select;
+ +  uint8_t adf4350_regs_8_bit_band_select_clock_divider_value;
+ +
+ +  int freq_mult;
+ +  int spi_mask;
+ +};
+ +
+ +struct db_wbxng_dummy {
+ +  struct db_base     base;
+ +  struct db_wbxng_common     common;
+ +};
+ +
+ +
+ +struct db_wbxng_rx {
+ +  struct db_base     base;
+ +  struct db_wbxng_common     common;
+ +};
+ +
+ +struct db_wbxng_tx {
+ +  struct db_base     base;
+ +  struct db_wbxng_common     common;
+ +};
+ +
+ +
+ +#endif /* DB_WBXNG_H */