function convert_hk, rec, mnem, raw_value=raw_value, qstop=qstop, $
	read_dbase=read_dbase, infil=infil, force_rd=force_rd, $
	insim=insim, nostring=nostring
;+
;NAME:
;	convert_hk
;PURPOSE:
;	To extract a given value of a mnemonic from a HK packet,
;	and convert it to the proper units (degrees/volts/...)
;SAMPLE CALLING SEQUENCE:
;	out = convert_hk(rec, mnem)
;	out = convert_hk(rec, 'm-15ae', /raw)
;INPUT:
;	rec	- The HK record structure
;	mnem	- The mnemonic to extract.  (single mnemonic input)
;OPTIONAL KEYWORD INPUT:
;	raw_value - Do not convert to engineering units.  Simply grab
;		    the right byte(s) and mask as necessary
;	qstop	- If set, then stop inside the program
;	read_dbase - If set, simply read the database file and return
;	infil	- the input database file to read
;	force_rd - Force the database file to be re-read
;	nostring - If set, then do not make the output string type (ie:
;		  do not use lookup table for "mnemonic" -- just send the
;		  raw value).  This only applies to digital mnemonics.
;HISTORY:
;	Written Apr-94 by M.Morrison
;	16-Jan-95 (MDM) - Modifications to allow SCHK1, SCHK2, SCHK4
;			- Added /FORCE_RD
;	 6-Feb-95 (MDM) - Added /NOSTRING option
;	16-Nov-95 (MDM) - Changed the default READ_HIST file names (from
;			  .DBS and .CCS to .INSIM and .EOF)
;	25-Apr-97 (SDW) - Added schk3
;-
;
;
common convert_hk_blk1, ootc, blktc, lvt_param, lvt_tx, lvt_txs, ca, cas
common convert_hk_blk2, hk1, hk2, schk, pdde, pdco, pca, pcdi
common convert_hk_blk3, schk1, schk2, schk3, schk4, map2pack
common convert_hk_blk4, last_convert
;
qinsim = keyword_set(insim)
if (n_elements(last_convert) eq 0) then last_convert = -99
if (qinsim ne last_convert) then force_rd = 1		;switched from CCS to/from INSIM mode - need new database
if ((n_elements(ootc) eq 0) or keyword_set(force_rd)) then begin
    print, 'Reading .HIS database file'
    if (n_elements(infil) eq 0) then begin
;	if (keyword_set(insim)) then infil = '$MDI_CAL_INFO/READ_HIST.DBS' $
;				else infil = '$MDI_CAL_INFO/READ_HIST.CCS'
	if (keyword_set(insim)) then infil = '$MDI_CAL_INFO/READ_HIST.INSIM' $
				else infil = '$MDI_CAL_INFO/READ_HIST.EOF'
    end
    rd_hist_dbase, ootc, blktc, lvt_param, lvt_tx, lvt_txs, ca, cas, $
                hk1, hk2, schk, pdde, pdco, pca, pcdi, $
		schk1, schk2, schk3, schk4, map2pack, infil=infil
end
last_convert = qinsim
;
if (keyword_set(read_dbase)) then return, -1
;
nam = string(lvt_param.st$name)
ss = where(nam eq mnem)
if (ss(0) eq -1) then begin
    print, 'Mnemonic not recognized: ' + mnem
    return, -1
end else begin
    case map2pack(ss(0)) of
	 1: mask_off = hk1		;out of MDI packet
	 2: mask_off = schk		;out of INSIM 14 byte S/C packet
	 4: mask_off = schk1		;out of S/C 1
	 8: mask_off = schk2		;out of S/C 2
	16: mask_off = schk3		;out of S/C 3
	32: mask_off = schk4		;out of S/C 4
    endcase
    ;
    nam2 = string(mask_off.st$name)
    ss2 = where(nam2 eq mnem)
    i1 = ss2(0)
    mask_off = mask_off(i1)
end

i2 = mask_off.lvt_idx
i3 = lvt_param(i2).pc_idx
;
val = 0L
nbits_set = 0
;for ibyte=1,4 do begin
for ibyte=4,1,-1 do begin
    status = execute('off = mask_off.offby' + strtrim(ibyte,2) )
    status = execute('mask = mask_off.mask' + strtrim(ibyte,2) )
    if (off ge 0) and (mask ne 0) then begin
	val0 = rec.hk(off)
	nbits_set0 = 8
	if (mask ne 255) and (mask gt 0) then begin
	    bits, mask, barr
	    ss = where(barr, nbits_set0)
	    shift0 = 2L^ss(0)
	    val0 = (val0 and mask) / shift0
	end
	val = val + val0 * 2L^nbits_set
	nbits_set = nbits_set + nbits_set0
    end
end
;
if (n_elements(val) gt 1) then val = reform(val)
if (keyword_set(raw_value)) then return, val
;
case lvt_param(i2).type of
    1: begin		;----- analog
		i4 = pca(i3).curve_idx
		ca0 = ca(i4)
		;
		xarr1 = cas( ca0.first_idx: ca0.last_idx).x_val
		yarr1 = cas( ca0.first_idx: ca0.last_idx).y_val
		xarr2 = indgen(2L^nbits_set)
		yarr2 = interpol(yarr1, xarr1, xarr2)
		val = yarr2(val)
       end
    2: begin		;----- digital
		i4 = pcdi(i3).tx_idx
		if (i4 ge 0) and (not keyword_set(nostring)) then begin
		    i5 = lvt_tx(i4).first_idx
		    i6 = lvt_tx(i4).last_idx
		    table = [string(lvt_txs(i5:i6).st$str_txs), '???']
		    nnn = n_elements(table)-1
		    val = table(val < nnn)
		end
	end
    4: 			;----- counter
    8: 			;----- register
endcase
;
if (keyword_set(qstop)) then stop
return, val
end
