Revision 096dbe5c

b/gr-vrt/src/Makefile.am
54 54
libgnuradio_vrt_la_SOURCES = \
55 55
	missing_pkt_checker.cc \
56 56
	vrt_source_base.cc \
57
	vrt_source_32fc.cc \
58
	vrt_quadradio_source_32fc.cc
57
	vrt_source_32fc.cc
59 58

60 59

61 60
#libgnuradio_vrt_la_SOURCES = \
......
77 76
grinclude_HEADERS = \
78 77
	vrt_source_base.h \
79 78
	vrt_source_32fc.h \
80
	vrt_quadradio_source_32fc.h \
81 79
	missing_pkt_checker.h
82 80

83 81
#	vrt_source_16sc.h \
......
95 93
# _vrt.so
96 94
# ----------------------------------------------------------------------
97 95

98
TOP_SWIG_IFILES =		\
99
	vrt.i
96
#TOP_SWIG_IFILES =		\
97
#	vrt.i
100 98

101 99
# Install so that they end up available as:
102 100
#   import gnuradio.vrt
103 101
# This ends up at:
104 102
#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
105
vrt_pythondir_category =	\
106
	gnuradio
103
#vrt_pythondir_category =	\
104
#	gnuradio
107 105

108 106
# additional arguments to the SWIG command
109
vrt_swig_args =		\
110
	$(VRT_INCLUDES)
107
#vrt_swig_args =		\
108
#	$(VRT_INCLUDES)
111 109

112 110
# additional libraries for linking with the SWIG-generated library
113
vrt_la_swig_libadd =		\
114
	libgnuradio-vrt.la
111
#vrt_la_swig_libadd =		\
112
#	libgnuradio-vrt.la
115 113

116
include $(top_srcdir)/Makefile.swig
114
#include $(top_srcdir)/Makefile.swig
117 115

118 116
# add some of the variables generated inside the Makefile.swig.gen
119
BUILT_SOURCES = $(swig_built_sources)
117
#BUILT_SOURCES = $(swig_built_sources)
120 118

121 119
# Do not distribute the output of SWIG
122
no_dist_files = $(swig_built_sources)
120
#no_dist_files = $(swig_built_sources)
/dev/null
1
/* -*- c++ -*- */
2
/*
3
 * Copyright 2008,2009 Free Software Foundation, Inc.
4
 * 
5
 * This file is part of GNU Radio
6
 * 
7
 * GNU Radio is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3, or (at your option)
10
 * any later version.
11
 * 
12
 * GNU Radio is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 * 
17
 * You should have received a copy of the GNU General Public License
18
 * along with GNU Radio; see the file COPYING.  If not, write to
19
 * the Free Software Foundation, Inc., 51 Franklin Street,
20
 * Boston, MA 02110-1301, USA.
21
 */
22

23
%include "gnuradio.i"	// the common stuff
24
%import <stdint.i>
25

26
%{
27
#include "vrt_quadradio_source_32fc.h"
28
#include <vrt/quadradio.h>
29
//#include "vrt_quadradio_source_16sc.h"
30
//#include "vrt_sink_32fc.h"
31
//#include "vrt_sink_16sc.h"
32
%}
33

34
%template(uint32_t_vector) std::vector<uint32_t>;
35

36
// ----------------------------------------------------------------
37

38
class vrt_source_base : public gr_sync_block
39
{
40
protected:
41
  vrt_source_base() throw (std::runtime_error);
42

43
public:
44
  ~vrt_source_base();
45

46
};
47

48
class vrt_source_32fc : public vrt_source_base
49
{
50
protected:
51
  vrt_source_32fc() throw (std::runtime_error);
52

53
public:
54
  ~vrt_source_32fc();
55
  void reset();
56
};
57

58
// ----------------------------------------------------------------
59

60
GR_SWIG_BLOCK_MAGIC(vrt,quadradio_source_32fc)
61

62
%include "vrt_quadradio_source_32fc.h"
63

64
%include <vrt/quadradio.h>
/dev/null
1
/* -*- c++ -*- */
2
/*
3
 * Copyright 2009 Free Software Foundation, Inc.
4
 * 
5
 * This file is part of GNU Radio
6
 * 
7
 * GNU Radio is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3, or (at your option)
10
 * any later version.
11
 * 
12
 * GNU Radio is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 * 
17
 * You should have received a copy of the GNU General Public License along
18
 * with this program; if not, write to the Free Software Foundation, Inc.,
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
 */
21
#ifdef HAVE_CONFIG_H
22
#include <config.h>
23
#endif
24
#include <vrt_quadradio_source_32fc.h>
25
#include <vrt/quadradio.h>
26
#include <vrt/rx_packet_handler.h>
27
#include <cstdio>
28

29
vrt_quadradio_source_32fc_sptr
30
vrt_make_quadradio_source_32fc(const std::string &ip, 
31
			       size_t rx_bufsize,
32
			       size_t samples_per_pkt,
33
			       int rxdspno)
34
{
35
  return gnuradio::get_initial_sptr(new vrt_quadradio_source_32fc(ip,
36
								  rx_bufsize,
37
								  samples_per_pkt,
38
								  rxdspno));
39
}
40

41
vrt_quadradio_source_32fc::vrt_quadradio_source_32fc(const std::string &ip,
42
						     size_t rx_bufsize,
43
						     size_t samples_per_pkt,
44
                             int rxdspno)
45
  : vrt_source_32fc("quadradio_source_32fc"),
46
    d_samples_per_pkt(samples_per_pkt == 0 ? (rxdspno == 0 ? 800 : 200) : samples_per_pkt),
47
    d_qr(vrt::quadradio::sptr(new vrt::quadradio(ip, rx_bufsize))),
48
    d_rxdspno(rxdspno)
49
{
50
}
51

52
vrt_quadradio_source_32fc::~vrt_quadradio_source_32fc()
53
{
54
  d_qr->stop_streaming(d_rxdspno);
55
}
56

57
vrt::rx::sptr 
58
vrt_quadradio_source_32fc::vrt_rx() const
59
{
60
  return d_qr->vrt_rx();
61
}
62

63
bool 
64
vrt_quadradio_source_32fc::start()
65
{
66
  // throw away any stale packets before starting
67
  vrt::rx_packet_handler nop;
68
  vrt_rx()->rx_packets(&nop, true);
69
  d_checker.resync();
70

71
  return d_qr->start_streaming(d_rxdspno, d_samples_per_pkt);
72
}  
73

74
bool
75
vrt_quadradio_source_32fc::stop()
76
{
77
  return d_qr->stop_streaming(d_rxdspno);
78
}
79

80
bool 
81
vrt_quadradio_source_32fc::set_dboard_pins(int which_dboard, int v)
82
{
83
  return d_qr->set_dboard_pins(which_dboard, v);
84
}
85

86
bool 
87
vrt_quadradio_source_32fc::set_center_freq(double target_freq)
88
{
89
  return d_qr->set_center_freq(target_freq);
90
}
91

92
bool 
93
vrt_quadradio_source_32fc::set_band_select(int band)
94
{
95
  return d_qr->set_band_select(static_cast<vrt_band_sel_t>(band));
96
}
97

98
int 
99
vrt_quadradio_source_32fc::get_band_select(void)
100
{
101
  return static_cast<int>(d_qr->get_band_select());
102
}
103

104
//void 
105
//vrt_quadradio_source_32fc::set_10dB_atten(bool on)
106
//{
107
//  return d_qr->set_10dB_atten(on);
108
//}
109

110
bool 
111
vrt_quadradio_source_32fc::select_rx_antenna(const std::string &ant)
112
{
113
  return d_qr->select_rx_antenna(ant);
114
}
115

116
bool 
117
vrt_quadradio_source_32fc::set_attenuation0(int attenuation)
118
{
119
  return d_qr->set_attenuation0(attenuation);
120
}
121

122
bool 
123
vrt_quadradio_source_32fc::set_attenuation1(int attenuation)
124
{
125
  return d_qr->set_attenuation1(attenuation);
126
}
127

128
void
129
vrt_quadradio_source_32fc::set_adc_gain(bool on){
130
  d_qr->set_adc_gain(on);
131
}
132

133
void
134
vrt_quadradio_source_32fc::set_dc_offset_comp(bool on){
135
  d_qr->set_dc_offset_comp(on);
136
}
137

138
void
139
vrt_quadradio_source_32fc::set_digital_gain(float gain){
140
  d_qr->set_digital_gain(gain);
141
}
142

143
void
144
vrt_quadradio_source_32fc::set_test_signal(int type){
145
  d_qr->set_test_signal(static_cast<vrt_test_sig_t>(type));
146
}
147

148
bool
149
vrt_quadradio_source_32fc::set_setting_reg(int regno, int value)
150
{
151
  return d_qr->set_setting_reg(regno, value);
152
}
153

154
bool
155
vrt_quadradio_source_32fc::set_hsadc_conf(int which_dboard, int regno, int value)
156
{
157
  return d_qr->set_hsadc_conf(which_dboard, regno, value);
158
}
159

160
bool
161
vrt_quadradio_source_32fc::set_lsdac(int which_dboard, int which_dac, int value)
162
{
163
  return d_qr->set_lsdac(which_dboard, which_dac, value);
164
}
165

166
bool
167
vrt_quadradio_source_32fc::set_mem32(int addr, int value)
168
{
169
  return d_qr->set_mem32(addr, value);
170
}
171

172
bool
173
vrt_quadradio_source_32fc::set_lo_freq(double freq)
174
{
175
  return d_qr->set_lo_freq(freq);
176
}
177

178
bool
179
vrt_quadradio_source_32fc::set_cal_freq(double freq)
180
{
181
  return d_qr->set_cal_freq(freq);
182
}
183

184
/*--------------------------------------------------------------------*/
185
#define IQ_IMBAL_NUM_TAPS 30
186
#define IQ_IMBAL_REG_NO 162
187

188
//helper function to set the iq imbalance register with a tap
189
static int get_iq_imbal_reg(bool real, bool init, float tap){
190
  int val = int(round(tap));
191
  val &= 0x1ffffff; //lower 25 bits for tap
192
  val |= (real?0:1) << 30; //30th bit for filter type
193
  val |= (init?1:0) << 31; //31st bit for initialization
194
  printf("Reg %d Val %x\n", IQ_IMBAL_REG_NO, val);
195
  return val;
196
}
197

198
void
199
vrt_quadradio_source_32fc::set_iq_imbal_taps(const std::vector<gr_complex> taps){
200
  int i = 0;
201
  /* set the real part of the taps */
202
  get_iq_imbal_reg(true, true, 0);
203
  for (i = 0; i < IQ_IMBAL_NUM_TAPS; i++){
204
      set_setting_reg(IQ_IMBAL_REG_NO, get_iq_imbal_reg(true, false, taps[IQ_IMBAL_NUM_TAPS-i-1].real()));
205
  }
206
  get_iq_imbal_reg(false, true, 0);
207
  /* set the imaginary part of the taps */
208
  for (i = 0; i < IQ_IMBAL_NUM_TAPS; i++){
209
      set_setting_reg(IQ_IMBAL_REG_NO, get_iq_imbal_reg(false, false, taps[IQ_IMBAL_NUM_TAPS-i-1].imag()));
210
  }
211
}
212

213
bool
214
vrt_quadradio_source_32fc::set_beamforming(std::vector<gr_complex> gains){
215
  int32_t gains_ints[8];
216
  for (int i = 0; i < 4; i++){
217
    gains_ints[2*i] = int32_t(gains[i].real());
218
    gains_ints[2*i+1] = int32_t(gains[i].imag());
219
  }
220
 return d_qr->set_beamforming(gains_ints);
221
}
222

223
bool
224
vrt_quadradio_source_32fc::set_cal_enb(bool enb){
225
  return d_qr->set_cal_enb(enb);
226
}
/dev/null
1
/* -*- c++ -*- */
2
/*
3
 * Copyright 2009 Free Software Foundation, Inc.
4
 * 
5
 * This file is part of GNU Radio
6
 * 
7
 * GNU Radio is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3, or (at your option)
10
 * any later version.
11
 * 
12
 * GNU Radio is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 * 
17
 * You should have received a copy of the GNU General Public License along
18
 * with this program; if not, write to the Free Software Foundation, Inc.,
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
 */
21
#ifndef INCLUDED_VRT_QUADRADIO_SOURCE_32FC_H
22
#define INCLUDED_VRT_QUADRADIO_SOURCE_32FC_H
23

24
#include <vrt_source_32fc.h>
25

26
namespace vrt {
27
  class quadradio;
28
};
29

30
class vrt_quadradio_source_32fc;
31
typedef boost::shared_ptr<vrt_quadradio_source_32fc> vrt_quadradio_source_32fc_sptr;
32

33
vrt_quadradio_source_32fc_sptr
34
vrt_make_quadradio_source_32fc(const std::string &ip,
35
			       size_t rx_bufsize = 0,
36
			       size_t samples_per_pkt = 0,
37
			       int rxdspno = 0);
38

39
class vrt_quadradio_source_32fc : public vrt_source_32fc
40
{
41
  size_t				d_samples_per_pkt;
42
  boost::shared_ptr<vrt::quadradio>	d_qr;
43
  int 					d_rxdspno;
44

45
  vrt_quadradio_source_32fc(const std::string &ip, size_t rx_bufsize,
46
			    size_t samples_per_pkt, int rxdspno);
47

48
  friend vrt_quadradio_source_32fc_sptr
49
  vrt_make_quadradio_source_32fc(const std::string &ip, size_t rx_bufsize,
50
				 size_t samples_per_pkt, int rxdspno);
51

52
public:
53
  virtual ~vrt_quadradio_source_32fc();
54
  virtual vrt::rx::sptr vrt_rx() const;
55

56
  /*!
57
   * \brief Called by scheduler when starting flowgraph
58
   */
59
  virtual bool start();
60
  
61
  /*!
62
   * \brief Called by scheduler when stopping flowgraph
63
   */
64
  virtual bool stop();
65

66
  /*!
67
   * \brief Set the LO frequency (actually just sets the band select for now).
68
   */
69
  bool set_center_freq(double target_freq);
70

71
  /*!
72
   * \brief Set the band select dboard bits.
73
   */
74
  bool set_band_select(int band);
75
  int get_band_select(void);
76

77
  /*!
78
   * \brief Turn the 10 dB attenuation on/off.
79
   */
80
  //void set_10dB_atten(bool on);
81

82
  /*!
83
   * \brief Set the antenna type to the main rf or calibrator.
84
   * \param ant "rf" or "cal"
85
   */
86
  bool select_rx_antenna(const std::string &ant);
87

88
  /*!
89
   * \brief Set the attenuation.
90
   * \param attenuation 0 to 31 in dB
91
   */
92
  bool set_attenuation0(int attenuation);
93
  bool set_attenuation1(int attenuation);
94

95
  void set_iq_imbal_taps(const std::vector<gr_complex> taps);
96

97
  void set_adc_gain(bool on);
98
  void set_dc_offset_comp(bool on);
99
  void set_digital_gain(float gain);
100
  void set_test_signal(int type);
101

102
  bool set_setting_reg(int regno, int value);
103

104
  /*!
105
   * \brief write \p v to daugherboard control setting register
106
   */
107
  bool set_dboard_pins(int which_dboard, int v);
108
  bool set_hsadc_conf(int which_dboard, int regno, int value);
109
  bool set_lsdac(int which_dboard, int which_dac, int value);
110
  bool set_mem32(int addr, int value);
111
  bool set_lo_freq(double freq);
112
  bool set_cal_freq(double freq);
113
  bool set_beamforming(std::vector<gr_complex> gains);
114
  bool set_cal_enb(bool enb);
115
  
116
  //caldiv public access methods
117
  double get_cal_freq(void){return d_cal_freq;}
118
  bool get_cal_locked(void){return d_cal_locked;}
119
  bool get_cal_enabled(void){return d_cal_enabled;}
120
  double get_lo_freq(void){return d_lo_freq;}
121
  bool get_lo_locked(void){return d_lo_locked;}
122
  double get_caldiv_temp(void){return d_caldiv_temp;}
123
  int get_caldiv_revision(void){return d_caldiv_rev;}
124
  int get_caldiv_serial(void){return d_caldiv_ser;}
125
  int get_caldiv_model(void){return d_caldiv_mod;}
126
  
127
  //gps public access methods
128
  int get_utc_time(void){return d_utc_time;}
129
  double get_altitude(void){return d_altitude;}
130
  double get_longitude(void){return d_longitude;}
131
  double get_latitude(void){return d_latitude;}
132
};
133

134

135

136
#endif /* INCLUDED_VRT_QUADRADIO_SOURCE_32FC_H */
b/vrt/include/vrt/Makefile.am
25 25
	bits.h \
26 26
	copiers.h \
27 27
	expanded_header.h \
28
	quadradio.h \
29 28
	if_context.h \
30 29
	rx.h \
31 30
	rx_packet_handler.h \
/dev/null
1
/* -*- c++ -*- */
2
/*
3
 * Copyright 2009 Free Software Foundation, Inc.
4
 * 
5
 * This file is part of GNU Radio
6
 * 
7
 * GNU Radio is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3, or (at your option)
10
 * any later version.
11
 * 
12
 * GNU Radio is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 * 
17
 * You should have received a copy of the GNU General Public License along
18
 * with this program; if not, write to the Free Software Foundation, Inc.,
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
 */
21
#ifndef INCLUDED_VRT_QUADRADIO_H
22
#define INCLUDED_VRT_QUADRADIO_H
23

24
#include <vrt/rx.h>
25

26
#include <arpa/inet.h>
27
#include <netinet/in.h>
28
#include <sys/types.h>
29
#include <sys/socket.h>
30

31
typedef enum{
32
    VRT_TEST_SIG_NORMAL=0,
33
    VRT_TEST_SIG_ZEROS=1,
34
    VRT_TEST_SIG_ONES=2,
35
    VRT_TEST_SIG_TOGGLE=3,
36
    VRT_TEST_SIG_RAMP=4,
37
    VRT_TEST_SIG_CUSTOM=5,  
38
      
39
    } vrt_test_sig_t;
40

41
typedef enum{
42
    VRT_BAND_SEL_A='A',
43
    VRT_BAND_SEL_B='B',
44
    VRT_BAND_SEL_C='C',
45
    VRT_BAND_SEL_D='D',  
46
      
47
    } vrt_band_sel_t;
48

49
namespace vrt {
50

51
  /*
52
   * We're not committing to this interface.  It's just here so we can make progress...
53
   *
54
   * This implements the ad-hoc control for bringup and has-a vrt::rx
55
   */
56
  class quadradio
57
  {
58
    int		   d_ctrl_fd;	       // socket for control
59
    struct in_addr d_ctrl_port_inaddr; // our ip addr
60
    int		   d_data_fd;	       // socket for data (owned by d_rx)
61
    int		   d_data_port;	       // our data port number
62
    vrt::rx::sptr  d_rx;	       // has-a rx
63
    
64
    vrt_band_sel_t		   d_band_select;	       // band select setting
65
    int		   d_rx_antenna;	       // antenna type rf/cal
66
    int		   d_attenuation0;	       // attenuation setting
67
    int		   d_attenuation1;	       // attenuation setting
68
    bool	   d_10dB_atten;	       // 10dB attenuation on/of
69

70
    static bool
71
    open_sockets(const char *quad_radio_ip, int quad_radio_ctrl_port,
72
		 int *ctrl_fd_ptr, struct in_addr *ctrl_port_inaddr,
73
		 int *data_fd_ptr, int *data_port_ptr);
74

75
    // dsprxno selects the Rx DSP pipe (0 or 1) to configure
76
    static bool
77
    send_rx_command(int ctrl_fd, int rxdspno, bool start,
78
		    struct in_addr addr, int data_port, int samples_per_pkt);
79

80
    // dsprxno selects the Rx DSP pipe (0 or 1) to stop
81
    static bool
82
    send_stop_rx_command(int ctrl_fd, int rxdspno);
83
    
84
    static int control_port() { return 790; }
85
    int data_socket_fd() const { return d_data_fd; }
86

87
    bool open(const char *ip);
88
    
89
    void update_dboard_pins(void);
90

91
  public:
92
    typedef boost::shared_ptr<quadradio> sptr;
93

94
    quadradio(const std::string &ip, size_t rx_bufsize = 0);
95
    ~quadradio();
96

97
    vrt::rx::sptr vrt_rx() const { return d_rx; }
98

99
    bool start_streaming(int rxdspno, int samples_per_pkt = 0);
100

101
    bool stop_streaming(int rxdspno);
102

103
    /* convenience methods that ultimately write the dboard pins */
104
    bool set_center_freq(double target_freq);
105
    bool set_band_select(vrt_band_sel_t band);
106
    vrt_band_sel_t get_band_select(void){return d_band_select;}
107
    //void set_10dB_atten(bool on);
108
    bool set_attenuation0(int attenuation);
109
    bool select_rx_antenna(const std::string &ant);
110
    bool set_attenuation1(int attenuation);
111
    
112
    /* convenience methods that ultimately call set_hsadc_conf */
113
    void set_adc_gain(bool on);
114
    void set_dc_offset_comp(bool on);
115
    void set_digital_gain(float gain);
116
    void set_test_signal(vrt_test_sig_t type);
117
    
118
    /* primitives */
119
    bool set_setting_reg(int regno, int value);
120
    bool set_mem32(int addr, int value);	// poke a 32-bit value
121
    bool set_lo_freq(double freq);
122
    bool set_cal_freq(double freq);
123
    bool set_beamforming(int32_t gains[8]);
124
    bool set_cal_enb(bool enb);
125
    /*
126
     * The first parameter for these is a bitmask which indicates which
127
     * daughterboard or daughterboards to apply the operation to.
128
     * 0x1	-> dboard 0
129
     * 0x2	-> dboard 1
130
     * 0x3	-> dboard 0 and 1...
131
     */
132
    bool set_dboard_pins(int dboard_bitmask, int v);
133
    bool set_hsadc_conf(int dboard_bitmask, int regno, int value);
134
    bool set_lsdac(int dboard_bitmask, int which_dac, int value);
135

136
  };
137

138
};
139

140

141
#endif /* INCLUDED_QUADRADIO_H */
b/vrt/lib/Makefile.am
32 32
	copiers.cc \
33 33
	data_handler.cc \
34 34
	expanded_header.cc \
35
	quadradio.cc \
36 35
	rx.cc \
37 36
	rx_packet_handler.cc \
38 37
	socket_rx_buffer.cc
/dev/null
1
/* -*- c++ -*- */
2
/*
3
 * Copyright 2009 Free Software Foundation, Inc.
4
 * 
5
 * This file is part of GNU Radio
6
 * 
7
 * GNU Radio is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3, or (at your option)
10
 * any later version.
11
 * 
12
 * GNU Radio is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 * 
17
 * You should have received a copy of the GNU General Public License along
18
 * with this program; if not, write to the Free Software Foundation, Inc.,
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
 */
21
#ifdef HAVE_CONFIG_H
22
#include <config.h>
23
#endif
24
#include <vrt/quadradio.h>
25
#include <vrt/types.h>
26
#include <gruel/inet.h>
27
#include <errno.h>
28
#include <string.h>
29
#include <stdio.h>
30
#include <stdexcept>
31
#include <math.h>
32

33
#define	MIN_IP_LOCAL_PORT	32768
34
#define	MAX_IP_LOCAL_PORT	61000
35

36
#define ALL_DBOARDS	0xf
37

38
static bool
39
send_and_check(int fd, void *buf, size_t len)
40
{
41
  int r = send(fd, buf, len, 0);
42
  if (r < 0){
43
    perror("send");
44
    return false;
45
  }
46
  if ((size_t) r != len){
47
    fprintf(stderr, "send: short return value.  expected %zd, got %d\n", len, r);
48
    return false;
49
  }
50
  return true;
51
}
52

53

54
vrt::quadradio::quadradio(const std::string &ip, size_t rx_bufsize)
55
  : d_ctrl_fd(0), d_data_fd(0), d_data_port(0),
56
  d_band_select(VRT_BAND_SEL_A), d_rx_antenna(0), d_attenuation0(0), d_attenuation1(0)//d_10dB_atten(true)
57
{
58
  if (!open(ip.c_str()))
59
    throw std::runtime_error("vrt::quadradio: failed to open " + ip + "\n");
60

61
  d_rx = vrt::rx::make(data_socket_fd(), rx_bufsize);
62
  set_test_signal(VRT_TEST_SIG_NORMAL);
63
}
64

65
vrt::quadradio::~quadradio()
66
{
67
  ::close(d_ctrl_fd);
68
}
69

70
bool
71
vrt::quadradio::open(const char *ip)
72
{
73
  return open_sockets(ip, control_port(),
74
		      &d_ctrl_fd, &d_ctrl_port_inaddr,
75
		      &d_data_fd, &d_data_port);
76
}
77

78
bool
79
vrt::quadradio::start_streaming(int rxdspno, int samples_per_pkt)
80
{
81
  return send_rx_command(d_ctrl_fd, rxdspno, true, d_ctrl_port_inaddr,
82
			 d_data_port, samples_per_pkt);
83
}
84

85
bool
86
vrt::quadradio::stop_streaming(int rxdspno)
87
{
88
  return send_stop_rx_command(d_ctrl_fd, rxdspno);
89
}
90

91
bool
92
vrt::quadradio::set_center_freq(double target_freq){
93
    if (target_freq < 700e6) return false;
94
    if (target_freq <= 1.0e9) return set_band_select(VRT_BAND_SEL_A);
95
    if (target_freq <= 1.5e9) return set_band_select(VRT_BAND_SEL_B);
96
    if (target_freq <= 2.2e9) return set_band_select(VRT_BAND_SEL_C);
97
    if (target_freq <= 3.0e9) return set_band_select(VRT_BAND_SEL_D);
98
    return false;
99
}
100

101
bool
102
vrt::quadradio::set_band_select(vrt_band_sel_t band){
103
    d_band_select = band;
104
    update_dboard_pins();
105
    return true;
106
}
107

108
//void
109
//vrt::quadradio::set_10dB_atten(bool on){
110
//    d_10dB_atten = on;
111
//    update_dboard_pins();
112
//}
113

114
bool
115
vrt::quadradio::select_rx_antenna(const std::string &ant){
116
    if (ant == "rf") d_rx_antenna = 0;
117
    else if (ant == "cal") d_rx_antenna = 1;
118
    else return true;
119
    update_dboard_pins();
120
    return true;
121
}
122

123
bool
124
vrt::quadradio::set_attenuation0(int attenuation){
125
    if (attenuation < 0 || attenuation > 31) return false;
126
    d_attenuation0 = attenuation;
127
    update_dboard_pins();
128
    return true;
129
}
130

131
bool
132
vrt::quadradio::set_attenuation1(int attenuation){
133
    if (attenuation < 0 || attenuation > 31) return false;
134
    d_attenuation1 = attenuation;
135
    update_dboard_pins();
136
    return true;
137
}
138

139
//bit reversal, length in bits
140
static int reverse_bits(int input, int len){
141
    int reversed = 0;
142
    for (int i = 0; i < len; i++){
143
        reversed += (input & (1<<i))?(1 << (len-i-1)):0;
144
    }
145
    return reversed;
146
}
147

148
void
149
vrt::quadradio::update_dboard_pins(void){
150
    //convert the band ID to bits
151
    int band_select;
152
    switch (d_band_select){
153
        case VRT_BAND_SEL_A: band_select = 3; break;
154
        case VRT_BAND_SEL_B: band_select = 2; break;
155
        case VRT_BAND_SEL_C: band_select = 1; break;
156
        case VRT_BAND_SEL_D: band_select = 0; break;
157
        default: band_select = 0;
158
    }
159
    //calculate the control bits
160
    int db_ctrl = \
161
        ((reverse_bits(d_attenuation0, 5)  & 0x1f) << 10) | \
162
        ((reverse_bits(~d_attenuation1, 5) & 0x1f) << 03) | \
163
        ((band_select                      & 0x03) << 01) | \
164
        ((d_rx_antenna                     & 0x01) << 00);
165
    set_dboard_pins(ALL_DBOARDS, db_ctrl);  // FIXME sets them all
166
}
167

168
void
169
vrt::quadradio::set_adc_gain(bool on){
170
  set_hsadc_conf(ALL_DBOARDS, 0x14, on ? 0x90 : 0x80);
171
}
172

173
void
174
vrt::quadradio::set_dc_offset_comp(bool on){
175
    if (on) {
176
        set_hsadc_conf(ALL_DBOARDS, 0x1B, 0x80);
177
        set_hsadc_conf(ALL_DBOARDS, 0x1A, 0x00); //bits 6:4 set time constant
178
    }
179
    else set_hsadc_conf(ALL_DBOARDS, 0x1B, 0x00);
180
}
181

182
void
183
vrt::quadradio::set_digital_gain(float gain){
184
    int gain_q1 = static_cast<int>(round(gain*2.0));
185
    set_hsadc_conf(ALL_DBOARDS, 0x17, gain_q1);
186
}
187

188
void
189
vrt::quadradio::set_test_signal(vrt_test_sig_t type){
190
    set_hsadc_conf(ALL_DBOARDS, 0x16, type);
191
}
192

193
bool
194
vrt::quadradio::open_sockets(const char *quad_radio_ip, int quad_radio_ctrl_port,
195
			     int *ctrl_fd_ptr, struct in_addr *ctrl_port_inaddr,
196
			     int *data_fd_ptr, int *data_port_ptr)
197
{
198
  int	ctrl_fd;	// socket for control
199
  int	data_fd;	// socket fd for data
200
  int	data_port;	// our port number
201

202
  //
203
  // create a udp socket and connect it to the quad radio control port
204
  //
205

206
  ctrl_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
207
  if (ctrl_fd == -1){
208
    perror("socket: ctrl_fd");
209
    return false;
210
  }
211

212
  struct sockaddr_in si_other;
213
  memset(&si_other, 0, sizeof(si_other));
214
  si_other.sin_family = AF_INET;
215
  si_other.sin_port = htons(quad_radio_ctrl_port);
216
  if (inet_pton(AF_INET, quad_radio_ip, &si_other.sin_addr) <= 0){
217
    perror("inet_pton");
218
    return false;
219
  }
220

221
  if (connect(ctrl_fd, (struct sockaddr *) &si_other, sizeof(si_other)) != 0){
222
    perror("connect");
223
    return false;
224
  }
225

226
  // get our ip address associated with the interface connected to the control port
227

228
  struct sockaddr_in si_me;
229
  memset(&si_me, 0, sizeof(si_me));
230
  socklen_t sockname_len = sizeof(si_me);
231
  if (getsockname(ctrl_fd, (struct sockaddr *) &si_me, &sockname_len) != 0){
232
    perror("getsockname");
233
  }
234
  
235
  *ctrl_port_inaddr = si_me.sin_addr;
236

237
  if (1){
238
    char buf[128];
239
    const char *s = inet_ntop(si_me.sin_family, &si_me.sin_addr, buf, sizeof(buf));
240
    if (s == 0){
241
      perror("inet_ntop");
242
      return false;
243
    }
244
    // printf("our ip addr associated with ctrl port: %s\n", s);
245
  }
246
  
247
  //
248
  // create a udp socket to use to receive data
249
  //
250

251
  data_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
252
  if (data_fd == -1){
253
    perror("socket: data_fd");
254
    return false;
255
  }
256

257
  // bind it to a local port on the interface that connects to the ctrl port.
258
  // FIXME this assumes that interface connected to the control port and the
259
  //   interface connected to the data port are the same.  If we're using
260
  //   both ethernet ports on the quad radio, this may not be the case.
261

262
  data_port = -1;
263
  for (int port = MIN_IP_LOCAL_PORT; port <= MAX_IP_LOCAL_PORT; port++){
264
    struct sockaddr_in si_me;
265
    memset(&si_me, 0, sizeof(si_me));
266
    si_me.sin_family = AF_INET;
267
    si_me.sin_port = htons(port);
268
    si_me.sin_addr.s_addr = htonl(INADDR_ANY);
269

270
    if (bind(data_fd, (struct sockaddr *) &si_me, sizeof(si_me)) == 0){	// found one!
271
      data_port = port;
272
      break;
273
    }
274
  }
275

276
  if (data_port == -1){
277
    fprintf(stderr, "failed to bind to a local port\n");
278
    return false;
279
  }
280

281
  // printf("our data port = %d\n", data_port);
282

283
  *ctrl_fd_ptr = ctrl_fd;
284
  *data_fd_ptr = data_fd;
285
  *data_port_ptr = data_port;
286

287
  return true;
288
}
289

290
// ------------------------------------------------------------------------
291

292
bool
293
vrt::quadradio::send_rx_command(int ctrl_fd, int rxdspno, bool start,
294
				struct in_addr addr, int data_port,
295
				int samples_per_pkt)
296
{
297
  uint32_t cmd[7];
298
  cmd[0] = htonl(0);		   // verb: set
299
  cmd[1] = htonl(0);		   // id: rx_streaming
300
  cmd[2] = htonl(start ? 1: 0);	   // start or stop?
301
  cmd[3] = addr.s_addr;	  	   // ip address to send data to (already network endian)
302
  cmd[4] = htonl(data_port);	   // port to send data to
303
  cmd[5] = htonl(samples_per_pkt);
304
  cmd[6] = htonl(rxdspno);	   // the DSP pipeline to configure
305

306
  return send_and_check(ctrl_fd, cmd, sizeof(cmd));
307
}
308

309
bool
310
vrt::quadradio::send_stop_rx_command(int ctrl_fd, int rxdspno)
311
{
312
  struct in_addr in_addr;
313
  in_addr.s_addr = 0;
314
  return send_rx_command(ctrl_fd, rxdspno, false, in_addr, 0, 0);
315
}
316

317
bool
318
vrt::quadradio::set_dboard_pins(int dboard_bitmask, int v)
319
{
320
  uint32_t cmd[4];
321
  cmd[0] = htonl(0);		   // verb: set
322
  cmd[1] = htonl(1);		   // id: dboard_pins
323
  cmd[2] = htonl(dboard_bitmask);
324
  cmd[3] = htonl(v);	   	   // value
325

326
  return send_and_check(d_ctrl_fd, cmd, sizeof(cmd));
327
}
328
  
329
bool
330
vrt::quadradio::set_setting_reg(int regno, int value)
331
{
332
  uint32_t cmd[4];
333
  cmd[0] = htonl(0);		   // verb: set
334
  cmd[1] = htonl(2);		   // id: SR
335
  cmd[2] = htonl(regno);
336
  cmd[3] = htonl(value);
337

338
  return send_and_check(d_ctrl_fd, cmd, sizeof(cmd));
339
}
340

341
bool
342
vrt::quadradio::set_hsadc_conf(int dboard_bitmask, int regno, int value)
343
{
344
  uint32_t cmd[5];
345
  cmd[0] = htonl(0);		   // verb: set
346
  cmd[1] = htonl(3);		   // id: HSADC_CONF
347
  cmd[2] = htonl(dboard_bitmask);
348
  cmd[3] = htonl(regno);
349
  cmd[4] = htonl(value);
350

351
  return send_and_check(d_ctrl_fd, cmd, sizeof(cmd));
352
}
353

354
bool
355
vrt::quadradio::set_lsdac(int dboard_bitmask, int which_dac, int value)
356
{
357
  uint32_t cmd[5];
358
  cmd[0] = htonl(0);		   // verb: set
359
  cmd[1] = htonl(4);		   // id: LSDAC
360
  cmd[2] = htonl(dboard_bitmask);
361
  cmd[3] = htonl(which_dac);
362
  cmd[4] = htonl(value);
363

364
  return send_and_check(d_ctrl_fd, cmd, sizeof(cmd));
365
}
366

367
bool
368
vrt::quadradio::set_mem32(int addr, int value)
369
{
370
  uint32_t cmd[4];
371
  cmd[0] = htonl(0);		   // verb: set
372
  cmd[1] = htonl(5);		   // id: MEM32
373
  cmd[2] = htonl(addr);
374
  cmd[3] = htonl(value);
375

376
  return send_and_check(d_ctrl_fd, cmd, sizeof(cmd));
377
}
378

379
bool
380
vrt::quadradio::set_lo_freq(double freq)
381
{
382
  vrt_freq_t lo_freq = htonll(double_to_vrt_freq(freq));
383
  uint32_t cmd[4];
384
  cmd[0] = htonl(0);		   // verb: set
385
  cmd[1] = htonl(6);		   // id: lo freq
386
  memcpy(cmd+2, &lo_freq, sizeof(lo_freq));
387

388
  return send_and_check(d_ctrl_fd, cmd, sizeof(cmd));
389
}
390

391
bool
392
vrt::quadradio::set_cal_freq(double freq)
393
{
394
  vrt_freq_t cal_freq = htonll(double_to_vrt_freq(freq));
395
  uint32_t cmd[4];
396
  cmd[0] = htonl(0);		   // verb: set
397
  cmd[1] = htonl(7);		   // id: cal freq
398
  memcpy(cmd+2, &cal_freq, sizeof(cal_freq));
399

400
  return send_and_check(d_ctrl_fd, cmd, sizeof(cmd));
401
}
402

403
bool
404
vrt::quadradio::set_beamforming(int32_t gains[8]){
405
  uint32_t cmd[2+8];
406
  cmd[0] = htonl(0);		   // verb: set
407
  cmd[1] = htonl(8);		   // id: beamformin
408
  for (int i = 0; i < 8; i++){
409
    //printf("%d\n", gains[i]);
410
    cmd[i+2] = htonl(gains[i]); 
411
  }
412
  return send_and_check(d_ctrl_fd, cmd, sizeof(cmd));
413
}
414

415
bool
416
vrt::quadradio::set_cal_enb(bool enb)
417
{
418
  uint32_t cmd[3];
419
  cmd[0] = htonl(0);		   // verb: set
420
  cmd[1] = htonl(9);		   // id: cal enb
421
  cmd[2] = htonl(enb);
422

423
  return send_and_check(d_ctrl_fd, cmd, sizeof(cmd));
424
}

Also available in: Unified diff