Which of the two hardware wrappers is the current one in dttsp (the one in
pyhw or pyhw2?)
Either way, I have a suggestion for partitioning the hardware wrapper.
Put the "SDR hardware" specific stuff (i.e. DDS control, relay controls) in one
extern int getPLLMult(void);
extern void setPLLMult(int value);
extern double getDDSClock(void);
extern void setDDSClock(double value);
and
Put the "PC sound card" specific stuff in the other (sample rate, FFT size)
extern int getSampleRate(void);
extern void setSampleRate(int value);
extern int getFFTLength(void);
extern void setFFTLength(int value);
There is some things that tie together (i.e. picking the sample rate tells
you what offset you should use when commanding the DDS for the LO
frequency), but that's at a higher level and shouldn't be in the hardware
interface, although it might be appropriate in a "system configuration"
layer. The SDR1K neither knows nor cares how long the FFT frame is.
One might also want to accomodate systems where there are multiple SDR1Ks,
and hence, there are multiple reference oscillators (each at a different
frequency). I think that this could be handled by multiple instances of
the hardware interface associated with each physical radio, but you'd want
to separate the PC part from the SDR part.
Consider this hardware architecture:
3 SDR1Ks (each with 2 audio outputs) all fed to a common A/D box. In this
case, you'd have the same sample rate for each "sound interface", but the
SDR1K DDS frequencies (as programmed) would all be different (especially if
you wanted to fool with minimizing DDS spurs), as would the desirable IF
frequency.
Moving with some more thoughts in that direction... You'd theoretically
want to "hide" the spur reduction details from the caller, so you might
want to have an interface that does a "recommended DDS frequency closest to
the desired frequency" so the flow goes something like:
double DDSRefFrequency(void); // current calibrated reference frequency
long int RecommendDDSFreq( long int DesiredFreq); // calculates DDS phase
accumulator increment for lowest spurs
long int SetDDSFreq( long int DDSFrequency); // Loads phase accumulator
increment into DDS
DesiredDDSFreq = DDSPhaseAccumulatorSize() * DesiredFrequency /
(DDSRefFrequency() * DDSRefMult());
ActualDDSFreq = SetDDSFreq( RecommendDDSFreq(DesiredDDSFreq))
-----------
One might want to provide an interface that tells a caller where the output
filters switch over.. If you're tuning around in a particular range, you
might not always want to switch filters, and you'd be willing to accept the
reduced signal from tuning into the edge of the filter.
While mentioning filters, it might be useful to have the whole filter
configuration thing encapsulated and exposed through a useful interface.
Especially if you want to take out things like group delay, etc., it might
be nice to have an interface that can at least "remember" the calibrated
filter characteristics.
AND
Put things that enforce amateur rules (not allowing Tx relay to be enabled
unless "in band") in the user interface. {e.g. SetTransmitRelay(BOOLEAN
value)}
Say you wanted to use your SDR1K for MARS/SHARES use, or you've got some
sort of frequency translator. (IARU bandplans should NOT be in a hardware
interface module, right?)
Put things that keep you from damaging the hardware in the hardware interface.
-------------------
Finally, we need to make sure we support ALL the various hardware
configurations. There are presumably some number of "pre-RFE" SDR1Ks out
there (other than the 5 I'm using). I don't know if the best way to do
this is to have the hardware interface software understand which hardware
configuration is there. (i.e. at init time, you tell it which hardware
configuration you have, with some rational default scheme)
James Lux, P.E.
Spacecraft Radio Frequency Subsystems Group
Flight Communications Systems Section
Jet Propulsion Laboratory, Mail Stop 161-213
4800 Oak Grove Drive
Pasadena CA 91109
tel: (818)354-2075
fax: (818)393-6875