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


Reply via email to