--[[ Eugeniy Mikhailov 1 June 2021 (copied over from past work)]] -- there are 8 registers to track for lmx2487 -- labeled R0, R1, ..., R7 in the manual lmx2487_registers = {0, 0, 0, 0, 0, 0, 0, 0} -- if a register needs update set to true, updater script will resend this register lmx2487_need_update = {true, true, true, true, true, true, true, true} function set_lmx2487register(value, register) -- register labeled 0, 1, 2, ..., 7 if (lmx2487_registers[register+1] ~= value) then -- this is new value and thus needs to be updated in hardware lmx2487_registers[register+1] = value lmx2487_need_update[register+1] = true --print("updating register " .. register .. " with value " .. value) end -- otherwise we do nothing end function get_lmx2487register(register) -- register labeled 0, 1, 2, ..., 7 local value = (lmx2487_registers[register+1]) --print("register " .. register .. " is set to " .. value) return value end function send_register_lmx2487( register) if ( lmx2487_need_update[register +1] ) then --print(tmr.now()) print("sending register " .. register .. " with value " .. get_lmx2487register( register ) ) --print(tmr.now()) -- do hardware talking microwire_send_data( get_lmx2487register( register ) ) lmx2487_need_update[register+1]=false end end function update_lmx2487state() for register=7,0,-1 do -- going over registers -- manual suggest to send R0 as last one send_register_lmx2487( register ) end end function set_lmx2487_board_to_default_state() -- this defaults are historic and borrowed from lmx2487lib.tcl -- defaults (set RF freq to 6.83468635e9 GHz and lock it to 10MHz oscillator) lmx2487_need_update = {true, true, true, true, true, true, true, true} set_lmx2487register(11197502 , 0) set_lmx2487register(4352515 , 1) set_lmx2487register(8560613 , 2) set_lmx2487register(15925287 , 3) set_lmx2487register(10618633 , 4) set_lmx2487register(393579 , 5) set_lmx2487register(8126541 , 6) set_lmx2487register(10639 , 7) update_lmx2487state() end function freq2regestersValues(freq) local F_COMP = 5000000 -- magic number local N = freq / F_COMP local RF_N = math.floor(N) local frac = math.abs(N - RF_N) local RF_FD = 4000000 --magic number local RF_FN = math.floor( (frac * RF_FD) + 0.5) return freq, RF_N, RF_FN, RF_FD end -- test freq2regestersValues fIn = 6.834e9 freq, RF_N, RF_FN, RF_FD = freq2regestersValues(fIn) if freq ~= fIn and RF_N ~= 1366 and RF_FN ~= 3200000 and 4000000 then print("ERROR in freq2regestersValues") end fIn=nil freq=nil RF_N=nil RF_FN=nil RF_FD=nil -- end of freq2regestersValues test -- bits in mask counted starting from position 1, -- i.e. 1 sets bit in 1st pos, 2 sets bit in 2nd pos mask_bits14to24=bit.lshift( bit.bit(11)-1, 13) mask_bits2to13=bit.lshift( bit.bit(12)-1, 1) mask_bits5to16=bit.lshift( bit.bit(12)-1, 4) mask_bits5to14=bit.lshift( bit.bit(10)-1, 4) mask_bits15to24=bit.lshift( bit.bit(10)-1, 14) mask_bits5to24=bit.bor(mask_bits5to14, mask_bits15to24) mask_low12bits = bit.bit(12)-1 mask_bits13andAbove = bit.bnot(mask_low12bits) function FreqToSettingsBin(freq) local freq, RF_N, RF_FN, RF_FD = freq2regestersValues(freq) R0_new=get_lmx2487register(0) R1_new=get_lmx2487register(1) R5_new=get_lmx2487register(5) -- this code is extremely convoluted refer to the lmx2487 manual -- to see what bits are used in what place in a register. -- But I show in comments obsolete but human readable notation: -- tableReplace( Rn, bitSlice(..), stPos, endPos) -- settings["R0"]=tableReplace(settings["R0"], bRF_N, 14, 24) bitsRF_N = bit.lshift(RF_N, 13) R0_new = bit.band(R0_new, bit.bnot(mask_bits14to24)) R0_new = bit.bor(R0_new, bitsRF_N) -- settings["R0"]=tableReplace(settings["R0"], bitSlice(bRF_FN, 1, 12), 2, 13) bitsRF_FN_low = bit.band( RF_FN, mask_low12bits) R0_new = bit.band(R0_new, bit.bnot(mask_bits2to13)) R0_new = bit.bor(R0_new, bit.lshift(bitsRF_FN_low,1)) -- settings["R1"]=tableReplace(settings["R1"], bitSlice(bRF_FD, 1, 12), 5, 16) bitsRF_FD_low = bit.band( RF_FD, mask_low12bits) R1_new = bit.band(R1_new, bit.bnot(mask_bits5to16)) R1_new = bit.bor(R1_new, bit.lshift(bitsRF_FD_low,4)) -- settings["R5"]=tableReplace(settings["R5"], bitSlice(bRF_FN, 13, 22), 5, 14) -- settings["R5"]=tableReplace(settings["R5"], bitSlice(bRF_FD, 13, 22), 15, 24) RF_FN_above_12 = bit.band( RF_FN, mask_bits13andAbove) RF_FN_part = bit.rshift(RF_FN_above_12, 12) RF_FD_above_12 = bit.band( RF_FD, mask_bits13andAbove) RF_FD_above_12 = bit.rshift( RF_FD_above_12, 2) new_bits = bit.bor(RF_FN_part, RF_FD_above_12) R5_new = bit.band(R5_new, bit.bnot(mask_bits5to24)) R5_new = bit.bor(R5_new, bit.lshift(new_bits,4)) set_lmx2487register(R0_new, 0) set_lmx2487register(R1_new, 1) set_lmx2487register(R5_new, 5) end -- test setFreq set_lmx2487_board_to_default_state() FreqToSettingsBin(6.834e9) if get_lmx2487register(0) ~= 11192320 and get_lmx2487register(1) ~= 4362243 and get_lmx2487register(2) ~= 8560613 -- should not change and get_lmx2487register(5) ~= 16003291 then print("ERROR in FreqToSettingsBin: registers do not match") end FreqToSettingsBin(6.8204e9) if get_lmx2487register(0) ~= 11174912 and get_lmx2487register(1) ~= 4362243 -- should not change and get_lmx2487register(2) ~= 8560613 -- should not change and get_lmx2487register(5) ~= 15992043 then print("ERROR in FreqToSettingsBin: registers do not match") end FreqToSettingsBin(6.8346e9) if get_lmx2487register(0) ~= 11193856 and get_lmx2487register(1) ~= 4362243 -- should not change and get_lmx2487register(2) ~= 8560613 -- should not change and get_lmx2487register(5) ~= 16005163 then print("ERROR in FreqToSettingsBin: registers do not match") end function setFreq(freq) FreqToSettingsBin(freq) update_lmx2487state() end