7 PRIVATE void CalcClock(void);
8 PRIVATE void Latch(CtrlPin vCtrlPin);
9 PRIVATE void PWrite(BYTE data);
10 PRIVATE void DDSWrite(BYTE data, BYTE addr);
11 PRIVATE void SetRadioFreq(double f);
12 PRIVATE void Delay(void);
13 PRIVATE void ResetLatches(void);
14 PRIVATE void ResetDDS(void);
15 BOOLEAN InputPin(StatusPin vStatusPin);
17 static int counter = 0;
19 // ======================================================
21 // ======================================================
25 return myRig.extended;
29 setExtended(BOOLEAN value) {
30 myRig.extended = value;
34 getRFE_Enabled(void) {
35 return myRig.rfe_enabled;
39 setRFE_Enabled(BOOLEAN value) {
40 myRig.rfe_enabled = value;
44 getXVTR_Enabled(void) {
45 return myRig.xvtr_enabled;
49 setXVTR_Enabled(BOOLEAN value) {
50 myRig.xvtr_enabled = value;
51 if (myRig.xvtr_enabled)
52 myRig.max_freq = 146.0;
54 myRig.max_freq = 65.0;
57 // private BOOLEANxvtr_tr_logic = FALSE;
59 getXVTR_TR_Logic(void) {
60 return myRig.xvtr_tr_logic;
64 setXVTR_TR_Logic(BOOLEAN value) {
65 myRig.xvtr_tr_logic = value;
70 return myRig.latch_delay;
74 setLatchDelay(int value) {
75 myRig.latch_delay = value;
80 return myRig.min_freq;
85 return myRig.max_freq;
94 setBaseAddr(unsigned short value) {
95 myRig.baseAdr = value;
100 return myRig.band_relay;
104 setBandRelay(BandSetting value) {
106 extern void Pwrite(unsigned char);
107 myRig.band_relay = value;
108 PWrite((unsigned char) (myRig.band_relay + myRig.transmit_relay +
114 getTransmitRelay(void) {
115 //Get state of TR relay on BPF board
116 if (myRig.transmit_relay == TR)
123 setTransmitRelay(BOOLEAN value) {
124 //If in valid Amateur BandRelay Save and output new TR Relay setting
126 BOOLEAN tmpATTN = FALSE;
128 if (IsHamBand(myRig.curBandPlan) == TRUE) {
129 myRig.transmit_relay = TR; // Set to TX
130 if (getRFE_Enabled()) {
131 tmpATTN = getATTN_Relay();
132 if (getXVTR_Enabled() && (myRig.dds_freq >= 144))
133 setXVTR_TR_Relay(myRig.xvtr_tr_logic); //Set XVTR TR to transmit
135 setAMP_Relay(TRUE); //Switch RFE to transmit
137 // TODO: REMOVE THE AMP RELAY SWITCH ON THE PRODUCTION RFE
139 tmpLatch = (BYTE) (myRig.transmit_relay + myRig.mute_relay);
142 (BYTE) (myRig.band_relay + myRig.transmit_relay +
146 myRig.transmit_relay = 0; // Set to RX
147 if (getRFE_Enabled()) {
149 tmpLatch = (BYTE) (myRig.transmit_relay + myRig.mute_relay);
150 if (getXVTR_Enabled())
151 setXVTR_TR_Relay(!myRig.xvtr_tr_logic); // Set XVTR TR to receive
152 setATTN_Relay(tmpATTN);
155 (BYTE) (myRig.band_relay + myRig.transmit_relay +
164 //Get state of MUTE relay on TRX board
165 if (myRig.mute_relay == MUTE)
172 setMuteRelay(BOOLEAN value) {
173 //Mute the speaker relay if TRUE
175 myRig.mute_relay = 0;
177 myRig.mute_relay = MUTE;
179 (myRig.band_relay + myRig.transmit_relay + myRig.mute_relay));
185 //Get state of GAIN relay on TRX board
186 if (myRig.gain_relay == GAIN)
193 setGainRelay(BOOLEAN value) { //Save and output state of GAIN relay on TRX board
195 myRig.gain_relay = 0; // 40dB or 0dB w/RFE
197 myRig.gain_relay = GAIN; // 26dB
198 PWrite((BYTE) (myRig.external_output + myRig.gain_relay));
203 getExternalOutput(void) { //Get state of External Control outputs on PIO board
204 return myRig.external_output;
208 setExternalOutput(int value) {
209 //Save and output state of External Control outputs on PIO board
210 myRig.external_output = value;
211 PWrite((BYTE) (myRig.external_output + myRig.gain_relay));
216 getDDSClockCorrection(void) {
217 return myRig.dds_clock_correction;
221 setDDSClockCorrection(double value) {
222 myRig.dds_clock_correction = value;
224 SetRadioFreq(myRig.dds_freq);
229 return myRig.pll_mult;
234 //sysClock = (pll_mult * dds_clock);
235 myRig.sysClock = (myRig.pll_mult * myRig.dds_clock)
236 + myRig.dds_clock_correction;
237 //Calculates step size for 16 bit frequency step size
238 myRig.dds_step_size = myRig.sysClock / pow(2.0, 48.0);
242 setPLLMult(int value) {
243 myRig.pll_mult = value;
249 return myRig.dds_clock;
253 setDDSClock(double value) {
254 //Compute internal DDS System Clock and Phase Truncation Elimination Step
255 myRig.dds_clock = value;
261 return myRig.if_shift;
265 setIFShift(BOOLEAN value) {
266 //Turns IF shift on and off
267 myRig.if_shift = value;
268 if (!myRig.spur_reduction) {
269 if (myRig.if_shift) {
270 myRig.OSC_change = -11025.0;
271 myRig.needs_OSC_change = TRUE;
273 myRig.OSC_change = 0.0;
274 myRig.needs_OSC_change = TRUE;
277 myRig.needs_OSC_change = FALSE;
278 SetRadioFreq(myRig.dds_freq);
282 getSpurReduction(void) {
283 return myRig.spur_reduction;
287 setSpurReduction(BOOLEAN value) {
288 //Turns DDS Phase Truncation Spur reduction on and off
289 myRig.spur_reduction = value;
290 if (!myRig.spur_reduction) {
291 if (myRig.if_shift) {
292 myRig.OSC_change = -11025.0;
293 myRig.needs_OSC_change = TRUE;
295 myRig.OSC_change = 0.0;
296 myRig.needs_OSC_change = TRUE;
299 myRig.needs_OSC_change = FALSE;
300 SetRadioFreq(myRig.dds_freq);
305 return myRig.if_freq;
309 setIFFreq(double value) {
310 //Sets the offset frequency for the IF in MHz
311 myRig.if_freq = value;
316 return myRig.dds_freq;
320 setDDSFreq(double value) {
321 myRig.dds_freq = value;
322 SetRadioFreq(myRig.dds_freq);
326 getSampleRate(void) {
327 return myRig.sample_rate;
331 setSampleRate(int value) {
332 myRig.sample_rate = value;
333 //Compute bandwidth of FFT bin
334 if (myRig.fft_length > 0)
335 myRig.FFT_Bin_Size = (myRig.sample_rate / myRig.fft_length) * 1e-6;
340 return myRig.fft_length;
344 setFFTLength(int value) {
345 myRig.fft_length = value;
346 //Compute bandwidth of FFT bin
347 if (myRig.fft_length > 0)
348 myRig.FFT_Bin_Size = (myRig.sample_rate / myRig.fft_length) * 1e-6;
353 return myRig.tune_fft;
357 getTuneFracRel(void) {
358 return myRig.tune_frac_rel;
363 return myRig.vfo_offset;
367 setVFOOffset(double value) {
368 myRig.vfo_offset = value;
369 SetRadioFreq(myRig.dds_freq);
374 return myRig.ioud_clock;
378 setIOUDClock(int value) {
379 double bitVal, bytVal;
382 myRig.ioud_clock = value; //Save value
384 bitVal = value; //Compute Numeric Value
386 for (i = 24; i >= 0; i -= 8) //Convert to binary strings
388 // bytVal = bitVal / (Math.Pow(2, i)); //Compute binary byte Value
389 bytVal = bitVal / pow(2.0, (double) i); //Compute binary byte Value
390 lWord = (BYTE) bytVal; //Truncate fractional portion
391 bitVal -= lWord * pow(2.0, (double) i); //Reduce value
392 switch (i) //Write to byte position
412 return myRig.dac_mult;
416 setDACMult(unsigned short value) {
417 double bitVal, bytVal;
420 //Send new I DAC Multiplier value to DDS
421 myRig.dac_mult = value;
422 bitVal = value; //Compute Numeric Value
423 for (i = 8; i >= 0; i -= 8) //Convert to binary strings
425 bytVal = bitVal / pow(2.0, (double) i); //Compute binary byte Value
426 lWord = (BYTE) bytVal; //Truncate fractional portion
427 bitVal -= lWord * pow(2.0, (double) i); //Reduce value
438 bitVal = value; //Compute Numeric Value
439 for (i = 8; i >= 0; i -= 8) //Convert to binary strings
441 bytVal = bitVal / pow(2.0, (double) i); //Compute binary byte Value
442 lWord = (BYTE) bytVal; //Truncate fractional portion
443 bitVal -= lWord * pow(2.0, (double) i); //Reduce value
455 // ======================================================
456 // Private Member Functions
457 // ======================================================
461 usleep(1000 * myRig.latch_delay);
465 Latch(CtrlPin vCtrlPin) {
467 //Strobe the specified pin to latch data
470 mask = 0xA, ioctl(myRig.fd, PPWCONTROL, &mask);
472 mask = 0xB, ioctl(myRig.fd, PPWCONTROL, &mask);
475 mask = 0x9, ioctl(myRig.fd, PPWCONTROL, &mask);
477 mask = 0xB, ioctl(myRig.fd, PPWCONTROL, &mask);
480 mask = 0xF, ioctl(myRig.fd, PPWCONTROL, &mask);
482 mask = 0xB, ioctl(myRig.fd, PPWCONTROL, &mask);
485 mask = 0x3, ioctl(myRig.fd, PPWCONTROL, &mask);
487 mask = 0xB, ioctl(myRig.fd, PPWCONTROL, &mask);
493 ResetLatches(void) { //Set all latch outputs to logic zero (relays off)
498 myRig.gain_relay = GAIN;
499 myRig.external_output = 0;
500 PWrite((BYTE) (myRig.external_output + myRig.gain_relay));
503 setBandRelay(bsnone);
504 myRig.transmit_relay = 0;
505 myRig.mute_relay = MUTE;
508 (myRig.band_relay + myRig.transmit_relay + myRig.mute_relay));
513 PWrite(BYTE data) { //Write data Byte to parallel port
514 ioctl(myRig.fd, PPWDATA, &data);
515 Delay(); //Delay to allow data line setup
520 PWrite(RESET + WRB); //Reset the DDS chip
522 PWrite(WRB); //Leave WRB high
524 DDSWrite(COMP_PD, 29); //Power down comparator
525 //TODO: ADD PLL MULTIPLIER PROPERTY AND LOGIC
526 DDSWrite(BYPASS_PLL, 30); //Bypass PLL
527 //DDSWrite(BYPASS_SINC + OSK_EN, 32);//Bypass Inverse Sinc and enable DAC Mult
528 DDSWrite(BYPASS_SINC, 32);
529 setDACMult(4095); //Set DAC multiplier value
533 DDSWrite(BYTE data, BYTE addr) {
538 //Set up address bits with WRB high
539 PWrite((BYTE) (addr + WRB));
542 //Send write command with WRB low
552 SetRadioFreq(double f) {
555 // calculate software frequency to program
556 if (getXVTR_Enabled() && f >= 144 && f <= 146) //If transverter enabled compute 28MHz IF frequency
557 f -= 116; //Subtract 116MHz (144-28) from VFO display frequency
560 f -= myRig.if_freq; // adjust for IF shift
562 f += myRig.vfo_offset; // adjust for vfo offset
564 unsigned long long int tuning_word =
565 (unsigned long long int) (f / myRig.sysClock * pow(2.0, 48.0));
567 // start with current tuning word
568 // clear first bit, low 31 bits; set bit 31
569 if (myRig.spur_reduction) {
570 unsigned long long int sr_tuning_word =
571 (tuning_word & ~(0x80007fffffffLL)) | 0x000080000000LL;
572 double software_offset =
573 (sr_tuning_word - tuning_word) * myRig.dds_step_size;
575 if (myRig.if_shift) //Convert the tuning fraction to rel frq
576 myRig.tune_frac_rel = 1000000.0 * (software_offset) - 11025.0;
578 myRig.tune_frac_rel = 1000000.0 * (software_offset);
579 myRig.OSC_change = myRig.tune_frac_rel;
580 myRig.needs_OSC_change = TRUE;
582 tuning_word = sr_tuning_word;
587 if (tuning_word != myRig.last_tuning_word) {
588 //Debug.WriteLine("tuning_word != last_tuning_word");
589 //Debug.Write("tuning word: ");
591 myRig.last_tuning_word = tuning_word; //save new tuning word
593 for (i = 0; i < 6; i++) {
595 (BYTE) (tuning_word >> (unsigned long long int) (40 - i * 8)) &
597 //Debug.Write(b+" ");
598 DDSWrite(b, (BYTE) (4 + i));
600 //Debug.WriteLine("");
604 // ======================================================
605 // Public Member Functions
606 // ======================================================
609 InputPin(StatusPin vStatusPin) { //Readback state and mask specified status pin
610 unsigned char status;
611 ioctl(myRig.fd, PPRSTATUS, &status);
612 if (vStatusPin == PIN_11) //Pin 11 is inverted
613 return (((BYTE) vStatusPin & status) == 0);
615 return (((BYTE) vStatusPin & status) != 0);
620 unsigned char status;
621 ioctl(myRig.fd, PPRSTATUS, &status);
629 // user setable through the setup form
630 //DDSClockCorrection = 0.000;
634 setSampleRate(48000);
638 // ResetLatches(void); //Reset all control latches
644 // XVTR_TR_Relay = TRUE; //Set transverter to receive mode
646 // ResetDDS(void); //Hardware reset for DDS
651 // set mute/gain relays based on console
652 if (getXVTR_Enabled())
653 setXVTR_TR_Relay(!myRig.xvtr_tr_logic);
654 setDDSFreq(myRig.dds_freq);
660 if (getRFE_Enabled())
662 if (getXVTR_Enabled())
663 setXVTR_TR_Relay(FALSE);
669 //Set the designated external pin high
670 myRig.external_output += (BYTE) pin;
671 PWrite((BYTE) (myRig.external_output + myRig.gain_relay));
677 //Reset the designated external pin high
678 myRig.external_output -= (BYTE) pin;
679 PWrite((BYTE) (myRig.external_output + myRig.gain_relay));
684 PinValue(ExtPin pin) {
685 //Return TRUE if Pin is set
686 if ((myRig.external_output & (int) pin) != 0)
693 SetBPF(double VFOValue) {
694 if (getRFE_Enabled()) // RFE is present
696 //Use shift registers on RFE to control BPF and LPF banks
697 if (VFOValue <= 2) // DC to 2MHz
699 SRLoad(IC10, LPF9 + BPF0);
701 } else if (VFOValue <= 4) // 2MHz to 4MHz
705 } else if (VFOValue <= 6) // 4MHz to 6MHz
709 } else if (VFOValue <= 7.3) // 6MHz to 7.3MHz
713 } else if (VFOValue <= 10.2) // 7.3MHz to 10.2MHz
717 } else if (VFOValue <= 12) // 10.2MHz to 12MHz
721 } else if (VFOValue <= 14.5) // 12MHz to 14.5MHz
725 } else if (VFOValue <= 21.5) // 14.5MHz to 21.5MHz
727 SRLoad(IC10, BPF3 + LPF8);
729 } else if (VFOValue <= 24) // 21.5MHz to 24MHz
733 } else if (VFOValue <= 30) // 24MHz to 30MHz
737 } else if (VFOValue <= 36) // 30MHz to 36MHz
741 } else if (VFOValue <= 65) // 36MHz to 65Mhz
745 } else if (getXVTR_Enabled() && VFOValue >= 144 && VFOValue <= 146) //28MHz IF for transverter
751 if (getXVTR_Enabled() && VFOValue < 144)
752 setXVTR_Relay(FALSE);
753 } else // RFE is not present
755 //Select the BPF relays using the high frequency cutoff
756 if (VFOValue < 2) //DC to 2MHz
758 else if (VFOValue < 6) //2MHz to 6MHz
760 else if (VFOValue < 12) //6MHz to 12MHz
762 else if (VFOValue < 24) //12MHz to 24MHz
764 else if (VFOValue < 36) //24MHz to 36MHz
766 else //36MHz to 65Mhz
772 IsHamBand(BandPlan b) {
778 if (myRig.dds_freq >= 1.8 && myRig.dds_freq <= 2.0)
780 else if (myRig.dds_freq >= 3.5 && myRig.dds_freq <= 4.0)
782 else if (myRig.dds_freq == 5.3305)
784 else if (myRig.dds_freq == 5.3465)
786 else if (myRig.dds_freq == 5.3665)
788 else if (myRig.dds_freq == 5.3715)
790 else if (myRig.dds_freq == 5.4035)
792 else if (myRig.dds_freq >= 7.0 && myRig.dds_freq <= 7.3)
794 else if (myRig.dds_freq >= 10.1 && myRig.dds_freq <= 10.15)
796 else if (myRig.dds_freq >= 14.0 && myRig.dds_freq <= 14.35)
798 else if (myRig.dds_freq >= 18.068 && myRig.dds_freq <= 18.168)
800 else if (myRig.dds_freq >= 21.0 && myRig.dds_freq <= 21.45)
802 else if (myRig.dds_freq >= 24.89 && myRig.dds_freq <= 24.99)
804 else if (myRig.dds_freq >= 21.0 && myRig.dds_freq <= 21.45)
806 else if (myRig.dds_freq >= 28.0 && myRig.dds_freq <= 29.7)
808 else if (myRig.dds_freq >= 50.0 && myRig.dds_freq <= 54.0)
810 else if (myRig.dds_freq >= 144.0 && myRig.dds_freq <= 146.0) {
811 if (getRFE_Enabled() && getXVTR_Enabled())
819 // TODO: Implement other bandplans here
825 //Toggle 1 and 0 to each of the four parallel port latches
839 RCKStrobe(BOOLEAN ClearReg, RFE_RCK Reg) {
840 //Strobe the RFE 1:4 decoder output to transfer contents of shift register to output latches
841 if (ClearReg) //Clear the shift register contents
842 PWrite((BYTE) (Reg)); //Strobe decoder output low and clear register
844 PWrite((BYTE) (SCLR_NOT + Reg + myRig.transmit_relay + myRig.mute_relay)); //Strobe decoder output low
846 PWrite((BYTE) (SCLR_NOT + DCDR_NE + myRig.transmit_relay + myRig.mute_relay)); //Disable 1:4 decoder outputs
851 SRLoad(RFE_RCK Reg, int Data) {
852 //Shift data into shift registers on RFE
853 int choose[] = { 128, 64, 32, 16, 8, 4, 2, 1 };
856 for (i = 0; i < 8; i++) {
857 int mask = choose[i]; //Mask the current bit
858 if ((mask & Data) == 0) //Current bit = 0
860 PWrite((BYTE) (SCLR_NOT + DCDR_NE + myRig.transmit_relay + myRig.mute_relay)); //Output 0 bit
862 PWrite((BYTE) (SCLR_NOT + DCDR_NE + SCK + myRig.transmit_relay + myRig.mute_relay)); //Clock 0 into shift register
863 } else //Current bit = 1
865 PWrite((BYTE) (SCLR_NOT + DCDR_NE + SER + myRig.transmit_relay + myRig.mute_relay)); //Output 1 bit
867 PWrite((BYTE) (SCLR_NOT + DCDR_NE + SER + SCK + myRig.transmit_relay + myRig.mute_relay)); //Clock 1 into shift register
870 PWrite((BYTE) (SCLR_NOT + DCDR_NE + myRig.transmit_relay + myRig.mute_relay)); //Return SCK low
873 RCKStrobe(FALSE, Reg); //Strobe Register Clock
878 //Reset all RFE shift registers to zero output
879 RCKStrobe(TRUE, IC11);
880 RCKStrobe(TRUE, IC7);
881 RCKStrobe(TRUE, IC10);
882 RCKStrobe(TRUE, IC9);
887 return (myRig.m_IC7_Memory & AMP_RLYS) != 0;
891 setAMP_Relay(BOOLEAN value) {
892 //Set or reset LNA relay
894 myRig.m_IC7_Memory = (myRig.m_IC7_Memory | AMP_RLYS);
896 myRig.m_IC7_Memory = (myRig.m_IC7_Memory & (AMP_RLYS ^ 255));
897 SRLoad(IC7, myRig.m_IC7_Memory);
902 getATTN_Relay(void) {
903 return (myRig.m_IC7_Memory & ATTN_RLY) != 0;
907 setATTN_Relay(BOOLEAN value) {
908 //Set or reset attenuator relay
910 myRig.m_IC7_Memory = (myRig.m_IC7_Memory | ATTN_RLY);
912 myRig.m_IC7_Memory = (myRig.m_IC7_Memory & (ATTN_RLY ^ 255));
913 SRLoad(IC7, myRig.m_IC7_Memory);
917 getXVTR_TR_Relay(void) {
918 return (myRig.m_IC7_Memory & XVTR_TR_RLY) != 0;
922 setXVTR_TR_Relay(BOOLEAN value) {
923 //Set or reset transverter relay
925 myRig.m_IC7_Memory = (myRig.m_IC7_Memory | XVTR_TR_RLY);
927 myRig.m_IC7_Memory = myRig.m_IC7_Memory & (XVTR_TR_RLY ^ 255);
928 SRLoad(IC7, myRig.m_IC7_Memory);
932 getXVTR_Relay(void) {
933 return (myRig.m_IC7_Memory & XVTR_RLY) != 0;
937 setXVTR_Relay(BOOLEAN value) {
938 //Set or reset XVTR 8R (TR) relay
940 myRig.m_IC7_Memory = myRig.m_IC7_Memory | XVTR_RLY;
942 myRig.m_IC7_Memory = myRig.m_IC7_Memory & (XVTR_RLY ^ 255);
943 SRLoad(IC7, myRig.m_IC7_Memory);
947 getIMPULSE_Relay(void) {
948 return (myRig.m_IC7_Memory & IMPULSE_RLY) != 0;
952 setIMPULSE_Relay(BOOLEAN value) {
953 //Set or reset Impulse relay
955 myRig.m_IC7_Memory = myRig.m_IC7_Memory | IMPULSE_RLY;
957 myRig.m_IC7_Memory = myRig.m_IC7_Memory & (IMPULSE_RLY ^ 255);
958 SRLoad(IC7, myRig.m_IC7_Memory);
963 //Send a single impulse to the QSD
964 SRLoad(IC7, (myRig.m_IC7_Memory | 128));
965 SRLoad(IC7, myRig.m_IC7_Memory);
969 openRig(char *port) {
970 int mode = IEEE1284_MODE_COMPAT;
971 if (!port) port = "/dev/parport0";
972 if ((myRig.fd = open(port, O_RDWR)) < 0) {
973 perror("open parallel port");
976 ioctl(myRig.fd, PPCLAIM);
977 ioctl(myRig.fd, PPSETMODE, &mode);
983 ioctl(myRig.fd, PPRELEASE);