|
gr-baz Package
|
00001 #ifndef INCLUDED_RTL2832 00002 #define INCLUDED_RTL2832 00003 00004 #include <stdio.h> 00005 #include <stdarg.h> 00006 00007 #ifdef LIBUSB_FOUND 00008 #include <libusb-1.0/libusb.h> 00009 #else 00010 #include <libusb/libusb.h> // libusbx on Windows 00011 #endif // LIBUSB_FOUND 00012 00013 #ifdef _WIN32 00014 00015 #ifdef RTL2832_EXPORTS 00016 #define RTL2832_API __declspec(dllexport) 00017 #else 00018 #define RTL2832_API __declspec(dllimport) 00019 #endif 00020 00021 // 'libusb.h' offers uint8_t & uint16_t 00022 typedef __int8 int8_t; 00023 typedef unsigned int uint32_t; 00024 typedef unsigned __int64 uint64_t; 00025 00026 #else 00027 00028 #define RTL2832_API 00029 #define RTL2832_TEMPLATE 00030 00031 #endif // _WIN32 00032 00033 #include <vector> 00034 #include <map> 00035 #include <string> 00036 00037 RTL2832_API extern int get_map_index(int value, const int* map, int pair_count); 00038 RTL2832_API extern const char* libusb_result_to_string(int res); 00039 00040 #ifdef _WIN32 00041 #define CURRENT_FUNCTION __FUNCTION__ 00042 #else 00043 #define CURRENT_FUNCTION __PRETTY_FUNCTION__ 00044 #endif // _WIN32 00045 00046 // Swap following comments to disable I2C reporting 00047 //#define DEBUG_TUNER_I2C(t,r) // This is empty on purpose 00048 #define DEBUG_TUNER_I2C(t,r) \ 00049 if (t->params().message_output && function && (line_number >= 0) && (line)) \ 00050 t->params().message_output->on_log_message_ex(RTL2832_NAMESPACE::log_sink::LOG_LEVEL_ERROR, "%s: %s [%i] @ %s:%i \"%s\"\n", __FUNCTION__, libusb_result_to_string(r), r, function, line_number, line); 00051 00052 #define RTL2832_NAMESPACE rtl2832 00053 00054 namespace RTL2832_NAMESPACE 00055 { 00056 00057 class demod; 00058 00059 enum result_code 00060 { 00061 // < 0: libusb result code 00062 FAILURE = 0, 00063 SUCCESS = 1 // > 0 also # bytes transferred 00064 }; 00065 00066 #define TUNERS_NAMESPACE tuners 00067 00068 #define TUNER_FACTORY_FN_NAME Factory 00069 #define TUNER_PROBE_FN_NAME Probe 00070 #define DECLARE_TUNER_FACTORY() \ 00071 public: \ 00072 static tuner* TUNER_FACTORY_FN_NAME(demod* p); \ 00073 static int TUNER_PROBE_FN_NAME(demod* d); 00074 #define IMPLEMENT_TUNER_FACTORY(class_name) \ 00075 tuner* class_name::TUNER_FACTORY_FN_NAME(demod* p) \ 00076 { return new class_name(p); } 00077 #define IMPLEMENT_INLINE_TUNER_FACTORY(class_name) \ 00078 public: \ 00079 static tuner* TUNER_FACTORY_FN_NAME(demod* p) \ 00080 { return new class_name(p); } \ 00081 static int TUNER_PROBE_FN_NAME(demod* d); 00082 00083 // _WIN32: DLL WARNING! These will cause C4251, but only 'vector' can be exported as a DLL interface. You must have exactly the same STL headers in your importing files, otherwise your app will crash. Solution is to recompile this library with your own STL headers. 00084 typedef std::pair<double,double> range_t; 00085 typedef std::vector<double> values_t; 00086 typedef std::map<int,std::string> num_name_map_t; 00087 00088 inline bool values_to_range(const values_t& v, range_t& r) 00089 { if (v.empty()) return false; r = std::make_pair(v[0], v[v.size() - 1]); return true; } 00090 00091 inline bool is_valid_range(const range_t& r) 00092 { return !(r.first == r.second); } 00093 00094 inline bool in_range(const range_t& r, double d) 00095 { return !((d < r.first) || (d > r.second)); } 00096 00097 inline bool in_valid_range(const range_t& r, double d) // If invalid range, return 'true' 00098 { return ((is_valid_range(r) == false) || (in_range(r, d))); } 00099 00100 inline double calc_range(const range_t& r) 00101 { return (r.second - r.first); } 00102 00103 class log_sink 00104 { 00105 public: 00106 enum level 00107 { 00108 LOG_LEVEL_ERROR = -1, // Negative: more serious 00109 LOG_LEVEL_DEFAULT = 0, 00110 LOG_LEVEL_VERBOSE = 1, // Positive: more verbose 00111 }; 00112 public: 00113 virtual void on_log_message_va(int level, const char* msg, va_list args)=0; 00114 public: 00115 inline virtual void on_log_message(const char* msg, ...) 00116 { va_list args; va_start(args, msg); on_log_message_va(LOG_LEVEL_DEFAULT, msg, args); } 00117 inline virtual void on_log_message_ex(int level, const char* msg, ...) 00118 { va_list args; va_start(args, msg); on_log_message_va(level, msg, args); } 00119 }; 00120 00121 class i2c_interface 00122 { 00123 public: 00124 virtual int set_i2c_repeater(bool on = true, const char* function_name = NULL, int line_number = -1, const char* line = NULL)=0; 00125 virtual int i2c_read(uint8_t i2c_addr, uint8_t *buffer, int len)=0; 00126 virtual int i2c_write(uint8_t i2c_addr, uint8_t *buffer, int len)=0; 00127 virtual int i2c_write_reg(uint8_t i2c_addr, uint8_t reg, uint8_t val)=0; 00128 virtual int i2c_read_reg(uint8_t i2c_addr, uint8_t reg, uint8_t& data)=0; 00129 }; 00130 00131 class named_interface 00132 { 00133 public: 00134 virtual const char* name() const=0; 00135 }; 00136 00137 class RTL2832_API tuner : public i2c_interface, public named_interface 00138 { 00139 public: 00140 virtual ~tuner(); 00141 public: 00142 typedef tuner* (*CreateTunerFn)(demod* p); 00143 typedef int (*ProbeTunerFn)(demod* p); 00144 typedef struct params 00145 { 00146 log_sink* message_output; 00147 bool verbose; 00148 } PARAMS, *PPARAMS; 00149 enum gain_mode { 00150 NOT_SUPPORTED = -1, 00151 DEFAULT = 0, 00152 // Specific values > 0 & internal to tuner implementations 00153 }; 00154 public: 00155 virtual int initialise(PPARAMS params = NULL)=0; 00156 //virtual const char* name()=0; 00157 virtual int set_frequency(double freq)=0; 00158 virtual int set_bandwidth(double bw)=0; 00159 virtual int set_gain(double gain)=0; 00160 virtual int set_gain_mode(int mode)=0; 00161 virtual int set_auto_gain_mode(bool on = true)=0; 00162 public: 00163 virtual int set_i2c_repeater(bool on = true, const char* function_name = NULL, int line_number = -1, const char* line = NULL)=0; 00164 virtual int i2c_read(uint8_t i2c_addr, uint8_t *buffer, int len)=0; 00165 virtual int i2c_write(uint8_t i2c_addr, uint8_t *buffer, int len)=0; 00166 public: 00167 virtual double frequency() const=0; 00168 virtual double bandwidth() const=0; 00169 virtual double gain() const=0; 00170 virtual int gain_mode() const=0; 00171 public: 00172 virtual range_t gain_range() const=0; 00173 virtual values_t gain_values() const=0; 00174 virtual range_t frequency_range() const=0; 00175 virtual range_t bandwidth_range() const=0; 00176 virtual values_t bandwidth_values() const=0; 00177 public: 00178 virtual num_name_map_t gain_modes() const=0; 00179 virtual bool calc_appropriate_gain_mode(int& mode)/* const*/=0; 00180 virtual bool auto_gain_mode() const=0; 00181 public: 00182 virtual const PARAMS& params() const=0; 00183 virtual demod* parent() const=0; 00184 }; 00185 00186 class RTL2832_API tuner_skeleton : public tuner 00187 { 00188 public: 00189 tuner_skeleton(demod* p); 00190 virtual ~tuner_skeleton(); 00191 protected: 00192 demod* m_demod; 00193 tuner::PARAMS m_params; 00194 bool m_auto_gain_mode; 00195 int m_gain_mode; 00196 double m_freq; 00197 double m_gain; 00198 double m_bandwidth; 00199 range_t m_gain_range; 00200 values_t m_gain_values; 00201 range_t m_frequency_range; 00202 range_t m_bandwidth_range; 00203 values_t m_bandwidth_values; 00204 num_name_map_t m_gain_modes; 00205 public: 00206 virtual int initialise(tuner::PPARAMS params = NULL); 00207 virtual const char* name() const 00208 { return "(dummy)"; } 00209 virtual int set_frequency(double freq) 00210 { return SUCCESS; } 00211 virtual int set_bandwidth(double bw) 00212 { return SUCCESS; } 00213 virtual int set_gain(double gain) 00214 { return SUCCESS; } 00215 virtual int set_gain_mode(int mode) 00216 { return SUCCESS; } 00217 public: 00218 virtual int set_i2c_repeater(bool on = true, const char* function_name = NULL, int line_number = -1, const char* line = NULL); 00219 virtual int i2c_read(uint8_t i2c_addr, uint8_t *buffer, int len); 00220 virtual int i2c_write(uint8_t i2c_addr, uint8_t *buffer, int len); 00221 virtual int i2c_write_reg(uint8_t i2c_addr, uint8_t reg, uint8_t val); 00222 virtual int i2c_read_reg(uint8_t i2c_addr, uint8_t reg, uint8_t& data); 00223 public: 00224 virtual double frequency() const 00225 { return m_freq; } 00226 virtual double bandwidth() const 00227 { return m_bandwidth; } 00228 virtual double gain() const 00229 { return m_gain; } 00230 virtual int gain_mode() const 00231 { return m_gain_mode; } 00232 virtual int set_auto_gain_mode(bool on = true) 00233 { m_auto_gain_mode = on; return SUCCESS; } 00234 public: 00235 virtual range_t gain_range() const 00236 { return m_gain_range; } 00237 virtual values_t gain_values() const 00238 { return m_gain_values; } 00239 virtual range_t frequency_range() const 00240 { return m_frequency_range; } 00241 virtual range_t bandwidth_range() const 00242 { return m_bandwidth_range; } 00243 virtual values_t bandwidth_values() const 00244 { return m_bandwidth_values; } 00245 public: 00246 virtual num_name_map_t gain_modes() const 00247 { return m_gain_modes; } 00248 virtual bool calc_appropriate_gain_mode(int& mode)/* const*/ 00249 { mode = m_gain_mode; return true; } 00250 virtual bool auto_gain_mode() const 00251 { return m_auto_gain_mode; } 00252 public: 00253 const tuner::PARAMS& params() const 00254 { return m_params; } 00255 demod* parent() const 00256 { return m_demod; } 00257 }; 00258 00259 class i2c_repeater_scope 00260 { 00261 private: 00262 i2c_interface* m_p; 00263 const char* m_function_name; 00264 int m_line_number; 00265 const char* m_line; 00266 public: 00267 i2c_repeater_scope(i2c_interface* p, const char* function_name = NULL, int line_number = -1, const char* line = NULL) 00268 : m_p(p) 00269 , m_function_name(function_name) 00270 , m_line_number(line_number) 00271 , m_line(line) 00272 { p->set_i2c_repeater(true, function_name, line_number, line); } 00273 ~i2c_repeater_scope() 00274 { m_p->set_i2c_repeater(false, m_function_name, m_line_number, m_line); } 00275 }; 00276 00277 #define I2C_REPEATER_SCOPE(p) i2c_repeater_scope _i2c_repeater_scope(p, CURRENT_FUNCTION, __LINE__, p->name()) 00278 #define THIS_I2C_REPEATER_SCOPE() I2C_REPEATER_SCOPE(this) 00279 00280 typedef struct device_info 00281 { 00282 const char* name; 00283 uint16_t vid, pid; 00284 tuner::CreateTunerFn factory; 00285 uint32_t max_rate, min_rate, crystal_frequency, flags; 00286 } DEVICE_INFO, *PDEVICE_INFO; 00287 00288 //#define CHECK_LIBUSB_RESULT(r) (r) 00289 //#define CHECK_LIBUSB_NEG_RESULT(r) (r) 00290 //#define CHECK_LIBUSB_RESULT_EX(r,f,l,s) (r) 00291 #define CHECK_LIBUSB_RESULT(r) check_libusb_result(r, false, CURRENT_FUNCTION, __LINE__, #r) 00292 #define CHECK_LIBUSB_NEG_RESULT(r) check_libusb_result(r, true, CURRENT_FUNCTION, __LINE__, #r) 00293 #define CHECK_LIBUSB_RESULT_EX(r,f,l,s) check_libusb_result(r, false, f, l, s) 00294 00295 #define CHECK_LIBUSB_RESULT_RETURN_EX(d,r) \ 00296 { int res = d->CHECK_LIBUSB_RESULT(r); \ 00297 if (res <= 0) return res; } 00298 00299 #define CHECK_LIBUSB_NEG_RESULT_RETURN_EX(d,r) \ 00300 { int res = d->CHECK_LIBUSB_NEG_RESULT(r); \ 00301 if (res < 0) return res; } 00302 00303 #define CHECK_LIBUSB_RESULT_RETURN(r) CHECK_LIBUSB_RESULT_RETURN_EX(this,r) 00304 #define CHECK_LIBUSB_NEG_RESULT_RETURN(d,r) CHECK_LIBUSB_NEG_RESULT_RETURN_EX(this,r) 00305 00306 #define RTL2832_FIR_COEFF_COUNT 20 00307 #define RTL2832_TUNER_NAME_LEN (32+1) 00308 00309 class RTL2832_API demod : public i2c_interface, public named_interface 00310 { 00311 public: 00312 demod(); 00313 virtual ~demod(); 00314 public: 00315 //static const int FIR_COEFF_COUNT = 20; 00316 //static const int TUNER_NAME_LEN = 32+1; 00317 typedef struct params 00318 { 00319 uint16_t vid; 00320 uint16_t pid; 00321 bool verbose; 00322 int default_timeout; // 0: use default, -1: poll only 00323 log_sink* message_output; 00324 bool use_custom_fir_coefficients; 00325 uint8_t fir_coeff[RTL2832_FIR_COEFF_COUNT]; 00326 //bool use_tuner_params; // Use if valid tuner::PPARAMS pointer 00327 tuner::PPARAMS tuner_params; 00328 uint32_t crystal_frequency; 00329 char tuner_name[RTL2832_TUNER_NAME_LEN]; 00330 } PARAMS, *PPARAMS; 00331 protected: 00332 struct libusb_device_handle *m_devh; 00333 PDEVICE_INFO m_current_info; 00334 tuner *m_tuner, *m_dummy_tuner; 00335 bool m_libusb_init_done; 00336 PARAMS m_params; 00337 range_t m_sample_rate_range; 00338 double m_sample_rate; 00339 uint32_t m_crystal_frequency; 00340 bool m_tuner_was_active; // True if the kernel driver was detached 00341 public: 00342 int initialise(PPARAMS params = NULL); 00343 const char* name() const; 00344 void destroy(); 00345 int reset(); 00346 int set_sample_rate(uint32_t samp_rate, double* real_rate = NULL); 00347 int set_if(double frequency); 00348 int read_samples(unsigned char* buffer, uint32_t buffer_size, int* bytes_read, int timeout = -1); 00349 protected: 00350 int find_device(); 00351 int init_demod(); 00352 int demod_write_reg(uint8_t page, uint16_t addr, uint16_t val, uint8_t len); 00353 int demod_read_reg(uint8_t page, uint8_t addr, uint8_t len, uint16_t& reg); 00354 int write_reg(uint8_t block, uint16_t addr, uint16_t val, uint8_t len); 00355 int read_reg(uint8_t block, uint16_t addr, uint8_t len, uint16_t& reg); 00356 int write_array(uint8_t block, uint16_t addr, uint8_t *array, uint8_t len); 00357 int read_array(uint8_t block, uint16_t addr, uint8_t *array, uint8_t len); 00358 public: 00359 int check_libusb_result(int res, bool zero_okay, const char* function_name = NULL, int line_number = -1, const char* line = NULL); 00360 void log(const char* message, ...); 00361 public: 00362 int set_i2c_repeater(bool on = true, const char* function_name = NULL, int line_number = -1, const char* line = NULL); 00363 int i2c_read(uint8_t i2c_addr, uint8_t *buffer, int len); 00364 int i2c_write(uint8_t i2c_addr, uint8_t *buffer, int len); 00365 int i2c_write_reg(uint8_t i2c_addr, uint8_t reg, uint8_t val); 00366 int i2c_read_reg(uint8_t i2c_addr, uint8_t reg, uint8_t& data); 00367 public: 00368 int set_gpio_output(uint8_t gpio); 00369 int set_gpio_bit(uint8_t gpio, int val); 00370 public: 00371 inline tuner* active_tuner() const 00372 { return m_tuner; } 00373 inline double sample_rate() const 00374 { return m_sample_rate; } 00375 inline uint32_t crystal_frequency() const 00376 { return m_crystal_frequency; } 00377 range_t sample_rate_range() const 00378 { return m_sample_rate_range; } 00379 protected: 00380 enum usb_reg { 00381 USB_SYSCTL = 0x2000, 00382 USB_CTRL = 0x2010, 00383 USB_STAT = 0x2014, 00384 USB_EPA_CFG = 0x2144, 00385 USB_EPA_CTL = 0x2148, 00386 USB_EPA_MAXPKT = 0x2158, 00387 USB_EPA_MAXPKT_2 = 0x215a, 00388 USB_EPA_FIFO_CFG = 0x2160, 00389 }; 00390 enum sys_reg { 00391 DEMOD_CTL = 0x3000, 00392 GPO = 0x3001, 00393 GPI = 0x3002, 00394 GPOE = 0x3003, 00395 GPD = 0x3004, 00396 SYSINTE = 0x3005, 00397 SYSINTS = 0x3006, 00398 GP_CFG0 = 0x3007, 00399 GP_CFG1 = 0x3008, 00400 SYSINTE_1 = 0x3009, 00401 SYSINTS_1 = 0x300a, 00402 DEMOD_CTL_1 = 0x300b, 00403 IR_SUSPEND = 0x300c, 00404 }; 00405 enum blocks { 00406 DEMODB = 0, 00407 USBB = 1, 00408 SYSB = 2, 00409 TUNB = 3, 00410 ROMB = 4, 00411 IRB = 5, 00412 IICB = 6, 00413 }; 00414 }; 00415 00416 } 00417 00418 #endif // INCLUDED_RTL2832