summaryrefslogtreecommitdiff
path: root/lmx2487lib.lua
blob: bfaf717dd0c7bed9e1949a8a88b9c94b7c8cef9f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
 --[[
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