From 4f4077fb26f0ce9f9bb9c6830f92dedc523ecf89 Mon Sep 17 00:00:00 2001 From: "Larry Gadallah, VE6VQ" Date: Tue, 22 Dec 2009 07:12:39 +0000 Subject: [PATCH] Alpha version of AR7030+ backend git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@2792 7ae35d74-ebe9-4afe-98af-79ac388436b8 --- aor/ar7030p.h | 1283 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1283 insertions(+) create mode 100644 aor/ar7030p.h diff --git a/aor/ar7030p.h b/aor/ar7030p.h new file mode 100644 index 000000000..1db199508 --- /dev/null +++ b/aor/ar7030p.h @@ -0,0 +1,1283 @@ + +/* +AR-7030 Computer remote control protocol. + +Information for firmware releases 1.1A, 1.2A, 1.4A and 1.4B + +1) Remote control overview. + +The AR-7303 receiver allows remote control of all of its functions by means +of a direct memory access system. A controlling computer can read and modify +the internal memory maps of the receiver to set required parameters and then +call for the receiver's control program to process the new settings. Commands +to the receiver are byte structured in binary format, so it is not possible +to control from a terminal. + +All multi-byte numbers within the receiver are binary, stored MSB first. + +2) Receiver frequency configuration. + +Receive frequency is set by two oscillators - local and carrier. In AM and FM +modes the carrier oscillator is not used, and the final IF frequency is 455 +kHz. In Sync mode the carrier oscillator is offset by +20.29kHz before mixing +with the IF. + +The IF frequencies have a fixed inter-conversion frequency of 44.545MHz and, +because of the high-side local oscillator, both IF's are inverted. + +The receiver controller processes the following variables to establish the +tuned frequency :- + +[local offset] Frequency shift applied to local oscillator. +[carrier offset] 455.00kHz for LSB, USB, Data and CW modes / + 434.71kHz for Sync mode. + +[filter offset] IF Filter frequency at the (vestigial) carrier position as an + offset from 455kHz. + +[PBS] User set filter shift. +[BFO] User set offset between carrier position and frequency display. +[TUNE] Receiver tuned frequency as shown on display. + +The relationship between these variables and the tuning is as follows :- + +[carrier offset] + [filter offset] + [PBS] + [BFO] ==> Carrier oscillator +45.000MHz + [filter offset] + [PBS] ==> [local offset] +[TUNE] + [local offset] ==> Local oscillator + +3) Serial data protocol. + +All data transfers are at 1200 baud, No parity, 8 bits, 1 stop bit +(1200 N 8 1). There is no hardware or software flow control other than that +inherent in the command structure. The receiver can accept data at any time at +full rate provided the IR remote controller is not used or is disabled. +A maximum of one byte can be transmitted for each byte received, so data flow +into a controlling computer is appropriately limited. + +Each byte sent to the receiver is a complete command - it is best thought of +as two hexadecimal digits - the first digit is the operation code, the second +digit is 4-bits of data relating to the operation. Because the receiver +operates with 8-bit bytes, intermediate 4-bit values are stored in registers +in the receiver for recombination and processing. For example to write into the +receiver's memory, the following steps would be followed:- + +a) Send address high order 4-bits into H-register +b) Send address low order 4-bits and set Address register +c) Send first data byte high order 4-bits into H-register +d) Send first data byte low order 4-bits and execute Write Data Operation +e) Send second data byte high order 4-bits into H-register +f) Send second data byte low order 4-bits and execute Write Data Operation +g) Repeat (e) and (f) for each subsequent byte to be written. + +4) Memory organisation. + +Different memory areas in the receiver are referenced by selecting Pages - +up to 16 pages are supported. + +The memory is broadly divided into 3 sections :- + +a) Working memory - where all current operating variables are stored and +registers and stack are located. This memory is volatile and data is lost +when power to the receiver is removed. + +b) Battery sustained memory - where duplicate parameters are stored for +retention when power is removed. This memory area is also used for storage +of filter parameters, setup memories and squelch and BFO settings for the +frequency memories and contains the real time clock registers. + +c) EEPROM - where frequency, mode, filter and PBS information for the +frequency memories is stored. Additionally S-meter and IF calibration values +are stored here. This memory can be read or written to download and upload +the receiver's frequency memories, but repetitive writing should be avoided +because the memory devices will only support a finite number of write cycles. + +5) Variations between A and B types and firmware revisions. +Type A firmware supports only basic receiver functions, type B extends +operations and includes support for the Notch / Noise Blanker option. +The whole of the type A memory map is retained in type B, but more +memory and operations are added for the extended functions of type B. + +In the following information, circled note numbers are included to indicate +where items are specific to one type or revision of the firmware:- + + <1> Applicable to type B firmware only. + <2> Applicable to revision 1.4 only, types A and B + <3> Function is changed or added to in type B + +6) Operation codes. +The high order 4-bits of each byte sent to the receiver is the operation code, +the low order 4-bits is data (shown here as x) :- + +Code Ident Operation +0x NOP No Operation + +3x SRH Set H-register x => H-register (4-bits) + +5x PGE Set page x => Page register (4-bits) + +4x ADR Set address 0Hx => Address register (12-bits) + 0 => H-register + +1x ADH Set address high x => Address register (high 4-bits) + +6x WRD Write data Hx => [Page, Address] + Address register + 1 => Address register + 0 => H-register, + 0 => Mask register + +9x MSK <1> Set mask Hx => Mask register + 0 => H-register +2x EXE Execute routine x + +Ax BUT <1> Operate button x + +7x RDD Read data [Page, Address] => Serial output + Address register + x => Address register + +8x LOC Set lock level x +*/ + +#define NOP(x) ( 0x00 | ( 0x0f & (x) ) ) +#define SRH(x) ( 0x30 | ( 0x0f & (x) ) ) +#define PGE(x) ( 0x50 | ( 0x0f & (x) ) ) +#define ADR(x) ( 0x40 | ( 0x0f & (x) ) ) +#define ADH(x) ( 0x10 | ( 0x0f & (x) ) ) +#define WRD(x) ( 0x60 | ( 0x0f & (x) ) ) +#define MSK(x) ( 0x90 | ( 0x0f & (x) ) ) +#define EXE(x) ( 0x20 | ( 0x0f & (x) ) ) +#define BUT(x) ( 0xa0 | ( 0x0f & (x) ) ) +#define RDD(x) ( 0x70 | ( 0x0f & (x) ) ) +#define LOC(x) ( 0x80 | ( 0x0f & (x) ) ) + +/* +Note that the H-register is zeroed after use, and that the high order 4-bits +of the Address register must be set (if non-zero) after the low order 8-bits. +The Address register is automatically incremented by one after a write data +operation and by x after a read data operation. When writing to any of the +EEPROM memory pages a time of 10ms per byte has to be allowed. For this reason +it is recommended that instructions SRH and WRD are always used together +(even if the SRH is not needed) since this will ensure that the EEPROM has +sufficient time to complete its write cycle. + +Additionally to allow time for local receiver memory updates and SNC detector +sampling in addition to the EEPROM write cycle, it is recommended to lock the +receiver to level 2 or 3, or add a NOP instruction after each write. This is +not required for firmware revision 1.4 but locking is still recommended. + +The mask operation helps with locations in memory that are shared by two +parameters and aids setting and clearing bits. The mask operates only in +Page 0. + +If bits in the mask are set, then a following write operation will leave the +corresponding bits unchanged. The mask register is cleared after a write so +that subsequent writes are processed normally. Because it defaults to zero at +reset, the mask is inoperative unless specifically set. + +The operate button instruction uses the same button codes as are returned +from routine 15 (see section 8), with an additional code of zero which +operates the power button, but will not switch the receiver off. Also code +0 will switch the receiver on (from standby state). + +7) Memory pages. + +Page 0 Working memory (RAM) 256 bytes. +Page 1 Battery sustained memory (RAM) 256 bytes. +Page 2 Non-volatile memory (EEPROM) 512 bytes. +Page 3 <1> Non-volatile memory (EEPROM) 4096 bytes. +Page 4 <1> Non-volatile memory (EEPROM) 4096 bytes. +Pages 5 - 14 Not assigned. +Page 15 Receiver Ident (ROM) 8 bytes. +*/ +enum PAGE_e +{ + WORKING = 0, + BBRAM = 1, + EEPROM1 = 2, + EEPROM2 = 3, + EEPROM3 = 4, + ROM = 15 +}; + +const unsigned int PAGE_SIZE[] = { + 256, 256, 512, 4096, 4096, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8 +}; + +/* +The ident is divided into model number (5 bytes), software revision (2 bytes) +and type letter (1 byte). + +e.g. 7030_14A => Model AR-7030, revision 1.4, type letter A. + +8) Lock levels. + +Level 0 Normal operation. + +Level 1 IR remote control disabled. + + Front panel buttons ignored. + Front panel spin-wheels logged but not actioned. + Display update (frequency & S-meter) continues. + +Level 2 As level 1, but display update suspended. + +In revisions before 1.4 squelch operation is inhibited, which results in +no audio output after a mode change. In revision 1.4 squelch operation +continues and mode changing is as expected. + +Level 3 Remote operation exclusively. + +Lock level 1 is recommended during any multi-byte reads or writes of the +receiver's memory to prevent data contention between internal and remote +memory access. See also EEPROM notes in section (6) +*/ +enum LOCK_LVL_e +{ + LOCK_0 = 0, + LOCK_1 = 1, + LOCK_2 = 2, + LOCK_3 = 3 +}; + +/* +8) Routines. + +Routine 0 Reset Setup receiver as at switch-on. + +Routine 1 Set frequency Program local oscillator from frequ area and + setup RF filters and oscillator range. + +Routine 2 Set mode Setup from mode byte in memory and display mode, + select preferred filter and PBS, BFO values etc. + +Routine 3 Set passband Setup all IF parameters from filter, pbsval and + bfoval bytes. + +Routine 4 Set all Set all receiver parameters from current memory values. + +Routine 5 <2> Set audio Setup audio controller from memory register values. + +Routine 6 <2> Set RF-IF Setup RF Gain, IF Gain and AGC speed. Also sets Notch + Filter and Noise Blanker if these options are fitted. + +Routine 7 Not assigned + +Routine 8 Not assigned + +Routine 9 Direct Rx control Program control register from rxcon area. + +Routine 10 Direct DDS control Program local oscillator and carrier + oscillator DDS systems from wbuff area. + The 32-bits at wbuff control the carrier frequency, + value is 385674.4682 / kHz. The 32 bits at wbuff+4 control + the local osc frequency, value is 753270.4456 / MHz. + +Routine 11 Display menus Display menus from menu1 and menu2 bytes. + +Routine 12 Display frequency Display frequency from frequ area. + +Routine 13 Display buffer Display ASCII data in wbuff area. First byte is + display address, starting at 128 for the top line and 192 + for the bottom line. An address value of 1 clears the display. + Data string (max length 24 characters) ends with a zero byte. + +Routine 14 Read signal strength Transmits byte representing received + signal strength (read from AGC voltage). Output is 8-bit + binary in range 0 to 255. + +Routine 15 Read buttons Transmits byte indicating state of front panel + buttons. Output is 8-bit binary with an offset of +48 + (i.e. ASCII numbers). Buttons held continuously will only be + registered once. +*/ + +enum ROUTINE_e +{ + RESET = 0, + SET_FREQ = 1, + SET_MODE = 2, + SET_PASS = 3, + SET_ALL = 4, + SET_AUDIO = 5, + SET_RFIF = 6, + DIR_RX_CTL = 9, + DIR_DDS_CTL = 10, + DISP_MENUS = 11, + DISP_FREQ = 12, + DISP_BUFF = 13, + READ_SIGNAL = 14, + READ_BTNS = 15 +}; + +/* +Button codes :- + + 0 = None pressed 5 = RF-IF button + 1 = Mode up button 6 = Memory button + 2 = Mode down button 7 = * button + 3 = Fast button 8 = Menu button + 4 = Filter button 9 = Power button +*/ +enum BUTTON_e +{ + BTN_NONE = 0, + BTN_UP = 1, + BTN_DOWN = 2, + BTN_FAST = 3, + BTN_FILTER = 4, + BTN_RFIF = 5, + BTN_MEMORY = 6, + BTN_STAR = 7, + BTN_MENU = 8, + BTN_POWER = 9 +}; + +/* +Note that the work buffer wbuff area in memory is used continuously by the +receiver unless lock levels 2 or 3 are invoked. Lock levels of 1 or more +should be used when reading any front panel controls to prevent erratic +results. + +10) Battery sustained RAM (Memory page 1) + + Address Ident Length Description + 0 0x000 13 bytes Real time clock / timer registers :- + 0 0x000 rt_con 1 byte Clock control register + 2 0x002 rt_sec 1 byte Clock seconds (2 BCD digits) + 3 0x003 rt_min 1 byte Clock minutes (2 BCD digits) + 4 0x004 rt_hrs 1 byte Clock hours (2 BCD digits - 24 hr format) + 5 0x005 rt_dat 1 byte Clock year (2 bits) and date (2 BCD digits) + 6 0x006 rt_mth 1 byte Clock month (2 BCD digits - low 5 bits only) + 8 0x008 tm_con 1 byte Timer control register + 10 0x00A tm_sec 1 byte Timer seconds (2 BCD digits) + 11 0x00B tm_min 1 byte Timer minutes (2 BCD digits) + 12 0x00C tm_hrs 1 byte Timer hours (2 BCD digits - 24 hr format) + 13 0x00D 15 bytes Power-down save area :- + 13 0x00D ph_cal 1 byte Sync detector phase cal value + 14 0x00E pd_slp 1 byte Timer run / sleep time in minutes + 15 0x00F pd_dly 1 byte Scan delay value x 0.125 seconds + 16 0x010 pd_sst 1 byte Scan start channel + 17 0x011 pd_ssp 1 byte Scan stop channel + 18 0x012 pd_stp 2 bytes Channel step size + 20 0x014 pd_sql 1 byte Squelch + 21 0x015 pd_ifg 1 byte IF gain + 22 0x016 pd_flg 1 byte Flags (from pdflgs) + 23 0x017 pd_frq 3 bytes Frequency + 26 0x01A pd_mod <3> 1 byte Mode (bits 0-3) and + NB threshold (bits 4-7) + 27 0x01B pd_vol <3> 1 byte Volume (bits 0-5) and + rx memory hundreds (bits 6&7) + 28 0x01C 26 bytes Receiver setup save area :- + 28 0x01C md_flt 1 byte AM mode : Filter (bits 0-3) and + AGC speed (bits 4-7) + 29 0x01D md_pbs 1 byte AM mode : PBS value + 30 0x01E md_bfo 1 byte AM mode : BFO value + 31 0x01F 3 bytes Ditto for Sync mode + 34 0x022 3 bytes Ditto for NFM mode - + except Squelch instead of BFO + 37 0x025 3 bytes Ditto for Data mode + 40 0x028 3 bytes Ditto for CW mode + 43 0x02B 3 bytes Ditto for LSB mode + 46 0x02E 3 bytes Ditto for USB mode + 49 0x031 st_aud <3> 1 byte Audio bass setting (bits 0-4) + bit 5 Notch auto track enable + bit 6 Ident search enable + bit 7 Ident preview enable + 50 0x032 1 byte Audio treble setting (bits 0-3) and + RF Gain (bits 4-7) + 51 0x033 1 byte Aux output level - left channel + 52 0x034 1 byte Aux output level - right channel + 53 0x035 st_flg 1 byte Flags (from stflgs) + 54 0x036 26 bytes Setup memory A (configured as above) + 80 0x050 26 bytes Setup memory B (configured as above) + 106 0x06A 26 bytes Setup memory C (configured as above) + 132 0x084 24 bytes Filter data area :- + 132 0x084 fl_sel 1 byte Filter 1 : selection bits and IF bandwidth + 133 0x085 fl_bw 1 byte Filter 1 : bandwidth (2 BCD digits, x.x kHz) + 134 0x086 fl_uso 1 byte Filter 1 : USB offset value x 33.19Hz + 135 0x087 fl_lso 1 byte Filter 1 : LSB offset value x 33.19Hz + 136 0x088 4 bytes Ditto for filter 2 + 140 0x08C 4 bytes Ditto for filter 3 + 144 0x090 4 bytes Ditto for filter 4 + 148 0x094 4 bytes Ditto for filter 5 + 152 0x098 4 bytes Ditto for filter 6 + 156 0x09C mem_sq 100 bytes Squelch / BFO values for + frequency memories 0 to 99 + (BFO for Data and CW modes, + Squelch for others) +*/ +#define MAX_MEM_SQL_PAGE0 (99) + +enum FILTER_e +{ + FILTER_1 = 1, + FILTER_2 = 2, + FILTER_3 = 3, + FILTER_4 = 4, + FILTER_5 = 5, + FILTER_6 = 6 +}; + +enum BBRAM_mem_e +{ + rt_con = 0, + rt_sec = 2, + rt_min = 3, + rt_hrs = 4, + rt_dat = 5, + rt_mth = 6, + tm_con = 8, + tm_sec = 10, + tm_min = 11, + tm_hrs = 12, + ph_cal = 13, + pd_slp = 14, + pd_dly = 15, + pd_sst = 16, + pd_ssp = 17, + pd_stp = 18, + pd_sql = 20, + pd_ifg = 21, + pd_flg = 22, + pd_frq = 23, + pd_mod = 26, + pd_vol = 27, + md_flt = 28, + md_pbs = 29, + md_bfo = 30, + st_aud = 49, + st_flg = 53, + fl_sel = 132, + fl_bw = 133, + fl_uso = 134, + fl_lso = 135, + mem_sq = 156 +}; + +/* +11) EEPROM (Memory page 2) + + Address Ident Length Description + 0 0x000 4 bytes Frequency memory data :- + 0 0x000 mem_fr 3 bytes Memory 00 : 24-bit frequency + 3 0x003 mem_md 1 byte bits 0 - 3 mode + bits 4 - 6 filter + bit 7 scan lockout + 4 0x004 396 bytes Ditto for memories 01 to 99 + 400 0x190 mem_pb 100 bytes PBS values for frequency memories 0 to 99 + 500 0x1F4 sm_cal 8 bytes S-meter calibration values :- + 500 0x1F4 1 byte RSS offset for S1 level + 501 0x1F5 1 byte RSS steps up to S3 level + 502 0x1F6 1 byte RSS steps up to S5 level + 503 0x1F7 1 byte RSS steps up to S7 level + 504 0x1F8 1 byte RSS steps up to S9 level + 505 0x1F9 1 byte RSS steps up to S9+10 level + 506 0x1FA 1 byte RSS steps up to S9+30 level + 507 0x1FB 1 byte RSS steps up to S9+50 level + 508 0x1FC if_cal 2 bytes RSS offsets for -20dB + and -8dB filter alignment + 510 0x1FE if_def 1 byte Default filter numbers for + narrow and wide (2 BCD digits) + 511 0x1FF option <1> 1 byte Option information :- + bit 0 Noise blanker + bit 1 Notch filter + bit 2 10 dB step attenuator (DX version) +*/ +#define MAX_MEM_FREQ_PAGE2 (99) +#define MAX_MEM_PBS_PAGE2 (99) + +enum EEPROM1_mem_e +{ + mem_fr = 0, + mem_md = 3, + mem_pb = 400, + sm_cal = 500, + if_cal = 508, + if_def = 510, + option = 511 +}; + +/* +12) EEPROM (Memory page 3) . + + Address Ident Length Description + 0 0x000 4 bytes Frequency memory data :- + 0 0x000 mex_fr 3 bytes Memory 100 : 24-bit frequency + 3 0x003 mex_md 1 byte bits 0 - 3 mode + bits 4 - 6 filter + bit 7 scan lockout + 4 0x004 1196 bytes Ditto for memories 101 to 399 +1200 0x4B0 8 bytes Timer memory data :- +1200 0x4B0 mtm_mn 1 byte Timer memory 0 : minutes (2 BCD digits) +1201 0x4B1 mtm_hr 1 byte hours (2 BCD digits) +1202 0x4B2 mtm_dt 1 byte date (2 BCD digits) +1203 0x4B3 mtm_mt 1 byte month (2 BCD digits) +1204 0x4B4 mtm_ch 2 bytes rx channel (hundreds and 0-99) +1206 0x4B6 mtm_rn 1 byte run time +1207 0x4B7 mtm_ac 1 byte active (0 = not active) +1208 0x4B8 72 bytes Ditto for timer memories 1 to 9 +1280 0x500 16 bytes Frequency memory data :- +1280 0x500 mex_sq 1 byte Memory 0 : Squelch / BFO (not used for + mems 0 to 99) + (BFO for Data and CW modes) +1281 0x501 mex_pb 1 byte PBS value (not used for mems 0 to 99) +1282 0x502 mex_id 14 bytes Text Ident +1296 0x510 2800 bytes Ditto for memories 1 to 175 +*/ +#define MAX_MEM_FREQ_PAGE3 (399) +#define MAX_MEM_SQL_PAGE3 (175) +#define MAX_MEM_PBS_PAGE3 (175) +#define MAX_MEM_ID_PAGE3 (175) + +enum EEPROM2_mem_e +{ + mex_fr = 0, + mex_md = 3, + mtm_mn = 1200, + mtm_hr = 1201, + mtm_dt = 1202, + mtm_mt = 1203, + mtm_ch = 1204, + mtm_rn = 1206, + mtm_ac = 1207, + mex_sq = 1280, + mex_pb = 1281, + mex_id = 1282 +}; + +/* +13) EEPROM (Memory page 4) <1> + + Address Ident Length Description + 0 0x000 16 bytes Frequency memory data :- + 0 0x000 1 byte Memory 176 : Squelch / BFO + (BFO for Data and CW modes) + 1 0x001 1 byte PBS value + 2 0x002 14 bytes Text Ident + 16 0x010 3568 bytes Ditto for memories 177 to 399 +3584 0xE00 mex_hx 400 bytes Frequency fast find index + (1 byte for each memory 0 to 399) + Index value is bits 9 to 16 of 24-bit + frequency stored in each memory. Empty + memories (frequency zero) should have + a random index byte. +3984 0xF90 112 bytes spare +*/ + +enum EEPROM3_mem_e +{ + mey_sq = 0, + mey_pb = 1, + mey_id = 2, + mex_hx = 3584 +}; + +/* +14) Working memory (Memory page 0) + +Areas not specifically addressed are used as workspace by the internal +processor. - Keep out (by order). + + Address Ident Length Description + 16 0x010 snphs 1 byte Sync detector phase offset cal value + 17 0x011 slptim 1 byte Sleep time (minutes) + 18 0x012 scnst 1 byte Scan start channel + 19 0x013 scnsp 1 byte Scan stop channel + 20 0x014 scndly 1 byte Scan delay time value x 0.125 seconds + 21 0x015 chnstp 2 bytes 16-bit channel step size, + value is 376.6352 / kHz + 23 0x017 sqlsav 1 byte Squelch save value (non-fm mode) + 24 0x018 ifgain 1 byte IF gain value (zero is max gain) + 26 0x01A frequ 3 bytes 24-bit tuned frequency, + value is 376635.2228 / MHz. + 29 0x01D mode 1 byte Current mode :- 1 = AM 4 = Data + 2 = Sync 5 = CW + 3 = NFM 6 = LSB + 7 = USB + 30 0x01E 10 bytes Audio control registers :- + 30 0x01E af_vol 1 byte Main channel volume (6-bits, values 15 to 63) + 31 0x01F af_vll 1 byte Left channel balance + (5-bits, half of volume value above) + 32 0x020 af_vlr 1 byte Right channel balance (as above) + 33 0x021 af_bas <1> 1 byte Main channel bass + (bits 0-4, values 6 to 25, 15 is flat) + bit 5 nchtrk Notch auto track enable + bit 6 idauto Ident auto search enable + bit 7 idprev Ident auto preview enable + 34 0x022 af_trb <3> 1 byte Main channel treble + (bits 0-3, values 2 to 10, 6 is flat) + bit 4 nb_opt Noise blanker menus enabled + bit 5 nt_opt Notch Filter menus enabled + bit 6 step10 10 dB RF attenuator fitted + 35 0x023 af_axl 1 byte Left aux channel level + (bits 0-5, values 27 to 63) + 36 0x024 af_axr <3> 1 byte Right aux channel level + (bits 0-5, values 27 to 63) + bit 7 nchsr Notch search running + 37 0x025 af_axs <3> 1 byte Aux channel source (bits 0-3) + bit 4 nchen Notch filter active + bit 5 nchsig Notch filter signal detected + bit 6 axmut Aux output mute + bit 7 nchato Notch auto tune active + 38 0x026 af_opt <3> 1 byte Option output source (bits 0-3) + bit 4 idover Ident on LCD over frequency + bit 5 idsrdn Ident search downwards + bit 7 idsrch Ident search in progress + 39 0x027 af_src 1 byte Main channel source + bit 6 afmut Main output mute + 40 0x028 rxcon 3 bytes Receiver control register mapping :- + byte 1 bit 0 rx_fs3 Filter select : FS3 + byte 1 bit 1 rx_fs2 Filter select : FS2 + byte 1 bit 2 rx_fs1 Filter select : FS1 + byte 1 bit 3 rx_fs4 Filter select : FS4 + byte 1 bit 4 rx_pre Preamplifier enable + byte 1 bit 5 rx_atr Atten : 0 = 20dB / 1 = 40dB + byte 1 bit 6 rx_rff Input filter : 0 = HF / 1 = LF + byte 1 bit 7 rx_atn Attenuator enable + byte 2 bit 0 rx_as1 AGC speed : 00 = Slow + byte 2 bit 1 rx_as2 10 = Med + 11 = Fast + byte 2 bit 2 rx_agi AGC inhibit + byte 2 bit 3 rx_en LO and HET enable + byte 2 bit 4 rx_aux Aux relay enable + byte 2 bit 5 rx_fs5 Filter select : FS5 + byte 2 bit 6 rx_fs6 Filter select : FS6 + byte 2 bit 7 rx_ibw IF b/w : 0 = 4kHz / 1 = 10kHz + byte 3 bit 0 rx_chg Fast charge enable + byte 3 bit 1 rx_pwr PSU enable + byte 3 bit 2 rx_svi Sync VCO inhibit + byte 3 bit 3 rx_agm AGC mode : 0 = peak / 1 = mean + byte 3 bit 4 rx_lr1 LO range : 00 = 17 - 30 MHz + byte 3 bit 5 rx_lr2 10 = 10 - 17 MHz + 01 = 4 - 10 MHz + 11 = 0 - 4 MHz + byte 3 bit 6 rx_sbw Sync b/w : 0 = Wide / 1 = Narrow + byte 3 bit 7 rx_car Car sel : 0 = AM / 1 = DDS + 43 0x02B bits 3 bytes General flags :- + byte 1 bit 6 lock1 Level 1 lockout + byte 1 bit 7 lock2 Level 2 lockout + byte 2 bit 0 upfred Update frequency display + byte 2 bit 1 upmend Update menus + byte 2 bit 2 tune4x Tune 4 times faster (AM & NFM) + byte 2 bit 3 quickly Quick tuning (fast AGC, Sync) + byte 2 bit 4 fast Fast tuning mode + byte 2 bit 5 sncpt1 Auto sync - frequency lock + byte 2 bit 6 sncpt2 Auto sync - phase lock + byte 2 bit 7 sncal Sync detector calibrating + byte 3 bit 0 sqlch Squelch active (i.e. low signal) + byte 3 bit 1 mutsql Mute on squelch (current setting) + byte 3 bit 2 bscnmd Scan mode for VFO B + byte 3 bit 3 dualw Dual watch active + byte 3 bit 4 scan Scan active + byte 3 bit 5 memlk Current memory scan lockout + byte 3 bit 6 pbsclr Enable PBS CLR from IR remote + <2> byte 3 bit 7 memodn MEM button scans downwards + 46 0x02E pdflgs 1 byte Flags saved at power-down :- + bit 0 power Power on + bit 1 flock Tuning locked + bit 2 batop Battery operation (for fast chg) + <1> bit 3 nben Noise blanker active + <1> bit 4 nblong Noise blanker long pulse + 47 0x02F stflgs 1 byte Flags saved in setup memories :- + bit 0 mutsav Mute on squelch (non-fm mode) + bit 1 mutaux Mute aux output on squelch + bit 2 axren Aux relay on timer + bit 3 axrsql Aux relay on squelch + bit 4 snauto Auto sync mode + bit 5 snarr Sync detector narrow bandwidth + bit 6 scanmd Scan runs irrespective of squelch + bit 7 autorf RF gain auto controlled + 48 0x030 rfgain 1 byte Current RF gain setting (0 to 5) (0=max gain) + 49 0x031 rfagc 1 byte Current RF AGC setting (added to above) + 50 0x032 agcspd 1 byte Current AGC speed : 0 = Fast 2 = Slow + 1 = Medium 3 = Off + 51 0x033 sqlval 1 byte Squelch value (current setting) + 52 0x034 filter 1 byte Current filter number (1 to 6) + 53 0x035 pbsval 1 byte PBS offset (x33.19Hz) + 54 0x036 bfoval 1 byte BFO offset (x33.19Hz) + 55 0x037 fltofs 1 byte Filter centre frequency offset (x33.19Hz) + 56 0x038 fltbw 1 byte Filter bandwidth (2 BCD digits : x.x kHz) + 57 0x039 ircode: 2 bytes Current / last IR command code + 59 0x03B spnpos 1 byte Misc spin-wheel movement } 0 = no movement + 60 0x03C volpos 1 byte Volume control movement } +ve = clockwise + 61 0x03D tunpos 1 byte Tuning control movement } -ve = anti-clockwise + 62 0x03E lstbut 1 byte Last button pressed + 63 0x03F smval 2 bytes Last S-meter reading (bars + segments) + 65 0x041 mestmr 1 byte Message time-out timer + 66 0x042 rfgtmr 1 byte RF gain delay timer + 67 0x043 updtmr 1 byte Sustained RAM update timer + 68 0x044 agctmr 1 byte AGC speed restore delay timer + 69 0x045 snctmr 1 byte Auto sync refresh timer + 70 0x046 scntmr 1 byte Scan delay timer + 71 0x047 irdly 1 byte IR remote auto repeat delay counter + 72 0x048 runtmr 1 byte Sleep mode timer + 73 0x049 snfrq 1 byte Sync detector frequency offset cal value + 74 0x04A frange 1 byte Input / LO range + 75 0x04B menu1 <3> 1 byte Current left menu (type A and B menu + numbers are different) + 76 0x04C menu2 <3> 1 byte Current right menu (type A and B menu + numbers are different) + 77 0x04D memno 1 byte Current memory number + 78 0x04E setno 1 byte Setup / config selection - load / save + 85 0x055 mempg <1> 1 byte Memory page (hundreds - value 0 to 3) + 86 0x056 nbthr <1> 1 byte Noise blanker threshold (values 0 to 15) + 87 0x057 hshfr <1> 1 byte Current tuned frequ index value + (during ident search) + 88 0x058 nchtmr <1> 1 byte Notch filter auto tune / search timer + 90 0x059 wbuff 26 bytes Work buffer + 115 0x073 keymd 1 byte IR remote +/- keys function + 116 0x074 keybuf 20 bytes IR remote key input buffer + 136 0x088 frofs: 4 bytes 32-bit local osc offset + 140 0x08C carofs 4 bytes 32-bit carrier osc offset + 144 0x090 smofs 1 byte S-meter starting offset + 145 0x091 smscl 7 bytes S-meter segment values + 152 0x098 ifcal 2 bytes RSS offsets for -20 dB and + -5 dB filter alignment + 154 0x09A ifdef 1 byte Default filter numbers for narrow and wide + (2 digits) + 155 0x09B vfo_b 22 bytes VFO B storage area :- + 155 0x09B 1 byte B : Scan delay time + 156 0x09C 2 bytes B : Channel step size + 158 0x09E 1 byte B : Squelch save value (non-fm mode) + 159 0x09F 1 byte B : IF gain value + 160 0x0A0 1 byte not used + 161 0x0A1 3 bytes B : Tuned frequency + 164 0x0A4 1 byte B : Mode + 165 0x0A5 1 byte B : Volume + 166 0x0A6 1 byte B : Left channel balance + 167 0x0A7 1 byte B : Right channel balance + 168 0x0A8 1 byte B : Bass response + 169 0x0A9 1 byte B : Treble response + 170 0x0AA 1 byte B : RF gain + 171 0x0AB 1 byte B : RF AGC + 172 0x0AC 1 byte B : AGC speed + 173 0x0AD 1 byte B : Squelch value + 174 0x0AE 1 byte B : Filter number + 175 0x0AF 1 byte B : PBS offset + 176 0x0B0 1 byte B : BFO offset + 218 0x0DA savmnu <1> 1 byte Saved menu 1 number during ident display + 219 0x0DB srchm <1> 2 bytes Ident search memory (page and number) + 222 0x0DD idtmr <1> 1 byte Auto ident search start timer + 223 0x0DE nchfr <1> 2 bytes 16-bit notch filter frequency, + value is 6553.6 / kHz +*/ + +#define HZ_PBS_STEP \ + ((44545000.0 * 25.0)/(16777216.0 * 2.0)) /* 33.1886 Hz/Step */ +#define NOTCH_STEP_HZ (6.5536) /* 6.5536 Hz/Step */ +#define VOL_MIN (15) +#define VOL_MAX (63) +#define BASS_MIN (6) +#define BASS_MAX (25) +#define TREB_MIN (2) +#define TREB_MAX (10) +#define AUX_MIN (27) +#define AUX_MAX (63) + +enum MODE_e +{ + AM = 1, + SAM = 2, + FM = 3, + DATA = 4, + CW = 5, + LSB = 6, + USB = 7 +}; + +enum AGC_decay_e +{ + decay_slow = 0, + decay_med = 2, + decay_fast = 3 +}; + +enum LO_range_e +{ + lo_17_30 = 0, + lo_4_10 = 1, + lo_10_17 = 2, + lo_0_4 = 3 +}; + +enum AGC_spd_e +{ + agc_fast = 0, + agc_med = 1, + agc_slow = 2, + agc_off = 3 +}; + +enum WORKING_mem_e +{ + snphs = 16, + slptim = 17, + scnst = 18, + scnsp = 19, + scndly = 20, + chnstp = 21, + sqlsav = 23, + ifgain = 24, + frequ = 26, + modew = 29, + af_vol = 30, + af_vll = 31, + af_vlr = 32, + af_bas = 33, + af_trb = 34, + af_axl = 35, + af_axr = 36, + af_axs = 37, + af_opt = 38, + af_src = 39, + rxcon = 40, + bits = 43, + pdflgs = 46, + stflgs = 47, + rfgain = 48, + rfagc = 49, + agcspd = 50, + sqlval = 51, + filter = 52, + pbsval = 53, + bfoval = 54, + fltofs = 55, + fltbw = 56, + ircode = 57, + spnpos = 59, + volpos = 60, + tunpos = 61, + lstbut = 62, + smval = 63, + mestmr = 65, + rfgtmr = 66, + updtmr = 67, + agctmr = 68, + snctmr = 69, + scntmr = 70, + irdly = 71, + runtmr = 72, + snfrq = 73, + frange = 74, + menu1 = 75, + menu2 = 76, + memno = 77, + setno = 78, + mempg = 85, + nbthr = 86, + hshfr = 87, + nchtmr = 88, + wbuff = 90, + keymd = 115, + keybuf = 116, + frofs = 136, + carofs = 140, + smofs = 144, + smscl = 145, + ifcal = 152, + ifdef = 154, + vfo_b = 155, + scndly_b = 155, + chnstp_b = 156, + sqlsav_b = 158, + ifgain_b = 159, + frequ_b = 161, + modew_b = 164, + af_vol_b = 165, + af_vll_b = 166, + af_vlr_b = 167, + af_bas_b = 168, + af_trb_b = 169, + rfgain_b = 170, + rfagc_b = 171, + agcspd_b = 172, + sqlval_b = 173, + filter_b = 174, + pbsval_b = 175, + bfoval_b = 176, + savmnu = 218, + srchm = 219, + idtmr = 222, + nchfr = 223 +}; + +enum ROM_mem_e +{ + identr = 0 +}; + +#define HZ_PER_STEP ( 44545000.0 / 16777216.0 ) /* 2.655 Hz/Step */ +#define STEPS_PER_HZ ( 16777216.0 / 44545000.0 ) /* 0.3766 Steps/Hz */ +#define MAX_FREQ (32010000.0) +#define MIN_FREQ (10000.0) + +/* +RS232 signal meter reading - additional comments + +Several commercial organisations are using the AR7030 for signal monitoring +purposes and wish to accurately log signal meter level. The information is +given in the RS232 PROTOCOL LISTING but the subject is fairly complex. A +summary of the required process is given here, the text has been generated by +John Thorpe in response to a commercial request for more detailed guidance +(November 2001). + +Reading the input signal strength from the AR7030 is not too difficult, but +some maths is needed to convert the level into dBm. + +Each set is calibrated after manufacture and a set of S-meter calibration +values stored in EEPROM in the receiver. This means that the signal strength +readings should be quite good and consistent. I think that you should get less +than 2dB change with frequency and maybe 3dB with temperature. Initial +calibration error should be less than +/- 2dB. + +I think the sets that you use have been modified for DRM use have some +changes in the IF stage. This will require that the sets are re-calibrated if +you are to get accurate results. The SM7030 service kit has a calibration +program (for PC) and is available from AOR. + +The signal strength is read from the AGC voltage within the 7030 so AGC +should be switched on and RF Gain set to maximum. To read AGC voltage send +opcode 02EH (execute routine 14) and the receiver will return a single byte +value between 0 and 255 which is the measured AGC voltage. + +The calibration table is stored in EEPROM, so the control software should +read this when connection to the receiver is established and store the data +in an array for computing. + +Calibration data is 8 bytes long and is stored in Page2 at locations +500 (0x01F4) to 507 (0x01FB). Use the PaGE opcode (0x52) then SRH, ADR, ADH +to setup the address, then 8 RDD opcodes to read the data, as below :- + +Opcode Hex Operation + +PGE 2 0x52 Set page 2 +SRH 15 0x3F H register = 15 +ADR 4 0x44 Set address 0x0F4 +ADH 1 0x11 Set address 0x1F4 +RDD +1 0x71 Read byte 1 of cal data +RDD +1 0x71 Read byte 2 of cal data +. . . +RDD +1 0x71 Read byte 8 of cal data + +PGE 0 0x50 Return to page 0 for subsequent control operations + +The first byte of calibration data holds the value of the AGC voltage for a +signal level of -113dBm (S1). Successive bytes hold the incremental values +for 10dB increases in signal level :- + +Cal data Typical Value RF signal level + +byte 1 64 -113dBm +byte 2 10 -103dBm +byte 3 10 -93dBm +byte 4 12 -83dBm +byte 5 12 -73dBm +byte 6 15 -63dBm +byte 7 30 -43dBm (note 20dB step) +byte 8 20 -23dBm (note 20dB step) +*/ +#define CAL_TAB_LENGTH (8) +#define STEP_SIZE_LOW (10) +#define STEP_SIZE_HIGH (20) + +/* +To calculate the signal level, table values should be subtracted from the AGC +voltage in turn until a negative value would result. This gives the rough +level from the table position. The accuracy can be improved by proportioning +the remainder into the next table step. See the following example :- + +A read signal strength operation returns a value of 100 +Subtract cal byte 1 (64) leaves 36 level > -113dBm +Subtract cal byte 2 (10) leaves 26 level > -103dBm +Subtract cal byte 3 (10) leaves 16 level > -93dBm +Subtract cal byte 4 (12) leaves 4 level > -83dBm +Test cal byte 5 (12) - no subtraction +Fine adjustment value = (remainder) / (cal byte 5) * (level step) + = 4 / 12 * 10 = 3dB +Signal level = -83dBm + 3dB = -80dB + +The receiver can operate the RF attenuator automatically if the signal level +is likely to overload the RF stages. Reading the RFAGC byte (page 0, location +49) gives the attenuation in 10dB steps. This value should be read and added +to the value calculated above. + +Further discussion has taken place on the subject of PC control with the +designer, the comments may be of assistance to other operators... + +As far as I can tell all of the commands and operations work exactly as +documented so when the client talks of "the set frequency command doesn't +work" they are obviously doing something wrong. + +Similarly, I am unable to duplicate the effects that they notice with +changing audio settings after changing modes. There are some issues with the +parameters that they are changing which I will address later, but first they +must sort out the basic communication so that the receiver control is as +expected. Further issues cannot really be sorted until this is working +properly. + +Programming issues... + +Since I have no Knowledge of what programming system the client is using +these are only general comments. The receiver control is in 8-bit binary code +so any communication must maintain all 8 bits (and not truncate bit 7 as some +printer outputs do). + +It is also essential that no extra characters are added to the output stream +so check that the software is not adding carriage returns, line feeds, nulls +or end-of-file markers to the output. If this might be a problem, monitor the +computer to receiver communication with a serial line monitor or another +computer running a simple RS-232 reading program. + +There is some sample BASIC code in the "AR-7030 Computer remote control +protocol" document which gives subroutines that cover the commonly used +receiver settings. Use this as a starting point for your own routines. The +published routines have been thoroughly tested and work without problems. + +http://www.aoruk.com/pdf/comp.pdf +http://www.aoruk.com/7030bulletin.htm#7030_rs232_s-meter + +With all "buffered" RS-232 connections it is possible for the computer and +receiver to get out of step when using two-way communication. For this reason +I included some "flush input buffer" routines in the sample code. Using these +ensures that missed characters or extra characters inserted due to noise or +disconnection do not disrupt communication between the computer and receiver, +and a recovery after communications failure can be automatic. + +Because the receiver's remote control is by direct access to memory and +processor it is a very flexible system but is also able to disrupt receiver +operation if incorrectly used. Only a few bytes of information stored in the +receiver's memory affect S-meter calibration and AOR (UK) hold records of +this data for each receiver made so that in the event of corruption it can be +re-programmed. + +See the note that follows regarding AGC calibration. + +All other working memory contents can be set to sensible values by a "Set +defaults" operation from the front panel. Most, but not all, of the working +memory is re-established by executing a remote "Reset" command (0x20) which +can be done as a last resort after control failure. + +Specific parameter settings... + +The client describes the correct operations for setting mode and frequency +but if, as he states, the set frequency command (021h) does not work then +this needs to be investigated. This may lead to discovering the cause of +other problems suffered by the client. + +Note that changing the frequency in this way re-tunes the receiver but does +not update the display on the front panel. A "Display frequency" command is +included for this purpose. + +To set the receiver main volume, three locations need to be written - +Page 0, addr 0x1e, 0x1f & 0x20. Details are in the protocol document, note the +minimum value (for zero volume) is 15. The aux channel level change is as +described by the client and after writing new values into the RAM will need +either a "Set audio" command or a "Set all" command to make the change. I can +find no reason for, nor duplicate, the effect of changing mode altering the +aux level so this effect also needs investigating - maybe the clients "write +to memory" is writing too many locations ? + +To initialise several receiver parameters I would recommend locking the +receiver, writing all of the required memory data, sending a "Set all" +command and then unlocking if required. There is no need to send individual +"Set" commands after each parameter. + +Unless very special requirements are needed (mainly test, setup and alignment +) the 3 rxcon locations should not be written. When a "Set all" command is +sent these will be programmed by the receiver firmware to appropriate values +for the mode, frequency and filters selected. + +Only the parameters that need changing need to be written, all other values +will be maintained. The locations that the client needs to program for the +parameters he lists are as follows:- + + (all Page 0) + frequency frequ 0x1a 0x1b 0x1c + mode mode 0x1d + volume af_vol 0x1e 0x1f 0x20 (values=0x0f 0x07 0x07 for min volume) + aux level af_axl 0x23 0x24 + agc speed agcspd 0x32 + squelch sqlval 0x33 + filter filter 0x34 + IF gain ifgain 0x18 + RF gain rfgain 0x30 (value=0x01 for no pre-amp) + message wbuff 0x59 (max 26 bytes) + +If the required parameter values are unknown, I recommend setting the +receiver as required through the front panel controls and then reading the +value of the memory locations affected using the "read data" operation. + +15) Sample routines (in MS QBASIC) + +REM Sample subroutines for communication with the AR-7030 A-type +REM These subroutines use the following variables :- +REM rx.freq# frequency in kHz (double precision) +REM rx.mode mode number (1 to 7) +REM rx.filt filter number (1 to 6) +REM rx.mem memory number (0 to 99) +REM rx.pbs passband shift value (-4.2 to +4.2 in kHz) +REM rx.sql squelch value (0 to 255) +REM ident$ -model number, revision and type + +REM Subroutine to open comms link to receiver +open.link: + open "com1:1200,n,8,1,cd0,cs0,ds0,rs" for random as #1 len = 1 + field #1, 1 as input.byte$ + return + +REM Subroutine to flush QBASIC serial input buffer +flush.buffer: + print #1,"//"; + do + time.mark# = timer + do while timer - time.mark# < 0.2 + loop + if eof(1) then exit do + get #1 + loop + return + +REM Subroutines to lock and unlock receiver controls +lock.rx: + print #1,chr$(&H81); ' Set lockout level 1 + return + +unlock.rx: + print #1,chr$(&H80); ' Lockout level 0 (not locked) + return + +REM Subroutine to read byte from comms link +read.byte: + read.value = -1 ' Value assigned for read error + time.mark# = timer + print #1,chr$(&H71); ' Read byte command + do while timer - time.mark# < 0.3 + if eof(1) = 0 then + get #1 + read.value = asc(input.byte$) + exit do + end if + loop + return + +REM Subroutine to set receiver frequency and mode +tune.rx: + gosub lock.rx + print #1,chr$(&H50); ' Select working mem (page 0) + print #1,chr$(&H31);chr$(&H4A); ' Frequency address = 01AH + gosub send.freq ' Write frequency + print #1,chr$(&H60+rx.mode); ' Write mode + print #1,chr$(&H24); ' Tune receiver + gosub unlock.rx + return + +REM Subroutine to store data into receiver's frequency memory +set.memory: + mem.loc = rx.mem+156 ' Squelch memory origin + mem.h = int(mem.loc/16) + mem.l = mem.loc mod 16 + print #1,chr$(&H51); ' Select squelch memory (page 1) + print #1,chr$(&H30+mem.h); + print #1,chr$(&H40+mem.l); ' Set memory address + print #1,chr$(&H30+int(rx.sql/16)) + print #1,chr$(&H60+rx.sql mod 16) ' Write squelch value + mem.loc = rx.mem*4 ' Frequency memory origin + mem.t = int(mem.loc/256) + mem.loc = mem.loc mod 256 + mem.h = int(mem.loc/16) + mem.l = mem.loc mod 16 + print #1,chr$(&H52); ' Select frequency memory (page 2) + print #1,chr$(&H30+mem.h); + print #1,chr$(&H40+mem.l); ' Set memory address + print #1,chr$(&H10+mem.t); + gosub send.freq ' Write frequency + print #1,chr$(&H30+rx.filt); + print #1,chr$(&H60+rx.mode); ' Write filter and mode + mem.loc = rx.mem+400-256 ' PBS memory origin + mem.h = int(mem.loc/16) + mem.l = mem.loc mod 16 + pbs.val = 255 and int(rx.pbs/0.033189+0.5) + print #1,chr$(&H30+mem.h); + print #1,chr$(&H40+mem.l); ' Set memory address + print #1,chr$(&H11); + print #1,chr$(&H30+int(pbs.val/16)) + print #1,chr$(&H60+pbs.val mod 16) ' Write passband value + return + +REM Subroutine to read data from receiver's frequency memory +read.memory: + mem.loc = rx.mem+156 ' Squelch memory origin + mem.h = int(mem.loc/16) + mem.l = mem.loc mod 16 + print #1,chr$(&H51); ' Select squelch memory (page 1) + print #1,chr$(&H30+mem.h); + print #1,chr$(&H40+mem.l); ' Set memory address + gosub read.byte ' Read squelch value + rx.sql = read.value + mem.loc = rx.mem*4 ' Frequency memory origin + mem.t = int(mem.loc/256) + mem.loc = mem.loc mod 256 + mem.h = int(mem.loc/16) + mem.l = mem.loc mod 16 + print #1,chr$(&H52); ' Select frequency memory (page 2) + print #1,chr$(&H30+mem.h); + print #1,chr$(&H40+mem.l); ' Set memory address + print #1,chr$(&H10+mem.t); + gosub read.freq ' Read frequency + gosub read.byte ' Read filter and mode + if read.value < 0 then return + rx.filt = int(read.value/16) + rx.mode = read.value mod 16 + mem.loc = rx.mem+400-256 ' PBS memory origin + mem.h = int(mem.loc/16) + mem.l = mem.loc mod 16 + print #1,chr$(&H30+mem.h); + print #1,chr$(&H40+mem.l); ' Set memory address + print #1,chr$(&H11); + gosub read.byte ' Read passband value + if read.value < 0 then return + if read.value > 127 then read.value = 256-read.value + rx.pbs = read.value*0.033189 + return + +REM Subroutine to read receiver ident string +read.ident: + print #1,chr$(&H5F); ' Select ident memory (page 15) + print #1,chr$(&H40); ' Set address 0 + ident$="" + for read.loop = 1 to 8 + gosub read.byte ' Read 8-byte ident + if read.value < 0 then exit for + ident$ = ident$+chr$(read.value) + next read.loop + return + +REM Subroutine to send frequency (Called only from other routines) +send.freq: + fr.val# = int(rx.freq#*376.635223+0.5) ' Convert kHz to steps + ' Exact multiplicand is + ' (2^24)/44545 + print #1,chr$(&H30+int(fr.val#/1048576)); + fr.val# = fr.val# mod 1048576 ' Write frequency as 6 hex digits + print #1,chr$(&H60+int(fr.val#/65536)); + fr.val# = fr.val# mod 65536 + print #1,chr$(&H30+int(fr.val#/4096)); + fr.val# = fr.val# mod 4096 + print #1,chr$(&H60+int(fr.val#/256)); + fr.val# = fr.val# mod 256 + print #1,chr$(&H30+int(fr.val#/16)); + print #1,chr$(&H60+(fr.val# mod 16)); + return + +REM Subroutine to read frequency (Called only from other routines) +read.freq: + fr.val# = 0 + for read.loop = 1 to 3 + gosub read.byte ' Read frequency as 3 bytes + if read.value < 0 then exit for + fr.val# = fr.val#*256+read.value + next read.loop + rx.freq# = fr.val#/376.635223 ' Convert steps to kHz + return +*/