1 // soft66.c V0.1
2 // Linrad's 'host control' routines for Soft66 series SDR receivers
3 // Uses libsoft66 by Thomas Horsten <thomas@horsten.com>
4 //
5 // There is currently no provision for listing devices or
6 // selecting one based on serial number, although the library
7 // supports these features. Instead you can set the environment
8 // variable SOFT66_SERIAL to the correct serial number and
9 // the correct one will be opened.
10 //
11 // Expect more features to be added, this is a raw first cut,
12 // just to get frequency control!
13 //
14 // This code is based on si570.c which in turn is based on
15 // ausbsoftrock.c by Andrew Nilsson (andrew.nilsson@gmail.com),
16 // powerSwitch.c by Christian Starkjohann,
17 // and usbtemp.c by Mathias Dalheimer of Objective Development Software GmbH (2005)
18 // (see http://www.obdev.at/products/vusb/index.html )
19 //
20 // Use at your own risk and enjoy
21 // Thomas
22 //
23 // UPDATE HISTORY
24 // 06 November 2010 Created
25
26 #include "loadusb.h"
27 #include "uidef.h"
28 #include "screendef.h"
29 #include "fft1def.h"
30 #include <string.h>
31
32
33 #if OSNUM == OSNUM_WINDOWS
34 #include <windows.h>
35 #ifdef interface
36 #undef interface
37 #endif
38 #endif
39
40
41
42
43 #define SOFT66_SERIAL_ENV "SOFT66_SERIAL"
44 #define SOFT66_VID_ENV "SOFT66_VID"
45 #define SOFT66_PID_ENV "SOFT66_PID"
46
47 #define SOFT66_VID_DEFAULT 0x0403
48 #define SOFT66_PID_DEFAULT 0x6001
49
50
51 enum soft66_model {
52 SOFT66_MODEL_UNKNOWN = 0x0,
53 SOFT66_MODEL_SOFT66ADD = 0x1,
54 };
55
56 struct soft66_context {
57 int model;
58 unsigned int chipid;
59 unsigned int freq_min;
60 unsigned int freq_max;
61 unsigned int mclk;
62
63 struct ftdi_context *ftdi;
64 };
65
66
67 //struct soft66_context *soft66_new(void);
68 typedef struct soft66_context* (*p_soft66_new)(void);
69 typedef void (*p_soft66_free)(struct soft66_context *ctx);
70 typedef int (*p_soft66_set_frequency)(struct soft66_context *ctx, int freq, int noreset);
71 typedef int (*p_soft66_open_device)(struct soft66_context *ctx,
72 int vid, int pid, const char *serial);
73 p_soft66_new soft66_new;
74 p_soft66_set_frequency soft66_set_frequency;
75 p_soft66_open_device soft66_open_device;
76 p_soft66_free soft66_free;
77
78 int soft66_library_flag;
79
80
81
82 #define MAX_SOFT66_PARM 1
83
84 static char *soft66_parfil_name="par_soft66";
85 static char *soft66_parm_text[MAX_SOFT66_PARM]={"Power down on exit"
86 };
87
88 typedef struct {
89 int PowerDownOnExit;
90 }P_SOFT66;
91 P_SOFT66 soft66;
92 struct soft66_context *soft66_handle = NULL;
93 int soft66_needs_reset = 0;
94
95 #if(OSNUM == OSNUM_WINDOWS)
96 #include <windows.h>
97 HANDLE soft66_libhandle;
98
load_soft66_library(void)99 void load_soft66_library(void)
100 {
101 int info;
102 if(soft66_library_flag)return;
103 info=0;
104 soft66_libhandle=LoadLibrary("soft66.dll");
105 if(!soft66_libhandle)goto soft66_load_error;
106 info=1;
107 soft66_new=(p_soft66_new)GetProcAddress(soft66_libhandle, "soft66_new");
108 if(!soft66_new)goto soft66_sym_error;
109 soft66_set_frequency=(p_soft66_set_frequency)
110 GetProcAddress(soft66_libhandle, "soft66_set_frequency");
111 if(!soft66_set_frequency)goto soft66_sym_error;
112 soft66_open_device=(p_soft66_open_device)
113 GetProcAddress(soft66_libhandle, "soft66_open_device");
114 if(!soft66_open_device)goto soft66_sym_error;
115 soft66_free=(p_soft66_free)GetProcAddress(soft66_libhandle, "soft66_free");
116 if(!soft66_free)goto soft66_sym_error;
117 soft66_library_flag=TRUE;
118 if(!soft66_new)goto soft66_sym_error;
119 return;
120 soft66_sym_error:;
121 FreeLibrary(soft66_libhandle);
122 soft66_load_error:;
123 library_error_screen("soft66.dll",info);
124 }
125
unload_soft66_library(void)126 void unload_soft66_library(void)
127 {
128 if(!soft66_library_flag)return;
129 FreeLibrary(soft66_libhandle);
130 soft66_library_flag=FALSE;
131 }
132 #endif
133
134
135 #if(OSNUM == OSNUM_LINUX)
136 #include <dlfcn.h>
137 void *soft66_libhandle;
138
load_soft66_library(void)139 void load_soft66_library(void)
140 {
141 int info;
142 info=0;
143 if(soft66_library_flag)return;
144 soft66_libhandle=dlopen(SOFT66_LIBNAME, RTLD_LAZY);
145 if(!soft66_libhandle)goto soft66_load_error;
146 info=1;
147 soft66_new=(p_soft66_new)dlsym(soft66_libhandle, "soft66_new");
148 if(dlerror() != 0)goto soft66_sym_error;
149 soft66_set_frequency=(p_soft66_set_frequency)
150 dlsym(soft66_libhandle, "soft66_set_frequency");
151 soft66_open_device=(p_soft66_open_device)
152 dlsym(soft66_libhandle, "soft66_open_device");
153 soft66_free=(p_soft66_free)dlsym(soft66_libhandle, "soft66_free");
154 soft66_library_flag=TRUE;
155 return;
156 soft66_sym_error:;
157 dlclose(soft66_libhandle);
158 soft66_load_error:;
159 library_error_screen(SOFT66_LIBNAME,info);
160 }
161
unload_soft66_library(void)162 void unload_soft66_library(void)
163 {
164 if(!soft66_library_flag)return;
165 dlclose(soft66_libhandle);
166 soft66_library_flag=FALSE;
167 }
168 #endif
169
170
171
set_default_parameters(void)172 static void set_default_parameters(void)
173 {
174 // SET DEFAULTS VALUES FOR Soft66
175 soft66.PowerDownOnExit =0;
176 }
177
read_par_soft66_file(void)178 static void read_par_soft66_file(void)
179 {
180 int errcod;
181 errcod=read_sdrpar(soft66_parfil_name, MAX_SOFT66_PARM,
182 soft66_parm_text, (int*)((void*)&soft66));
183 if (errcod != 0)
184 {
185 FILE *soft66_file;
186 int *sdr_pi,i;
187 soft66_file=fopen(soft66_parfil_name,"w");
188 set_default_parameters();
189 sdr_pi=(int*)(&soft66);
190 for(i=0; i<MAX_SOFT66_PARM; i++)
191 {
192 fprintf(soft66_file,"%s [%d]\n",soft66_parm_text[i],sdr_pi[i]);
193 }
194 parfile_end(soft66_file);
195 }
196 }
197
save_par_soft66_file(void)198 static void save_par_soft66_file(void)
199 {
200 FILE *soft66_file;
201 int *sdr_pi,i;
202 soft66_file=fopen(soft66_parfil_name,"w");
203 sdr_pi=(int*)(&soft66);
204 for(i=0; i<MAX_SOFT66_PARM; i++)
205 {
206 fprintf(soft66_file,"%s [%d]\n",soft66_parm_text[i],sdr_pi[i]);
207 }
208 parfile_end(soft66_file);
209 }
210
Soft66OpenDevice(void)211 static int Soft66OpenDevice(void)
212 {
213 int r;
214 struct soft66_context *ctx = soft66_new();
215 read_par_soft66_file();
216 if (!ctx)
217 return -1;
218 r = soft66_open_device(ctx, 0, 0, NULL);
219 if (r < 0) {
220 soft66_free(ctx);
221 ctx = NULL;
222 }
223 soft66_needs_reset = 1;
224 soft66_handle = ctx;
225 return r;
226 return 0;
227 }
228 /*
229 static int Soft66CloseDevice(void)
230 {
231 if (soft66_handle)
232 soft66_free(soft66_handle);
233 soft66_handle = NULL;
234 soft66_needs_reset = 0;
235 return 0;
236 }
237 */
setFreqByValue(unsigned int frequency)238 static int setFreqByValue(unsigned int frequency)
239 {
240 int r;
241 if (!soft66_handle) {
242 r = Soft66OpenDevice();
243 if (r<0)
244 return r;
245 }
246
247 r = soft66_set_frequency(soft66_handle, frequency, soft66_needs_reset);
248 //printf("sfbv: %d (%d)\n", frequency, soft66_needs_reset);
249 if (r < 0)
250 printf("soft66.c: Error when setting frequency %d, returncode=%i\n",frequency,r);
251 soft66_needs_reset = 0;
252 return r;
253 }
254
soft66_setup(void)255 void soft66_setup(void)
256 {
257 char s[160];
258 int retval;
259 int line;
260 load_soft66_library();
261 if(!soft66_library_flag)return;
262 start_setup:
263 clear_screen();
264 settextcolor(14);
265 lir_text(2,1,"CURRENT SETUP FOR 'SOFT66 USB DEVICE' ");
266 settextcolor(7);
267 line= 4;
268 read_par_soft66_file();
269 retval=Soft66OpenDevice();
270 if(retval == 0)
271 {
272 settextcolor(10);
273 sprintf(s,"Soft66 Model: %d", soft66_handle->model);
274 lir_text(38,line,s);
275 settextcolor(7);
276 line+=2;
277 }
278 else
279 {
280 settextcolor(12);
281 sprintf(s,"Could not open device, probably not connected");
282 lir_text(58,line,s);
283 settextcolor(7);
284 line+=2;
285 }
286 sprintf(s,"Soft66 power down on exit = ");
287 lir_text(2,line,s);
288 settextcolor(10);
289 sprintf(s,"%i",soft66.PowerDownOnExit);
290 lir_text(38,line,s);
291 settextcolor(7);
292 line+=6;
293 lir_text(2,line,"A = Enable automatic power-down.");
294 line++;
295 lir_text(2,line,"B = Disable automatic power-down.");
296 line++;
297 line++;
298 lir_text(2,line,"X = Exit.");
299 setup_menu:;
300 await_processed_keyboard();
301 if(kill_all_flag)return;
302 switch(lir_inkey)
303 {
304 case 'A':
305 soft66.PowerDownOnExit=0;
306 save_par_soft66_file();
307 goto start_setup;
308
309 case 'B':
310 soft66.PowerDownOnExit=0;
311 save_par_soft66_file();
312 goto start_setup;
313
314 case 'X':
315 unload_soft66_library();
316 return;
317
318 default:
319 goto setup_menu;
320 }
321 }
322
soft66_rx_freq_control(void)323 void soft66_rx_freq_control(void)
324 {
325 int retval;
326 int f;
327
328 fg.passband_direction=1;
329 fft1_direction = fg.passband_direction;
330 fg.passband_increment=0.050;
331
332 if (!soft66_handle) {
333 retval=Soft66OpenDevice();
334 if(retval != 0 ) printf("soft66.c: Could not find Soft66 device\n");
335 return;
336 }
337
338 if (fg.passband_center*1000000.0 < soft66_handle->freq_min )
339 {
340 fg.passband_center = soft66_handle->freq_min/1000000.0;
341 } else if (fg.passband_center*1000000.0 > soft66_handle->freq_max )
342 {
343 fg.passband_center = soft66_handle->freq_max/1000000.0;
344 }
345 f = (int)(fg.passband_center*1000000.0);
346 //f = (int)(fg.passband_center*1000000.0);
347 retval=setFreqByValue(f);
348 if (retval < 0 )
349 {
350 if(retval != 0 ) printf("soft66.c: Could not set frequency\n");
351 }
352 }
353