Compare commits
197
Commits
alpha-0.1
...
7f913a6d81
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f913a6d81 | ||
|
|
d377311d51 | ||
|
|
e2c4733a93 | ||
|
|
d8ed94bf2b | ||
|
|
169cb6bd91 | ||
|
|
6d665eb853 | ||
|
|
b8e8c6272a | ||
|
|
6b5ab3dc59 | ||
|
|
0339fd03c3 | ||
|
|
a6aff34dee | ||
|
|
08e1965a8e | ||
|
|
0753c698f7 | ||
|
|
0c5fc1ec2b | ||
|
|
a24d8e8d35 | ||
|
|
3e7060965e | ||
|
|
fd9e7f54eb | ||
|
|
f8212892a2 | ||
|
|
884d9bcca9 | ||
|
|
5af74419e0 | ||
|
|
f0b28b55fb | ||
|
|
97b8f28e70 | ||
|
|
608bbf1cfa | ||
|
|
711cb50658 | ||
|
|
746e87df86 | ||
|
|
fa24e0f109 | ||
|
|
40fdf13fd1 | ||
|
|
55cd53b746 | ||
|
|
c7c81ddb83 | ||
|
|
52f9390981 | ||
|
|
475a625663 | ||
|
|
7b36324101 | ||
|
|
c9f827661b | ||
|
|
475314f2a5 | ||
|
|
68396cb7ac | ||
|
|
688534c117 | ||
|
|
98ec0e7855 | ||
|
|
45a13b9c5d | ||
|
|
f7f3d76d9a | ||
|
|
f8985df185 | ||
|
|
fdc37dab4a | ||
|
|
cfc538bd4d | ||
|
|
da1659a582 | ||
|
|
f363d3afba | ||
|
|
ff4b609a37 | ||
|
|
bbdaa49d53 | ||
|
|
06169451f8 | ||
|
|
c763f1a481 | ||
|
|
8d72288675 | ||
|
|
16d1ad30a7 | ||
|
|
8779c9855e | ||
|
|
69a8d9d36d | ||
|
|
41964520a8 | ||
|
|
bab91e13df | ||
|
|
9b416114a1 | ||
|
|
e7b45ae1f5 | ||
|
|
3edfce69f2 | ||
|
|
ad3bc29cfa | ||
|
|
02fd467708 | ||
|
|
1fc4fad5ea | ||
|
|
957672a191 | ||
|
|
807b045b75 | ||
|
|
6f4774f6b8 | ||
|
|
de5759b392 | ||
|
|
2b18765563 | ||
|
|
03a6d86a3a | ||
|
|
729bbeb60e | ||
|
|
33545b63e1 | ||
|
|
6c64421336 | ||
|
|
dda9d09f2a | ||
|
|
14f2be3053 | ||
|
|
b7607a7a1b | ||
|
|
c07cd00f2f | ||
|
|
20da80f6c2 | ||
|
|
c7e3eb2800 | ||
|
|
9acdd0609a | ||
|
|
66529637a3 | ||
|
|
62cc15c3d4 | ||
|
|
98e6935d9a | ||
|
|
0c6d861620 | ||
|
|
f6c2568a75 | ||
|
|
ef1c41b500 | ||
|
|
9a7b89ca82 | ||
|
|
80035d5208 | ||
|
|
ab7ce2e082 | ||
|
|
f5aca7d5cf | ||
|
|
c3e0c7a66a | ||
|
|
2898bdfa15 | ||
|
|
31dcb5aa69 | ||
|
|
a1fc87dc97 | ||
|
|
009ddfd895 | ||
|
|
222dcb789c | ||
|
|
6b016e1181 | ||
|
|
712d37061a | ||
|
|
dfecadac56 | ||
|
|
c09bd57408 | ||
|
|
ec772ba9e3 | ||
|
|
51b96825a3 | ||
|
|
274ee8922e | ||
|
|
8c12c0e755 | ||
|
|
1e5f8052e5 | ||
|
|
10c72585de | ||
|
|
c3e47b0fae | ||
|
|
60033f36a7 | ||
|
|
582cbd57af | ||
|
|
34b851fab7 | ||
|
|
8ffcb8b048 | ||
|
|
b0067e53a6 | ||
|
|
3073a2767b | ||
|
|
7818a754c6 | ||
|
|
b99d0bfca0 | ||
|
|
3dedebbe79 | ||
|
|
22417853dd | ||
|
|
633f6dff37 | ||
|
|
1192f7b4cd | ||
|
|
871c9882b4 | ||
|
|
04a75154c5 | ||
|
|
f1e1ddf48f | ||
|
|
09cc2ce347 | ||
|
|
0c270df599 | ||
|
|
8be194a410 | ||
|
|
ea5d6e0962 | ||
|
|
7edb8cb3f0 | ||
|
|
6299d8982d | ||
|
|
8af1439087 | ||
|
|
95041a8395 | ||
|
|
5cabf2ab65 | ||
|
|
638b24a6a1 | ||
|
|
2b74942521 | ||
|
|
597ea2c7cd | ||
|
|
6d08ee216a | ||
|
|
d87a4434c7 | ||
|
|
c27d6fc455 | ||
|
|
0701eb6f43 | ||
|
|
ffc9f22694 | ||
|
|
c7898003c0 | ||
|
|
2c45d1e5b8 | ||
|
|
9412f65c3c | ||
|
|
c0ebef41ee | ||
|
|
a2c6ff83f7 | ||
|
|
73b8ee8bc5 | ||
|
|
d8fbdfb8e6 | ||
|
|
ff87644416 | ||
|
|
adcf7200bc | ||
|
|
f71ce6bd94 | ||
|
|
c8b0ca74a3 | ||
|
|
1a413e4d06 | ||
|
|
b7a337f821 | ||
|
|
38b7f6b985 | ||
|
|
4457eb8bc1 | ||
|
|
0248c185e4 | ||
|
|
e81be59bbb | ||
|
|
d0aad73ce5 | ||
|
|
c384bf9e9d | ||
|
|
752e9b3081 | ||
|
|
81fdd612ce | ||
|
|
ad3a6be9b1 | ||
|
|
6a680a1291 | ||
|
|
1f98662ee8 | ||
|
|
73f236bbd3 | ||
|
|
223a772582 | ||
|
|
3a99da8b76 | ||
|
|
d9ce3ae207 | ||
|
|
29d5ec32cb | ||
|
|
45080efd34 | ||
|
|
b5acfcf827 | ||
|
|
bf2a199f79 | ||
|
|
15e0fc2e39 | ||
|
|
bd51428bca | ||
|
|
d15dd7ece5 | ||
|
|
e308a61abc | ||
|
|
b9e055c039 | ||
|
|
2700e7442e | ||
|
|
653483a68e | ||
|
|
d310647fa6 | ||
|
|
d2eee6548f | ||
|
|
28a2767efc | ||
|
|
3dbf893347 | ||
|
|
070face8d3 | ||
|
|
bfa0d40996 | ||
|
|
9fcfcce584 | ||
|
|
f8dec485c5 | ||
|
|
b27bc16ab0 | ||
|
|
99e564476b | ||
|
|
4d5a4ec0da | ||
|
|
2f63058882 | ||
|
|
413c984e85 | ||
|
|
448895866a | ||
|
|
aba91e02b0 | ||
|
|
56d0fd80d0 | ||
|
|
6acd4b1ca0 | ||
|
|
f4175cd7b5 | ||
|
|
678bb7f393 | ||
|
|
085e5cea93 | ||
|
|
3916b18a6f | ||
|
|
74d20c1010 | ||
|
|
25d89b30a1 | ||
|
|
632b1ec636 |
@@ -0,0 +1,441 @@
|
||||
declare -A calMap
|
||||
calMap[JG01]="\{\n\
|
||||
\{ 0, 406, -10530, -8223\}, \{ 0, 697, -9933, -7988\},\n\
|
||||
\{ 0, 296, -10497, -8272\}, \{ 0, 515, -10264, -8093\},\n\
|
||||
\{ 0, 689, -10212, -8064\}, \{ 0, 40, -10960, -8572\},\n\
|
||||
\{ 0, 722, -10878, -8518\}, \{ 0, 59, -10987, -8962\},\n\
|
||||
\{ 0, 56, -11264, -8770\}, \{ 0, -464, -11341, -9159\},\n\
|
||||
\{ 0, 19, -10924, -8887\}, \{ 0, -669, -10927, -8679\},\n\
|
||||
\{ 0, -701, -11154, -8712\}, \{ 0, -255, -10739, -8009\},\n\
|
||||
\{ 0, -192, -10509, -8242\}, \{ 0, -1057, -11183, -9007\},\n\
|
||||
\{ 0, -57, -10606, -8350\}, \{ 0, -719, -10949, -8880\},\n\
|
||||
\{ 0, -760, -11084, -8660\}, \{ 0, -457, -10735, -8833\},\n\
|
||||
\{ 0, -188, -10623, -9119\}, \{ 0, -628, -12609, -10119\},\n\
|
||||
\{ 0, -434, -12714, -10225\}, \{ 0, -727, -13074, -10685\},\n\
|
||||
\{ 0, -12, -12408, -10190\}, \{ 0, 33, -12790, -10624\},\n\
|
||||
\{ 0, 93, -13235, -10819\}, \{ 0, -363, -13301, -11183\},\n\
|
||||
\{ 0, -514, -13955, -11557\}, \{ 0, -458, -13878, -11722\},\n\
|
||||
\{ 0, 93, -13086, -11726\}, \{ 0, -663, -13597, -11868\},\n\
|
||||
\{ 0, 174, -12814, -11295\}, \{ 0, 121, -12278, -11150\},\n\
|
||||
\{ 0, 425, -11255, -10363\}, \{ 0, 430, -11645, -10189\},\n\
|
||||
\{ 0, 277, -11844, -9499\}, \{ 0, -132, -12241, -9420\},\n\
|
||||
\{ 0, 448, -11934, -9612\}, \{ 0, 200, -11778, -9582\},\n\
|
||||
\{ 0, -40, -12069, -9336\}, \{ 0, 1692, -11315, -9085\},\n\
|
||||
\{ 0, -1753, -11445, -9482\}, \{ 0, -2520, -12620, -10068\},\n\
|
||||
\{ 0, -1976, -12674, -10218\}, \{ 0, -1984, -12525, -10354\},\n\
|
||||
\{ 0, -2272, -13476, -10932\}, \{ 0, -2123, -13918, -11095\},\n\
|
||||
\{ 0, -2883, -14447, -11659\}, \{ 0, -2826, -13946, -11563\},\n\
|
||||
\{ 0, -2697, -13680, -11328\}, \{ 0, -3068, -13393, -11614\},\n\
|
||||
\{ 0, -2935, -13074, -11882\}, \{ 0, -3017, -13038, -11163\},\n\
|
||||
\{ 0, -2490, -12379, -11288\}, \{ 0, -2463, -12286, -10726\},\n\
|
||||
\{ 0, -2686, -12167, -10673\}, \{ 0, -2428, -12077, -10555\},\n\
|
||||
\{ 0, -2282, -12564, -10388\}, \{ 0, -2017, -12303, -10844\},\n\
|
||||
\{ 0, -2329, -12637, -11250\}, \{ 0, -2703, -13362, -11807\},\n\
|
||||
\{ 0, -1820, -12605, -11733\}, \{ 0, 596, -10833, -9852\},\n\
|
||||
\{ 0, 9, -11140, -9776\}, \{ 0, 41, -11168, -9478\},\n\
|
||||
\{ 0, -261, -11368, -9752\}, \{ 0, 226, -11282, -9879\},\n\
|
||||
\{ 0, -68, -11454, -10148\}, \{ 0, -314, -12278, -10716\},\n\
|
||||
\{ 0, -66, -11998, -10762\}, \{ 0, -58, -11469, -10664\},\n\
|
||||
\{ 0, 319, -10759, -10212\}, \{ 0, 122, -11041, -9901\},\n\
|
||||
\{ 0, -269, -11085, -10008\}, \{ 0, 637, -10569, -9674\},\n\
|
||||
\{ 0, 1185, -10632, -9521\}, \{ 0, 902, -11053, -9681\},\n\
|
||||
\{ 0, 560, -11408, -9588\}, \{ 0, 1162, -11079, -9371\},\n\
|
||||
\{ 0, 1780, -10547, -9133\}, \n\
|
||||
};"
|
||||
|
||||
calMap[JG02]="\{\n\
|
||||
\{ 0, 509, -2785, -4375\}, \{ 0, 655, -3482, -4447\},\n\
|
||||
\{ 0, 520, -3231, -4651\}, \{ 0, 680, -3122, -4790\},\n\
|
||||
\{ 0, 328, -3648, -4712\}, \{ 0, 260, -3454, -4515\},\n\
|
||||
\{ 0, 433, -3027, -4446\}, \{ 0, 34, -4304, -4676\},\n\
|
||||
\{ 0, 54, -3707, -4650\}, \{ 0, -19, -3829, -5231\},\n\
|
||||
\{ 0, -156, -4018, -5292\}, \{ 0, -331, -4155, -5423\},\n\
|
||||
\{ 0, -424, -4210, -5207\}, \{ 0, -592, -4131, -5572\},\n\
|
||||
\{ 0, -494, -4135, -5732\}, \{ 0, -687, -4055, -5030\},\n\
|
||||
\{ 0, -1000, -4456, -5228\}, \{ 0, -337, -3931, -5340\},\n\
|
||||
\{ 0, -168, -3962, -5326\}, \{ 0, -852, -4534, -5798\},\n\
|
||||
\{ 0, -541, -4458, -5156\}, \{ 0, -842, -5570, -6166\},\n\
|
||||
\{ 0, -1490, -5883, -6645\}, \{ 0, -1036, -5917, -6151\},\n\
|
||||
\{ 0, -1369, -5946, -5969\}, \{ 0, -916, -5927, -6200\},\n\
|
||||
\{ 0, -521, -5595, -6066\}, \{ 0, -823, -5731, -5925\},\n\
|
||||
\{ 0, -262, -5267, -5315\}, \{ 0, -697, -5434, -5676\},\n\
|
||||
\{ 0, -362, -5193, -4887\}, \{ 0, -430, -5147, -4911\},\n\
|
||||
\{ 0, -94, -5403, -5159\}, \{ 0, -747, -5796, -4772\},\n\
|
||||
\{ 0, -679, -4909, -4531\}, \{ 0, -500, -5364, -4694\},\n\
|
||||
\{ 0, -147, -5225, -4463\}, \{ 0, -283, -5815, -4360\},\n\
|
||||
\{ 0, -724, -6148, -4647\}, \{ 0, -295, -6069, -4375\},\n\
|
||||
\{ 0, -397, -6086, -4105\}, \{ 0, -116, -6343, -4698\},\n\
|
||||
\{ 0, -589, -6398, -5353\}, \{ 0, -1068, -6640, -5014\},\n\
|
||||
\{ 0, -785, -7017, -5093\}, \{ 0, -29, -6238, -5186\},\n\
|
||||
\{ 0, 380, -6370, -5063\}, \{ 0, -239, -7191, -5605\},\n\
|
||||
\{ 0, 321, -7256, -5177\}, \{ 0, 430, -6673, -4887\},\n\
|
||||
\{ 0, 226, -7136, -5687\}, \{ 0, 142, -7175, -5498\},\n\
|
||||
\{ 0, 333, -6596, -5434\}, \{ 0, 315, -6574, -5520\},\n\
|
||||
\{ 0, -109, -6681, -5798\}, \{ 0, -587, -7290, -5748\},\n\
|
||||
\{ 0, -229, -7105, -5463\}, \{ 0, -480, -7092, -6033\},\n\
|
||||
\{ 0, -1162, -7488, -6578\}, \{ 0, -1244, -8230, -6838\},\n\
|
||||
\{ 0, -941, -7941, -6976\}, \{ 0, -1181, -7816, -6868\},\n\
|
||||
\{ 0, -1792, -8128, -6590\}, \{ 0, -644, -7614, -4524\},\n\
|
||||
\{ 0, -873, -7358, -3775\}, \{ 0, -1250, -7370, -4506\},\n\
|
||||
\{ 0, -819, -7520, -4500\}, \{ 0, -1579, -8679, -4626\},\n\
|
||||
\{ 0, -1332, -7353, -4338\}, \{ 0, -1128, -7821, -5030\},\n\
|
||||
\{ 0, -927, -7988, -4954\}, \{ 0, -2035, -7884, -5097\},\n\
|
||||
\{ 0, -2533, -8953, -6171\}, \{ 0, -1576, -8029, -5542\},\n\
|
||||
\{ 0, -1185, -7297, -5523\}, \{ 0, -2139, -8830, -6236\},\n\
|
||||
\{ 0, -2137, -8976, -6225\}, \{ 0, -1387, -8252, -6043\},\n\
|
||||
\{ 0, -1139, -8286, -5988\}, \{ 0, -1252, -8224, -6388\},\n\
|
||||
\{ 0, -1617, -8211, -5983\}, \n\
|
||||
};"
|
||||
|
||||
calMap[JG03]="\{\n\
|
||||
\{ 0, -5670, -14728, -16999\}, \{ 0, -5942, -14703, -17077\},\n\
|
||||
\{ 0, -5889, -14421, -16670\}, \{ 0, -6039, -14464, -16644\},\n\
|
||||
\{ 0, -5991, -14403, -16390\}, \{ 0, -6103, -14418, -16510\},\n\
|
||||
\{ 0, -5953, -14364, -16180\}, \{ 0, -6154, -14364, -16125\},\n\
|
||||
\{ 0, -5945, -14263, -15929\}, \{ 0, -6075, -14327, -15930\},\n\
|
||||
\{ 0, -5928, -14392, -15878\}, \{ 0, -5986, -14443, -15932\},\n\
|
||||
\{ 0, -5783, -14256, -15873\}, \{ 0, -5945, -14360, -15887\},\n\
|
||||
\{ 0, -5749, -14536, -15874\}, \{ 0, -5733, -14684, -15887\},\n\
|
||||
\{ 0, -5630, -14594, -15987\}, \{ 0, -5752, -14743, -16002\},\n\
|
||||
\{ 0, -5490, -14694, -15993\}, \{ 0, -5481, -14866, -16056\},\n\
|
||||
\{ 0, -5293, -14807, -16060\}, \{ 0, -7935, -20143, -18383\},\n\
|
||||
\{ 0, -7733, -20142, -18482\}, \{ 0, -7628, -20060, -18538\},\n\
|
||||
\{ 0, -7437, -20112, -18495\}, \{ 0, -7314, -20012, -18544\},\n\
|
||||
\{ 0, -7072, -19980, -18573\}, \{ 0, -6986, -20006, -18632\},\n\
|
||||
\{ 0, -6718, -20048, -18569\}, \{ 0, -6601, -19987, -18517\},\n\
|
||||
\{ 0, -6485, -20035, -18537\}, \{ 0, -6292, -20047, -18537\},\n\
|
||||
\{ 0, -6105, -20153, -18482\}, \{ 0, -6081, -20314, -18501\},\n\
|
||||
\{ 0, -5865, -19916, -18164\}, \{ 0, -5786, -20218, -18174\},\n\
|
||||
\{ 0, -5728, -20282, -18110\}, \{ 0, -5690, -20451, -18135\},\n\
|
||||
\{ 0, -5643, -20768, -18154\}, \{ 0, -5603, -20874, -18273\},\n\
|
||||
\{ 0, -5621, -21190, -18095\}, \{ 0, -5522, -21547, -18146\},\n\
|
||||
\{ 0, -5549, -20721, -16825\}, \{ 0, -5547, -21087, -17001\},\n\
|
||||
\{ 0, -5491, -21394, -17040\}, \{ 0, -5484, -21696, -17064\},\n\
|
||||
\{ 0, -5542, -22265, -17091\}, \{ 0, -5483, -22543, -17198\},\n\
|
||||
\{ 0, -5460, -22748, -17254\}, \{ 0, -5417, -22961, -17307\},\n\
|
||||
\{ 0, -5455, -23299, -17323\}, \{ 0, -5445, -23552, -17382\},\n\
|
||||
\{ 0, -5426, -23645, -17428\}, \{ 0, -5480, -23902, -17349\},\n\
|
||||
\{ 0, -5558, -24011, -17360\}, \{ 0, -5569, -24032, -17326\},\n\
|
||||
\{ 0, -5614, -24067, -17305\}, \{ 0, -5656, -24000, -17251\},\n\
|
||||
\{ 0, -5739, -23971, -17228\}, \{ 0, -5777, -23886, -17215\},\n\
|
||||
\{ 0, -5832, -23823, -17051\}, \{ 0, -5891, -23719, -16957\},\n\
|
||||
\{ 0, -6007, -23598, -16925\}, \{ 0, -5893, -20829, -15256\},\n\
|
||||
\{ 0, -5886, -20669, -15091\}, \{ 0, -5883, -20496, -14990\},\n\
|
||||
\{ 0, -5969, -20469, -14898\}, \{ 0, -5971, -20245, -14876\},\n\
|
||||
\{ 0, -5996, -20108, -14764\}, \{ 0, -5979, -19934, -14694\},\n\
|
||||
\{ 0, -5997, -19721, -14571\}, \{ 0, -6046, -19573, -14456\},\n\
|
||||
\{ 0, -6001, -19418, -14381\}, \{ 0, -5942, -19239, -14265\},\n\
|
||||
\{ 0, -5978, -19040, -14240\}, \{ 0, -5928, -18873, -14317\},\n\
|
||||
\{ 0, -5917, -18715, -14238\}, \{ 0, -5865, -18576, -14201\},\n\
|
||||
\{ 0, -5750, -18386, -14200\}, \{ 0, -5772, -18299, -14235\},\n\
|
||||
\{ 0, -5754, -18187, -14300\}, \n\
|
||||
};"
|
||||
|
||||
calMap[JG05]="\{\n\
|
||||
\{ 0, 178, -7222, 8474\}, \{ 0, 218, -7139, 8383\},\n\
|
||||
\{ 0, 215, -7438, 8352\}, \{ 0, 198, -7247, 8498\},\n\
|
||||
\{ 0, 138, -7640, 8644\}, \{ 0, 158, -7805, 8610\},\n\
|
||||
\{ 0, 135, -7804, 8531\}, \{ 0, 143, -7881, 8575\},\n\
|
||||
\{ 0, 165, -8096, 8584\}, \{ 0, 118, -7962, 8558\},\n\
|
||||
\{ 0, 148, -7947, 8550\}, \{ 0, 118, -8193, 8494\},\n\
|
||||
\{ 0, 149, -8042, 8441\}, \{ 0, 59, -8207, 8454\},\n\
|
||||
\{ 0, 101, -8029, 8575\}, \{ 0, 156, -8029, 8422\},\n\
|
||||
\{ 0, 205, -8074, 8451\}, \{ 0, 167, -7912, 8405\},\n\
|
||||
\{ 0, 263, -7980, 8405\}, \{ 0, 258, -8007, 8404\},\n\
|
||||
\{ 0, 288, -7790, 8342\}, \{ 0, -802, -10286, 6559\},\n\
|
||||
\{ 0, -717, -10120, 6574\}, \{ 0, -590, -9884, 6675\},\n\
|
||||
\{ 0, -446, -9651, 6686\}, \{ 0, -371, -9600, 6700\},\n\
|
||||
\{ 0, -259, -9243, 6756\}, \{ 0, -77, -9216, 6768\},\n\
|
||||
\{ 0, 108, -8979, 6844\}, \{ 0, 220, -8769, 6970\},\n\
|
||||
\{ 0, 348, -8820, 6991\}, \{ 0, 569, -8618, 7028\},\n\
|
||||
\{ 0, 688, -8430, 7162\}, \{ 0, 798, -8520, 7293\},\n\
|
||||
\{ 0, 1050, -8141, 7758\}, \{ 0, 1284, -7775, 7850\},\n\
|
||||
\{ 0, 1447, -7625, 7967\}, \{ 0, 1527, -7708, 8032\},\n\
|
||||
\{ 0, 1661, -7547, 8153\}, \{ 0, 1784, -7532, 8169\},\n\
|
||||
\{ 0, 1863, -7560, 8430\}, \{ 0, 1977, -7617, 8609\},\n\
|
||||
\{ 0, 1318, -6902, 8849\}, \{ 0, 1390, -7060, 8848\},\n\
|
||||
\{ 0, 1470, -6967, 8872\}, \{ 0, 1532, -6958, 8915\},\n\
|
||||
\{ 0, 1607, -7162, 8946\}, \{ 0, 1718, -7119, 9030\},\n\
|
||||
\{ 0, 1781, -6970, 9113\}, \{ 0, 1807, -6943, 9071\},\n\
|
||||
\{ 0, 1831, -7114, 9061\}, \{ 0, 1899, -7105, 9088\},\n\
|
||||
\{ 0, 1935, -7026, 9070\}, \{ 0, 2040, -6685, 9125\},\n\
|
||||
\{ 0, -8187, -6757, 9115\}, \{ 0, -10749, -6464, 9194\},\n\
|
||||
\{ 0, -21024, -6513, 9071\}, \{ 0, 6072, -6529, 9040\},\n\
|
||||
\{ 0, -22290, -6590, 9075\}, \{ 0, -12054, -6510, 9114\},\n\
|
||||
\{ 0, -18487, -6491, 9179\}, \{ 0, -12050, -6878, 9144\},\n\
|
||||
\{ 0, -4425, -6526, 9189\}, \{ 0, 2575, -4991, 10202\},\n\
|
||||
\{ 0, 2566, -4792, 10308\}, \{ 0, 2596, -4920, 10513\},\n\
|
||||
\{ 0, 2585, -5106, 10573\}, \{ 0, 2538, -5290, 10578\},\n\
|
||||
\{ 0, 2560, -5424, 10627\}, \{ 0, 2613, -5352, 10915\},\n\
|
||||
\{ 0, 2531, -5578, 10919\}, \{ 0, 2545, -5652, 11012\},\n\
|
||||
\{ 0, 2646, -5819, 11079\}, \{ 0, 2661, -6046, 11136\},\n\
|
||||
\{ 0, 2692, -6314, 11187\}, \{ 0, 2759, -6284, 11209\},\n\
|
||||
\{ 0, 2739, -6557, 11185\}, \{ 0, 2815, -6469, 11256\},\n\
|
||||
\{ 0, 2849, -6807, 11103\}, \{ 0, 2850, -6769, 11097\},\n\
|
||||
\{ 0, 2923, -6999, 11232\}, \n\
|
||||
};"
|
||||
|
||||
calMap[JG06]="\{\n\
|
||||
\{ 0, -3836, -1067, 4891\}, \{ 0, -4831, -2098, 4103\},\n\
|
||||
\{ 0, -4849, -1871, 4566\}, \{ 0, -4534, -1666, 4512\},\n\
|
||||
\{ 0, -5764, -2767, 4245\}, \{ 0, -5591, -2123, 4174\},\n\
|
||||
\{ 0, -4727, -1565, 4368\}, \{ 0, -5834, -2262, 3942\},\n\
|
||||
\{ 0, -5421, -2062, 3790\}, \{ 0, -4996, -1380, 4260\},\n\
|
||||
\{ 0, -5538, -1861, 3494\}, \{ 0, -5272, -1652, 3740\},\n\
|
||||
\{ 0, -5561, -1802, 4038\}, \{ 0, -5320, -1734, 3742\},\n\
|
||||
\{ 0, -4354, -1230, 4170\}, \{ 0, -5705, -1862, 3840\},\n\
|
||||
\{ 0, -6223, -2211, 3218\}, \{ 0, -5048, -1596, 3669\},\n\
|
||||
\{ 0, -5235, -1541, 3735\}, \{ 0, -6009, -2219, 3301\},\n\
|
||||
\{ 0, -5545, -1879, 3686\}, \{ 0, -7174, -2853, -434\},\n\
|
||||
\{ 0, -6759, -3117, 56\}, \{ 0, -7376, -3291, 221\},\n\
|
||||
\{ 0, -7601, -3243, 150\}, \{ 0, -7065, -2752, -42\},\n\
|
||||
\{ 0, -7701, -2828, -144\}, \{ 0, -7598, -3002, 464\},\n\
|
||||
\{ 0, -7312, -2476, 399\}, \{ 0, -7939, -2374, -62\},\n\
|
||||
\{ 0, -7622, -2213, 482\}, \{ 0, -6715, -1688, 1033\},\n\
|
||||
\{ 0, -6755, -1445, 722\}, \{ 0, -6817, -1385, 1061\},\n\
|
||||
\{ 0, -6155, -864, 1431\}, \{ 0, -6700, -1746, 1070\},\n\
|
||||
\{ 0, -6973, -1127, 835\}, \{ 0, -6456, -1152, 686\},\n\
|
||||
\{ 0, -6542, -1505, 1059\}, \{ 0, -6659, -1374, 584\},\n\
|
||||
\{ 0, -6605, -983, 630\}, \{ 0, -6366, -1046, 800\},\n\
|
||||
\{ 0, -4668, 343, 1086\}, \{ 0, -5072, 560, 468\},\n\
|
||||
\{ 0, -4124, 1399, 1284\}, \{ 0, -3465, 10068, 22599\},\n\
|
||||
\{ 0, -4167, 2018, 1119\}, \{ 0, -4910, 1612, 717\},\n\
|
||||
\{ 0, -4917, 1600, 968\}, \{ 0, -4171, 1731, 430\},\n\
|
||||
\{ 0, -3432, 13873, 166\}, \{ 0, -3571, 2840, 870\},\n\
|
||||
\{ 0, -3060, 2468, 463\}, \{ 0, -2858, 2369, 373\},\n\
|
||||
\{ 0, -2948, 3186, 438\}, \{ 0, -3305, 2984, -160\},\n\
|
||||
\{ 0, -2027, 3128, -798\}, \{ 0, -2663, 3320, -865\},\n\
|
||||
\{ 0, -3992, -562, -1509\}, \{ 0, -2913, 2844, -1081\},\n\
|
||||
\{ 0, -3205, 3373, -1418\}, \{ 0, -3366, 3063, -1645\},\n\
|
||||
\{ 0, -3878, 2873, -920\}, \{ 0, -1801, 6168, 2384\},\n\
|
||||
\{ 0, -1252, 6409, 2308\}, \{ 0, -1724, 6027, 2474\},\n\
|
||||
\{ 0, -1937, 5849, 2730\}, \{ 0, -1921, 5622, 2349\},\n\
|
||||
\{ 0, -2162, 5995, -1804\}, \{ 0, -1707, 6306, 2744\},\n\
|
||||
\{ 0, -1334, 5651, 3112\}, \{ 0, -2132, 5216, 2588\},\n\
|
||||
\{ 0, -1878, 5912, 2448\}, \{ 0, -1233, 5205, 2467\},\n\
|
||||
\{ 0, -1139, 5350, 2967\}, \{ 0, -2373, 5368, -23580\},\n\
|
||||
\{ 0, -1706, 5450, 2374\}, \{ 0, -1718, 5876, 2333\},\n\
|
||||
\{ 0, -1569, 5961, 2570\}, \{ 0, -1177, 6423, 2665\},\n\
|
||||
\{ 0, -1210, 5976, 2608\}, \n\
|
||||
};"
|
||||
|
||||
calMap[LJ01]="\{\n\
|
||||
\{ 0, 5716, -1041, -12697\}, \{ 0, 5110, -1450, -13222\},\n\
|
||||
\{ 0, 4487, -1630, -13282\}, \{ 0, 4606, -1821, -13197\},\n\
|
||||
\{ 0, 4663, -2299, -13302\}, \{ 0, 4092, -2324, -13451\},\n\
|
||||
\{ 0, 4233, -2419, -13189\}, \{ 0, 3702, -2961, -14147\},\n\
|
||||
\{ 0, 3167, -3408, -14660\}, \{ 0, 3564, -3255, -13877\},\n\
|
||||
\{ 0, 3320, -3407, -13671\}, \{ 0, 3137, -3350, -13820\},\n\
|
||||
\{ 0, 3342, -3703, -13808\}, \{ 0, 3519, -3970, -14069\},\n\
|
||||
\{ 0, 2983, -4415, -14335\}, \{ 0, 3636, -3825, -13840\},\n\
|
||||
\{ 0, 3461, -3922, -14323\}, \{ 0, 3419, -4022, -14031\},\n\
|
||||
\{ 0, 3763, -4066, -13832\}, \{ 0, 3929, -3504, -13827\},\n\
|
||||
\{ 0, 3634, -4035, -14096\}, \{ 0, 3195, -6232, -14808\},\n\
|
||||
\{ 0, 3428, -6179, -14913\}, \{ 0, 3506, -5525, -14510\},\n\
|
||||
\{ 0, 3754, -5724, -14134\}, \{ 0, 3630, -5791, -14743\},\n\
|
||||
\{ 0, 3857, -5548, -14269\}, \{ 0, 4654, -4964, -13701\},\n\
|
||||
\{ 0, 4853, -4388, -13822\}, \{ 0, 4735, -4632, -13864\},\n\
|
||||
\{ 0, 4981, -4381, -13979\}, \{ 0, 5528, -3984, -13626\},\n\
|
||||
\{ 0, 5130, -4326, -13639\}, \{ 0, 5095, -3792, -13638\},\n\
|
||||
\{ 0, 5346, -3366, -13030\}, \{ 0, 5498, -3496, -13682\},\n\
|
||||
\{ 0, 5144, -3120, -13986\}, \{ 0, 5427, -2871, -12931\},\n\
|
||||
\{ 0, 5939, -2824, -12646\}, \{ 0, 6030, -2983, -12662\},\n\
|
||||
\{ 0, 5959, -3142, -12116\}, \{ 0, 5903, -2700, -11731\},\n\
|
||||
\{ 0, 6256, -3546, -10932\}, \{ 0, 6384, -3767, -11326\},\n\
|
||||
\{ 0, 6086, -3399, -11769\}, \{ 0, 5915, -3257, -12066\},\n\
|
||||
\{ 0, 6257, -4021, -12273\}, \{ 0, 6084, -4192, -12153\},\n\
|
||||
\{ 0, 5482, -4102, -12637\}, \{ 0, 5836, -3698, -12767\},\n\
|
||||
\{ 0, 6025, -4014, -13219\}, \{ 0, 5713, -3812, -14315\},\n\
|
||||
\{ 0, 5997, -3855, -14788\}, \{ 0, 5866, -3905, -15408\},\n\
|
||||
\{ 0, 5328, -4627, -16458\}, \{ 0, 5686, -3646, -14885\},\n\
|
||||
\{ 0, 5551, -3407, -15112\}, \{ 0, 5720, -3165, -14247\},\n\
|
||||
\{ 0, 6044, -3818, -14224\}, \{ 0, 5963, -3342, -14531\},\n\
|
||||
\{ 0, 6128, -3225, -13495\}, \{ 0, 6564, -3662, -13408\},\n\
|
||||
\{ 0, 6000, -3479, -13609\}, \{ 0, 5876, -3190, -11817\},\n\
|
||||
\{ 0, 7165, -2876, -10874\}, \{ 0, 6593, -4000, -11565\},\n\
|
||||
\{ 0, 6207, -3694, -11278\}, \{ 0, 6732, -2326, -11167\},\n\
|
||||
\{ 0, 6335, -3650, -11508\}, \{ 0, 6220, -4220, -12438\},\n\
|
||||
\{ 0, 6069, -3838, -12545\}, \{ 0, 6182, -4635, -12472\},\n\
|
||||
\{ 0, 5696, -4834, -12334\}, \{ 0, 6047, -4121, -11691\},\n\
|
||||
\{ 0, 6324, -4125, -10980\}, \{ 0, 6102, -3923, -10939\},\n\
|
||||
\{ 0, 6091, -3829, -10736\}, \{ 0, 5858, -4001, -10473\},\n\
|
||||
\{ 0, 5473, -4773, -11209\}, \{ 0, 6045, -4642, -10361\},\n\
|
||||
\{ 0, 5494, -4391, -10203\}, \n\
|
||||
};"
|
||||
|
||||
calMap[LJ02]="\{\n\
|
||||
\{ 0, -726, 598, -2561\}, \{ 0, -743, 864, -2549\},\n\
|
||||
\{ 0, -769, 992, -2477\}, \{ 0, -905, 665, -2742\},\n\
|
||||
\{ 0, -944, 665, -2710\}, \{ 0, -1180, 727, -2794\},\n\
|
||||
\{ 0, -1012, 642, -2599\}, \{ 0, -1195, 690, -2770\},\n\
|
||||
\{ 0, -1191, 667, -2846\}, \{ 0, -1173, 684, -2759\},\n\
|
||||
\{ 0, -1158, 708, -2795\}, \{ 0, -1072, 678, -2852\},\n\
|
||||
\{ 0, -1175, 872, -2747\}, \{ 0, -1011, 862, -2673\},\n\
|
||||
\{ 0, -1086, 755, -2927\}, \{ 0, -1042, 1076, -2731\},\n\
|
||||
\{ 0, -1042, 914, -2765\}, \{ 0, -758, 1182, -2443\},\n\
|
||||
\{ 0, -757, 1219, -2500\}, \{ 0, -534, 1472, -2295\},\n\
|
||||
\{ 0, -497, 1543, -2104\}, \{ 0, -1267, -632, -3273\},\n\
|
||||
\{ 0, -1133, -761, -3048\}, \{ 0, -1065, -375, -2952\},\n\
|
||||
\{ 0, -722, -133, -2551\}, \{ 0, -586, 52, -2505\},\n\
|
||||
\{ 0, -546, 67, -2219\}, \{ 0, -477, 177, -2017\},\n\
|
||||
\{ 0, -317, 317, -1888\}, \{ 0, -161, 364, -1712\},\n\
|
||||
\{ 0, 5, 359, -1770\}, \{ 0, -283, 214, -1901\},\n\
|
||||
\{ 0, -59, 353, -1551\}, \{ 0, 108, 454, -1465\},\n\
|
||||
\{ 0, -74, 796, -1225\}, \{ 0, 41, 685, -1221\},\n\
|
||||
\{ 0, 84, 576, -1318\}, \{ 0, 14, 504, -1313\},\n\
|
||||
\{ 0, 37, 448, -1301\}, \{ 0, 18, 344, -1408\},\n\
|
||||
\{ 0, -70, 240, -1384\}, \{ 0, -27, 186, -1595\},\n\
|
||||
\{ 0, 622, 981, -855\}, \{ 0, 351, 889, -1188\},\n\
|
||||
\{ 0, 475, 758, -1328\}, \{ 0, 305, 1025, -1222\},\n\
|
||||
\{ 0, 526, 609, -1397\}, \{ 0, 398, 426, -1695\},\n\
|
||||
\{ 0, 237, 543, -1835\}, \{ 0, 357, 739, -1747\},\n\
|
||||
\{ 0, 400, 699, -1834\}, \{ 0, 319, 943, -1998\},\n\
|
||||
\{ 0, 244, 783, -2197\}, \{ 0, 249, 976, -2195\},\n\
|
||||
\{ 0, 266, 859, -2406\}, \{ 0, 332, 959, -2477\},\n\
|
||||
\{ 0, 225, 968, -2554\}, \{ 0, 97, 808, -2815\},\n\
|
||||
\{ 0, 73, 895, -2852\}, \{ 0, -155, 877, -2986\},\n\
|
||||
\{ 0, -71, 914, -2943\}, \{ 0, -232, 862, -2966\},\n\
|
||||
\{ 0, -347, 772, -3176\}, \{ 0, 675, 250, -956\},\n\
|
||||
\{ 0, 589, 204, -935\}, \{ 0, 459, 110, -867\},\n\
|
||||
\{ 0, 149, -88, -1251\}, \{ 0, 272, -145, -930\},\n\
|
||||
\{ 0, 304, -62, -857\}, \{ 0, 24, -487, -1384\},\n\
|
||||
\{ 0, 51, -31, -984\}, \{ 0, 154, -77, -992\},\n\
|
||||
\{ 0, -23, -238, -1234\}, \{ 0, 28, -331, -1323\},\n\
|
||||
\{ 0, 104, -415, -1424\}, \{ 0, -177, -633, -1704\},\n\
|
||||
\{ 0, 21, -514, -1572\}, \{ 0, 210, -796, -1584\},\n\
|
||||
\{ 0, 133, -693, -1782\}, \{ 0, 161, -882, -1824\},\n\
|
||||
\{ 0, 118, -1098, -1994\}, \n\
|
||||
};"
|
||||
|
||||
calMap[LJ03]="\{\n\
|
||||
\{ 0, 13063, -4747, -10433\}, \{ 0, 3443, -4140, -9849\},\n\
|
||||
\{ 0, 7069, -4629, -10540\}, \{ 0, 13946, -4544, -10775\},\n\
|
||||
\{ 0, 12968, -4307, -10347\}, \{ 0, 20281, -5019, -11282\},\n\
|
||||
\{ 0, 22661, -5079, -11148\}, \{ 0, 16734, -4442, -10374\},\n\
|
||||
\{ 0, 15423, -4074, -10422\}, \{ 0, 22851, -4441, -10405\},\n\
|
||||
\{ 0, 14291, -3978, -9960\}, \{ 0, 4367, -3954, -9810\},\n\
|
||||
\{ 0, 11785, -3957, -10150\}, \{ 0, 3218, -3775, -9825\},\n\
|
||||
\{ 0, 3344, -3314, -9254\}, \{ 0, 6873, -3528, -9614\},\n\
|
||||
\{ 0, 3630, -3230, -9069\}, \{ 0, 3442, -3275, -9653\},\n\
|
||||
\{ 0, 3346, -3858, -9895\}, \{ 0, 3721, -3391, -9296\},\n\
|
||||
\{ 0, 3261, -3428, -9383\}, \{ 0, -24770, -8031, -10490\},\n\
|
||||
\{ 0, -24608, -7690, -10198\}, \{ 0, -24868, -7897, -9937\},\n\
|
||||
\{ 0, -24880, -7994, -10295\}, \{ 0, -24908, -7089, -10312\},\n\
|
||||
\{ 0, -24547, -7588, -10044\}, \{ 0, -24905, -8076, -9985\},\n\
|
||||
\{ 0, -24646, -7229, -9709\}, \{ 0, -24916, -7800, -10193\},\n\
|
||||
\{ 0, -25334, -8019, -10733\}, \{ 0, -24839, -7637, -10037\},\n\
|
||||
\{ 0, -25020, -7138, -9907\}, \{ 0, -24502, -7503, -10369\},\n\
|
||||
\{ 0, -24471, -7222, -10546\}, \{ 0, -24537, -7066, -10359\},\n\
|
||||
\{ 0, -24407, -6616, -9797\}, \{ 0, -23898, -7370, -10755\},\n\
|
||||
\{ 0, -24587, -7630, -10656\}, \{ 0, -24411, -7258, -11072\},\n\
|
||||
\{ 0, -24028, -7203, -10471\}, \{ 0, -24139, -7585, -10014\},\n\
|
||||
\{ 0, -23817, -6456, -10002\}, \{ 0, -24122, -6453, -10354\},\n\
|
||||
\{ 0, 25236, -6345, -9380\}, \{ 0, 25260, -6144, -9727\},\n\
|
||||
\{ 0, -25031, -6591, -10264\}, \{ 0, 11624, -6478, -10071\},\n\
|
||||
\{ 0, 11896, -5407, -9780\}, \{ 0, 14144, -5554, -10328\},\n\
|
||||
\{ 0, 5556, -5558, -10775\}, \{ 0, 3406, -5945, -10115\},\n\
|
||||
\{ 0, 3384, -5384, -10050\}, \{ 0, 3263, -4468, -9634\},\n\
|
||||
\{ 0, 5991, -4734, -9494\}, \{ 0, 3953, -5377, -10430\},\n\
|
||||
\{ 0, 4514, -3687, -9547\}, \{ 0, 4487, -3691, -9332\},\n\
|
||||
\{ 0, 5085, -4417, -9657\}, \{ 0, 5222, -3694, -9115\},\n\
|
||||
\{ 0, 4960, -4086, -8862\}, \{ 0, 4994, -4292, -9127\},\n\
|
||||
\{ 0, 5162, -4509, -8554\}, \{ 0, 4337, -5390, -8443\},\n\
|
||||
\{ 0, 4628, -4976, -9047\}, \{ 0, 4293, -4876, -9218\},\n\
|
||||
\{ 0, 4465, -5352, -9014\}, \{ 0, 4428, -4936, -9521\},\n\
|
||||
\{ 0, 4048, -5497, -9795\}, \{ 0, 4290, -6034, -9032\},\n\
|
||||
\{ 0, 4184, -4996, -8434\}, \{ 0, 3950, -4983, -8474\},\n\
|
||||
\{ 0, 4247, -4407, -7955\}, \{ 0, 4386, -4769, -8079\},\n\
|
||||
\{ 0, 4311, -5367, -8478\}, \{ 0, 4283, -4809, -8025\},\n\
|
||||
\{ 0, 3885, -4011, -7495\}, \{ 0, 3885, -4593, -7577\},\n\
|
||||
\{ 0, 3622, -5239, -8157\}, \{ 0, 3576, -5007, -7816\},\n\
|
||||
\{ 0, 3778, -3793, -7362\}, \n\
|
||||
};"
|
||||
|
||||
calMap[LJ04]="\{\n\
|
||||
\{ 0, -3188, -5668, -7029\}, \{ 0, -3144, -5592, -6708\},\n\
|
||||
\{ 0, -3332, -5859, -7135\}, \{ 0, -3402, -5694, -6908\},\n\
|
||||
\{ 0, -3376, -5858, -7070\}, \{ 0, -3383, -5474, -6886\},\n\
|
||||
\{ 0, -3518, -5487, -6925\}, \{ 0, -3383, -5342, -6659\},\n\
|
||||
\{ 0, -3487, -5535, -6848\}, \{ 0, -3472, -5206, -6576\},\n\
|
||||
\{ 0, -3432, -5335, -6581\}, \{ 0, -3502, -5071, -6421\},\n\
|
||||
\{ 0, -3549, -5020, -6390\}, \{ 0, -3618, -4961, -6310\},\n\
|
||||
\{ 0, -3774, -4938, -6377\}, \{ 0, -3868, -5039, -6488\},\n\
|
||||
\{ 0, -3865, -4778, -6328\}, \{ 0, -3812, -4602, -6360\},\n\
|
||||
\{ 0, -3990, -4498, -6189\}, \{ 0, -3820, -4493, -6070\},\n\
|
||||
\{ 0, -3793, -4262, -5963\}, \{ 0, -4355, -5745, -6648\},\n\
|
||||
\{ 0, -4372, -5742, -6633\}, \{ 0, -4458, -5618, -6650\},\n\
|
||||
\{ 0, -4484, -5695, -6732\}, \{ 0, -4367, -5513, -6642\},\n\
|
||||
\{ 0, -4433, -5498, -6628\}, \{ 0, -4364, -5480, -6563\},\n\
|
||||
\{ 0, -4344, -5382, -6497\}, \{ 0, -4255, -5470, -6465\},\n\
|
||||
\{ 0, -4154, -5145, -6183\}, \{ 0, -4211, -5200, -6136\},\n\
|
||||
\{ 0, -4086, -5205, -6195\}, \{ 0, -4113, -5261, -6338\},\n\
|
||||
\{ 0, -4069, -4832, -5831\}, \{ 0, -3835, -4826, -5801\},\n\
|
||||
\{ 0, -4030, -5011, -6065\}, \{ 0, -3711, -4838, -5795\},\n\
|
||||
\{ 0, -3644, -4881, -5899\}, \{ 0, -3507, -4813, -5800\},\n\
|
||||
\{ 0, -3453, -4947, -5520\}, \{ 0, -3374, -4954, -5642\},\n\
|
||||
\{ 0, -4837, -5736, -7500\}, \{ 0, -4470, -5620, -7385\},\n\
|
||||
\{ 0, -4401, -5408, -7370\}, \{ 0, -4271, -5626, -7496\},\n\
|
||||
\{ 0, -4286, -5828, -7556\}, \{ 0, -4184, -5982, -7565\},\n\
|
||||
\{ 0, -3923, -5491, -7415\}, \{ 0, -3926, -5554, -7685\},\n\
|
||||
\{ 0, -3657, -5235, -7542\}, \{ 0, -3530, -5104, -7717\},\n\
|
||||
\{ 0, -3370, -4853, -7737\}, \{ 0, -3224, -4703, -7679\},\n\
|
||||
\{ 0, -3100, -4620, -7733\}, \{ 0, -3010, -4547, -7648\},\n\
|
||||
\{ 0, -2838, -4318, -7619\}, \{ 0, -2907, -4260, -7604\},\n\
|
||||
\{ 0, -2883, -4306, -7768\}, \{ 0, -2878, -3949, -7601\},\n\
|
||||
\{ 0, -2927, -4097, -7840\}, \{ 0, -2816, -3790, -7544\},\n\
|
||||
\{ 0, -2853, -3654, -7534\}, \{ 0, -2052, -2142, -3986\},\n\
|
||||
\{ 0, -2109, -2259, -4027\}, \{ 0, -2132, -2002, -3745\},\n\
|
||||
\{ 0, -2275, -2181, -3810\}, \{ 0, -2353, -1951, -3419\},\n\
|
||||
\{ 0, -2428, -2046, -3391\}, \{ 0, -2537, -1974, -3301\},\n\
|
||||
\{ 0, -2568, -1805, -3074\}, \{ 0, -2764, -1930, -3068\},\n\
|
||||
\{ 0, -2793, -1922, -2816\}, \{ 0, -2931, -2060, -2982\},\n\
|
||||
\{ 0, -3118, -2158, -2858\}, \{ 0, -3370, -2240, -3088\},\n\
|
||||
\{ 0, -3411, -2369, -3055\}, \{ 0, -3867, -2590, -3016\},\n\
|
||||
\{ 0, -3965, -2696, -3099\}, \{ 0, -4112, -2907, -3438\},\n\
|
||||
\{ 0, -4226, -2747, -3341\}, \n\
|
||||
};"
|
||||
|
||||
calMap[LJ06]="\{\n\
|
||||
\{ 0, -4989, -7102, -2178\}, \{ 0, -5092, -7204, -2325\},\n\
|
||||
\{ 0, -4959, -7013, -2137\}, \{ 0, -4960, -6784, -1920\},\n\
|
||||
\{ 0, -5025, -6734, -2104\}, \{ 0, -5181, -6637, -2017\},\n\
|
||||
\{ 0, -5262, -6792, -2110\}, \{ 0, -5362, -6621, -2110\},\n\
|
||||
\{ 0, -5258, -6451, -2031\}, \{ 0, -5375, -6390, -2064\},\n\
|
||||
\{ 0, -5280, -6288, -2052\}, \{ 0, -5445, -6434, -2101\},\n\
|
||||
\{ 0, -5553, -6402, -2272\}, \{ 0, -5603, -6628, -2477\},\n\
|
||||
\{ 0, -5661, -6626, -2492\}, \{ 0, -5731, -6618, -2616\},\n\
|
||||
\{ 0, -5746, -6626, -2664\}, \{ 0, -6007, -7024, -2951\},\n\
|
||||
\{ 0, -6018, -7010, -2969\}, \{ 0, -5746, -6939, -2833\},\n\
|
||||
\{ 0, -5770, -7034, -3026\}, \{ 0, -8509, -8777, -6863\},\n\
|
||||
\{ 0, -8593, -9060, -6868\}, \{ 0, -8514, -9104, -6795\},\n\
|
||||
\{ 0, -8401, -9387, -6931\}, \{ 0, -8236, -9191, -6586\},\n\
|
||||
\{ 0, -8155, -9371, -6595\}, \{ 0, -8192, -9551, -6363\},\n\
|
||||
\{ 0, -7995, -9550, -6185\}, \{ 0, -7968, -9690, -6220\},\n\
|
||||
\{ 0, -7826, -9694, -6052\}, \{ 0, -7694, -9660, -5763\},\n\
|
||||
\{ 0, -7857, -10020, -5947\}, \{ 0, -7543, -9682, -5463\},\n\
|
||||
\{ 0, -7184, -9071, -4747\}, \{ 0, -7282, -9220, -4767\},\n\
|
||||
\{ 0, -7417, -9371, -4765\}, \{ 0, -7238, -9321, -4430\},\n\
|
||||
\{ 0, -7320, -9420, -4560\}, \{ 0, -7254, -9185, -4270\},\n\
|
||||
\{ 0, -7378, -9262, -4324\}, \{ 0, -7078, -9074, -3976\},\n\
|
||||
\{ 0, -10047, -10956, -7258\}, \{ 0, -10107, -10961, -7192\},\n\
|
||||
\{ 0, -10264, -11167, -7427\}, \{ 0, -10160, -10823, -7282\},\n\
|
||||
\{ 0, -10276, -11378, -7508\}, \{ 0, -10576, -11282, -7688\},\n\
|
||||
\{ 0, -10801, -11460, -7845\}, \{ 0, -10822, -10983, -7809\},\n\
|
||||
\{ 0, -10947, -10998, -8018\}, \{ 0, -11215, -10876, -8255\},\n\
|
||||
\{ 0, -11247, -10590, -8188\}, \{ 0, -11302, -10269, -8237\},\n\
|
||||
\{ 0, -11583, -10213, -8413\}, \{ 0, -11561, -10001, -8448\},\n\
|
||||
\{ 0, -11482, -9425, -8273\}, \{ 0, -11573, -9203, -8344\},\n\
|
||||
\{ 0, -11661, -8895, -8267\}, \{ 0, -11843, -8879, -8259\},\n\
|
||||
\{ 0, -11799, -8715, -8112\}, \{ 0, -12002, -8422, -8238\},\n\
|
||||
\{ 0, -12022, -8434, -8409\}, \{ 0, -8755, -4274, -4932\},\n\
|
||||
\{ 0, -9183, -4523, -5458\}, \{ 0, -9293, -4300, -5260\},\n\
|
||||
\{ 0, -9530, -4543, -5569\}, \{ 0, -9573, -4168, -5429\},\n\
|
||||
\{ 0, -9847, -4448, -5638\}, \{ 0, -9999, -4504, -5969\},\n\
|
||||
\{ 0, -9858, -4176, -5716\}, \{ 0, -9988, -4378, -5978\},\n\
|
||||
\{ 0, -9760, -3942, -5627\}, \{ 0, -10072, -4163, -6002\},\n\
|
||||
\{ 0, -9892, -4091, -5833\}, \{ 0, -9873, -3867, -5828\},\n\
|
||||
\{ 0, -9911, -4149, -5877\}, \{ 0, -9844, -4016, -5908\},\n\
|
||||
\{ 0, -9528, -3912, -5604\}, \{ 0, -9432, -3911, -5648\},\n\
|
||||
\{ 0, -9314, -3730, -5422\}, \n\
|
||||
};"
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
clear;clc;
|
||||
|
||||
fid = fopen("../caldata", "w");
|
||||
fprintf(fid, "declare -A calMap\n");
|
||||
|
||||
for i = 1:6
|
||||
id = sprintf("JG%02d", i);
|
||||
write_data(fid, pwd, id);
|
||||
end
|
||||
|
||||
for i = 1:6
|
||||
id = sprintf("LJ%02d", i);
|
||||
write_data(fid, pwd, id);
|
||||
end
|
||||
|
||||
fclose(fid);
|
||||
|
||||
function write_data(fid, folder_name, dev_id)
|
||||
file_path = sprintf("%s/phase_%s.mat", folder_name, dev_id);
|
||||
if ~isfile(file_path)
|
||||
warning('[%s] dose not exist.\n', file_path);
|
||||
return;
|
||||
end
|
||||
load(file_path);
|
||||
data = sortrows(dataDec1, 1);
|
||||
fprintf(fid, 'calMap[%s]="\\{\\n\\\n', dev_id);
|
||||
for i = 1:size(data,1)
|
||||
if (mod(i, 2) == 1)
|
||||
fprintf(fid, "\t");
|
||||
end
|
||||
fprintf(fid, "\\{%6d, %6d, %6d, %6d\\},", ...
|
||||
data(i,2), data(i,3), data(i,4), data(i,5));
|
||||
if (mod(i, 2) == 1)
|
||||
fprintf(fid, " ");
|
||||
else
|
||||
fprintf(fid, "\\n\\\n");
|
||||
end
|
||||
end
|
||||
fprintf(fid, '\\n\\\n};"\n\n');
|
||||
end
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,442 @@
|
||||
'''
|
||||
@brief This is an example plugin, can receive and send data
|
||||
@author
|
||||
@date
|
||||
@license LGPL-3.0
|
||||
'''
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QTextEdit, QPushButton, QLabel, QScrollArea, QSplitter
|
||||
from PyQt5.QtCore import Qt, pyqtSignal
|
||||
from PyQt5.QtGui import QFont, QTextCursor
|
||||
from struct import Struct
|
||||
try:
|
||||
import utils_ui
|
||||
from plugins.base import Plugin_Base
|
||||
from conn import ConnectionStatus
|
||||
from i18n import _
|
||||
from widgets import statusBar
|
||||
except ImportError:
|
||||
from COMTool import utils_ui
|
||||
from COMTool.plugins.base import Plugin_Base
|
||||
from COMTool.i18n import _
|
||||
from COMTool.conn import ConnectionStatus
|
||||
from COMTool.widgets import statusBar
|
||||
|
||||
class Plugin(Plugin_Base):
|
||||
id = "DUIFEI"
|
||||
name = _("DUIFEI")
|
||||
showReceiveDataSignal = pyqtSignal(str)
|
||||
|
||||
def onInit(self, config):
|
||||
'''
|
||||
init params
|
||||
'''
|
||||
default = {
|
||||
"version": 1,
|
||||
"customSendItems": [
|
||||
{
|
||||
"caption": "自检",
|
||||
"icon": "fa5.question-circle",
|
||||
"data": "5A 54 E1 DD 00 BE 02 5A FE"
|
||||
},
|
||||
# {
|
||||
# "caption": "数据发送测试 - 1",
|
||||
# "icon": "fa5.play-circle",
|
||||
# "data": ""
|
||||
# },
|
||||
# {
|
||||
# "caption": "数据发送测试 - 2",
|
||||
# "icon": "fa5.play-circle",
|
||||
# "data": ""
|
||||
# },
|
||||
{
|
||||
"caption": "装订 - 【主】反拦截小功率",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E3 DD 77 11 00 00 00 48 06 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "装订 - 【主】反拦截全功率",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E3 DD 66 11 00 00 00 37 06 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "装订 - 【主】反拦截静默",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E3 DD 88 11 00 00 00 59 06 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "遥测 - 【主】反拦截",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E6 DD 99 00 5C 03 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "点名 - 【主】反拦截",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E5 DD 77 00 39 03 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "装订 - 【从】拦截小功率",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E3 DD 77 00 00 00 00 37 06 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "装订 - 【从】拦截大功率",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E3 DD 66 00 00 00 00 26 06 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "装订 - 【从】拦截静默",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 E3 DD 88 00 00 00 00 48 06 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "遥测 - 【从】拦截",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 F6 DD 99 00 6C 03 5A FE"
|
||||
},
|
||||
{
|
||||
"caption": "点名 - 【从】拦截",
|
||||
"icon": "fa5.play-circle",
|
||||
"data": "5A 54 F5 DD 77 00 49 03 5A FE"
|
||||
}
|
||||
]
|
||||
}
|
||||
self.config = config
|
||||
for k in default:
|
||||
if not k in self.config:
|
||||
self.config[k] = default[k]
|
||||
|
||||
def onConnChanged(self, status:ConnectionStatus, msg:str):
|
||||
print("-- connection changed: {}, msg: {}".format(status, msg))
|
||||
|
||||
def onWidgetMain(self, parent):
|
||||
'''
|
||||
main widget, just return a QWidget object
|
||||
'''
|
||||
self.mainWidget = QSplitter(Qt.Vertical)
|
||||
# receive widget
|
||||
self.receiveWidget = QTextEdit("")
|
||||
font = QFont('Consolas, DejaVu Sans Mono, Courier New, monospace, Microsoft YaHei', 10)
|
||||
self.receiveWidget.setFont(font)
|
||||
self.receiveWidget.setLineWrapMode(QTextEdit.NoWrap)
|
||||
# clear button
|
||||
self.clearBtn = QPushButton("")
|
||||
utils_ui.setButtonIcon(self.clearBtn, "mdi6.broom")
|
||||
# send scroll
|
||||
self.customSendScroll = QScrollArea()
|
||||
self.customSendScroll.setMinimumHeight(20)
|
||||
self.customSendScroll.setWidgetResizable(True)
|
||||
self.customSendScroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||
self.customSendScroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
cutomSendItemsWraper = QWidget()
|
||||
self.customSendScroll.setWidget(cutomSendItemsWraper)
|
||||
|
||||
# -- wrapper widget
|
||||
cutomSendItemsWraper0 = QWidget()
|
||||
cutomSendItemsWraper0.setProperty("class", "scrollbar2")
|
||||
layout0 = QVBoxLayout()
|
||||
layout0.setContentsMargins(0,8,0,0)
|
||||
cutomSendItemsWraper0.setLayout(layout0)
|
||||
layout0.addWidget(self.customSendScroll)
|
||||
customSendItemsLayoutWrapper = QVBoxLayout()
|
||||
customSendItemsLayoutWrapper.setContentsMargins(0,0,0,0)
|
||||
cutomSendItemsWraper.setLayout(customSendItemsLayoutWrapper)
|
||||
|
||||
# -- items container
|
||||
self.customItems = QWidget()
|
||||
self.customSendItemsLayout = QVBoxLayout()
|
||||
self.customSendItemsLayout.setContentsMargins(0,0,0,0)
|
||||
self.customItems.setLayout(self.customSendItemsLayout)
|
||||
customSendItemsLayoutWrapper.addWidget(self.customItems)
|
||||
customSendItemsLayoutWrapper.addStretch(0)
|
||||
|
||||
# add widgets
|
||||
self.mainWidget.addWidget(self.receiveWidget)
|
||||
self.mainWidget.addWidget(self.clearBtn)
|
||||
self.mainWidget.addWidget(cutomSendItemsWraper0)
|
||||
self.mainWidget.setStretchFactor(0, 2)
|
||||
self.mainWidget.setStretchFactor(1, 1)
|
||||
self.mainWidget.setStretchFactor(2, 11)
|
||||
|
||||
# event
|
||||
def clearReceived():
|
||||
self.receiveWidget.clear();self.statusBar.clear()
|
||||
self.clearBtn.clicked.connect(clearReceived)
|
||||
return self.mainWidget
|
||||
|
||||
def onWidgetStatusBar(self, parent):
|
||||
self.statusBar = statusBar(rxTxCount=True)
|
||||
return self.statusBar
|
||||
|
||||
def onUiInitDone(self):
|
||||
'''
|
||||
UI init done, you can update your widget here
|
||||
this method runs in UI thread, do not block too long
|
||||
'''
|
||||
newItems = []
|
||||
print(self.config["customSendItems"])
|
||||
for item in self.config["customSendItems"]:
|
||||
print(item)
|
||||
item = self.insertSendItem(item, load=True)
|
||||
newItems.append(item)
|
||||
self.config["customSendItems"] = newItems
|
||||
self.showReceiveDataSignal.connect(self.showReceivedData)
|
||||
# frame struct
|
||||
self.structSelfTestRsp = Struct("<BB B BBBbbb BbBBB BB")
|
||||
self.structStatusCheckRsp = Struct("<BB Q HIII IBBBBI BBHH HHHIIIIII i II 4s IIII d Q dBB dB H B 3s BBBbbb BbBBB 2s")
|
||||
self.structFljData = Struct("<dddd IHI fff fff")
|
||||
self.structLjData = Struct("<IHI ffff IHI fff fff fff IHI fff fff fff IHI fff fff fff I")
|
||||
self.structSysInfo = Struct("<IHI H B I B fff fff fff")
|
||||
|
||||
def insertSendItem(self, item = None, load = False):
|
||||
caption = item["caption"]
|
||||
itemWidget = QWidget()
|
||||
layout = QHBoxLayout()
|
||||
layout.setContentsMargins(0,0,0,0)
|
||||
itemWidget.setLayout(layout)
|
||||
send = QPushButton("")
|
||||
label = QLabel(caption)
|
||||
if (not "icon" in item) or not item["icon"]:
|
||||
item["icon"] = "fa.send"
|
||||
utils_ui.setButtonIcon(send, item["icon"])
|
||||
send.setProperty("class", "smallBtn")
|
||||
def sendCustomData(idx):
|
||||
self.sendCustomItem(self.config["customSendItems"][idx])
|
||||
send.clicked.connect(lambda: sendCustomData(self.customSendItemsLayout.indexOf(itemWidget)))
|
||||
layout.addWidget(label)
|
||||
layout.addWidget(send)
|
||||
self.customSendItemsLayout.addWidget(itemWidget)
|
||||
if not load:
|
||||
self.config["customSendItems"].append(item)
|
||||
return item
|
||||
|
||||
def showReceivedData(self, text: str):
|
||||
curScrollValue = self.receiveWidget.verticalScrollBar().value()
|
||||
self.receiveWidget.moveCursor(QTextCursor.End)
|
||||
endScrollValue = self.receiveWidget.verticalScrollBar().value()
|
||||
self.receiveWidget.insertPlainText(text)
|
||||
if curScrollValue < endScrollValue:
|
||||
self.receiveWidget.verticalScrollBar().setValue(curScrollValue)
|
||||
else:
|
||||
self.receiveWidget.moveCursor(QTextCursor.End)
|
||||
|
||||
def onReceived(self, data : bytes):
|
||||
'''
|
||||
call in receive thread, not UI thread
|
||||
'''
|
||||
self.statusBar.addRx(len(data))
|
||||
## Apply data validation check
|
||||
if len(data) < 7:
|
||||
self.showReceiveDataSignal.emit("\n### Wrong data format: wrong frame header/tail\n")
|
||||
return
|
||||
|
||||
dataLen = data[-3]
|
||||
if data[0] != 0x5A or data[1] != 0x54 or data[-1] != 0xFE or data[-2] != 0x5A:
|
||||
self.showReceiveDataSignal.emit("\n### Wrong data format: wrong length\n")
|
||||
|
||||
checkSum = 0
|
||||
for i in data[2:-4]:
|
||||
checkSum += i
|
||||
if checkSum & 0xFF != data[-4]:
|
||||
self.showReceiveDataSignal.emit("\n### Wrong data format: wrong check sum\n")
|
||||
|
||||
## Eval data
|
||||
data = data[2:-5].replace(b'\x00\x54\xFE', b'\x54\xFE')
|
||||
# self.printFrame(data)
|
||||
if data[0] == 0xE1:
|
||||
# eval self test
|
||||
self.showReceiveDataSignal.emit(self.evalSelfTestRsp(data) + "\n")
|
||||
elif data[0] == 0xE6 or data[0] == 0xF6:
|
||||
self.showReceiveDataSignal.emit(self.evalStatusCheckRsp(data) + "\n")
|
||||
elif data[0] == 0xE5 or data[0] == 0xF5:
|
||||
self.showReceiveDataSignal.emit('Retrieved Data Frame:\n' + self.printFrame(data) + "\n")
|
||||
else:
|
||||
self.showReceiveDataSignal.emit(f"\n### Unexpected response code 0x{data[0]:02x}.\n")
|
||||
|
||||
def evalSelfTestRsp(self, data: bytes):
|
||||
try:
|
||||
payload = self.structSelfTestRsp.unpack(data)
|
||||
except :
|
||||
return f"\n### evalSelfTestRsp:: Failed to unpack data (data length {len(data)} byte).\n"
|
||||
|
||||
ret = "----------- 自检回令 -----------\n"
|
||||
|
||||
ret += f"节点编号: 0x{payload[-2]:02X}\n"
|
||||
|
||||
ret += "节点类型: "
|
||||
if payload[1] == 0xDD:
|
||||
ret += f"K频段 (0x{payload[1]:02X})\n"
|
||||
elif payload[1] == 0xEE:
|
||||
ret += f"S频段 (0x{payload[1]:02X})\n"
|
||||
else:
|
||||
ret += f"【未知错误】(0x{payload[1]:02X})\n"
|
||||
|
||||
ret += "自检结果: "
|
||||
if payload[2] == 0xAA:
|
||||
ret += f"正常 (0x{payload[2]:02X})\n"
|
||||
elif payload[2] == 0x55:
|
||||
ret += f"异常 (0x{payload[2]:02X})\n"
|
||||
else:
|
||||
ret += f"【未知错误】(0x{payload[2]:02X})\n"
|
||||
|
||||
hwOffset = 3
|
||||
|
||||
ret += f"FPGA 电压监测: {bin(payload[hwOffset+0])[2:].zfill(8)}\n"
|
||||
ret += f"时钟锁定状态: {bin(payload[hwOffset+1])[2:].zfill(8)}\n"
|
||||
ret += f"AD 锁定状态: {bin(payload[hwOffset+2])[2:].zfill(8)}\n"
|
||||
ret += f"AD 温度 1: {payload[hwOffset+3]:>4d}\n"
|
||||
ret += f"AD 温度 2: {payload[hwOffset+4]:>4d}\n"
|
||||
ret += f"FPGA 温度: {payload[hwOffset+5]:>4d}\n"
|
||||
ret += f"电压监测: {bin(payload[hwOffset+6])[2:].zfill(8)}\n"
|
||||
ret += f"射频温度: {payload[hwOffset+7]:>4d}\n"
|
||||
ret += f"锁定指示: {bin(payload[hwOffset+8])[2:].zfill(8)}\n"
|
||||
ret += f"MGC 1~2: {payload[hwOffset+9] & 0x0f:>2d} - {payload[hwOffset+9] >> 4:>2d}\n"
|
||||
ret += f"MGC 3~4: {payload[hwOffset+10] & 0x0f:>2d} - {payload[hwOffset+10] >> 4:>2d}\n"
|
||||
ret += "--------------------------------\n"
|
||||
|
||||
return ret + '\n' + self.printFrame(data)
|
||||
|
||||
def printFrame(self, data: bytes):
|
||||
ret = ''
|
||||
for i in range(len(data)):
|
||||
ret += f'{data[i]:02X}'
|
||||
ret += '\n' if i%16 == 15 else ' '
|
||||
ret += '\n'
|
||||
return ret
|
||||
|
||||
def evalStatusCheckRsp(self, data: bytes):
|
||||
try:
|
||||
payload = self.structStatusCheckRsp.unpack(data)
|
||||
except :
|
||||
return f"\n### evalStatusCheckRsp:: Failed to unpack data (data length {len(data)} byte).\n"
|
||||
|
||||
ret = "----------- 遥测回令 -----------\n"
|
||||
|
||||
ret += "节点类型: "
|
||||
if payload[1] == 0xDD:
|
||||
ret += f"K频段 (0x{payload[1]:02X})\n"
|
||||
elif payload[1] == 0xEE:
|
||||
ret += f"S频段 (0x{payload[1]:02X})\n"
|
||||
else:
|
||||
ret += f"【未知错误】(0x{payload[1]:02X})\n"
|
||||
|
||||
ret += f"时间戳: {payload[2]/1e5:.2f} ms\n"
|
||||
|
||||
sysbusOffset = 3
|
||||
linkOffset = 7
|
||||
phyOffset = 30
|
||||
hwOffset = 44
|
||||
|
||||
ret += "\n -- 总线状态\n"
|
||||
ret += f"配置装订: {payload[sysbusOffset + 0]:04X}\n"
|
||||
ret += f"装置点名计数: {payload[sysbusOffset + 1]:>6d}\n"
|
||||
ret += f"业务下发计数: {payload[sysbusOffset + 2]:>6d}\n"
|
||||
ret += f"遥测请求计数: {payload[sysbusOffset + 3]:>6d}\n"
|
||||
|
||||
ret += "\n -- 链路层状态\n"
|
||||
ret += f"帧号: {payload[linkOffset + 0]:>6d}\n"
|
||||
ret += f"时隙号: {payload[linkOffset + 1]:>3d}\n"
|
||||
|
||||
ret += "当前角色: "
|
||||
if payload[linkOffset + 2] == 0xAA:
|
||||
ret += f"反拦截 (0x{payload[linkOffset + 2]:02X})\n"
|
||||
elif payload[linkOffset + 2] == 0xCC:
|
||||
ret += f"拦截 (0x{payload[linkOffset + 2]:02X})\n"
|
||||
else:
|
||||
ret += f"【未知错误】(0x{payload[linkOffset + 2]:02X})\n"
|
||||
|
||||
ret += "网络连接状态: "
|
||||
if payload[linkOffset + 3] == 0x11:
|
||||
ret += f"已连接 (0x{payload[linkOffset + 3]:02X})\n"
|
||||
elif payload[linkOffset + 3] == 0x00:
|
||||
ret += f"未连接 (0x{payload[linkOffset + 3]:02X})\n"
|
||||
else:
|
||||
ret += f"【未知错误】(0x{payload[linkOffset + 3]:02X})\n"
|
||||
|
||||
ret += "网络运行阶段: "
|
||||
if payload[linkOffset + 4] == 0x11:
|
||||
ret += f"扫描建网 (0x{payload[linkOffset + 4]:02X})\n"
|
||||
elif payload[linkOffset + 4] == 0x22:
|
||||
ret += f"业务通信 (0x{payload[linkOffset + 4]:02X})\n"
|
||||
else:
|
||||
ret += f"【未知错误】(0x{payload[linkOffset + 4]:02X})\n"
|
||||
|
||||
ret += f"重建/入网计数: {payload[linkOffset + 5]:>6d}\n"
|
||||
ret += f"通信波位号: {payload[linkOffset + 6]:>2d}\n"
|
||||
|
||||
ret += "通信波束宽度: "
|
||||
if payload[linkOffset + 7] == 0x01:
|
||||
ret += f"120° 宽波束 (0x{payload[linkOffset + 7]:02X})\n"
|
||||
elif payload[linkOffset + 7] == 0x02:
|
||||
ret += f"60° 次波束 (0x{payload[linkOffset + 7]:02X})\n"
|
||||
elif payload[linkOffset + 7] == 0x03:
|
||||
ret += f"25° 次波束 (0x{payload[linkOffset + 7]:02X})\n"
|
||||
elif payload[linkOffset + 7] == 0x04:
|
||||
ret += f"8° 窄波束 (0x{payload[linkOffset + 7]:02X})\n"
|
||||
else:
|
||||
ret += f"【未知错误】(0x{payload[linkOffset + 7]:02X})\n"
|
||||
|
||||
ret += f"离轴角: {payload[linkOffset + 8]*0.1:.2f}°\n"
|
||||
ret += f"偏航角: {payload[linkOffset + 9]*0.1:.2f}°\n"
|
||||
ret += f"基准帧发送计数: {payload[linkOffset + 10]:>6d}\n"
|
||||
ret += f"基准帧接收计数: {payload[linkOffset + 11]:>6d}\n"
|
||||
ret += f"基准帧正确计数: {payload[linkOffset + 12]:>6d}\n"
|
||||
ret += f"双向握手帧发送计数: {payload[linkOffset + 13]:>6d}\n"
|
||||
ret += f"双向握手帧接收计数: {payload[linkOffset + 14]:>6d}\n"
|
||||
ret += f"双向握手帧正确计数: {payload[linkOffset + 15]:>6d}\n"
|
||||
ret += f"业务帧发送计数: {payload[linkOffset + 16]:>6d}\n"
|
||||
ret += f"业务帧接收计数: {payload[linkOffset + 17]:>6d}\n"
|
||||
ret += f"业务帧正确计数: {payload[linkOffset + 18]:>6d}\n"
|
||||
ret += f"时间偏差记录: {payload[linkOffset + 19]/1e2:.2f} us\n"
|
||||
ret += f"发送数据 ID: {payload[linkOffset + 20]:>6d}\n"
|
||||
ret += f"接收数据 ID: {payload[linkOffset + 21]:>6d}\n"
|
||||
|
||||
ret += "\n -- 物理层状态\n"
|
||||
ret += f"捕获计数: {payload[phyOffset + 0]:>6d}\n"
|
||||
ret += f"帧同步计数: {payload[phyOffset + 1]:>6d}\n"
|
||||
ret += f"译码计数: {payload[phyOffset + 2]:>6d}\n"
|
||||
ret += f"CRC 正确计数:{payload[phyOffset + 3]:>6d}\n"
|
||||
ret += f"多普勒估计: {payload[phyOffset + 4]:.2f} Hz\n"
|
||||
ret += f"正确接收时刻: {payload[phyOffset + 5]/1e2:.2f} us\n"
|
||||
ret += f"捕获峰均比: {payload[phyOffset + 6]:.2f}\n"
|
||||
ret += f"捕获相位值: {payload[phyOffset + 7]:>3d}\n"
|
||||
ret += f"捕获频偏通道: {payload[phyOffset + 8]:>3d}\n"
|
||||
ret += f"帧同步峰均比: {payload[phyOffset + 9]:.2f}\n"
|
||||
ret += f"帧同步频偏通道: {payload[phyOffset + 10]:>3d}\n"
|
||||
ret += f"交织输入数据幅度统计:\t0x{payload[phyOffset + 11]:04X}\n"
|
||||
ret += "天线工作模式: "
|
||||
if payload[phyOffset + 12] == 0x01:
|
||||
ret += f"静默模式 (0x{payload[phyOffset + 12]:02X})\n"
|
||||
elif payload[phyOffset + 12] == 0x02:
|
||||
ret += f"低功率模式 (0x{payload[phyOffset + 12]:02X})\n"
|
||||
elif payload[phyOffset + 12] == 0x03:
|
||||
ret += f"全功率模式 (0x{payload[phyOffset + 12]:02X})\n"
|
||||
else:
|
||||
ret += f"【未知错误】(0x{payload[phyOffset + 12]:02X})\n"
|
||||
|
||||
ret += "\n -- 硬件状态\n"
|
||||
ret += f"FPGA 电压监测: {bin(payload[hwOffset+0])[2:].zfill(8)}\n"
|
||||
ret += f"时钟锁定状态: {bin(payload[hwOffset+1])[2:].zfill(8)}\n"
|
||||
ret += f"AD 锁定状态: {bin(payload[hwOffset+2])[2:].zfill(8)}\n"
|
||||
ret += f"AD 温度 1: {payload[hwOffset+3]:>4d}\n"
|
||||
ret += f"AD 温度 2: {payload[hwOffset+4]:>4d}\n"
|
||||
ret += f"FPGA 温度: {payload[hwOffset+5]:>4d}\n"
|
||||
ret += f"电压监测: {bin(payload[hwOffset+6])[2:].zfill(8)}\n"
|
||||
ret += f"射频温度: {payload[hwOffset+7]:>4d}\n"
|
||||
ret += f"锁定指示: {bin(payload[hwOffset+8])[2:].zfill(8)}\n"
|
||||
ret += f"MGC 1~2: {payload[hwOffset+9] & 0x0f:>2d} - {payload[hwOffset+9] >> 4:>2d}\n"
|
||||
ret += f"MGC 3~4: {payload[hwOffset+10] & 0x0f:>2d} - {payload[hwOffset+10] >> 4:>2d}\n"
|
||||
|
||||
ret += "--------------------------------\n"
|
||||
return ret + '\n' + self.printFrame(data)
|
||||
|
||||
def onSent(self, ok, msg, length, path):
|
||||
if ok:
|
||||
self.statusBar.addTx(length)
|
||||
else:
|
||||
self.hintSignal.emit("error", _("Error"), _("Send data failed!") + " " + msg)
|
||||
|
||||
def sendCustomItem(self, item):
|
||||
data = item["data"]
|
||||
dateBytes = self.parseSendData(data, encoding = self.configGlobal["encoding"], isHexStr = True)
|
||||
if dateBytes:
|
||||
self.send(dateBytes, callback=self.onSent)
|
||||
@@ -359,20 +359,20 @@
|
||||
/* Definitions for driver GPIO */
|
||||
#define XPAR_XGPIO_NUM_INSTANCES 1
|
||||
|
||||
/* Definitions for peripheral CONFIG_GPIO */
|
||||
#define XPAR_CONFIG_GPIO_BASEADDR 0x41200000
|
||||
#define XPAR_CONFIG_GPIO_HIGHADDR 0x4120FFFF
|
||||
#define XPAR_CONFIG_GPIO_DEVICE_ID 0
|
||||
#define XPAR_CONFIG_GPIO_INTERRUPT_PRESENT 0
|
||||
#define XPAR_CONFIG_GPIO_IS_DUAL 1
|
||||
/* Definitions for peripheral MPC_GPIO */
|
||||
#define XPAR_MPC_GPIO_BASEADDR 0x41200000
|
||||
#define XPAR_MPC_GPIO_HIGHADDR 0x4120FFFF
|
||||
#define XPAR_MPC_GPIO_DEVICE_ID 0
|
||||
#define XPAR_MPC_GPIO_INTERRUPT_PRESENT 0
|
||||
#define XPAR_MPC_GPIO_IS_DUAL 1
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
/* Canonical definitions for peripheral CONFIG_GPIO */
|
||||
/* Canonical definitions for peripheral MPC_GPIO */
|
||||
#define XPAR_GPIO_0_BASEADDR 0x41200000
|
||||
#define XPAR_GPIO_0_HIGHADDR 0x4120FFFF
|
||||
#define XPAR_GPIO_0_DEVICE_ID XPAR_CONFIG_GPIO_DEVICE_ID
|
||||
#define XPAR_GPIO_0_DEVICE_ID XPAR_MPC_GPIO_DEVICE_ID
|
||||
#define XPAR_GPIO_0_INTERRUPT_PRESENT 0
|
||||
#define XPAR_GPIO_0_IS_DUAL 1
|
||||
|
||||
@@ -425,17 +425,14 @@
|
||||
|
||||
/* Definitions for Fabric interrupts connected to ps7_scugic_0 */
|
||||
#define XPAR_FABRIC_PHY_IRQ_INTR 61U
|
||||
#define XPAR_FABRIC_FRAME_UART_0_RX_INTR_INTR 62U
|
||||
#define XPAR_FABRIC_FRAME_UART_0_TX_INTR_INTR 63U
|
||||
#define XPAR_FABRIC_MPC_IRQ_INTR 64U
|
||||
#define XPAR_FABRIC_PHY_5MS_INTR 65U
|
||||
#define XPAR_FABRIC_PHY_5MS_DELAY_2MS_INTR 66U
|
||||
#define XPAR_FABRIC_PHY_5MS_INTR 62U
|
||||
#define XPAR_FABRIC_PHY_5MS_DELAY_2MS_INTR 63U
|
||||
#define XPAR_FABRIC_MPC_RX_IRQ_INTR 64U
|
||||
#define XPAR_FABRIC_MPC_TX_IRQ_INTR 65U
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
/* Canonical definitions for Fabric interrupts connected to ps7_scugic_0 */
|
||||
#define XPAR_FABRIC_FRAME_UART_0_RX_INTR_VEC_ID XPAR_FABRIC_FRAME_UART_0_RX_INTR_INTR
|
||||
#define XPAR_FABRIC_FRAME_UART_0_TX_INTR_VEC_ID XPAR_FABRIC_FRAME_UART_0_TX_INTR_INTR
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
|
||||
@@ -43,10 +43,10 @@
|
||||
XGpio_Config XGpio_ConfigTable[XPAR_XGPIO_NUM_INSTANCES] =
|
||||
{
|
||||
{
|
||||
XPAR_CONFIG_GPIO_DEVICE_ID,
|
||||
XPAR_CONFIG_GPIO_BASEADDR,
|
||||
XPAR_CONFIG_GPIO_INTERRUPT_PRESENT,
|
||||
XPAR_CONFIG_GPIO_IS_DUAL
|
||||
XPAR_MPC_GPIO_DEVICE_ID,
|
||||
XPAR_MPC_GPIO_BASEADDR,
|
||||
XPAR_MPC_GPIO_INTERRUPT_PRESENT,
|
||||
XPAR_MPC_GPIO_IS_DUAL
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -18,18 +18,6 @@ BEGIN PROCESSOR
|
||||
END
|
||||
|
||||
|
||||
BEGIN DRIVER
|
||||
PARAMETER DRIVER_NAME = frame_uart
|
||||
PARAMETER DRIVER_VER = 1.0
|
||||
PARAMETER HW_INSTANCE = Frame_Uart_0
|
||||
END
|
||||
|
||||
BEGIN DRIVER
|
||||
PARAMETER DRIVER_NAME = gpio
|
||||
PARAMETER DRIVER_VER = 4.4
|
||||
PARAMETER HW_INSTANCE = config_gpio
|
||||
END
|
||||
|
||||
BEGIN DRIVER
|
||||
PARAMETER DRIVER_NAME = generic
|
||||
PARAMETER DRIVER_VER = 2.0
|
||||
@@ -54,6 +42,12 @@ BEGIN DRIVER
|
||||
PARAMETER HW_INSTANCE = mpc_bram_interface_mpc_bram_ctrl
|
||||
END
|
||||
|
||||
BEGIN DRIVER
|
||||
PARAMETER DRIVER_NAME = gpio
|
||||
PARAMETER DRIVER_VER = 4.4
|
||||
PARAMETER HW_INSTANCE = mpc_gpio
|
||||
END
|
||||
|
||||
BEGIN DRIVER
|
||||
PARAMETER DRIVER_NAME = bram
|
||||
PARAMETER DRIVER_VER = 4.3
|
||||
|
||||
@@ -13,7 +13,7 @@ RM := rm -rf
|
||||
-include sources.mk
|
||||
-include src/util/subdir.mk
|
||||
-include src/time_ctrl/subdir.mk
|
||||
-include src/systembus/subdir.mk
|
||||
-include src/mpc/subdir.mk
|
||||
-include src/networking/phy_layer/subdir.mk
|
||||
-include src/networking/link_layer/geometry/subdir.mk
|
||||
-include src/networking/link_layer/subdir.mk
|
||||
|
||||
@@ -23,7 +23,7 @@ C_DEPS += \
|
||||
src/dev_profile/%.o: ../src/dev_profile/%.c
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: ARM v7 gcc compiler'
|
||||
$(CC) -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||
$(CC) -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
||||
+7
-7
@@ -4,23 +4,23 @@
|
||||
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
C_SRCS += \
|
||||
../src/systembus/systembus.c \
|
||||
../src/systembus/systembus_uart.c
|
||||
../src/mpc/mpc.c \
|
||||
../src/mpc/mpc_hw.c
|
||||
|
||||
OBJS += \
|
||||
./src/systembus/systembus.o \
|
||||
./src/systembus/systembus_uart.o
|
||||
./src/mpc/mpc.o \
|
||||
./src/mpc/mpc_hw.o
|
||||
|
||||
C_DEPS += \
|
||||
./src/systembus/systembus.d \
|
||||
./src/systembus/systembus_uart.d
|
||||
./src/mpc/mpc.d \
|
||||
./src/mpc/mpc_hw.d
|
||||
|
||||
|
||||
# Each subdirectory must supply rules for building sources it contributes
|
||||
src/systembus/%.o: ../src/systembus/%.c
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: ARM v7 gcc compiler'
|
||||
$(CC) -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||
$(CC) -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
@@ -23,7 +23,7 @@ C_DEPS += \
|
||||
src/networking/link_layer/geometry/%.o: ../src/networking/link_layer/geometry/%.c
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: ARM v7 gcc compiler'
|
||||
$(CC) -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||
$(CC) -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ C_DEPS += \
|
||||
src/networking/link_layer/%.o: ../src/networking/link_layer/%.c
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: ARM v7 gcc compiler'
|
||||
$(CC) -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||
$(CC) -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ C_DEPS += \
|
||||
src/networking/phy_layer/%.o: ../src/networking/phy_layer/%.c
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: ARM v7 gcc compiler'
|
||||
$(CC) -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||
$(CC) -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ C_DEPS += \
|
||||
src/%.o: ../src/%.c
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: ARM v7 gcc compiler'
|
||||
$(CC) -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||
$(CC) -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ C_DEPS += \
|
||||
src/time_ctrl/%.o: ../src/time_ctrl/%.c
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: ARM v7 gcc compiler'
|
||||
$(CC) -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||
$(CC) -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ C_DEPS += \
|
||||
src/util/%.o: ../src/util/%.c
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: ARM v7 gcc compiler'
|
||||
$(CC) -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||
$(CC) -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
*startfile:
|
||||
crti%O%s crtbegin%O%s
|
||||
@@ -10,18 +10,24 @@
|
||||
* History:
|
||||
* [2021-04-28]: Initial edition.
|
||||
*
|
||||
* Copyright(c) 2021 Beijing Institute of Technology.
|
||||
* Copyright(c) 2024 Beijing Institute of Technology.
|
||||
* Lab of Communication and Networking
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef CONFIG_H_
|
||||
#define CONFIG_H_
|
||||
|
||||
#define XILINX_PLATFORM
|
||||
#ifndef __APP_CONFIG_H_
|
||||
#define __APP_CONFIG_H_
|
||||
|
||||
#include "xparameters.h"
|
||||
|
||||
#ifdef PLATFORM_ZYNQMP // Zynq MPSoC (Zynq UltraScale+)
|
||||
#define HSJL_GE
|
||||
#elif defined(PLATFORM_ZYNQ)
|
||||
#define HSJL_NODE
|
||||
#else
|
||||
#error Unsupported hardware...
|
||||
#endif
|
||||
|
||||
/******** Software Version ********/
|
||||
#define _APP_VER 0x00010008
|
||||
|
||||
@@ -35,34 +41,42 @@
|
||||
// 2 - print warnings and errors
|
||||
// 1 - print only errors
|
||||
// other - print nothing
|
||||
|
||||
#define DATALINK_ENABLE_AUTORECONNECT
|
||||
#define DATALINK_ENABLE_AUTOTIMESYNC
|
||||
// #define DATALINK_ENABLE_BERTEST
|
||||
|
||||
|
||||
/************ Hardware Configs ************/
|
||||
#define CPU_CLK_HZ XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ
|
||||
#define GLOBAL_TIMER_CLK_HZ (CPU_CLK_HZ/2)
|
||||
#define SCU_TIMER_CLK_HZ (CPU_CLK_HZ/2)
|
||||
#ifdef HSJL_GE // Zynq MPSoC (Zynq UltraScale+)
|
||||
#define CPU_CLK_HZ XPAR_CPU_CORTEXA53_0_CPU_CLK_FREQ_HZ
|
||||
#define FCLK_CLK0_HZ 100000000
|
||||
|
||||
#define APP_TIMER_CLK_HZ FCLK_CLK0_HZ
|
||||
#else // Zynq-7000
|
||||
#define CPU_CLK_HZ XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ
|
||||
#define APP_TIMER_CLK_HZ (CPU_CLK_HZ / 2)
|
||||
#define FCLK_CLK0_HZ 100000000
|
||||
#endif
|
||||
/********* Zynq Platform Configs **********/
|
||||
// SCU Timer (for logging)
|
||||
#define SCUTIMER_DEVICE_ID XPAR_PS7_SCUTIMER_0_DEVICE_ID
|
||||
#define SCUTIMER_INTR_ID XPAR_SCUTIMER_INTR
|
||||
|
||||
// APP Timer (for logging)
|
||||
#ifdef HSJL_GE // Zynq MPSoC (Zynq UltraScale+)
|
||||
#define APPTIMER_DEVICE_ID XPAR_AXI_TIMER_DEVICE_ID
|
||||
#define APPTIMER_INTR_ID XPAR_FABRIC_AXI_TIMER_INTERRUPT_INTR
|
||||
#else
|
||||
#define APPTIMER_DEVICE_ID XPAR_PS7_SCUTIMER_0_DEVICE_ID
|
||||
#define APPTIMER_INTR_ID XPAR_SCUTIMER_INTR
|
||||
#endif
|
||||
// Physical Layer Configs
|
||||
#define PHY_DEVICE_ID 0
|
||||
#define PHY_DEVICE_ID (0x01 | 0x00)
|
||||
#define PHY_BASEADDR XPAR_PHYC_BASEADDR
|
||||
#define PHY_BEAM_SET_PRESET
|
||||
#define PHY_BEAM_FORMING_ENABLE
|
||||
// -- Antenna Bram Configs
|
||||
#define PHY_ANTCONFIG_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DEVICE_ID
|
||||
#define PHY_ANTCONFIG_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_DEVICE_ID
|
||||
#define PHY_ANTINFO_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_DEVICE_ID
|
||||
// -- Buffers
|
||||
#define PHY_TXBUFF_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_DEVICE_ID
|
||||
#define PHY_RXBUFF_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_DEVICE_ID
|
||||
// -- Xadc
|
||||
#define PHY_HW_XADC_DEVICE_ID XPAR_PS7_XADC_0_DEVICE_ID
|
||||
#define PHY_HW_SYSMON_DEVICE_ID XPAR_SYSTEM_MANAGEMENT_DEVICE_ID
|
||||
// -- Interrupt id
|
||||
#define PHY_INTR_ID XPAR_FABRIC_PHY_IRQ_INTR
|
||||
#define PERIODIC_5MS_INTR_ID XPAR_FABRIC_PHY_5MS_DELAY_2MS_INTR
|
||||
@@ -71,18 +85,202 @@
|
||||
#define TIME_CONTROLLER_BASEADDR XPAR_TMC_BASEADDR
|
||||
|
||||
// System Bus Configs
|
||||
//#define SYSBUS_BASE_ADDR XPAR_SYSTEMBUS_BASEADDR
|
||||
//#define SYSBUS_TX_INTR_ID XPAR_FABRIC_SYSTEMBUS_TX_DONE_INTR
|
||||
//#define SYSBUS_RX_INTR_ID XPAR_FABRIC_SYSTEMBUS_RX_DONE_INTR
|
||||
|
||||
// Global Timer config
|
||||
#define GLOBAL_TIMER_DEVICE_ID XPAR_GLOBAL_TMR_DEVICE_ID
|
||||
#define GLOBAL_TIMER_BASEADDR XPAR_GLOBAL_TMR_BASEADDR
|
||||
#define GLOBAL_TIMER_INTR_ID XPAR_GLOBAL_TMR_INTR
|
||||
#define SYSBUS_BASE_ADDR XPAR_SYSTEMBUS_BASEADDR
|
||||
#define SYSBUS_TX_INTR_ID XPAR_FABRIC_SYSTEMBUS_TX_DONE_INTR
|
||||
#define SYSBUS_RX_INTR_ID XPAR_FABRIC_SYSTEMBUS_RX_DONE_INTR
|
||||
|
||||
// INTC configis
|
||||
#define INTC_DEVICE_ID XPAR_SCUGIC_0_DEVICE_ID
|
||||
|
||||
/********* Hardware Configurations **********/
|
||||
#ifdef HSJL_GE // Zynq MPSoC (Zynq UltraScale+)
|
||||
#define RFSOC
|
||||
#define LMK04828
|
||||
//#define LMX2594_ADC
|
||||
//#define LMX2594_DAC
|
||||
#define RFDC_DEVICE_ID XPAR_XRFDC_0_DEVICE_ID
|
||||
#else
|
||||
#define AD9361_REG
|
||||
//#define AD9361_API
|
||||
#define AD9528
|
||||
//#define AD9653
|
||||
//#define AD9694
|
||||
#endif
|
||||
|
||||
// AD9361 Configuration
|
||||
#define SPI_INTERFACE_SPI_ENGINE
|
||||
#define HAVE_SPLIT_GAIN_TABLE 1 /* only set to 0 in case split_gain_table_mode_enable = 0*/
|
||||
#define HAVE_TDD_SYNTH_TABLE 1 /* only set to 0 in case split_gain_table_mode_enable = 0*/
|
||||
#define AD9361_DEVICE 1 /* set it 1 if AD9361 device is used, 0 otherwise */
|
||||
#define AD9364_DEVICE 0 /* set it 1 if AD9364 device is used, 0 otherwise */
|
||||
#define AD9363A_DEVICE 0 /* set it 1 if AD9363A device is used, 0 otherwise */
|
||||
#define HAVE_VERBOSE_MESSAGES /* Recommended during development prints errors and warnings */
|
||||
// #define HAVE_DEBUG_MESSAGES /* For Debug purposes only */
|
||||
// AD9361 GPIO Configurations
|
||||
#define AD9361_GPIO_DEVICE_ID 0
|
||||
#define AD9361_GPIO_OFFSET 54
|
||||
#define AD9361_GPIO_INPUT 0
|
||||
#define AD9361_GPIO_OUTPUT 1
|
||||
#define AD9361_GPIO_DISABLE 0
|
||||
#define AD9361_GPIO_ENABLE 1
|
||||
// -- AD9361-1 SPI Engine Configuration
|
||||
#define AD9361_SPI_DEVICE_ID 0
|
||||
#define AD9361_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
|
||||
#define AD9361_SPI_ENGINE_MAX_SPEED 5000000
|
||||
#define AD9361_SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR
|
||||
#define AD9361_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define AD9361_SPI_ENGINE_CS_DELAY 3
|
||||
#define AD9361_TIMEOUT_TH 2000
|
||||
#define AD9361_1_SPI_CS 0x01
|
||||
#define AD9361_2_SPI_CS 0x02
|
||||
#define AD9361_2_TIMEOUT_TH 2000
|
||||
// -- AD9361-1 GPIO
|
||||
#define AD9361_1_TXNRX (AD9361_GPIO_OFFSET + 6)
|
||||
#define AD9361_1_ENABLE (AD9361_GPIO_OFFSET + 7)
|
||||
#define AD9361_1_EN_AGC (AD9361_GPIO_OFFSET + 8)
|
||||
#define AD9361_1_RESET_B (AD9361_GPIO_OFFSET + 9)
|
||||
#define AD9361_1_CTRL_OUT0 (AD9361_GPIO_OFFSET + 10)
|
||||
#define AD9361_1_CTRL_OUT1 (AD9361_GPIO_OFFSET + 11)
|
||||
#define AD9361_1_CTRL_OUT2 (AD9361_GPIO_OFFSET + 12)
|
||||
#define AD9361_1_CTRL_OUT3 (AD9361_GPIO_OFFSET + 13)
|
||||
#define AD9361_1_CTRL_OUT4 (AD9361_GPIO_OFFSET + 14)
|
||||
#define AD9361_1_CTRL_OUT5 (AD9361_GPIO_OFFSET + 15)
|
||||
#define AD9361_1_CTRL_OUT6 (AD9361_GPIO_OFFSET + 16)
|
||||
#define AD9361_1_CTRL_OUT7 (AD9361_GPIO_OFFSET + 17)
|
||||
#define AD9361_1_CTRL_IN0 (AD9361_GPIO_OFFSET + 18)
|
||||
#define AD9361_1_CTRL_IN1 (AD9361_GPIO_OFFSET + 19)
|
||||
#define AD9361_1_CTRL_IN2 (AD9361_GPIO_OFFSET + 20)
|
||||
#define AD9361_1_CTRL_IN3 (AD9361_GPIO_OFFSET + 21)
|
||||
// -- AD9361-2 GPIO
|
||||
#define AD9361_2_TXNRX (AD9361_GPIO_OFFSET + 22)
|
||||
#define AD9361_2_ENABLE (AD9361_GPIO_OFFSET + 23)
|
||||
#define AD9361_2_EN_AGC (AD9361_GPIO_OFFSET + 24)
|
||||
#define AD9361_2_RESET_B (AD9361_GPIO_OFFSET + 25)
|
||||
#define AD9361_2_CTRL_OUT0 (AD9361_GPIO_OFFSET + 26)
|
||||
#define AD9361_2_CTRL_OUT1 (AD9361_GPIO_OFFSET + 27)
|
||||
#define AD9361_2_CTRL_OUT2 (AD9361_GPIO_OFFSET + 28)
|
||||
#define AD9361_2_CTRL_OUT3 (AD9361_GPIO_OFFSET + 29)
|
||||
#define AD9361_2_CTRL_OUT4 (AD9361_GPIO_OFFSET + 30)
|
||||
#define AD9361_2_CTRL_OUT5 (AD9361_GPIO_OFFSET + 31)
|
||||
#define AD9361_2_CTRL_OUT6 (AD9361_GPIO_OFFSET + 32)
|
||||
#define AD9361_2_CTRL_OUT7 (AD9361_GPIO_OFFSET + 33)
|
||||
#define AD9361_2_CTRL_IN0 (AD9361_GPIO_OFFSET + 34)
|
||||
#define AD9361_2_CTRL_IN1 (AD9361_GPIO_OFFSET + 35)
|
||||
#define AD9361_2_CTRL_IN2 (AD9361_GPIO_OFFSET + 36)
|
||||
#define AD9361_2_CTRL_IN3 (AD9361_GPIO_OFFSET + 37)
|
||||
// AD9361-Status Code
|
||||
#define AD9361_SYNC (AD9361_GPIO_OFFSET + 38)
|
||||
#define AD9361_RX_FIFO_RST (AD9361_GPIO_OFFSET + 39)
|
||||
#define AD9361_1_CAL_START (AD9361_GPIO_OFFSET + 40)
|
||||
#define AD9361_2_CAL_START (AD9361_GPIO_OFFSET + 41)
|
||||
#define AD9361_RECAL (AD9361_GPIO_OFFSET + 42)
|
||||
#define AD9361_TX_SWITCH (AD9361_GPIO_OFFSET + 43)
|
||||
#define AD9361_1_CAL_DONE (AD9361_GPIO_OFFSET + 44)
|
||||
#define AD9361_2_CAL_DONE (AD9361_GPIO_OFFSET + 45)
|
||||
#define AD9361_CAL_RESULT (AD9361_GPIO_OFFSET + 46)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TX_FREQ_125,
|
||||
TX_FREQ_126,
|
||||
TX_FREQ_4125
|
||||
} ad9361TxFreq;
|
||||
|
||||
// HMC7044 Configurations
|
||||
#define HMC7044_GPIO_DEVICE_ID 0
|
||||
#define HMC7044_GPIO_OFFSET 54
|
||||
#define HMC7044_RESET (HMC7044_GPIO_OFFSET + 0)
|
||||
#define HMC7044_SYNC (HMC7044_GPIO_OFFSET + 1)
|
||||
#define HMC7044_GPIO_0 (HMC7044_GPIO_OFFSET + 2)
|
||||
#define HMC7044_GPIO_1 (HMC7044_GPIO_OFFSET + 3)
|
||||
#define HMC7044_GPIO_2 (HMC7044_GPIO_OFFSET + 4)
|
||||
#define HMC7044_GPIO_3 (HMC7044_GPIO_OFFSET + 5)
|
||||
// -- HMC7044 SPI Engine Configuration
|
||||
#define HMC7044_SPI_DEVICE_ID 0
|
||||
#define HMC7044_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
|
||||
#define HMC7044_SPI_ENGINE_MAX_SPEED 5000000
|
||||
#define HMC7044_SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR
|
||||
#define HMC7044_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define HMC7044_SPI_ENGINE_CS_DELAY 3
|
||||
#define HMC7044_SPI_CS_HMC7044 0x00
|
||||
|
||||
// AD9528 Configurations
|
||||
#define AD9528_GPIO_DEVICE_ID 0
|
||||
#define AD9528_GPIO_OFFSET 54
|
||||
#define AD9528_RESETB (AD9528_GPIO_OFFSET+0)
|
||||
#define AD9528_SYSREF_REQ (AD9528_GPIO_OFFSET+1)
|
||||
#define AD9528_STATUS_0 (AD9528_GPIO_OFFSET+2)
|
||||
#define AD9528_STATUS_1 (AD9528_GPIO_OFFSET+3)
|
||||
// -- AD9528 SPI Engine Configuration
|
||||
#define AD9528_SPI_DEVICE_ID 0
|
||||
#define AD9528_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
|
||||
#define AD9528_SPI_ENGINE_MAX_SPEED 5000000
|
||||
#define AD9528_SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR
|
||||
#define AD9528_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define AD9528_SPI_ENGINE_CS_DELAY 3
|
||||
#define AD9528_SPI_CS 0x00
|
||||
|
||||
// LMK04828 Configurations
|
||||
#define LMK04828_GPIO_DEVICE_ID 0
|
||||
#define LMK04828_GPIO_OFFSET 54
|
||||
// -- LMK04828 SPI Engine Configuration
|
||||
#define LMK04828_SPI_DEVICE_ID 0
|
||||
#define LMK04828_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
|
||||
#define LMK04828_SPI_ENGINE_MAX_SPEED 5000000
|
||||
#define LMK04828_SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR
|
||||
#define LMK04828_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define LMK04828_SPI_ENGINE_CS_DELAY 3
|
||||
#define LMK04828_SPI_CS 0x00
|
||||
|
||||
// LMX2594_ADC Configurations
|
||||
#define LMX2594_ADC_GPIO_DEVICE_ID 0
|
||||
#define LMX2594_ADC_GPIO_OFFSET 54
|
||||
// -- LMX2594_ADC SPI Engine Configuration
|
||||
#define LMX2594_ADC_SPI_DEVICE_ID 0
|
||||
#define LMX2594_ADC_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
|
||||
#define LMX2594_ADC_SPI_ENGINE_MAX_SPEED 5000000
|
||||
#define LMX2594_ADC_SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR
|
||||
#define LMX2594_ADC_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define LMX2594_ADC_SPI_ENGINE_CS_DELAY 3
|
||||
#define LMX2594_ADC_SPI_CS 0x01
|
||||
|
||||
// LMX2594_DAC Configurations
|
||||
#define LMX2594_DAC_GPIO_DEVICE_ID 0
|
||||
#define LMX2594_DAC_GPIO_OFFSET 54
|
||||
// -- LMX2594_DAC SPI Engine Configuration
|
||||
#define LMX2594_DAC_SPI_DEVICE_ID 0
|
||||
#define LMX2594_DAC_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
|
||||
#define LMX2594_DAC_SPI_ENGINE_MAX_SPEED 5000000
|
||||
#define LMX2594_DAC_SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR
|
||||
#define LMX2594_DAC_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define LMX2594_DAC_SPI_ENGINE_CS_DELAY 3
|
||||
#define LMX2594_DAC_SPI_CS 0x02
|
||||
|
||||
// AD9653 Configurations
|
||||
#define AD9653_GPIO_DEVICE_ID 0
|
||||
#define AD9653_GPIO_OFFSET 54
|
||||
#define AD9653_POWR_DOWN (AD9653_GPIO_OFFSET+0)
|
||||
// -- AD9653 SPI Engine Configuration
|
||||
#define AD9653_SPI_DEVICE_ID 0
|
||||
#define AD9653_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
|
||||
#define AD9653_SPI_ENGINE_MAX_SPEED 5000000
|
||||
#define AD9653_SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR
|
||||
#define AD9653_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define AD9653_SPI_ENGINE_CS_DELAY 3
|
||||
#define AD9653_SPI_CS 0x03
|
||||
|
||||
// AD9694 Configurations
|
||||
#define AD9694_GPIO_DEVICE_ID 0
|
||||
#define AD9694_GPIO_OFFSET 54
|
||||
// -- AD9694 SPI Engine Configuration
|
||||
#define AD9694_SPI_DEVICE_ID 0
|
||||
#define AD9694_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
|
||||
#define AD9694_SPI_ENGINE_MAX_SPEED 5000000
|
||||
#define AD9694_SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR
|
||||
#define AD9694_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define AD9694_SPI_ENGINE_CS_DELAY 3
|
||||
#define AD9694_SPI_CS 0x03
|
||||
|
||||
// Configuration Check
|
||||
#if defined(PHY_BEAM_SET_PRESET) && !defined(PHY_BEAM_FORMING_ENABLE)
|
||||
#define PHY_BEAM_FORMING_ENABLE
|
||||
@@ -93,9 +291,6 @@
|
||||
#if !defined(DATALINK_ENABLE_AUTOTIMESYNC)
|
||||
#warning To enbale bit error rate test, auto time-sync should be enabled...
|
||||
#endif
|
||||
#if defined(DATALINK_ENABLE_AUTORECONNECT)
|
||||
#error Do not support auto reconnnect in bit error rate test mode...
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif //__APP_CONFIG_H_
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xil_cache.h"
|
||||
#include "platform_config.h"
|
||||
|
||||
/*
|
||||
* Uncomment one of the following two lines, depending on the target,
|
||||
* if ps7/psu init source files are added in the source directory for
|
||||
* compiling example outside of SDK.
|
||||
*/
|
||||
/*#include "ps7_init.h"*/
|
||||
/*#include "psu_init.h"*/
|
||||
|
||||
#ifdef STDOUT_IS_16550
|
||||
#include "xuartns550_l.h"
|
||||
|
||||
#define UART_BAUD 9600
|
||||
#endif
|
||||
|
||||
void
|
||||
enable_caches()
|
||||
{
|
||||
#ifdef __PPC__
|
||||
Xil_ICacheEnableRegion(CACHEABLE_REGION_MASK);
|
||||
Xil_DCacheEnableRegion(CACHEABLE_REGION_MASK);
|
||||
#elif __MICROBLAZE__
|
||||
#ifdef XPAR_MICROBLAZE_USE_ICACHE
|
||||
Xil_ICacheEnable();
|
||||
#endif
|
||||
#ifdef XPAR_MICROBLAZE_USE_DCACHE
|
||||
Xil_DCacheEnable();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
disable_caches()
|
||||
{
|
||||
#ifdef __MICROBLAZE__
|
||||
#ifdef XPAR_MICROBLAZE_USE_DCACHE
|
||||
Xil_DCacheDisable();
|
||||
#endif
|
||||
#ifdef XPAR_MICROBLAZE_USE_ICACHE
|
||||
Xil_ICacheDisable();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
init_uart()
|
||||
{
|
||||
#ifdef STDOUT_IS_16550
|
||||
XUartNs550_SetBaud(STDOUT_BASEADDR, XPAR_XUARTNS550_CLOCK_HZ, UART_BAUD);
|
||||
XUartNs550_SetLineControlReg(STDOUT_BASEADDR, XUN_LCR_8_DATA_BITS);
|
||||
#endif
|
||||
/* Bootrom/BSP configures PS7/PSU UART to 115200 bps */
|
||||
}
|
||||
|
||||
void
|
||||
init_platform()
|
||||
{
|
||||
/*
|
||||
* If you want to run this example outside of SDK,
|
||||
* uncomment one of the following two lines and also #include "ps7_init.h"
|
||||
* or #include "ps7_init.h" at the top, depending on the target.
|
||||
* Make sure that the ps7/psu_init.c and ps7/psu_init.h files are included
|
||||
* along with this example source files for compilation.
|
||||
*/
|
||||
/* ps7_init();*/
|
||||
/* psu_init();*/
|
||||
enable_caches();
|
||||
init_uart();
|
||||
}
|
||||
|
||||
void
|
||||
cleanup_platform()
|
||||
{
|
||||
disable_caches();
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2008 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __PLATFORM_H_
|
||||
#define __PLATFORM_H_
|
||||
|
||||
#include "platform_config.h"
|
||||
|
||||
void init_platform();
|
||||
void cleanup_platform();
|
||||
|
||||
#endif
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef __PLATFORM_CONFIG_H_
|
||||
#define __PLATFORM_CONFIG_H_
|
||||
|
||||
#define STDOUT_IS_PS7_UART
|
||||
#define UART_DEVICE_ID 0
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,340 @@
|
||||
#include "dev_profile.h"
|
||||
#include "../config/app_config.h"
|
||||
#include "../drivers/rf-transceiver/ad9361/ad9361_api.h"
|
||||
#include "../drivers/axi_core/spi_engine/spi_engine.h"
|
||||
#include "../drivers/platform/xilinx_gpio.h"
|
||||
|
||||
struct spi_engine_init_param spi_engine_param = {
|
||||
.ref_clk_hz = AD9361_SPI_ENGINE_REF_CLK,
|
||||
.type = SPI_ENGINE,
|
||||
.spi_engine_baseaddr = AD9361_SPI_ENGINE_BASEADDR,
|
||||
.cs_delay = AD9361_SPI_ENGINE_CS_DELAY,
|
||||
.data_width = AD9361_SPI_ENGINE_DATA_WIDTH
|
||||
};
|
||||
|
||||
struct xil_gpio_init_param xil_gpio_param = {
|
||||
.type = GPIO_PS,
|
||||
.device_id = AD9361_GPIO_DEVICE_ID
|
||||
};
|
||||
|
||||
AD9361_InitParam ad9361_default_init_param = {
|
||||
/* Device selection */
|
||||
ID_AD9361, // dev_sel
|
||||
/* Reference Clock */
|
||||
48000000UL, //reference_clk_rate
|
||||
/* Base Configuration */
|
||||
1, //two_rx_two_tx_mode_enable *** adi,2rx-2tx-mode-enable
|
||||
1, //one_rx_one_tx_mode_use_rx_num *** adi,1rx-1tx-mode-use-rx-num
|
||||
1, //one_rx_one_tx_mode_use_tx_num *** adi,1rx-1tx-mode-use-tx-num
|
||||
1, //frequency_division_duplex_mode_enable *** adi,frequency-division-duplex-mode-enable
|
||||
0, //frequency_division_duplex_independent_mode_enable *** adi,frequency-division-duplex-independent-mode-enable
|
||||
0, //tdd_use_dual_synth_mode_enable *** adi,tdd-use-dual-synth-mode-enable
|
||||
0, //tdd_skip_vco_cal_enable *** adi,tdd-skip-vco-cal-enable
|
||||
0, //tx_fastlock_delay_ns *** adi,tx-fastlock-delay-ns
|
||||
0, //rx_fastlock_delay_ns *** adi,rx-fastlock-delay-ns
|
||||
0, //rx_fastlock_pincontrol_enable *** adi,rx-fastlock-pincontrol-enable
|
||||
0, //tx_fastlock_pincontrol_enable *** adi,tx-fastlock-pincontrol-enable
|
||||
0, //external_rx_lo_enable *** adi,external-rx-lo-enable
|
||||
0, //external_tx_lo_enable *** adi,external-tx-lo-enable
|
||||
5, //dc_offset_tracking_update_event_mask *** adi,dc-offset-tracking-update-event-mask
|
||||
6, //dc_offset_attenuation_high_range *** adi,dc-offset-attenuation-high-range
|
||||
5, //dc_offset_attenuation_low_range *** adi,dc-offset-attenuation-low-range
|
||||
0x28, //dc_offset_count_high_range *** adi,dc-offset-count-high-range
|
||||
0x32, //dc_offset_count_low_range *** adi,dc-offset-count-low-range
|
||||
0, //split_gain_table_mode_enable *** adi,split-gain-table-mode-enable
|
||||
MAX_SYNTH_FREF, //trx_synthesizer_target_fref_overwrite_hz *** adi,trx-synthesizer-target-fref-overwrite-hz
|
||||
0, // qec_tracking_slow_mode_enable *** adi,qec-tracking-slow-mode-enable
|
||||
/* ENSM Control */
|
||||
0, //ensm_enable_pin_pulse_mode_enable *** adi,ensm-enable-pin-pulse-mode-enable
|
||||
0, //ensm_enable_txnrx_control_enable *** adi,ensm-enable-txnrx-control-enable
|
||||
/* LO Control */
|
||||
4125000000UL, //rx_synthesizer_frequency_hz *** adi,rx-synthesizer-frequency-hz
|
||||
4126000000UL, //tx_synthesizer_frequency_hz *** adi,tx-synthesizer-frequency-hz
|
||||
1, //tx_lo_powerdown_managed_enable *** adi,tx-lo-powerdown-managed-enable
|
||||
/* Rate & BW Control */
|
||||
{768000000, 192000000, 96000000, 48000000, 24000000, 24000000},// rx_path_clock_frequencies[6] *** adi,rx-path-clock-frequencies
|
||||
{768000000, 192000000, 96000000, 48000000, 24000000, 24000000},// tx_path_clock_frequencies[6] *** adi,tx-path-clock-frequencies
|
||||
18000000,//rf_rx_bandwidth_hz *** adi,rf-rx-bandwidth-hz
|
||||
18000000,//rf_tx_bandwidth_hz *** adi,rf-tx-bandwidth-hz
|
||||
/* RF Port Control */
|
||||
0, //rx_rf_port_input_select *** adi,rx-rf-port-input-select
|
||||
0, //tx_rf_port_input_select *** adi,tx-rf-port-input-select
|
||||
/* TX Attenuation Control */
|
||||
10000, //tx_attenuation_mdB *** adi,tx-attenuation-mdB
|
||||
0, //update_tx_gain_in_alert_enable *** adi,update-tx-gain-in-alert-enable
|
||||
/* Reference Clock Control */
|
||||
0, //xo_disable_use_ext_refclk_enable *** adi,xo-disable-use-ext-refclk-enable
|
||||
{8, 5920}, //dcxo_coarse_and_fine_tune[2] *** adi,dcxo-coarse-and-fine-tune
|
||||
CLKOUT_DISABLE, //clk_output_mode_select *** adi,clk-output-mode-select
|
||||
/* Gain Control */
|
||||
2, //gc_rx1_mode *** adi,gc-rx1-mode
|
||||
2, //gc_rx2_mode *** adi,gc-rx2-mode
|
||||
58, //gc_adc_large_overload_thresh *** adi,gc-adc-large-overload-thresh
|
||||
4, //gc_adc_ovr_sample_size *** adi,gc-adc-ovr-sample-size
|
||||
47, //gc_adc_small_overload_thresh *** adi,gc-adc-small-overload-thresh
|
||||
8192, //gc_dec_pow_measurement_duration *** adi,gc-dec-pow-measurement-duration
|
||||
0, //gc_dig_gain_enable *** adi,gc-dig-gain-enable
|
||||
800, //gc_lmt_overload_high_thresh *** adi,gc-lmt-overload-high-thresh
|
||||
704, //gc_lmt_overload_low_thresh *** adi,gc-lmt-overload-low-thresh
|
||||
24, //gc_low_power_thresh *** adi,gc-low-power-thresh
|
||||
15, //gc_max_dig_gain *** adi,gc-max-dig-gain
|
||||
0, //gc_use_rx_fir_out_for_dec_pwr_meas_enable *** adi,gc-use-rx-fir-out-for-dec-pwr-meas-enable
|
||||
/* Gain MGC Control */
|
||||
2, //mgc_dec_gain_step *** adi,mgc-dec-gain-step
|
||||
2, //mgc_inc_gain_step *** adi,mgc-inc-gain-step
|
||||
0, //mgc_rx1_ctrl_inp_enable *** adi,mgc-rx1-ctrl-inp-enable
|
||||
0, //mgc_rx2_ctrl_inp_enable *** adi,mgc-rx2-ctrl-inp-enable
|
||||
0, //mgc_split_table_ctrl_inp_gain_mode *** adi,mgc-split-table-ctrl-inp-gain-mode
|
||||
/* Gain AGC Control */
|
||||
10, //agc_adc_large_overload_exceed_counter *** adi,agc-adc-large-overload-exceed-counter
|
||||
2, //agc_adc_large_overload_inc_steps *** adi,agc-adc-large-overload-inc-steps
|
||||
0, //agc_adc_lmt_small_overload_prevent_gain_inc_enable *** adi,agc-adc-lmt-small-overload-prevent-gain-inc-enable
|
||||
10, //agc_adc_small_overload_exceed_counter *** adi,agc-adc-small-overload-exceed-counter
|
||||
4, //agc_dig_gain_step_size *** adi,agc-dig-gain-step-size
|
||||
3, //agc_dig_saturation_exceed_counter *** adi,agc-dig-saturation-exceed-counter
|
||||
1000, // agc_gain_update_interval_us *** adi,agc-gain-update-interval-us
|
||||
0, //agc_immed_gain_change_if_large_adc_overload_enable *** adi,agc-immed-gain-change-if-large-adc-overload-enable
|
||||
0, //agc_immed_gain_change_if_large_lmt_overload_enable *** adi,agc-immed-gain-change-if-large-lmt-overload-enable
|
||||
10, //agc_inner_thresh_high *** adi,agc-inner-thresh-high
|
||||
1, //agc_inner_thresh_high_dec_steps *** adi,agc-inner-thresh-high-dec-steps
|
||||
12, //agc_inner_thresh_low *** adi,agc-inner-thresh-low
|
||||
1, //agc_inner_thresh_low_inc_steps *** adi,agc-inner-thresh-low-inc-steps
|
||||
10, //agc_lmt_overload_large_exceed_counter *** adi,agc-lmt-overload-large-exceed-counter
|
||||
2, //agc_lmt_overload_large_inc_steps *** adi,agc-lmt-overload-large-inc-steps
|
||||
10, //agc_lmt_overload_small_exceed_counter *** adi,agc-lmt-overload-small-exceed-counter
|
||||
5, //agc_outer_thresh_high *** adi,agc-outer-thresh-high
|
||||
2, //agc_outer_thresh_high_dec_steps *** adi,agc-outer-thresh-high-dec-steps
|
||||
18, //agc_outer_thresh_low *** adi,agc-outer-thresh-low
|
||||
2, //agc_outer_thresh_low_inc_steps *** adi,agc-outer-thresh-low-inc-steps
|
||||
1, //agc_attack_delay_extra_margin_us; *** adi,agc-attack-delay-extra-margin-us
|
||||
0, //agc_sync_for_gain_counter_enable *** adi,agc-sync-for-gain-counter-enable
|
||||
/* Fast AGC */
|
||||
64, //fagc_dec_pow_measuremnt_duration *** adi,fagc-dec-pow-measurement-duration
|
||||
260, //fagc_state_wait_time_ns *** adi,fagc-state-wait-time-ns
|
||||
/* Fast AGC - Low Power */
|
||||
0, //fagc_allow_agc_gain_increase *** adi,fagc-allow-agc-gain-increase-enable
|
||||
5, //fagc_lp_thresh_increment_time *** adi,fagc-lp-thresh-increment-time
|
||||
1, //fagc_lp_thresh_increment_steps *** adi,fagc-lp-thresh-increment-steps
|
||||
/* Fast AGC - Lock Level (Lock Level is set via slow AGC inner high threshold) */
|
||||
1, //fagc_lock_level_lmt_gain_increase_en *** adi,fagc-lock-level-lmt-gain-increase-enable
|
||||
5, //fagc_lock_level_gain_increase_upper_limit *** adi,fagc-lock-level-gain-increase-upper-limit
|
||||
/* Fast AGC - Peak Detectors and Final Settling */
|
||||
1, //fagc_lpf_final_settling_steps *** adi,fagc-lpf-final-settling-steps
|
||||
1, //fagc_lmt_final_settling_steps *** adi,fagc-lmt-final-settling-steps
|
||||
3, //fagc_final_overrange_count *** adi,fagc-final-overrange-count
|
||||
/* Fast AGC - Final Power Test */
|
||||
0, //fagc_gain_increase_after_gain_lock_en *** adi,fagc-gain-increase-after-gain-lock-enable
|
||||
/* Fast AGC - Unlocking the Gain */
|
||||
0, //fagc_gain_index_type_after_exit_rx_mode *** adi,fagc-gain-index-type-after-exit-rx-mode
|
||||
1, //fagc_use_last_lock_level_for_set_gain_en *** adi,fagc-use-last-lock-level-for-set-gain-enable
|
||||
1, //fagc_rst_gla_stronger_sig_thresh_exceeded_en *** adi,fagc-rst-gla-stronger-sig-thresh-exceeded-enable
|
||||
5, //fagc_optimized_gain_offset *** adi,fagc-optimized-gain-offset
|
||||
10, //fagc_rst_gla_stronger_sig_thresh_above_ll *** adi,fagc-rst-gla-stronger-sig-thresh-above-ll
|
||||
1, //fagc_rst_gla_engergy_lost_sig_thresh_exceeded_en *** adi,fagc-rst-gla-engergy-lost-sig-thresh-exceeded-enable
|
||||
1, //fagc_rst_gla_engergy_lost_goto_optim_gain_en *** adi,fagc-rst-gla-engergy-lost-goto-optim-gain-enable
|
||||
10, //fagc_rst_gla_engergy_lost_sig_thresh_below_ll *** adi,fagc-rst-gla-engergy-lost-sig-thresh-below-ll
|
||||
8, //fagc_energy_lost_stronger_sig_gain_lock_exit_cnt *** adi,fagc-energy-lost-stronger-sig-gain-lock-exit-cnt
|
||||
1, //fagc_rst_gla_large_adc_overload_en *** adi,fagc-rst-gla-large-adc-overload-enable
|
||||
1, //fagc_rst_gla_large_lmt_overload_en *** adi,fagc-rst-gla-large-lmt-overload-enable
|
||||
0, //fagc_rst_gla_en_agc_pulled_high_en *** adi,fagc-rst-gla-en-agc-pulled-high-enable
|
||||
0, //fagc_rst_gla_if_en_agc_pulled_high_mode *** adi,fagc-rst-gla-if-en-agc-pulled-high-mode
|
||||
64, //fagc_power_measurement_duration_in_state5 *** adi,fagc-power-measurement-duration-in-state5
|
||||
2, //fagc_large_overload_inc_steps *** adi,fagc-adc-large-overload-inc-steps
|
||||
/* RSSI Control */
|
||||
1, //rssi_delay *** adi,rssi-delay
|
||||
1000, //rssi_duration *** adi,rssi-duration
|
||||
3, //rssi_restart_mode *** adi,rssi-restart-mode
|
||||
0, //rssi_unit_is_rx_samples_enable *** adi,rssi-unit-is-rx-samples-enable
|
||||
1, //rssi_wait *** adi,rssi-wait
|
||||
/* Aux ADC Control */
|
||||
256, //aux_adc_decimation *** adi,aux-adc-decimation
|
||||
48000000UL, //aux_adc_rate *** adi,aux-adc-rate
|
||||
/* AuxDAC Control */
|
||||
1, //aux_dac_manual_mode_enable *** adi,aux-dac-manual-mode-enable
|
||||
0, //aux_dac1_default_value_mV *** adi,aux-dac1-default-value-mV
|
||||
0, //aux_dac1_active_in_rx_enable *** adi,aux-dac1-active-in-rx-enable
|
||||
0, //aux_dac1_active_in_tx_enable *** adi,aux-dac1-active-in-tx-enable
|
||||
0, //aux_dac1_active_in_alert_enable *** adi,aux-dac1-active-in-alert-enable
|
||||
0, //aux_dac1_rx_delay_us *** adi,aux-dac1-rx-delay-us
|
||||
0, //aux_dac1_tx_delay_us *** adi,aux-dac1-tx-delay-us
|
||||
0, //aux_dac2_default_value_mV *** adi,aux-dac2-default-value-mV
|
||||
0, //aux_dac2_active_in_rx_enable *** adi,aux-dac2-active-in-rx-enable
|
||||
0, //aux_dac2_active_in_tx_enable *** adi,aux-dac2-active-in-tx-enable
|
||||
0, //aux_dac2_active_in_alert_enable *** adi,aux-dac2-active-in-alert-enable
|
||||
0, //aux_dac2_rx_delay_us *** adi,aux-dac2-rx-delay-us
|
||||
0, //aux_dac2_tx_delay_us *** adi,aux-dac2-tx-delay-us
|
||||
/* Temperature Sensor Control */
|
||||
256, //temp_sense_decimation *** adi,temp-sense-decimation
|
||||
1000, //temp_sense_measurement_interval_ms *** adi,temp-sense-measurement-interval-ms
|
||||
0xCE, //temp_sense_offset_signed *** adi,temp-sense-offset-signed
|
||||
1, //temp_sense_periodic_measurement_enable *** adi,temp-sense-periodic-measurement-enable
|
||||
/* Control Out Setup */
|
||||
0xFF, //ctrl_outs_enable_mask *** adi,ctrl-outs-enable-mask
|
||||
0, //ctrl_outs_index *** adi,ctrl-outs-index
|
||||
/* External LNA Control */
|
||||
0, //elna_settling_delay_ns *** adi,elna-settling-delay-ns
|
||||
0, //elna_gain_mdB *** adi,elna-gain-mdB
|
||||
0, //elna_bypass_loss_mdB *** adi,elna-bypass-loss-mdB
|
||||
0, //elna_rx1_gpo0_control_enable *** adi,elna-rx1-gpo0-control-enable
|
||||
0, //elna_rx2_gpo1_control_enable *** adi,elna-rx2-gpo1-control-enable
|
||||
0, //elna_gaintable_all_index_enable *** adi,elna-gaintable-all-index-enable
|
||||
/* Digital Interface Control */
|
||||
0, //digital_interface_tune_skip_mode *** adi,digital-interface-tune-skip-mode
|
||||
0, //digital_interface_tune_fir_disable *** adi,digital-interface-tune-fir-disable
|
||||
1, //pp_tx_swap_enable *** adi,pp-tx-swap-enable
|
||||
1, //pp_rx_swap_enable *** adi,pp-rx-swap-enable
|
||||
0, //tx_channel_swap_enable *** adi,tx-channel-swap-enable
|
||||
0, //rx_channel_swap_enable *** adi,rx-channel-swap-enable
|
||||
1, //rx_frame_pulse_mode_enable *** adi,rx-frame-pulse-mode-enable
|
||||
0, //two_t_two_r_timing_enable *** adi,2t2r-timing-enable
|
||||
0, //invert_data_bus_enable *** adi,invert-data-bus-enable
|
||||
0, //invert_data_clk_enable *** adi,invert-data-clk-enable
|
||||
0, //fdd_alt_word_order_enable *** adi,fdd-alt-word-order-enable
|
||||
0, //invert_rx_frame_enable *** adi,invert-rx-frame-enable
|
||||
0, //fdd_rx_rate_2tx_enable *** adi,fdd-rx-rate-2tx-enable
|
||||
0, //swap_ports_enable *** adi,swap-ports-enable
|
||||
0, //single_data_rate_enable *** adi,single-data-rate-enable
|
||||
1, //lvds_mode_enable *** adi,lvds-mode-enable
|
||||
0, //half_duplex_mode_enable *** adi,half-duplex-mode-enable
|
||||
0, //single_port_mode_enable *** adi,single-port-mode-enable
|
||||
0, //full_port_enable *** adi,full-port-enable
|
||||
0, //full_duplex_swap_bits_enable *** adi,full-duplex-swap-bits-enable
|
||||
0, //delay_rx_data *** adi,delay-rx-data
|
||||
0, //rx_data_clock_delay *** adi,rx-data-clock-delay
|
||||
4, //rx_data_delay *** adi,rx-data-delay
|
||||
7, //tx_fb_clock_delay *** adi,tx-fb-clock-delay
|
||||
0, //tx_data_delay *** adi,tx-data-delay
|
||||
150, //lvds_bias_mV *** adi,lvds-bias-mV
|
||||
1, //lvds_rx_onchip_termination_enable *** adi,lvds-rx-onchip-termination-enable
|
||||
0, //rx1rx2_phase_inversion_en *** adi,rx1-rx2-phase-inversion-enable
|
||||
0xFF, //lvds_invert1_control *** adi,lvds-invert1-control
|
||||
0x0F, //lvds_invert2_control *** adi,lvds-invert2-control
|
||||
/* GPO Control */
|
||||
0, //gpo_manual_mode_enable *** adi,gpo-manual-mode-enable
|
||||
0, //gpo_manual_mode_enable_mask *** adi,gpo-manual-mode-enable-mask
|
||||
0, //gpo0_inactive_state_high_enable *** adi,gpo0-inactive-state-high-enable
|
||||
0, //gpo1_inactive_state_high_enable *** adi,gpo1-inactive-state-high-enable
|
||||
0, //gpo2_inactive_state_high_enable *** adi,gpo2-inactive-state-high-enable
|
||||
0, //gpo3_inactive_state_high_enable *** adi,gpo3-inactive-state-high-enable
|
||||
0, //gpo0_slave_rx_enable *** adi,gpo0-slave-rx-enable
|
||||
0, //gpo0_slave_tx_enable *** adi,gpo0-slave-tx-enable
|
||||
0, //gpo1_slave_rx_enable *** adi,gpo1-slave-rx-enable
|
||||
0, //gpo1_slave_tx_enable *** adi,gpo1-slave-tx-enable
|
||||
0, //gpo2_slave_rx_enable *** adi,gpo2-slave-rx-enable
|
||||
0, //gpo2_slave_tx_enable *** adi,gpo2-slave-tx-enable
|
||||
0, //gpo3_slave_rx_enable *** adi,gpo3-slave-rx-enable
|
||||
0, //gpo3_slave_tx_enable *** adi,gpo3-slave-tx-enable
|
||||
0, //gpo0_rx_delay_us *** adi,gpo0-rx-delay-us
|
||||
0, //gpo0_tx_delay_us *** adi,gpo0-tx-delay-us
|
||||
0, //gpo1_rx_delay_us *** adi,gpo1-rx-delay-us
|
||||
0, //gpo1_tx_delay_us *** adi,gpo1-tx-delay-us
|
||||
0, //gpo2_rx_delay_us *** adi,gpo2-rx-delay-us
|
||||
0, //gpo2_tx_delay_us *** adi,gpo2-tx-delay-us
|
||||
0, //gpo3_rx_delay_us *** adi,gpo3-rx-delay-us
|
||||
0, //gpo3_tx_delay_us *** adi,gpo3-tx-delay-us
|
||||
/* Tx Monitor Control */
|
||||
37000, //low_high_gain_threshold_mdB *** adi,txmon-low-high-thresh
|
||||
0, //low_gain_dB *** adi,txmon-low-gain
|
||||
24, //high_gain_dB *** adi,txmon-high-gain
|
||||
0, //tx_mon_track_en *** adi,txmon-dc-tracking-enable
|
||||
0, //one_shot_mode_en *** adi,txmon-one-shot-mode-enable
|
||||
511, //tx_mon_delay *** adi,txmon-delay
|
||||
8192, //tx_mon_duration *** adi,txmon-duration
|
||||
2, //tx1_mon_front_end_gain *** adi,txmon-1-front-end-gain
|
||||
2, //tx2_mon_front_end_gain *** adi,txmon-2-front-end-gain
|
||||
48, //tx1_mon_lo_cm *** adi,txmon-1-lo-cm
|
||||
48, //tx2_mon_lo_cm *** adi,txmon-2-lo-cm
|
||||
/* GPIO definitions */
|
||||
/* Reset_b */
|
||||
{
|
||||
.number = AD9361_1_RESET_B,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
}, //gpio_resetb *** reset-gpios
|
||||
/* MCS Sync */
|
||||
{
|
||||
.number = -1,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
}, //gpio_sync *** sync-gpios
|
||||
/* Cal-SW1 */
|
||||
{
|
||||
.number = -1,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
}, //gpio_cal_sw1 *** cal-sw1-gpios
|
||||
/* Cal-SW2 */
|
||||
{
|
||||
.number = -1,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
}, //gpio_cal_sw2 *** cal-sw2-gpios
|
||||
|
||||
{
|
||||
.device_id = AD9361_SPI_DEVICE_ID,
|
||||
.mode = SPI_MODE_1,
|
||||
.chip_select = AD9361_1_SPI_CS,
|
||||
.platform_ops = &spi_eng_platform_ops,
|
||||
.extra = &spi_engine_param
|
||||
},
|
||||
|
||||
/* External LO clocks */
|
||||
NULL, //(*ad9361_rfpll_ext_recalc_rate)()
|
||||
NULL, //(*ad9361_rfpll_ext_round_rate)()
|
||||
NULL, //(*ad9361_rfpll_ext_set_rate)()
|
||||
};
|
||||
|
||||
AD9361_RXFIRConfig rx_fir_config = { // BPF PASSBAND 3/20 fs to 1/4 fs
|
||||
3, // rx
|
||||
0, // rx_gain
|
||||
1, // rx_dec
|
||||
{
|
||||
-4, -6, -37, 35, 186, 86, -284, -315,
|
||||
107, 219, -4, 271, 558, -307, -1182, -356,
|
||||
658, 157, 207, 1648, 790, -2525, -2553, 748,
|
||||
865, -476, 3737, 6560, -3583, -14731, -5278, 14819,
|
||||
14819, -5278, -14731, -3583, 6560, 3737, -476, 865,
|
||||
748, -2553, -2525, 790, 1648, 207, 157, 658,
|
||||
-356, -1182, -307, 558, 271, -4, 219, 107,
|
||||
-315, -284, 86, 186, 35, -37, -6, -4,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
}, // rx_coef[128]
|
||||
64, // rx_coef_size
|
||||
{0, 0, 0, 0, 0, 0}, //rx_path_clks[6]
|
||||
0 // rx_bandwidth
|
||||
};
|
||||
|
||||
AD9361_TXFIRConfig tx_fir_config = { // BPF PASSBAND 3/20 fs to 1/4 fs
|
||||
3, // tx
|
||||
-6, // tx_gain
|
||||
1, // tx_int
|
||||
{
|
||||
-4, -6, -37, 35, 186, 86, -284, -315,
|
||||
107, 219, -4, 271, 558, -307, -1182, -356,
|
||||
658, 157, 207, 1648, 790, -2525, -2553, 748,
|
||||
865, -476, 3737, 6560, -3583, -14731, -5278, 14819,
|
||||
14819, -5278, -14731, -3583, 6560, 3737, -476, 865,
|
||||
748, -2553, -2525, 790, 1648, 207, 157, 658,
|
||||
-356, -1182, -307, 558, 271, -4, 219, 107,
|
||||
-315, -284, 86, 186, 35, -37, -6, -4,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
}, // tx_coef[128]
|
||||
64, // tx_coef_size
|
||||
{0, 0, 0, 0, 0, 0}, // tx_path_clks[6]
|
||||
0 // tx_bandwidth
|
||||
};
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
#include "dev_profile.h"
|
||||
#include "../config/app_config.h"
|
||||
#include "../drivers/platform/xilinx_gpio.h"
|
||||
#include "../drivers/axi_core/spi_engine/spi_engine.h"
|
||||
#include "../drivers/frequency/ad9528/ad9528.h"
|
||||
|
||||
static struct spi_engine_init_param spi_engine_param = {
|
||||
.ref_clk_hz = AD9528_SPI_ENGINE_REF_CLK,
|
||||
.type = SPI_ENGINE,
|
||||
.spi_engine_baseaddr = AD9528_SPI_ENGINE_BASEADDR,
|
||||
.cs_delay = AD9528_SPI_ENGINE_CS_DELAY,
|
||||
.data_width = AD9528_SPI_ENGINE_DATA_WIDTH
|
||||
};
|
||||
|
||||
static struct xil_gpio_init_param xil_gpio_param = {
|
||||
.type = GPIO_PS,
|
||||
.device_id = AD9528_GPIO_DEVICE_ID
|
||||
};
|
||||
|
||||
static struct spi_init_param ad9528_spi_init = {
|
||||
.device_id = AD9528_SPI_DEVICE_ID,
|
||||
.max_speed_hz = AD9528_SPI_ENGINE_MAX_SPEED,
|
||||
.mode = SPI_MODE_0,
|
||||
.chip_select = AD9528_SPI_CS,
|
||||
.platform_ops = &spi_eng_platform_ops,
|
||||
.extra = &spi_engine_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param ad9528_gpio_resetb_init = {
|
||||
.number = AD9528_RESETB,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param ad9528_gpio_sysref_req_init = {
|
||||
.number = AD9528_SYSREF_REQ,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static ad9528pll1Settings_t clockPll1Settings = {
|
||||
.refA_Frequency_Hz = 50000000,
|
||||
.refA_Divider = 1,
|
||||
.refA_bufferCtrl = SINGLE_ENDED,
|
||||
.refB_Frequency_Hz = 0,
|
||||
.refB_Divider = 1,
|
||||
.refB_bufferCtrl = DISABLED,
|
||||
.vcxo_Frequency_Hz = 50000000,
|
||||
.vcxoBufferCtrl = SINGLE_ENDED,
|
||||
.nDivider = 1
|
||||
};
|
||||
|
||||
static ad9528pll2Settings_t clockPll2Settings = {
|
||||
.rfDivider = 4,
|
||||
.n2Divider = 20,
|
||||
.totalNdiv = 80
|
||||
};
|
||||
|
||||
/*******************************************************************
|
||||
* Output Distribution Settings
|
||||
* 9369CE02A uses the following clock outputs
|
||||
* OUT 1: FPGA REFCLK
|
||||
* OUT 3: FPGA SYSREF
|
||||
* OUT 12: DUT SYSREF
|
||||
* OUT 13: DUT REFCLK
|
||||
*******************************************************************
|
||||
*/
|
||||
static ad9528outputSettings_t clockOutputSettings = {
|
||||
.outPowerDown = 0xE001,
|
||||
.outSource = {
|
||||
AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV,
|
||||
AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV,
|
||||
AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV
|
||||
},
|
||||
.outBufferCtrl = {
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0
|
||||
},
|
||||
.outAnalogDelay = {
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0
|
||||
},
|
||||
.outDigitalDelay = {
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0
|
||||
},
|
||||
.outChannelDiv = {
|
||||
5,25,25,5,5,
|
||||
5,5,5,5,5,
|
||||
5,5,10,5
|
||||
},
|
||||
.outFrequency_Hz = {
|
||||
200e6, 40e6, 40e6, 200e6, 200e6,
|
||||
200e6, 200e6, 200e6, 200e6, 200e6,
|
||||
200e6, 200e6, 100e6, 200e6
|
||||
}
|
||||
};
|
||||
|
||||
static ad9528sysrefSettings_t clockSysrefSettings = {
|
||||
.sysrefRequestMethod = PIN,
|
||||
.sysrefSource = INTERNAL,
|
||||
.sysrefPinEdgeMode = LEVEL_ACTIVE_HIGH,
|
||||
.sysrefPinBufferMode = DISABLED,
|
||||
.sysrefPatternMode = CONTINUOUS,
|
||||
.sysrefNshotMode = FOUR_PULSES,
|
||||
.sysrefDivide = 256
|
||||
};
|
||||
|
||||
static ad9528spiSettings_t clockSpiSettings = {
|
||||
.chipSelectIndex = AD9528_SPI_CS, //chip select Index, not used
|
||||
.writeBitPolarity = 0, //Write bit polarity
|
||||
.longInstructionWord = 1, //16bit instruction word
|
||||
.MSBFirst = 1, //MSB first
|
||||
.CPHA = 0, //Clock phase
|
||||
.CPOL = 0, //Clock polarity
|
||||
.enSpiStreaming = 0, //uint8_t enSpiStreaming;
|
||||
.autoIncAddrUp = 1, //uint8_t autoIncAddrUp;
|
||||
.fourWireMode = 1 //uint8_t fourWireMode;
|
||||
};
|
||||
|
||||
ad9528Init_t ad9528_default_init_param = {
|
||||
/* SPI */
|
||||
.spi_init = &ad9528_spi_init,
|
||||
.gpio_init_resetb = &ad9528_gpio_resetb_init,
|
||||
.gpio_init_sysref_req = &ad9528_gpio_sysref_req_init,
|
||||
.spiSettings = &clockSpiSettings,
|
||||
.pll1Settings = &clockPll1Settings,
|
||||
.pll2Settings = &clockPll2Settings,
|
||||
.outputSettings = &clockOutputSettings,
|
||||
.sysrefSettings = &clockSysrefSettings
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
#include "dev_profile.h"
|
||||
#include "spi.h"
|
||||
#include "../config/app_config.h"
|
||||
#include "../drivers/adc/ad9653/ad9653.h"
|
||||
#include "../drivers/axi_core/spi_engine/spi_engine.h"
|
||||
#include "../drivers/platform/xilinx_gpio.h"
|
||||
|
||||
static struct spi_engine_init_param spi_engine_param = {
|
||||
.ref_clk_hz = AD9653_SPI_ENGINE_REF_CLK,
|
||||
.type = SPI_ENGINE,
|
||||
.spi_engine_baseaddr = AD9653_SPI_ENGINE_BASEADDR,
|
||||
.cs_delay = AD9653_SPI_ENGINE_CS_DELAY,
|
||||
.data_width = AD9653_SPI_ENGINE_DATA_WIDTH
|
||||
};
|
||||
|
||||
static struct xil_gpio_init_param xil_gpio_param = {
|
||||
.type = GPIO_PS,
|
||||
.device_id = AD9653_GPIO_DEVICE_ID
|
||||
};
|
||||
|
||||
static struct spi_init_param ad9653_spi_init = {
|
||||
.device_id = AD9653_SPI_DEVICE_ID,
|
||||
.max_speed_hz = AD9653_SPI_ENGINE_MAX_SPEED,
|
||||
.mode = SPI_MODE_4,
|
||||
.chip_select = AD9653_SPI_CS,
|
||||
.platform_ops = &spi_eng_platform_ops,
|
||||
.extra = &spi_engine_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param ad9653_gpio_resetb_init = {
|
||||
.number = AD9653_POWR_DOWN,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
struct ad9653_init_param ad9653_default_init_param = {
|
||||
/* SPI */
|
||||
.spi_init = &ad9653_spi_init,
|
||||
.gpio_pdwn = &ad9653_gpio_resetb_init
|
||||
};
|
||||
|
||||
const uint32_t ad9653_default_config_len = 36;
|
||||
const struct ad9653_config ad9653_default_config[] = {
|
||||
// configuration
|
||||
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
#include "dev_profile.h"
|
||||
#include "spi.h"
|
||||
#include "../config/app_config.h"
|
||||
#include "../drivers/adc/ad9694/ad9694.h"
|
||||
#include "../drivers/axi_core/spi_engine/spi_engine.h"
|
||||
#include "../drivers/platform/xilinx_gpio.h"
|
||||
|
||||
static struct spi_engine_init_param spi_engine_param = {
|
||||
.ref_clk_hz = AD9694_SPI_ENGINE_REF_CLK,
|
||||
.type = SPI_ENGINE,
|
||||
.spi_engine_baseaddr = AD9694_SPI_ENGINE_BASEADDR,
|
||||
.cs_delay = AD9694_SPI_ENGINE_CS_DELAY,
|
||||
.data_width = AD9694_SPI_ENGINE_DATA_WIDTH
|
||||
};
|
||||
|
||||
//static struct xil_gpio_init_param xil_gpio_param = {
|
||||
// .type = GPIO_PS,
|
||||
// .device_id = AD9694_GPIO_DEVICE_ID
|
||||
//};
|
||||
|
||||
static struct spi_init_param ad9694_spi_init = {
|
||||
.device_id = AD9694_SPI_DEVICE_ID,
|
||||
.max_speed_hz = AD9694_SPI_ENGINE_MAX_SPEED,
|
||||
.mode = SPI_MODE_4,
|
||||
.chip_select = AD9694_SPI_CS,
|
||||
.platform_ops = &spi_eng_platform_ops,
|
||||
.extra = &spi_engine_param
|
||||
};
|
||||
|
||||
struct ad9694_init_param ad9694_default_init_param = {
|
||||
/* SPI */
|
||||
.spi_init = &ad9694_spi_init
|
||||
};
|
||||
|
||||
const uint32_t ad9694_default_config_len = 36;
|
||||
const struct ad9694_config ad9694_default_config[] = {
|
||||
// reset
|
||||
{0x0000, 0x81},
|
||||
{0x1228, 0x4F}, // JESD204B start-up circuit reset
|
||||
{0x1228, 0x0F}, // JESD204B start-up normal operation
|
||||
{0x1222, 0x04}, // PLL calibration
|
||||
{0x1222, 0x00}, // PLL normal operation
|
||||
{0x1262, 0x08}, // PLL loss of lock control - Clear loss of lock
|
||||
{0x1262, 0x00}, // PLL loss of lock control - Normal operation
|
||||
|
||||
// system clock
|
||||
{0x0108, 0x00}, // Clock divider = 1 -> device clock = 368.64MHz
|
||||
{0x0201, 0x00}, // Chip decimation ration = 1 -> full sample rate
|
||||
|
||||
// channel configuration
|
||||
{0x0009, 0x03}, // ADC Pair AB & CD receive all spi command
|
||||
{0x0571, 0x15}, // JESD204B map JTX Link Control 1
|
||||
{0x056E, 0x00}, // JESD204B map PLL control, lane rate 6.75~13.5Gbps, actual = 7.3728Gbps
|
||||
{0x0570, 0x49}, // JESD204B map JTX quick config: L=2 M=2 F=2
|
||||
{0x058B, 0x01}, // JESD204B map JTX SCR L config: scrambler disabled, L=2
|
||||
{0x0590, 0x2F}, // JESD204B map JTX Subclass & NP config: subclass 1, N' = 16
|
||||
{0x058D, 0x1F}, // JESD204B map JTX K config: K = 32
|
||||
{0x058F, 0x2D}, // JESD204B map JTX N config: CS = 0, N = 14
|
||||
{0x0571, 0x14}, // JESD204B map JTX Link Control 1
|
||||
{0x05B0, 0x00}, // SERDOUTx0, SERDOUTx1 power on
|
||||
{0x0120, 0x0A}, // SYSREF COntrol: continuous mode, captured on falling edge
|
||||
|
||||
// fast detect control
|
||||
{0x0040, 0x00}, // FD_B/FD_D, FD_A/FD_C function as Fast Detect B/D, A/C output
|
||||
{0x0245, 0x01}, // Fine fast detect enabled
|
||||
{0x0247, 0xFE}, // Channel map fast detect upper threshold LSB
|
||||
{0x0248, 0x1F}, // Channel map fast detect upper threshold MSB, -> 8190
|
||||
{0x0249, 0xA4}, // Channel map fast detect lower threshold LSB
|
||||
{0x024A, 0x1F}, // Channel map fast detect lower threshold MSB, -> 8100
|
||||
{0x024B, 0x80}, // Channel map fast detect dwell time LSB
|
||||
{0x024C, 0x00} // Channel map fast detect dwell time MSB, -> 128
|
||||
};
|
||||
@@ -3,11 +3,55 @@
|
||||
|
||||
#include "irq.h"
|
||||
#include "error.h"
|
||||
#include "../drivers/frequency/hmc7044/hmc7044.h"
|
||||
#include "../drivers/frequency/ad9528/ad9528.h"
|
||||
#include "../drivers/frequency/lmk04828/lmk04828.h"
|
||||
#include "../drivers/frequency/lmx2594/lmx2594.h"
|
||||
#include "../drivers/rf-transceiver/ad9361_reg/ad9361_reg.h"
|
||||
#include "../drivers/rf-transceiver/ad9361/ad9361_api.h"
|
||||
#include "../drivers/adc/ad9694/ad9694.h"
|
||||
#include "../drivers/adc/ad9653/ad9653.h"
|
||||
#include "../config/app_config.h"
|
||||
|
||||
// device parameters
|
||||
extern struct irq_init_param intc_init_param;
|
||||
extern struct timer_init_param scutimer_init_param;
|
||||
extern struct global_timer_init_param globaltimer_init_param;
|
||||
extern struct timer_init_param apptimer_init_param;
|
||||
|
||||
// HMC7044
|
||||
extern struct hmc7044_init_param hmc7044_default_init_param;
|
||||
|
||||
// AD9528
|
||||
extern ad9528Init_t ad9528_default_init_param;
|
||||
|
||||
// LMK04828
|
||||
extern struct lmk04828_init_param lmk04828_default_init_param;
|
||||
extern const struct lmk04828_config lmk04828_default_config[];
|
||||
extern const uint32_t lmk04828_default_config_len;
|
||||
|
||||
// LMX2594
|
||||
extern struct lmx2594_init_param lmx2594_adc_init_param;
|
||||
extern struct lmx2594_init_param lmx2594_dac_init_param;
|
||||
extern const struct lmx2594_config lmx2594_default_config[];
|
||||
extern const uint32_t lmx2594_default_config_len;
|
||||
|
||||
// AD9361
|
||||
extern AD9361_InitParam ad9361_default_init_param;
|
||||
extern AD9361_RXFIRConfig rx_fir_config;
|
||||
extern AD9361_TXFIRConfig tx_fir_config;
|
||||
extern struct ad9361_reg_init_param ad9361_1_reg_default_init_param;
|
||||
extern struct ad9361_reg_init_param ad9361_2_reg_default_init_param;
|
||||
uint32_t ad9361_1_reg_config(struct ad9361_reg_dev *dev);
|
||||
uint32_t ad9361_2_reg_config(struct ad9361_reg_dev *dev);
|
||||
|
||||
// AD9653
|
||||
extern struct ad9653_init_param ad9653_default_init_param;
|
||||
extern const struct ad9653_config ad9653_default_config[];
|
||||
extern const uint32_t ad9653_default_config_len;
|
||||
|
||||
// AD9694
|
||||
extern struct ad9694_init_param ad9694_default_init_param;
|
||||
extern const struct ad9694_config ad9694_default_config[];
|
||||
extern const uint32_t ad9694_default_config_len;
|
||||
|
||||
|
||||
#endif /* SRC_DEV_PROFILE_H_ */
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#include "dev_profile.h"
|
||||
#include "global_timer.h"
|
||||
#include "../config/app_config.h"
|
||||
|
||||
struct global_timer_init_param globaltimer_init_param = {
|
||||
.base_addr = GLOBAL_TIMER_BASEADDR,
|
||||
.id = GLOBAL_TIMER_DEVICE_ID,
|
||||
.freq_hz = GLOBAL_TIMER_CLK_HZ,
|
||||
.load_value = 0x0000000000000000
|
||||
};
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
#include "dev_profile.h"
|
||||
#include "../config/app_config.h"
|
||||
#include "../drivers/platform/xilinx_gpio.h"
|
||||
#include "../drivers/axi_core/spi_engine/spi_engine.h"
|
||||
#include "../drivers/frequency/hmc7044/hmc7044.h"
|
||||
|
||||
|
||||
static struct spi_engine_init_param spi_engine_param = {
|
||||
.ref_clk_hz = HMC7044_SPI_ENGINE_REF_CLK,
|
||||
.type = SPI_ENGINE,
|
||||
.spi_engine_baseaddr = HMC7044_SPI_ENGINE_BASEADDR,
|
||||
.cs_delay = HMC7044_SPI_ENGINE_CS_DELAY,
|
||||
.data_width = HMC7044_SPI_ENGINE_DATA_WIDTH
|
||||
};
|
||||
|
||||
//static struct xil_gpio_init_param xil_gpio_param = {
|
||||
// .type = GPIO_PS,
|
||||
// .device_id = AD9361_GPIO_DEVICE_ID
|
||||
//};
|
||||
|
||||
// hmc7044 spi settings
|
||||
static struct spi_init_param hmc7044_spi_init_param = {
|
||||
.device_id = HMC7044_SPI_DEVICE_ID,
|
||||
.max_speed_hz = HMC7044_SPI_ENGINE_MAX_SPEED,
|
||||
.mode = SPI_MODE_4,
|
||||
.chip_select = HMC7044_SPI_CS_HMC7044,
|
||||
.platform_ops = &spi_eng_platform_ops,
|
||||
.extra = &spi_engine_param
|
||||
};
|
||||
|
||||
// hmc7044 channel specifications
|
||||
struct hmc7044_chan_spec hmc7044_chan_spec[4] = {
|
||||
/* AD9361_XTAL */
|
||||
{
|
||||
.disable = 0,
|
||||
.num = 3,
|
||||
.divider = 100,
|
||||
.coarse_delay = 0,
|
||||
.fine_delay = 0,
|
||||
.high_performance_mode_dis = true,
|
||||
.start_up_mode_dynamic_enable = false,
|
||||
.dynamic_driver_enable = false,
|
||||
.output_control0_rb4_enable = true,
|
||||
.force_mute_enable = false,
|
||||
.driver_mode = CML,
|
||||
.driver_impedance = INTERNAL_100OHM_PER_PIN,
|
||||
.out_mux_mode = CHANNEL_DIV
|
||||
},
|
||||
/* FPGA_DAC_LOGIC_CLK */
|
||||
{
|
||||
.disable = 0,
|
||||
.num = 4,
|
||||
.divider = 10,
|
||||
.coarse_delay = 0,
|
||||
.fine_delay = 0,
|
||||
.high_performance_mode_dis = true,
|
||||
.start_up_mode_dynamic_enable = false,
|
||||
.dynamic_driver_enable = false,
|
||||
.output_control0_rb4_enable = true,
|
||||
.force_mute_enable = false,
|
||||
.driver_mode = CML,
|
||||
.driver_impedance = INTERNAL_100OHM_PER_PIN,
|
||||
.out_mux_mode = CHANNEL_DIV
|
||||
},
|
||||
/* B_AD9361_XTAL */
|
||||
{
|
||||
.disable = 0,
|
||||
.num = 12,
|
||||
.divider = 100,
|
||||
.coarse_delay = 0,
|
||||
.fine_delay = 0,
|
||||
.high_performance_mode_dis = false,
|
||||
.start_up_mode_dynamic_enable = false,
|
||||
.dynamic_driver_enable = false,
|
||||
.output_control0_rb4_enable = true,
|
||||
.force_mute_enable = false,
|
||||
.driver_mode = CML,
|
||||
.driver_impedance = INTERNAL_100OHM_PER_PIN,
|
||||
.out_mux_mode = CHANNEL_DIV
|
||||
},
|
||||
/* AD9361_RX_EXT_LO */
|
||||
{
|
||||
.disable = 0,
|
||||
.num = 13,
|
||||
.divider = 10,
|
||||
.coarse_delay = 0,
|
||||
.fine_delay = 0,
|
||||
.high_performance_mode_dis = false,
|
||||
.start_up_mode_dynamic_enable = false,
|
||||
.dynamic_driver_enable = false,
|
||||
.output_control0_rb4_enable = true,
|
||||
.force_mute_enable = false,
|
||||
.driver_mode = CML,
|
||||
.driver_impedance = INTERNAL_100OHM_PER_PIN,
|
||||
.out_mux_mode = CHANNEL_DIV
|
||||
},
|
||||
};
|
||||
|
||||
// hmc7044 default configurations
|
||||
struct hmc7044_init_param hmc7044_default_init_param = {
|
||||
.spi_init = &hmc7044_spi_init_param,
|
||||
.clkin_freq = {0, 100000000, 0, 0},
|
||||
.vcxo_freq = 100000000,
|
||||
.pll2_freq = 2500000000,
|
||||
.pll1_loop_bw = 200,
|
||||
.sysref_timer_div = 1536,
|
||||
.in_buf_mode = {
|
||||
BUFFER_DISABLE,
|
||||
ENABLE_AC_COUPLE | ENABLE_INTERNAL_TERM | BUFFER_ENABLE,
|
||||
BUFFER_DISABLE,
|
||||
BUFFER_DISABLE,
|
||||
ENABLE_AC_COUPLE | ENABLE_INTERNAL_TERM | BUFFER_ENABLE
|
||||
},
|
||||
.gpi_ctrl = {
|
||||
GPI_DISABLE,
|
||||
GPI_DISABLE,
|
||||
CHIP_SLEEP_MODE,
|
||||
PULSE_GEN_REQUSET
|
||||
},
|
||||
.gpo_ctrl = {
|
||||
PLL1_LOCK_DETECT | GPO_CMOS_MODE,
|
||||
PLL2_LOCK_DETECT | GPO_CMOS_MODE,
|
||||
GPO_DISABLE,
|
||||
GPO_DISABLE
|
||||
},
|
||||
.num_channels = 4,
|
||||
.pll1_ref_prio_ctrl = 0xE4,
|
||||
.sync_pin_mode = SYNC_MULTICHIP,
|
||||
.high_performance_mode_clock_dist_en = false,
|
||||
.pulse_gen_mode = PULSE_ONE,
|
||||
.channels = hmc7044_chan_spec
|
||||
};
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "irq.h"
|
||||
#include "../config/app_config.h"
|
||||
#include "../drivers/platform/xilinx_irq.h"
|
||||
|
||||
struct xil_irq_init_param xil_intc_init_param = {
|
||||
.type = IRQ_PS
|
||||
};
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
#include "dev_profile.h"
|
||||
#include "spi.h"
|
||||
#include "../config/app_config.h"
|
||||
#include "../drivers/frequency/lmk04828/lmk04828.h"
|
||||
#include "../drivers/axi_core/spi_engine/spi_engine.h"
|
||||
#include "../drivers/platform/xilinx_gpio.h"
|
||||
|
||||
static struct spi_engine_init_param spi_engine_param = {
|
||||
.ref_clk_hz = LMK04828_SPI_ENGINE_REF_CLK,
|
||||
.type = SPI_ENGINE,
|
||||
.spi_engine_baseaddr = LMK04828_SPI_ENGINE_BASEADDR,
|
||||
.cs_delay = LMK04828_SPI_ENGINE_CS_DELAY,
|
||||
.data_width = LMK04828_SPI_ENGINE_DATA_WIDTH
|
||||
};
|
||||
|
||||
//static struct xil_gpio_init_param xil_gpio_param = {
|
||||
// .type = GPIO_PS,
|
||||
// .device_id = LMK04828_GPIO_DEVICE_ID
|
||||
//};
|
||||
|
||||
static struct spi_init_param lmk04828_spi_init = {
|
||||
.device_id = LMK04828_SPI_DEVICE_ID,
|
||||
.max_speed_hz = LMK04828_SPI_ENGINE_MAX_SPEED,
|
||||
.mode = SPI_MODE_0,
|
||||
.chip_select = LMK04828_SPI_CS,
|
||||
.platform_ops = &spi_eng_platform_ops,
|
||||
.extra = &spi_engine_param
|
||||
};
|
||||
|
||||
struct lmk04828_init_param lmk04828_default_init_param = {
|
||||
/* SPI */
|
||||
.spi_init = &lmk04828_spi_init
|
||||
};
|
||||
|
||||
const uint32_t lmk04828_default_config_len = 137;
|
||||
const struct lmk04828_config lmk04828_default_config[] = {
|
||||
// 192MHz
|
||||
{0x0000, 0x90}, // [7] reset; [4] 3-wire mode disabled
|
||||
{0x0000, 0x10}, // [7] normal operation; [4] 3-wire mode disabled
|
||||
{0x0002, 0x00}, // [0] normal operation
|
||||
{0x0003, 0x06}, // [7-0] product device type, read only, default: 6
|
||||
{0x0004, 0xD0}, // [7-0] msb of product identifier, read only, default: 208
|
||||
{0x0005, 0x5B}, // [7-0] lsb of product identifier, read only, default: 91
|
||||
{0x0006, 0x00}, // [7-0] ic version identifier, read only, default: 32
|
||||
{0x000C, 0x51}, // [7-0] msb of vendor identifier, read only, default: 81
|
||||
{0x000D, 0x04}, // [7-0] lsb of vendor identifier, read only, default: 4
|
||||
// device clock 0
|
||||
{0x0100, 0x10}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0101, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x0102, 0x55},
|
||||
{0x0103, 0x01}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x0104, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x0105, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x0106, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x0107, 0x11}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 2
|
||||
{0x0108, 0x10}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0109, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x010A, 0x55},
|
||||
{0x010B, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x010C, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x010D, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x010E, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x010F, 0x10}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 4
|
||||
{0x0110, 0x10}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0111, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x0112, 0x55},
|
||||
{0x0113, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x0114, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x0115, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x0116, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x0117, 0x11}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 6
|
||||
{0x0118, 0x10}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0119, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x011A, 0x55},
|
||||
{0x011B, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x011C, 0x02}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x011D, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x011E, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x011F, 0x55}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 8
|
||||
{0x0120, 0x10}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0121, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x0122, 0x55},
|
||||
{0x0123, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x0124, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x0125, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x0126, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x0127, 0x55}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 10
|
||||
{0x0128, 0x10}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0129, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x012A, 0x55},
|
||||
{0x012B, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x012C, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x012D, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x012E, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x012F, 0x51}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 12
|
||||
{0x0130, 0x10}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0131, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x0132, 0x55},
|
||||
{0x0133, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x0134, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x0135, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x0136, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x0137, 0x55}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// clock distribution source
|
||||
{0x0138, 0x20}, // [6-5] VCO mux; [4] OSCout mux; [3:0] OSCout format
|
||||
{0x0139, 0x03}, // [2] SYSREF output mux; [1-0] SYSREF source
|
||||
{0x013A, 0x0C}, // [4-0] SYSREF divider [12:8]
|
||||
{0x013B, 0x00}, // [7-0] SYSREF divider [7:0]
|
||||
{0x013C, 0x00}, // [4-0] SYSREF DDLY [12:8]
|
||||
{0x013D, 0x08}, // [7-0] SYSREF DDLY [7:0]
|
||||
{0x013E, 0x03}, // [1-0] SYSREF pulse count
|
||||
{0x013F, 0x00}, // [4] pll2 mux; [3] pll1 mux; [2-1] feedback mux; [0] feedback mux enable
|
||||
{0x0140, 0x0B}, // power-down control: [7] pll1; [6] vco_ldo; [5] vco; [4] OSCin; [3] individual SYSREF; [2] SYSREF; [1] SYSREF DDLY; [0] SYSREF pluse generator
|
||||
{0x0141, 0x00}, // dynamic DDLY control
|
||||
{0x0142, 0x00}, // dynamic DDLY step control
|
||||
{0x0143, 0x10},
|
||||
{0x0144, 0xFF},
|
||||
{0x0145, 0x7F},
|
||||
{0x0146, 0x12},
|
||||
{0x0147, 0x1A},
|
||||
{0x0148, 0x03},
|
||||
{0x0149, 0x05},
|
||||
{0x014A, 0x1B},
|
||||
{0x014B, 0x16},
|
||||
{0x014C, 0x00},
|
||||
{0x014D, 0x00},
|
||||
{0x014E, 0xC0},
|
||||
{0x014F, 0x7F},
|
||||
{0x0150, 0x03},
|
||||
{0x0151, 0x02},
|
||||
{0x0152, 0x00},
|
||||
{0x0153, 0x00},
|
||||
{0x0154, 0x78},
|
||||
{0x0155, 0x00},
|
||||
{0x0156, 0x7D},
|
||||
{0x0157, 0x00},
|
||||
{0x0158, 0x96},
|
||||
{0x0159, 0x06},
|
||||
{0x015A, 0x00},
|
||||
{0x015B, 0xD4},
|
||||
{0x015C, 0x20},
|
||||
{0x015D, 0x00},
|
||||
{0x015E, 0x00},
|
||||
{0x015F, 0x3B},
|
||||
{0x0160, 0x00},
|
||||
{0x0161, 0x02},
|
||||
{0x0162, 0x44},
|
||||
{0x0163, 0x00},
|
||||
{0x0164, 0x00},
|
||||
{0x0165, 0x0C},
|
||||
{0x0171, 0xAA},
|
||||
{0x0172, 0x02},
|
||||
{0x017C, 0x15},
|
||||
{0x017D, 0x33},
|
||||
{0x0166, 0x00},
|
||||
{0x0167, 0x00},
|
||||
{0x0168, 0x19},
|
||||
{0x0169, 0x59},
|
||||
{0x016A, 0x20},
|
||||
{0x016B, 0x00},
|
||||
{0x016C, 0x00},
|
||||
{0x016D, 0x00},
|
||||
{0x016E, 0x1B},
|
||||
{0x0173, 0x00},
|
||||
{0x0182, 0x00},
|
||||
{0x0183, 0x00},
|
||||
{0x0184, 0x00},
|
||||
{0x0185, 0x00},
|
||||
{0x0188, 0x00},
|
||||
{0x0189, 0x00},
|
||||
{0x018A, 0x00},
|
||||
{0x018B, 0x00},
|
||||
{0x1FFD, 0x00},
|
||||
{0x1FFE, 0x00},
|
||||
{0x1FFF, 0x53}
|
||||
};
|
||||
@@ -0,0 +1,181 @@
|
||||
#include "dev_profile.h"
|
||||
#include "spi.h"
|
||||
#include "../config/app_config.h"
|
||||
#include "../drivers/frequency/lmx2594/lmx2594.h"
|
||||
#include "../drivers/axi_core/spi_engine/spi_engine.h"
|
||||
#include "../drivers/platform/xilinx_gpio.h"
|
||||
|
||||
static struct spi_engine_init_param spi_engine_param = {
|
||||
.ref_clk_hz = AD9653_SPI_ENGINE_REF_CLK,
|
||||
.type = SPI_ENGINE,
|
||||
.spi_engine_baseaddr = AD9653_SPI_ENGINE_BASEADDR,
|
||||
.cs_delay = AD9653_SPI_ENGINE_CS_DELAY,
|
||||
.data_width = AD9653_SPI_ENGINE_DATA_WIDTH
|
||||
};
|
||||
|
||||
//static struct xil_gpio_init_param xil_gpio_param = {
|
||||
// .type = GPIO_PS,
|
||||
// .device_id = AD9653_GPIO_DEVICE_ID
|
||||
//};
|
||||
|
||||
static struct spi_init_param lmx2594_adc_spi_init = {
|
||||
.device_id = LMX2594_ADC_SPI_DEVICE_ID,
|
||||
.max_speed_hz = LMX2594_ADC_SPI_ENGINE_MAX_SPEED,
|
||||
.mode = SPI_MODE_0,
|
||||
.chip_select = LMX2594_ADC_SPI_CS,
|
||||
.platform_ops = &spi_eng_platform_ops,
|
||||
.extra = &spi_engine_param
|
||||
};
|
||||
|
||||
static struct spi_init_param lmx2594_dac_spi_init = {
|
||||
.device_id = LMX2594_DAC_SPI_DEVICE_ID,
|
||||
.max_speed_hz = LMX2594_DAC_SPI_ENGINE_MAX_SPEED,
|
||||
.mode = SPI_MODE_0,
|
||||
.chip_select = LMX2594_DAC_SPI_CS,
|
||||
.platform_ops = &spi_eng_platform_ops,
|
||||
.extra = &spi_engine_param
|
||||
};
|
||||
|
||||
struct lmx2594_init_param lmx2594_adc_init_param = {
|
||||
/* SPI */
|
||||
.spi_init = &lmx2594_adc_spi_init
|
||||
};
|
||||
|
||||
struct lmx2594_init_param lmx2594_dac_init_param = {
|
||||
/* SPI */
|
||||
.spi_init = &lmx2594_dac_spi_init
|
||||
};
|
||||
|
||||
const uint32_t lmx2594_default_config_len = 110;
|
||||
const struct lmx2594_config lmx2594_default_config[] = {
|
||||
// 0 ~ 78: General configuration
|
||||
// 79 ~ 106: Ramping configuration
|
||||
// 107 ~ 112: Readback registers
|
||||
|
||||
// Recommended Initial Power-Up Sequence
|
||||
// For the most reliable programming, TI recommends this procedure::
|
||||
// 1. Apply power to device.
|
||||
// 2. Program RESET = 1 to reset registers.
|
||||
// 3. Program RESET = 0 to remove reset.
|
||||
// 4. Program registers as shown in the register map in REVERSE order from highest to lowest.
|
||||
// 5. Wait 10 ms.
|
||||
// 6. Program register R0 one additional time with FCAL_EN = 1 to ensure that the VCO calibration runs from a stable state.
|
||||
|
||||
// Reset
|
||||
{ 0, 0x0002},
|
||||
|
||||
// Remove Reset
|
||||
{ 0, 0x0000},
|
||||
|
||||
// Reverse order programming
|
||||
{106, 0x0000},
|
||||
{105, 0x0021},
|
||||
{104, 0x0000},
|
||||
{103, 0xD555},
|
||||
{102, 0x3F97},
|
||||
{101, 0x0011},
|
||||
{100, 0x0000},
|
||||
{ 99, 0x2AAB},
|
||||
{ 98, 0x01A0},
|
||||
{ 97, 0x0888},
|
||||
{ 96, 0x0000},
|
||||
{ 95, 0x0000}, // fixed
|
||||
{ 94, 0x0000}, // fixed
|
||||
{ 93, 0x0000}, // fixed
|
||||
{ 92, 0x0000}, // fixed
|
||||
{ 91, 0x0000}, // fixed
|
||||
{ 90, 0x0000}, // fixed
|
||||
{ 89, 0x0000}, // fixed
|
||||
{ 88, 0x0000}, // fixed
|
||||
{ 87, 0x0000}, // fixed
|
||||
{ 86, 0x5879},
|
||||
{ 85, 0xEC58},
|
||||
{ 84, 0x0001},
|
||||
{ 83, 0x54C9},
|
||||
{ 82, 0x2961},
|
||||
{ 81, 0x0000},
|
||||
{ 80, 0x4000},
|
||||
{ 79, 0x001F},
|
||||
{ 78, 0x0003}, // [8:1] VCO_CAPCTRL_STRT
|
||||
{ 77, 0x0000}, // fixed
|
||||
{ 76, 0x000C}, // fixed
|
||||
{ 75, 0x0800}, // [10:6] CHDIV
|
||||
{ 74, 0x0000}, // [11:6] JESD_DAC4_CTRL; [5:0] JESD_DAC3_CTRL
|
||||
{ 73, 0x003F}, // [11:6] JESD_DAC2_CTRL; [5:0] JESD_DAC1_CTRL
|
||||
{ 72, 0x0001}, // [10:0] SYSREF_DIV
|
||||
{ 71, 0x0081}, // [7:5] SYSREF_DIV_PRE; [4] SYSREF_PULSE; [3] SYSREF_EN; [2] SYSREF_REPEAT
|
||||
{ 70, 0xC350}, // [15:0] MASH_RST_COUNT
|
||||
{ 69, 0x0000}, // [15:0] MASH_RST_COUNT
|
||||
{ 68, 0x03E8}, // fixed
|
||||
{ 67, 0x0000}, // fixed
|
||||
{ 66, 0x01F4}, // fixed
|
||||
{ 65, 0x0000}, // fixed
|
||||
{ 64, 0x1388}, // fixed
|
||||
{ 63, 0x0000}, // fixed
|
||||
{ 62, 0x0322}, // fixed
|
||||
{ 61, 0x00A8}, // fixed
|
||||
{ 60, 0x0000}, // [15:0] LD_DLY
|
||||
{ 59, 0x0001}, // [0] LD_TYPE
|
||||
{ 58, 0x9001}, // [15] INPIN_IGNORE; [14] INPIN_HYST; [13:12] INPIN_LVL; [11:9] INPIN_FMT
|
||||
{ 57, 0x0020}, // fixed
|
||||
{ 56, 0x0000}, // fixed
|
||||
{ 55, 0x0000}, // fixed
|
||||
{ 54, 0x0000}, // fixed
|
||||
{ 53, 0x0000}, // fixed
|
||||
{ 52, 0x0820}, // fixed
|
||||
{ 51, 0x0080}, // fixed
|
||||
{ 50, 0x0000}, // fixed
|
||||
{ 49, 0x4180}, // fixed
|
||||
{ 48, 0x0300}, // fixed
|
||||
{ 47, 0x0300}, // fixed
|
||||
{ 46, 0x07FC}, // [1:0] OUTB_MUX
|
||||
{ 45, 0xC0DF}, // [12:11] OUTA_MUX; [10:9] OUT_ISET; [5:0] OUTB_PWR
|
||||
{ 44, 0x1AA3}, // [13:8] OUTA_PWR; [7] OUTB_PD; [6] OUTA_PD; [5] MASH_RESET_N; [2:0] MASH_ORDER
|
||||
{ 43, 0x0000}, // [15:0] PLL_NUM
|
||||
{ 42, 0x0000}, // [15:0] PLL_NUM
|
||||
{ 41, 0x0000}, // [15:0] MASH_SEE
|
||||
{ 40, 0x0000}, // [15:0] MASH_SEE
|
||||
{ 39, 0x03E8}, // [15:0] PLL_DEN
|
||||
{ 38, 0x0000}, // [15:0] PLL_DEN
|
||||
{ 37, 0x0304}, // [37] MASH_SEED_EN; [13:8] PFD_DLY_SEL
|
||||
{ 36, 0x0028}, // [15:0] PLL_N
|
||||
{ 35, 0x0004}, // fixed
|
||||
{ 34, 0x0000}, // [2:0] PLL_N
|
||||
{ 33, 0x1E21}, // fixed
|
||||
{ 32, 0x0393}, // fixed
|
||||
{ 31, 0x43EC}, // [14] SEG1_EN
|
||||
{ 30, 0x318C}, // fixed
|
||||
{ 29, 0x318C}, // fixed
|
||||
{ 28, 0x0488}, // fixed
|
||||
{ 27, 0x0002}, // fixed
|
||||
{ 26, 0x0DB0}, // fixed
|
||||
{ 25, 0x0C2B}, // fixed
|
||||
{ 24, 0x071A}, // fixed
|
||||
{ 23, 0x007C}, // fixed
|
||||
{ 22, 0x0001}, // fixed
|
||||
{ 21, 0x0401}, // fixed
|
||||
{ 20, 0xE048}, // [13:11] VCO_SEL. [10] VCO_SEL_FORCE
|
||||
{ 19, 0x27B7}, // [7:0] VCO_CAPCTRL
|
||||
{ 18, 0x0064}, // fixed
|
||||
{ 17, 0x012C}, // [8:0] VCO_DACISET_STRT
|
||||
{ 16, 0x0080}, // [8:0] VCO_DACISET
|
||||
{ 15, 0x064F}, // fixed
|
||||
{ 14, 0x1E70}, // [6:4] CPG
|
||||
{ 13, 0x4000}, // fixed
|
||||
{ 12, 0x5001}, // [11:0] PLL_R_PR
|
||||
{ 11, 0x0018}, // [11:4] PLL_R
|
||||
{ 10, 0x10D8}, // [11:7] MULT
|
||||
{ 9, 0x0604}, // [12] OSC_2X
|
||||
{ 8, 0x2000}, // [14] VCO_DACISET_FORCE; [11] VCO_CAPCTRL_FORCE
|
||||
{ 7, 0x40B2}, // [14] OUT_FORCE
|
||||
{ 6, 0xC802}, // fixed
|
||||
{ 5, 0x00C8}, // fixed
|
||||
{ 4, 0x0C43}, // [15:8] ACAL_CMP_DLY
|
||||
{ 3, 0x0642}, // fixed
|
||||
{ 2, 0x0500}, // fixed
|
||||
{ 1, 0x0809}, // [2:0] CAL_CLK_DIV
|
||||
{ 0, 0x2598}, // [15] RAMP_EN; [14] VCO_PHASE_SYNC; [9] OUT_MUTE; [8:7] FCAL_HPFD_ADJ; [6:5] FCAL_LPFD_ADJ; [3] FCAL_EN; [2] MUXOUT_LD_SEL; [1] RESET; [0] POWERDOWN
|
||||
|
||||
// one more time
|
||||
{ 0, 0x2598}
|
||||
};
|
||||
@@ -3,15 +3,19 @@
|
||||
#include "../config/app_config.h"
|
||||
#include "../drivers/platform/xilinx_timer.h"
|
||||
|
||||
struct xil_timer_init_param xil_scutimer_init_param = {
|
||||
struct xil_timer_init_param xil_apptimer_init_param = {
|
||||
.active_tmr = 0,
|
||||
#ifdef __aarch64__
|
||||
.type = TIMER_PL
|
||||
#else
|
||||
.type = TIMER_PS
|
||||
#endif
|
||||
};
|
||||
|
||||
struct timer_init_param scutimer_init_param = {
|
||||
.id = SCUTIMER_DEVICE_ID,
|
||||
.freq_hz = SCU_TIMER_CLK_HZ,
|
||||
.ticks_count = (SCU_TIMER_CLK_HZ/10), //update log every 100ms
|
||||
struct timer_init_param apptimer_init_param = {
|
||||
.id = APPTIMER_DEVICE_ID,
|
||||
.freq_hz = APP_TIMER_CLK_HZ,
|
||||
.ticks_count = (APP_TIMER_CLK_HZ/10), //update log every 100ms
|
||||
.platform_ops = &xil_timer_ops,
|
||||
.extra = &xil_scutimer_init_param
|
||||
.extra = &xil_apptimer_init_param
|
||||
};
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9653.c
|
||||
* @brief Implementation of AD9653 Driver.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2014-2016(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include "ad9653.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "../../../include/error.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief ad9653_read
|
||||
*******************************************************************************/
|
||||
int32_t ad9653_read(struct ad9653_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t *reg_data)
|
||||
{
|
||||
uint8_t tx_buf[2];
|
||||
uint8_t rx_buf[1];
|
||||
int32_t ret;
|
||||
|
||||
tx_buf[0] = 0x80 | (reg_addr >> 8);
|
||||
tx_buf[1] = reg_addr & 0xFF;
|
||||
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
tx_buf, rx_buf, 2, 1);
|
||||
|
||||
*reg_data = rx_buf[0];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief ad9653_write
|
||||
*******************************************************************************/
|
||||
int32_t ad9653_write(struct ad9653_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t reg_data)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
|
||||
int32_t ret;
|
||||
|
||||
buf[0] = reg_addr >> 8;
|
||||
buf[1] = reg_addr & 0xFF;
|
||||
buf[2] = reg_data;
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
buf, NULL, 3, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief ad9653_init
|
||||
*******************************************************************************/
|
||||
int32_t ad9653_init(struct ad9653_dev **device,
|
||||
const struct ad9653_init_param *init_param)
|
||||
{
|
||||
int ret = SUCCESS;
|
||||
struct ad9653_dev *dev;
|
||||
|
||||
dev = (struct ad9653_dev *)malloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
return FAILURE;
|
||||
|
||||
/* SPI */
|
||||
ret = spi_init(&dev->spi_desc, init_param->spi_init);
|
||||
|
||||
*device = dev;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Free the resources allocated by ad9653_setup().
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
*
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*******************************************************************************/
|
||||
int32_t ad9653_remove(struct ad9653_dev *dev)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = spi_remove(dev->spi_desc);
|
||||
|
||||
free(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9653.h
|
||||
* @brief Header file of AD9653 Driver.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2014-2016(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef AD9653_H_
|
||||
#define AD9653_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "delay.h"
|
||||
#include "spi.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
#define AD9694_REG_GLOBAL_MAP_SPI_CONF_A 0x0000
|
||||
#define AD9694_REG_GLOBAL_MAP_SPI_CONF_B 0x0001
|
||||
#define AD9694_REG_CH_MAP_CHIP_CONF 0x0002
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_TYPE 0x0003
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_ID_LSB 0x0004
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_GRADE 0x0006
|
||||
#define AD9694_REG_PAIR_MAP_DEV_INDEX 0x0008
|
||||
#define AD9694_REG_GLOBAL_MAP_PAIR_INDEX 0x0009
|
||||
#define AD9694_REG_PAIR_MAP_SCRATCH_PAD 0x000A
|
||||
#define AD9694_REG_PAIR_MAP_SPI_REVISION 0x000B
|
||||
#define AD9694_REG_PAIR_MAP_VENDOR_ID_LSB 0x000C
|
||||
#define AD9694_REG_PAIR_MAP_VENDOR_ID_MSB 0x000D
|
||||
#define AD9694_REG_CH_MAP_CHIP_PD_PIN 0x003F
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_PIN_CTRL_1 0x0040
|
||||
#define AD9694_REG_PAIR_MAP_CLK_DIV_CTRL 0x0108
|
||||
#define AD9694_REG_CH_MAP_CLK_DIV_PHASE 0x0109
|
||||
#define AD9694_REG_PAIR_MAP_CLK_DIV_SYSREF_CTRL 0x010A
|
||||
#define AD9694_REG_PAIR_MAP_CLK_DELAY_CTRL 0x0110
|
||||
#define AD9694_REG_CH_MAP_CLK_SUPER_FINE_DELAY 0x0111
|
||||
#define AD9694_REG_CH_MAP_CLK_FINE_DELAY 0x0112
|
||||
#define AD9694_REG_CLK_DETN_CTRL 0x011A
|
||||
#define AD9694_REG_PAIR_MAP_CLK_STAT 0x011B
|
||||
#define AD9694_REG_CLK_DCS_CTRL_1 0x011C
|
||||
#define AD9694_REG_CLK_DCS_CTRL_2 0x011E
|
||||
#define AD9694_REG_CLK_DCS_CTRL_3 0x011F
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_CTRL_1 0x0120
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_CTRL_2 0x0121
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_CTRL_4 0x0123
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_STAT_1 0x0128
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_STAT_2 0x0129
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_STAT_3 0x012A
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_SYNC 0x01FF
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_MODE 0x0200
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_DEC_RATIO 0x0201
|
||||
#define AD9694_REG_CH_MAP_CUSTOM_OFFSET 0x0228
|
||||
#define AD9694_REG_CH_MAP_FD_CTRL 0x0245
|
||||
#define AD9694_REG_CH_MAP_FD_UT_LSB 0x0247
|
||||
#define AD9694_REG_CH_MAP_FD_UT_MSB 0x0248
|
||||
#define AD9694_REG_CH_MAP_FD_LT_LSB 0x0249
|
||||
#define AD9694_REG_CH_MAP_FD_LT_MSB 0x024A
|
||||
#define AD9694_REG_CH_MAP_FD_DWELL_TIME_LSB 0x024B
|
||||
#define AD9694_REG_CH_MAP_FD_DWELL_TIME_MSB 0x024C
|
||||
#define AD9694_REG_PAIR_MAP_SIG_MON_SYNC_CTRL 0x026F
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_CTRL 0x0270
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_PERIOD_0 0x0271
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_PERIOD_1 0x0272
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_PERIOD_2 0x0273
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_STAT_CTRL 0x0274
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_STAT_0 0x0275
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_STAT_1 0x0276
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_STAT_2 0x0277
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_STAT_FRAME_CNT 0x0278
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_SERIAL_FRAMER_CTRL 0x0279
|
||||
#define AD9694_REG_SPORT_OVER_JESD204B_INPUT_SEL 0x027A
|
||||
#define AD9694_REG_PAIR_MAP_DDC_SYNC_CTRL 0x0300
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_CTRL 0x0310
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_INPUT_SEL 0x0311
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_0 0x0314
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_1 0x0315
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_2 0x0316
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_3 0x0317
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_4 0x0318
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_5 0x031A
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_0 0x031D
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_1 0x031E
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_2 0x031F
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_3 0x0320
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_4 0x0321
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_5 0x0322
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_TEST_ENABLE 0x0327
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_CTRL 0x0330
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_INPUT_SEL 0x0331
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_0 0x0334
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_1 0x0335
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_2 0x0336
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_3 0x0337
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_4 0x0338
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_5 0x033A
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_0 0x033D
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_1 0x033E
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_2 0x033F
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_3 0x0340
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_4 0x0341
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_5 0x0342
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_TEST_ENABLE 0x0347
|
||||
#define AD9694_REG_CH_MAP_TEST_MODE_CTRL 0x0550
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_1_LSB 0x0551
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_1_MSB 0x0552
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_2_LSB 0x0553
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_2_MSB 0x0554
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_3_LSB 0x0555
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_3_MSB 0x0556
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_4_LSB 0x0557
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_4_MSB 0x0558
|
||||
#define AD9694_REG_PAIR_MAP_OUTPUT_CTRL_MODE_0 0x0559
|
||||
#define AD9694_REG_PAIR_MAP_OUTPUT_CTRL_MODE_1 0x055A
|
||||
#define AD9694_REG_PAIR_MAP_OUTPUT_SAMPLE_MODE 0x0561
|
||||
#define AD9694_REG_PAIR_MAP_OUTPUT_CH_SEL 0x0564
|
||||
#define AD9694_REG_JESD204B_MAP_PLL_CTRL 0x056E
|
||||
#define AD9694_REG_JESD204B_MAP_PLL_STAT 0x056F
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_QUICK_CONF 0x0570
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_1 0x0571
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_2 0x0572
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_3 0x0573
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_4 0x0574
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LMFC_OFFSET 0x0578
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_DID_CONF 0x0580
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_BID_CONF 0x0581
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LID_0_CONF 0x0583
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LID_1_CONF 0x0585
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_SCR_L_CONF 0x058B
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_F_CONF 0x058C
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_K_CONF 0x058D
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_M_CONF 0x058E
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_CS_N_CONF 0x058F
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_SUBCLASS_CONF 0x0590
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_S_CONF 0x0591
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_HD_CF_CONF 0x0592
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_CHECKSUM_0_CONF 0x05A0
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_CHECKSUM_1_CONF 0x05A1
|
||||
#define AD9694_REG_SERDOUTX0_SERDOUTX1_LANE_PD 0x05B0
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LANE_ASSIGN_1 0x05B2
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LANE_ASSIGN_2 0x05B3
|
||||
#define AD9694_REG_JESD204B_MAP_SERD_ADJUST_0 0x05C0
|
||||
#define AD9694_REG_JESD204B_MAP_SERD_ADJUST_1 0x05C1
|
||||
#define AD9694_REG_JESD204B_SER_PE_SEL_LANE_0 0x05C4
|
||||
#define AD9694_REG_JESD204B_SER_PE_SEL_LANE_1 0x05C6
|
||||
#define AD9694_REG_LARGE_DITHER_CTRL 0x0922
|
||||
#define AD9694_REG_PLL_CAL 0x1222
|
||||
#define AD9694_REG_JESD204B_STARTUP_CIRCUIT_RST 0x1228
|
||||
#define AD9694_REG_PLL_LOSS_OF_LOCK_CTRL 0x1262
|
||||
#define AD9694_REG_DC_OFFSET_CAL_CTRL 0x0701
|
||||
#define AD9694_REG_DC_OFFSET_CAL_CTRL_2 0x073B
|
||||
#define AD9694_REG_PAIR_MAP_VREF_CTRL 0x18A6
|
||||
#define AD9694_REG_EXT_VCM_BUF_CTRL_1 0x18E0
|
||||
#define AD9694_REG_EXT_VCM_BUF_CTRL_2 0x18E1
|
||||
#define AD9694_REG_EXT_VCM_BUF_CTRL_3 0x18E2
|
||||
#define AD9694_REG_EXT_VCM_BUF_CTRL 0x18E3
|
||||
#define AD9694_REG_TEMP_DIODE_EXPORT 0x18E6
|
||||
#define AD9694_REG_CH_MAP_ANALOG_INPUT_CTRL 0x1908
|
||||
#define AD9694_REG_CH_MAP_INPUT_FULLSCALE_RANGE 0x1910
|
||||
#define AD9694_REG_CH_MAP_BUF_CTRL_1 0x1A4C
|
||||
#define AD9694_REG_CH_MAP_BUF_CTRL_2 0x1A4D
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
struct ad9653_dev {
|
||||
/* SPI */
|
||||
struct spi_desc *spi_desc;
|
||||
struct gpio_desc *gpio_desc_pdwn;
|
||||
};
|
||||
|
||||
struct ad9653_init_param {
|
||||
/* SPI */
|
||||
struct spi_init_param *spi_init;
|
||||
struct gpio_init_param *gpio_pdwn;
|
||||
};
|
||||
|
||||
struct ad9653_config {
|
||||
uint16_t addr;
|
||||
uint8_t value;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
int32_t ad9653_read(struct ad9653_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t *reg_data);
|
||||
|
||||
int32_t ad9653_write(struct ad9653_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t reg_data);
|
||||
|
||||
int32_t ad9653_init(struct ad9653_dev **device,
|
||||
const struct ad9653_init_param *init_param);
|
||||
|
||||
int32_t ad9653_remove(struct ad9653_dev *dev);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,128 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9694.c
|
||||
* @brief Implementation of AD9680 Driver.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2014-2016(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "ad9694.h"
|
||||
#include "../../../include/error.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief ad9694_read
|
||||
*******************************************************************************/
|
||||
int32_t ad9694_read(struct ad9694_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t *reg_data)
|
||||
{
|
||||
uint8_t tx_buf[2];
|
||||
uint8_t rx_buf[1];
|
||||
int32_t ret;
|
||||
|
||||
tx_buf[0] = 0x80 | (reg_addr >> 8);
|
||||
tx_buf[1] = reg_addr & 0xFF;
|
||||
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
tx_buf, rx_buf, 2, 1);
|
||||
|
||||
*reg_data = rx_buf[0];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief ad9694_write
|
||||
*******************************************************************************/
|
||||
int32_t ad9694_write(struct ad9694_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t reg_data)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
|
||||
int32_t ret;
|
||||
|
||||
buf[0] = reg_addr >> 8;
|
||||
buf[1] = reg_addr & 0xFF;
|
||||
buf[2] = reg_data;
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
buf, NULL, 3, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief ad9694_init
|
||||
*******************************************************************************/
|
||||
int32_t ad9694_init(struct ad9694_dev **device,
|
||||
const struct ad9694_init_param *init_param)
|
||||
{
|
||||
int ret = SUCCESS;
|
||||
struct ad9694_dev *dev;
|
||||
|
||||
dev = (struct ad9694_dev *)malloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
return FAILURE;
|
||||
|
||||
/* SPI */
|
||||
ret = spi_init(&dev->spi_desc, init_param->spi_init);
|
||||
|
||||
*device = dev;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Free the resources allocated by ad9694_setup().
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
*
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*******************************************************************************/
|
||||
int32_t ad9694_remove(struct ad9694_dev *dev)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = spi_remove(dev->spi_desc);
|
||||
|
||||
free(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9694.h
|
||||
* @brief Header file of AD9694 Driver.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2014-2016(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef AD9694_H_
|
||||
#define AD9694_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "delay.h"
|
||||
#include "spi.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
#define AD9694_REG_GLOBAL_MAP_SPI_CONF_A 0x0000
|
||||
#define AD9694_REG_GLOBAL_MAP_SPI_CONF_B 0x0001
|
||||
#define AD9694_REG_CH_MAP_CHIP_CONF 0x0002
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_TYPE 0x0003
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_ID_LSB 0x0004
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_GRADE 0x0006
|
||||
#define AD9694_REG_PAIR_MAP_DEV_INDEX 0x0008
|
||||
#define AD9694_REG_GLOBAL_MAP_PAIR_INDEX 0x0009
|
||||
#define AD9694_REG_PAIR_MAP_SCRATCH_PAD 0x000A
|
||||
#define AD9694_REG_PAIR_MAP_SPI_REVISION 0x000B
|
||||
#define AD9694_REG_PAIR_MAP_VENDOR_ID_LSB 0x000C
|
||||
#define AD9694_REG_PAIR_MAP_VENDOR_ID_MSB 0x000D
|
||||
#define AD9694_REG_CH_MAP_CHIP_PD_PIN 0x003F
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_PIN_CTRL_1 0x0040
|
||||
#define AD9694_REG_PAIR_MAP_CLK_DIV_CTRL 0x0108
|
||||
#define AD9694_REG_CH_MAP_CLK_DIV_PHASE 0x0109
|
||||
#define AD9694_REG_PAIR_MAP_CLK_DIV_SYSREF_CTRL 0x010A
|
||||
#define AD9694_REG_PAIR_MAP_CLK_DELAY_CTRL 0x0110
|
||||
#define AD9694_REG_CH_MAP_CLK_SUPER_FINE_DELAY 0x0111
|
||||
#define AD9694_REG_CH_MAP_CLK_FINE_DELAY 0x0112
|
||||
#define AD9694_REG_CLK_DETN_CTRL 0x011A
|
||||
#define AD9694_REG_PAIR_MAP_CLK_STAT 0x011B
|
||||
#define AD9694_REG_CLK_DCS_CTRL_1 0x011C
|
||||
#define AD9694_REG_CLK_DCS_CTRL_2 0x011E
|
||||
#define AD9694_REG_CLK_DCS_CTRL_3 0x011F
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_CTRL_1 0x0120
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_CTRL_2 0x0121
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_CTRL_4 0x0123
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_STAT_1 0x0128
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_STAT_2 0x0129
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_STAT_3 0x012A
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_SYNC 0x01FF
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_MODE 0x0200
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_DEC_RATIO 0x0201
|
||||
#define AD9694_REG_CH_MAP_CUSTOM_OFFSET 0x0228
|
||||
#define AD9694_REG_CH_MAP_FD_CTRL 0x0245
|
||||
#define AD9694_REG_CH_MAP_FD_UT_LSB 0x0247
|
||||
#define AD9694_REG_CH_MAP_FD_UT_MSB 0x0248
|
||||
#define AD9694_REG_CH_MAP_FD_LT_LSB 0x0249
|
||||
#define AD9694_REG_CH_MAP_FD_LT_MSB 0x024A
|
||||
#define AD9694_REG_CH_MAP_FD_DWELL_TIME_LSB 0x024B
|
||||
#define AD9694_REG_CH_MAP_FD_DWELL_TIME_MSB 0x024C
|
||||
#define AD9694_REG_PAIR_MAP_SIG_MON_SYNC_CTRL 0x026F
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_CTRL 0x0270
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_PERIOD_0 0x0271
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_PERIOD_1 0x0272
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_PERIOD_2 0x0273
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_STAT_CTRL 0x0274
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_STAT_0 0x0275
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_STAT_1 0x0276
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_STAT_2 0x0277
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_STAT_FRAME_CNT 0x0278
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_SERIAL_FRAMER_CTRL 0x0279
|
||||
#define AD9694_REG_SPORT_OVER_JESD204B_INPUT_SEL 0x027A
|
||||
#define AD9694_REG_PAIR_MAP_DDC_SYNC_CTRL 0x0300
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_CTRL 0x0310
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_INPUT_SEL 0x0311
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_0 0x0314
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_1 0x0315
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_2 0x0316
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_3 0x0317
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_4 0x0318
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_5 0x031A
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_0 0x031D
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_1 0x031E
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_2 0x031F
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_3 0x0320
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_4 0x0321
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_5 0x0322
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_TEST_ENABLE 0x0327
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_CTRL 0x0330
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_INPUT_SEL 0x0331
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_0 0x0334
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_1 0x0335
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_2 0x0336
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_3 0x0337
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_4 0x0338
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_5 0x033A
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_0 0x033D
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_1 0x033E
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_2 0x033F
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_3 0x0340
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_4 0x0341
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_5 0x0342
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_TEST_ENABLE 0x0347
|
||||
#define AD9694_REG_CH_MAP_TEST_MODE_CTRL 0x0550
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_1_LSB 0x0551
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_1_MSB 0x0552
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_2_LSB 0x0553
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_2_MSB 0x0554
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_3_LSB 0x0555
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_3_MSB 0x0556
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_4_LSB 0x0557
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_4_MSB 0x0558
|
||||
#define AD9694_REG_PAIR_MAP_OUTPUT_CTRL_MODE_0 0x0559
|
||||
#define AD9694_REG_PAIR_MAP_OUTPUT_CTRL_MODE_1 0x055A
|
||||
#define AD9694_REG_PAIR_MAP_OUTPUT_SAMPLE_MODE 0x0561
|
||||
#define AD9694_REG_PAIR_MAP_OUTPUT_CH_SEL 0x0564
|
||||
#define AD9694_REG_JESD204B_MAP_PLL_CTRL 0x056E
|
||||
#define AD9694_REG_JESD204B_MAP_PLL_STAT 0x056F
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_QUICK_CONF 0x0570
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_1 0x0571
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_2 0x0572
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_3 0x0573
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_4 0x0574
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LMFC_OFFSET 0x0578
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_DID_CONF 0x0580
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_BID_CONF 0x0581
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LID_0_CONF 0x0583
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LID_1_CONF 0x0585
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_SCR_L_CONF 0x058B
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_F_CONF 0x058C
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_K_CONF 0x058D
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_M_CONF 0x058E
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_CS_N_CONF 0x058F
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_SUBCLASS_CONF 0x0590
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_S_CONF 0x0591
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_HD_CF_CONF 0x0592
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_CHECKSUM_0_CONF 0x05A0
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_CHECKSUM_1_CONF 0x05A1
|
||||
#define AD9694_REG_SERDOUTX0_SERDOUTX1_LANE_PD 0x05B0
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LANE_ASSIGN_1 0x05B2
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LANE_ASSIGN_2 0x05B3
|
||||
#define AD9694_REG_JESD204B_MAP_SERD_ADJUST_0 0x05C0
|
||||
#define AD9694_REG_JESD204B_MAP_SERD_ADJUST_1 0x05C1
|
||||
#define AD9694_REG_JESD204B_SER_PE_SEL_LANE_0 0x05C4
|
||||
#define AD9694_REG_JESD204B_SER_PE_SEL_LANE_1 0x05C6
|
||||
#define AD9694_REG_LARGE_DITHER_CTRL 0x0922
|
||||
#define AD9694_REG_PLL_CAL 0x1222
|
||||
#define AD9694_REG_JESD204B_STARTUP_CIRCUIT_RST 0x1228
|
||||
#define AD9694_REG_PLL_LOSS_OF_LOCK_CTRL 0x1262
|
||||
#define AD9694_REG_DC_OFFSET_CAL_CTRL 0x0701
|
||||
#define AD9694_REG_DC_OFFSET_CAL_CTRL_2 0x073B
|
||||
#define AD9694_REG_PAIR_MAP_VREF_CTRL 0x18A6
|
||||
#define AD9694_REG_EXT_VCM_BUF_CTRL_1 0x18E0
|
||||
#define AD9694_REG_EXT_VCM_BUF_CTRL_2 0x18E1
|
||||
#define AD9694_REG_EXT_VCM_BUF_CTRL_3 0x18E2
|
||||
#define AD9694_REG_EXT_VCM_BUF_CTRL 0x18E3
|
||||
#define AD9694_REG_TEMP_DIODE_EXPORT 0x18E6
|
||||
#define AD9694_REG_CH_MAP_ANALOG_INPUT_CTRL 0x1908
|
||||
#define AD9694_REG_CH_MAP_INPUT_FULLSCALE_RANGE 0x1910
|
||||
#define AD9694_REG_CH_MAP_BUF_CTRL_1 0x1A4C
|
||||
#define AD9694_REG_CH_MAP_BUF_CTRL_2 0x1A4D
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
struct ad9694_dev {
|
||||
/* SPI */
|
||||
struct spi_desc *spi_desc;
|
||||
};
|
||||
|
||||
struct ad9694_init_param {
|
||||
/* SPI */
|
||||
struct spi_init_param *spi_init;
|
||||
};
|
||||
|
||||
struct ad9694_config {
|
||||
uint16_t addr;
|
||||
uint8_t value;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
int32_t ad9694_read(struct ad9694_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t *reg_data);
|
||||
|
||||
int32_t ad9694_write(struct ad9694_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t reg_data);
|
||||
|
||||
int32_t ad9694_init(struct ad9694_dev **device,
|
||||
const struct ad9694_init_param *init_param);
|
||||
|
||||
int32_t ad9694_remove(struct ad9694_dev *dev);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,241 @@
|
||||
/***************************************************************************//**
|
||||
* @file gpio.c
|
||||
* @brief Implementation of the GPIO Interface
|
||||
* @author Antoniu Miclaus ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2020(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "gpio.h"
|
||||
#include <stdlib.h>
|
||||
#include "error.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Obtain the GPIO decriptor.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param param - GPIO Initialization parameters.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t gpio_get(struct gpio_desc **desc,
|
||||
const struct gpio_init_param *param)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
if (!param || !param->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!param->platform_ops->gpio_ops_get)
|
||||
return -ENOSYS;
|
||||
|
||||
ret = param->platform_ops->gpio_ops_get(desc, param);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
(*desc)->platform_ops = param->platform_ops;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the value of an optional GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param param - GPIO Initialization parameters.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t gpio_get_optional(struct gpio_desc **desc,
|
||||
const struct gpio_init_param *param)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
if (!param || (param->number == -1)) {
|
||||
*desc = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!param->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!param->platform_ops->gpio_ops_get_optional)
|
||||
return -ENOSYS;
|
||||
|
||||
ret = param->platform_ops->gpio_ops_get_optional(desc, param);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
(*desc)->platform_ops = param->platform_ops;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* @brief Free the resources allocated by gpio_get().
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t gpio_remove(struct gpio_desc *desc)
|
||||
{
|
||||
if (desc) {
|
||||
if (!desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->gpio_ops_remove)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->gpio_ops_remove(desc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the input direction of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t gpio_direction_input(struct gpio_desc *desc)
|
||||
{
|
||||
if (desc) {
|
||||
if (!desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->gpio_ops_direction_input)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->gpio_ops_direction_input(desc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the output direction of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param value - The value.
|
||||
* Example: GPIO_HIGH
|
||||
* GPIO_LOW
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t gpio_direction_output(struct gpio_desc *desc,
|
||||
uint8_t value)
|
||||
{
|
||||
if (desc) {
|
||||
if (!desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->gpio_ops_direction_output)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->
|
||||
gpio_ops_direction_output(desc, value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the direction of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param direction - The direction.
|
||||
* Example: GPIO_OUT
|
||||
* GPIO_IN
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t gpio_get_direction(struct gpio_desc *desc,
|
||||
uint8_t *direction)
|
||||
{
|
||||
if (desc) {
|
||||
if (!desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->gpio_ops_get_direction)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->
|
||||
gpio_ops_get_direction(desc, direction);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the value of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param value - The value.
|
||||
* Example: GPIO_HIGH
|
||||
* GPIO_LOW
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t gpio_set_value(struct gpio_desc *desc,
|
||||
uint8_t value)
|
||||
{
|
||||
if (desc) {
|
||||
if (!desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->gpio_ops_set_value)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->gpio_ops_set_value(desc, value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the value of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param value - The value.
|
||||
* Example: GPIO_HIGH
|
||||
* GPIO_LOW
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t gpio_get_value(struct gpio_desc *desc,
|
||||
uint8_t *value)
|
||||
{
|
||||
if (desc) {
|
||||
if (!desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->gpio_ops_set_value)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->gpio_ops_get_value(desc, value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/***************************************************************************//**
|
||||
* @file i2c.c
|
||||
* @brief Implementation of the I2C Interface
|
||||
* @author Antoniu Miclaus ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2020(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "i2c.h"
|
||||
#include <stdlib.h>
|
||||
#include "error.h"
|
||||
|
||||
/**
|
||||
* @brief Initialize the I2C communication peripheral.
|
||||
* @param desc - The I2C descriptor.
|
||||
* @param param - The structure that contains the I2C parameters.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t i2c_init(struct i2c_desc **desc,
|
||||
const struct i2c_init_param *param)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
if (!param || !param->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!param->platform_ops->i2c_ops_init)
|
||||
return -ENOSYS;
|
||||
|
||||
ret = param->platform_ops->i2c_ops_init(desc, param);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
(*desc)->platform_ops = param->platform_ops;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by i2c_init().
|
||||
* @param desc - The I2C descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t i2c_remove(struct i2c_desc *desc)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->i2c_ops_remove)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->i2c_ops_remove(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief I2C Write data to slave device.
|
||||
* @param desc - The I2C descriptor.
|
||||
* @param data - The buffer with the transmitted/received data.
|
||||
* @param bytes_number - Number of bytes to write.
|
||||
* @param stop_bit - Stop conditional control.
|
||||
* Example: 0 - A stop condition will not be generated.
|
||||
* 1 - A stop condition will be generated.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t i2c_write(struct i2c_desc *desc,
|
||||
uint8_t *data,
|
||||
uint8_t bytes_number,
|
||||
uint8_t stop_bit)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->i2c_ops_write)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->i2c_ops_write(desc, data, bytes_number,
|
||||
stop_bit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief I2C Read data from slave device.
|
||||
* @param desc - The i2c descriptor.
|
||||
* @param data - The buffer with the transmitted/received data.
|
||||
* @param bytes_number - Number of bytes to read.
|
||||
* @param stop_bit - Stop conditional control.
|
||||
* Example: 0 - A stop condition will not be generated.
|
||||
* 1 - A stop condition will be generated.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t i2c_read(struct i2c_desc *desc,
|
||||
uint8_t *data,
|
||||
uint8_t bytes_number,
|
||||
uint8_t stop_bit)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->i2c_ops_read)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->i2c_ops_read(desc, data, bytes_number,
|
||||
stop_bit);
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
/***************************************************************************//**
|
||||
* @file spi.c
|
||||
* @brief Implementation of the SPI Interface
|
||||
* @author Antoniu Miclaus ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2020(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "spi.h"
|
||||
#include <stdlib.h>
|
||||
#include "error.h"
|
||||
|
||||
/**
|
||||
* @brief Initialize the SPI communication peripheral.
|
||||
* @param desc - The SPI descriptor.
|
||||
* @param param - The structure that contains the SPI parameters.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t spi_init(struct spi_desc **desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
if (!param || !param->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!param->platform_ops->init)
|
||||
return -ENOSYS;
|
||||
|
||||
ret = param->platform_ops->init(desc, param);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
(*desc)->platform_ops = param->platform_ops;
|
||||
(*desc)->parent = param->parent;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by spi_init().
|
||||
* @param desc - The SPI descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t spi_remove(struct spi_desc *desc)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->remove)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->remove(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write and read data to/from SPI.
|
||||
* @param desc - The SPI descriptor.
|
||||
* @param data - The buffer with the transmitted/received data.
|
||||
* @param bytes_number - Number of bytes to write/read.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t spi_write_and_read(struct spi_desc *desc,
|
||||
uint8_t *data,
|
||||
uint16_t bytes_number)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->write_and_read)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->write_and_read(desc, data, bytes_number);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write and read data to/from SPI in 3 wire mode.
|
||||
* @param desc - The SPI descriptor.
|
||||
* @param write_data - The buffer with the transmitted data.
|
||||
* @param read_data - The buffer with the received data.
|
||||
* @param write_bytes_number - Number of bytes to write.
|
||||
* @param read_bytes_number - Number of bytes to read.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t spi_write_and_read_3wire(struct spi_desc *desc,
|
||||
uint8_t *write_data,
|
||||
uint8_t *read_data,
|
||||
uint16_t write_bytes_number,
|
||||
uint16_t read_bytes_number)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->write_and_read_3wire)
|
||||
return -ENOSYS;
|
||||
return desc->platform_ops->write_and_read_3wire(desc, write_data, read_data,
|
||||
write_bytes_number, read_bytes_number);
|
||||
}
|
||||
/**
|
||||
* @brief Iterate over head list and send all spi messages
|
||||
* @param desc - The SPI descriptor.
|
||||
* @param msgs - Array of messages.
|
||||
* @param len - Number of messages in the array.
|
||||
* @return 0 in case of success, negativ error code otherwise.
|
||||
*/
|
||||
int32_t spi_transfer(struct spi_desc *desc,
|
||||
struct spi_msg *msgs,
|
||||
uint32_t len)
|
||||
{
|
||||
int32_t ret;
|
||||
uint32_t i;
|
||||
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (desc->platform_ops->transfer)
|
||||
return desc->platform_ops->transfer(desc, msgs, len);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (msgs[i].rx_buff != msgs[i].tx_buff || !msgs[i].tx_buff)
|
||||
return -EINVAL;
|
||||
ret = spi_write_and_read(desc, msgs[i].rx_buff,
|
||||
msgs[i].bytes_number);
|
||||
if (IS_ERR_VALUE(ret))
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,547 @@
|
||||
/*******************************************************************************
|
||||
* @file axi_dmac.c
|
||||
* @brief Driver for the Analog Devices AXI-DMAC core.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2018(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "axi_io.h"
|
||||
#include "error.h"
|
||||
#include "delay.h"
|
||||
#include "axi_dmac.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief ISR for dev to mem DMA transfer. It computes the next transfer params,
|
||||
* if any, and sets the transfer structure fields accordingly.
|
||||
*
|
||||
* @param instance - the instance that triggered the ISR.
|
||||
*
|
||||
* @return None.
|
||||
*******************************************************************************/
|
||||
void axi_dmac_dev_to_mem_isr(void *instance)
|
||||
{
|
||||
struct axi_dmac *dmac = (struct axi_dmac *)instance;
|
||||
uint32_t burst_size;
|
||||
uint32_t reg_val;
|
||||
|
||||
/* Get interrupt sources and clear interrupts. */
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_PENDING, reg_val);
|
||||
|
||||
if (reg_val & AXI_DMAC_IRQ_SOT) {
|
||||
if (dmac->remaining_size) {
|
||||
/* See if remaining size is bigger than max transfer size and
|
||||
* set burst size. */
|
||||
if (dmac->remaining_size > dmac->max_length) {
|
||||
burst_size = dmac->max_length;
|
||||
} else {
|
||||
burst_size = dmac->remaining_size - 1;
|
||||
}
|
||||
|
||||
/* The current transfer was started; set up the new one. */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, dmac->next_dest_addr);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, 0x0);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, burst_size);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0);
|
||||
|
||||
/* Compute size of the next transfer. */
|
||||
dmac->remaining_size = dmac->remaining_size - (burst_size + 1);
|
||||
/* Address must advance with +1 since the DMAC writes X_LENGTH+1. */
|
||||
dmac->next_dest_addr = dmac->next_dest_addr + (burst_size + 1);
|
||||
|
||||
/* Trigger the next transfer. */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_TRANSFER_SUBMIT, AXI_DMAC_TRANSFER_SUBMIT);
|
||||
}
|
||||
}
|
||||
if (reg_val & AXI_DMAC_IRQ_EOT) {
|
||||
if (!dmac->remaining_size) {
|
||||
dmac->transfer.transfer_done = true;
|
||||
dmac->next_dest_addr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief ISR for mem DMA to dev transfer. It computes the next transfer params,
|
||||
* if any, and sets the transfer structure fields accordingly.
|
||||
*
|
||||
* @param instance - the instance that triggered the ISR.
|
||||
*
|
||||
* @return None.
|
||||
*******************************************************************************/
|
||||
void axi_dmac_mem_to_dev_isr(void *instance)
|
||||
{
|
||||
struct axi_dmac *dmac = (struct axi_dmac *)instance;
|
||||
uint32_t burst_size;
|
||||
uint32_t reg_val;
|
||||
|
||||
/* Get interrupt sources and clear interrupts. */
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_PENDING, reg_val);
|
||||
|
||||
if (reg_val & AXI_DMAC_IRQ_SOT) {
|
||||
if ((dmac->transfer.cyclic == CYCLIC) &&
|
||||
(dmac->next_src_addr >= (dmac->init_addr + dmac->transfer.size - 1))) {
|
||||
dmac->remaining_size = dmac->transfer.size;
|
||||
dmac->next_src_addr = dmac->init_addr;
|
||||
}
|
||||
|
||||
if (dmac->remaining_size) {
|
||||
/** See if remaining size is bigger than max transfer size and
|
||||
* set burst size. */
|
||||
if (dmac->remaining_size > dmac->max_length) {
|
||||
burst_size = dmac->max_length;
|
||||
} else {
|
||||
burst_size = dmac->remaining_size - 1;
|
||||
}
|
||||
|
||||
/* The current transfer was started; set up the new one. */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, dmac->next_src_addr);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, 0x0);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, burst_size);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0);
|
||||
|
||||
/* Compute parameters for the next transfer. */
|
||||
dmac->remaining_size = dmac->remaining_size - (burst_size + 1);
|
||||
/* Address must advance with +1 since the DMAC writes X_LENGTH+1. */
|
||||
dmac->next_src_addr = dmac->next_src_addr + (burst_size + 1);
|
||||
|
||||
/* Trigger the current transfer */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_TRANSFER_SUBMIT, AXI_DMAC_TRANSFER_SUBMIT);
|
||||
}
|
||||
}
|
||||
if (reg_val & AXI_DMAC_IRQ_EOT) {
|
||||
if ((!dmac->remaining_size) && (dmac->transfer.cyclic != CYCLIC)) {
|
||||
dmac->transfer.transfer_done = true;
|
||||
dmac->next_src_addr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief ISR for mem DMA to mem DMA transfer. It computes the next transfer
|
||||
* params, if any, and sets the transfer structure fields accordingly.
|
||||
*
|
||||
* @param instance - the instance that triggered the ISR.
|
||||
*
|
||||
* @return None.
|
||||
*******************************************************************************/
|
||||
void axi_dmac_mem_to_mem_isr(void *instance)
|
||||
{
|
||||
struct axi_dmac *dmac = (struct axi_dmac *)instance;
|
||||
uint32_t burst_size;
|
||||
uint32_t reg_val;
|
||||
|
||||
/* Get interrupt sources and clear interrupts. */
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_PENDING, reg_val);
|
||||
|
||||
if (reg_val & AXI_DMAC_IRQ_SOT) {
|
||||
if (dmac->remaining_size) {
|
||||
/** See if remaining size is bigger than max transfer size and
|
||||
* set burst size. */
|
||||
if (dmac->remaining_size > dmac->max_length) {
|
||||
burst_size = dmac->max_length;
|
||||
} else {
|
||||
burst_size = dmac->remaining_size - 1;
|
||||
}
|
||||
|
||||
/* The current transfer was started; set up the new one. */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, dmac->next_src_addr);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, 0x0);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, dmac->next_dest_addr);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, 0x0);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, burst_size);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0);
|
||||
|
||||
/* Compute parameters for the next transfer. */
|
||||
dmac->remaining_size = dmac->remaining_size - (burst_size + 1);
|
||||
/* Address must advance with +1 since the DMAC writes X_LENGTH+1. */
|
||||
dmac->next_src_addr = dmac->next_src_addr + (burst_size + 1);
|
||||
dmac->next_dest_addr = dmac->next_dest_addr + (burst_size + 1);
|
||||
|
||||
/* If transfer finished advance src address so that transfer_done can be set*/
|
||||
if (!dmac->remaining_size) {
|
||||
dmac->next_src_addr = dmac->next_src_addr + (burst_size + 1);
|
||||
}
|
||||
|
||||
/* Trigger the current transfer */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_TRANSFER_SUBMIT, AXI_DMAC_TRANSFER_SUBMIT);
|
||||
}
|
||||
}
|
||||
if (reg_val & AXI_DMAC_IRQ_EOT) {
|
||||
if (!dmac->remaining_size) {
|
||||
if(dmac->next_src_addr > (dmac->init_addr + dmac->transfer.size)) {
|
||||
dmac->transfer.transfer_done = true;
|
||||
dmac->next_src_addr = 0;
|
||||
dmac->next_dest_addr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Wrapper for AXI IO through UIO/devmem read function.
|
||||
*
|
||||
* @param dmac - DMAC istance containing UIO index (/dev/uioX)/base address.
|
||||
* @param reg_addr - Address to read from.
|
||||
* @param reg_data - Location where read data will be stored.
|
||||
*
|
||||
* @return 0 - success.
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_read(struct axi_dmac *dmac,
|
||||
uint32_t reg_addr,
|
||||
uint32_t *reg_data)
|
||||
{
|
||||
axi_io_read(dmac->base, reg_addr, reg_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Wrapper for AXI IO through UIO/devmem wrrite function.
|
||||
*
|
||||
* @param dmac - DMAC istance containing UIO index (/dev/uioX)/base address.
|
||||
* @param reg_addr - Address to write to.
|
||||
* @param reg_data - Data to be written.
|
||||
*
|
||||
* @return 0 - success.
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_write(struct axi_dmac *dmac,
|
||||
uint32_t reg_addr,
|
||||
uint32_t reg_data)
|
||||
{
|
||||
axi_io_write(dmac->base, reg_addr, reg_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Get transfer status (value of dmac->transfer.transfer_done flag).
|
||||
*
|
||||
* @note This function should not be used if DMA IRQ is not used.
|
||||
*
|
||||
* @param dmac - DMAC istance.
|
||||
* @param rdy - Transfer status (0 - not ready, 1 - ready).
|
||||
*
|
||||
* @return 0 - success.
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_is_transfer_ready(struct axi_dmac *dmac, bool *rdy)
|
||||
{
|
||||
*rdy = dmac->transfer.transfer_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Get DMAC capabilities.
|
||||
*
|
||||
* @param dmac - DMAC istance.
|
||||
*
|
||||
* @return 0 for success, -1 in case of failure.
|
||||
*******************************************************************************/
|
||||
static int32_t axi_dmac_detect_caps(struct axi_dmac *dmac)
|
||||
{
|
||||
uint32_t reg_val, initial_reg_val = 0;
|
||||
uint32_t src_mem_mapped = 0;
|
||||
uint32_t dest_mem_mapped = 0;
|
||||
|
||||
dmac->max_length = -1;
|
||||
dmac->direction = INVALID_DIR;
|
||||
|
||||
/* Check if HW cyclic possible */
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS, &initial_reg_val);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, DMA_CYCLIC);
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS, ®_val);
|
||||
if (reg_val == DMA_CYCLIC)
|
||||
dmac->hw_cyclic = true;
|
||||
/* Restore initial value for AXI_DMAC_REG_FLAGS register */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, initial_reg_val);
|
||||
|
||||
/* Get maximum burst size and set value. */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, dmac->max_length);
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_X_LENGTH, &dmac->max_length);
|
||||
|
||||
/* Get transfer direction and set value. */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, 0xffffffff);
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_DEST_ADDRESS, &dest_mem_mapped);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, 0xffffffff);
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_SRC_ADDRESS, &src_mem_mapped);
|
||||
|
||||
if (dest_mem_mapped && !src_mem_mapped) {
|
||||
dmac->direction = DMA_DEV_TO_MEM;
|
||||
} else if (!dest_mem_mapped && src_mem_mapped) {
|
||||
dmac->direction = DMA_MEM_TO_DEV;
|
||||
} else if (dest_mem_mapped && src_mem_mapped) {
|
||||
dmac->direction = DMA_MEM_TO_MEM;
|
||||
} else {
|
||||
printf("Destination and source memory-mapped interfaces not supported.\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Get transfer status (value of dmac->transfer.transfer_done flag).
|
||||
*
|
||||
* @param dmac_core - DMAC istance.
|
||||
* @param init - Structure containing initializing data.
|
||||
*
|
||||
* @return 0 for success, -1 in case of failure.
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_init(struct axi_dmac **dmac_core,
|
||||
const struct axi_dmac_init *init)
|
||||
{
|
||||
struct axi_dmac *dmac;
|
||||
|
||||
dmac = (struct axi_dmac *)calloc(1, sizeof(*dmac));
|
||||
if (!dmac)
|
||||
return -1;
|
||||
|
||||
dmac->name = init->name;
|
||||
dmac->base = init->base;
|
||||
dmac->irq_option = init->irq_option;
|
||||
|
||||
*dmac_core = dmac;
|
||||
|
||||
int32_t status = axi_dmac_detect_caps(*dmac_core);
|
||||
if (status < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Remove the DMAC instance.
|
||||
*
|
||||
* @param dmac - DMAC istance.
|
||||
*
|
||||
* @return 0 for success, -1 in case of failure.
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_remove(struct axi_dmac *dmac)
|
||||
{
|
||||
if (!dmac)
|
||||
return -1;
|
||||
|
||||
free(dmac);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Start a DMA transfer.
|
||||
*
|
||||
* @param dmac - DMAC istance.
|
||||
* @param dma_transfer - Structure containing transfer details.
|
||||
*
|
||||
* @return 0 for success, -1 in case of failure.
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_transfer_start(struct axi_dmac *dmac,
|
||||
struct axi_dma_transfer *dma_transfer)
|
||||
{
|
||||
uint32_t reg_val, burst_size;
|
||||
|
||||
if (dma_transfer->size == 0)
|
||||
return 0; /* Nothing to do. */
|
||||
|
||||
/* Set current transfer parameters. */
|
||||
dmac->transfer.size = dma_transfer->size;
|
||||
dmac->transfer.cyclic = dma_transfer->cyclic;
|
||||
dmac->transfer.dest_addr = dma_transfer->dest_addr;
|
||||
dmac->transfer.src_addr = dma_transfer->src_addr;
|
||||
|
||||
dmac->remaining_size = dma_transfer->size;
|
||||
dmac->next_dest_addr = dma_transfer->dest_addr;
|
||||
dmac->next_src_addr = dma_transfer->src_addr;
|
||||
|
||||
/* If HW cyclic transfer selected and not available, show error */
|
||||
/* HW cyclic transfer available only for MEM to DEV transfers. */
|
||||
if ((!dmac->hw_cyclic) && (dma_transfer->cyclic == CYCLIC)) {
|
||||
printf("Transfer mode not supported!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Cyclic transfers not possible for DEV_TO_MEM and MEM_TO_MEM transmissions. */
|
||||
if ((dmac->direction == DMA_DEV_TO_MEM)
|
||||
|| (dmac->direction == DMA_MEM_TO_MEM)) {
|
||||
if (dma_transfer->cyclic == CYCLIC) {
|
||||
printf("Transfer mode not supported!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cyclic transfers set to HW or SW depending on size for MEM to DEV. */
|
||||
if ((dmac->direction == DMA_MEM_TO_DEV) && (dmac->transfer.cyclic == CYCLIC)) {
|
||||
if ((dmac->remaining_size - 1) <= dmac->max_length) {
|
||||
if (dmac->hw_cyclic) {
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS, ®_val);
|
||||
reg_val = reg_val | DMA_CYCLIC;
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, reg_val);
|
||||
}
|
||||
} else {
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS, ®_val);
|
||||
reg_val = reg_val & ~DMA_CYCLIC;
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, reg_val);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable DMA if not already enabled. */
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_CTRL, ®_val);
|
||||
if (!(reg_val & AXI_DMAC_CTRL_ENABLE)) {
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, 0x0);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, AXI_DMAC_CTRL_ENABLE);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_MASK, 0x0);
|
||||
}
|
||||
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_TRANSFER_SUBMIT, ®_val);
|
||||
/* If we don't have a start of transfer then start compute
|
||||
* values and trigger next transfer. */
|
||||
if (!(reg_val & AXI_DMAC_QUEUE_FULL)) {
|
||||
switch (dmac->direction) {
|
||||
case DMA_DEV_TO_MEM:
|
||||
dmac->init_addr = dmac->next_dest_addr;
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, dmac->next_dest_addr);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, 0x0);
|
||||
break;
|
||||
case DMA_MEM_TO_DEV:
|
||||
dmac->init_addr = dmac->next_src_addr;
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, dmac->next_src_addr);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, 0x0);
|
||||
break;
|
||||
case DMA_MEM_TO_MEM:
|
||||
dmac->init_addr = dmac->next_src_addr;
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, dmac->next_dest_addr);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, 0x0);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, dmac->next_src_addr);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, 0x0);
|
||||
break;
|
||||
default:
|
||||
return -1; /* Other directions are not supported yet. */
|
||||
}
|
||||
|
||||
/* Compute the burst size. */
|
||||
if (dmac->remaining_size > dmac->max_length) {
|
||||
burst_size = dmac->max_length;
|
||||
} else {
|
||||
burst_size = dmac->remaining_size - 1;
|
||||
}
|
||||
|
||||
/* Compute next address (src or dest, or both, depending on type of transfer). */
|
||||
switch (dmac->direction) {
|
||||
case DMA_DEV_TO_MEM:
|
||||
dmac->next_dest_addr = dmac->next_dest_addr + (burst_size + 1);
|
||||
break;
|
||||
case DMA_MEM_TO_DEV:
|
||||
dmac->next_src_addr = dmac->next_src_addr + (burst_size + 1);
|
||||
break;
|
||||
case DMA_MEM_TO_MEM:
|
||||
dmac->next_dest_addr = dmac->next_dest_addr + (burst_size + 1);
|
||||
dmac->next_src_addr = dmac->next_src_addr + (burst_size + 1);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Compute remaining size. */
|
||||
dmac->remaining_size = dmac->remaining_size - (burst_size + 1);
|
||||
|
||||
/* Specify the length of the transfer and trigger transfer. */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, burst_size);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_TRANSFER_SUBMIT, AXI_DMAC_TRANSFER_SUBMIT);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Wait for DMA transfer to be completed.
|
||||
*
|
||||
* @param dmac - DMAC istance.
|
||||
* @param timeout_ms - Number of ms to wait for completion of transfer.
|
||||
*
|
||||
* @return 0 for success, -1 in case trasnfer not completed in specified time.
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_transfer_wait_completion(struct axi_dmac *dmac,
|
||||
uint32_t timeout_ms)
|
||||
{
|
||||
uint32_t timeout = 0;
|
||||
uint32_t reg_val = 0;
|
||||
|
||||
if (dmac->irq_option == IRQ_ENABLED) {
|
||||
while (!dmac->transfer.transfer_done) {
|
||||
timeout++;
|
||||
mdelay(1);
|
||||
if (timeout == timeout_ms) {
|
||||
printf("Error transferring data using DMA.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (dmac->irq_option == IRQ_DISABLED) {
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val);
|
||||
while (reg_val != (AXI_DMAC_IRQ_SOT | AXI_DMAC_IRQ_EOT)) {
|
||||
timeout++;
|
||||
mdelay(1);
|
||||
if (timeout == timeout_ms) {
|
||||
printf("Error transferring data using DMA.\n");
|
||||
return -1;
|
||||
}
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Stop a DMA transfer.
|
||||
*
|
||||
* @param dmac - DMAC istance.
|
||||
*
|
||||
* @return None
|
||||
*******************************************************************************/
|
||||
void axi_dmac_transfer_stop(struct axi_dmac *dmac)
|
||||
{
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, AXI_DMAC_CTRL_DISABLE);
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/***************************************************************************//**
|
||||
* @file axi_dmac.h
|
||||
* @brief Driver for the Analog Devices AXI-DMAC core.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2018(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef AXI_DMAC_H_
|
||||
#define AXI_DMAC_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "util.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
#define AXI_DMAC_REG_IRQ_MASK 0x80
|
||||
#define AXI_DMAC_REG_IRQ_PENDING 0x84
|
||||
#define AXI_DMAC_IRQ_SOT BIT(0)
|
||||
#define AXI_DMAC_IRQ_EOT BIT(1)
|
||||
|
||||
#define AXI_DMAC_REG_INTF_DESC 0x010
|
||||
#define AXI_DMAC_DMA_TYPE_DEST GENMASK(5,4)
|
||||
#define AXI_DMAC_DMA_TYPE_SRC GENMASK(13,12)
|
||||
//Define macro for src and dest
|
||||
|
||||
#define AXI_DMAC_REG_CTRL 0x400
|
||||
#define AXI_DMAC_CTRL_ENABLE BIT(0)
|
||||
#define AXI_DMAC_CTRL_DISABLE 0u
|
||||
#define AXI_DMAC_CTRL_PAUSE BIT(1)
|
||||
|
||||
#define AXI_DMAC_REG_TRANSFER_ID 0x404
|
||||
#define AXI_DMAC_REG_TRANSFER_SUBMIT 0x408
|
||||
#define AXI_DMAC_TRANSFER_SUBMIT BIT(0)
|
||||
#define AXI_DMAC_QUEUE_FULL BIT(0)
|
||||
#define AXI_DMAC_REG_FLAGS 0x40c
|
||||
#define AXI_DMAC_REG_DEST_ADDRESS 0x410
|
||||
#define AXI_DMAC_REG_SRC_ADDRESS 0x414
|
||||
#define AXI_DMAC_REG_X_LENGTH 0x418
|
||||
#define AXI_DMAC_REG_Y_LENGTH 0x41c
|
||||
#define AXI_DMAC_REG_DEST_STRIDE 0x420
|
||||
#define AXI_DMAC_REG_SRC_STRIDE 0x424
|
||||
#define AXI_DMAC_REG_TRANSFER_DONE 0x428
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
enum use_irq {
|
||||
IRQ_DISABLED = 0,
|
||||
IRQ_ENABLED = 1
|
||||
};
|
||||
|
||||
enum dma_direction {
|
||||
INVALID_DIR = 0,
|
||||
DMA_DEV_TO_MEM = 1,
|
||||
DMA_MEM_TO_DEV = 2,
|
||||
DMA_MEM_TO_MEM = 3
|
||||
};
|
||||
|
||||
enum dma_flags {
|
||||
DMA_CYCLIC = 1,
|
||||
DMA_LAST = 2,
|
||||
DMA_PARTIAL_REPORTING_EN = 4
|
||||
};
|
||||
|
||||
// Could be transformed to a bool
|
||||
enum cyclic_transfer {
|
||||
NO = 0,
|
||||
CYCLIC = 1
|
||||
};
|
||||
|
||||
struct axi_dma_transfer {
|
||||
uint32_t size;
|
||||
volatile bool transfer_done;
|
||||
enum cyclic_transfer cyclic;
|
||||
uint32_t src_addr;
|
||||
uint32_t dest_addr;
|
||||
};
|
||||
|
||||
struct axi_dmac {
|
||||
const char *name;
|
||||
uint32_t base;
|
||||
enum use_irq irq_option;
|
||||
enum dma_direction direction;
|
||||
bool hw_cyclic;
|
||||
uint32_t max_length;
|
||||
volatile struct axi_dma_transfer transfer;
|
||||
//Current sub-transfer properties
|
||||
uint32_t init_addr;
|
||||
uint32_t remaining_size;
|
||||
uint32_t next_src_addr;
|
||||
uint32_t next_dest_addr;
|
||||
};
|
||||
|
||||
struct axi_dmac_init {
|
||||
const char *name;
|
||||
uint32_t base;
|
||||
enum use_irq irq_option;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
void axi_dmac_dev_to_mem_isr(void *instance);
|
||||
void axi_dmac_mem_to_dev_isr(void *instance);
|
||||
void axi_dmac_mem_to_mem_isr(void *instance);
|
||||
void axi_dmac_write_isr(void *instance);
|
||||
int32_t axi_dmac_read(struct axi_dmac *dmac, uint32_t reg_addr,
|
||||
uint32_t *reg_data);
|
||||
int32_t axi_dmac_write(struct axi_dmac *dmac, uint32_t reg_addr,
|
||||
uint32_t reg_data);
|
||||
int32_t axi_dmac_is_transfer_ready(struct axi_dmac *dmac, bool *rdy);
|
||||
int32_t axi_dmac_init(struct axi_dmac **adc_core,
|
||||
const struct axi_dmac_init *init);
|
||||
int32_t axi_dmac_remove(struct axi_dmac *dmac);
|
||||
int32_t axi_dmac_transfer_start(struct axi_dmac *dmac,
|
||||
struct axi_dma_transfer *dma_transfer);
|
||||
int32_t axi_dmac_transfer_wait_completion(struct axi_dmac *dmac,
|
||||
uint32_t timeout_ms);
|
||||
void axi_dmac_transfer_stop(struct axi_dmac *dmac);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,996 @@
|
||||
/*******************************************************************************
|
||||
* @file spi_engine.c
|
||||
* @brief Core implementation of the SPI Engine Driver.
|
||||
* @author Sergiu Cuciurean ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* In debug mode the printf function used in displaying the messages is causing
|
||||
significant delays */
|
||||
//#define DEBUG_LEVEL 2
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sleep.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "axi_io.h"
|
||||
#include "error.h"
|
||||
#include "spi_engine.h"
|
||||
|
||||
/**
|
||||
* @brief Spi engine platform specific SPI platform ops structure
|
||||
*/
|
||||
const struct spi_platform_ops spi_eng_platform_ops = {
|
||||
.init = &spi_engine_init,
|
||||
.write_and_read = &spi_engine_write_and_read,
|
||||
.write_and_read_3wire = &spi_engine_write_and_read_3wire,
|
||||
.remove = &spi_engine_remove
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Static variables *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Static variable used to sync transfers
|
||||
*
|
||||
*/
|
||||
static uint8_t _sync_id = 0x01;
|
||||
|
||||
/******************************************************************************/
|
||||
/************************** Functions Implementation **************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Write SPI Engine's axi registers
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param reg_addr The address of the SPI Engine's axi register where the data
|
||||
* will be written
|
||||
* @param reg_data Data that will be written
|
||||
* @return int32_t This function allways returns SUCCESS
|
||||
*/
|
||||
int32_t spi_engine_write(struct spi_engine_desc *desc,
|
||||
uint32_t reg_addr,
|
||||
uint32_t reg_data)
|
||||
{
|
||||
axi_io_write(desc->spi_engine_baseaddr, reg_addr, reg_data);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read SPI Engine's axi registers
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param reg_addr The address of the SPI Engine's axi register from where the
|
||||
* data where the data will be read
|
||||
* @param reg_data Pointer where the read that will be stored
|
||||
* @return int32_t This function allways returns SUCCESS
|
||||
*/
|
||||
int32_t spi_engine_read(struct spi_engine_desc *desc,
|
||||
uint32_t reg_addr,
|
||||
uint32_t *reg_data)
|
||||
{
|
||||
axi_io_read(desc->spi_engine_baseaddr, reg_addr, reg_data);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set width of the transferred word over SPI
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param data_width The desired data width
|
||||
* The supported values are:
|
||||
* - 8
|
||||
* - 16
|
||||
* - 24
|
||||
* - 32
|
||||
*/
|
||||
int32_t spi_engine_set_transfer_width(struct spi_desc *desc,
|
||||
uint8_t data_width)
|
||||
{
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
if (data_width > desc_extra->max_data_width)
|
||||
desc_extra->data_width = desc_extra->max_data_width;
|
||||
else
|
||||
desc_extra->data_width = data_width;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set SPI engine clock frequency
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param speed_hz SPI engine transfer speed
|
||||
*/
|
||||
void spi_engine_set_speed(struct spi_desc *desc,
|
||||
uint32_t speed_hz)
|
||||
{
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
desc_extra->clk_div = desc_extra->ref_clk_hz /
|
||||
(2 * speed_hz) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the number of words transferred in a single transaction
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param bytes_number The number of bytes to be converted
|
||||
* @return uint8_t A number of words in which bytes_number can be grouped
|
||||
*/
|
||||
static uint8_t spi_get_words_number(struct spi_engine_desc *desc,
|
||||
uint8_t bytes_number)
|
||||
{
|
||||
uint8_t xfer_word_len;
|
||||
uint8_t words_number;
|
||||
|
||||
xfer_word_len = desc->data_width / 8;
|
||||
words_number = bytes_number / xfer_word_len;
|
||||
|
||||
if ((bytes_number % xfer_word_len) != 0)
|
||||
words_number++;
|
||||
|
||||
return words_number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the word length in bytes
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @return uint8_t Number of bytes that fit in one word
|
||||
*/
|
||||
static uint8_t spi_get_word_length(struct spi_engine_desc *desc)
|
||||
{
|
||||
uint8_t word_length;
|
||||
|
||||
word_length = desc->data_width / 8;
|
||||
|
||||
return word_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compute the prescaler used to set the sleep period.
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param sleep_time_ns The amount of time where the transfer hangs
|
||||
* @param sleep_div Clock prescaler
|
||||
* @return int32_t This function allways returns SUCCESS
|
||||
*/
|
||||
static int32_t spi_get_sleep_div(struct spi_desc *desc,
|
||||
uint32_t sleep_time_ns,
|
||||
uint32_t *sleep_div)
|
||||
{
|
||||
struct spi_engine_desc *eng_desc;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
/*
|
||||
* Engine Wiki:
|
||||
*
|
||||
* The frequency of the SCLK signal is derived from the
|
||||
* module clock frequency using the following formula:
|
||||
* f_sclk = f_clk / ((div + 1) * 2)
|
||||
*/
|
||||
|
||||
*sleep_div = (desc->max_speed_hz / 1000000 * sleep_time_ns / 1000) /
|
||||
((eng_desc->clk_div + 1) * 2) - 1;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a new commands queue used in a spi transfer
|
||||
*
|
||||
* @param fifo Command buffer, usually used in fifo mode
|
||||
* @param cmd Command with which the buffer will be initiated
|
||||
* @return int32_t Failure if the memory allocation failed
|
||||
*/
|
||||
static int32_t spi_engine_queue_new_cmd(struct spi_engine_cmd_queue **fifo,
|
||||
uint32_t cmd)
|
||||
{
|
||||
struct spi_engine_cmd_queue *local_fifo;
|
||||
|
||||
local_fifo = (spi_engine_cmd_queue*)malloc(sizeof(*local_fifo));
|
||||
|
||||
if(!local_fifo)
|
||||
return FAILURE;
|
||||
|
||||
local_fifo->cmd = cmd;
|
||||
local_fifo->next = NULL;
|
||||
*fifo = local_fifo;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a command at the end of an existing queue
|
||||
*
|
||||
* @param fifo Command buffer, usually used in fifo mode
|
||||
* @param cmd Command to be added
|
||||
*/
|
||||
static void spi_engine_queue_add_cmd(struct spi_engine_cmd_queue **fifo,
|
||||
uint32_t cmd)
|
||||
{
|
||||
struct spi_engine_cmd_queue *to_add = NULL;
|
||||
struct spi_engine_cmd_queue *local_fifo;
|
||||
|
||||
local_fifo = *fifo;
|
||||
while (local_fifo->next != NULL) {
|
||||
// Get the last element
|
||||
local_fifo = local_fifo->next;
|
||||
}
|
||||
|
||||
// Create a new element
|
||||
spi_engine_queue_new_cmd(&to_add, cmd);
|
||||
// Add as the next element
|
||||
local_fifo->next = to_add;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a command at the beginning of an existing queue
|
||||
*
|
||||
* @param fifo Command buffer, usually used in fifo mode
|
||||
* @param cmd Command to be added
|
||||
*/
|
||||
static void spi_engine_queue_append_cmd(struct spi_engine_cmd_queue **fifo,
|
||||
uint32_t cmd)
|
||||
{
|
||||
struct spi_engine_cmd_queue *to_add = NULL;
|
||||
|
||||
// Create a new element
|
||||
spi_engine_queue_new_cmd(&to_add, cmd);
|
||||
// Interchange the addresses
|
||||
to_add->next = *fifo;
|
||||
*fifo = to_add;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the command from the beginning of the queue
|
||||
*
|
||||
* @param fifo Command buffer, usually used in fifo mode
|
||||
* @param cmd Value of the command that was extracted
|
||||
* @return int32_t Return FAILURE if the queue is empty
|
||||
*/
|
||||
static int32_t spi_engine_queue_get_cmd(struct spi_engine_cmd_queue **fifo,
|
||||
uint32_t *cmd)
|
||||
{
|
||||
struct spi_engine_cmd_queue *local_fifo;
|
||||
|
||||
if (!*fifo)
|
||||
return FAILURE;
|
||||
|
||||
local_fifo = *fifo;
|
||||
*cmd = local_fifo->cmd;
|
||||
if ((*fifo)->next) {
|
||||
*fifo = local_fifo->next;
|
||||
free(local_fifo);
|
||||
} else {
|
||||
free(*fifo);
|
||||
*fifo = NULL;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the memory allocated by a queue
|
||||
*
|
||||
* @param fifo The queue that needs it's memory freed
|
||||
* @return int32_t This function always returns SUCCESS
|
||||
*/
|
||||
static int32_t spi_engine_queue_free(struct spi_engine_cmd_queue **fifo)
|
||||
{
|
||||
if(*fifo && (*fifo)->next)
|
||||
spi_engine_queue_free(&(*fifo)->next);
|
||||
if((*fifo) != NULL) {
|
||||
free(*fifo);
|
||||
*fifo = NULL;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the SPI engine's command fifo
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param cmd The command that will be written
|
||||
* @return int32_t Returns FAILURE if the the axi transfer failed
|
||||
*/
|
||||
static int32_t spi_engine_write_cmd_reg(struct spi_engine_desc *desc,
|
||||
uint32_t cmd)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
/* Check if offload is enabled */
|
||||
if(desc->offload_config & (OFFLOAD_TX_EN | OFFLOAD_RX_EN)) {
|
||||
ret = spi_engine_write(desc,
|
||||
SPI_ENGINE_REG_OFFLOAD_CMD_MEM(0),
|
||||
cmd);
|
||||
|
||||
} else {
|
||||
ret = spi_engine_write(desc,
|
||||
SPI_ENGINE_REG_CMD_FIFO,
|
||||
cmd);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a transfer command to the SPI engine's command fifo
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param read_write Read/Write operation flag
|
||||
* @param bytes_number Number of bytes to transfer
|
||||
* @return int32_t This function always returns SUCCESS
|
||||
*/
|
||||
static int32_t spi_engine_transfer(struct spi_engine_desc *desc,
|
||||
uint8_t read_write,
|
||||
uint8_t bytes_number)
|
||||
{
|
||||
uint8_t words_number;
|
||||
|
||||
words_number = spi_get_words_number(desc, bytes_number);
|
||||
|
||||
desc->offload_tx_len += words_number;
|
||||
|
||||
/*
|
||||
* Engine Wiki:
|
||||
*
|
||||
* https://wiki.analog.com/resources/fpga/peripherals/spi_engine
|
||||
*
|
||||
* The words number is zero based
|
||||
*/
|
||||
|
||||
spi_engine_write_cmd_reg(desc,
|
||||
SPI_ENGINE_CMD_TRANSFER(read_write,
|
||||
words_number - 1));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Change the state of the chip select port
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param assert Chip select state.
|
||||
* The supported values are :
|
||||
* -true (HIGH)
|
||||
* -false (LOW)
|
||||
*/
|
||||
static void spi_engine_set_cs(struct spi_desc *desc,
|
||||
bool assert)
|
||||
{
|
||||
uint8_t mask;
|
||||
struct spi_engine_desc *eng_desc;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
mask = 0xFF;
|
||||
/* Switch the state only of the selected chip select */
|
||||
if (!assert)
|
||||
mask ^= BIT(desc->chip_select);
|
||||
|
||||
spi_engine_write_cmd_reg(eng_desc,
|
||||
SPI_ENGINE_CMD_ASSERT(eng_desc->cs_delay,
|
||||
mask));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a delay between the engine commands
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param sleep_time_ns Number of nanoseconds to sleep between commands
|
||||
*/
|
||||
static void spi_gen_sleep_ns(struct spi_desc *desc,
|
||||
uint32_t sleep_time_ns)
|
||||
{
|
||||
uint32_t sleep_div;
|
||||
struct spi_engine_desc *eng_desc;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
spi_get_sleep_div(desc, sleep_time_ns, &sleep_div);
|
||||
|
||||
spi_engine_write_cmd_reg(eng_desc, SPI_ENGINE_CMD_SLEEP(sleep_div));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Spi engine command interpreter
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param cmd Command to send to the engine
|
||||
* @return int32_t - SUCCESS if the command is transferred
|
||||
* - FAILURE if the command format is invalid
|
||||
*/
|
||||
static int32_t spi_engine_write_cmd(struct spi_desc *desc,
|
||||
uint32_t cmd)
|
||||
{
|
||||
uint8_t engine_command;
|
||||
uint8_t parameter;
|
||||
uint8_t modifier;
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
engine_command = (cmd >> 12) & 0x0F;
|
||||
modifier = (cmd >> 8) & 0x0F;
|
||||
parameter = cmd & 0xFF;
|
||||
|
||||
switch(engine_command) {
|
||||
case SPI_ENGINE_INST_TRANSFER:
|
||||
spi_engine_transfer(desc_extra, modifier, parameter);
|
||||
break;
|
||||
|
||||
case SPI_ENGINE_INST_ASSERT:
|
||||
if(parameter == 0xFF) {
|
||||
/* Set the CS HIGH */
|
||||
spi_engine_set_cs(desc, true);
|
||||
} else if(parameter == 0x00) {
|
||||
/* Set the CS LOW */
|
||||
spi_engine_set_cs(desc, false);
|
||||
}
|
||||
break;
|
||||
|
||||
/* The SYNC and SLEEP commands got the same value but different
|
||||
modifier */
|
||||
case SPI_ENGINE_INST_SYNC_SLEEP:
|
||||
/* SYNC instruction */
|
||||
if(modifier == 0x00) {
|
||||
spi_engine_write_cmd_reg(desc_extra, cmd);
|
||||
} else if(modifier == 0x01) {
|
||||
spi_gen_sleep_ns(desc, parameter);
|
||||
}
|
||||
break;
|
||||
case SPI_ENGINE_INST_CONFIG:
|
||||
spi_engine_write_cmd_reg(desc_extra, cmd);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepare the command queue before sending it to the engine
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param msg Structure used to store the transfer messages
|
||||
* @return int32_t This function always returns SUCCESS
|
||||
*/
|
||||
static int32_t spi_engine_compile_message(struct spi_desc *desc,
|
||||
struct spi_engine_msg *msg)
|
||||
{
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
/* Configure the prescaler */
|
||||
spi_engine_queue_append_cmd(&msg->cmds,
|
||||
SPI_ENGINE_CMD_CONFIG(
|
||||
SPI_ENGINE_CMD_REG_CLK_DIV,
|
||||
desc_extra->clk_div));
|
||||
|
||||
/* Set the data transfer length */
|
||||
spi_engine_queue_append_cmd(&msg->cmds,
|
||||
SPI_ENGINE_CMD_CONFIG(
|
||||
SPI_ENGINE_CMD_DATA_TRANSFER_LEN,
|
||||
desc_extra->data_width));
|
||||
/*
|
||||
* Configure the spi mode :
|
||||
* - 3 wire
|
||||
* - CPOL
|
||||
* - CPHA
|
||||
*/
|
||||
spi_engine_queue_append_cmd(&msg->cmds,
|
||||
SPI_ENGINE_CMD_CONFIG(
|
||||
SPI_ENGINE_CMD_REG_CONFIG,
|
||||
desc->mode));
|
||||
|
||||
/* Add a sync command to signal that the transfer has finished */
|
||||
spi_engine_queue_add_cmd(&msg->cmds, SPI_ENGINE_CMD_SYNC(_sync_id));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initiate a spi transfer (Blocking)
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param msg Structure used to store the transfer messages
|
||||
* @return int32_t - SUCCESS if the transfer finished
|
||||
* - FAILURE if the memory allocation failed
|
||||
*/
|
||||
static int32_t spi_engine_transfer_message(struct spi_desc *desc,
|
||||
struct spi_engine_msg *msg)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t data;
|
||||
uint32_t sync_id;
|
||||
bool offload_en;
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
spi_engine_compile_message(desc, msg);
|
||||
|
||||
offload_en = (desc_extra->offload_config & OFFLOAD_TX_EN) |
|
||||
(desc_extra->offload_config & OFFLOAD_RX_EN);
|
||||
|
||||
/* Write the command fifo buffer */
|
||||
while(msg->cmds != NULL) {
|
||||
spi_engine_queue_get_cmd(&msg->cmds, &data);
|
||||
spi_engine_write_cmd(desc, data);
|
||||
}
|
||||
|
||||
/* Write a number of tx_length WORDS on the SDO line */
|
||||
if(offload_en) {
|
||||
for(i = 0; i < desc_extra->offload_tx_len; i++)
|
||||
spi_engine_write(desc_extra,
|
||||
SPI_ENGINE_REG_OFFLOAD_SDO_MEM(0),
|
||||
msg->tx_buf[i]);
|
||||
|
||||
} else {
|
||||
if(msg->tx_buf != NULL){
|
||||
for(i = 0; i < msg->tx_length; i++)
|
||||
spi_engine_write(desc_extra,
|
||||
SPI_ENGINE_REG_SDO_DATA_FIFO,
|
||||
msg->tx_buf[i]);
|
||||
}
|
||||
do {
|
||||
spi_engine_read(desc_extra,
|
||||
SPI_ENGINE_REG_SYNC_ID,
|
||||
&sync_id);
|
||||
}
|
||||
/* Wait for the end sync signal */
|
||||
while(sync_id != _sync_id);
|
||||
_sync_id++;
|
||||
|
||||
/* Read a number of rx_length WORDS from the SDI line and store
|
||||
them */
|
||||
for(i = 0; i < msg->rx_length; i++) {
|
||||
spi_engine_read(desc_extra,
|
||||
SPI_ENGINE_REG_SDI_DATA_FIFO,
|
||||
&data);
|
||||
/* Store the rx data if rx buffer valid, flush sdi_fifo if
|
||||
rx buffer is invalid.*/
|
||||
if(msg->rx_buf != NULL){
|
||||
msg->rx_buf[i] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the spi engine
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param param Structure containing the spi init parameters
|
||||
* @return int32_t - SUCCESS if the transfer finished
|
||||
* - FAILURE if the memory allocation failed
|
||||
*/
|
||||
int32_t spi_engine_init(struct spi_desc **desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
uint32_t data_width;
|
||||
uint32_t spi_engine_version;
|
||||
struct spi_engine_desc *eng_desc;
|
||||
struct spi_engine_init_param *spi_engine_init;
|
||||
|
||||
if (!param) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
*desc = malloc(sizeof(**desc));
|
||||
if(! *desc) {
|
||||
free(*desc);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
eng_desc = (struct spi_engine_desc*)malloc(sizeof(*eng_desc));
|
||||
|
||||
if (!eng_desc)
|
||||
return FAILURE;
|
||||
|
||||
spi_engine_init = param->extra;
|
||||
|
||||
(*desc)->max_speed_hz = param->max_speed_hz;
|
||||
(*desc)->chip_select = param->chip_select;
|
||||
(*desc)->mode = param->mode;
|
||||
(*desc)->extra = eng_desc;
|
||||
|
||||
eng_desc->offload_config = OFFLOAD_DISABLED;
|
||||
eng_desc->spi_engine_baseaddr = spi_engine_init->spi_engine_baseaddr;
|
||||
eng_desc->type = spi_engine_init->type;
|
||||
eng_desc->cs_delay = spi_engine_init->cs_delay;
|
||||
eng_desc->ref_clk_hz = spi_engine_init->ref_clk_hz;
|
||||
eng_desc->clk_div = eng_desc->ref_clk_hz /
|
||||
(2 * param->max_speed_hz) - 1;
|
||||
|
||||
/* Perform a reset */
|
||||
spi_engine_write(eng_desc, SPI_ENGINE_REG_RESET, 0x01);
|
||||
usleep(1000);
|
||||
spi_engine_write(eng_desc, SPI_ENGINE_REG_RESET, 0x00);
|
||||
|
||||
/* Get current data width */
|
||||
spi_engine_read(eng_desc, SPI_ENGINE_REG_DATA_WIDTH, &data_width);
|
||||
eng_desc->max_data_width = data_width;
|
||||
|
||||
spi_engine_set_transfer_width(*desc, spi_engine_init->data_width);
|
||||
|
||||
/* Get spi engine version */
|
||||
spi_engine_read(eng_desc, SPI_ENGINE_REG_VERSION, &spi_engine_version);
|
||||
|
||||
printf("Spi engine v%"PRIu32".%"PRIu32".%"PRIu32" successfully initialized.\n",
|
||||
(spi_engine_version >> 16),
|
||||
((spi_engine_version >> 8) & 0xFF),
|
||||
(spi_engine_version & 0xFF));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write/read on the spi interface in 4-wire mode (full-duplex)
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param data Pointer to data buffer
|
||||
* @param bytes_number Number of bytes to transfer
|
||||
* @return int32_t - SUCCESS if the transfer finished
|
||||
* - FAILURE if the memory allocation or transfer failed
|
||||
*/
|
||||
int32_t spi_engine_write_and_read(struct spi_desc *desc,
|
||||
uint8_t *data,
|
||||
uint16_t bytes_number)
|
||||
{
|
||||
uint8_t word_len;
|
||||
uint8_t words_number;
|
||||
int32_t ret;
|
||||
struct spi_engine_msg msg;
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
/* If we want to access SPI interface and SPI engine offload module was
|
||||
* activated, we need to disable it
|
||||
* This is set in spi_engine_offload_init() */
|
||||
desc_extra->offload_config = OFFLOAD_DISABLED;
|
||||
/* This is set in spi_engine_offload_transfer() */
|
||||
spi_engine_write(desc_extra, SPI_ENGINE_REG_OFFLOAD_CTRL(0), 0);
|
||||
|
||||
words_number = spi_get_words_number(desc_extra, bytes_number);
|
||||
|
||||
msg.cmds = (spi_engine_cmd_queue*)malloc(sizeof(*msg.cmds));
|
||||
if (!msg.cmds)
|
||||
return FAILURE;
|
||||
|
||||
msg.tx_buf =(uint32_t*)calloc(words_number, sizeof(msg.tx_buf[0]));
|
||||
msg.rx_buf =(uint32_t*)calloc(words_number, sizeof(msg.rx_buf[0]));
|
||||
msg.tx_length = words_number;
|
||||
msg.rx_length = words_number;
|
||||
|
||||
/* Get the length of transferred word */
|
||||
word_len = spi_get_word_length(desc_extra);
|
||||
|
||||
/* Make sure the CS is HIGH before starting a transaction */
|
||||
msg.cmds->next = NULL;
|
||||
msg.cmds->cmd = CS_HIGH;
|
||||
// Assert select.
|
||||
spi_engine_queue_add_cmd(&msg.cmds, CS_LOW);
|
||||
// add read/write command
|
||||
spi_engine_queue_add_cmd(&msg.cmds, WRITE_READ(bytes_number));
|
||||
// Disable select.
|
||||
spi_engine_queue_add_cmd(&msg.cmds, CS_HIGH);
|
||||
|
||||
/* Pack the bytes into engine WORDS */
|
||||
for (int i = 0; i < bytes_number; i++)
|
||||
msg.tx_buf[i / word_len] |= data[i] << (desc_extra->data_width-
|
||||
(i % word_len + 1) * 8);
|
||||
|
||||
ret = spi_engine_transfer_message(desc, &msg);
|
||||
|
||||
for (int i = 0; i < bytes_number; i++)
|
||||
data[i] = msg.rx_buf[(i) / word_len] >>
|
||||
(desc_extra->data_width -
|
||||
((i) % word_len + 1) * 8);
|
||||
|
||||
spi_engine_queue_free(&msg.cmds);
|
||||
free(msg.tx_buf);
|
||||
free(msg.rx_buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write and read on the spi interface in 3-wire mode (half-duplex)
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param data Pointer to data buffer
|
||||
* @param bytes_number Number of bytes to transfer
|
||||
* @return int32_t - SUCCESS if the transfer finished
|
||||
* - FAILURE if the memory allocation or transfer failed
|
||||
*/
|
||||
int32_t spi_engine_write_and_read_3wire(struct spi_desc *desc,
|
||||
uint8_t *write_data,
|
||||
uint8_t *read_data,
|
||||
uint16_t write_bytes_number,
|
||||
uint16_t read_bytes_number)
|
||||
{
|
||||
uint8_t word_len;
|
||||
uint8_t wr_words_number;
|
||||
uint8_t rd_words_number;
|
||||
int32_t ret;
|
||||
struct spi_engine_msg msg;
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
/* If we want to access SPI interface and SPI engine offload module was
|
||||
* activated, we need to disable it
|
||||
* This is set in spi_engine_offload_init() */
|
||||
desc_extra->offload_config = OFFLOAD_DISABLED;
|
||||
/* This is set in spi_engine_offload_transfer() */
|
||||
spi_engine_write(desc_extra, SPI_ENGINE_REG_OFFLOAD_CTRL(0), 0);
|
||||
|
||||
wr_words_number = spi_get_words_number(desc_extra, write_bytes_number);
|
||||
rd_words_number = spi_get_words_number(desc_extra, read_bytes_number);
|
||||
|
||||
msg.cmds = (spi_engine_cmd_queue*)malloc(sizeof(*msg.cmds));
|
||||
if (!msg.cmds)
|
||||
return FAILURE;
|
||||
|
||||
msg.tx_buf =(wr_words_number>0)?(uint32_t*)calloc(wr_words_number, sizeof(msg.tx_buf[0])):NULL;
|
||||
msg.rx_buf =(rd_words_number>0)?(uint32_t*)calloc(rd_words_number, sizeof(msg.rx_buf[0])):NULL;
|
||||
msg.tx_length = wr_words_number;
|
||||
msg.rx_length = rd_words_number;
|
||||
|
||||
/* Get the length of transferred word */
|
||||
word_len = spi_get_word_length(desc_extra);
|
||||
|
||||
/* Make sure the CS is HIGH before starting a transaction */
|
||||
msg.cmds->next = NULL;
|
||||
msg.cmds->cmd = CS_HIGH;
|
||||
|
||||
// Assert select.
|
||||
spi_engine_queue_add_cmd(&msg.cmds, CS_LOW);
|
||||
|
||||
// add read/write command
|
||||
if(write_bytes_number > 0)
|
||||
spi_engine_queue_add_cmd(&msg.cmds, WRITE(write_bytes_number));
|
||||
if(read_bytes_number > 0)
|
||||
spi_engine_queue_add_cmd(&msg.cmds, READ(read_bytes_number));
|
||||
|
||||
// Disable select.
|
||||
spi_engine_queue_add_cmd(&msg.cmds, CS_HIGH);
|
||||
|
||||
/* Pack the bytes into engine WORDS */
|
||||
for (int i = 0; i < write_bytes_number; i++)
|
||||
msg.tx_buf[i / word_len] |= write_data[i] << (desc_extra->data_width-
|
||||
(i % word_len + 1) * 8);
|
||||
|
||||
ret = spi_engine_transfer_message(desc, &msg);
|
||||
|
||||
for (int i = 0; i < read_bytes_number; i++)
|
||||
read_data[i] = msg.rx_buf[(i) / word_len] >>
|
||||
(desc_extra->data_width -
|
||||
((i) % word_len + 1) * 8);
|
||||
|
||||
spi_engine_queue_free(&msg.cmds);
|
||||
free(msg.tx_buf);
|
||||
free(msg.rx_buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the SPI engine's offload module
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param param Structure containing the offload init parameters
|
||||
* @return int32_t This function always returns SUCCESS
|
||||
*/
|
||||
int32_t spi_engine_offload_init(struct spi_desc *desc,
|
||||
const struct spi_engine_offload_init_param *param)
|
||||
{
|
||||
struct spi_engine_desc *eng_desc;
|
||||
struct axi_dmac_init dmac_init;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
eng_desc->offload_config = param->offload_config;
|
||||
|
||||
if(!(param->dma_flags)) {
|
||||
eng_desc->cyclic = CYCLIC;
|
||||
} else {
|
||||
if((*(param->dma_flags)) & DMA_CYCLIC)
|
||||
eng_desc->cyclic = CYCLIC;
|
||||
else
|
||||
eng_desc->cyclic = NO;
|
||||
}
|
||||
|
||||
|
||||
if(param->offload_config & OFFLOAD_TX_EN) {
|
||||
dmac_init.name = "DAC DMAC";
|
||||
dmac_init.base = param->tx_dma_baseaddr;
|
||||
axi_dmac_init(&eng_desc->offload_tx_dma, &dmac_init);
|
||||
if(!eng_desc->offload_tx_dma)
|
||||
return FAILURE;
|
||||
}
|
||||
if(param->offload_config & OFFLOAD_RX_EN) {
|
||||
dmac_init.name = "ADC DMAC";
|
||||
dmac_init.base = param->rx_dma_baseaddr;
|
||||
axi_dmac_init(&eng_desc->offload_rx_dma, &dmac_init);
|
||||
if(!eng_desc->offload_rx_dma)
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initiate a SPI transfer in offload mode
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param msg Offload message that get's to be transferred
|
||||
* @param no_samples Number of time the messages will be transferred
|
||||
* @return int32_t This function always returns SUCCESS
|
||||
*/
|
||||
int32_t spi_engine_offload_transfer(struct spi_desc *desc,
|
||||
struct spi_engine_offload_message msg,
|
||||
uint32_t no_samples)
|
||||
{
|
||||
struct spi_engine_msg transfer;
|
||||
struct spi_engine_desc *eng_desc;
|
||||
uint32_t i;
|
||||
uint8_t word_length;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
/* Check if offload is disabled */
|
||||
if(!((eng_desc->offload_config & OFFLOAD_TX_EN) |
|
||||
(eng_desc->offload_config & OFFLOAD_RX_EN)))
|
||||
return FAILURE;
|
||||
|
||||
spi_engine_write(eng_desc, SPI_ENGINE_REG_OFFLOAD_RESET(0), 1);
|
||||
spi_engine_write(eng_desc, SPI_ENGINE_REG_OFFLOAD_RESET(0), 0);
|
||||
|
||||
eng_desc->offload_tx_len = 0;
|
||||
eng_desc->offload_rx_len = 0;
|
||||
|
||||
transfer.cmds = (spi_engine_cmd_queue*)malloc(sizeof(*transfer.cmds));
|
||||
|
||||
if (!transfer.cmds)
|
||||
return -1;
|
||||
|
||||
transfer.tx_buf = msg.commands_data;
|
||||
|
||||
/* Load the commands into the message */
|
||||
transfer.cmds->next = NULL;
|
||||
transfer.cmds->cmd = msg.commands[0];
|
||||
i = 1;
|
||||
while(i < msg.no_commands) {
|
||||
spi_engine_queue_add_cmd(&transfer.cmds, msg.commands[i++]);
|
||||
|
||||
}
|
||||
|
||||
spi_engine_transfer_message(desc, &transfer);
|
||||
|
||||
/* Start transfer */
|
||||
spi_engine_write(eng_desc, SPI_ENGINE_REG_OFFLOAD_CTRL(0), 0x0001);
|
||||
|
||||
word_length = spi_get_word_length(eng_desc);
|
||||
if(eng_desc->offload_config & OFFLOAD_TX_EN) {
|
||||
struct axi_dma_transfer tx_transfer = {
|
||||
// Number of bytes to write/read
|
||||
.size = word_length * eng_desc->offload_tx_len * no_samples,
|
||||
// Transfer done flag
|
||||
.transfer_done = 0,
|
||||
// Signal transfer mode
|
||||
.cyclic = eng_desc->cyclic,
|
||||
// Address of data source
|
||||
.src_addr = (uintptr_t)msg.tx_addr,
|
||||
// Address of data destination
|
||||
.dest_addr = 0
|
||||
};
|
||||
axi_dmac_transfer_start(eng_desc->offload_tx_dma, &tx_transfer);
|
||||
}
|
||||
|
||||
if(eng_desc->offload_config & OFFLOAD_RX_EN) {
|
||||
struct axi_dma_transfer rx_transfer = {
|
||||
// Number of bytes to write/read
|
||||
.size = word_length * eng_desc->offload_tx_len * no_samples,
|
||||
// Transfer done flag
|
||||
.transfer_done = 0,
|
||||
// Signal transfer mode
|
||||
.cyclic = NO,
|
||||
// Address of data source
|
||||
.src_addr = 0,
|
||||
// Address of data destination
|
||||
.dest_addr = (uintptr_t)msg.rx_addr
|
||||
};
|
||||
axi_dmac_transfer_start(eng_desc->offload_rx_dma, &rx_transfer);
|
||||
axi_dmac_transfer_wait_completion(eng_desc->offload_rx_dma, 500);
|
||||
}
|
||||
|
||||
usleep(1000);
|
||||
|
||||
spi_engine_queue_free(&transfer.cmds);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by spi_init().
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @return int32_t This function allways returns SUCCESS
|
||||
*/
|
||||
int32_t spi_engine_remove(struct spi_desc *desc)
|
||||
{
|
||||
struct spi_engine_desc *eng_desc;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
if(eng_desc->offload_config & OFFLOAD_TX_EN)
|
||||
axi_dmac_remove(eng_desc->offload_tx_dma);
|
||||
if(eng_desc->offload_config & OFFLOAD_RX_EN)
|
||||
axi_dmac_remove(eng_desc->offload_rx_dma);
|
||||
free(desc->extra);
|
||||
free(desc);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/*******************************************************************************
|
||||
* @file spi_engine.h
|
||||
* @brief Header file of SPI Engine core features.
|
||||
* @author Sergiu Cuciurean ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef SPI_ENGINE_H
|
||||
#define SPI_ENGINE_H
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "spi_engine_private.h"
|
||||
#include "../axi_dmac/axi_dmac.h"
|
||||
#include "../../platform/xilinx_spi.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define OFFLOAD_DISABLED 0x00
|
||||
#define OFFLOAD_TX_EN BIT(0)
|
||||
#define OFFLOAD_RX_EN BIT(1)
|
||||
#define OFFLOAD_TX_RX_EN OFFLOAD_TX_EN | OFFLOAD_RX_EN
|
||||
|
||||
#define SPI_ENGINE_MSG_QUEUE_END 0xFFFFFFFF
|
||||
|
||||
/* Spi engine commands */
|
||||
#define WRITE(no_bytes) ((SPI_ENGINE_INST_TRANSFER << 12) |\
|
||||
(SPI_ENGINE_INSTRUCTION_TRANSFER_W << 8) | no_bytes)
|
||||
|
||||
#define READ(no_bytes) ((SPI_ENGINE_INST_TRANSFER << 12) |\
|
||||
(SPI_ENGINE_INSTRUCTION_TRANSFER_R << 8) | no_bytes)
|
||||
|
||||
#define WRITE_READ(no_bytes) ((SPI_ENGINE_INST_TRANSFER << 12) |\
|
||||
(SPI_ENGINE_INSTRUCTION_TRANSFER_RW << 8) | no_bytes)
|
||||
|
||||
#define SLEEP(time) SPI_ENGINE_CMD_SLEEP(time & 0xF)
|
||||
|
||||
/* The delay and chip select parmeters are passed over the engine descriptor
|
||||
and will be used inside the function call */
|
||||
#define CS_HIGH SPI_ENGINE_CMD_ASSERT(0x01, 0xFF)
|
||||
#define CS_LOW SPI_ENGINE_CMD_ASSERT(0x01, 0x00)
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @struct spi_engine_init_param
|
||||
* @brief Structure containing the init parameters needed by the SPI engine
|
||||
*/
|
||||
struct spi_engine_init_param {
|
||||
/** SPI engine reference clock */
|
||||
uint32_t ref_clk_hz;
|
||||
/** Type of implementation */
|
||||
enum xil_spi_type type;
|
||||
/** Base address where the HDL core is situated */
|
||||
uint32_t spi_engine_baseaddr;
|
||||
/** Delay between the CS toggle and the start of SCLK */
|
||||
uint32_t cs_delay;
|
||||
/** Data with of one SPI transfer ( in bits ) */
|
||||
uint8_t data_width;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @struct spi_engine_desc
|
||||
* @brief Structure representing an SPI engine device
|
||||
*/
|
||||
struct spi_engine_desc {
|
||||
/** SPI engine reference clock */
|
||||
uint32_t ref_clk_hz;
|
||||
/** Type of implementation */
|
||||
enum xil_spi_type type;
|
||||
/** Pointer to a DMAC used in transmission */
|
||||
struct axi_dmac *offload_tx_dma;
|
||||
/** Pointer to a DMAC used in reception */
|
||||
struct axi_dmac *offload_rx_dma;
|
||||
/** Transfer mode for Tx DMAC */
|
||||
enum cyclic_transfer cyclic;
|
||||
/** Offload's module transfer direction : TX, RX or both */
|
||||
uint8_t offload_config;
|
||||
/** Number of words that the module has to send */
|
||||
uint8_t offload_tx_len;
|
||||
/** Number of words that the module has to receive */
|
||||
uint8_t offload_rx_len;
|
||||
/** Base address where the HDL core is situated */
|
||||
uint32_t spi_engine_baseaddr;
|
||||
/** Base address where the RX DMAC core is situated */
|
||||
uint32_t rx_dma_baseaddr;
|
||||
/** Base address where the TX DMAC core is situated */
|
||||
uint32_t tx_dma_baseaddr;
|
||||
/** Delay between the CS toggle and the start of SCLK */
|
||||
uint8_t cs_delay;
|
||||
/** Clock divider used in transmission delays */
|
||||
uint32_t clk_div;
|
||||
/** Data with of one SPI transfer ( in bits ) */
|
||||
uint8_t data_width;
|
||||
/** The maximum data width supported by the engine */
|
||||
uint8_t max_data_width;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @struct spi_engine_offload_init_param
|
||||
* @brief Structure containing the init parameters needed by the offload module
|
||||
*/
|
||||
struct spi_engine_offload_init_param {
|
||||
/** Base address where the RX DMAC core is situated */
|
||||
uint32_t rx_dma_baseaddr;
|
||||
/** Base address where the TX DMAC core is situated */
|
||||
uint32_t tx_dma_baseaddr;
|
||||
/** DMAC flags - if not initialized, the default value is DMA_CYCLIC */
|
||||
uint32_t *dma_flags;
|
||||
/** Offload's module transfer direction : TX, RX or both */
|
||||
uint8_t offload_config;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct spi_engine_offload_message
|
||||
* @brief Structure representing an offload message
|
||||
*/
|
||||
struct spi_engine_offload_message {
|
||||
/** Pointer to the SPI engine commands buffer that will be sent.
|
||||
* The available commands can be found at:
|
||||
* https://wiki.analog.com/resources/fpga/peripherals/spi_engine/
|
||||
*/
|
||||
uint32_t *commands;
|
||||
/** Length of the SPI engine commands buffer */
|
||||
uint32_t no_commands;
|
||||
/** Pointer of the data that will be sent over spi */
|
||||
uint32_t *commands_data;
|
||||
/** The address where the data that will be transmitted is situated */
|
||||
uint32_t tx_addr;
|
||||
/** The address where the data that will be received is situated */
|
||||
uint32_t rx_addr;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Spi engine platform specific SPI platform ops structure
|
||||
*/
|
||||
extern const struct spi_platform_ops xil_spi_ops;
|
||||
|
||||
/* Write SPI Engine's axi registers */
|
||||
int32_t spi_engine_write(struct spi_engine_desc *desc,
|
||||
uint32_t reg_addr,
|
||||
uint32_t reg_data);
|
||||
|
||||
/* Read SPI Engine's axi registers */
|
||||
int32_t spi_engine_read(struct spi_engine_desc *desc,
|
||||
uint32_t reg_addr,
|
||||
uint32_t *reg_data);
|
||||
/* Initialize the SPI engine device */
|
||||
int32_t spi_engine_init(struct spi_desc **desc,
|
||||
const struct spi_init_param *param);
|
||||
|
||||
/* Write and read data over SPI using the SPI engine */
|
||||
int32_t spi_engine_write_and_read(struct spi_desc *desc,
|
||||
uint8_t *data,
|
||||
uint16_t bytes_number);
|
||||
|
||||
/* Write and read data over SPI using the SPI engine in 3-wire mode */
|
||||
int32_t spi_engine_write_and_read_3wire(struct spi_desc *desc,
|
||||
uint8_t *write_data,
|
||||
uint8_t *read_data,
|
||||
uint16_t write_bytes_number,
|
||||
uint16_t read_bytes_number);
|
||||
/* Free the resources used by the SPI engine device */
|
||||
int32_t spi_engine_remove(struct spi_desc *desc);
|
||||
|
||||
/* Initialize the SPI engine offload module */
|
||||
int32_t spi_engine_offload_init(struct spi_desc *desc,
|
||||
const struct spi_engine_offload_init_param *param);
|
||||
|
||||
/* Write and read data over SPI using the offload module */
|
||||
int32_t spi_engine_offload_transfer(struct spi_desc *desc,
|
||||
struct spi_engine_offload_message msg,
|
||||
uint32_t no_samples);
|
||||
|
||||
/* Set SPI transfer width */
|
||||
int32_t spi_engine_set_transfer_width(struct spi_desc *desc,
|
||||
uint8_t data_wdith);
|
||||
|
||||
/* Set SPI transfer speed */
|
||||
void spi_engine_set_speed(struct spi_desc *desc,
|
||||
uint32_t speed_hz);
|
||||
|
||||
#endif // SPI_ENGINE_H
|
||||
@@ -0,0 +1,154 @@
|
||||
/*******************************************************************************
|
||||
* @file spi_engine_private.h
|
||||
* @brief Private definitions of the SPI Engine
|
||||
* @author Sergiu Cuciurean ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef SPI_ENGINE_PRIVATE_H
|
||||
#define SPI_ENGINE_PRIVATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "spi.h"
|
||||
#include "util.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Spi Engine registers *****************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define SPI_ENGINE_REG_VERSION 0x00
|
||||
#define SPI_ENGINE_REG_DATA_WIDTH 0x0C
|
||||
#define SPI_ENGINE_REG_RESET 0x40
|
||||
#define SPI_ENGINE_REG_INT_ENABLE 0x80
|
||||
#define SPI_ENGINE_REG_INT_PENDING 0x84
|
||||
#define SPI_ENGINE_REG_INT_SOURCE 0x88
|
||||
#define SPI_ENGINE_REG_SYNC_ID 0xC0
|
||||
#define SPI_ENGINE_REG_CMD_FIFO_ROOM 0xD0
|
||||
#define SPI_ENGINE_REG_SDO_FIFO_ROOM 0xD4
|
||||
#define SPI_ENGINE_REG_SDI_FIFO_LEVEL 0xD8
|
||||
#define SPI_ENGINE_REG_CMD_FIFO 0xE0
|
||||
#define SPI_ENGINE_REG_SDO_DATA_FIFO 0xE4
|
||||
#define SPI_ENGINE_REG_SDI_DATA_FIFO 0xE8
|
||||
#define SPI_ENGINE_REG_SDI_DATA_FIFO_PEEK 0xEC
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Spi Engine register parameters **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define SPI_ENGINE_INST_TRANSFER 0x00
|
||||
#define SPI_ENGINE_INST_ASSERT 0x01
|
||||
#define SPI_ENGINE_INST_CONFIG 0x02
|
||||
#define SPI_ENGINE_INST_SYNC_SLEEP 0x03
|
||||
#define SPI_ENGINE_INST_MISC 0x03
|
||||
#define SPI_ENGINE_CMD_REG_CLK_DIV 0x00
|
||||
#define SPI_ENGINE_CMD_REG_CONFIG 0x01
|
||||
#define SPI_ENGINE_CMD_DATA_TRANSFER_LEN 0x02
|
||||
#define SPI_ENGINE_MISC_SYNC 0x00
|
||||
#define SPI_ENGINE_MISC_SLEEP 0x01
|
||||
#define SPI_ENGINE_SYNC_TRANSFER_BEGIN BIT(1)
|
||||
#define SPI_ENGINE_SYNC_TRANSFER_END BIT(2)
|
||||
#define SPI_ENGINE_INT_CMD_ALMOST_EMPTY BIT(0)
|
||||
#define SPI_ENGINE_INT_SDO_ALMOST_EMPTY BIT(1)
|
||||
#define SPI_ENGINE_INT_SDI_ALMOST_FULL BIT(2)
|
||||
#define SPI_ENGINE_INT_SYNC BIT(3)
|
||||
#define SPI_ENGINE_OFFLOAD_CTRL_ENABLE BIT(0)
|
||||
#define SPI_ENGINE_OFFLOAD_STATUS_ENABLED BIT(0)
|
||||
#define SPI_ENGINE_CONFIG_CPHA BIT(0)
|
||||
#define SPI_ENGINE_CONFIG_CPOL BIT(1)
|
||||
#define SPI_ENGINE_CONFIG_3WIRE BIT(2)
|
||||
#define SPI_ENGINE_VERSION_MAJOR(x) ((x >> 16) & 0xff)
|
||||
#define SPI_ENGINE_VERSION_MINOR(x) ((x >> 8) & 0xff)
|
||||
#define SPI_ENGINE_VERSION_PATCH(x) (x & 0xff)
|
||||
|
||||
/******************************************************************************/
|
||||
/**************************** Spi Engine commands *****************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define SPI_ENGINE_INSTRUCTION_TRANSFER_W 0x01
|
||||
#define SPI_ENGINE_INSTRUCTION_TRANSFER_R 0x02
|
||||
#define SPI_ENGINE_INSTRUCTION_TRANSFER_RW 0x03
|
||||
|
||||
#define SPI_ENGINE_REG_OFFLOAD_CTRL(x) (0x100 + (0x20 * x))
|
||||
#define SPI_ENGINE_REG_OFFLOAD_STATUS(x) (0x104 + (0x20 * x))
|
||||
#define SPI_ENGINE_REG_OFFLOAD_RESET(x) (0x108 + (0x20 * x))
|
||||
#define SPI_ENGINE_REG_OFFLOAD_CMD_MEM(x) (0x110 + (0x20 * x))
|
||||
#define SPI_ENGINE_REG_OFFLOAD_SDO_MEM(x) (0x114 + (0x20 * x))
|
||||
|
||||
#define SPI_ENGINE_CMD(inst, arg1, arg2) \
|
||||
(((inst & 0x03) << 12) | \
|
||||
((arg1 & 0x03) << 8) | arg2 )
|
||||
|
||||
#define SPI_ENGINE_CMD_TRANSFER(readwrite, n) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_TRANSFER, \
|
||||
(readwrite), (n))
|
||||
|
||||
#define SPI_ENGINE_CMD_ASSERT(delay, cs) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_ASSERT, \
|
||||
(delay), (cs))
|
||||
|
||||
#define SPI_ENGINE_CMD_CONFIG(reg, val) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_CONFIG, \
|
||||
(reg), (val))
|
||||
|
||||
#define SPI_ENGINE_CMD_SLEEP(delay) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, \
|
||||
SPI_ENGINE_MISC_SLEEP, \
|
||||
(delay))
|
||||
|
||||
#define SPI_ENGINE_CMD_SYNC(id) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, \
|
||||
SPI_ENGINE_MISC_SYNC, \
|
||||
(id))
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
typedef struct spi_engine_cmd_queue {
|
||||
uint32_t cmd;
|
||||
struct spi_engine_cmd_queue *next;
|
||||
} spi_engine_cmd_queue;
|
||||
|
||||
typedef struct spi_engine_msg {
|
||||
uint32_t *tx_buf;
|
||||
uint32_t *rx_buf;
|
||||
uint32_t tx_length;
|
||||
uint32_t rx_length;
|
||||
struct spi_engine_cmd_queue *cmds;
|
||||
} spi_engine_msg;
|
||||
|
||||
#endif // SPI_ENGINE_PRIVATE_H
|
||||
@@ -0,0 +1,783 @@
|
||||
/**
|
||||
* \file ad9528.c
|
||||
* \brief Contains source code for configuring and initializing AD9528 clock device
|
||||
*/
|
||||
|
||||
/**
|
||||
* \page Disclaimer Legal Disclaimer
|
||||
* Copyright 2015-2017 Analog Devices Inc.
|
||||
* Released under the AD9371 API license.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "ad9528.h"
|
||||
#include "../../../include/error.h"
|
||||
|
||||
static uint32_t _desired_time_to_elapse_ms = 0;
|
||||
|
||||
/**
|
||||
* \brief Write data to a register
|
||||
*/
|
||||
int32_t AD9528_spiWriteByte(ad9528Device_t *device, uint16_t addr,
|
||||
uint8_t data)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
int32_t status;
|
||||
|
||||
buf[0] = (addr >> 8) & 0x7F;
|
||||
buf[1] = addr & 0xFF;
|
||||
buf[2] = data;
|
||||
status = spi_write_and_read_3wire(device->spi_desc,
|
||||
buf, NULL, 3, 0);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Read data from a register
|
||||
*/
|
||||
int32_t AD9528_spiReadByte(ad9528Device_t *device, uint16_t addr,
|
||||
uint8_t *readdata)
|
||||
{
|
||||
uint8_t tx_buf[2];
|
||||
uint8_t rx_buf[1];
|
||||
int32_t status;
|
||||
|
||||
tx_buf[0] = 0x80 | addr >> 8;
|
||||
tx_buf[1] = addr & 0xFF;
|
||||
|
||||
status = spi_write_and_read_3wire(device->spi_desc,
|
||||
tx_buf, rx_buf, 2, 1);
|
||||
|
||||
*readdata = rx_buf[0];
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Modify a field of bits from a register
|
||||
*/
|
||||
int32_t AD9528_spiWriteField(ad9528Device_t *device,
|
||||
uint16_t addr, uint8_t fieldVal, uint8_t mask, uint8_t startBit)
|
||||
{
|
||||
int32_t errVal;
|
||||
uint8_t readVal;
|
||||
|
||||
errVal = AD9528_spiReadByte(device, addr, &readVal);
|
||||
if (errVal < 0)
|
||||
return errVal;
|
||||
|
||||
readVal = (readVal & ~mask) | ((fieldVal << startBit) & mask);
|
||||
|
||||
return AD9528_spiWriteByte(device, addr, readVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the desired timeout value
|
||||
*/
|
||||
int32_t AD9528_setTimeout_ms(uint32_t timeOut_ms)
|
||||
{
|
||||
_desired_time_to_elapse_ms = timeOut_ms;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Verify if the desired time has elapsed
|
||||
*/
|
||||
int32_t AD9528_hasTimeoutExpired()
|
||||
{
|
||||
udelay(1000);
|
||||
|
||||
_desired_time_to_elapse_ms--;
|
||||
if (_desired_time_to_elapse_ms > 0)
|
||||
return SUCCESS;
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Performs a hard reset on the AD9528 DUT
|
||||
*
|
||||
* <B>Dependencies</B>
|
||||
* - device->spiSettings->chipSelectIndex
|
||||
*
|
||||
* \param device is structure pointer to the AD9528 data structure containing settings
|
||||
* \return Returns enum ADI_ERR, ADIERR_OK=pass, !ADIERR_OK=fail
|
||||
*/
|
||||
int32_t AD9528_resetDevice(ad9528Device_t *device)
|
||||
{
|
||||
gpio_direction_output(device->gpio_resetb, 0);
|
||||
mdelay(100);
|
||||
gpio_direction_output(device->gpio_resetb, 1);
|
||||
mdelay(100);
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_ADI_SPI_CONFIG_A, 0x81);
|
||||
mdelay(100);
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_ADI_SPI_CONFIG_A, 0x00);
|
||||
mdelay(100);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets the AD9528 device SPI settings (3wire/4wire, MSBFirst, etc).
|
||||
*
|
||||
* This function will use the settings in the device->spiSettings structure
|
||||
* to set SPI stream mode, address auto increment direction, MSBFirst/LSBfirst,
|
||||
* and 3wire/4wire mode. The AD9528 device always uses SPI MODE 0 (CPHA=0, CPOL=0).
|
||||
* This function will update your device->spiSettings to set CHPA=0 and CPOL=0 and
|
||||
* longInstructionWord =1 to use a 16bit instruction word.
|
||||
*
|
||||
* <B>Dependencies</B>
|
||||
* - writes device->spiSettings->CPHA = 0
|
||||
* - writes device->spiSettings->CPOL = 0
|
||||
* - writes device->spiSettings->longInstructionWord = 1
|
||||
*
|
||||
* - device->spiSettings->MSBFirst
|
||||
* - device->spiSettings->enSpiStreaming
|
||||
* - device->spiSettings->autoIncAddrUp
|
||||
* - device->spiSettings->fourWireMode
|
||||
*
|
||||
* \param device is structure pointer to the AD9528 data structure containing settings
|
||||
*
|
||||
* \return Returns enum ADI_ERR, ADIERR_OK=pass, !ADIERR_OK=fail
|
||||
*/
|
||||
int32_t AD9528_setSpiSettings(ad9528Device_t *device)
|
||||
{
|
||||
uint8_t spiReg = 0;
|
||||
|
||||
device->spiSettings->CPHA = 0;
|
||||
device->spiSettings->CPOL = 0;
|
||||
device->spiSettings->longInstructionWord = 1;
|
||||
|
||||
if (device->spiSettings->MSBFirst == 0) {
|
||||
spiReg |= 0x42; /* SPI bit is 1=LSB first */
|
||||
}
|
||||
|
||||
if (device->spiSettings->autoIncAddrUp > 0) {
|
||||
spiReg |= 0x24;
|
||||
}
|
||||
|
||||
if (device->spiSettings->fourWireMode > 0) {
|
||||
spiReg |= 0x18;
|
||||
}
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_ADI_SPI_CONFIG_A, spiReg);
|
||||
|
||||
if (device->spiSettings->enSpiStreaming > 0) {
|
||||
/* Allow SPI streaming mode: SPI message ends when chip select deasserts */
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_ADI_SPI_CONFIG_B, 0x00);
|
||||
} else {
|
||||
/* Force single instruction mode */
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_ADI_SPI_CONFIG_B, 0x80);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Helper function for ADI transceiver eval boards to init the AD9528 data structure
|
||||
*
|
||||
* This function inits the AD9528 device data structure with defaults that
|
||||
* are known to work with the ADI AD9369 and AD9371 evaluation boards. NOTE: This function will
|
||||
* modify the contents of the AD9528 device data structure.
|
||||
*
|
||||
* <B>Dependencies</B>
|
||||
* - spi->chipSelectIndex
|
||||
* - spi
|
||||
*
|
||||
* \param device Pointer to the AD9528 device data structure to initialize
|
||||
* \param vcxoFrequency_Hz The VCXO frequency that is connected to the AD9528
|
||||
* \param refAFrequency_Hz The reference clock frequency being input into the AD9528 REFCLK A input
|
||||
* \param outputDeviceClock_Hz Desired output clock frequency to the FPGA and transceiver device
|
||||
*
|
||||
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
|
||||
*/
|
||||
int32_t AD9528_initDeviceDataStruct(ad9528Device_t *device,
|
||||
uint32_t vcxoFrequency_Hz, uint32_t refAFrequency_Hz,
|
||||
uint32_t outputDeviceClock_Hz)
|
||||
{
|
||||
// uint16_t chDiv;
|
||||
// uint8_t i = 0;
|
||||
//
|
||||
// uint32_t pll1PfdFreq_Hz = 0;
|
||||
// uint8_t pll1Ndiv = 0;
|
||||
// uint8_t validPll1DivSetting = 0;
|
||||
// uint8_t refAdiv = 1;
|
||||
//
|
||||
//
|
||||
// uint8_t pll2RfDiv = 3; /* Valid values 3,4,5 */
|
||||
// uint16_t pll2Ndiv = 1; /* Valid values 1-256 */
|
||||
// uint32_t pll2InputFreq_Hz = 0;
|
||||
// uint64_t pll2VcoFreq_Hz = 0;
|
||||
// uint16_t pll2NdivStart = 0;
|
||||
// uint8_t validPll2DivSetting = 0;
|
||||
// uint64_t chDivU64 = 0;
|
||||
//
|
||||
// static const uint64_t PLL2_MIN_VCO_FREQ_HZ = 3450000000ULL;
|
||||
// static const uint64_t PLL2_MAX_VCO_FREQ_HZ = 4025000000ULL;
|
||||
|
||||
// struct spi_init_param spi_param;
|
||||
// int32_t status;
|
||||
//
|
||||
// status = gpio_get(&device->gpio_resetb, CLK_RESETB);
|
||||
// status |= gpio_get(&device->gpio_sysref_req, ADRV_SYSREF_REQ);
|
||||
//
|
||||
// spi_param.id = 0;
|
||||
// spi_param.mode = SPI_MODE_0;
|
||||
// spi_param.chip_select = CLK_CS;
|
||||
// status |= spi_init(&device->spi_desc, &spi_param);
|
||||
//
|
||||
// if (status != SUCCESS)
|
||||
// return FAILURE;
|
||||
|
||||
/*******************************************************************
|
||||
* PLL1 Settings
|
||||
*******************************************************************
|
||||
*/
|
||||
|
||||
/* find valid PLL1 Ndiv and REFA div */
|
||||
// for (pll1Ndiv = 1; pll1Ndiv < 20; pll1Ndiv++) {
|
||||
// pll1PfdFreq_Hz = vcxoFrequency_Hz / pll1Ndiv;
|
||||
//
|
||||
// if ((pll1PfdFreq_Hz <= 110000000) && (pll1PfdFreq_Hz >= 1000000) &&
|
||||
// (pll1PfdFreq_Hz <= refAFrequency_Hz) &&
|
||||
// (refAFrequency_Hz % pll1PfdFreq_Hz == 0)
|
||||
// ) {
|
||||
// validPll1DivSetting = 1;
|
||||
// refAdiv = refAFrequency_Hz / pll1PfdFreq_Hz ;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (validPll1DivSetting == 0) {
|
||||
// return FAILURE;
|
||||
// }
|
||||
|
||||
// device->pll1Settings->nDivider =
|
||||
// pll1Ndiv; //This init function always runs PLL1 at 30.72MHz Pfd rate
|
||||
// device->pll1Settings->refA_bufferCtrl =
|
||||
// DIFFERENTIAL; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL
|
||||
// device->pll1Settings->refA_Divider = refAdiv;
|
||||
// device->pll1Settings->refA_Frequency_Hz = refAFrequency_Hz;
|
||||
// device->pll1Settings->refB_bufferCtrl =
|
||||
// DISABLED; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL
|
||||
// device->pll1Settings->refB_Divider = 1;
|
||||
// device->pll1Settings->refB_Frequency_Hz = 0;
|
||||
// device->pll1Settings->vcxoBufferCtrl =
|
||||
// NEG_SINGLE_ENDED; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL
|
||||
// device->pll1Settings->vcxo_Frequency_Hz = vcxoFrequency_Hz;
|
||||
|
||||
/*******************************************************************
|
||||
* PLL2 Settings
|
||||
*******************************************************************
|
||||
*/
|
||||
|
||||
/*******************************************************************
|
||||
* Output Distribution Settings
|
||||
* 9369CE02A uses the following clock outputs
|
||||
* OUT 1: FPGA REFCLK
|
||||
* OUT 3: FPGA SYSREF
|
||||
* OUT 12: DUT SYSREF
|
||||
* OUT 13: DUT REFCLK
|
||||
*******************************************************************
|
||||
*/
|
||||
|
||||
/* PLL 2 input clock can be several different things. Currently hard coded by this init funciton to use
|
||||
* PLL 1 output (VCXO Frequency) with no scaling
|
||||
*/
|
||||
// pll2InputFreq_Hz = device->pll1Settings->vcxo_Frequency_Hz;
|
||||
// validPll2DivSetting = 0;
|
||||
|
||||
/* Sweep PLL2 Divider settings to find something that has a valid integer divide (3,4,5)*/
|
||||
// for (pll2RfDiv = 3; pll2RfDiv <= 5; pll2RfDiv++) {
|
||||
//
|
||||
// pll2NdivStart = (PLL2_MIN_VCO_FREQ_HZ / pll2RfDiv / pll2InputFreq_Hz);
|
||||
// /* find valid PLL2 Ndiv (1-256) */
|
||||
// for (pll2Ndiv = pll2NdivStart; pll2Ndiv <= 256; pll2Ndiv++) {
|
||||
// pll2VcoFreq_Hz = (pll2InputFreq_Hz * pll2RfDiv * pll2Ndiv);
|
||||
//
|
||||
// if (pll2VcoFreq_Hz < PLL2_MIN_VCO_FREQ_HZ) {
|
||||
// /* Continue to next PLL2 N div */
|
||||
// continue;
|
||||
// } else if (pll2VcoFreq_Hz > PLL2_MAX_VCO_FREQ_HZ) {
|
||||
// /* Break to next PLL2 RF div */
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// if (((pll2VcoFreq_Hz / pll2RfDiv) % outputDeviceClock_Hz) == 0) {
|
||||
//
|
||||
// device->pll2Settings->rfDivider = pll2RfDiv;
|
||||
// device->pll2Settings->n2Divider = pll2Ndiv;
|
||||
// device->pll2Settings->totalNdiv = pll2RfDiv * pll2Ndiv;
|
||||
// chDivU64 = ((pll2VcoFreq_Hz / pll2RfDiv) / outputDeviceClock_Hz);
|
||||
//
|
||||
// if ((chDivU64 < 1) || (chDivU64 > 256)) {
|
||||
// return FAILURE;
|
||||
// } else {
|
||||
// chDiv = (uint16_t)(chDivU64);
|
||||
// }
|
||||
//
|
||||
// validPll2DivSetting = 1;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (validPll2DivSetting == 1) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (validPll2DivSetting == 0) {
|
||||
// return FAILURE;
|
||||
// }
|
||||
//
|
||||
// device->outputSettings->outPowerDown = (uint16_t)(
|
||||
// ~0x318A); //enable outputs 13,12,8,7,3 and 1
|
||||
//
|
||||
// for (i=0; i<14; i++) {
|
||||
// device->outputSettings->outSource[i] =
|
||||
// CHANNEL_DIV; //CHANNEL_DIV , PLL1_OUTPUT, SYSREF, INV_PLL1_OUTPUT
|
||||
// device->outputSettings->outBufferCtrl[i] = LVDS; //LVDS, LVDS_BOOST, HSTL
|
||||
// device->outputSettings->outChannelDiv[i] = chDiv;
|
||||
// device->outputSettings->outFrequency_Hz[i] = outputDeviceClock_Hz;
|
||||
// device->outputSettings->outAnalogDelay[i] = 0;
|
||||
// device->outputSettings->outDigitalDelay[i] = 0;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// device->outputSettings->outSource[3] = SYSREF;
|
||||
// device->outputSettings->outSource[7] = SYSREF;
|
||||
// device->outputSettings->outSource[12] = SYSREF;
|
||||
//
|
||||
//
|
||||
// device->sysrefSettings->sysrefDivide =
|
||||
// 512; //SYSREF frequency = VCXO / 2 / sysrefDivde
|
||||
// device->sysrefSettings->sysrefNshotMode =
|
||||
// ONE_PULSE; //ONE_PULSE=0, TWO_PULSES=2, FOUR_PULSES=3, SIX_PULSES=4, EIGHT_PULSES=5
|
||||
// device->sysrefSettings->sysrefPatternMode =
|
||||
// CONTINUOUS; //NSHOT=0, CONTINUOUS=1, PRBS=2, STOP=3
|
||||
// device->sysrefSettings->sysrefPinBufferMode =
|
||||
// DISABLED; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL
|
||||
// device->sysrefSettings->sysrefPinEdgeMode =
|
||||
// LEVEL_ACTIVE_HIGH; //LEVEL_ACTIVE_HIGH=0, LEVEL_ACTIVE_LOW=1, RISING_EDGE=2, FALLING_EDGE=3
|
||||
// device->sysrefSettings->sysrefRequestMethod = PIN; //SPI=0,PIN=1
|
||||
// device->sysrefSettings->sysrefSource =
|
||||
// INTERNAL; //EXTERNAL=0, EXT_RESAMPLED=1, INTERNAL=2
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int32_t AD9528_init(ad9528Device_t **device, const ad9528Init_t *init_device)
|
||||
{
|
||||
int ret = SUCCESS;
|
||||
ad9528Device_t *dev;
|
||||
|
||||
dev = (ad9528Device_t *)malloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
return FAILURE;
|
||||
|
||||
/* SPI */
|
||||
ret = spi_init(&dev->spi_desc, init_device->spi_init);
|
||||
ret |= gpio_get(&dev->gpio_resetb, init_device->gpio_init_resetb);
|
||||
ret |= gpio_get(&dev->gpio_sysref_req, init_device->gpio_init_sysref_req);
|
||||
|
||||
gpio_direction_output(dev->gpio_resetb, 0);
|
||||
gpio_direction_output(dev->gpio_sysref_req, 0);
|
||||
|
||||
AD9528_resetDevice(dev);
|
||||
|
||||
dev->spiSettings = init_device->spiSettings;
|
||||
dev->pll1Settings = init_device->pll1Settings;
|
||||
dev->pll2Settings = init_device->pll2Settings;
|
||||
dev->outputSettings = init_device->outputSettings;
|
||||
dev->sysrefSettings = init_device->sysrefSettings;
|
||||
|
||||
*device = dev;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initializes the AD9528 by writing all SPI registers
|
||||
*
|
||||
* Initializes the AD9528 for use with the AD9369 transceiver. Designed to work with
|
||||
* a reference clock of 122.88MHz. Reference clock is expected to be 30.72MHz.
|
||||
* The output clocks from the AD9528 can run at 122.88M, 153.6M, 184.32M, 245.76M, or 307.2M.
|
||||
* Typical setup: REFA frequency = 30.72, VCXO = 122.88MHz
|
||||
* SYNC(SYSREF) pulses output at rate of 120kHz
|
||||
*
|
||||
* <B>Dependencies</B>
|
||||
* - All parameters in device structure
|
||||
*
|
||||
* \param device is structure pointer to AD9528 clock device structure
|
||||
*
|
||||
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
|
||||
*/
|
||||
int32_t AD9528_config(ad9528Device_t
|
||||
*device) //writes all registers to desired values, leaves clock outputs off, SYSREF output disabled.
|
||||
{
|
||||
uint8_t pll2_Adiv=0;
|
||||
uint8_t pll2_Bdiv=0;
|
||||
uint8_t reg108=0;
|
||||
uint8_t reg109=0x4;
|
||||
uint8_t i = 0;
|
||||
uint8_t j = 0;
|
||||
uint8_t reg508;
|
||||
int32_t retval = SUCCESS;
|
||||
|
||||
retval = AD9528_setSpiSettings(device);
|
||||
if (retval != SUCCESS) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Configure PLL1
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_REF_A_DIVIDER_LSB,
|
||||
device->pll1Settings->refA_Divider & 0xFF); //REF A div[7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_REF_A_DIVIDER_MSB,
|
||||
(device->pll1Settings->refA_Divider >> 8) & 0x03); //REF A div[9:8]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_REF_B_DIVIDER_LSB,
|
||||
device->pll1Settings->refB_Divider & 0xFF); //REF B div[7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_REF_B_DIVIDER_MSB,
|
||||
(device->pll1Settings->refB_Divider >> 8) & 0x03); //REF B div[9:8]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL1_N_DIV_LSB,
|
||||
device->pll1Settings->nDivider & 0xFF); //PLL1 N div[7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL1_N_DIV_MSB,
|
||||
(device->pll1Settings->nDivider >> 8) & 0x03); //PLL1 N div[9:8]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL1_CHARGEPUMP,
|
||||
0x0A); //PLL1 Charge Pump control 1
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL1_CP_CTRL2,
|
||||
0x03); //PLL1 Charge Pump control 2
|
||||
|
||||
switch (device->pll1Settings->refA_bufferCtrl) {
|
||||
case DISABLED:
|
||||
reg108 &= ~0x28;
|
||||
reg109 &= ~0x01;
|
||||
break; //clear all REFA enable bits
|
||||
case SINGLE_ENDED:
|
||||
reg108 |= 0x08;
|
||||
reg109 &= ~0x01;
|
||||
break; //Set REFA receiver enable, clear REFA SE negative input enable
|
||||
case NEG_SINGLE_ENDED:
|
||||
reg108 |= 0x08;
|
||||
reg108 &= ~0x10;
|
||||
reg109 |= 0x01;
|
||||
break; //Disable REFA diff receiver, enable REFA receiver and use negative REFA input
|
||||
case DIFFERENTIAL:
|
||||
reg108 |= 0x28;
|
||||
reg109 &= ~0x01;
|
||||
break;
|
||||
default:
|
||||
reg108 |= 0x08;
|
||||
reg109 &= ~0x01;
|
||||
break; //default to single ended case
|
||||
}
|
||||
switch (device->pll1Settings->refB_bufferCtrl) {
|
||||
case DISABLED:
|
||||
reg108 &= ~0x50;
|
||||
reg109 &= ~0x02;
|
||||
break; //clear all REFB enable bits
|
||||
case SINGLE_ENDED:
|
||||
reg108 |= 0x10;
|
||||
reg109 &= ~0x02;
|
||||
break; //Set REFB receiver enable, clear REFB SE negative input enable
|
||||
case NEG_SINGLE_ENDED:
|
||||
reg108 |= 0x10;
|
||||
reg108 &= ~0x40;
|
||||
reg109 |= 0x02;
|
||||
break; //Disable REFB diff receiver, enable REFB receiver and use negative REFB input
|
||||
case DIFFERENTIAL:
|
||||
reg108 |= 0x50;
|
||||
reg109 &= ~0x02;
|
||||
break;
|
||||
default:
|
||||
reg108 |= 0x10;
|
||||
reg109 &= ~0x02;
|
||||
break; //default to single ended case
|
||||
}
|
||||
switch (device->pll1Settings->vcxoBufferCtrl) {
|
||||
case DISABLED:
|
||||
reg108 &= ~0x03;
|
||||
reg108 |= 0x04;
|
||||
break; //power down VCXO input
|
||||
case SINGLE_ENDED:
|
||||
reg108 &= ~0x07;
|
||||
break; //Clear VCXO receiver power down, defaults to Single ended mode
|
||||
case NEG_SINGLE_ENDED:
|
||||
reg108 &= ~0x07;
|
||||
reg108 |= 0x02;
|
||||
break; //Clear VCXO power down, enable Negative single ended mode[1]
|
||||
case DIFFERENTIAL:
|
||||
reg108 &= ~0x07;
|
||||
reg108 |= 0x01;
|
||||
break; //Clear VCXO power down, enable differential input buffer[0]
|
||||
default:
|
||||
reg108 &= ~0x07;
|
||||
break; //default to positive single ended case
|
||||
}
|
||||
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_INPUT_RECEIVERS1,
|
||||
reg108); //Input receiver settings (single ended or differential clock inputs)
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_INPUT_RECEIVERS2,
|
||||
reg109); //Input receiver settings
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_INPUT_RECEIVERS3,
|
||||
0x0A); //Reference selection mode
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL1_FASTLOCK,
|
||||
0x00); //Disable Fast lock
|
||||
|
||||
/**********************************************************************
|
||||
* Configure PLL2
|
||||
**********************************************************************
|
||||
*/
|
||||
pll2_Bdiv = device->pll2Settings->totalNdiv / 4;
|
||||
pll2_Adiv = device->pll2Settings->totalNdiv % 4;
|
||||
|
||||
if (pll2_Adiv > 3) { //A div valid range (0 to 3)
|
||||
return FAILURE;
|
||||
}
|
||||
if (pll2_Bdiv < 3 || pll2_Bdiv > 63) {
|
||||
return FAILURE;
|
||||
}
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_CHARGEPUMP,
|
||||
0xE6); //PLL2 Charge Pump[7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_N_DIV,
|
||||
((pll2_Adiv & 0x3) << 6) | (pll2_Bdiv & 0x3F)); //PLL2 A and B divider
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_CTRL, 0x03); //PLL2 control
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_VCO_CTRL, 0x01); //Manual VCO CAL
|
||||
|
||||
if (device->pll2Settings->rfDivider < 3
|
||||
|| device->pll2Settings->rfDivider > 5) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_VCO_DIV,
|
||||
device->pll2Settings->rfDivider); //VCO divider
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_LF_CTRL1,
|
||||
0x3A); //PLL2 Loop filter [7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_LF_CTRL2,
|
||||
0x00); //PLL2 Loop filter [8]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_RDIV, 0x01); //R divider
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_REPLICA_CHDIV,
|
||||
(device->pll2Settings->totalNdiv / device->pll2Settings->rfDivider)
|
||||
-1 ); //Replica channel divider: Ndivider = rfDivider * R divider
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_REPLICA_DIV_PHASE,
|
||||
0x00); //Replica Channel Divider phase
|
||||
|
||||
/**********************************************************************
|
||||
* Configure Output Distribution
|
||||
**********************************************************************
|
||||
*/
|
||||
for (i=0; i<14; i=i+1) {
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_CH_OUT0_CTRL1 + j,
|
||||
((device->outputSettings->outSource[i] & 0x7) << 5) |
|
||||
(device->outputSettings->outAnalogDelay[i] & 0x1F));
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_CH_OUT0_CTRL2 + j,
|
||||
((device->outputSettings->outBufferCtrl[i] & 0x3) << 6) |
|
||||
(device->outputSettings->outDigitalDelay[i] & 0x3F));
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_CH_OUT0_CHDIV + j,
|
||||
device->outputSettings->outChannelDiv[i]-1);
|
||||
j = j+3;
|
||||
}
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_OUTPUT_SYNC, 0x00); //Sync outputs
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_MASK_SYNC1, 0x00); //Mask SYNC[7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_MASK_SYNC2, 0x00); //Mask SYNC[13:8]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_EN_OUTPUT_PATH_SEL1,
|
||||
0x00); //Bypass SYSREF resample [6:0], bit0:Enable VCXO to feed output distrubution
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_EN_OUTPUT_PATH_SEL2,
|
||||
0x00); //Bypass SYSREF resample [13:7]
|
||||
|
||||
/**********************************************************************
|
||||
* Configure SYSREF operation
|
||||
**********************************************************************
|
||||
*/
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSERF_DIV_LSB,
|
||||
device->sysrefSettings->sysrefDivide & 0xFF); //SYSREF divider [7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSERF_DIV_MSB,
|
||||
(device->sysrefSettings->sysrefDivide >> 8) & 0xFF); //SYSREF divider [7:0]
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL3,
|
||||
((device->sysrefSettings->sysrefRequestMethod & 0x1) << 7) |
|
||||
((device->sysrefSettings->sysrefPinEdgeMode & 0x3) << 5) );
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL4,
|
||||
((device->sysrefSettings->sysrefSource & 0x03) << 6) |
|
||||
((device->sysrefSettings->sysrefPatternMode & 0x3) << 4 ) |
|
||||
((device->sysrefSettings->sysrefNshotMode & 0x7) << 1) );
|
||||
|
||||
if(device->sysrefSettings->sysrefPinBufferMode == DISABLED) {
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL5,
|
||||
0x04); //power down input buffer for external SYSREF
|
||||
} else if(device->sysrefSettings->sysrefPinBufferMode == SINGLE_ENDED) {
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL5,
|
||||
0x00); //enable positive singled ended input
|
||||
} else if(device->sysrefSettings->sysrefPinBufferMode == NEG_SINGLE_ENDED) {
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL5,
|
||||
0x02); //enable negative singled ended input
|
||||
} else if(device->sysrefSettings->sysrefPinBufferMode == DIFFERENTIAL) {
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL5,
|
||||
0x01); //enable differential input buffer
|
||||
} else {
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL5,
|
||||
0x04); //power down input buffer for external SYSREF
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Power down control
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
if (device->pll1Settings->bypassPll1 > 0) {
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_POWERDOWN_CTRL,
|
||||
0x14);// power up PLL2 and output distribution, power down PLL1
|
||||
} else {
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_POWERDOWN_CTRL,
|
||||
0x10);// power up PLL1, PLL2 and output distribution
|
||||
}
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_CH_POWERDOWN1,
|
||||
device->outputSettings->outPowerDown & 0xFF); //power down out[7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_CH_POWERDOWN2,
|
||||
((device->outputSettings->outPowerDown >> 8) & 0x3F)); //power down out[13:8]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_LDO_ENABLES1,
|
||||
0xFF); //LDO enable per output channel [7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_LDO_ENABLES2,
|
||||
0xFF); //LDO enable per output channel [15:8]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_STATUS0_CTRL,
|
||||
0x07); //STATUS 0 outputs REFA present
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_STATUS1_CTRL,
|
||||
0x01); //STATUS 1 outputs PLL1 and PLL2 locked
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_STATUS_OE,
|
||||
0x0C);// Make Status0 and Status1 outputs after reset.
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_IO_UPDATE,
|
||||
0x01); //IO update to make all these settings valid in the 9528
|
||||
|
||||
AD9528_setTimeout_ms(1000);
|
||||
|
||||
do {
|
||||
AD9528_spiReadByte(device, AD9528_ADDR_STATUS_READBACK0, ®508);
|
||||
if(AD9528_hasTimeoutExpired() > 0) {
|
||||
return FAILURE;
|
||||
}
|
||||
} while((reg508 & 0x26) != 0x26);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/// Send a SPI message to request a SYSREF pulse or continuous SYSREF from the AD9528.
|
||||
/*******************************************************************************//**
|
||||
* Requests a SYSREF from the AD9528. It will use whatever settings for SYSREF
|
||||
* that are current configured in the AD9528. This could be a single pulse,
|
||||
* multiple pulses, or continuous pulses.
|
||||
* <B>Dependencies</B>
|
||||
* - device->spiSettings
|
||||
* - device->sysrefSettings->sysrefPatternMode
|
||||
*
|
||||
* \param device is structure pointer to AD9528 clock device structure
|
||||
* \param enableSYSREF If NSHOT SYSREF mode, this parameter is ignored. If PRBS/CONTINUOUS SYSREF mode, 1= enable SYSREF, 0= disable SYSREF.
|
||||
*
|
||||
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
|
||||
***********************************************************************************/
|
||||
int32_t AD9528_requestSysref(ad9528Device_t *device, uint8_t enableSYSREF)
|
||||
{
|
||||
uint8_t _enableSYSREF=0;
|
||||
|
||||
if (device->sysrefSettings->sysrefPatternMode == NSHOT || enableSYSREF > 0) {
|
||||
_enableSYSREF = 1;
|
||||
} else {
|
||||
_enableSYSREF = 0;
|
||||
}
|
||||
|
||||
AD9528_spiWriteField(device, AD9528_ADDR_SYSREF_CTRL4, _enableSYSREF, 0x01,
|
||||
0x00); //Set SPI SYSREF request bit
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_IO_UPDATE,
|
||||
0x01); //IO update to make all these settings valid in the 9528
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/// Allow changing the 9528 SYSREF frequency and pattern mode(CONTINUOUS, PRBS vs NSHOT mode)
|
||||
/*******************************************************************************//**
|
||||
* NOTE: this function will update the device structure with the parameter values passed
|
||||
* into this function. The device->sysrefSettings->sysrefPatternMode, device->sysrefSettings->sysrefNshotMode,
|
||||
* and device->sysrefSettings->sysrefDivide values will be updated in the device structure.
|
||||
*
|
||||
* <B>Dependencies</B>
|
||||
* - device->spiSettings
|
||||
*
|
||||
* \param device is structure pointer to AD9528 clock device structure
|
||||
* \param divideFromPll1Out Sets the SYSREF pulse frequency. SYSREF frequency = PLL1_VCXO frequency/divideFromPll1Out
|
||||
* \param sysrefPatternMode Valid settings: NSHOT, CONTINUOUS, PRBS, STOP
|
||||
* \param nShotPulses Valid settings: ONE_PULSE=0, TWO_PULSES=2, FOUR_PULSES=3, SIX_PULSES=4, EIGHT_PULSES=5
|
||||
*
|
||||
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
|
||||
***********************************************************************************/
|
||||
int32_t AD9528_setupSYSREF(ad9528Device_t *device,
|
||||
uint16_t divideFromPll1Out, sysrefPatternMode_t sysrefPatternMode,
|
||||
sysrefNshotMode_t nShotPulses)
|
||||
{
|
||||
uint8_t reg403=0;
|
||||
|
||||
device->sysrefSettings->sysrefPatternMode = sysrefPatternMode;
|
||||
device->sysrefSettings->sysrefNshotMode = nShotPulses;
|
||||
device->sysrefSettings->sysrefDivide = divideFromPll1Out >>
|
||||
1; //SYSREF frequency is (PLL1)VCXO frequency / 2 / device->sysrefSettings->sysrefDivide
|
||||
|
||||
AD9528_spiReadByte(device, AD9528_ADDR_SYSREF_CTRL4, ®403);
|
||||
|
||||
reg403 = reg403 & ~0x01; //clear bit 0 to stop a continuous sysref if it is on.
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL4, reg403);
|
||||
|
||||
reg403 = reg403 & ~0x3E; //clear bits for pattern mode and Nshot mode bitfields
|
||||
reg403 = reg403 | ((sysrefPatternMode & 0x3) << 4) | ((nShotPulses & 0x7) << 1);
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL4,
|
||||
reg403); //update internal sysref pattern mode and Nshot mode (number of pulses)
|
||||
|
||||
//SYSREF request bit x403[0] is left 0. The next call to AD9528_requestSysref will start the SYSREF
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_IO_UPDATE,
|
||||
0x01); //IO update to make all these settings valid in the 9528
|
||||
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int32_t AD9528_sysrefReq(ad9528Device_t *device,
|
||||
ad9528SysrefReqMode_t mode)
|
||||
{
|
||||
if (mode == SYSREF_CONT_ON)
|
||||
gpio_direction_output(device->gpio_sysref_req, 1);
|
||||
else if (mode == SYSREF_CONT_OFF)
|
||||
gpio_direction_output(device->gpio_sysref_req, 0);
|
||||
else if (mode == SYSREF_PULSE) {
|
||||
gpio_direction_output(device->gpio_sysref_req, 1);
|
||||
mdelay(1);
|
||||
gpio_direction_output(device->gpio_sysref_req, 0);
|
||||
} else
|
||||
return FAILURE;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Free the allocated resources
|
||||
*/
|
||||
int32_t AD9528_remove(ad9528Device_t *device)
|
||||
{
|
||||
int32_t status;
|
||||
|
||||
status = gpio_remove(device->gpio_resetb);
|
||||
status |= gpio_remove(device->gpio_sysref_req);
|
||||
status |= spi_remove(device->spi_desc);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
/**
|
||||
* \file ad9528.h
|
||||
* \brief Contains function declarations and ad9528Device_t structure typedef for ad9528.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* \page Disclaimer Legal Disclaimer
|
||||
* Copyright 2015-2017 Analog Devices Inc.
|
||||
* Released under the AD9371 API license.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AD9528_H_
|
||||
#define _AD9528_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "delay.h"
|
||||
#include "spi.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* AD9528 SPI Address defines */
|
||||
#define AD9528_ADDR_ADI_SPI_CONFIG_A 0x000
|
||||
#define AD9528_ADDR_ADI_SPI_CONFIG_B 0x001
|
||||
#define AD9528_ADDR_IO_UPDATE 0x00F
|
||||
|
||||
#define AD9528_ADDR_REF_A_DIVIDER_LSB 0x100
|
||||
#define AD9528_ADDR_REF_A_DIVIDER_MSB 0x101
|
||||
#define AD9528_ADDR_REF_B_DIVIDER_LSB 0x102
|
||||
#define AD9528_ADDR_REF_B_DIVIDER_MSB 0x103
|
||||
#define AD9528_ADDR_PLL1_N_DIV_LSB 0x104
|
||||
#define AD9528_ADDR_PLL1_N_DIV_MSB 0x105
|
||||
#define AD9528_ADDR_PLL1_CHARGEPUMP 0x106
|
||||
#define AD9528_ADDR_PLL1_CP_CTRL2 0x107
|
||||
#define AD9528_ADDR_INPUT_RECEIVERS1 0x108
|
||||
#define AD9528_ADDR_INPUT_RECEIVERS2 0x109
|
||||
#define AD9528_ADDR_INPUT_RECEIVERS3 0x10A
|
||||
#define AD9528_ADDR_PLL1_FASTLOCK 0x10B
|
||||
|
||||
#define AD9528_ADDR_PLL2_CHARGEPUMP 0x200
|
||||
#define AD9528_ADDR_PLL2_N_DIV 0x201
|
||||
#define AD9528_ADDR_PLL2_CTRL 0x202
|
||||
#define AD9528_ADDR_PLL2_VCO_CTRL 0x203
|
||||
#define AD9528_ADDR_PLL2_VCO_DIV 0x204
|
||||
#define AD9528_ADDR_PLL2_LF_CTRL1 0x205
|
||||
#define AD9528_ADDR_PLL2_LF_CTRL2 0x206
|
||||
#define AD9528_ADDR_PLL2_RDIV 0x207
|
||||
#define AD9528_ADDR_PLL2_REPLICA_CHDIV 0x208
|
||||
#define AD9528_ADDR_PLL2_REPLICA_DIV_PHASE 0x209
|
||||
|
||||
#define AD9528_ADDR_CH_OUT0_CTRL1 0x300
|
||||
#define AD9528_ADDR_CH_OUT0_CTRL2 0x301
|
||||
#define AD9528_ADDR_CH_OUT0_CHDIV 0x302
|
||||
#define AD9528_ADDR_OUTPUT_SYNC 0x32A
|
||||
#define AD9528_ADDR_MASK_SYNC1 0x32B
|
||||
#define AD9528_ADDR_MASK_SYNC2 0x32C
|
||||
#define AD9528_ADDR_EN_OUTPUT_PATH_SEL1 0x32D
|
||||
#define AD9528_ADDR_EN_OUTPUT_PATH_SEL2 0x32E
|
||||
|
||||
#define AD9528_ADDR_SYSERF_DIV_LSB 0x400
|
||||
#define AD9528_ADDR_SYSERF_DIV_MSB 0x401
|
||||
#define AD9528_ADDR_SYSREF_CTRL3 0x402
|
||||
#define AD9528_ADDR_SYSREF_CTRL4 0x403
|
||||
#define AD9528_ADDR_SYSREF_CTRL5 0x404
|
||||
|
||||
#define AD9528_ADDR_POWERDOWN_CTRL 0x500
|
||||
#define AD9528_ADDR_CH_POWERDOWN1 0x501
|
||||
#define AD9528_ADDR_CH_POWERDOWN2 0x502
|
||||
#define AD9528_ADDR_LDO_ENABLES1 0x503
|
||||
#define AD9528_ADDR_LDO_ENABLES2 0x504
|
||||
#define AD9528_ADDR_STATUS0_CTRL 0x505
|
||||
#define AD9528_ADDR_STATUS1_CTRL 0x506
|
||||
#define AD9528_ADDR_STATUS_OE 0x507
|
||||
#define AD9528_ADDR_STATUS_READBACK0 0x508
|
||||
#define AD9528_ADDR_STATUS_READBACK1 0x509
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
///Enum to select what source outputs from each AD9528 output channel
|
||||
typedef enum {
|
||||
AD9528_CHANNEL_DIV = 0, PLL1_OUTPUT = 1, //VCXO frequency
|
||||
SYSREF = 2,
|
||||
INV_PLL1_OUTPUT = 5 //VCXO inverted
|
||||
} ad9528outSourceSel_t;
|
||||
|
||||
///Enum to select what output buffer standard is used for the clock outputs
|
||||
typedef enum {
|
||||
AD9528_LVDS = 0, AD9528_LVDS_BOOST = 1, AD9528_HSTL = 2
|
||||
} ad9528outBufferControl_t;
|
||||
|
||||
///Enum to select the clock input buffer mode.
|
||||
typedef enum {
|
||||
DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL
|
||||
} ad9528RefBuffer_t;
|
||||
|
||||
/// Structure to hold AD9528 PLL1 settings
|
||||
typedef struct {
|
||||
uint32_t refA_Frequency_Hz;
|
||||
uint16_t refA_Divider;
|
||||
ad9528RefBuffer_t refA_bufferCtrl;
|
||||
|
||||
uint32_t refB_Frequency_Hz;
|
||||
uint16_t refB_Divider;
|
||||
ad9528RefBuffer_t refB_bufferCtrl;
|
||||
|
||||
uint32_t vcxo_Frequency_Hz;
|
||||
ad9528RefBuffer_t vcxoBufferCtrl;
|
||||
|
||||
uint16_t nDivider;
|
||||
uint8_t bypassPll1;
|
||||
} ad9528pll1Settings_t;
|
||||
|
||||
/// Structure to hold AD9528 PLL2 settings
|
||||
typedef struct {
|
||||
uint8_t rfDivider; //VCO divider: Valid range (3,4,5)
|
||||
uint8_t n2Divider; //PLL2 N2 Divider
|
||||
uint8_t totalNdiv; //NDiv = 4*Bdiv + Adiv //Bdiv valid range (3 to 63), Adiv valid range (0-3)
|
||||
} ad9528pll2Settings_t;
|
||||
|
||||
/// Structure to hold AD9528 Output Clock settings
|
||||
typedef struct {
|
||||
uint16_t outPowerDown; //bit per output, if 1 power down that output.
|
||||
ad9528outSourceSel_t
|
||||
outSource[14]; //CHANNEL_DIV, PLL1_OUTPUT, SYSREF, INV_PLL1_OUTPUT
|
||||
ad9528outBufferControl_t outBufferCtrl[14]; //LVDS, LVDS_BOOST, HSTL
|
||||
uint8_t outAnalogDelay[14]; //5 bits
|
||||
uint8_t outDigitalDelay[14]; //6 bits, 1/2 clock resolution @ channel div input frequency
|
||||
uint8_t outChannelDiv[14]; //8 bit channel divider
|
||||
uint32_t outFrequency_Hz[14]; //output clock frequency per clock output
|
||||
} ad9528outputSettings_t;
|
||||
|
||||
///Enum to select the SYSREF output source
|
||||
typedef enum {
|
||||
EXTERNAL = 0, EXT_RESAMPLED = 1, INTERNAL = 2
|
||||
} sysrefSourceSelection_t;
|
||||
|
||||
///Enum to choose the SYSREF pattern mode.
|
||||
typedef enum {
|
||||
NSHOT = 0, CONTINUOUS = 1, PRBS = 2, STOP = 3
|
||||
} sysrefPatternMode_t;
|
||||
|
||||
///Enum to select the SYSREF input pin mode.
|
||||
typedef enum {
|
||||
LEVEL_ACTIVE_HIGH = 0, LEVEL_ACTIVE_LOW = 1, RISING_EDGE = 2, FALLING_EDGE = 3
|
||||
} sysrefPinEdgeMode_t;
|
||||
|
||||
///Enum to select the SYSREF output # of pulses for NSHOT mode.
|
||||
typedef enum {
|
||||
ONE_PULSE = 0, TWO_PULSES = 2, FOUR_PULSES = 3, SIX_PULSES = 4, EIGHT_PULSES = 5
|
||||
} sysrefNshotMode_t;
|
||||
|
||||
//Enum to select how a SYSREF is requested.
|
||||
typedef enum {
|
||||
SPI = 0, PIN = 1
|
||||
} sysrefRequestMethod_t;
|
||||
|
||||
/// Structure to hold AD9528 SYSREF output settings
|
||||
typedef struct {
|
||||
sysrefRequestMethod_t sysrefRequestMethod;
|
||||
sysrefSourceSelection_t sysrefSource;
|
||||
sysrefPinEdgeMode_t sysrefPinEdgeMode;
|
||||
ad9528RefBuffer_t sysrefPinBufferMode;
|
||||
sysrefPatternMode_t sysrefPatternMode;
|
||||
sysrefNshotMode_t sysrefNshotMode;
|
||||
uint16_t sysrefDivide;
|
||||
|
||||
} ad9528sysrefSettings_t;
|
||||
|
||||
/// Structure to hold AD9528 SPI settings
|
||||
typedef struct {
|
||||
uint8_t chipSelectIndex; ///< valid 1~8
|
||||
uint8_t writeBitPolarity; ///< the level of the write bit of a SPI write instruction word, value is inverted for SPI read operation
|
||||
uint8_t longInstructionWord; ///< 1 = 16bit instruction word, 0 = 8bit instruction word
|
||||
uint8_t MSBFirst; ///< 1 = MSBFirst, 0 = LSBFirst
|
||||
uint8_t CPHA; ///< clock phase, sets which clock edge the data updates (valid 0 or 1)
|
||||
uint8_t CPOL; ///< clock polarity 0 = clock starts low, 1 = clock starts high
|
||||
uint8_t enSpiStreaming; ///< Not implemented. SW feature to improve SPI throughput.
|
||||
uint8_t autoIncAddrUp; ///< Not implemented. For SPI Streaming, set address increment direction. 1= next addr = addr+1, 0:addr = addr-1
|
||||
uint8_t fourWireMode; ///< 1: Use 4-wire SPI, 0: 3-wire SPI (SDIO pin is bidirectional). NOTE: ADI's FPGA platform always uses 4-wire mode.
|
||||
uint32_t spiClkFreq_Hz; ///< SPI Clk frequency in Hz (default 25000000), platform will use next lowest frequency that it's baud rate generator can create */
|
||||
} ad9528spiSettings_t;
|
||||
|
||||
/// Structure to hold AD9528 settings
|
||||
typedef struct {
|
||||
struct gpio_desc *gpio_resetb;
|
||||
struct gpio_desc *gpio_sysref_req;
|
||||
struct spi_desc *spi_desc;
|
||||
ad9528spiSettings_t *spiSettings;
|
||||
ad9528pll1Settings_t *pll1Settings;
|
||||
ad9528pll2Settings_t *pll2Settings;
|
||||
ad9528outputSettings_t *outputSettings;
|
||||
ad9528sysrefSettings_t *sysrefSettings;
|
||||
} ad9528Device_t;
|
||||
|
||||
typedef struct {
|
||||
struct gpio_init_param *gpio_init_resetb;
|
||||
struct gpio_init_param *gpio_init_sysref_req;
|
||||
struct spi_init_param *spi_init;
|
||||
ad9528spiSettings_t *spiSettings;
|
||||
ad9528pll1Settings_t *pll1Settings;
|
||||
ad9528pll2Settings_t *pll2Settings;
|
||||
ad9528outputSettings_t *outputSettings;
|
||||
ad9528sysrefSettings_t *sysrefSettings;
|
||||
} ad9528Init_t;
|
||||
|
||||
typedef enum {
|
||||
SYSREF_CONT_ON,
|
||||
SYSREF_CONT_OFF,
|
||||
SYSREF_PULSE,
|
||||
} ad9528SysrefReqMode_t;
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
//Helper function to setup the 9528 device data structure specifically for the ADI transceiver evaluation cards
|
||||
int32_t AD9528_initDeviceDataStruct(ad9528Device_t *device,
|
||||
uint32_t vcxoFrequency_Hz, uint32_t refAFrequency_Hz,
|
||||
uint32_t outputDeviceClock_Hz);
|
||||
int32_t AD9528_spiReadByte(ad9528Device_t *device, uint16_t addr,
|
||||
uint8_t *readdata);
|
||||
|
||||
//AD9528 API functions
|
||||
int32_t AD9528_hasTimeoutExpired();
|
||||
int32_t AD9528_resetDevice(ad9528Device_t *device);
|
||||
int32_t AD9528_init(ad9528Device_t **device, const ad9528Init_t *init_device);
|
||||
int32_t AD9528_config(ad9528Device_t
|
||||
*device); //writes all registers to desired values, leaves clock outputs off.
|
||||
int32_t AD9528_setupSYSREF(ad9528Device_t *device,
|
||||
uint16_t divideFromPll1Out, sysrefPatternMode_t sysrefPatternMode,
|
||||
sysrefNshotMode_t nShotPulses);
|
||||
int32_t AD9528_requestSysref(ad9528Device_t *device, uint8_t enableSYSREF);
|
||||
int32_t AD9528_sysrefReq(ad9528Device_t *device,
|
||||
ad9528SysrefReqMode_t mode);
|
||||
int32_t AD9528_remove(ad9528Device_t *device);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,927 @@
|
||||
/***************************************************************************//**
|
||||
* @file hmc7044.c
|
||||
* @brief Implementation of HMC7044, HMC7043 Driver.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2018-2020(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "hmc7044.h"
|
||||
#include "../../../include/error.h"
|
||||
#include "../../../include/util.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
#define HMC7044_WRITE (0 << 15)
|
||||
#define HMC7044_READ (1 << 15)
|
||||
#define HMC7044_CNT(x) (((x) - 1) << 13)
|
||||
#define HMC7044_ADDR(x) ((x) & 0xFFF)
|
||||
|
||||
/* Global Control */
|
||||
#define HMC7044_REG_SOFT_RESET 0x0000
|
||||
#define HMC7044_SOFT_RESET BIT(0)
|
||||
|
||||
#define HMC7044_REG_REQ_MODE_0 0x0001
|
||||
#define HMC7044_RESEED_REQ BIT(7)
|
||||
#define HMC7044_HIGH_PERF_DISTRIB_PATH BIT(6)
|
||||
#define HMC7044_HIGH_PERF_PLL_VCO BIT(5)
|
||||
#define HMC7044_FORCE_HOLDOVER BIT(4)
|
||||
#define HMC7044_MUTE_OUT_DIV BIT(3)
|
||||
#define HMC7044_PULSE_GEN_REQ BIT(2)
|
||||
#define HMC7044_RESTART_DIV_FSM BIT(1)
|
||||
#define HMC7044_SLEEP_MODE BIT(0)
|
||||
|
||||
#define HMC7044_REG_REQ_MODE_1 0x0002
|
||||
#define HMC7044_PLL2_AUTOTUNE_TRIG BIT(2)
|
||||
#define HMC7044_SLIP_REQ BIT(1)
|
||||
|
||||
#define HMC7044_REG_EN_CTRL_0 0x0003
|
||||
#define HMC7044_RF_RESEEDER_EN BIT(5)
|
||||
#define HMC7044_VCO_SEL(x) (((x) & 0x3) << 3)
|
||||
#define HMC7044_VCO_EXT 0
|
||||
#define HMC7044_VCO_HIGH 1
|
||||
#define HMC7044_VCO_LOW 2
|
||||
#define HMC7044_SYSREF_TIMER_EN BIT(2)
|
||||
#define HMC7044_PLL2_EN BIT(1)
|
||||
#define HMC7044_PLL1_EN BIT(0)
|
||||
|
||||
#define HMC7044_REG_EN_CTRL_1 0x0004
|
||||
#define HMC7044_SEVEN_PAIRS(x) ((x) & 0x7f)
|
||||
|
||||
#define HMC7044_REG_GLOB_MODE 0x0005
|
||||
#define HMC7044_REF_PATH_EN(x) ((x) & 0xf)
|
||||
#define HMC7044_RFSYNC_EN BIT(4)
|
||||
#define HMC7044_VCOIN_MODE_EN BIT(5)
|
||||
#define HMC7044_SYNC_PIN_MODE(x) (((x) & 0x3) << 6)
|
||||
|
||||
/* PLL1 */
|
||||
#define HMC7044_REG_CLKIN0_BUF_CTRL 0x000A
|
||||
#define HMC7044_REG_CLKIN1_BUF_CTRL 0x000B
|
||||
#define HMC7044_REG_CLKIN2_BUF_CTRL 0x000C
|
||||
#define HMC7044_REG_CLKIN3_BUF_CTRL 0x000D
|
||||
#define HMC7044_REG_OSCIN_BUF_CTRL 0x000E
|
||||
|
||||
#define HMC7044_REG_PLL1_REF_PRIO_CTRL 0x0014
|
||||
|
||||
#define HMC7044_HIGH_Z_EN BIT(4)
|
||||
#define HMC7044_LVPECL_EN BIT(3)
|
||||
#define HMC7044_AC_COUPLING_EN BIT(2)
|
||||
#define HMC7044_100_OHM_EN BIT(1)
|
||||
#define HMC7044_BUF_EN BIT(0)
|
||||
|
||||
#define HMC7044_REG_CLKIN_PRESCALER(x) (0x001C + (x))
|
||||
#define HMC7044_REG_OSCIN_PRESCALER 0x0020
|
||||
|
||||
#define HMC7044_REG_PLL1_R_LSB 0x0021
|
||||
#define HMC7044_R1_LSB(x) ((x) & 0xff)
|
||||
|
||||
#define HMC7044_REG_PLL1_R_MSB 0x0022
|
||||
#define HMC7044_R1_MSB(x) (((x) & 0xff00) >> 8)
|
||||
|
||||
#define HMC7044_REG_PLL1_N_LSB 0x0026
|
||||
#define HMC7044_N1_LSB(x) ((x) & 0xff)
|
||||
|
||||
#define HMC7044_REG_PLL1_N_MSB 0x0027
|
||||
#define HMC7044_N1_MSB(x) (((x) & 0xff00) >> 8)
|
||||
|
||||
#define HMC7044_REG_PLL1_LOCK_DETECT 0x0028
|
||||
#define HMC7044_LOCK_DETECT_SLIP BIT(5)
|
||||
#define HMC7044_LOCK_DETECT_TIMER(x) ((x) & 0x1f)
|
||||
|
||||
/* PLL2 */
|
||||
#define HMC7044_REG_PLL2_FREQ_DOUBLER 0x0032
|
||||
#define HMC7044_PLL2_FREQ_DOUBLER_DIS BIT(0)
|
||||
|
||||
#define HMC7044_REG_PLL2_R_LSB 0x0033
|
||||
#define HMC7044_R2_LSB(x) ((x) & 0xff)
|
||||
|
||||
#define HMC7044_REG_PLL2_R_MSB 0x0034
|
||||
#define HMC7044_R2_MSB(x) (((x) & 0xf00) >> 8)
|
||||
|
||||
#define HMC7044_REG_PLL2_N_LSB 0x0035
|
||||
#define HMC7044_N2_LSB(x) ((x) & 0xff)
|
||||
|
||||
#define HMC7044_REG_PLL2_N_MSB 0x0036
|
||||
#define HMC7044_N2_MSB(x) (((x) & 0xff00) >> 8)
|
||||
|
||||
#define HMC7044_REG_OSCOUT_PATH 0x0039
|
||||
#define HMC7044_REG_OSCOUT_DRIVER_0 0x003A
|
||||
#define HMC7044_REG_OSCOUT_DRIVER_1 0x003B
|
||||
|
||||
/* GPIO/SDATA Control */
|
||||
#define HMC7044_REG_GPI_CTRL(x) (0x0046 + (x))
|
||||
#define HMC7044_REG_GPI_SEL(x) ((x) & 0xf)
|
||||
|
||||
#define HMC7044_REG_GPO_CTRL(x) (0x0050 + (x))
|
||||
#define HMC7044_GPO_SEL(x) (((x) & 0x3f) << 2)
|
||||
#define HMC7044_GPO_MODE BIT(1)
|
||||
#define HMC7044_GPO_EN BIT(0)
|
||||
|
||||
/* SYSREF/SYNC Control */
|
||||
#define HMC7044_REG_PULSE_GEN 0x005A
|
||||
#define HMC7044_PULSE_GEN_MODE(x) ((x) & 0x7)
|
||||
|
||||
#define HMC7044_REG_SYNC 0x005B
|
||||
#define HMC7044_SYNC_RETIME BIT(2)
|
||||
#define HMC7044_SYNC_THROUGH_PLL2 BIT(1)
|
||||
#define HMC7044_SYNC_POLARITY BIT(0)
|
||||
|
||||
#define HMC7044_REG_SYSREF_TIMER_LSB 0x005C
|
||||
#define HMC7044_SYSREF_TIMER_LSB(x) ((x) & 0xff)
|
||||
|
||||
#define HMC7044_REG_SYSREF_TIMER_MSB 0x005D
|
||||
#define HMC7044_SYSREF_TIMER_MSB(x) (((x) & 0xf00) >> 8)
|
||||
|
||||
#define HMC7044_CLK_INPUT_CTRL 0x0064
|
||||
#define HMC7044_LOW_FREQ_INPUT_MODE BIT(0)
|
||||
#define HMC7044_DIV_2_INPUT_MODE BIT(1)
|
||||
|
||||
/* Status and Alarm readback */
|
||||
#define HMC7044_REG_ALARM_READBACK 0x007D
|
||||
#define HMC7044_REG_PLL1_STATUS 0x0082
|
||||
|
||||
#define HMC7044_PLL1_FSM_STATE(x) ((x) & 0x7)
|
||||
#define HMC7044_PLL1_ACTIVE_CLKIN(x) (((x) >> 3) & 0x3)
|
||||
|
||||
#define HMC7044_PLL2_LOCK_DETECT(x) ((x) & 0x1)
|
||||
#define HMC7044_SYSREF_SYNC_STAT(x) ((x) & 0x2)
|
||||
#define HMC7044_CLK_OUT_PH_STATUS(x) ((x) & 0x4)
|
||||
#define HMC7044_PLL1_PLL2_LOCK_STAT(x) ((x) & 0x8)
|
||||
#define HMC7044_SYNC_REQ_STATUS(x) ((x) & 0x10)
|
||||
|
||||
/* Other Controls */
|
||||
#define HMC7044_REG_CLK_OUT_DRV_LOW_PW 0x009F
|
||||
#define HMC7044_REG_CLK_OUT_DRV_HIGH_PW 0x00A0
|
||||
#define HMC7044_REG_PLL1_DELAY 0x00A5
|
||||
#define HMC7044_REG_PLL1_HOLDOVER 0x00A8
|
||||
#define HMC7044_REG_VTUNE_PRESET 0x00B0
|
||||
|
||||
/* Clock Distribution */
|
||||
#define HMC7044_REG_CH_OUT_CRTL_0(ch) (0x00C8 + 0xA * (ch))
|
||||
#define HMC7044_HI_PERF_MODE BIT(7)
|
||||
#define HMC7044_SYNC_EN BIT(6)
|
||||
#define HMC7044_CH_EN BIT(0)
|
||||
#define HMC7044_START_UP_MODE_DYN_EN (BIT(3) | BIT(2))
|
||||
|
||||
#define HMC7044_REG_CH_OUT_CRTL_1(ch) (0x00C9 + 0xA * (ch))
|
||||
#define HMC7044_DIV_LSB(x) ((x) & 0xFF)
|
||||
|
||||
#define HMC7044_REG_CH_OUT_CRTL_2(ch) (0x00CA + 0xA * (ch))
|
||||
#define HMC7044_DIV_MSB(x) (((x) >> 8) & 0xFF)
|
||||
|
||||
#define HMC7044_REG_CH_OUT_CRTL_3(ch) (0x00CB + 0xA * (ch))
|
||||
#define HMC7044_REG_CH_OUT_CRTL_4(ch) (0x00CC + 0xA * (ch))
|
||||
#define HMC7044_REG_CH_OUT_CRTL_5(ch) (0x00CD + 0xA * (ch))
|
||||
#define HMC7044_REG_CH_OUT_CRTL_6(ch) (0x00CE + 0xA * (ch))
|
||||
#define HMC7044_REG_CH_OUT_CRTL_7(ch) (0x00CF + 0xA * (ch))
|
||||
|
||||
#define HMC7044_REG_CH_OUT_CRTL_8(ch) (0x00D0 + 0xA * (ch))
|
||||
#define HMC7044_DRIVER_MODE(x) (((x) & 0x3) << 3)
|
||||
#define HMC7044_DRIVER_Z_MODE(x) (((x) & 0x3) << 0)
|
||||
#define HMC7044_DYN_DRIVER_EN BIT(5)
|
||||
#define HMC7044_FORCE_MUTE_EN BIT(7)
|
||||
|
||||
#define HMC7044_NUM_CHAN 14
|
||||
|
||||
#define HMC7044_LOW_VCO_MIN 2150000
|
||||
#define HMC7044_LOW_VCO_MAX 2880000
|
||||
#define HMC7044_HIGH_VCO_MIN 2650000
|
||||
#define HMC7044_HIGH_VCO_MAX 3200000
|
||||
|
||||
#define HMC7044_RECOMM_LCM_MIN 30000
|
||||
#define HMC7044_RECOMM_LCM_MAX 70000
|
||||
#define HMC7044_RECOMM_FPD1 10000
|
||||
|
||||
#define HMC7044_R1_MAX 65535
|
||||
#define HMC7044_N1_MAX 65535
|
||||
|
||||
#define HMC7044_R2_MIN 1
|
||||
#define HMC7044_R2_MAX 4095
|
||||
#define HMC7044_N2_MIN 8
|
||||
#define HMC7044_N2_MAX 65535
|
||||
|
||||
#define HMC7044_OUT_DIV_MIN 1
|
||||
#define HMC7044_OUT_DIV_MAX 4094
|
||||
|
||||
/******************************************************************************/
|
||||
/************************** Functions Implementation **************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* SPI register write to device.
|
||||
* @param dev - The device structure.
|
||||
* @param reg - The register address.
|
||||
* @param val - The register data.
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*/
|
||||
int32_t hmc7044_write(struct hmc7044_dev *dev,
|
||||
uint16_t reg,
|
||||
uint8_t val)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
uint16_t cmd;
|
||||
|
||||
cmd = HMC7044_WRITE | HMC7044_CNT(1) | HMC7044_ADDR(reg);
|
||||
buf[0] = cmd >> 8;
|
||||
buf[1] = cmd & 0xFF;
|
||||
buf[2] = val;
|
||||
return spi_write_and_read_3wire(dev->spi_desc, buf, NULL,
|
||||
ARRAY_SIZE(buf), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* SPI register read from device.
|
||||
* @param dev - The device structure.
|
||||
* @param reg - The register address.
|
||||
* @param val - The register data.
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*/
|
||||
|
||||
int32_t hmc7044_read(struct hmc7044_dev *dev, uint16_t reg, uint8_t *val)
|
||||
{
|
||||
uint8_t wr_buf[2];
|
||||
uint8_t rd_data[1];
|
||||
uint16_t cmd;
|
||||
int ret;
|
||||
|
||||
cmd = HMC7044_READ | HMC7044_CNT(1) | HMC7044_ADDR(reg);
|
||||
wr_buf[0] = cmd >> 8;
|
||||
wr_buf[1] = cmd & 0xFF;
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc, wr_buf, rd_data,
|
||||
ARRAY_SIZE(wr_buf), ARRAY_SIZE(rd_data));
|
||||
if (ret != SUCCESS)
|
||||
return ret;
|
||||
|
||||
*val = rd_data[0];
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the output channel divider.
|
||||
* @param rate - The desired rate.
|
||||
* @param parent_rate - The parent rate.
|
||||
* @return The output divider.
|
||||
*/
|
||||
uint32_t hmc7044_calc_out_div(uint32_t rate,
|
||||
uint32_t parent_rate)
|
||||
{
|
||||
uint32_t div;
|
||||
|
||||
div = DIV_ROUND_CLOSEST(parent_rate, rate);
|
||||
|
||||
/* Supported odd divide ratios are 1, 3, and 5 */
|
||||
if ((div != 1) && (div != 3) && (div != 5) && (div % 2))
|
||||
div = DIV_ROUND_CLOSEST(parent_rate, rate * 2) * 2;
|
||||
|
||||
div = clamp_t(unsigned int,
|
||||
div,
|
||||
HMC7044_OUT_DIV_MIN,
|
||||
HMC7044_OUT_DIV_MAX);
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculate rate corresponding to a channel.
|
||||
* @param dev - The device structure.
|
||||
* @param chan_num - Channel number.
|
||||
* @param rate - Channel rate.
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*/
|
||||
int32_t hmc7044_clk_recalc_rate(struct hmc7044_dev *dev, uint32_t chan_num,
|
||||
uint64_t *rate)
|
||||
{
|
||||
int i;
|
||||
struct hmc7044_chan_spec *chan = NULL;
|
||||
|
||||
/* Find the reqested channel number */
|
||||
for (i = 0; i < dev->num_channels; i++) {
|
||||
if (dev->channels[i].num == chan_num) {
|
||||
chan = &dev->channels[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (chan == NULL )
|
||||
return FAILURE;
|
||||
|
||||
*rate = dev->pll2_freq / chan->divider;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate closest possible rate
|
||||
* @param dev - The device structure
|
||||
* @param rate - The desired rate.
|
||||
* @param rounded_rate - The closest possible rate of desired rate.
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*/
|
||||
int32_t hmc7044_clk_round_rate(struct hmc7044_dev *dev, uint32_t rate,
|
||||
uint64_t *rounded_rate)
|
||||
{
|
||||
uint32_t div = hmc7044_calc_out_div(rate, dev->pll2_freq);
|
||||
|
||||
*rounded_rate = DIV_ROUND_CLOSEST(dev->pll2_freq, div);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set channel rate.
|
||||
* @param dev - The device structure.
|
||||
* @param chan_num - Channel number.
|
||||
* @param rate - Channel rate.
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*/
|
||||
int32_t hmc7044_clk_set_rate(struct hmc7044_dev *dev, uint32_t chan_num,
|
||||
uint64_t rate)
|
||||
{
|
||||
uint32_t div;
|
||||
int32_t ret;
|
||||
int i;
|
||||
struct hmc7044_chan_spec *chan = NULL;
|
||||
|
||||
/* Find the reqested channel number */
|
||||
for (i = 0; i < dev->num_channels; i++) {
|
||||
if (dev->channels[i].num == chan_num) {
|
||||
chan = &dev->channels[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (chan == NULL )
|
||||
return FAILURE;
|
||||
|
||||
div = hmc7044_calc_out_div(rate, dev->pll2_freq);
|
||||
chan->divider = div;
|
||||
|
||||
ret = hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_1(chan->num),
|
||||
HMC7044_DIV_LSB(div));
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
|
||||
return hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_2(chan->num),
|
||||
HMC7044_DIV_MSB(div));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the device.
|
||||
* @param dev - The device structure.
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*/
|
||||
static int32_t hmc7044_setup(struct hmc7044_dev *dev)
|
||||
{
|
||||
struct hmc7044_chan_spec *chan;
|
||||
bool high_vco_en;
|
||||
bool pll2_freq_doubler_en;
|
||||
uint32_t vcxo_freq, pll2_freq;
|
||||
uint32_t clkin_freq[4];
|
||||
uint32_t lcm_freq;
|
||||
uint32_t in_prescaler[5];
|
||||
uint32_t pll1_lock_detect;
|
||||
uint32_t n1, r1;
|
||||
uint32_t pfd1_freq;
|
||||
uint32_t vco_limit;
|
||||
uint32_t n2[2], r2[2];
|
||||
uint32_t i, ref_en = 0;
|
||||
|
||||
vcxo_freq = dev->vcxo_freq / 1000;
|
||||
pll2_freq = dev->pll2_freq / 1000;
|
||||
|
||||
lcm_freq = vcxo_freq;
|
||||
for (i = 0; i < ARRAY_SIZE(clkin_freq); i++) {
|
||||
if (dev->clkin_freq_ccf[i])
|
||||
clkin_freq[i] = dev->clkin_freq_ccf[i] / 1000;
|
||||
else
|
||||
clkin_freq[i] = dev->clkin_freq[i] / 1000;
|
||||
|
||||
if (clkin_freq[i]) {
|
||||
lcm_freq = greatest_common_divisor(clkin_freq[i], lcm_freq);
|
||||
ref_en |= BIT(i);
|
||||
}
|
||||
}
|
||||
|
||||
while (lcm_freq > HMC7044_RECOMM_LCM_MAX)
|
||||
lcm_freq /= 2;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clkin_freq); i++) {
|
||||
if (clkin_freq[i])
|
||||
in_prescaler[i] = clkin_freq[i] / lcm_freq;
|
||||
else
|
||||
in_prescaler[i] = 1;
|
||||
}
|
||||
in_prescaler[4] = vcxo_freq / lcm_freq;
|
||||
|
||||
pll1_lock_detect = log_base_2((lcm_freq * 4000) / dev->pll1_loop_bw);
|
||||
|
||||
/* fVCXO / N1 = fLCM / R1 */
|
||||
rational_best_approximation(vcxo_freq, lcm_freq,
|
||||
HMC7044_N1_MAX, HMC7044_R1_MAX,
|
||||
&n1, &r1);
|
||||
|
||||
pfd1_freq = vcxo_freq / n1;
|
||||
while ((pfd1_freq > HMC7044_RECOMM_FPD1) &&
|
||||
(n1 <= HMC7044_N1_MAX / 2) &&
|
||||
(r1 <= HMC7044_R1_MAX / 2)) {
|
||||
pfd1_freq /= 2;
|
||||
n1 *= 2;
|
||||
r1 *= 2;
|
||||
}
|
||||
|
||||
dev->pll1_pfd = pfd1_freq;
|
||||
|
||||
if (pll2_freq < HMC7044_LOW_VCO_MIN ||
|
||||
pll2_freq > HMC7044_HIGH_VCO_MAX)
|
||||
return FAILURE;
|
||||
|
||||
vco_limit = (HMC7044_LOW_VCO_MAX + HMC7044_HIGH_VCO_MIN) / 2;
|
||||
if (pll2_freq >= vco_limit)
|
||||
high_vco_en = true;
|
||||
else
|
||||
high_vco_en = false;
|
||||
|
||||
/* fVCO / N2 = fVCXO * doubler / R2 */
|
||||
pll2_freq_doubler_en = true;
|
||||
rational_best_approximation(pll2_freq, vcxo_freq * 2,
|
||||
HMC7044_N2_MAX, HMC7044_R2_MAX,
|
||||
&n2[0], &r2[0]);
|
||||
|
||||
if (pll2_freq != vcxo_freq * n2[0] / r2[0]) {
|
||||
rational_best_approximation(pll2_freq, vcxo_freq,
|
||||
HMC7044_N2_MAX, HMC7044_R2_MAX,
|
||||
&n2[1], &r2[1]);
|
||||
|
||||
if (abs((int)pll2_freq - (int)(vcxo_freq * 2 * n2[0] / r2[0])) >
|
||||
abs((int)pll2_freq - (int)(vcxo_freq * n2[1] / r2[1]))) {
|
||||
n2[0] = n2[1];
|
||||
r2[0] = r2[1];
|
||||
pll2_freq_doubler_en = false;
|
||||
}
|
||||
}
|
||||
|
||||
while ((n2[0] < HMC7044_N2_MIN) && (r2[0] <= HMC7044_R2_MAX / 2)) {
|
||||
n2[0] *= 2;
|
||||
r2[0] *= 2;
|
||||
}
|
||||
if (n2[0] < HMC7044_N2_MIN)
|
||||
return -FAILURE;
|
||||
|
||||
/* Resets all registers to default values */
|
||||
hmc7044_write(dev, HMC7044_REG_SOFT_RESET, HMC7044_SOFT_RESET);
|
||||
mdelay(10);
|
||||
hmc7044_write(dev, HMC7044_REG_SOFT_RESET, 0);
|
||||
mdelay(10);
|
||||
|
||||
/* Disable all channels */
|
||||
for (i = 0; i < HMC7044_NUM_CHAN; i++)
|
||||
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_0(i), 0);
|
||||
|
||||
/* Load the configuration updates (provided by Analog Devices) */
|
||||
hmc7044_write(dev, HMC7044_REG_CLK_OUT_DRV_LOW_PW, 0x4d);
|
||||
hmc7044_write(dev, HMC7044_REG_CLK_OUT_DRV_HIGH_PW, 0xdf);
|
||||
hmc7044_write(dev, HMC7044_REG_PLL1_DELAY, 0x06);
|
||||
hmc7044_write(dev, HMC7044_REG_PLL1_HOLDOVER, 0x06);
|
||||
hmc7044_write(dev, HMC7044_REG_VTUNE_PRESET, 0x04);
|
||||
|
||||
uint8_t rd_back;
|
||||
hmc7044_read(dev, HMC7044_REG_CLK_OUT_DRV_LOW_PW, &rd_back);
|
||||
hmc7044_read(dev, HMC7044_REG_CLK_OUT_DRV_HIGH_PW, &rd_back);
|
||||
hmc7044_read(dev, HMC7044_REG_PLL1_DELAY, &rd_back);
|
||||
hmc7044_read(dev, HMC7044_REG_PLL1_HOLDOVER, &rd_back);
|
||||
hmc7044_read(dev, HMC7044_REG_VTUNE_PRESET, &rd_back);
|
||||
|
||||
hmc7044_write(dev, HMC7044_REG_GLOB_MODE,
|
||||
HMC7044_SYNC_PIN_MODE(dev->sync_pin_mode) |
|
||||
(dev->clkin0_rfsync_en ? HMC7044_RFSYNC_EN : 0) |
|
||||
(dev->clkin1_vcoin_en ? HMC7044_VCOIN_MODE_EN : 0) |
|
||||
HMC7044_REF_PATH_EN(ref_en));
|
||||
|
||||
/* Program PLL2 */
|
||||
|
||||
/* Select the VCO range */
|
||||
hmc7044_write(dev, HMC7044_REG_EN_CTRL_0,
|
||||
(dev->rf_reseeder_en ? HMC7044_RF_RESEEDER_EN : 0) |
|
||||
HMC7044_VCO_SEL(high_vco_en ?
|
||||
HMC7044_VCO_HIGH :
|
||||
HMC7044_VCO_LOW) |
|
||||
HMC7044_SYSREF_TIMER_EN | HMC7044_PLL2_EN |
|
||||
HMC7044_PLL1_EN);
|
||||
|
||||
/* Program the dividers */
|
||||
hmc7044_write(dev, HMC7044_REG_PLL2_R_LSB,
|
||||
HMC7044_R2_LSB(r2[0]));
|
||||
hmc7044_write(dev, HMC7044_REG_PLL2_R_MSB,
|
||||
HMC7044_R2_MSB(r2[0]));
|
||||
hmc7044_write(dev, HMC7044_REG_PLL2_N_LSB,
|
||||
HMC7044_N2_LSB(n2[0]));
|
||||
hmc7044_write(dev, HMC7044_REG_PLL2_N_MSB,
|
||||
HMC7044_N2_MSB(n2[0]));
|
||||
|
||||
/* Program the reference doubler */
|
||||
hmc7044_write(dev, HMC7044_REG_PLL2_FREQ_DOUBLER,
|
||||
pll2_freq_doubler_en ? 0 : HMC7044_PLL2_FREQ_DOUBLER_DIS);
|
||||
|
||||
/* Program PLL1 */
|
||||
|
||||
/* Set the lock detect timer threshold */
|
||||
hmc7044_write(dev, HMC7044_REG_PLL1_LOCK_DETECT,
|
||||
HMC7044_LOCK_DETECT_TIMER(pll1_lock_detect));
|
||||
|
||||
/* Set the LCM */
|
||||
for (i = 0; i < ARRAY_SIZE(clkin_freq); i++) {
|
||||
hmc7044_write(dev, HMC7044_REG_CLKIN_PRESCALER(i),
|
||||
in_prescaler[i]);
|
||||
}
|
||||
hmc7044_write(dev, HMC7044_REG_OSCIN_PRESCALER,
|
||||
in_prescaler[4]);
|
||||
|
||||
/* Program the dividers */
|
||||
hmc7044_write(dev, HMC7044_REG_PLL1_R_LSB,
|
||||
HMC7044_R2_LSB(r1));
|
||||
hmc7044_write(dev, HMC7044_REG_PLL1_R_MSB,
|
||||
HMC7044_R2_MSB(r1));
|
||||
hmc7044_write(dev, HMC7044_REG_PLL1_N_LSB,
|
||||
HMC7044_N2_LSB(n1));
|
||||
hmc7044_write(dev, HMC7044_REG_PLL1_N_MSB,
|
||||
HMC7044_N2_MSB(n1));
|
||||
|
||||
hmc7044_write(dev, HMC7044_REG_PLL1_REF_PRIO_CTRL,
|
||||
dev->pll1_ref_prio_ctrl);
|
||||
|
||||
/* Program the SYSREF timer */
|
||||
|
||||
/* Set the divide ratio */
|
||||
hmc7044_write(dev, HMC7044_REG_SYSREF_TIMER_LSB,
|
||||
HMC7044_SYSREF_TIMER_LSB(dev->sysref_timer_div));
|
||||
hmc7044_write(dev, HMC7044_REG_SYSREF_TIMER_MSB,
|
||||
HMC7044_SYSREF_TIMER_MSB(dev->sysref_timer_div));
|
||||
|
||||
/* Set the pulse generator mode configuration */
|
||||
hmc7044_write(dev, HMC7044_REG_PULSE_GEN,
|
||||
HMC7044_PULSE_GEN_MODE(dev->pulse_gen_mode));
|
||||
|
||||
/* Enable the input buffers */
|
||||
hmc7044_write(dev, HMC7044_REG_CLKIN0_BUF_CTRL,
|
||||
dev->in_buf_mode[0]);
|
||||
hmc7044_write(dev, HMC7044_REG_CLKIN1_BUF_CTRL,
|
||||
dev->in_buf_mode[1]);
|
||||
hmc7044_write(dev, HMC7044_REG_CLKIN2_BUF_CTRL,
|
||||
dev->in_buf_mode[2]);
|
||||
hmc7044_write(dev, HMC7044_REG_CLKIN3_BUF_CTRL,
|
||||
dev->in_buf_mode[3]);
|
||||
hmc7044_write(dev, HMC7044_REG_OSCIN_BUF_CTRL,
|
||||
dev->in_buf_mode[4]);
|
||||
|
||||
/* Set GPIOs */
|
||||
for (i = 0; i < ARRAY_SIZE(dev->gpi_ctrl); i++) {
|
||||
hmc7044_write(dev, HMC7044_REG_GPI_CTRL(i),
|
||||
dev->gpi_ctrl[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->gpo_ctrl); i++) {
|
||||
hmc7044_write(dev, HMC7044_REG_GPO_CTRL(i),
|
||||
dev->gpo_ctrl[i]);
|
||||
}
|
||||
|
||||
mdelay(10);
|
||||
|
||||
/* Program the output channels */
|
||||
for (i = 0; i < dev->num_channels; i++) {
|
||||
chan = &dev->channels[i];
|
||||
if (chan->num >= HMC7044_NUM_CHAN || chan->disable)
|
||||
continue;
|
||||
|
||||
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_1(chan->num),
|
||||
HMC7044_DIV_LSB(chan->divider));
|
||||
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_2(chan->num),
|
||||
HMC7044_DIV_MSB(chan->divider));
|
||||
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_8(chan->num),
|
||||
HMC7044_DRIVER_MODE(chan->driver_mode) |
|
||||
HMC7044_DRIVER_Z_MODE(chan->driver_impedance) |
|
||||
(chan->dynamic_driver_enable ?
|
||||
HMC7044_DYN_DRIVER_EN : 0) |
|
||||
(chan->force_mute_enable ?
|
||||
HMC7044_FORCE_MUTE_EN : 0));
|
||||
|
||||
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_3(chan->num),
|
||||
chan->fine_delay & 0x1F);
|
||||
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_4(chan->num),
|
||||
chan->coarse_delay & 0x1F);
|
||||
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_7(chan->num),
|
||||
chan->out_mux_mode & 0x3);
|
||||
|
||||
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_0(chan->num),
|
||||
(chan->start_up_mode_dynamic_enable ?
|
||||
HMC7044_START_UP_MODE_DYN_EN : 0) |
|
||||
(chan->output_control0_rb4_enable ? BIT(4) : 0) |
|
||||
(chan->high_performance_mode_dis ?
|
||||
0 : HMC7044_HI_PERF_MODE) | HMC7044_SYNC_EN |
|
||||
HMC7044_CH_EN);
|
||||
}
|
||||
mdelay(10);
|
||||
|
||||
/* Do a restart to reset the system and initiate calibration */
|
||||
hmc7044_write(dev, HMC7044_REG_REQ_MODE_0,
|
||||
HMC7044_RESTART_DIV_FSM);
|
||||
mdelay(1);
|
||||
hmc7044_write(dev, HMC7044_REG_REQ_MODE_0,
|
||||
(dev->high_performance_mode_clock_dist_en ?
|
||||
HMC7044_HIGH_PERF_DISTRIB_PATH : 0));
|
||||
mdelay(1);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the device.
|
||||
* @param dev - The device structure.
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*/
|
||||
static int32_t hmc7043_setup(struct hmc7044_dev *dev)
|
||||
{
|
||||
struct hmc7044_chan_spec *chan;
|
||||
uint32_t i;
|
||||
|
||||
if (dev->clkin_freq_ccf[0])
|
||||
dev->pll2_freq = dev->clkin_freq_ccf[0];
|
||||
else
|
||||
dev->pll2_freq = dev->clkin_freq[0];
|
||||
|
||||
if (!dev->pll2_freq) {
|
||||
printf("%s: Failed to get valid parent rate\n", __func__);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/* Resets all registers to default values */
|
||||
hmc7044_write(dev, HMC7044_REG_SOFT_RESET, HMC7044_SOFT_RESET);
|
||||
mdelay(10);
|
||||
hmc7044_write(dev, HMC7044_REG_SOFT_RESET, 0);
|
||||
mdelay(10);
|
||||
|
||||
/* Load the configuration updates (provided by Analog Devices) */
|
||||
hmc7044_write(dev, HMC7044_REG_CLK_OUT_DRV_LOW_PW, 0x4d);
|
||||
hmc7044_write(dev, HMC7044_REG_CLK_OUT_DRV_HIGH_PW, 0xdf);
|
||||
|
||||
/* Disable all channels */
|
||||
for (i = 0; i < HMC7044_NUM_CHAN; i++)
|
||||
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_0(i), 0);
|
||||
|
||||
if (dev->pll2_freq < 1000000000U)
|
||||
hmc7044_write(dev, HMC7044_CLK_INPUT_CTRL,
|
||||
HMC7044_LOW_FREQ_INPUT_MODE);
|
||||
|
||||
hmc7044_write(dev, HMC7044_REG_EN_CTRL_0,
|
||||
(dev->rf_reseeder_en ? HMC7044_RF_RESEEDER_EN : 0) |
|
||||
HMC7044_SYSREF_TIMER_EN);
|
||||
|
||||
/* Program the SYSREF timer */
|
||||
|
||||
/* Set the divide ratio */
|
||||
hmc7044_write(dev, HMC7044_REG_SYSREF_TIMER_LSB,
|
||||
HMC7044_SYSREF_TIMER_LSB(dev->sysref_timer_div));
|
||||
hmc7044_write(dev, HMC7044_REG_SYSREF_TIMER_MSB,
|
||||
HMC7044_SYSREF_TIMER_MSB(dev->sysref_timer_div));
|
||||
|
||||
/* Set the pulse generator mode configuration */
|
||||
hmc7044_write(dev, HMC7044_REG_PULSE_GEN,
|
||||
HMC7044_PULSE_GEN_MODE(dev->pulse_gen_mode));
|
||||
|
||||
/* Enable the input buffers */
|
||||
hmc7044_write(dev, HMC7044_REG_CLKIN0_BUF_CTRL,
|
||||
dev->in_buf_mode[0]);
|
||||
hmc7044_write(dev, HMC7044_REG_CLKIN1_BUF_CTRL,
|
||||
dev->in_buf_mode[1]);
|
||||
|
||||
/* Set GPIOs */
|
||||
hmc7044_write(dev, HMC7044_REG_GPI_CTRL(0),
|
||||
dev->gpi_ctrl[0]);
|
||||
|
||||
hmc7044_write(dev, HMC7044_REG_GPO_CTRL(0),
|
||||
dev->gpo_ctrl[0]);
|
||||
|
||||
/* Program the output channels */
|
||||
for (i = 0; i < dev->num_channels; i++) {
|
||||
chan = &dev->channels[i];
|
||||
|
||||
if (chan->num >= HMC7044_NUM_CHAN || chan->disable)
|
||||
continue;
|
||||
|
||||
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_1(chan->num),
|
||||
HMC7044_DIV_LSB(chan->divider));
|
||||
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_2(chan->num),
|
||||
HMC7044_DIV_MSB(chan->divider));
|
||||
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_8(chan->num),
|
||||
HMC7044_DRIVER_MODE(chan->driver_mode) |
|
||||
HMC7044_DRIVER_Z_MODE(chan->driver_impedance) |
|
||||
(chan->dynamic_driver_enable ?
|
||||
HMC7044_DYN_DRIVER_EN : 0) |
|
||||
(chan->force_mute_enable ?
|
||||
HMC7044_FORCE_MUTE_EN : 0));
|
||||
|
||||
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_3(chan->num),
|
||||
chan->fine_delay & 0x1F);
|
||||
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_4(chan->num),
|
||||
chan->coarse_delay & 0x1F);
|
||||
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_7(chan->num),
|
||||
chan->out_mux_mode & 0x3);
|
||||
|
||||
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_0(chan->num),
|
||||
(chan->start_up_mode_dynamic_enable ?
|
||||
HMC7044_START_UP_MODE_DYN_EN : 0) |
|
||||
(chan->output_control0_rb4_enable ? BIT(4) : 0) |
|
||||
(chan->high_performance_mode_dis ?
|
||||
0 : HMC7044_HI_PERF_MODE) | HMC7044_SYNC_EN |
|
||||
HMC7044_CH_EN);
|
||||
}
|
||||
mdelay(10);
|
||||
|
||||
|
||||
/* Do a restart to reset the system and initiate calibration */
|
||||
hmc7044_write(dev, HMC7044_REG_REQ_MODE_0,
|
||||
HMC7044_RESTART_DIV_FSM);
|
||||
mdelay(1);
|
||||
hmc7044_write(dev, HMC7044_REG_REQ_MODE_0,
|
||||
(dev->high_performance_mode_clock_dist_en ?
|
||||
HMC7044_HIGH_PERF_DISTRIB_PATH : 0));
|
||||
mdelay(1);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief hmc7044_reg_init
|
||||
*******************************************************************************/
|
||||
int32_t hmc7044_reg_init(struct hmc7044_dev **device,
|
||||
const struct hmc7044_init_param *init_param)
|
||||
{
|
||||
int ret = SUCCESS;
|
||||
struct hmc7044_dev *dev;
|
||||
|
||||
dev = (struct hmc7044_dev *)malloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
return FAILURE;
|
||||
|
||||
/* SPI */
|
||||
ret = spi_init(&dev->spi_desc, init_param->spi_init);
|
||||
|
||||
*device = dev;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the device.
|
||||
* @param device - The device structure.
|
||||
* @param init_param - The structure that contains the device initial
|
||||
* parameters.
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*/
|
||||
int32_t hmc7044_init(struct hmc7044_dev **device,
|
||||
const struct hmc7044_init_param *init_param)
|
||||
{
|
||||
struct hmc7044_dev *dev;
|
||||
int32_t ret;
|
||||
unsigned int i;
|
||||
|
||||
dev = (struct hmc7044_dev *)malloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
return FAILURE;
|
||||
|
||||
ret = spi_init(&dev->spi_desc, init_param->spi_init);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dev->is_hmc7043 = init_param->is_hmc7043;
|
||||
|
||||
dev->clkin_freq[0] = init_param->clkin_freq[0];
|
||||
dev->clkin_freq[1] = init_param->clkin_freq[1];
|
||||
dev->clkin_freq[2] = init_param->clkin_freq[2];
|
||||
dev->clkin_freq[3] = init_param->clkin_freq[3];
|
||||
|
||||
dev->clkin_freq_ccf[0] = init_param->clkin_freq_ccf[0];
|
||||
dev->clkin_freq_ccf[1] = init_param->clkin_freq_ccf[1];
|
||||
dev->clkin_freq_ccf[2] = init_param->clkin_freq_ccf[2];
|
||||
dev->clkin_freq_ccf[3] = init_param->clkin_freq_ccf[3];
|
||||
|
||||
dev->vcxo_freq = init_param->vcxo_freq;
|
||||
dev->pll1_pfd = init_param->pll1_pfd;
|
||||
dev->pll2_freq = init_param->pll2_freq;
|
||||
dev->pll1_loop_bw = init_param->pll1_loop_bw;
|
||||
|
||||
dev->sysref_timer_div = init_param->sysref_timer_div;
|
||||
dev->pll1_ref_prio_ctrl = init_param->pll1_ref_prio_ctrl;
|
||||
dev->clkin0_rfsync_en = init_param->clkin0_rfsync_en;
|
||||
dev->clkin1_vcoin_en = init_param->clkin1_vcoin_en;
|
||||
dev->high_performance_mode_clock_dist_en =
|
||||
init_param->high_performance_mode_clock_dist_en;
|
||||
dev->rf_reseeder_en = !init_param->rf_reseeder_disable;
|
||||
dev->sync_pin_mode = init_param->sync_pin_mode;
|
||||
dev->pulse_gen_mode = init_param->pulse_gen_mode;
|
||||
|
||||
dev->in_buf_mode[0] = init_param->in_buf_mode[0];
|
||||
dev->in_buf_mode[1] = init_param->in_buf_mode[1];
|
||||
dev->in_buf_mode[2] = init_param->in_buf_mode[2];
|
||||
dev->in_buf_mode[3] = init_param->in_buf_mode[3];
|
||||
dev->in_buf_mode[4] = init_param->in_buf_mode[4];
|
||||
|
||||
dev->gpi_ctrl[0] = init_param->gpi_ctrl[0];
|
||||
dev->gpi_ctrl[1] = init_param->gpi_ctrl[1];
|
||||
dev->gpi_ctrl[2] = init_param->gpi_ctrl[2];
|
||||
dev->gpi_ctrl[3] = init_param->gpi_ctrl[3];
|
||||
|
||||
dev->gpo_ctrl[0] = init_param->gpo_ctrl[0];
|
||||
dev->gpo_ctrl[1] = init_param->gpo_ctrl[1];
|
||||
dev->gpo_ctrl[2] = init_param->gpo_ctrl[2];
|
||||
dev->gpo_ctrl[3] = init_param->gpo_ctrl[3];
|
||||
|
||||
dev->num_channels = init_param->num_channels;
|
||||
dev->channels = (struct hmc7044_chan_spec *)
|
||||
malloc(sizeof(*dev->channels) * dev->num_channels);
|
||||
|
||||
for (i = 0; i < dev->num_channels; i++) {
|
||||
dev->channels[i].num = init_param->channels[i].num;
|
||||
dev->channels[i].disable = init_param->channels[i].disable;
|
||||
dev->channels[i].divider = init_param->channels[i].divider;
|
||||
dev->channels[i].driver_mode =
|
||||
init_param->channels[i].driver_mode;
|
||||
dev->channels[i].high_performance_mode_dis =
|
||||
init_param->channels[i].high_performance_mode_dis;
|
||||
dev->channels[i].start_up_mode_dynamic_enable =
|
||||
init_param->channels[i].start_up_mode_dynamic_enable;
|
||||
dev->channels[i].dynamic_driver_enable =
|
||||
init_param->channels[i].dynamic_driver_enable;
|
||||
dev->channels[i].output_control0_rb4_enable =
|
||||
init_param->channels[i].output_control0_rb4_enable;
|
||||
dev->channels[i].force_mute_enable =
|
||||
init_param->channels[i].force_mute_enable;
|
||||
dev->channels[i].driver_impedance =
|
||||
init_param->channels[i].driver_impedance;
|
||||
dev->channels[i].coarse_delay =
|
||||
init_param->channels[i].coarse_delay;
|
||||
dev->channels[i].fine_delay =
|
||||
init_param->channels[i].fine_delay;
|
||||
dev->channels[i].out_mux_mode =
|
||||
init_param->channels[i].out_mux_mode;
|
||||
}
|
||||
|
||||
*device = dev;
|
||||
|
||||
if (!dev->is_hmc7043)
|
||||
return hmc7044_setup(dev);
|
||||
else
|
||||
return hmc7043_setup(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the device - release resources.
|
||||
* @param device - The device structure.
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*/
|
||||
int32_t hmc7044_remove(struct hmc7044_dev *device)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = spi_remove(device->spi_desc);
|
||||
free(device->channels);
|
||||
free(device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
/***************************************************************************//**
|
||||
* @file hmc7044.h
|
||||
* @brief Header file of HMC7044, HMC7043 Driver.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2018-2020(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef HMC7044_H_
|
||||
#define HMC7044_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "delay.h"
|
||||
#include "spi.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
// Enum to select SYNC pin configuration with respect to PLL2 (0x0005)
|
||||
typedef enum
|
||||
{
|
||||
SYNC_DISABLED = 0,
|
||||
SYNC_MULTICHIP = 1,
|
||||
SYNC_PULSE_GEN = 2,
|
||||
SYNC_ALARM = 3
|
||||
} hmc7044SyncPinModeSelect_t;
|
||||
|
||||
// Enum to select input buffer mode (0x000A, 0x000B, 0x000C, 0x000D, 0x000E)
|
||||
typedef enum
|
||||
{
|
||||
BUFFER_ENABLE = (1) << 0,
|
||||
BUFFER_DISABLE = (0) << 0,
|
||||
ENABLE_INTERNAL_TERM = (1) << 1,
|
||||
ENABLE_AC_COUPLE = (1) << 2,
|
||||
ENABLE_LVPECL = (1) << 3,
|
||||
ENABLE_HIGH_Z = (1) << 4
|
||||
} hmc7044InputBufferMode_t;
|
||||
|
||||
// Enum to select output driver mode (0x003A, 0x003B, 0x00D0, 0x00DA, 0x00E4,
|
||||
// 0x00EE, 0x00F8, 0x0102, 0x010C, 0x0116, 0x0120, 0x012A, 0x0134, 0x013E,
|
||||
// 0x0148, 0x0152)
|
||||
typedef enum
|
||||
{
|
||||
CML = 0,
|
||||
LVPECL = 1,
|
||||
LVDS = 2,
|
||||
CMOS = 3
|
||||
} hmc7044DriverMode_t;
|
||||
|
||||
// Enum to select the GPIx functionality. (0x0046, 0x0047, 0x0048, 0x0049)
|
||||
typedef enum
|
||||
{
|
||||
GPI_ENABLE = (1) << 0,
|
||||
GPI_DISABLE = (0) << 0,
|
||||
FORCE_PLL1_HOLDOVER = (0x01) << 1 | GPI_ENABLE,
|
||||
SELECT_PLL1_REF_BIT1 = (0x02) << 1 | GPI_ENABLE,
|
||||
SELECT_PLL1_REF_BIT2 = (0x03) << 1 | GPI_ENABLE,
|
||||
CHIP_SLEEP_MODE = (0x04) << 1 | GPI_ENABLE,
|
||||
MUTE_REQUSET = (0x05) << 1 | GPI_ENABLE,
|
||||
SELECT_INTERNAL_VCO_TYPE = (0x06) << 1 | GPI_ENABLE,
|
||||
SELECT_HI_PERF_MODE = (0x07) << 1 | GPI_ENABLE,
|
||||
PULSE_GEN_REQUSET = (0x08) << 1 | GPI_ENABLE,
|
||||
RESEED_REQUEST = (0x09) << 1 | GPI_ENABLE,
|
||||
RESTART_REQUSET = (0x0A) << 1 | GPI_ENABLE,
|
||||
FORCE_FANOUT_MODE = (0x0B) << 1 | GPI_ENABLE,
|
||||
SLIP_REQUEST = (0x0D) << 1 | GPI_ENABLE,
|
||||
} hmc7044GPIControl_t;
|
||||
|
||||
// Enum to select the GPOx functionality. (0x0050, 0x0051, 0x0052, 0x0053)
|
||||
typedef enum
|
||||
{
|
||||
GPO_ENABLE = (1) << 0,
|
||||
GPO_DISABLE = (0) << 0,
|
||||
GPO_CMOS_MODE = (1) << 1,
|
||||
GPO_OPEN_DRAIN_MODE = (0) << 1,
|
||||
ALARM_SIGNAL = (0x00) << 3 | GPO_ENABLE,
|
||||
SPI_SDATA = (0x01) << 3 | GPO_ENABLE,
|
||||
CLKIN3_SIGNAL_LOSS = (0x02) << 3 | GPO_ENABLE,
|
||||
CLKIN2_SIGNAL_LOSS = (0x03) << 3 | GPO_ENABLE,
|
||||
CLKIN1_SIGNAL_LOSS = (0x04) << 3 | GPO_ENABLE,
|
||||
CLKIN0_SIGNAL_LOSS = (0x05) << 3 | GPO_ENABLE,
|
||||
PLL1_HOLDOVER_ENABLE = (0x06) << 3 | GPO_ENABLE,
|
||||
PLL1_LOCK_DETECT = (0x07) << 3 | GPO_ENABLE,
|
||||
PLL1_ACQUIRING_LOCK = (0x08) << 3 | GPO_ENABLE,
|
||||
PLL1_NEAR_CLOCK_ACQ_STAT = (0x09) << 3 | GPO_ENABLE,
|
||||
PLL2_LOCK_DETECT = (0x0A) << 3 | GPO_ENABLE,
|
||||
PLL2_SYSREF_SYNC = (0x0B) << 3 | GPO_ENABLE,
|
||||
CLOCK_OUTPUT_PHASE_STAT = (0x0C) << 3 | GPO_ENABLE,
|
||||
PLL1_PLL2_LOCKED = (0x0D) << 3 | GPO_ENABLE,
|
||||
SYNC_REQUSRT_STAT = (0x0E) << 3 | GPO_ENABLE,
|
||||
PLL1_ACTIVE_CLKIN0 = (0x0F) << 3 | GPO_ENABLE,
|
||||
PLL1_ACTIVE_CLKIN1 = (0x10) << 3 | GPO_ENABLE,
|
||||
PLL1_HOLDOVER_IN_RANGE_STAT = (0x11) << 3 | GPO_ENABLE,
|
||||
PLL1_HOLDOVER_IN_STAT = (0x12) << 3 | GPO_ENABLE,
|
||||
PLL1_VCXO_STAT = (0x13) << 3 | GPO_ENABLE,
|
||||
PLL1_ACTIVE_CLKINx_STAT = (0x14) << 3 | GPO_ENABLE,
|
||||
PLL1_FSM_BIT0 = (0x15) << 3 | GPO_ENABLE,
|
||||
PLL1_FSM_BIT1 = (0x16) << 3 | GPO_ENABLE,
|
||||
PLL1_FSM_BIT2 = (0x17) << 3 | GPO_ENABLE,
|
||||
PLL1_HOLDOVER_EXIT_PHASE_BIT0 = (0x18) << 3 | GPO_ENABLE,
|
||||
PLL1_HOLDOVER_EXIT_PHASE_BIT1 = (0x19) << 3 | GPO_ENABLE,
|
||||
CHANNEL_OUTPUT_FSM_BUSY = (0x1A) << 3 | GPO_ENABLE,
|
||||
SYSREF_FSM_STAT_BIT0 = (0x1B) << 3 | GPO_ENABLE,
|
||||
SYSREF_FSM_STAT_BIT1 = (0x1C) << 3 | GPO_ENABLE,
|
||||
SYSREF_FSM_STAT_BIT2 = (0x1D) << 3 | GPO_ENABLE,
|
||||
SYSREF_FSM_STAT_BIT3 = (0x1E) << 3 | GPO_ENABLE,
|
||||
FORCE_LOGIC_1 = (0x1F) << 3 | GPO_ENABLE,
|
||||
FORCE_LOGIC_0 = (0x20) << 3 | GPO_ENABLE,
|
||||
PLL1_HOLDOVER_AVG_VALUE_BIT0 = (0x27) << 3 | GPO_ENABLE,
|
||||
PLL1_HOLDOVER_AVG_VALUE_BIT1 = (0x28) << 3 | GPO_ENABLE,
|
||||
PLL1_HOLDOVER_AVG_VALUE_BIT2 = (0x29) << 3 | GPO_ENABLE,
|
||||
PLL1_HOLDOVER_AVG_VALUE_BIT3 = (0x2A) << 3 | GPO_ENABLE,
|
||||
PLL1_HOLDOVER_CURR_VALUE_BIT0 = (0x2B) << 3 | GPO_ENABLE,
|
||||
PLL1_HOLDOVER_CURR_VALUE_BIT1 = (0x2C) << 3 | GPO_ENABLE,
|
||||
PLL1_HOLDOVER_CURR_VALUE_BIT2 = (0x2D) << 3 | GPO_ENABLE,
|
||||
PLL1_HOLDOVER_CURR_VALUE_BIT3 = (0x2E) << 3 | GPO_ENABLE
|
||||
} hmc7044GPOControl_t;
|
||||
|
||||
// Enum to select output channel (0x00CF, 0x00D9, 0x00E3, 0x00ED, 0x00F7,
|
||||
// 0x0101, 0x010B, 0x0115, 0x011F, 0x0129, 0x0133, 0x013D, 0x0147, 0x0151
|
||||
typedef enum
|
||||
{
|
||||
CHANNEL_DIV = 0,
|
||||
ANALOG_DELAY = 1,
|
||||
OTHER_CHANNEL = 2,
|
||||
VCO_CLOCK = 3
|
||||
} hmc7044OutputMuxSelect_t;
|
||||
|
||||
// Enum to select output driver impedance selection for CML mode (0x00D0,
|
||||
// 0x00DA, 0x00E4, 0x00EE, 0x00F8, 0x0102, 0x010C, 0x0116, 0x0120, 0x012A,
|
||||
// 0x0134, 0x013E, 0x0148, 0x0152)
|
||||
typedef enum
|
||||
{
|
||||
INTERNAL_RES_DISABLE = 0,
|
||||
INTERNAL_100OHM_PER_PIN = 1,
|
||||
// INTERNAL_RES_RESERVED = 2,
|
||||
INTERNAL_50OHM_PER_PIN = 3
|
||||
} hmc7044DriverImpedance_t;
|
||||
|
||||
// Enum to select pulse generator mode (0x005A)
|
||||
typedef enum
|
||||
{
|
||||
PULSE_LEVEL_SENSITIVE = 0,
|
||||
PULSE_ONE = 1,
|
||||
PULSE_TWO = 2,
|
||||
PULSE_FOUR = 3,
|
||||
PULSE_EIGHT = 4,
|
||||
PULSE_SIXTEEN = 5,
|
||||
// PULSE_SIXTEEN = 6,
|
||||
PULSE_CONTINOUS = 7
|
||||
} hmc7044SyncPulseGenControl_t;
|
||||
|
||||
struct hmc7044_chan_spec {
|
||||
unsigned int num;
|
||||
bool disable;
|
||||
bool high_performance_mode_dis;
|
||||
bool start_up_mode_dynamic_enable;
|
||||
bool dynamic_driver_enable;
|
||||
bool output_control0_rb4_enable;
|
||||
bool force_mute_enable;
|
||||
unsigned int divider;
|
||||
unsigned int coarse_delay;
|
||||
unsigned int fine_delay;
|
||||
hmc7044DriverMode_t driver_mode;
|
||||
hmc7044DriverImpedance_t driver_impedance;
|
||||
hmc7044OutputMuxSelect_t out_mux_mode;
|
||||
};
|
||||
|
||||
struct hmc7044_config {
|
||||
uint16_t addr;
|
||||
uint8_t value;
|
||||
};
|
||||
|
||||
struct hmc7044_dev {
|
||||
struct spi_desc *spi_desc;
|
||||
bool is_hmc7043;
|
||||
uint32_t clkin_freq[4];
|
||||
uint32_t clkin_freq_ccf[4];
|
||||
uint32_t vcxo_freq;
|
||||
uint32_t pll1_pfd;
|
||||
uint32_t pll2_freq;
|
||||
uint32_t pll1_loop_bw;
|
||||
uint32_t sysref_timer_div;
|
||||
unsigned int pll1_ref_prio_ctrl;
|
||||
bool clkin0_rfsync_en;
|
||||
bool clkin1_vcoin_en;
|
||||
bool high_performance_mode_clock_dist_en;
|
||||
bool rf_reseeder_en;
|
||||
hmc7044SyncPinModeSelect_t sync_pin_mode;
|
||||
hmc7044SyncPulseGenControl_t pulse_gen_mode;
|
||||
uint32_t in_buf_mode[5];
|
||||
uint32_t gpi_ctrl[4];
|
||||
uint32_t gpo_ctrl[4];
|
||||
uint32_t num_channels;
|
||||
struct hmc7044_chan_spec *channels;
|
||||
};
|
||||
|
||||
struct hmc7044_init_param {
|
||||
struct spi_init_param *spi_init;
|
||||
bool is_hmc7043;
|
||||
uint32_t clkin_freq[4];
|
||||
uint32_t clkin_freq_ccf[4];
|
||||
uint32_t vcxo_freq;
|
||||
uint32_t pll1_pfd;
|
||||
uint32_t pll2_freq;
|
||||
uint32_t pll1_loop_bw;
|
||||
uint32_t sysref_timer_div;
|
||||
unsigned int pll1_ref_prio_ctrl;
|
||||
bool clkin0_rfsync_en;
|
||||
bool clkin1_vcoin_en;
|
||||
bool high_performance_mode_clock_dist_en;
|
||||
bool rf_reseeder_disable;
|
||||
hmc7044SyncPinModeSelect_t sync_pin_mode;
|
||||
hmc7044SyncPulseGenControl_t pulse_gen_mode;
|
||||
uint32_t in_buf_mode[5];
|
||||
uint32_t gpi_ctrl[4];
|
||||
uint32_t gpo_ctrl[4];
|
||||
uint32_t num_channels;
|
||||
struct hmc7044_chan_spec *channels;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
/* Initialize the device. */
|
||||
int32_t hmc7044_reg_init(struct hmc7044_dev **device,
|
||||
const struct hmc7044_init_param *init_param);
|
||||
int32_t hmc7044_init(struct hmc7044_dev **device,
|
||||
const struct hmc7044_init_param *init_param);
|
||||
/* Remove the device. */
|
||||
int32_t hmc7044_remove(struct hmc7044_dev *device);
|
||||
int32_t hmc7044_write(struct hmc7044_dev *dev,
|
||||
uint16_t reg, uint8_t val);
|
||||
int32_t hmc7044_read(struct hmc7044_dev *dev, uint16_t reg, uint8_t *val);
|
||||
int32_t hmc7044_clk_recalc_rate(struct hmc7044_dev *dev, uint32_t chan_num,
|
||||
uint64_t *rate);
|
||||
int32_t hmc7044_clk_round_rate(struct hmc7044_dev *dev, uint32_t rate,
|
||||
uint64_t *rounded_rate);
|
||||
int32_t hmc7044_clk_set_rate(struct hmc7044_dev *dev, uint32_t chan_num,
|
||||
uint64_t rate);
|
||||
|
||||
#endif // HMC7044_H_
|
||||
@@ -0,0 +1,128 @@
|
||||
/***************************************************************************//**
|
||||
* @file lmk04828.c
|
||||
* @brief Implementation of AD9680 Driver.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2014-2016(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "lmk04828.h"
|
||||
#include "../../../include/error.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief lmk04828_read
|
||||
*******************************************************************************/
|
||||
int32_t lmk04828_read(struct lmk04828_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t *reg_data)
|
||||
{
|
||||
uint8_t tx_buf[2];
|
||||
uint8_t rx_buf[1];
|
||||
int32_t ret;
|
||||
|
||||
tx_buf[0] = 0x80 | (reg_addr >> 8);
|
||||
tx_buf[1] = reg_addr & 0xFF;
|
||||
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
tx_buf, rx_buf, 2, 1);
|
||||
|
||||
*reg_data = rx_buf[0];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief lmk04828_write
|
||||
*******************************************************************************/
|
||||
int32_t lmk04828_write(struct lmk04828_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t reg_data)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
|
||||
int32_t ret;
|
||||
|
||||
buf[0] = reg_addr >> 8;
|
||||
buf[1] = reg_addr & 0xFF;
|
||||
buf[2] = reg_data;
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
buf, NULL, 3, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief lmk04828_init
|
||||
*******************************************************************************/
|
||||
int32_t lmk04828_init(struct lmk04828_dev **device,
|
||||
const struct lmk04828_init_param *init_param)
|
||||
{
|
||||
int ret = SUCCESS;
|
||||
struct lmk04828_dev *dev;
|
||||
|
||||
dev = (struct lmk04828_dev *)malloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
return FAILURE;
|
||||
|
||||
/* SPI */
|
||||
ret = spi_init(&dev->spi_desc, init_param->spi_init);
|
||||
|
||||
*device = dev;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Free the resources allocated by lmk04828_setup().
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
*
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*******************************************************************************/
|
||||
int32_t lmk04828_remove(struct lmk04828_dev *dev)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = spi_remove(dev->spi_desc);
|
||||
|
||||
free(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/***************************************************************************//**
|
||||
* @file lmk04828.h
|
||||
* @brief Header file of lmk04828 Driver.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2014-2016(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef LMK04828_H_
|
||||
#define LMK04828_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "delay.h"
|
||||
#include "spi.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
struct lmk04828_dev {
|
||||
/* SPI */
|
||||
struct spi_desc *spi_desc;
|
||||
};
|
||||
|
||||
struct lmk04828_init_param {
|
||||
/* SPI */
|
||||
struct spi_init_param *spi_init;
|
||||
};
|
||||
|
||||
struct lmk04828_config {
|
||||
uint16_t addr;
|
||||
uint8_t value;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
int32_t lmk04828_read(struct lmk04828_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t *reg_data);
|
||||
|
||||
int32_t lmk04828_write(struct lmk04828_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t reg_data);
|
||||
|
||||
int32_t lmk04828_init(struct lmk04828_dev **device,
|
||||
const struct lmk04828_init_param *init_param);
|
||||
|
||||
int32_t lmk04828_remove(struct lmk04828_dev *dev);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,129 @@
|
||||
/***************************************************************************//**
|
||||
* @file lmx2594.c
|
||||
* @brief Implementation of AD9680 Driver.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2014-2016(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include "../lmx2594/lmx2594.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "../../../include/error.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief lmx2594_read
|
||||
*******************************************************************************/
|
||||
int32_t lmx2594_read(struct lmx2594_dev *dev,
|
||||
uint8_t reg_addr,
|
||||
uint16_t *reg_data)
|
||||
{
|
||||
uint8_t tx_buf[1];
|
||||
uint8_t rx_buf[2];
|
||||
int32_t ret;
|
||||
|
||||
tx_buf[0] = 0x80 | reg_addr;
|
||||
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
tx_buf, rx_buf, 1, 2);
|
||||
|
||||
*reg_data = rx_buf[1];
|
||||
*reg_data |= ((uint16_t)rx_buf[0]) << 8;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief lmx2594_write
|
||||
*******************************************************************************/
|
||||
int32_t lmx2594_write(struct lmx2594_dev *dev,
|
||||
uint8_t reg_addr,
|
||||
uint16_t reg_data)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
|
||||
int32_t ret;
|
||||
|
||||
buf[0] = reg_addr;
|
||||
buf[1] = reg_data >> 8;
|
||||
buf[2] = reg_data & 0xFF;
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
buf, NULL, 3, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief lmx2594_init
|
||||
*******************************************************************************/
|
||||
int32_t lmx2594_init(struct lmx2594_dev **device,
|
||||
const struct lmx2594_init_param *init_param)
|
||||
{
|
||||
int ret = SUCCESS;
|
||||
struct lmx2594_dev *dev;
|
||||
|
||||
dev = (struct lmx2594_dev *)malloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
return FAILURE;
|
||||
|
||||
/* SPI */
|
||||
ret = spi_init(&dev->spi_desc, init_param->spi_init);
|
||||
|
||||
*device = dev;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Free the resources allocated by lmx2594_setup().
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
*
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*******************************************************************************/
|
||||
int32_t lmx2594_remove(struct lmx2594_dev *dev)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = spi_remove(dev->spi_desc);
|
||||
|
||||
free(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/***************************************************************************//**
|
||||
* @file lmx2594.h
|
||||
* @brief Header file of lmx2594 Driver.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2014-2016(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef LMX2594_H_
|
||||
#define LMX2594_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "delay.h"
|
||||
#include "spi.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
struct lmx2594_dev {
|
||||
/* SPI */
|
||||
struct spi_desc *spi_desc;
|
||||
};
|
||||
|
||||
struct lmx2594_init_param {
|
||||
/* SPI */
|
||||
struct spi_init_param *spi_init;
|
||||
};
|
||||
|
||||
struct lmx2594_config {
|
||||
uint8_t addr;
|
||||
uint16_t value;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
int32_t lmx2594_read(struct lmx2594_dev *dev,
|
||||
uint8_t reg_addr,
|
||||
uint16_t *reg_data);
|
||||
|
||||
int32_t lmx2594_write(struct lmx2594_dev *dev,
|
||||
uint8_t reg_addr,
|
||||
uint16_t reg_data);
|
||||
|
||||
int32_t lmx2594_init(struct lmx2594_dev **device,
|
||||
const struct lmx2594_init_param *init_param);
|
||||
|
||||
int32_t lmx2594_remove(struct lmx2594_dev *dev);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,100 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/xilinx_delay.c
|
||||
* @brief Implementation of Xilinx Delay Functions.
|
||||
* @author Antoniu Miclaus ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "delay.h"
|
||||
#include <sleep.h>
|
||||
#ifdef _XPARAMETERS_PS_H_
|
||||
#include "util.h"
|
||||
#include "xtime_l.h"
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Generate microseconds delay.
|
||||
* @param usecs - Delay in microseconds.
|
||||
* @return None.
|
||||
*/
|
||||
void udelay(uint32_t usecs)
|
||||
{
|
||||
#ifdef _XPARAMETERS_PS_H_
|
||||
usleep(usecs);
|
||||
#else
|
||||
usleep_MB(usecs);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generate miliseconds delay.
|
||||
* @param msecs - Delay in miliseconds.
|
||||
* @return None.
|
||||
*/
|
||||
void mdelay(uint32_t msecs)
|
||||
{
|
||||
#ifdef _XPARAMETERS_PS_H_
|
||||
usleep(msecs * 1000);
|
||||
#else
|
||||
usleep_MB(msecs * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get current time.
|
||||
* @return Current time structure from system start (seconds, microseconds).
|
||||
*/
|
||||
struct time get_time(void)
|
||||
{
|
||||
struct time t = {0, 0};
|
||||
#ifdef _XPARAMETERS_PS_H_
|
||||
unsigned long long Xtime_Global;
|
||||
uint32_t rem;
|
||||
|
||||
XTime_GetTime(&Xtime_Global);
|
||||
t.s = div_u64_rem(Xtime_Global, COUNTS_PER_SECOND, &rem);
|
||||
t.us = div_u64((uint64_t)rem * 1000000, COUNTS_PER_SECOND);
|
||||
#endif
|
||||
|
||||
return t;
|
||||
}
|
||||
@@ -0,0 +1,464 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/xilinx_gpio.c
|
||||
* @brief Implementation of Xilinx GPIO Generic Driver.
|
||||
* @author Antoniu Miclaus ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <xparameters.h>
|
||||
#ifdef XPAR_XGPIO_NUM_INSTANCES
|
||||
#include <xgpio.h>
|
||||
#endif
|
||||
#ifdef XPAR_XGPIOPS_NUM_INSTANCES
|
||||
#include <xgpiops.h>
|
||||
#endif
|
||||
|
||||
#include "error.h"
|
||||
#include "gpio.h"
|
||||
#include "xilinx_gpio.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Prepare the GPIO decriptor.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param param - The structure that contains the GPIO parameters.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t _gpio_init(struct gpio_desc *desc,
|
||||
const struct gpio_init_param *param)
|
||||
{
|
||||
int32_t ret;
|
||||
struct xil_gpio_desc *xdesc;
|
||||
struct xil_gpio_init_param *xinit;
|
||||
|
||||
ret = -1;
|
||||
|
||||
xdesc = desc->extra;
|
||||
xinit = param->extra;
|
||||
|
||||
xdesc->type = xinit->type;
|
||||
desc->number = param->number;
|
||||
|
||||
switch (xinit->type) {
|
||||
case GPIO_PL:
|
||||
#ifdef XGPIO_H
|
||||
xdesc->instance = (XGpio *)malloc(sizeof(XGpio));
|
||||
if(!xdesc->instance)
|
||||
goto pl_error;
|
||||
|
||||
xdesc->config = XGpio_LookupConfig(xinit->device_id);
|
||||
if(xdesc->config == NULL)
|
||||
goto pl_error;
|
||||
|
||||
ret = XGpio_CfgInitialize(xdesc->instance,
|
||||
xdesc->config,
|
||||
((XGpio_Config*)xdesc->config)
|
||||
->BaseAddress);
|
||||
if(ret < 0)
|
||||
goto pl_error;
|
||||
|
||||
break;
|
||||
pl_error:
|
||||
free(xdesc->instance);
|
||||
#endif
|
||||
goto error;
|
||||
case GPIO_PS:
|
||||
#ifdef XGPIOPS_H
|
||||
xdesc->instance = (XGpioPs *)malloc(sizeof(XGpioPs));
|
||||
if(!xdesc->instance)
|
||||
goto ps_error;
|
||||
|
||||
xdesc->config = XGpioPs_LookupConfig(xinit->device_id);
|
||||
if(xdesc->config == NULL)
|
||||
goto ps_error;
|
||||
|
||||
ret = XGpioPs_CfgInitialize(xdesc->instance,
|
||||
xdesc->config,
|
||||
((XGpioPs_Config*)xdesc->config)->BaseAddr);
|
||||
if(ret < 0)
|
||||
goto ps_error;
|
||||
break;
|
||||
ps_error:
|
||||
free(xdesc->instance);
|
||||
#endif
|
||||
goto error;
|
||||
error:
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Obtain the GPIO decriptor.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param param - GPIO initialization parameters
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_get(struct gpio_desc **desc,
|
||||
const struct gpio_init_param *param)
|
||||
{
|
||||
struct gpio_desc *descriptor;
|
||||
struct xil_gpio_desc *extra;
|
||||
int32_t ret;
|
||||
|
||||
descriptor = (struct gpio_desc *)malloc(sizeof(*descriptor));
|
||||
extra = (struct xil_gpio_desc*)malloc(sizeof(*extra));
|
||||
|
||||
if (!descriptor || !extra)
|
||||
return -1;
|
||||
|
||||
descriptor->extra = extra;
|
||||
ret = _gpio_init(descriptor, param);
|
||||
|
||||
if(ret != 0)
|
||||
goto error;
|
||||
|
||||
*desc = descriptor;
|
||||
|
||||
return 0;
|
||||
error:
|
||||
free(extra);
|
||||
free(descriptor);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the value of an optional GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param param - GPIO Initialization parameters.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_get_optional(struct gpio_desc **desc,
|
||||
const struct gpio_init_param *param)
|
||||
{
|
||||
if(param == NULL) {
|
||||
*desc = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return xil_gpio_get(desc, param);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by gpio_get().
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_remove(struct gpio_desc *desc)
|
||||
{
|
||||
if (desc != NULL) {
|
||||
free(((struct xil_gpio_desc *)(desc->extra))->instance);
|
||||
free(desc->extra);
|
||||
free(desc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the input direction of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_direction_input(struct gpio_desc *desc)
|
||||
{
|
||||
struct xil_gpio_desc *extra;
|
||||
#ifdef XGPIO_H
|
||||
uint8_t pin = desc->number;
|
||||
uint32_t channel = 1;
|
||||
uint32_t config = 0;
|
||||
#endif
|
||||
extra = desc->extra;
|
||||
|
||||
switch (extra->type) {
|
||||
case GPIO_PL:
|
||||
#ifdef XGPIO_H
|
||||
/* We assume that pin 32 is the first pin from channel 2 */
|
||||
if (pin >= 32) {
|
||||
channel = 2;
|
||||
pin -= 32;
|
||||
}
|
||||
|
||||
config = XGpio_GetDataDirection((XGpio *)extra->instance,
|
||||
channel);
|
||||
config |= (1 << pin);
|
||||
XGpio_SetDataDirection((XGpio *)extra->instance,
|
||||
channel,
|
||||
config);
|
||||
#endif
|
||||
break;
|
||||
case GPIO_PS:
|
||||
#ifdef XGPIOPS_H
|
||||
XGpioPs_SetDirectionPin(extra->instance,
|
||||
desc->number,
|
||||
GPIO_IN);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the output direction of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param value - The value.
|
||||
* Example: GPIO_HIGH
|
||||
* GPIO_LOW
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_direction_output(struct gpio_desc *desc,
|
||||
uint8_t value)
|
||||
{
|
||||
struct xil_gpio_desc *extra;
|
||||
#ifdef XGPIO_H
|
||||
uint8_t pin = desc->number;
|
||||
uint8_t channel;
|
||||
uint32_t reg_val;
|
||||
#endif
|
||||
extra = desc->extra;
|
||||
|
||||
switch (extra->type) {
|
||||
case GPIO_PL:
|
||||
#ifdef XGPIO_H
|
||||
if (pin >= 32) {
|
||||
channel = 2;
|
||||
pin -= 32;
|
||||
} else
|
||||
channel = 1;
|
||||
|
||||
reg_val = XGpio_GetDataDirection(extra->instance,
|
||||
channel);
|
||||
reg_val &= ~(1 << pin);
|
||||
XGpio_SetDataDirection(extra->instance,
|
||||
channel,
|
||||
reg_val);
|
||||
reg_val = XGpio_DiscreteRead(extra->instance,
|
||||
channel);
|
||||
if(value)
|
||||
reg_val |= (1 << pin);
|
||||
else
|
||||
reg_val &= ~(1 << pin);
|
||||
XGpio_DiscreteWrite(extra->instance,
|
||||
channel,
|
||||
reg_val);
|
||||
#endif
|
||||
break;
|
||||
case GPIO_PS:
|
||||
#ifdef XGPIOPS_H
|
||||
XGpioPs_SetDirectionPin(extra->instance,
|
||||
desc->number,
|
||||
GPIO_OUT);
|
||||
XGpioPs_SetOutputEnablePin(extra->instance,
|
||||
desc->number,
|
||||
GPIO_OUT);
|
||||
XGpioPs_WritePin(extra->instance,
|
||||
desc->number,
|
||||
value);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the direction of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param direction - The direction.
|
||||
* Example: GPIO_OUT
|
||||
* GPIO_IN
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_get_direction(struct gpio_desc *desc,
|
||||
uint8_t *direction)
|
||||
{
|
||||
if (!desc)
|
||||
return -1;
|
||||
|
||||
struct xil_gpio_desc *extra;
|
||||
uint8_t pin = desc->number;
|
||||
|
||||
#ifdef XGPIO_H
|
||||
uint8_t channel;
|
||||
#endif
|
||||
extra = desc->extra;
|
||||
|
||||
switch (extra->type) {
|
||||
case GPIO_PL:
|
||||
#ifdef XGPIO_H
|
||||
if (pin >= 32) {
|
||||
channel = 2;
|
||||
pin -= 32;
|
||||
} else
|
||||
channel = 1;
|
||||
*direction = ((XGpio_GetDataDirection(extra->instance,
|
||||
channel) >> pin) & 0x1) ^ 0x1;
|
||||
#endif
|
||||
break;
|
||||
case GPIO_PS:
|
||||
#ifdef XGPIOPS_H
|
||||
*direction = XGpioPs_GetDirectionPin(extra->instance, pin);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the value of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param value - The value.
|
||||
* Example: GPIO_HIGH
|
||||
* GPIO_LOW
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_set_value(struct gpio_desc *desc,
|
||||
uint8_t value)
|
||||
{
|
||||
struct xil_gpio_desc *extra;
|
||||
#ifdef XGPIO_H
|
||||
uint8_t pin = desc->number;
|
||||
uint8_t channel;
|
||||
uint32_t reg_val;
|
||||
#endif
|
||||
extra = desc->extra;
|
||||
|
||||
switch (extra->type) {
|
||||
case GPIO_PL:
|
||||
#ifdef XGPIO_H
|
||||
if (pin >= 32) {
|
||||
channel = 2;
|
||||
pin -= 32;
|
||||
} else
|
||||
channel = 1;
|
||||
|
||||
reg_val = XGpio_DiscreteRead(extra->instance, channel);
|
||||
if(value)
|
||||
reg_val |= (1 << pin);
|
||||
else
|
||||
reg_val &= ~(1 << pin);
|
||||
XGpio_DiscreteWrite(extra->instance, channel, reg_val);
|
||||
#endif
|
||||
break;
|
||||
case GPIO_PS:
|
||||
#ifdef XGPIOPS_H
|
||||
XGpioPs_WritePin(extra->instance, desc->number, value);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the value of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param value - The value.
|
||||
* Example: GPIO_HIGH
|
||||
* GPIO_LOW
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_get_value(struct gpio_desc *desc,
|
||||
uint8_t *value)
|
||||
{
|
||||
if (!desc)
|
||||
return -1;
|
||||
|
||||
struct xil_gpio_desc *extra;
|
||||
uint8_t pin = desc->number;
|
||||
|
||||
#ifdef XGPIO_H
|
||||
uint8_t channel;
|
||||
#endif
|
||||
extra = desc->extra;
|
||||
|
||||
switch (extra->type) {
|
||||
case GPIO_PL:
|
||||
#ifdef XGPIO_H
|
||||
if (pin >= 32) {
|
||||
channel = 2;
|
||||
pin -= 32;
|
||||
} else
|
||||
channel = 1;
|
||||
*value = (XGpio_DiscreteRead(extra->instance, channel) >> pin) & 0x01;
|
||||
#endif
|
||||
break;
|
||||
case GPIO_PS:
|
||||
#ifdef XGPIOPS_H
|
||||
*value = XGpioPs_ReadPin(extra->instance, pin);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Xilinx platform specific GPIO platform ops structure
|
||||
*/
|
||||
const struct gpio_platform_ops xil_gpio_ops = {
|
||||
.gpio_ops_get = &xil_gpio_get,
|
||||
.gpio_ops_get_optional = &xil_gpio_get_optional,
|
||||
.gpio_ops_remove = &xil_gpio_remove,
|
||||
.gpio_ops_direction_input = &xil_gpio_direction_input,
|
||||
.gpio_ops_direction_output = &xil_gpio_direction_output,
|
||||
.gpio_ops_get_direction = &xil_gpio_get_direction,
|
||||
.gpio_ops_set_value = &xil_gpio_set_value,
|
||||
.gpio_ops_get_value = &xil_gpio_get_value,
|
||||
};
|
||||
@@ -0,0 +1,95 @@
|
||||
/*******************************************************************************
|
||||
* @file xilinx/xilinx_gpio.h
|
||||
* @brief Header containing extra types used in the gpio driver
|
||||
* @author scuciurean ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef XILINX_GPIO_H_
|
||||
#define XILINX_GPIO_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @enum xil_gpio_type
|
||||
* @brief Xilinx platform architecture sections
|
||||
*/
|
||||
enum xil_gpio_type {
|
||||
/** Programmable Logic */
|
||||
GPIO_PL,
|
||||
/** Processing System */
|
||||
GPIO_PS
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_gpio_init_param
|
||||
* @brief Structure holding the initialization parameters for Xilinx platform
|
||||
* specific GPIO parameters.
|
||||
*/
|
||||
struct xil_gpio_init_param {
|
||||
/** Xilinx architecture */
|
||||
enum xil_gpio_type type;
|
||||
/** Device ID */
|
||||
uint32_t device_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_gpio_desc
|
||||
* @brief Xilinx platform specific GPIO descriptor
|
||||
*/
|
||||
struct xil_gpio_desc {
|
||||
/** Xilinx architecture */
|
||||
enum xil_gpio_type type;
|
||||
/** Xilinx GPIO configuration */
|
||||
void *config;
|
||||
/** Xilinx GPIO Instance */
|
||||
void *instance;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Xilinx platform specific gpio platform ops structure
|
||||
*/
|
||||
extern const struct gpio_platform_ops xil_gpio_ops;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,360 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/xilinx_gpio_irq.c
|
||||
* @brief Implementation of Xilinx GPIO IRQ Generic Driver.
|
||||
* @author Porumb Andrei ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2021(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "xparameters.h"
|
||||
#include "error.h"
|
||||
#include "xilinx_gpio_irq.h"
|
||||
#include "util.h"
|
||||
#include "list.h"
|
||||
#include "irq.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Comparing function used by list.
|
||||
* @param desc_a - Compared item
|
||||
* @param desc_b - Reference item
|
||||
* @return - 0 if items match
|
||||
*/
|
||||
static int32_t call_cmp(struct xil_callback_desc *desc_a,
|
||||
struct xil_callback_desc *desc_b)
|
||||
{
|
||||
return desc_a->pin_nb - desc_b->pin_nb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function called when GPIO IRQ occurs.
|
||||
* @param param - GPIO IRQ desc's extra field
|
||||
* @return - None.
|
||||
*/
|
||||
static void xil_gpio_irq_handler(struct xil_gpio_irq_desc *param)
|
||||
{
|
||||
int32_t status = 0;
|
||||
int32_t pin_nb;
|
||||
struct xil_callback_desc *callback_desc;
|
||||
|
||||
status = iterator_move_to_idx(param->it, 0);
|
||||
while(!status) {
|
||||
iterator_read(param->it, &callback_desc);
|
||||
status = iterator_move(param->it, 1);
|
||||
if(XGpioPs_IntrGetStatusPin(¶m->my_Gpio, callback_desc->pin_nb))
|
||||
callback_desc->triggered = true;
|
||||
}
|
||||
|
||||
status = iterator_move_to_idx(param->it, 0);
|
||||
while(!status) {
|
||||
iterator_read(param->it, &callback_desc);
|
||||
status = iterator_move(param->it, 1);
|
||||
if(callback_desc->triggered == true) {
|
||||
callback_desc->triggered = false;
|
||||
XGpioPs_IntrDisablePin(¶m->my_Gpio, callback_desc->pin_nb);
|
||||
XGpioPs_IntrClearPin(¶m->my_Gpio, callback_desc->pin_nb);
|
||||
callback_desc->callback.legacy_callback(callback_desc->callback.ctx, 0U, NULL);
|
||||
if(callback_desc->enabled)
|
||||
XGpioPs_IntrEnablePin(¶m->my_Gpio, callback_desc->pin_nb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable specific GPIO IRQ pin.
|
||||
* @param desc - The GPIO IRQ controller descriptor.
|
||||
* @param irq_id - Pin number.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_irq_disable(struct irq_ctrl_desc *desc, uint32_t irq_id)
|
||||
{
|
||||
int32_t status;
|
||||
struct xil_gpio_irq_desc *extra;
|
||||
struct xil_callback_desc *callback_desc;
|
||||
|
||||
extra = desc->extra;
|
||||
|
||||
status = iterator_move_to_idx(extra->it, 0);
|
||||
while(!status) {
|
||||
iterator_read(extra->it, &callback_desc);
|
||||
status = iterator_move(extra->it, 1);
|
||||
if(callback_desc->pin_nb == irq_id) {
|
||||
callback_desc->enabled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XGpioPs_IntrDisablePin(&extra->my_Gpio, irq_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the GPIO IRQ controller.
|
||||
* @param desc - The GPIO IRQ controller descriptor.
|
||||
* @param param - The GPIO IRQ controller initial parameters.
|
||||
* irq_ctrl_id from irq_init_param is the interrupt id for the parent controller
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_irq_ctrl_init(struct irq_ctrl_desc **desc,
|
||||
const struct irq_init_param *param)
|
||||
{
|
||||
int32_t i;
|
||||
int32_t status;
|
||||
struct irq_ctrl_desc *ldesc;
|
||||
static XGpioPs_Config *GPIO_Config;
|
||||
struct xil_gpio_irq_desc *xil_desc;
|
||||
struct xil_gpio_irq_init_param *xil_ip;
|
||||
struct callback_desc callback;
|
||||
|
||||
xil_desc = (struct xil_gpio_irq_desc *)calloc(1, sizeof(*xil_desc));
|
||||
if(!xil_desc)
|
||||
return -ENOMEM;
|
||||
|
||||
ldesc = (struct irq_ctrl_desc *)calloc(1, sizeof(*ldesc));
|
||||
if(!ldesc) {
|
||||
free(xil_desc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
xil_ip = param->extra;
|
||||
GPIO_Config = XGpioPs_LookupConfig(xil_ip->gpio_device_id);
|
||||
status = XGpioPs_CfgInitialize(&xil_desc->my_Gpio, GPIO_Config,
|
||||
GPIO_Config->BaseAddr);
|
||||
if(status)
|
||||
goto error_desc;
|
||||
|
||||
ldesc->extra = xil_desc;
|
||||
xil_desc->parent_desc = xil_ip->parent_desc;
|
||||
|
||||
status = list_init(&xil_desc->callback_list, LIST_DEFAULT,
|
||||
call_cmp);
|
||||
if(status)
|
||||
goto error_list;
|
||||
|
||||
status = iterator_init(&xil_desc->it, xil_desc->callback_list, 0);
|
||||
if(status) {
|
||||
iterator_remove(xil_desc->it);
|
||||
goto error_list;
|
||||
}
|
||||
|
||||
ldesc->irq_ctrl_id = param->irq_ctrl_id;
|
||||
status = irq_trigger_level_set(xil_desc->parent_desc, ldesc->irq_ctrl_id,
|
||||
IRQ_EDGE_RISING);
|
||||
if(status)
|
||||
goto error_op;
|
||||
|
||||
status = irq_enable(xil_desc->parent_desc, ldesc->irq_ctrl_id);
|
||||
if(status)
|
||||
goto error_op;
|
||||
|
||||
callback.legacy_callback = &xil_gpio_irq_handler;
|
||||
callback.ctx = ldesc->extra;
|
||||
status = irq_register_callback(xil_desc->parent_desc, ldesc->irq_ctrl_id,
|
||||
&callback);
|
||||
if(status)
|
||||
goto error_op;
|
||||
|
||||
*desc = ldesc;
|
||||
|
||||
return 0;
|
||||
|
||||
error_op:
|
||||
iterator_remove(xil_desc->it);
|
||||
error_list:
|
||||
list_remove(xil_desc->callback_list);
|
||||
error_desc:
|
||||
free(xil_desc);
|
||||
free(ldesc);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set GPIO interrupt trigger level.
|
||||
* @param desc - The GPIO IRQ controller descriptor.
|
||||
* @param irq_id - Pin number.
|
||||
* @param trig - New trigger level for the GPIO interrupt.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_irq_trigger_level_set(struct irq_ctrl_desc *desc,
|
||||
uint32_t irq_id,
|
||||
enum irq_trig_level trig)
|
||||
{
|
||||
static const int32_t trig_level[5] = {XGPIOPS_IRQ_TYPE_LEVEL_LOW,
|
||||
XGPIOPS_IRQ_TYPE_LEVEL_HIGH,
|
||||
XGPIOPS_IRQ_TYPE_EDGE_FALLING,
|
||||
XGPIOPS_IRQ_TYPE_EDGE_RISING,
|
||||
XGPIOPS_IRQ_TYPE_EDGE_BOTH
|
||||
};
|
||||
struct xil_gpio_irq_desc *extra;
|
||||
|
||||
extra = desc->extra;
|
||||
XGpioPs_SetIntrTypePin(&extra->my_Gpio, irq_id, trig_level[trig]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register pin specific GPIO interrupt.
|
||||
* @param desc - The GPIO IRQ controller descriptor.
|
||||
* @param irq_id - Pin number.
|
||||
* @param callback_desc - Callback.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_irq_register_callback(struct irq_ctrl_desc *desc,
|
||||
uint32_t irq_id,
|
||||
struct callback_desc *callback_desc)
|
||||
{
|
||||
struct xil_callback_desc *dev_callback;
|
||||
struct xil_gpio_irq_desc *extra;
|
||||
|
||||
dev_callback = (struct xil_callback_desc *)calloc(1,
|
||||
sizeof(*dev_callback));
|
||||
if(!dev_callback)
|
||||
return -1;
|
||||
|
||||
dev_callback->pin_nb = irq_id;
|
||||
dev_callback->callback.legacy_callback = callback_desc->legacy_callback;
|
||||
dev_callback->callback.ctx = callback_desc->ctx;
|
||||
dev_callback->triggered = false;
|
||||
|
||||
extra = desc->extra;
|
||||
XGpioPs_SetDirectionPin(&extra->my_Gpio, irq_id, 0);
|
||||
list_add_last(extra->callback_list, dev_callback);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister pin specific GPIO interrupt.
|
||||
* @param desc - The GPIO IRQ controller descriptor.
|
||||
* @param irq_id - Pin number.
|
||||
* @param cb - Callback descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_irq_unregister_callback(struct irq_ctrl_desc *desc,
|
||||
uint32_t irq_id, struct callback_desc *cb)
|
||||
{
|
||||
int32_t status;
|
||||
struct xil_gpio_irq_desc *extra;
|
||||
struct xil_callback_desc *dev_callback;
|
||||
struct xil_callback_desc search_callback;
|
||||
|
||||
extra = desc->extra;
|
||||
search_callback.pin_nb = irq_id;
|
||||
status = list_get_find(extra->callback_list, &dev_callback,
|
||||
&search_callback);
|
||||
if(status)
|
||||
return -ENXIO;
|
||||
|
||||
free(dev_callback);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable specific GPIO IRQ pin.
|
||||
* @param desc - The GPIO IRQ controller descriptor.
|
||||
* @param irq_id - Pin number.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_irq_enable(struct irq_ctrl_desc *desc, uint32_t irq_id)
|
||||
{
|
||||
int32_t status;
|
||||
struct xil_gpio_irq_desc *extra;
|
||||
struct xil_callback_desc *callback_desc;
|
||||
|
||||
extra = desc->extra;
|
||||
|
||||
status = iterator_move_to_idx(extra->it, 0);
|
||||
while(!status) {
|
||||
iterator_read(extra->it, &callback_desc);
|
||||
status = iterator_move(extra->it, 1);
|
||||
if(callback_desc->pin_nb == irq_id) {
|
||||
callback_desc->enabled = true;
|
||||
XGpioPs_IntrClearPin(&extra->my_Gpio, irq_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XGpioPs_IntrEnablePin(&extra->my_Gpio, irq_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove the GPIO IRQ controller.
|
||||
* @param desc - The GPIO IRQ controller descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_irq_ctrl_remove(struct irq_ctrl_desc *desc)
|
||||
{
|
||||
struct xil_gpio_irq_desc *extra;
|
||||
struct xil_callback_desc *callback_desc;
|
||||
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
extra = desc->extra;
|
||||
while (0 == list_get_first(extra->callback_list, &callback_desc))
|
||||
free(callback_desc);
|
||||
|
||||
iterator_remove(extra->it);
|
||||
list_remove(extra->callback_list);
|
||||
free(extra);
|
||||
free(desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Xilinx platform specific GPIO IRQ platform ops structure
|
||||
*/
|
||||
const struct irq_platform_ops xil_gpio_irq_ops = {
|
||||
.init = &xil_gpio_irq_ctrl_init,
|
||||
.enable = &xil_gpio_irq_enable,
|
||||
.disable = &xil_gpio_irq_disable,
|
||||
.trigger_level_set = &xil_gpio_irq_trigger_level_set,
|
||||
.register_callback = &xil_gpio_irq_register_callback,
|
||||
.unregister_callback = xil_gpio_irq_unregister_callback,
|
||||
.remove = &xil_gpio_irq_ctrl_remove
|
||||
};
|
||||
@@ -0,0 +1,92 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx_gpio_irq.h
|
||||
* @brief Implementation of Xilinx GPIO IRQ Generic Driver.
|
||||
* @author Porumb Andrei ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2021(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef XILINX_GPIO_IRQ_H_
|
||||
#define XILINX_GPIO_IRQ_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "stdbool.h"
|
||||
#include "list.h"
|
||||
#include "xgpiops.h"
|
||||
#include "irq.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* @struct xil_callback_desc
|
||||
* @brief Structure holding callback parameters for each pin
|
||||
*/
|
||||
struct xil_callback_desc {
|
||||
int32_t pin_nb;
|
||||
struct callback_desc callback;
|
||||
bool triggered;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_gpio_irq_init_param
|
||||
* @brief Structure holding the initialization parameters for Xilinx platform
|
||||
* specific GPIO IRQ parameters.
|
||||
*/
|
||||
struct xil_gpio_irq_init_param {
|
||||
struct irq_ctrl_desc *parent_desc;
|
||||
int32_t gpio_device_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_gpio_irq_desc
|
||||
* @brief Xilinx platform specific GPIO IRQ descriptor
|
||||
*/
|
||||
struct xil_gpio_irq_desc {
|
||||
struct irq_ctrl_desc *parent_desc;
|
||||
XGpioPs my_Gpio;
|
||||
struct list_desc *callback_list;
|
||||
struct iterator *it;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Xilinx specific GPIO IRQ platform ops structure
|
||||
*/
|
||||
extern const struct irq_platform_ops xil_gpio_irq_ops;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,514 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/xilinx_i2c.c
|
||||
* @brief Implementation of Xilinx I2C Generic Driver.
|
||||
* @author Antoniu Miclaus ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <xparameters.h>
|
||||
#ifdef XPAR_XIIC_NUM_INSTANCES
|
||||
#include <xiic.h>
|
||||
#endif
|
||||
#ifdef XPAR_XIICPS_NUM_INSTANCES
|
||||
#include <xiicps.h>
|
||||
#endif
|
||||
|
||||
#include "error.h"
|
||||
#include "i2c.h"
|
||||
#include "xilinx_i2c.h"
|
||||
#include "list.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
static struct list_desc *pl_list = NULL;
|
||||
static struct iterator *pl_it = NULL;
|
||||
|
||||
#ifdef XIICPS_H
|
||||
static struct list_desc *ps_list = NULL;
|
||||
static struct iterator *ps_it = NULL;
|
||||
#endif /* XIICPS_H */
|
||||
|
||||
/**
|
||||
* @struct inst_table_item
|
||||
* @brief Table item for I2C cores already started.
|
||||
*/
|
||||
struct inst_table_item {
|
||||
/** Instance the BSP driver uses for this core. */
|
||||
void *instance;
|
||||
/** Core ID in BSP. */
|
||||
uint32_t device_id;
|
||||
/** Number of ADI driver instances running on this core. */
|
||||
uint32_t inst_no;
|
||||
};
|
||||
|
||||
#ifdef XPAR_XIICPS_NUM_INSTANCES
|
||||
/** Save the current state of the bitrate to not change it each time */
|
||||
static uint32_t ps_last_bitrate = 0;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Xilinx platform specific I2C platform ops structure
|
||||
*/
|
||||
const struct i2c_platform_ops xil_i2c_ops = {
|
||||
.i2c_ops_init = &xil_i2c_init,
|
||||
.i2c_ops_write = &xil_i2c_write,
|
||||
.i2c_ops_read = &xil_i2c_read,
|
||||
.i2c_ops_remove = &xil_i2c_remove
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Compare two I2C cores by ID.
|
||||
* @param el1 - First I2C core to compare.
|
||||
* @param el2 - Second I2C core to compare.
|
||||
* @return \ref 0 if the two cores have the same ID,
|
||||
* \ref difference between the first and the second IDs otherwise.
|
||||
*/
|
||||
static int32_t xil_i2c_cmp(void *el1, void *el2)
|
||||
{
|
||||
struct inst_table_item *sel1 = el1, *sel2 = el2;
|
||||
|
||||
return (sel1->device_id - sel2->device_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure slave address and bitrate if needed
|
||||
* @param desc - Descriptor of the I2C device
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
static int32_t xil_i2c_set_transmission_config(struct i2c_desc *desc)
|
||||
{
|
||||
struct xil_i2c_desc *xil_i2c_desc = desc->extra;
|
||||
#ifdef XIICPS_H
|
||||
int32_t ret;
|
||||
#endif
|
||||
|
||||
switch (xil_i2c_desc->type) {
|
||||
case IIC_PL:
|
||||
#ifdef XIIC_H
|
||||
break;
|
||||
#endif
|
||||
return -1;
|
||||
case IIC_PS:
|
||||
#ifdef XIICPS_H
|
||||
if (desc->max_speed_hz != ps_last_bitrate) {
|
||||
ret = XIicPs_SetSClk(xil_i2c_desc->instance, desc->max_speed_hz);
|
||||
if (ret != XST_SUCCESS)
|
||||
return -1;
|
||||
ps_last_bitrate = desc->max_speed_hz;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
return -1;
|
||||
default:
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the I2C communication peripheral.
|
||||
* @param desc - The I2C descriptor.
|
||||
* @param param - The structure that contains the I2C parameters.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_i2c_init(struct i2c_desc **desc,
|
||||
const struct i2c_init_param *param)
|
||||
{
|
||||
int32_t ret;
|
||||
struct i2c_desc *idesc;
|
||||
struct xil_i2c_desc *xdesc;
|
||||
struct xil_i2c_init_param *xinit;
|
||||
|
||||
idesc = (struct i2c_desc *)malloc(sizeof(*idesc));
|
||||
xdesc = (struct xil_i2c_desc *)malloc(sizeof(*xdesc));
|
||||
|
||||
if(!idesc || !xdesc)
|
||||
goto error;
|
||||
|
||||
idesc->max_speed_hz = param->max_speed_hz;
|
||||
idesc->slave_address = param->slave_address;
|
||||
xinit = param->extra;
|
||||
|
||||
idesc->extra = xdesc;
|
||||
xdesc->type = xinit->type;
|
||||
xdesc->device_id = xinit->device_id;
|
||||
switch (xinit->type) {
|
||||
case IIC_PL:
|
||||
#ifdef XIIC_H
|
||||
; /** Intentional empty statement */
|
||||
struct inst_table_item tab_check_pl;
|
||||
struct inst_table_item *temp_el_pl;
|
||||
|
||||
if (!pl_list)
|
||||
list_init(&pl_list, LIST_DEFAULT, xil_i2c_cmp);
|
||||
if (!pl_it)
|
||||
iterator_init(&pl_it, pl_list, true);
|
||||
|
||||
tab_check_pl.device_id = xdesc->device_id;
|
||||
|
||||
if (!IS_ERR_VALUE(list_read_find(pl_list, (void **)&temp_el_pl,
|
||||
&tab_check_pl))) {
|
||||
xdesc->instance = temp_el_pl->instance;
|
||||
temp_el_pl->inst_no++;
|
||||
break;
|
||||
}
|
||||
|
||||
xdesc->instance = (XIic *)malloc(sizeof(XIic));
|
||||
if(!xdesc->instance)
|
||||
goto pl_error;
|
||||
|
||||
xdesc->config = XIic_LookupConfig(xinit->device_id);
|
||||
if(xdesc->config == NULL)
|
||||
goto pl_error;
|
||||
|
||||
ret = XIic_CfgInitialize(xdesc->instance,
|
||||
xdesc->config,
|
||||
((XIic_Config*)xdesc->config)
|
||||
->BaseAddress);
|
||||
if(ret != 0)
|
||||
goto pl_error;
|
||||
|
||||
ret = XIic_Start(xdesc->instance);
|
||||
if(ret != 0)
|
||||
goto pl_error;
|
||||
|
||||
ret = XIic_SetAddress(xdesc->instance,
|
||||
XII_ADDR_TO_SEND_TYPE,
|
||||
param->slave_address);
|
||||
if(ret != 0)
|
||||
goto pl_error;
|
||||
|
||||
ret = XIic_SelfTest(xdesc->instance);
|
||||
if(ret < 0)
|
||||
goto pl_error;
|
||||
|
||||
ret = XIic_SetGpOutput(xdesc->instance, 1);
|
||||
if(ret < 0)
|
||||
goto pl_error;
|
||||
|
||||
temp_el_pl = (struct inst_table_item*)calloc(1, sizeof(*temp_el_pl));
|
||||
temp_el_pl->device_id = xinit->device_id;
|
||||
temp_el_pl->inst_no = 1;
|
||||
temp_el_pl->instance = xdesc->instance;
|
||||
pl_list->push(pl_list, temp_el_pl);
|
||||
|
||||
break;
|
||||
pl_error:
|
||||
free(xdesc->instance);
|
||||
#endif
|
||||
goto error;
|
||||
case IIC_PS:
|
||||
#ifdef XIICPS_H
|
||||
; /** Intentional empty statement */
|
||||
struct inst_table_item tab_check_ps;
|
||||
struct inst_table_item *temp_el_ps;
|
||||
|
||||
if (!pl_list)
|
||||
list_init(&ps_list, LIST_DEFAULT, xil_i2c_cmp);
|
||||
if (!pl_it)
|
||||
iterator_init(&ps_it, ps_list, true);
|
||||
|
||||
tab_check_ps.device_id = xdesc->device_id;
|
||||
|
||||
if (!IS_ERR_VALUE(list_read_find(ps_list,
|
||||
(void **)&temp_el_ps,
|
||||
&tab_check_ps))) {
|
||||
xdesc->instance = temp_el_ps->instance;
|
||||
temp_el_ps->inst_no++;
|
||||
break;
|
||||
}
|
||||
|
||||
xdesc->instance = (XIicPs *)malloc(sizeof(XIicPs));
|
||||
if(!xdesc->instance)
|
||||
goto ps_error;
|
||||
|
||||
xdesc->config = XIicPs_LookupConfig(xinit->device_id);
|
||||
if(xdesc->config == NULL)
|
||||
goto ps_error;
|
||||
|
||||
ret = XIicPs_CfgInitialize(xdesc->instance,
|
||||
xdesc->config,
|
||||
((XIicPs_Config*)xdesc->config)
|
||||
->BaseAddress);
|
||||
if(ret != 0)
|
||||
goto ps_error;
|
||||
|
||||
XIicPs_SetSClk(xdesc->instance, param->max_speed_hz);
|
||||
|
||||
temp_el_ps = (struct inst_table_item*)calloc(1, sizeof(*temp_el_ps));
|
||||
temp_el_ps->device_id = xinit->device_id;
|
||||
temp_el_ps->inst_no = 1;
|
||||
temp_el_ps->instance = xdesc->instance;
|
||||
ps_list->push(ps_list, temp_el_ps);
|
||||
|
||||
break;
|
||||
ps_error:
|
||||
free(xdesc->instance);
|
||||
#endif
|
||||
goto error;
|
||||
|
||||
default:
|
||||
goto error;
|
||||
break;
|
||||
}
|
||||
|
||||
*desc = idesc;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free(idesc);
|
||||
free(xdesc);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by i2c_init().
|
||||
* @param desc - The I2C descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_i2c_remove(struct i2c_desc *desc)
|
||||
{
|
||||
struct xil_i2c_desc *xdesc;
|
||||
int32_t ret;
|
||||
|
||||
xdesc = desc->extra;
|
||||
|
||||
switch (xdesc->type) {
|
||||
case IIC_PL:
|
||||
#ifdef XIIC_H
|
||||
; /** Intentional empty statement */
|
||||
struct inst_table_item tab_check_pl;
|
||||
struct inst_table_item *temp_el_pl;
|
||||
tab_check_pl.device_id = xdesc->device_id;
|
||||
ret = iterator_find(pl_it, &tab_check_pl);
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
iterator_read(pl_it, (void **)&temp_el_pl);
|
||||
temp_el_pl->inst_no--;
|
||||
if (temp_el_pl->inst_no != 0)
|
||||
break;
|
||||
|
||||
ret = XIic_Stop(((XIic *)xdesc->instance));
|
||||
|
||||
if(ret != 0)
|
||||
goto error;
|
||||
|
||||
/** Remove list element */
|
||||
iterator_get(pl_it, (void **)&temp_el_pl);
|
||||
free(temp_el_pl);
|
||||
break;
|
||||
#endif
|
||||
goto error;
|
||||
case IIC_PS:
|
||||
#ifdef XIICPS_H
|
||||
; /** Intentional empty statement */
|
||||
struct inst_table_item tab_check_ps;
|
||||
struct inst_table_item *temp_el_ps;
|
||||
tab_check_ps.device_id = xdesc->device_id;
|
||||
ret = iterator_find(ps_it, &tab_check_ps);
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
iterator_read(ps_it, (void **)&temp_el_ps);
|
||||
temp_el_ps->inst_no--;
|
||||
if (temp_el_ps->inst_no != 0)
|
||||
break;
|
||||
|
||||
/** Remove list element */
|
||||
iterator_get(ps_it, (void **)&temp_el_ps);
|
||||
free(temp_el_ps);
|
||||
break;
|
||||
#endif
|
||||
/* Intended fallthrough */
|
||||
error:
|
||||
default:
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(desc->extra);
|
||||
free(desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write data to a slave device.
|
||||
* @param desc - The I2C descriptor.
|
||||
* @param data - Buffer that stores the transmission data.
|
||||
* @param bytes_number - Number of bytes to write.
|
||||
* @param stop_bit - Stop condition control.
|
||||
* Example: 0 - A stop condition will not be generated;
|
||||
* 1 - A stop condition will be generated.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_i2c_write(struct i2c_desc *desc,
|
||||
uint8_t *data,
|
||||
uint8_t bytes_number,
|
||||
uint8_t stop_bit)
|
||||
{
|
||||
struct xil_i2c_desc *xdesc;
|
||||
int32_t ret;
|
||||
|
||||
xdesc = desc->extra;
|
||||
|
||||
switch (xdesc->type) {
|
||||
case IIC_PL:
|
||||
#ifdef XIIC_H
|
||||
ret = xil_i2c_set_transmission_config(desc);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
|
||||
XIic_Send(((XIic*)xdesc->instance)->BaseAddress,
|
||||
desc->slave_address,
|
||||
data,
|
||||
bytes_number,
|
||||
stop_bit ? XIIC_STOP : XIIC_REPEATED_START);
|
||||
break;
|
||||
#endif
|
||||
goto error;
|
||||
case IIC_PS:
|
||||
#ifdef XIICPS_H
|
||||
ret = xil_i2c_set_transmission_config(desc);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
|
||||
ret = XIicPs_SetOptions(xdesc->instance,
|
||||
stop_bit ? 0 : XIICPS_REP_START_OPTION);
|
||||
if(ret != 0)
|
||||
goto error;
|
||||
|
||||
XIicPs_MasterSend(xdesc->instance,
|
||||
data,
|
||||
bytes_number,
|
||||
desc->slave_address);
|
||||
if(ret != 0)
|
||||
goto error;
|
||||
|
||||
break;
|
||||
#endif
|
||||
/* Intended fallthrough */
|
||||
error:
|
||||
default:
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read data from a slave device.
|
||||
* @param desc - The I2C descriptor.
|
||||
* @param data - Buffer that will store the received data.
|
||||
* @param bytes_number - Number of bytes to read.
|
||||
* @param stop_bit - Stop condition control.
|
||||
* Example: 0 - A stop condition will not be generated;
|
||||
* 1 - A stop condition will be generated.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_i2c_read(struct i2c_desc *desc,
|
||||
uint8_t *data,
|
||||
uint8_t bytes_number,
|
||||
uint8_t stop_bit)
|
||||
{
|
||||
struct xil_i2c_desc *xdesc;
|
||||
int32_t ret;
|
||||
|
||||
xdesc = desc->extra;
|
||||
|
||||
switch (xdesc->type) {
|
||||
case IIC_PL:
|
||||
#ifdef XIIC_H
|
||||
ret = xil_i2c_set_transmission_config(desc);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
|
||||
ret = XIic_Recv(((XIic*)xdesc->instance)->BaseAddress,
|
||||
desc->slave_address,
|
||||
data,
|
||||
bytes_number,
|
||||
stop_bit ? XIIC_STOP : XIIC_REPEATED_START);
|
||||
if(ret != bytes_number)
|
||||
goto error;
|
||||
|
||||
break;
|
||||
#endif
|
||||
goto error;
|
||||
case IIC_PS:
|
||||
#ifdef XIICPS_H
|
||||
ret = xil_i2c_set_transmission_config(desc);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
|
||||
ret = XIicPs_SetOptions(xdesc->instance,
|
||||
stop_bit ? 0 : XIICPS_REP_START_OPTION);
|
||||
if(ret != 0)
|
||||
goto error;
|
||||
|
||||
XIicPs_MasterRecv(xdesc->instance,
|
||||
data,
|
||||
bytes_number,
|
||||
desc->slave_address);
|
||||
if(ret != 0)
|
||||
goto error;
|
||||
|
||||
break;
|
||||
#endif
|
||||
/* Intended fallthrough */
|
||||
error:
|
||||
default:
|
||||
return -1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*******************************************************************************
|
||||
* @file xilinx/xilinx_i2c.h
|
||||
* @brief Header containing types used in the i2c driver.
|
||||
* @author scuciurean ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef XILINX_I2C_H_
|
||||
#define XILINX_I2C_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @enum xil_i2c_type
|
||||
* @brief Xilinx platform architecture sections
|
||||
*/
|
||||
enum xil_i2c_type {
|
||||
/** Programmable Logic */
|
||||
IIC_PL,
|
||||
/** Processing System */
|
||||
IIC_PS
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_i2c_init
|
||||
* @brief Structure holding the initialization parameters for Xilinx platform
|
||||
* specific I2C parameters.
|
||||
*/
|
||||
struct xil_i2c_init_param {
|
||||
/** Xilinx architecture */
|
||||
enum xil_i2c_type type;
|
||||
/** Device ID */
|
||||
uint32_t device_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_i2c_desc
|
||||
* @brief Xilinx platform specific I2C descriptor
|
||||
*/
|
||||
struct xil_i2c_desc {
|
||||
/** Xilinx architecture */
|
||||
enum xil_i2c_type type;
|
||||
/** Device ID */
|
||||
uint32_t device_id;
|
||||
/** Xilinx I2C configuration */
|
||||
void *config;
|
||||
/** Xilinx I2C Instance */
|
||||
void *instance;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Xilinx platform specific i2c platform ops structure
|
||||
*/
|
||||
extern const struct i2c_platform_ops xil_i2c_ops;
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* Initialize the I2C communication peripheral. */
|
||||
int32_t xil_i2c_init(struct i2c_desc **desc,
|
||||
const struct i2c_init_param *param);
|
||||
|
||||
/* Free the resources allocated by i2c_init(). */
|
||||
int32_t xil_i2c_remove(struct i2c_desc *desc);
|
||||
|
||||
/* I2C Write data */
|
||||
int32_t xil_i2c_write(struct i2c_desc *desc, uint8_t *data,
|
||||
uint8_t bytes_number, uint8_t stop_bit);
|
||||
|
||||
/* I2C Read data. */
|
||||
int32_t xil_i2c_read(struct i2c_desc *desc, uint8_t *data,
|
||||
uint8_t bytes_number, uint8_t stop_bit);
|
||||
|
||||
#endif // XILINX_I2C_H_
|
||||
@@ -0,0 +1,462 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/xilinx_spi.c
|
||||
* @brief Implementation of Xilinx SPI Generic Driver.
|
||||
* @author Antoniu Miclaus ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <xparameters.h>
|
||||
#ifdef XPAR_XSPI_NUM_INSTANCES
|
||||
#include <xspi.h>
|
||||
#endif
|
||||
#ifdef XPAR_XSPIPS_NUM_INSTANCES
|
||||
#include <xspips.h>
|
||||
#endif
|
||||
|
||||
#include "error.h"
|
||||
#include "spi.h"
|
||||
#include "xilinx_spi.h"
|
||||
|
||||
#if defined(PLATFORM_ZYNQ)
|
||||
#define SPI_CLK_FREQ_HZ(dev) (XPAR_PS7_SPI_ ## dev ## _SPI_CLK_FREQ_HZ)
|
||||
#define SPI_NUM_INSTANCES XPAR_XSPIPS_NUM_INSTANCES
|
||||
#elif defined(PLATFORM_ZYNQMP)
|
||||
#define SPI_CLK_FREQ_HZ(dev) (XPAR_PSU_SPI_ ## dev ## _SPI_CLK_FREQ_HZ)
|
||||
#define SPI_NUM_INSTANCES XPAR_XSPIPS_NUM_INSTANCES
|
||||
#else
|
||||
#define SPI_NUM_INSTANCES 0
|
||||
#endif
|
||||
|
||||
#warning SPI delays are not supported on the xilinx platform
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Initialize the hardware SPI peripherial
|
||||
*
|
||||
* @param xdesc Platform specific SPI descriptor
|
||||
* @param xinit Platform specific SPI init param
|
||||
* @return int32_t -1 if the device couldn't be found or configured
|
||||
*/
|
||||
static int32_t spi_init_pl(struct spi_desc *desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
#ifdef XSPI_H
|
||||
int32_t ret;
|
||||
struct xil_spi_desc *xdesc;
|
||||
struct xil_spi_init_param *xinit;
|
||||
|
||||
xdesc = (struct xil_spi_desc*)malloc(sizeof(struct xil_spi_desc));
|
||||
if(!xdesc) {
|
||||
free(xdesc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
desc->extra = xdesc;
|
||||
xinit = param->extra;
|
||||
xdesc->type = xinit->type;
|
||||
xdesc->flags = xinit->flags;
|
||||
|
||||
xdesc->instance = (XSpi*)calloc(1, sizeof(XSpi));
|
||||
if(!xdesc->instance)
|
||||
goto pl_error;
|
||||
|
||||
xdesc->config = XSpi_LookupConfig(param->device_id);
|
||||
if(xdesc->config == NULL)
|
||||
goto pl_error;
|
||||
|
||||
ret = XSpi_CfgInitialize(xdesc->instance,
|
||||
xdesc->config,
|
||||
((XSpi_Config*)xdesc->config)
|
||||
->BaseAddress);
|
||||
if(ret != 0)
|
||||
goto pl_error;
|
||||
|
||||
ret = XSpi_Initialize(xdesc->instance, param->device_id);
|
||||
if (ret != 0)
|
||||
goto pl_error;
|
||||
|
||||
ret = XSpi_SetOptions(xdesc->instance,
|
||||
XSP_MASTER_OPTION |
|
||||
((desc->mode & SPI_CPOL) ?
|
||||
XSP_CLK_ACTIVE_LOW_OPTION : 0) |
|
||||
((desc->mode & SPI_CPHA) ?
|
||||
XSP_CLK_PHASE_1_OPTION : 0));
|
||||
if (ret != 0)
|
||||
goto pl_error;
|
||||
|
||||
ret = XSpi_Start(xdesc->instance);
|
||||
if (ret != 0)
|
||||
goto pl_error;
|
||||
|
||||
XSpi_IntrGlobalDisable((XSpi *)(xdesc->instance));
|
||||
|
||||
return 0;
|
||||
|
||||
pl_error:
|
||||
free(xdesc->instance);
|
||||
free(xdesc);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the hardware SPI peripherial
|
||||
*
|
||||
* @param xdesc Platform specific SPI descriptor
|
||||
* @param xinit Platform specific SPI init param
|
||||
* @return int32_t -1 if the device couldn't be found or configured
|
||||
*/
|
||||
static int32_t spi_init_ps(struct spi_desc *desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
#ifdef XSPIPS_H
|
||||
int32_t ret;
|
||||
struct xil_spi_desc *xdesc;
|
||||
struct xil_spi_init_param *xinit;
|
||||
const uint32_t prescaler_default = XSPIPS_CLK_PRESCALE_64;
|
||||
const uint32_t prescaler_min = XSPIPS_CLK_PRESCALE_4;
|
||||
const uint32_t prescaler_max = XSPIPS_CLK_PRESCALE_256;
|
||||
uint32_t prescaler = 0u;
|
||||
uint32_t input_clock = 0u;
|
||||
|
||||
xdesc = (struct xil_spi_desc*)malloc(sizeof(struct xil_spi_desc));
|
||||
if(!xdesc) {
|
||||
free(xdesc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
desc->extra = xdesc;
|
||||
xinit = param->extra;
|
||||
xdesc->type = xinit->type;
|
||||
xdesc->flags = xinit->flags;
|
||||
|
||||
xdesc->instance = (XSpiPs*)malloc(sizeof(XSpiPs));
|
||||
if(!xdesc->instance)
|
||||
goto ps_error;
|
||||
|
||||
xdesc->config = XSpiPs_LookupConfig(param->device_id);
|
||||
if(xdesc->config == NULL)
|
||||
goto ps_error;
|
||||
|
||||
ret = XSpiPs_CfgInitialize(xdesc->instance,
|
||||
xdesc->config,
|
||||
((XSpiPs_Config*)xdesc->config)
|
||||
->BaseAddress);
|
||||
if(ret != 0)
|
||||
goto ps_error;
|
||||
|
||||
switch (param->device_id) {
|
||||
#if (SPI_NUM_INSTANCES >= 1)
|
||||
case 0:
|
||||
input_clock = SPI_CLK_FREQ_HZ(0);
|
||||
break;
|
||||
#endif
|
||||
#if (SPI_NUM_INSTANCES >= 2)
|
||||
case 1:
|
||||
input_clock = SPI_CLK_FREQ_HZ(1);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
goto ps_error;
|
||||
};
|
||||
|
||||
if (desc->max_speed_hz != 0u) {
|
||||
uint32_t div = input_clock / desc->max_speed_hz;
|
||||
uint32_t rem = input_clock % desc->max_speed_hz;
|
||||
uint32_t po2 = !(div & (div - 1)) && !rem;
|
||||
|
||||
// find the power of two just higher than div and
|
||||
// store the exponent in prescaler
|
||||
while(div) {
|
||||
prescaler += 1;
|
||||
div >>= 1u;
|
||||
}
|
||||
|
||||
// this exponent - 1 is needed because of the way
|
||||
// xilinx stores it into registers
|
||||
if (prescaler)
|
||||
prescaler -= 1;
|
||||
|
||||
// this exponent - 1 is needed when initial div was
|
||||
// precisely a power of two
|
||||
if (prescaler && po2)
|
||||
prescaler -= 1;
|
||||
|
||||
if (prescaler < prescaler_min)
|
||||
prescaler = prescaler_min;
|
||||
|
||||
if (prescaler > prescaler_max)
|
||||
prescaler = prescaler_max;
|
||||
} else
|
||||
prescaler = prescaler_default;
|
||||
|
||||
ret = XSpiPs_SetClkPrescaler(xdesc->instance, prescaler);
|
||||
|
||||
if(ret != 0)
|
||||
goto ps_error;
|
||||
|
||||
return 0;
|
||||
|
||||
ps_error:
|
||||
free(xdesc->instance);
|
||||
free(xdesc);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the SPI communication peripheral.
|
||||
* @param desc - The SPI descriptor.
|
||||
* @param param - The structure that contains the SPI parameters.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_spi_init(struct spi_desc **desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
int32_t ret;
|
||||
enum xil_spi_type *spi_type;
|
||||
|
||||
if (!param) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*desc = malloc(sizeof(**desc));
|
||||
if(! *desc) {
|
||||
free(*desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
spi_type = param->extra;
|
||||
|
||||
if(!spi_type)
|
||||
goto init_error;
|
||||
|
||||
(*desc)->max_speed_hz = param->max_speed_hz;
|
||||
(*desc)->mode = param->mode;
|
||||
(*desc)->bit_order = param->bit_order;
|
||||
(*desc)->chip_select = param->chip_select;
|
||||
|
||||
switch (*spi_type) {
|
||||
case SPI_PL:
|
||||
ret = spi_init_pl(*desc, param);
|
||||
break;
|
||||
case SPI_PS:
|
||||
ret = spi_init_ps(*desc, param);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto init_error;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
init_error:
|
||||
free(*desc);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by spi_init().
|
||||
* @param desc - The SPI descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_spi_remove(struct spi_desc *desc)
|
||||
{
|
||||
#ifdef XSPI_H
|
||||
int32_t ret;
|
||||
#endif
|
||||
struct xil_spi_desc *xdesc = NULL;
|
||||
enum xil_spi_type *spi_type;
|
||||
|
||||
spi_type = desc->extra;
|
||||
|
||||
if(!spi_type)
|
||||
return -1;
|
||||
|
||||
switch (*spi_type ) {
|
||||
case SPI_PL:
|
||||
#ifdef XSPI_H
|
||||
xdesc = desc->extra;
|
||||
|
||||
if(!xdesc)
|
||||
return -1;
|
||||
|
||||
ret = XSpi_Stop((XSpi *)(xdesc->instance));
|
||||
if(ret != 0)
|
||||
goto error;
|
||||
#endif
|
||||
break;
|
||||
case SPI_PS:
|
||||
#ifdef XSPIPS_H
|
||||
xdesc = desc->extra;
|
||||
|
||||
if(!xdesc)
|
||||
return -1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
/* Intended fallthrough */
|
||||
#ifdef XSPI_H
|
||||
error:
|
||||
#endif
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(xdesc)
|
||||
free(xdesc->instance);
|
||||
free(desc->extra);
|
||||
free(desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write and read data to/from SPI.
|
||||
* @param desc - The SPI descriptor.
|
||||
* @param data - The buffer with the transmitted/received data.
|
||||
* @param bytes_number - Number of bytes to write/read.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_spi_write_and_read(struct spi_desc *desc,
|
||||
uint8_t *data,
|
||||
uint16_t bytes_number)
|
||||
{
|
||||
int32_t ret;
|
||||
#ifdef XSPI_H
|
||||
uint32_t ctrl_reg;
|
||||
#endif
|
||||
struct xil_spi_desc *xdesc;
|
||||
enum xil_spi_type *spi_type;
|
||||
|
||||
ret = -1;
|
||||
|
||||
spi_type = desc->extra;
|
||||
|
||||
if(!spi_type)
|
||||
return -1;
|
||||
|
||||
xdesc = desc->extra;
|
||||
|
||||
switch (*spi_type) {
|
||||
case SPI_PL:
|
||||
#ifdef XSPI_H
|
||||
ret = XSpi_SetOptions(xdesc->instance,
|
||||
XSP_MASTER_OPTION |
|
||||
((desc->mode & SPI_CPOL) ?
|
||||
XSP_CLK_ACTIVE_LOW_OPTION : 0) |
|
||||
((desc->mode & SPI_CPHA) ?
|
||||
XSP_CLK_PHASE_1_OPTION : 0));
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
|
||||
ctrl_reg = XSpi_GetControlReg(((XSpi*)xdesc->instance));
|
||||
if (desc->bit_order == SPI_BIT_ORDER_LSB_FIRST)
|
||||
ctrl_reg |= XSP_CR_LSB_MSB_FIRST_MASK;
|
||||
else
|
||||
ctrl_reg &= ~ XSP_CR_LSB_MSB_FIRST_MASK;
|
||||
XSpi_SetControlReg(((XSpi*)xdesc->instance), ctrl_reg);
|
||||
|
||||
ret = XSpi_SetSlaveSelect(xdesc->instance,
|
||||
0x01 << desc->chip_select);
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
|
||||
ret = XSpi_Transfer(xdesc->instance,
|
||||
data,
|
||||
data,
|
||||
bytes_number);
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
#endif
|
||||
break;
|
||||
case SPI_PS:
|
||||
#ifdef XSPIPS_H
|
||||
ret = XSpiPs_SetOptions(xdesc->instance,
|
||||
XSPIPS_MASTER_OPTION |
|
||||
((xdesc->flags & SPI_CS_DECODE) ?
|
||||
XSPIPS_DECODE_SSELECT_OPTION : 0) |
|
||||
XSPIPS_FORCE_SSELECT_OPTION |
|
||||
((desc->mode & SPI_CPOL) ?
|
||||
XSPIPS_CLK_ACTIVE_LOW_OPTION : 0) |
|
||||
((desc->mode & SPI_CPHA) ?
|
||||
XSPIPS_CLK_PHASE_1_OPTION : 0));
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
|
||||
ret = XSpiPs_SetSlaveSelect(xdesc->instance,
|
||||
desc->chip_select);
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
ret = XSpiPs_PolledTransfer(xdesc->instance,
|
||||
data,
|
||||
data,
|
||||
bytes_number);
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
ret = XSpiPs_SetSlaveSelect(xdesc->instance, SPI_DEASSERT_CURRENT_SS);
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
#endif
|
||||
break;
|
||||
error:
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Xilinx platform specific SPI platform ops structure
|
||||
*/
|
||||
const struct spi_platform_ops xil_spi_ops = {
|
||||
.init = &xil_spi_init,
|
||||
.write_and_read = &xil_spi_write_and_read,
|
||||
.remove = &xil_spi_remove
|
||||
};
|
||||
@@ -0,0 +1,115 @@
|
||||
/*******************************************************************************
|
||||
* @file xilinx/xilinx_spi.h
|
||||
* @brief Header containing extra types used in the spi driver.
|
||||
* @author scuciurean ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef XILINX_SPI_H_
|
||||
#define XILINX_SPI_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "spi.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define SPI_CS_DECODE 0x01
|
||||
#define SPI_DEASSERT_CURRENT_SS 0x0F
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @enum xil_spi_type
|
||||
* @brief Xilinx platform architecture sections
|
||||
*/
|
||||
enum xil_spi_type {
|
||||
/** Programmable Logic */
|
||||
SPI_PL,
|
||||
/** Processing System */
|
||||
SPI_PS,
|
||||
/** SPI Engine */
|
||||
SPI_ENGINE
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_spi_init_param
|
||||
* @brief Structure holding the initialization parameters for Xilinx platform
|
||||
* specific SPI parameters when using xil_spi_ops.
|
||||
*/
|
||||
struct xil_spi_init_param {
|
||||
/** Xilinx architecture */
|
||||
enum xil_spi_type type;
|
||||
/** SPI flags */
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_spi_desc
|
||||
* @brief Xilinx platform specific SPI descriptor
|
||||
*/
|
||||
struct xil_spi_desc {
|
||||
/** Xilinx architecture */
|
||||
enum xil_spi_type type;
|
||||
/** SPI flags */
|
||||
uint32_t flags;
|
||||
/** SPI configuration */
|
||||
void *config;
|
||||
/** SPI instance */
|
||||
void *instance;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief SPI engine platform ops structure
|
||||
*/
|
||||
extern const struct spi_platform_ops spi_eng_platform_ops;
|
||||
|
||||
/**
|
||||
* @brief Xilinx specific SPI platform ops structure
|
||||
*/
|
||||
extern const struct spi_platform_ops xil_spi_ops;
|
||||
|
||||
/**
|
||||
* @brief Xilinx SPI PS register functions. No extra param needed
|
||||
*/
|
||||
extern const struct spi_platform_ops xil_spi_pl_ops;
|
||||
|
||||
#endif // XILINX_SPI_H_
|
||||
@@ -0,0 +1,533 @@
|
||||
/*******************************************************************************
|
||||
* @file xilinx/xilinx_spi_pl.c
|
||||
* @brief Driver for spi pl device using registers
|
||||
* @author Mihail Chindris ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2021(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#include <xparameters.h>
|
||||
|
||||
#ifdef XPAR_XSPI_NUM_INSTANCES
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <xspi.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "spi.h"
|
||||
#include "error.h"
|
||||
#include "delay.h"
|
||||
#include "util.h"
|
||||
#include "alloc.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define XPS_TYPE_WRITE 0x1
|
||||
#define XPS_TYPE_READ 0x2
|
||||
#define XSP_DEFAULT_SR_VALUE 0x25
|
||||
#define XSP_DUMMY_DATA 0xFF
|
||||
|
||||
/*
|
||||
* Used to store current spi device configuration in order to not update it for
|
||||
* each spi transaction if not needed.
|
||||
*/
|
||||
static struct spi_desc g_spi_desc[XPAR_XSPI_NUM_INSTANCES];
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* Xilinx PL spi specific data */
|
||||
struct xspi_desc {
|
||||
uint32_t base_addr;
|
||||
uint32_t disable_slaves_mask;
|
||||
uint32_t fifo_depth;
|
||||
uint8_t cs_asserted;
|
||||
};
|
||||
|
||||
/* Structure used to iterate over SPI messages */
|
||||
struct msg_iter {
|
||||
struct spi_msg *msgs;
|
||||
uint32_t len;
|
||||
uint32_t i;
|
||||
uint32_t buff_i;
|
||||
uint8_t is_wr;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* Read device register */
|
||||
static inline uint32_t _read(struct xspi_desc *xdesc, uint32_t reg)
|
||||
{
|
||||
return Xil_In32(xdesc->base_addr + reg);
|
||||
}
|
||||
|
||||
/* Write device register */
|
||||
static inline void _write(struct xspi_desc *xdesc, uint32_t reg, uint32_t val)
|
||||
{
|
||||
Xil_Out32(xdesc->base_addr + reg, val);
|
||||
}
|
||||
|
||||
/* Update device register. Only bits set to 1 in mask will be modified */
|
||||
static inline void _wr_mask(struct xspi_desc *xdesc, uint32_t reg,
|
||||
uint32_t val, uint32_t mask)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = _read(xdesc, reg);
|
||||
tmp &= ~mask;
|
||||
tmp |= val & mask;
|
||||
_write(xdesc, reg, tmp);
|
||||
}
|
||||
|
||||
/* Update spi device configuration if needed */
|
||||
static void _update_mode(struct spi_desc *desc)
|
||||
{
|
||||
uint32_t val;
|
||||
uint32_t mask;
|
||||
|
||||
if (desc->mode == g_spi_desc[desc->device_id].mode &&
|
||||
desc->bit_order == g_spi_desc[desc->device_id].bit_order)
|
||||
return ;
|
||||
|
||||
/* Update mode */
|
||||
val = desc->mode | SPI_CPOL ? XSP_CR_CLK_POLARITY_MASK : 0;
|
||||
val |= desc->mode | SPI_CPHA ? XSP_CR_CLK_PHASE_MASK : 0;
|
||||
mask = XSP_CR_CLK_POLARITY_MASK | XSP_CR_CLK_PHASE_MASK;
|
||||
|
||||
val |= desc->bit_order == SPI_BIT_ORDER_LSB_FIRST ?
|
||||
XSP_CR_LSB_MSB_FIRST_MASK : 0;
|
||||
mask |= XSP_CR_LSB_MSB_FIRST_MASK;
|
||||
|
||||
_wr_mask(desc->extra, XSP_CR_OFFSET, val, mask);
|
||||
g_spi_desc[desc->device_id] = *desc;
|
||||
}
|
||||
|
||||
/* Configure SPI PL device */
|
||||
static int32_t _xil_spi_init_dev(struct xspi_desc *xdesc)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
/* Software reset */
|
||||
_write(xdesc, XSP_SRR_OFFSET, XSP_SRR_RESET_MASK);
|
||||
mdelay(1);
|
||||
|
||||
/* Check if success reset */
|
||||
val = _read(xdesc, XSP_SR_OFFSET);
|
||||
if (val != XSP_DEFAULT_SR_VALUE)
|
||||
return -ENODEV;
|
||||
|
||||
/* Disable interrupts. Drivers only works with pooled mode */
|
||||
_write(xdesc, XSP_IIER_OFFSET, 0);
|
||||
|
||||
/* Deasert chip selects */
|
||||
_write(xdesc, XSP_SSR_OFFSET, 0xFFFFFFFF);
|
||||
|
||||
/* Get fifo depth */
|
||||
while (!(_read(xdesc, XSP_SR_OFFSET) & XSP_SR_TX_FULL_MASK))
|
||||
_write(xdesc, XSP_DTR_OFFSET, XSP_DUMMY_DATA);
|
||||
xdesc->fifo_depth = _read(xdesc, XSP_TFO_OFFSET) + 1;
|
||||
|
||||
/* Configure spi device */
|
||||
val = XSP_CR_ENABLE_MASK |
|
||||
XSP_CR_MANUAL_SS_MASK |
|
||||
XSP_CR_TXFIFO_RESET_MASK |
|
||||
XSP_CR_RXFIFO_RESET_MASK |
|
||||
XSP_CR_MASTER_MODE_MASK |
|
||||
XSP_CR_TRANS_INHIBIT_MASK;
|
||||
|
||||
_write(xdesc, XSP_CR_OFFSET, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize spi_desc structure and device */
|
||||
static int32_t xil_spi_init_pl(struct spi_desc **desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
struct spi_desc *ldesc;
|
||||
struct xspi_desc *xdesc;
|
||||
int32_t err;
|
||||
XSpi_Config *cfg;
|
||||
|
||||
if (!desc || !param || param->device_id >= XPAR_XSPI_NUM_INSTANCES)
|
||||
return -EINVAL;
|
||||
|
||||
cfg = XSpi_LookupConfig(param->device_id);
|
||||
if (!cfg)
|
||||
return -EINVAL;
|
||||
|
||||
if (param->chip_select > cfg->NumSlaveBits)
|
||||
return -EINVAL;
|
||||
|
||||
ldesc = (struct spi_desc *)calloc(1, sizeof(*ldesc));
|
||||
if (!ldesc)
|
||||
return -ENOMEM;
|
||||
|
||||
xdesc = (struct xspi_desc *)calloc(1, sizeof(*xdesc));
|
||||
if (!xdesc) {
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
ldesc->bit_order = param->bit_order;
|
||||
ldesc->chip_select = param->chip_select;
|
||||
ldesc->mode = param->mode;
|
||||
xdesc->base_addr = cfg->BaseAddress;
|
||||
xdesc->disable_slaves_mask = (1 << cfg->NumSlaveBits) - 1;
|
||||
xdesc->cs_asserted = 0;
|
||||
|
||||
err = _xil_spi_init_dev(xdesc);
|
||||
if (IS_ERR_VALUE(err))
|
||||
goto error;
|
||||
|
||||
ldesc->extra = xdesc;
|
||||
*desc = ldesc;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free(xdesc);
|
||||
free(ldesc);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Remove allocated resources */
|
||||
static int32_t xil_spi_remove_pl(struct spi_desc *desc)
|
||||
{
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
free(desc->extra);
|
||||
free(desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill fifo until fifo is full or no more data available.
|
||||
* Return the number of written bytes.
|
||||
*/
|
||||
static uint32_t _wr_fifo(struct xspi_desc *xdesc, uint8_t *data,
|
||||
uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t to_write;
|
||||
uint32_t tx_available;
|
||||
|
||||
tx_available = xdesc->fifo_depth - _read(xdesc, XSP_TFO_OFFSET);
|
||||
to_write = min(tx_available, len);
|
||||
for (i = 0; i < to_write; ++i)
|
||||
if (data)
|
||||
_write(xdesc, XSP_DTR_OFFSET, data[i]);
|
||||
else
|
||||
_write(xdesc, XSP_DTR_OFFSET, XSP_DUMMY_DATA);
|
||||
|
||||
return to_write;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read fifo until fifo is empty or no more buffer available to read into
|
||||
* Returns the number of read bytes
|
||||
*/
|
||||
static uint32_t _rd_fifo(struct xspi_desc *xdesc, uint8_t *data,
|
||||
uint32_t len)
|
||||
{
|
||||
uint32_t rx_available;
|
||||
uint32_t to_read;
|
||||
uint32_t tmp;
|
||||
uint32_t i;
|
||||
|
||||
tmp = _read(xdesc, XSP_SR_OFFSET);
|
||||
if (tmp & XSP_SR_RX_EMPTY_MASK)
|
||||
return 0;
|
||||
|
||||
rx_available = _read(xdesc, XSP_RFO_OFFSET) + 1;
|
||||
to_read = min(rx_available, len);
|
||||
for (i = 0; i < to_read; ++i) {
|
||||
tmp = _read(xdesc, XSP_DRR_OFFSET);
|
||||
if (data)
|
||||
data[i] = tmp;
|
||||
}
|
||||
|
||||
return to_read;
|
||||
}
|
||||
|
||||
/* If start is 0 stop transfer, else start it.
|
||||
* CS will be asserted if needed. If different CS othere than the one needed
|
||||
* is asserted. Deassert it and assert correct one */
|
||||
static void _xil_spi_start_transfer(struct spi_desc *desc, uint8_t start)
|
||||
{
|
||||
struct xspi_desc *xdesc;
|
||||
|
||||
xdesc = desc->extra;
|
||||
if (start) {
|
||||
if (xdesc->cs_asserted) {
|
||||
if (desc->chip_select ==
|
||||
g_spi_desc[desc->device_id].chip_select)
|
||||
return ;
|
||||
else
|
||||
/* Stop transfer to start again with new CS */
|
||||
_xil_spi_start_transfer(desc, 0);
|
||||
}
|
||||
_write(xdesc, XSP_SSR_OFFSET, ~(1 << desc->chip_select));
|
||||
_wr_mask(xdesc, XSP_CR_OFFSET, 0, XSP_CR_TRANS_INHIBIT_MASK);
|
||||
} else {
|
||||
_wr_mask(xdesc, XSP_CR_OFFSET, XSP_CR_TRANS_INHIBIT_MASK,
|
||||
XSP_CR_TRANS_INHIBIT_MASK);
|
||||
_write(xdesc, XSP_SSR_OFFSET, xdesc->disable_slaves_mask);
|
||||
}
|
||||
xdesc->cs_asserted = start;
|
||||
}
|
||||
|
||||
|
||||
/* SPI polled transfer */
|
||||
static int32_t xil_spi_write_and_read_pl(struct spi_desc *desc,
|
||||
uint8_t *data,
|
||||
uint16_t bytes_number)
|
||||
{
|
||||
struct xspi_desc *xdesc;
|
||||
uint32_t rx;
|
||||
uint32_t tx;
|
||||
|
||||
if (!desc || !desc->extra)
|
||||
return -EINVAL;
|
||||
|
||||
xdesc = desc->extra;
|
||||
_update_mode(desc);
|
||||
|
||||
_xil_spi_start_transfer(desc, 1);
|
||||
rx = 0;
|
||||
tx = 0;
|
||||
while (rx < bytes_number) {
|
||||
if (tx < bytes_number)
|
||||
tx += _wr_fifo(xdesc, data + tx, bytes_number - tx);
|
||||
rx += _rd_fifo(xdesc, data + rx, bytes_number - rx);
|
||||
}
|
||||
_xil_spi_start_transfer(desc, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get type of message. It can be READ, WRITE or both */
|
||||
static uint32_t _get_msg_type(struct spi_msg *msg)
|
||||
{
|
||||
uint32_t type;
|
||||
|
||||
type = 0;
|
||||
if (msg->tx_buff)
|
||||
type |= XPS_TYPE_WRITE;
|
||||
if (msg->rx_buff)
|
||||
type |= XPS_TYPE_READ;
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/* Get information based on current iterator position */
|
||||
static void _get_data(struct msg_iter *it, uint8_t **buff, uint32_t *len,
|
||||
uint32_t *type)
|
||||
{
|
||||
struct spi_msg *msg;
|
||||
|
||||
if (it->i == it->len) {
|
||||
*len = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
msg = it->msgs + it->i;
|
||||
if (it->is_wr)
|
||||
*buff = msg->tx_buff;
|
||||
else
|
||||
*buff = msg->rx_buff;
|
||||
|
||||
if (*buff)
|
||||
*buff += it->buff_i;
|
||||
|
||||
*len = msg->bytes_number - it->buff_i;
|
||||
if (type)
|
||||
*type = _get_msg_type(msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Increment iterator position with desired length.
|
||||
* If the new position has a different message type, new_type will be set to 1
|
||||
* If a CS change is needed, cs_change is set
|
||||
*/
|
||||
static void _increment_iter(struct msg_iter *it, uint32_t len,
|
||||
uint8_t *cs_change, uint8_t *new_type)
|
||||
{
|
||||
struct spi_msg *msg;
|
||||
uint32_t type;
|
||||
uint32_t extra_len;
|
||||
|
||||
if (!len)
|
||||
return ;
|
||||
|
||||
*cs_change = 0;
|
||||
*new_type = 0;
|
||||
msg = it->msgs + it->i;
|
||||
if (it->buff_i + len > msg->bytes_number)
|
||||
extra_len = it->buff_i + len - msg->bytes_number;
|
||||
else
|
||||
extra_len = 0;
|
||||
len -= extra_len;
|
||||
it->buff_i += len;
|
||||
if (it->buff_i == msg->bytes_number) {
|
||||
type = _get_msg_type(msg);
|
||||
++it->i;
|
||||
it->buff_i = 0;
|
||||
if (cs_change && msg->cs_change)
|
||||
*cs_change = 1;
|
||||
if (new_type)
|
||||
if (it->i == it->len ||
|
||||
type != _get_msg_type(it->msgs + it->i))
|
||||
*new_type = 1;
|
||||
}
|
||||
if (extra_len)
|
||||
_increment_iter(it, extra_len, cs_change, new_type);
|
||||
}
|
||||
|
||||
/*
|
||||
* SPI polling transfer of multiple messages.
|
||||
*/
|
||||
static int32_t xil_spi_transfer_pl(struct spi_desc *desc,
|
||||
struct spi_msg *msgs,
|
||||
uint32_t len)
|
||||
|
||||
{
|
||||
struct xspi_desc *xdesc;
|
||||
uint8_t cs_change;
|
||||
uint8_t new_type;
|
||||
struct msg_iter rx = {.msgs = msgs, .len = len, .is_wr = 0};
|
||||
struct msg_iter tx = {.msgs = msgs, .len = len, .is_wr = 1};
|
||||
uint8_t *buff;
|
||||
uint32_t bytes;
|
||||
uint32_t type;
|
||||
/* Bytes to increment rx when only a write transaction is executed */
|
||||
uint32_t to_inc_rx;
|
||||
/* Difference between rx and tx iterators in bytes */
|
||||
uint32_t tx_advance;
|
||||
/* Save bytes sent during a write loop */
|
||||
uint32_t tx_sent;
|
||||
/* Used to loop if need to empty the RX FIFO */
|
||||
uint32_t loop;
|
||||
|
||||
if (!desc || !desc->extra)
|
||||
return -EINVAL;
|
||||
|
||||
xdesc = desc->extra;
|
||||
_update_mode(desc);
|
||||
|
||||
tx_advance = 0;
|
||||
to_inc_rx = 0;
|
||||
buff = NULL;
|
||||
type = 0;
|
||||
do {
|
||||
_xil_spi_start_transfer(desc, 1);
|
||||
|
||||
tx_sent = 0;
|
||||
/* Writing loop */
|
||||
do {
|
||||
_get_data(&tx, &buff, &bytes, &type);
|
||||
if (type & XPS_TYPE_READ)
|
||||
/*
|
||||
* Do not write more bytes than fifo_depth if
|
||||
* they haven't been read.
|
||||
*/
|
||||
bytes = min(bytes,
|
||||
xdesc->fifo_depth - tx_advance);
|
||||
bytes = _wr_fifo(xdesc, buff, bytes);
|
||||
tx_sent += bytes;
|
||||
_increment_iter(&tx, bytes, &cs_change, &new_type);
|
||||
tx_advance += bytes;
|
||||
} while (!cs_change && !new_type && bytes);
|
||||
|
||||
if (type & XPS_TYPE_READ) {
|
||||
loop = 1;
|
||||
/*
|
||||
* Loop only when no more data to write otherwise read
|
||||
* only available data.
|
||||
*/
|
||||
while (loop) {
|
||||
if (!new_type)
|
||||
loop = 0;
|
||||
_get_data(&rx, &buff, &bytes, NULL);
|
||||
bytes = _rd_fifo(xdesc, buff, bytes);
|
||||
_increment_iter(&rx, bytes, &cs_change, &new_type);
|
||||
tx_advance -= bytes;
|
||||
if (loop && new_type)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Clean RX FIFO if it was only a WRITE message */
|
||||
to_inc_rx += tx_sent;
|
||||
if (new_type) {
|
||||
/* Wait for TX to be sent */
|
||||
while (!(_read(xdesc, XSP_SR_OFFSET) &
|
||||
XSP_SR_TX_EMPTY_MASK))
|
||||
;
|
||||
/* Reset fifo. Only write was performed */
|
||||
_wr_mask(xdesc, XSP_CR_OFFSET,
|
||||
XSP_CR_RXFIFO_RESET_MASK,
|
||||
XSP_CR_RXFIFO_RESET_MASK);
|
||||
|
||||
_increment_iter(&rx, to_inc_rx, NULL, NULL);
|
||||
tx_advance -= to_inc_rx;
|
||||
to_inc_rx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((cs_change && rx.i != len) || (!cs_change && rx.i == len))
|
||||
_xil_spi_start_transfer(desc, 0);
|
||||
} while (rx.i < len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct spi_platform_ops xil_spi_pl_ops = {
|
||||
.init = xil_spi_init_pl,
|
||||
.remove = xil_spi_remove_pl,
|
||||
.write_and_read = xil_spi_write_and_read_pl,
|
||||
.transfer = xil_spi_transfer_pl
|
||||
};
|
||||
|
||||
#endif // XPAR_XSPI_NUM_INSTANCES
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,552 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9361_api.h
|
||||
* @brief Header file of AD9361 API Driver.
|
||||
* @author DBogdan (dragos.bogdan@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2013(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef AD9361_API_H_
|
||||
#define AD9361_API_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include "ad9361_util.h"
|
||||
#include "gpio.h"
|
||||
#include "spi.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
typedef struct {
|
||||
/* Device selection */
|
||||
enum dev_id dev_sel;
|
||||
/* Reference Clock */
|
||||
uint32_t reference_clk_rate;
|
||||
/* Base Configuration */
|
||||
uint8_t two_rx_two_tx_mode_enable; /* adi,2rx-2tx-mode-enable */
|
||||
uint8_t one_rx_one_tx_mode_use_rx_num; /* adi,1rx-1tx-mode-use-rx-num */
|
||||
uint8_t one_rx_one_tx_mode_use_tx_num; /* adi,1rx-1tx-mode-use-tx-num */
|
||||
uint8_t frequency_division_duplex_mode_enable; /* adi,frequency-division-duplex-mode-enable */
|
||||
uint8_t frequency_division_duplex_independent_mode_enable; /* adi,frequency-division-duplex-independent-mode-enable */
|
||||
uint8_t tdd_use_dual_synth_mode_enable; /* adi,tdd-use-dual-synth-mode-enable */
|
||||
uint8_t tdd_skip_vco_cal_enable; /* adi,tdd-skip-vco-cal-enable */
|
||||
uint32_t tx_fastlock_delay_ns; /* adi,tx-fastlock-delay-ns */
|
||||
uint32_t rx_fastlock_delay_ns; /* adi,rx-fastlock-delay-ns */
|
||||
uint8_t rx_fastlock_pincontrol_enable; /* adi,rx-fastlock-pincontrol-enable */
|
||||
uint8_t tx_fastlock_pincontrol_enable; /* adi,tx-fastlock-pincontrol-enable */
|
||||
uint8_t external_rx_lo_enable; /* adi,external-rx-lo-enable */
|
||||
uint8_t external_tx_lo_enable; /* adi,external-tx-lo-enable */
|
||||
uint8_t dc_offset_tracking_update_event_mask; /* adi,dc-offset-tracking-update-event-mask */
|
||||
uint8_t dc_offset_attenuation_high_range; /* adi,dc-offset-attenuation-high-range */
|
||||
uint8_t dc_offset_attenuation_low_range; /* adi,dc-offset-attenuation-low-range */
|
||||
uint8_t dc_offset_count_high_range; /* adi,dc-offset-count-high-range */
|
||||
uint8_t dc_offset_count_low_range; /* adi,dc-offset-count-low-range */
|
||||
uint8_t split_gain_table_mode_enable; /* adi,split-gain-table-mode-enable */
|
||||
uint32_t trx_synthesizer_target_fref_overwrite_hz; /* adi,trx-synthesizer-target-fref-overwrite-hz */
|
||||
uint8_t qec_tracking_slow_mode_enable; /* adi,qec-tracking-slow-mode-enable */
|
||||
/* ENSM Control */
|
||||
uint8_t ensm_enable_pin_pulse_mode_enable; /* adi,ensm-enable-pin-pulse-mode-enable */
|
||||
uint8_t ensm_enable_txnrx_control_enable; /* adi,ensm-enable-txnrx-control-enable */
|
||||
/* LO Control */
|
||||
uint64_t rx_synthesizer_frequency_hz; /* adi,rx-synthesizer-frequency-hz */
|
||||
uint64_t tx_synthesizer_frequency_hz; /* adi,tx-synthesizer-frequency-hz */
|
||||
uint8_t tx_lo_powerdown_managed_enable; /* adi,tx-lo-powerdown-managed-enable */
|
||||
/* Rate & BW Control */
|
||||
uint32_t rx_path_clock_frequencies[6]; /* adi,rx-path-clock-frequencies */
|
||||
uint32_t tx_path_clock_frequencies[6]; /* adi,tx-path-clock-frequencies */
|
||||
uint32_t rf_rx_bandwidth_hz; /* adi,rf-rx-bandwidth-hz */
|
||||
uint32_t rf_tx_bandwidth_hz; /* adi,rf-tx-bandwidth-hz */
|
||||
/* RF Port Control */
|
||||
uint32_t rx_rf_port_input_select; /* adi,rx-rf-port-input-select */
|
||||
uint32_t tx_rf_port_input_select; /* adi,tx-rf-port-input-select */
|
||||
/* TX Attenuation Control */
|
||||
int32_t tx_attenuation_mdB; /* adi,tx-attenuation-mdB */
|
||||
uint8_t update_tx_gain_in_alert_enable; /* adi,update-tx-gain-in-alert-enable */
|
||||
/* Reference Clock Control */
|
||||
uint8_t xo_disable_use_ext_refclk_enable; /* adi,xo-disable-use-ext-refclk-enable */
|
||||
uint32_t dcxo_coarse_and_fine_tune[2]; /* adi,dcxo-coarse-and-fine-tune */
|
||||
uint32_t clk_output_mode_select; /* adi,clk-output-mode-select */
|
||||
/* Gain Control */
|
||||
uint8_t gc_rx1_mode; /* adi,gc-rx1-mode */
|
||||
uint8_t gc_rx2_mode; /* adi,gc-rx2-mode */
|
||||
uint8_t gc_adc_large_overload_thresh; /* adi,gc-adc-large-overload-thresh */
|
||||
uint8_t gc_adc_ovr_sample_size; /* adi,gc-adc-ovr-sample-size */
|
||||
uint8_t gc_adc_small_overload_thresh; /* adi,gc-adc-small-overload-thresh */
|
||||
uint16_t gc_dec_pow_measurement_duration; /* adi,gc-dec-pow-measurement-duration */
|
||||
uint8_t gc_dig_gain_enable; /* adi,gc-dig-gain-enable */
|
||||
uint16_t gc_lmt_overload_high_thresh; /* adi,gc-lmt-overload-high-thresh */
|
||||
uint16_t gc_lmt_overload_low_thresh; /* adi,gc-lmt-overload-low-thresh */
|
||||
uint8_t gc_low_power_thresh; /* adi,gc-low-power-thresh */
|
||||
uint8_t gc_max_dig_gain; /* adi,gc-max-dig-gain */
|
||||
uint8_t gc_use_rx_fir_out_for_dec_pwr_meas_enable; /* adi,gc-use-rx-fir-out-for-dec-pwr-meas-enable */
|
||||
/* Gain MGC Control */
|
||||
uint8_t mgc_dec_gain_step; /* adi,mgc-dec-gain-step */
|
||||
uint8_t mgc_inc_gain_step; /* adi,mgc-inc-gain-step */
|
||||
uint8_t mgc_rx1_ctrl_inp_enable; /* adi,mgc-rx1-ctrl-inp-enable */
|
||||
uint8_t mgc_rx2_ctrl_inp_enable; /* adi,mgc-rx2-ctrl-inp-enable */
|
||||
uint8_t mgc_split_table_ctrl_inp_gain_mode; /* adi,mgc-split-table-ctrl-inp-gain-mode */
|
||||
/* Gain AGC Control */
|
||||
uint8_t agc_adc_large_overload_exceed_counter; /* adi,agc-adc-large-overload-exceed-counter */
|
||||
uint8_t agc_adc_large_overload_inc_steps; /* adi,agc-adc-large-overload-inc-steps - Name is misleading should be dec-steps*/
|
||||
uint8_t agc_adc_lmt_small_overload_prevent_gain_inc_enable; /* adi,agc-adc-lmt-small-overload-prevent-gain-inc-enable */
|
||||
uint8_t agc_adc_small_overload_exceed_counter; /* adi,agc-adc-small-overload-exceed-counter */
|
||||
uint8_t agc_dig_gain_step_size; /* adi,agc-dig-gain-step-size */
|
||||
uint8_t agc_dig_saturation_exceed_counter; /* adi,agc-dig-saturation-exceed-counter */
|
||||
uint32_t agc_gain_update_interval_us; /* adi,agc-gain-update-interval-us */
|
||||
uint8_t agc_immed_gain_change_if_large_adc_overload_enable; /* adi,agc-immed-gain-change-if-large-adc-overload-enable */
|
||||
uint8_t agc_immed_gain_change_if_large_lmt_overload_enable; /* adi,agc-immed-gain-change-if-large-lmt-overload-enable */
|
||||
uint8_t agc_inner_thresh_high; /* adi,agc-inner-thresh-high */
|
||||
uint8_t agc_inner_thresh_high_dec_steps; /* adi,agc-inner-thresh-high-dec-steps */
|
||||
uint8_t agc_inner_thresh_low; /* adi,agc-inner-thresh-low */
|
||||
uint8_t agc_inner_thresh_low_inc_steps; /* adi,agc-inner-thresh-low-inc-steps */
|
||||
uint8_t agc_lmt_overload_large_exceed_counter; /* adi,agc-lmt-overload-large-exceed-counter */
|
||||
uint8_t agc_lmt_overload_large_inc_steps; /* adi,agc-lmt-overload-large-inc-steps */
|
||||
uint8_t agc_lmt_overload_small_exceed_counter; /* adi,agc-lmt-overload-small-exceed-counter */
|
||||
uint8_t agc_outer_thresh_high; /* adi,agc-outer-thresh-high */
|
||||
uint8_t agc_outer_thresh_high_dec_steps; /* adi,agc-outer-thresh-high-dec-steps */
|
||||
uint8_t agc_outer_thresh_low; /* adi,agc-outer-thresh-low */
|
||||
uint8_t agc_outer_thresh_low_inc_steps; /* adi,agc-outer-thresh-low-inc-steps */
|
||||
uint32_t agc_attack_delay_extra_margin_us; /* adi,agc-attack-delay-extra-margin-us */
|
||||
uint8_t agc_sync_for_gain_counter_enable; /* adi,agc-sync-for-gain-counter-enable */
|
||||
/* Fast AGC */
|
||||
uint32_t fagc_dec_pow_measuremnt_duration; /* adi,fagc-dec-pow-measurement-duration */
|
||||
uint32_t fagc_state_wait_time_ns; /* adi,fagc-state-wait-time-ns */
|
||||
/* Fast AGC - Low Power */
|
||||
uint8_t fagc_allow_agc_gain_increase; /* adi,fagc-allow-agc-gain-increase-enable */
|
||||
uint32_t fagc_lp_thresh_increment_time; /* adi,fagc-lp-thresh-increment-time */
|
||||
uint32_t fagc_lp_thresh_increment_steps; /* adi,fagc-lp-thresh-increment-steps */
|
||||
/* Fast AGC - Lock Level (Lock Level is set via slow AGC inner high threshold) */
|
||||
uint8_t fagc_lock_level_lmt_gain_increase_en; /* adi,fagc-lock-level-lmt-gain-increase-enable */
|
||||
uint32_t fagc_lock_level_gain_increase_upper_limit; /* adi,fagc-lock-level-gain-increase-upper-limit */
|
||||
/* Fast AGC - Peak Detectors and Final Settling */
|
||||
uint32_t fagc_lpf_final_settling_steps; /* adi,fagc-lpf-final-settling-steps */
|
||||
uint32_t fagc_lmt_final_settling_steps; /* adi,fagc-lmt-final-settling-steps */
|
||||
uint32_t fagc_final_overrange_count; /* adi,fagc-final-overrange-count */
|
||||
/* Fast AGC - Final Power Test */
|
||||
uint8_t fagc_gain_increase_after_gain_lock_en; /* adi,fagc-gain-increase-after-gain-lock-enable */
|
||||
/* Fast AGC - Unlocking the Gain */
|
||||
uint32_t fagc_gain_index_type_after_exit_rx_mode; /* adi,fagc-gain-index-type-after-exit-rx-mode */
|
||||
uint8_t fagc_use_last_lock_level_for_set_gain_en; /* adi,fagc-use-last-lock-level-for-set-gain-enable */
|
||||
uint8_t fagc_rst_gla_stronger_sig_thresh_exceeded_en; /* adi,fagc-rst-gla-stronger-sig-thresh-exceeded-enable */
|
||||
uint32_t fagc_optimized_gain_offset; /* adi,fagc-optimized-gain-offset */
|
||||
uint32_t fagc_rst_gla_stronger_sig_thresh_above_ll; /* adi,fagc-rst-gla-stronger-sig-thresh-above-ll */
|
||||
uint8_t fagc_rst_gla_engergy_lost_sig_thresh_exceeded_en; /* adi,fagc-rst-gla-engergy-lost-sig-thresh-exceeded-enable */
|
||||
uint8_t fagc_rst_gla_engergy_lost_goto_optim_gain_en; /* adi,fagc-rst-gla-engergy-lost-goto-optim-gain-enable */
|
||||
uint32_t fagc_rst_gla_engergy_lost_sig_thresh_below_ll; /* adi,fagc-rst-gla-engergy-lost-sig-thresh-below-ll */
|
||||
uint32_t fagc_energy_lost_stronger_sig_gain_lock_exit_cnt; /* adi,fagc-energy-lost-stronger-sig-gain-lock-exit-cnt */
|
||||
uint8_t fagc_rst_gla_large_adc_overload_en; /* adi,fagc-rst-gla-large-adc-overload-enable */
|
||||
uint8_t fagc_rst_gla_large_lmt_overload_en; /* adi,fagc-rst-gla-large-lmt-overload-enable */
|
||||
uint8_t fagc_rst_gla_en_agc_pulled_high_en; /* adi,fagc-rst-gla-en-agc-pulled-high-enable */
|
||||
uint32_t fagc_rst_gla_if_en_agc_pulled_high_mode; /* adi,fagc-rst-gla-if-en-agc-pulled-high-mode */
|
||||
uint32_t fagc_power_measurement_duration_in_state5; /* adi,fagc-power-measurement-duration-in-state5 */
|
||||
uint32_t fagc_large_overload_inc_steps; /* adi,fagc-adc-large-overload-inc-steps - Name is misleading should be dec-steps */
|
||||
/* RSSI Control */
|
||||
uint32_t rssi_delay; /* adi,rssi-delay */
|
||||
uint32_t rssi_duration; /* adi,rssi-duration */
|
||||
uint8_t rssi_restart_mode; /* adi,rssi-restart-mode */
|
||||
uint8_t rssi_unit_is_rx_samples_enable; /* adi,rssi-unit-is-rx-samples-enable */
|
||||
uint32_t rssi_wait; /* adi,rssi-wait */
|
||||
/* Aux ADC Control */
|
||||
uint32_t aux_adc_decimation; /* adi,aux-adc-decimation */
|
||||
uint32_t aux_adc_rate; /* adi,aux-adc-rate */
|
||||
/* AuxDAC Control */
|
||||
uint8_t aux_dac_manual_mode_enable; /* adi,aux-dac-manual-mode-enable */
|
||||
uint32_t aux_dac1_default_value_mV; /* adi,aux-dac1-default-value-mV */
|
||||
uint8_t aux_dac1_active_in_rx_enable; /* adi,aux-dac1-active-in-rx-enable */
|
||||
uint8_t aux_dac1_active_in_tx_enable; /* adi,aux-dac1-active-in-tx-enable */
|
||||
uint8_t aux_dac1_active_in_alert_enable; /* adi,aux-dac1-active-in-alert-enable */
|
||||
uint32_t aux_dac1_rx_delay_us; /* adi,aux-dac1-rx-delay-us */
|
||||
uint32_t aux_dac1_tx_delay_us; /* adi,aux-dac1-tx-delay-us */
|
||||
uint32_t aux_dac2_default_value_mV; /* adi,aux-dac2-default-value-mV */
|
||||
uint8_t aux_dac2_active_in_rx_enable; /* adi,aux-dac2-active-in-rx-enable */
|
||||
uint8_t aux_dac2_active_in_tx_enable; /* adi,aux-dac2-active-in-tx-enable */
|
||||
uint8_t aux_dac2_active_in_alert_enable; /* adi,aux-dac2-active-in-alert-enable */
|
||||
uint32_t aux_dac2_rx_delay_us; /* adi,aux-dac2-rx-delay-us */
|
||||
uint32_t aux_dac2_tx_delay_us; /* adi,aux-dac2-tx-delay-us */
|
||||
/* Temperature Sensor Control */
|
||||
uint32_t temp_sense_decimation; /* adi,temp-sense-decimation */
|
||||
uint16_t temp_sense_measurement_interval_ms; /* adi,temp-sense-measurement-interval-ms */
|
||||
int8_t temp_sense_offset_signed; /* adi,temp-sense-offset-signed */
|
||||
uint8_t temp_sense_periodic_measurement_enable; /* adi,temp-sense-periodic-measurement-enable */
|
||||
/* Control Out Setup */
|
||||
uint8_t ctrl_outs_enable_mask; /* adi,ctrl-outs-enable-mask */
|
||||
uint8_t ctrl_outs_index; /* adi,ctrl-outs-index */
|
||||
/* External LNA Control */
|
||||
uint32_t elna_settling_delay_ns; /* adi,elna-settling-delay-ns */
|
||||
uint32_t elna_gain_mdB; /* adi,elna-gain-mdB */
|
||||
uint32_t elna_bypass_loss_mdB; /* adi,elna-bypass-loss-mdB */
|
||||
uint8_t elna_rx1_gpo0_control_enable; /* adi,elna-rx1-gpo0-control-enable */
|
||||
uint8_t elna_rx2_gpo1_control_enable; /* adi,elna-rx2-gpo1-control-enable */
|
||||
uint8_t elna_gaintable_all_index_enable; /* adi,elna-gaintable-all-index-enable */
|
||||
/* Digital Interface Control */
|
||||
uint8_t digital_interface_tune_skip_mode; /* adi,digital-interface-tune-skip-mode */
|
||||
uint8_t digital_interface_tune_fir_disable; /* adi,digital-interface-tune-fir-disable */
|
||||
uint8_t pp_tx_swap_enable; /* adi,pp-tx-swap-enable */
|
||||
uint8_t pp_rx_swap_enable; /* adi,pp-rx-swap-enable */
|
||||
uint8_t tx_channel_swap_enable; /* adi,tx-channel-swap-enable */
|
||||
uint8_t rx_channel_swap_enable; /* adi,rx-channel-swap-enable */
|
||||
uint8_t rx_frame_pulse_mode_enable; /* adi,rx-frame-pulse-mode-enable */
|
||||
uint8_t two_t_two_r_timing_enable; /* adi,2t2r-timing-enable */
|
||||
uint8_t invert_data_bus_enable; /* adi,invert-data-bus-enable */
|
||||
uint8_t invert_data_clk_enable; /* adi,invert-data-clk-enable */
|
||||
uint8_t fdd_alt_word_order_enable; /* adi,fdd-alt-word-order-enable */
|
||||
uint8_t invert_rx_frame_enable; /* adi,invert-rx-frame-enable */
|
||||
uint8_t fdd_rx_rate_2tx_enable; /* adi,fdd-rx-rate-2tx-enable */
|
||||
uint8_t swap_ports_enable; /* adi,swap-ports-enable */
|
||||
uint8_t single_data_rate_enable; /* adi,single-data-rate-enable */
|
||||
uint8_t lvds_mode_enable; /* adi,lvds-mode-enable */
|
||||
uint8_t half_duplex_mode_enable; /* adi,half-duplex-mode-enable */
|
||||
uint8_t single_port_mode_enable; /* adi,single-port-mode-enable */
|
||||
uint8_t full_port_enable; /* adi,full-port-enable */
|
||||
uint8_t full_duplex_swap_bits_enable; /* adi,full-duplex-swap-bits-enable */
|
||||
uint32_t delay_rx_data; /* adi,delay-rx-data */
|
||||
uint32_t rx_data_clock_delay; /* adi,rx-data-clock-delay */
|
||||
uint32_t rx_data_delay; /* adi,rx-data-delay */
|
||||
uint32_t tx_fb_clock_delay; /* adi,tx-fb-clock-delay */
|
||||
uint32_t tx_data_delay; /* adi,tx-data-delay */
|
||||
uint32_t lvds_bias_mV; /* adi,lvds-bias-mV */
|
||||
uint8_t lvds_rx_onchip_termination_enable; /* adi,lvds-rx-onchip-termination-enable */
|
||||
uint8_t rx1rx2_phase_inversion_en; /* adi,rx1-rx2-phase-inversion-enable */
|
||||
uint8_t lvds_invert1_control; /* adi,lvds-invert1-control */
|
||||
uint8_t lvds_invert2_control; /* adi,lvds-invert2-control */
|
||||
/* GPO Control */
|
||||
uint8_t gpo_manual_mode_enable; /* adi,gpo-manual-mode-enable */
|
||||
uint32_t gpo_manual_mode_enable_mask; /* adi,gpo-manual-mode-enable-mask */
|
||||
uint8_t gpo0_inactive_state_high_enable; /* adi,gpo0-inactive-state-high-enable */
|
||||
uint8_t gpo1_inactive_state_high_enable; /* adi,gpo1-inactive-state-high-enable */
|
||||
uint8_t gpo2_inactive_state_high_enable; /* adi,gpo2-inactive-state-high-enable */
|
||||
uint8_t gpo3_inactive_state_high_enable; /* adi,gpo3-inactive-state-high-enable */
|
||||
uint8_t gpo0_slave_rx_enable; /* adi,gpo0-slave-rx-enable */
|
||||
uint8_t gpo0_slave_tx_enable; /* adi,gpo0-slave-tx-enable */
|
||||
uint8_t gpo1_slave_rx_enable; /* adi,gpo1-slave-rx-enable */
|
||||
uint8_t gpo1_slave_tx_enable; /* adi,gpo1-slave-tx-enable */
|
||||
uint8_t gpo2_slave_rx_enable; /* adi,gpo2-slave-rx-enable */
|
||||
uint8_t gpo2_slave_tx_enable; /* adi,gpo2-slave-tx-enable */
|
||||
uint8_t gpo3_slave_rx_enable; /* adi,gpo3-slave-rx-enable */
|
||||
uint8_t gpo3_slave_tx_enable; /* adi,gpo3-slave-tx-enable */
|
||||
uint8_t gpo0_rx_delay_us; /* adi,gpo0-rx-delay-us */
|
||||
uint8_t gpo0_tx_delay_us; /* adi,gpo0-tx-delay-us */
|
||||
uint8_t gpo1_rx_delay_us; /* adi,gpo1-rx-delay-us */
|
||||
uint8_t gpo1_tx_delay_us; /* adi,gpo1-tx-delay-us */
|
||||
uint8_t gpo2_rx_delay_us; /* adi,gpo2-rx-delay-us */
|
||||
uint8_t gpo2_tx_delay_us; /* adi,gpo2-tx-delay-us */
|
||||
uint8_t gpo3_rx_delay_us; /* adi,gpo3-rx-delay-us */
|
||||
uint8_t gpo3_tx_delay_us; /* adi,gpo3-tx-delay-us */
|
||||
/* Tx Monitor Control */
|
||||
uint32_t low_high_gain_threshold_mdB; /* adi,txmon-low-high-thresh */
|
||||
uint32_t low_gain_dB; /* adi,txmon-low-gain */
|
||||
uint32_t high_gain_dB; /* adi,txmon-high-gain */
|
||||
uint8_t tx_mon_track_en; /* adi,txmon-dc-tracking-enable */
|
||||
uint8_t one_shot_mode_en; /* adi,txmon-one-shot-mode-enable */
|
||||
uint32_t tx_mon_delay; /* adi,txmon-delay */
|
||||
uint32_t tx_mon_duration; /* adi,txmon-duration */
|
||||
uint32_t tx1_mon_front_end_gain; /* adi,txmon-1-front-end-gain */
|
||||
uint32_t tx2_mon_front_end_gain; /* adi,txmon-2-front-end-gain */
|
||||
uint32_t tx1_mon_lo_cm; /* adi,txmon-1-lo-cm */
|
||||
uint32_t tx2_mon_lo_cm; /* adi,txmon-2-lo-cm */
|
||||
/* GPIO definitions */
|
||||
struct gpio_init_param gpio_resetb; /* reset-gpios */
|
||||
/* MCS Sync */
|
||||
struct gpio_init_param gpio_sync; /* sync-gpios */
|
||||
struct gpio_init_param gpio_cal_sw1; /* cal-sw1-gpios */
|
||||
struct gpio_init_param gpio_cal_sw2; /* cal-sw2-gpios */
|
||||
|
||||
struct spi_init_param spi_param;
|
||||
|
||||
/* External LO clocks */
|
||||
uint32_t (*ad9361_rfpll_ext_recalc_rate)(struct refclk_scale *clk_priv);
|
||||
int32_t (*ad9361_rfpll_ext_round_rate)(struct refclk_scale *clk_priv,
|
||||
uint32_t rate);
|
||||
int32_t (*ad9361_rfpll_ext_set_rate)(struct refclk_scale *clk_priv,
|
||||
uint32_t rate);
|
||||
|
||||
} AD9361_InitParam;
|
||||
|
||||
typedef struct {
|
||||
uint32_t rx; /* 1, 2, 3(both) */
|
||||
int32_t rx_gain; /* -12, -6, 0, 6 */
|
||||
uint32_t rx_dec; /* 1, 2, 4 */
|
||||
int16_t rx_coef[128];
|
||||
uint8_t rx_coef_size;
|
||||
uint32_t rx_path_clks[6];
|
||||
uint32_t rx_bandwidth;
|
||||
} AD9361_RXFIRConfig;
|
||||
|
||||
typedef struct {
|
||||
uint32_t tx; /* 1, 2, 3(both) */
|
||||
int32_t tx_gain; /* -6, 0 */
|
||||
uint32_t tx_int; /* 1, 2, 4 */
|
||||
int16_t tx_coef[128];
|
||||
uint8_t tx_coef_size;
|
||||
uint32_t tx_path_clks[6];
|
||||
uint32_t tx_bandwidth;
|
||||
} AD9361_TXFIRConfig;
|
||||
|
||||
enum ad9361_ensm_mode {
|
||||
ENSM_MODE_TX,
|
||||
ENSM_MODE_RX,
|
||||
ENSM_MODE_ALERT,
|
||||
ENSM_MODE_FDD,
|
||||
ENSM_MODE_WAIT,
|
||||
ENSM_MODE_SLEEP,
|
||||
ENSM_MODE_PINCTRL,
|
||||
ENSM_MODE_PINCTRL_FDD_INDEP,
|
||||
};
|
||||
|
||||
#define ENABLE 1
|
||||
#define DISABLE 0
|
||||
|
||||
#define RX1 0
|
||||
#define RX2 1
|
||||
|
||||
#define TX1 0
|
||||
#define TX2 1
|
||||
|
||||
#define A_BALANCED 0
|
||||
#define B_BALANCED 1
|
||||
#define C_BALANCED 2
|
||||
#define A_N 3
|
||||
#define A_P 4
|
||||
#define B_N 5
|
||||
#define B_P 6
|
||||
#define C_N 7
|
||||
#define C_P 8
|
||||
#define TX_MON1 9
|
||||
#define TX_MON2 10
|
||||
#define TX_MON1_2 11
|
||||
|
||||
#define TXA 0
|
||||
#define TXB 1
|
||||
|
||||
#define MODE_1x1 1
|
||||
#define MODE_2x2 2
|
||||
|
||||
#define HIGHEST_OSR 0
|
||||
#define NOMINAL_OSR 1
|
||||
|
||||
#define INT_LO 0
|
||||
#define EXT_LO 1
|
||||
|
||||
#define ON 0
|
||||
#define OFF 1
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
/* Initialize the AD9361 part. */
|
||||
int32_t ad9361_init (struct ad9361_rf_phy **ad9361_phy,
|
||||
AD9361_InitParam *init_param);
|
||||
/* Free the allocated resources. */
|
||||
int32_t ad9361_remove(struct ad9361_rf_phy *phy);
|
||||
/* Set the Enable State Machine (ENSM) mode. */
|
||||
int32_t ad9361_set_en_state_machine_mode (struct ad9361_rf_phy *phy,
|
||||
uint32_t mode);
|
||||
/* Get the Enable State Machine (ENSM) mode. */
|
||||
int32_t ad9361_get_en_state_machine_mode (struct ad9361_rf_phy *phy,
|
||||
uint32_t *mode);
|
||||
/* Set the receive RF gain for the selected channel. */
|
||||
int32_t ad9361_set_rx_rf_gain (struct ad9361_rf_phy *phy, uint8_t ch,
|
||||
int32_t gain_db);
|
||||
/* Get current receive RF gain for the selected channel. */
|
||||
int32_t ad9361_get_rx_rf_gain (struct ad9361_rf_phy *phy, uint8_t ch,
|
||||
int32_t *gain_db);
|
||||
/* Set the RX RF bandwidth. */
|
||||
int32_t ad9361_set_rx_rf_bandwidth (struct ad9361_rf_phy *phy,
|
||||
uint32_t bandwidth_hz);
|
||||
/* Get the RX RF bandwidth. */
|
||||
int32_t ad9361_get_rx_rf_bandwidth (struct ad9361_rf_phy *phy,
|
||||
uint32_t *bandwidth_hz);
|
||||
/* Set the RX sampling frequency. */
|
||||
int32_t ad9361_set_rx_sampling_freq (struct ad9361_rf_phy *phy,
|
||||
uint32_t sampling_freq_hz);
|
||||
/* Get current RX sampling frequency. */
|
||||
int32_t ad9361_get_rx_sampling_freq (struct ad9361_rf_phy *phy,
|
||||
uint32_t *sampling_freq_hz);
|
||||
/* Set the RX LO frequency. */
|
||||
int32_t ad9361_set_rx_lo_freq (struct ad9361_rf_phy *phy, uint64_t lo_freq_hz);
|
||||
/* Get current RX LO frequency. */
|
||||
int32_t ad9361_get_rx_lo_freq (struct ad9361_rf_phy *phy, uint64_t *lo_freq_hz);
|
||||
/* Switch between internal and external LO. */
|
||||
int32_t ad9361_set_rx_lo_int_ext(struct ad9361_rf_phy *phy, uint8_t int_ext);
|
||||
/* Get the RSSI for the selected channel. */
|
||||
int32_t ad9361_get_rx_rssi (struct ad9361_rf_phy *phy, uint8_t ch,
|
||||
struct rf_rssi *rssi);
|
||||
/* Set the gain control mode for the selected channel. */
|
||||
int32_t ad9361_set_rx_gain_control_mode (struct ad9361_rf_phy *phy, uint8_t ch,
|
||||
uint8_t gc_mode);
|
||||
/* Get the gain control mode for the selected channel. */
|
||||
int32_t ad9361_get_rx_gain_control_mode (struct ad9361_rf_phy *phy, uint8_t ch,
|
||||
uint8_t *gc_mode);
|
||||
/* Set the RX FIR filter configuration. */
|
||||
int32_t ad9361_set_rx_fir_config (struct ad9361_rf_phy *phy,
|
||||
AD9361_RXFIRConfig fir_cfg);
|
||||
/* Get the RX FIR filter configuration. */
|
||||
int32_t ad9361_get_rx_fir_config(struct ad9361_rf_phy *phy, uint8_t rx_ch,
|
||||
AD9361_RXFIRConfig *fir_cfg);
|
||||
/* Enable/disable the RX FIR filter. */
|
||||
int32_t ad9361_set_rx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t en_dis);
|
||||
/* Get the status of the RX FIR filter. */
|
||||
int32_t ad9361_get_rx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t *en_dis);
|
||||
/* Enable/disable the RX RFDC Tracking. */
|
||||
int32_t ad9361_set_rx_rfdc_track_en_dis (struct ad9361_rf_phy *phy,
|
||||
uint8_t en_dis);
|
||||
/* Get the status of the RX RFDC Tracking. */
|
||||
int32_t ad9361_get_rx_rfdc_track_en_dis (struct ad9361_rf_phy *phy,
|
||||
uint8_t *en_dis);
|
||||
/* Enable/disable the RX BasebandDC Tracking. */
|
||||
int32_t ad9361_set_rx_bbdc_track_en_dis (struct ad9361_rf_phy *phy,
|
||||
uint8_t en_dis);
|
||||
/* Get the status of the RX BasebandDC Tracking. */
|
||||
int32_t ad9361_get_rx_bbdc_track_en_dis (struct ad9361_rf_phy *phy,
|
||||
uint8_t *en_dis);
|
||||
/* Enable/disable the RX Quadrature Tracking. */
|
||||
int32_t ad9361_set_rx_quad_track_en_dis (struct ad9361_rf_phy *phy,
|
||||
uint8_t en_dis);
|
||||
/* Get the status of the RX Quadrature Tracking. */
|
||||
int32_t ad9361_get_rx_quad_track_en_dis (struct ad9361_rf_phy *phy,
|
||||
uint8_t *en_dis);
|
||||
/* Set the RX RF input port. */
|
||||
int32_t ad9361_set_rx_rf_port_input (struct ad9361_rf_phy *phy, uint32_t mode);
|
||||
/* Get the selected RX RF input port. */
|
||||
int32_t ad9361_get_rx_rf_port_input (struct ad9361_rf_phy *phy, uint32_t *mode);
|
||||
/* Store RX fastlock profile. */
|
||||
int32_t ad9361_rx_fastlock_store(struct ad9361_rf_phy *phy, uint32_t profile);
|
||||
/* Recall RX fastlock profile. */
|
||||
int32_t ad9361_rx_fastlock_recall(struct ad9361_rf_phy *phy, uint32_t profile);
|
||||
/* Load RX fastlock profile. */
|
||||
int32_t ad9361_rx_fastlock_load(struct ad9361_rf_phy *phy, uint32_t profile,
|
||||
uint8_t *values);
|
||||
/* Save RX fastlock profile. */
|
||||
int32_t ad9361_rx_fastlock_save(struct ad9361_rf_phy *phy, uint32_t profile,
|
||||
uint8_t *values);
|
||||
/* Power down the RX Local Oscillator. */
|
||||
int32_t ad9361_rx_lo_powerdown(struct ad9361_rf_phy *phy, uint8_t option);
|
||||
/* Get the RX Local Oscillator power status. */
|
||||
int32_t ad9361_get_rx_lo_power(struct ad9361_rf_phy *phy, uint8_t *option);
|
||||
/* Set the transmit attenuation for the selected channel. */
|
||||
int32_t ad9361_set_tx_attenuation (struct ad9361_rf_phy *phy, uint8_t ch,
|
||||
uint32_t attenuation_mdb);
|
||||
/* Get current transmit attenuation for the selected channel. */
|
||||
int32_t ad9361_get_tx_attenuation (struct ad9361_rf_phy *phy, uint8_t ch,
|
||||
uint32_t *attenuation_mdb);
|
||||
/* Set the TX RF bandwidth. */
|
||||
int32_t ad9361_set_tx_rf_bandwidth (struct ad9361_rf_phy *phy,
|
||||
uint32_t bandwidth_hz);
|
||||
/* Get the TX RF bandwidth. */
|
||||
int32_t ad9361_get_tx_rf_bandwidth (struct ad9361_rf_phy *phy,
|
||||
uint32_t *bandwidth_hz);
|
||||
/* Set the TX sampling frequency. */
|
||||
int32_t ad9361_set_tx_sampling_freq (struct ad9361_rf_phy *phy,
|
||||
uint32_t sampling_freq_hz);
|
||||
/* Get current TX sampling frequency. */
|
||||
int32_t ad9361_get_tx_sampling_freq (struct ad9361_rf_phy *phy,
|
||||
uint32_t *sampling_freq_hz);
|
||||
/* Set the TX LO frequency. */
|
||||
int32_t ad9361_set_tx_lo_freq (struct ad9361_rf_phy *phy, uint64_t lo_freq_hz);
|
||||
/* Get current TX LO frequency. */
|
||||
int32_t ad9361_get_tx_lo_freq (struct ad9361_rf_phy *phy, uint64_t *lo_freq_hz);
|
||||
/* Switch between internal and external LO. */
|
||||
int32_t ad9361_set_tx_lo_int_ext(struct ad9361_rf_phy *phy, uint8_t int_ext);
|
||||
/* Set the TX FIR filter configuration. */
|
||||
int32_t ad9361_set_tx_fir_config (struct ad9361_rf_phy *phy,
|
||||
AD9361_TXFIRConfig fir_cfg);
|
||||
/* Get the TX FIR filter configuration. */
|
||||
int32_t ad9361_get_tx_fir_config(struct ad9361_rf_phy *phy, uint8_t tx_ch,
|
||||
AD9361_TXFIRConfig *fir_cfg);
|
||||
/* Enable/disable the TX FIR filter. */
|
||||
int32_t ad9361_set_tx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t en_dis);
|
||||
/* Get the status of the TX FIR filter. */
|
||||
int32_t ad9361_get_tx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t *en_dis);
|
||||
/* Get the TX RSSI for the selected channel. */
|
||||
int32_t ad9361_get_tx_rssi (struct ad9361_rf_phy *phy, uint8_t ch,
|
||||
uint32_t *rssi_db_x_1000);
|
||||
/* Set the TX RF output port. */
|
||||
int32_t ad9361_set_tx_rf_port_output (struct ad9361_rf_phy *phy, uint32_t mode);
|
||||
/* Get the selected TX RF output port. */
|
||||
int32_t ad9361_get_tx_rf_port_output (struct ad9361_rf_phy *phy,
|
||||
uint32_t *mode);
|
||||
/* Enable/disable the auto calibration. */
|
||||
int32_t ad9361_set_tx_auto_cal_en_dis (struct ad9361_rf_phy *phy,
|
||||
uint8_t en_dis);
|
||||
/* Get the status of the auto calibration flag. */
|
||||
int32_t ad9361_get_tx_auto_cal_en_dis (struct ad9361_rf_phy *phy,
|
||||
uint8_t *en_dis);
|
||||
/* Store TX fastlock profile. */
|
||||
int32_t ad9361_tx_fastlock_store(struct ad9361_rf_phy *phy, uint32_t profile);
|
||||
/* Recall TX fastlock profile. */
|
||||
int32_t ad9361_tx_fastlock_recall(struct ad9361_rf_phy *phy, uint32_t profile);
|
||||
/* Load TX fastlock profile. */
|
||||
int32_t ad9361_tx_fastlock_load(struct ad9361_rf_phy *phy, uint32_t profile,
|
||||
uint8_t *values);
|
||||
/* Save TX fastlock profile. */
|
||||
int32_t ad9361_tx_fastlock_save(struct ad9361_rf_phy *phy, uint32_t profile,
|
||||
uint8_t *values);
|
||||
/* Power down the TX Local Oscillator. */
|
||||
int32_t ad9361_tx_lo_powerdown(struct ad9361_rf_phy *phy, uint8_t option);
|
||||
/* Get the TX Local Oscillator power status. */
|
||||
int32_t ad9361_get_tx_lo_power(struct ad9361_rf_phy *phy, uint8_t *option);
|
||||
/* Set the RX and TX path rates. */
|
||||
int32_t ad9361_set_trx_path_clks(struct ad9361_rf_phy *phy,
|
||||
uint32_t *rx_path_clks, uint32_t *tx_path_clks);
|
||||
/* Get the RX and TX path rates. */
|
||||
int32_t ad9361_get_trx_path_clks(struct ad9361_rf_phy *phy,
|
||||
uint32_t *rx_path_clks, uint32_t *tx_path_clks);
|
||||
/* Set the number of channels mode. */
|
||||
int32_t ad9361_set_no_ch_mode(struct ad9361_rf_phy *phy, uint8_t no_ch_mode);
|
||||
/* Do multi chip synchronization. */
|
||||
int32_t ad9361_do_mcs(struct ad9361_rf_phy *phy_master,
|
||||
struct ad9361_rf_phy *phy_slave);
|
||||
/* Enable/disable the TRX FIR filters. */
|
||||
int32_t ad9361_set_trx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t en_dis);
|
||||
/* Set the OSR rate governor. */
|
||||
int32_t ad9361_set_trx_rate_gov (struct ad9361_rf_phy *phy, uint32_t rate_gov);
|
||||
/* Get the OSR rate governor. */
|
||||
int32_t ad9361_get_trx_rate_gov (struct ad9361_rf_phy *phy, uint32_t *rate_gov);
|
||||
/* Perform the selected calibration. */
|
||||
int32_t ad9361_do_calib(struct ad9361_rf_phy *phy, uint32_t cal, int32_t arg);
|
||||
/* Load and enable TRX FIR filters configurations. */
|
||||
int32_t ad9361_trx_load_enable_fir(struct ad9361_rf_phy *phy,
|
||||
AD9361_RXFIRConfig rx_fir_cfg,
|
||||
AD9361_TXFIRConfig tx_fir_cfg);
|
||||
/* Do DCXO coarse tuning. */
|
||||
int32_t ad9361_do_dcxo_tune_coarse(struct ad9361_rf_phy *phy,
|
||||
uint32_t coarse);
|
||||
/* Do DCXO fine tuning. */
|
||||
int32_t ad9361_do_dcxo_tune_fine(struct ad9361_rf_phy *phy,
|
||||
uint32_t fine);
|
||||
/* Get the temperature. */
|
||||
int32_t ad9361_get_temperature(struct ad9361_rf_phy *phy,
|
||||
int32_t *temp);
|
||||
#endif
|
||||
@@ -0,0 +1,86 @@
|
||||
|
||||
/***************************************************************************//**
|
||||
* @file ad9361_conv.c
|
||||
* @brief Implementation of AD9361 Conv Driver.
|
||||
********************************************************************************
|
||||
* Copyright 2014-2015(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include "ad9361.h"
|
||||
#include "ad9361_util.h"
|
||||
#include "delay.h"
|
||||
#include "../../../config/app_config.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* HDL loopback enable/disable.
|
||||
* @param phy The AD9361 state structure.
|
||||
* @param enable Enable/disable option.
|
||||
* @return 0 in case of success, negative error code otherwise.
|
||||
*/
|
||||
int32_t ad9361_hdl_loopback(struct ad9361_rf_phy *phy, bool enable)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Digital tune.
|
||||
* @param phy The AD9361 state structure.
|
||||
* @param max_freq Maximum frequency.
|
||||
* @param flags Flags: BE_VERBOSE, BE_MOREVERBOSE, DO_IDELAY, DO_ODELAY.
|
||||
* @return 0 in case of success, negative error code otherwise.
|
||||
*/
|
||||
int32_t ad9361_dig_tune(struct ad9361_rf_phy *phy, uint32_t max_freq,
|
||||
enum dig_tune_flags flags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the AD9361 device.
|
||||
* @param phy The AD9361 state structure.
|
||||
* @return 0 in case of success, negative error code otherwise.
|
||||
*/
|
||||
int32_t ad9361_post_setup(struct ad9361_rf_phy *phy)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9361_util.c
|
||||
* @brief AD9361 Implementation of Util Driver.
|
||||
* @author DBogdan (dragos.bogdan@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2013(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <string.h>
|
||||
#include "ad9361_util.h"
|
||||
#include "../../../include/delay.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Macros Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
#define BITS_PER_LONG 32
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief clk_prepare_enable
|
||||
*******************************************************************************/
|
||||
int32_t clk_prepare_enable(struct clk *clk)
|
||||
{
|
||||
if (clk) {
|
||||
// Unused variable - fix compiler warning
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief clk_get_rate
|
||||
*******************************************************************************/
|
||||
uint32_t clk_get_rate(struct ad9361_rf_phy *phy,
|
||||
struct refclk_scale *clk_priv)
|
||||
{
|
||||
uint32_t rate = 0;
|
||||
uint32_t source;
|
||||
|
||||
source = clk_priv->source;
|
||||
|
||||
switch (source) {
|
||||
case TX_REFCLK:
|
||||
case RX_REFCLK:
|
||||
case BB_REFCLK:
|
||||
rate = ad9361_clk_factor_recalc_rate(clk_priv,
|
||||
phy->clk_refin->rate);
|
||||
break;
|
||||
case TX_RFPLL_INT:
|
||||
case RX_RFPLL_INT:
|
||||
rate = ad9361_rfpll_int_recalc_rate(clk_priv,
|
||||
phy->clks[clk_priv->parent_source]->rate);
|
||||
break;
|
||||
case RX_RFPLL_DUMMY:
|
||||
case TX_RFPLL_DUMMY:
|
||||
rate = ad9361_rfpll_dummy_recalc_rate(clk_priv);
|
||||
break;
|
||||
case TX_RFPLL:
|
||||
case RX_RFPLL:
|
||||
rate = ad9361_rfpll_recalc_rate(clk_priv);
|
||||
break;
|
||||
case BBPLL_CLK:
|
||||
rate = ad9361_bbpll_recalc_rate(clk_priv,
|
||||
phy->clks[clk_priv->parent_source]->rate);
|
||||
break;
|
||||
case ADC_CLK:
|
||||
case R2_CLK:
|
||||
case R1_CLK:
|
||||
case CLKRF_CLK:
|
||||
case RX_SAMPL_CLK:
|
||||
case DAC_CLK:
|
||||
case T2_CLK:
|
||||
case T1_CLK:
|
||||
case CLKTF_CLK:
|
||||
case TX_SAMPL_CLK:
|
||||
rate = ad9361_clk_factor_recalc_rate(clk_priv,
|
||||
phy->clks[clk_priv->parent_source]->rate);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief clk_set_rate
|
||||
*******************************************************************************/
|
||||
int32_t clk_set_rate(struct ad9361_rf_phy *phy,
|
||||
struct refclk_scale *clk_priv,
|
||||
uint32_t rate)
|
||||
{
|
||||
uint32_t source;
|
||||
int32_t i;
|
||||
uint32_t round_rate;
|
||||
|
||||
source = clk_priv->source;
|
||||
if(phy->clks[source]->rate != rate)
|
||||
{
|
||||
switch (source) {
|
||||
case TX_REFCLK:
|
||||
case RX_REFCLK:
|
||||
case BB_REFCLK:
|
||||
round_rate = ad9361_clk_factor_round_rate(clk_priv, rate,
|
||||
&phy->clk_refin->rate);
|
||||
ad9361_clk_factor_set_rate(clk_priv, round_rate,
|
||||
phy->clk_refin->rate);
|
||||
phy->clks[source]->rate = ad9361_clk_factor_recalc_rate(clk_priv,
|
||||
phy->clk_refin->rate);
|
||||
break;
|
||||
case TX_RFPLL_INT:
|
||||
case RX_RFPLL_INT:
|
||||
round_rate = ad9361_rfpll_int_round_rate(clk_priv, rate,
|
||||
&phy->clks[clk_priv->parent_source]->rate);
|
||||
ad9361_rfpll_int_set_rate(clk_priv, round_rate,
|
||||
phy->clks[clk_priv->parent_source]->rate);
|
||||
phy->clks[source]->rate = ad9361_rfpll_int_recalc_rate(clk_priv,
|
||||
phy->clks[clk_priv->parent_source]->rate);
|
||||
break;
|
||||
case RX_RFPLL_DUMMY:
|
||||
case TX_RFPLL_DUMMY:
|
||||
ad9361_rfpll_dummy_set_rate(clk_priv, rate);
|
||||
break;
|
||||
case TX_RFPLL:
|
||||
case RX_RFPLL:
|
||||
round_rate = ad9361_rfpll_round_rate(clk_priv, rate);
|
||||
ad9361_rfpll_set_rate(clk_priv, round_rate);
|
||||
phy->clks[source]->rate = ad9361_rfpll_recalc_rate(clk_priv);
|
||||
break;
|
||||
case BBPLL_CLK:
|
||||
round_rate = ad9361_bbpll_round_rate(clk_priv, rate,
|
||||
&phy->clks[clk_priv->parent_source]->rate);
|
||||
ad9361_bbpll_set_rate(clk_priv, round_rate,
|
||||
phy->clks[clk_priv->parent_source]->rate);
|
||||
phy->clks[source]->rate = ad9361_bbpll_recalc_rate(clk_priv,
|
||||
phy->clks[clk_priv->parent_source]->rate);
|
||||
phy->bbpll_initialized = true;
|
||||
break;
|
||||
case ADC_CLK:
|
||||
case R2_CLK:
|
||||
case R1_CLK:
|
||||
case CLKRF_CLK:
|
||||
case RX_SAMPL_CLK:
|
||||
case DAC_CLK:
|
||||
case T2_CLK:
|
||||
case T1_CLK:
|
||||
case CLKTF_CLK:
|
||||
case TX_SAMPL_CLK:
|
||||
round_rate = ad9361_clk_factor_round_rate(clk_priv, rate,
|
||||
&phy->clks[clk_priv->parent_source]->rate);
|
||||
ad9361_clk_factor_set_rate(clk_priv, round_rate,
|
||||
phy->clks[clk_priv->parent_source]->rate);
|
||||
phy->clks[source]->rate = ad9361_clk_factor_recalc_rate(clk_priv,
|
||||
phy->clks[clk_priv->parent_source]->rate);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for(i = BB_REFCLK; i < BBPLL_CLK; i++)
|
||||
{
|
||||
phy->clks[i]->rate = ad9361_clk_factor_recalc_rate(phy->ref_clk_scale[i],
|
||||
phy->clk_refin->rate);
|
||||
}
|
||||
phy->clks[BBPLL_CLK]->rate = ad9361_bbpll_recalc_rate(phy->ref_clk_scale[BBPLL_CLK],
|
||||
phy->clks[phy->ref_clk_scale[BBPLL_CLK]->parent_source]->rate);
|
||||
for(i = ADC_CLK; i < RX_RFPLL_INT; i++)
|
||||
{
|
||||
phy->clks[i]->rate = ad9361_clk_factor_recalc_rate(phy->ref_clk_scale[i],
|
||||
phy->clks[phy->ref_clk_scale[i]->parent_source]->rate);
|
||||
}
|
||||
for(i = RX_RFPLL_INT; i < RX_RFPLL_DUMMY; i++)
|
||||
{
|
||||
phy->clks[i]->rate = ad9361_rfpll_int_recalc_rate(phy->ref_clk_scale[i],
|
||||
phy->clks[phy->ref_clk_scale[i]->parent_source]->rate);
|
||||
}
|
||||
for(i = RX_RFPLL_DUMMY; i < RX_RFPLL; i++)
|
||||
{
|
||||
phy->clks[i]->rate = ad9361_rfpll_dummy_recalc_rate(phy->ref_clk_scale[i]);
|
||||
}
|
||||
for(i = RX_RFPLL; i < NUM_AD9361_CLKS; i++)
|
||||
{
|
||||
phy->clks[i]->rate = ad9361_rfpll_recalc_rate(phy->ref_clk_scale[i]);
|
||||
}
|
||||
} else {
|
||||
if ((source == BBPLL_CLK) && !phy->bbpll_initialized) {
|
||||
round_rate = ad9361_bbpll_round_rate(clk_priv, rate,
|
||||
&phy->clks[clk_priv->parent_source]->rate);
|
||||
ad9361_bbpll_set_rate(clk_priv, round_rate,
|
||||
phy->clks[clk_priv->parent_source]->rate);
|
||||
phy->clks[source]->rate = ad9361_bbpll_recalc_rate(clk_priv,
|
||||
phy->clks[clk_priv->parent_source]->rate);
|
||||
phy->bbpll_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief int_sqrt
|
||||
*******************************************************************************/
|
||||
uint32_t int_sqrt(uint32_t x)
|
||||
{
|
||||
uint32_t b, m, y = 0;
|
||||
|
||||
if (x <= 1)
|
||||
return x;
|
||||
|
||||
m = 1UL << (BITS_PER_LONG - 2);
|
||||
while (m != 0) {
|
||||
b = y + m;
|
||||
y >>= 1;
|
||||
|
||||
if (x >= b) {
|
||||
x -= b;
|
||||
y += m;
|
||||
}
|
||||
m >>= 2;
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief ilog2
|
||||
*******************************************************************************/
|
||||
int32_t ilog2(int32_t x)
|
||||
{
|
||||
int32_t A = !(!(x >> 16));
|
||||
int32_t count = 0;
|
||||
int32_t x_copy = x;
|
||||
|
||||
count = count + (A << 4);
|
||||
|
||||
x_copy = (((~A + 1) & (x >> 16)) + (~(~A + 1) & x));
|
||||
|
||||
A = !(!(x_copy >> 8));
|
||||
count = count + (A << 3);
|
||||
x_copy = (((~A + 1) & (x_copy >> 8)) + (~(~A + 1) & x_copy));
|
||||
|
||||
A = !(!(x_copy >> 4));
|
||||
count = count + (A << 2);
|
||||
x_copy = (((~A + 1) & (x_copy >> 4)) + (~(~A + 1) & x_copy));
|
||||
|
||||
A = !(!(x_copy >> 2));
|
||||
count = count + (A << 1);
|
||||
x_copy = (((~A + 1) & (x_copy >> 2)) + (~(~A + 1) & x_copy));
|
||||
|
||||
A = !(!(x_copy >> 1));
|
||||
count = count + A;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief find_first_bit
|
||||
*******************************************************************************/
|
||||
uint32_t find_first_bit(uint32_t word)
|
||||
{
|
||||
int32_t num = 0;
|
||||
|
||||
if ((word & 0xffff) == 0) {
|
||||
num += 16;
|
||||
word >>= 16;
|
||||
}
|
||||
if ((word & 0xff) == 0) {
|
||||
num += 8;
|
||||
word >>= 8;
|
||||
}
|
||||
if ((word & 0xf) == 0) {
|
||||
num += 4;
|
||||
word >>= 4;
|
||||
}
|
||||
if ((word & 0x3) == 0) {
|
||||
num += 2;
|
||||
word >>= 2;
|
||||
}
|
||||
if ((word & 0x1) == 0)
|
||||
num += 1;
|
||||
return num;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief ERR_PTR
|
||||
*******************************************************************************/
|
||||
void * ERR_PTR(long error)
|
||||
{
|
||||
return (void *) error;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief zmalloc
|
||||
*******************************************************************************/
|
||||
void *zmalloc(size_t size)
|
||||
{
|
||||
void *ptr = malloc(size);
|
||||
if (ptr)
|
||||
memset(ptr, 0, size);
|
||||
mdelay(1);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9361_util.h
|
||||
* @brief AD9361 Header file of Util driver.
|
||||
* @author DBogdan (dragos.bogdan@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2013(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef __AD9361_UTIL_H__
|
||||
#define __AD9361_UTIL_H__
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "ad9361.h"
|
||||
#include "common.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
#define CLK_IGNORE_UNUSED BIT(3)
|
||||
#define CLK_GET_RATE_NOCACHE BIT(6)
|
||||
|
||||
#if defined(HAVE_VERBOSE_MESSAGES)
|
||||
#define dev_err(dev, format, ...) ({printf(format, ## __VA_ARGS__);printf("\n"); })
|
||||
#define dev_warn(dev, format, ...) ({printf(format, ## __VA_ARGS__);printf("\n"); })
|
||||
#if defined(HAVE_DEBUG_MESSAGES)
|
||||
#define dev_dbg(dev, format, ...) ({printf(format, ## __VA_ARGS__);printf("\n"); })
|
||||
#else
|
||||
#define dev_dbg(dev, format, ...) ({ if (0) printf(format, ## __VA_ARGS__); })
|
||||
#endif
|
||||
#define printk(format, ...) printf(format, ## __VA_ARGS__)
|
||||
#else
|
||||
#define dev_err(dev, format, ...) ({ if (0) printf(format, ## __VA_ARGS__); })
|
||||
#define dev_warn(dev, format, ...) ({ if (0) printf(format, ## __VA_ARGS__); })
|
||||
#define dev_dbg(dev, format, ...) ({ if (0) printf(format, ## __VA_ARGS__); })
|
||||
#define printk(format, ...) ({ if (0) printf(format, ## __VA_ARGS__); })
|
||||
#endif
|
||||
|
||||
struct device {
|
||||
};
|
||||
|
||||
struct spi_device {
|
||||
struct device dev;
|
||||
uint8_t id_no;
|
||||
};
|
||||
|
||||
struct axiadc_state {
|
||||
struct ad9361_rf_phy *phy;
|
||||
uint32_t pcore_version;
|
||||
};
|
||||
|
||||
struct axiadc_chip_info {
|
||||
char *name;
|
||||
int32_t num_channels;
|
||||
};
|
||||
|
||||
struct axiadc_converter {
|
||||
struct axiadc_chip_info *chip_info;
|
||||
uint32_t scratch_reg[16];
|
||||
};
|
||||
|
||||
#ifdef WIN32
|
||||
#include "basetsd.h"
|
||||
typedef SSIZE_T ssize_t;
|
||||
#define strsep(s, ct) 0
|
||||
#define snprintf(s, n, format, ...) 0
|
||||
#define __func__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
int32_t clk_prepare_enable(struct clk *clk);
|
||||
uint32_t clk_get_rate(struct ad9361_rf_phy *phy,
|
||||
struct refclk_scale *clk_priv);
|
||||
int32_t clk_set_rate(struct ad9361_rf_phy *phy,
|
||||
struct refclk_scale *clk_priv,
|
||||
uint32_t rate);
|
||||
uint32_t int_sqrt(uint32_t x);
|
||||
int32_t ilog2(int32_t x);
|
||||
uint32_t find_first_bit(uint32_t word);
|
||||
void * ERR_PTR(long error);
|
||||
void *zmalloc(size_t size);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,66 @@
|
||||
/***************************************************************************//**
|
||||
* @file common.h
|
||||
* @brief Header file of Common Driver.
|
||||
* @author DBogdan (dragos.bogdan@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2013(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef __AD9361_COMMON_H_
|
||||
#define __AD9361_COMMON_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "../../../include/error.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
#if defined (__STDC__) && (__STDC_VERSION__ >= 199901L)
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
typedef enum { false, true } bool;
|
||||
#endif
|
||||
|
||||
struct clk {
|
||||
const char *name;
|
||||
uint32_t rate;
|
||||
};
|
||||
|
||||
struct clk_hw {
|
||||
struct clk *clk;
|
||||
};
|
||||
|
||||
#endif // __AD9361_COMMON_H_
|
||||
@@ -0,0 +1,151 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9361_reg.c
|
||||
* @brief Implementation of AD9680 Driver.
|
||||
* @author DBogdan (dragos.bogdan@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2014-2016(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include "ad9361_reg.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "../../../include/error.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief ad9361_reg_read
|
||||
*******************************************************************************/
|
||||
int32_t ad9361_reg_read(struct ad9361_reg_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t *reg_data)
|
||||
{
|
||||
uint8_t tx_buf[2];
|
||||
uint8_t rx_buf[1];
|
||||
int32_t ret;
|
||||
|
||||
tx_buf[0] = reg_addr >> 8;
|
||||
tx_buf[1] = reg_addr & 0xFF;
|
||||
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
tx_buf, rx_buf, 2, 1);
|
||||
|
||||
*reg_data = rx_buf[0];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief ad9361_reg_write
|
||||
*******************************************************************************/
|
||||
int32_t ad9361_reg_write(struct ad9361_reg_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t reg_data)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
|
||||
int32_t ret;
|
||||
|
||||
buf[0] = 0x80 | reg_addr >> 8;
|
||||
buf[1] = reg_addr & 0xFF;
|
||||
buf[2] = reg_data;
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
buf, NULL, 3, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief ad9361_reg_init
|
||||
*******************************************************************************/
|
||||
int32_t ad9361_reg_init(struct ad9361_reg_dev **device,
|
||||
const struct ad9361_reg_init_param *init_param)
|
||||
{
|
||||
int ret = SUCCESS;
|
||||
struct ad9361_reg_dev *dev;
|
||||
|
||||
dev = (struct ad9361_reg_dev *)malloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
return FAILURE;
|
||||
|
||||
/* SPI */
|
||||
ret = spi_init(&dev->spi_desc, init_param->spi_init);
|
||||
ret |= gpio_get(&dev->gpio_desc_resetb, init_param->gpio_resetb);
|
||||
|
||||
gpio_direction_output(dev->gpio_desc_resetb, 0);
|
||||
|
||||
ad9361_reg_reset(dev);
|
||||
|
||||
*device = dev;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* AD9361 Device Reset
|
||||
* @param phy The AD9361 state structure.
|
||||
* @return 0 in case of success, negative error code otherwise.
|
||||
*/
|
||||
int32_t ad9361_reg_reset(struct ad9361_reg_dev *dev)
|
||||
{
|
||||
if (dev->gpio_desc_resetb) {
|
||||
gpio_set_value(dev->gpio_desc_resetb, 0);
|
||||
mdelay(10);
|
||||
gpio_set_value(dev->gpio_desc_resetb, 1);
|
||||
mdelay(10);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Free the resources allocated by ad9361_reg_setup().
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
*
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*******************************************************************************/
|
||||
int32_t ad9361_reg_remove(struct ad9361_reg_dev *dev)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = spi_remove(dev->spi_desc);
|
||||
|
||||
free(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9361_reg.h
|
||||
* @brief Header file of ad9361_reg Driver.
|
||||
* @author DBogdan (dragos.bogdan@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2014-2016(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef ad9361_reg_H_
|
||||
#define ad9361_reg_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "delay.h"
|
||||
#include "spi.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
struct ad9361_reg_dev {
|
||||
/* SPI */
|
||||
struct spi_desc *spi_desc;
|
||||
struct gpio_desc *gpio_desc_resetb;
|
||||
};
|
||||
|
||||
struct ad9361_reg_init_param {
|
||||
/* SPI */
|
||||
struct spi_init_param *spi_init;
|
||||
struct gpio_init_param *gpio_resetb;
|
||||
};
|
||||
|
||||
enum Operation_Type{
|
||||
AD9361_WRITE,
|
||||
AD9361_READ,
|
||||
AD9361_WAIT,
|
||||
AD9361_WHEN
|
||||
};
|
||||
|
||||
struct ad9361_reg_config {
|
||||
int operation;
|
||||
uint16_t val1;
|
||||
uint16_t val2;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
int32_t ad9361_reg_read(struct ad9361_reg_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t *reg_data);
|
||||
|
||||
int32_t ad9361_reg_write(struct ad9361_reg_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t reg_data);
|
||||
|
||||
int32_t ad9361_reg_init(struct ad9361_reg_dev **device,
|
||||
const struct ad9361_reg_init_param *init_param);
|
||||
|
||||
int32_t ad9361_reg_reset(struct ad9361_reg_dev *dev);
|
||||
|
||||
int32_t ad9361_reg_remove(struct ad9361_reg_dev *dev);
|
||||
|
||||
#endif
|
||||
@@ -1,275 +0,0 @@
|
||||
/**
|
||||
* \file common.c
|
||||
* \brief Contains Mykonos API common wrapper functions for user hardware platform drivers
|
||||
*/
|
||||
|
||||
/**
|
||||
* \page Disclaimer Legal Disclaimer
|
||||
* Copyright 2015-2017 Analog Devices Inc.
|
||||
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "common.h"
|
||||
#include "platform_drivers.h"
|
||||
#include "parameters.h"
|
||||
|
||||
ADI_LOGLEVEL CMB_LOGLEVEL = ADIHAL_LOG_NONE;
|
||||
|
||||
static uint32_t _desired_time_to_elapse_us = 0;
|
||||
struct spi_desc *spi_ad_desc;
|
||||
struct gpio_desc *gpio_ad9371_resetb;
|
||||
struct gpio_desc *gpio_ad9528_resetb;
|
||||
struct gpio_desc *gpio_ad9528_sysref_req;
|
||||
|
||||
commonErr_t CMB_initPlatform(void)
|
||||
{
|
||||
struct spi_init_param spi_param;
|
||||
int32_t status = COMMONERR_OK;
|
||||
|
||||
status |= gpio_get(&gpio_ad9371_resetb, AD9371_RESET_B);
|
||||
status |= gpio_get(&gpio_ad9528_resetb, AD9528_RESET_B);
|
||||
status |= gpio_get(&gpio_ad9528_sysref_req, AD9528_SYSREF_REQ);
|
||||
|
||||
spi_param.id = 0;
|
||||
spi_param.mode = SPI_MODE_0;
|
||||
spi_param.chip_select = AD9371_CS;
|
||||
spi_param.max_speed_hz = 25000000u;
|
||||
|
||||
status |= spi_init(&spi_ad_desc, &spi_param);
|
||||
|
||||
if (status != SUCCESS) {
|
||||
return COMMONERR_FAILED;
|
||||
}
|
||||
|
||||
return COMMONERR_OK;
|
||||
}
|
||||
|
||||
commonErr_t CMB_closeHardware(void)
|
||||
{
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_setGPIO(uint32_t GPIO)
|
||||
{
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_hardReset(uint8_t spiChipSelectIndex)
|
||||
{
|
||||
struct gpio_desc *reset_gpio;
|
||||
|
||||
switch (spiChipSelectIndex) {
|
||||
case AD9371_CS:
|
||||
reset_gpio = gpio_ad9371_resetb;
|
||||
break;
|
||||
case AD9528_CS:
|
||||
reset_gpio = gpio_ad9528_resetb;
|
||||
break;
|
||||
default:
|
||||
return(COMMONERR_FAILED);
|
||||
}
|
||||
|
||||
gpio_direction_output(reset_gpio, 1);
|
||||
CMB_wait_ms(1);
|
||||
gpio_direction_output(reset_gpio, 0);
|
||||
CMB_wait_ms(1);
|
||||
gpio_direction_output(reset_gpio, 1);
|
||||
CMB_wait_ms(1);
|
||||
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_setSPIOptions(spiSettings_t *spiSettings)
|
||||
{
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_setSPIChannel(uint16_t chipSelectIndex )
|
||||
{
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_SPIWriteByte(spiSettings_t *spiSettings, uint16_t addr,
|
||||
uint8_t data)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
|
||||
spi_ad_desc->chip_select = spiSettings->chipSelectIndex - 1;
|
||||
|
||||
buf[0] = (uint8_t) ((addr >> 8) & 0x7f);
|
||||
buf[1] = (uint8_t) (addr & 0xff);
|
||||
buf[2] = (uint8_t) data;
|
||||
|
||||
spi_write_and_read(spi_ad_desc, buf, 3);
|
||||
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_SPIWriteBytes(spiSettings_t *spiSettings, uint16_t *addr,
|
||||
uint8_t *data, uint32_t count)
|
||||
{
|
||||
uint32_t index;
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
if (CMB_SPIWriteByte(spiSettings, *(addr + index),
|
||||
*(data + index)) != COMMONERR_OK)
|
||||
return(COMMONERR_FAILED);
|
||||
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_SPIReadByte(spiSettings_t *spiSettings, uint16_t addr,
|
||||
uint8_t *readdata)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
|
||||
spi_ad_desc->chip_select = spiSettings->chipSelectIndex - 1;
|
||||
|
||||
buf[0] = (uint8_t) ((addr >> 8) | 0x80);
|
||||
buf[1] = (uint8_t) (addr & 0xff);
|
||||
buf[2] = (uint8_t) 0x00;
|
||||
|
||||
spi_write_and_read(spi_ad_desc, buf, 3);
|
||||
*readdata = buf[2];
|
||||
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_SPIWriteField(spiSettings_t *spiSettings, uint16_t addr,
|
||||
uint8_t field_val, uint8_t mask, uint8_t start_bit)
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
if (CMB_SPIReadByte(spiSettings, addr, &data) != COMMONERR_OK)
|
||||
return(COMMONERR_FAILED);
|
||||
|
||||
data = (data & ~mask) | ((field_val << start_bit) & mask);
|
||||
|
||||
if (CMB_SPIWriteByte(spiSettings, addr, data) != COMMONERR_OK)
|
||||
return(COMMONERR_FAILED);
|
||||
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
/* read a field in a single register space (not multibyte fields) */
|
||||
commonErr_t CMB_SPIReadField(spiSettings_t *spiSettings, uint16_t addr,
|
||||
uint8_t *field_val, uint8_t mask, uint8_t start_bit)
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
if (CMB_SPIReadByte(spiSettings, addr, &data) != COMMONERR_OK)
|
||||
return(COMMONERR_FAILED);
|
||||
|
||||
data = (data & mask) >> start_bit;
|
||||
*field_val = data;
|
||||
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
|
||||
commonErr_t CMB_writeToLog(ADI_LOGLEVEL level, uint8_t deviceIndex,
|
||||
uint32_t errorCode, const char *comment)
|
||||
{
|
||||
|
||||
if((CMB_LOGLEVEL & ADIHAL_LOG_ERROR) && (level == ADIHAL_LOG_ERROR)) {
|
||||
printf("ERROR: %d: %s", (int)errorCode, comment);
|
||||
} else if((CMB_LOGLEVEL & ADIHAL_LOG_WARNING)
|
||||
&& (level == ADIHAL_LOG_WARNING)) {
|
||||
printf("WARNING: %d: %s",(int)errorCode, comment);
|
||||
} else if((CMB_LOGLEVEL & ADIHAL_LOG_MESSAGE)
|
||||
&& (level == ADIHAL_LOG_MESSAGE)) {
|
||||
printf("MESSAGE: %d: %s",(int)errorCode, comment);
|
||||
} else if(CMB_LOGLEVEL == ADIHAL_LOG_NONE ) {
|
||||
//printf("MESSAGE: %d: %s",(int)errorCode, comment);
|
||||
} else {
|
||||
printf("Undefined Log Level: 0x%X", level);
|
||||
}
|
||||
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
/* if filename null, a default path will be used in logging.c */
|
||||
commonErr_t CMB_openLog(const char *filename)
|
||||
{
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_closeLog(void)
|
||||
{
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_flushLog(void)
|
||||
{
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_wait_ms(uint32_t time_ms)
|
||||
{
|
||||
mdelay(time_ms);
|
||||
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_wait_us(uint32_t time_us)
|
||||
{
|
||||
udelay(time_us);
|
||||
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_setTimeout_ms(uint32_t timeOut_ms)
|
||||
{
|
||||
#ifdef _XPARAMETERS_PS_H_
|
||||
_desired_time_to_elapse_us = timeOut_ms * 1000;
|
||||
#else
|
||||
_desired_time_to_elapse_us = timeOut_ms * 50; // FIXME
|
||||
#endif
|
||||
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_setTimeout_us(uint32_t timeOut_us)
|
||||
{
|
||||
_desired_time_to_elapse_us = timeOut_us;
|
||||
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
|
||||
commonErr_t CMB_hasTimeoutExpired()
|
||||
{
|
||||
udelay(1);
|
||||
|
||||
_desired_time_to_elapse_us--;
|
||||
if (_desired_time_to_elapse_us > 0)
|
||||
return(COMMONERR_OK);
|
||||
|
||||
return(COMMONERR_FAILED);
|
||||
}
|
||||
|
||||
commonErr_t CMB_regRead(uint32_t offset, uint32_t *data)
|
||||
{
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_regWrite(uint32_t offset, uint32_t data)
|
||||
{
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_memRead(uint32_t offset, uint32_t *data, uint32_t len)
|
||||
{
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
|
||||
commonErr_t CMB_memWrite(uint32_t offset, uint32_t *data, uint32_t len)
|
||||
{
|
||||
return(COMMONERR_OK);
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
/**
|
||||
* \file common.h
|
||||
* \brief Contains type definitions and prototype declarations for common.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* \page Disclaimer Legal Disclaimer
|
||||
* Copyright 2015-2017 Analog Devices Inc.
|
||||
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _COMMON_H_
|
||||
#define _COMMON_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* build project settings include the path to the desired platform folder for correct includes */
|
||||
#include "stdint.h"
|
||||
|
||||
#define THROW_ERROR()
|
||||
|
||||
#define SPIARRAYSIZE 1024
|
||||
|
||||
/* assuming 3 byte SPI message - integer math enforces floor() */
|
||||
#define SPIARRAYTRIPSIZE ((SPIARRAYSIZE / 3) * 3)
|
||||
|
||||
/*========================================
|
||||
* Enums and structures
|
||||
*=======================================*/
|
||||
/* proposed to increase number of error return values to make unique for each return */
|
||||
typedef enum
|
||||
{
|
||||
ADIERR_OK=0,
|
||||
ADIERR_INV_PARM,
|
||||
ADIERR_FAILED
|
||||
} ADI_ERR;
|
||||
|
||||
/*!< \brief COMMON layer error reporting enumerated types */
|
||||
typedef enum
|
||||
{
|
||||
COMMONERR_OK=0,
|
||||
COMMONERR_FAILED
|
||||
} commonErr_t;
|
||||
|
||||
/* bit 0 is MESSAGE, bit 1 is WARNING, bit 2 is ERROR */
|
||||
typedef enum
|
||||
{
|
||||
ADIHAL_LOG_NONE = 0x0,
|
||||
ADIHAL_LOG_MESSAGE = 0x1,
|
||||
ADIHAL_LOG_WARNING = 0x2,
|
||||
ADIHAL_LOG_ERROR = 0x4,
|
||||
ADIHAL_LOG_SPI = 0x8,
|
||||
ADIHAL_LOG_AXI_REG = 0x10,
|
||||
ADIHAL_LOG_AXI_MEM = 0x20,
|
||||
ADIHAL_LOG_ALL = 0x3F
|
||||
} ADI_LOGLEVEL;
|
||||
|
||||
/**
|
||||
* \brief Data structure to hold SPI settings for all system device types
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t chipSelectIndex; ///< valid 1~8
|
||||
uint8_t writeBitPolarity; ///< the level of the write bit of a SPI write instruction word, value is inverted for SPI read operation
|
||||
uint8_t longInstructionWord; ///< 1 = 16bit instruction word, 0 = 8bit instruction word
|
||||
uint8_t MSBFirst; ///< 1 = MSBFirst, 0 = LSBFirst
|
||||
uint8_t CPHA; ///< clock phase, sets which clock edge the data updates (valid 0 or 1)
|
||||
uint8_t CPOL; ///< clock polarity 0 = clock starts low, 1 = clock starts high
|
||||
uint8_t enSpiStreaming; ///< Not implemented. SW feature to improve SPI throughput.
|
||||
uint8_t autoIncAddrUp; ///< Not implemented. For SPI Streaming, set address increment direction. 1= next addr = addr+1, 0:addr = addr-1
|
||||
uint8_t fourWireMode; ///< 1: Use 4-wire SPI, 0: 3-wire SPI (SDIO pin is bidirectional). NOTE: ADI's FPGA platform always uses 4-wire mode.
|
||||
uint32_t spiClkFreq_Hz; ///< SPI Clk frequency in Hz (default 25000000), platform will use next lowest frequency that it's baud rate generator can create */
|
||||
|
||||
} spiSettings_t;
|
||||
|
||||
/* global variable so application layer can set the log level */
|
||||
extern ADI_LOGLEVEL CMB_LOGLEVEL;
|
||||
extern struct spi_desc *spi_ad_desc;
|
||||
extern struct gpio_desc *gpio_ad9371_resetb;
|
||||
extern struct gpio_desc *gpio_ad9528_resetb;
|
||||
extern struct gpio_desc *gpio_ad9528_sysref_req;
|
||||
|
||||
/* initialize hardware platform */
|
||||
commonErr_t CMB_initPlatform(void);
|
||||
|
||||
/* close hardware pointers */
|
||||
commonErr_t CMB_closeHardware(void);
|
||||
|
||||
/* GPIO function */
|
||||
commonErr_t CMB_setGPIO(uint32_t GPIO);
|
||||
|
||||
/* hardware reset function */
|
||||
commonErr_t CMB_hardReset(uint8_t spiChipSelectIndex);
|
||||
|
||||
/* SPI read/write functions */
|
||||
commonErr_t CMB_setSPIOptions(spiSettings_t *spiSettings); /* allows the platform HAL to work with devices with various SPI settings */
|
||||
commonErr_t CMB_setSPIChannel(uint16_t chipSelectIndex ); /* value of 0 deasserts all chip selects */
|
||||
commonErr_t CMB_SPIWriteByte(spiSettings_t *spiSettings, uint16_t addr, uint8_t data); /* single SPI byte write function */
|
||||
commonErr_t CMB_SPIWriteBytes(spiSettings_t *spiSettings, uint16_t *addr, uint8_t *data, uint32_t count);
|
||||
commonErr_t CMB_SPIReadByte (spiSettings_t *spiSettings, uint16_t addr, uint8_t *readdata); /* single SPI byte read function */
|
||||
commonErr_t CMB_SPIWriteField(spiSettings_t *spiSettings, uint16_t addr, uint8_t field_val, uint8_t mask, uint8_t start_bit); /* write a field in a single register */
|
||||
commonErr_t CMB_SPIReadField (spiSettings_t *spiSettings, uint16_t addr, uint8_t *field_val, uint8_t mask, uint8_t start_bit); /* read a field in a single register */
|
||||
|
||||
/* platform timer functions */
|
||||
commonErr_t CMB_wait_ms(uint32_t time_ms);
|
||||
commonErr_t CMB_wait_us(uint32_t time_us);
|
||||
commonErr_t CMB_setTimeout_ms(uint32_t timeOut_ms);
|
||||
commonErr_t CMB_setTimeout_us(uint32_t timeOut_us);
|
||||
commonErr_t CMB_hasTimeoutExpired();
|
||||
|
||||
/* platform logging functions */
|
||||
commonErr_t CMB_openLog(const char *filename);
|
||||
commonErr_t CMB_closeLog(void);
|
||||
commonErr_t CMB_writeToLog(ADI_LOGLEVEL level, uint8_t deviceIndex, uint32_t errorCode, const char *comment);
|
||||
commonErr_t CMB_flushLog(void);
|
||||
|
||||
/* platform FPGA AXI register read/write functions */
|
||||
commonErr_t CMB_regRead(uint32_t offset, uint32_t *data);
|
||||
commonErr_t CMB_regWrite(uint32_t offset, uint32_t data);
|
||||
|
||||
/* platform DDR3 memory read/write functions */
|
||||
commonErr_t CMB_memRead(uint32_t offset, uint32_t *data, uint32_t len);
|
||||
commonErr_t CMB_memWrite(uint32_t offset, uint32_t *data, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,348 +0,0 @@
|
||||
/*
|
||||
* headless.h
|
||||
*
|
||||
* Created on: 2021Äê6ÔÂ8ÈÕ
|
||||
* Author: Josh
|
||||
*/
|
||||
|
||||
#ifndef SRC_HEADLESS_H_
|
||||
#define SRC_HEADLESS_H_
|
||||
|
||||
/***************************** Include Files ********************************/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "xil_cache.h"
|
||||
#include "xscugic.h"
|
||||
//#include "xgpio.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "./mykonos/ad9528.h"
|
||||
#include "./mykonos/mykonos.h"
|
||||
#include "./mykonos/Mykonos_M3.h"
|
||||
#include "./mykonos/mykonos_gpio.h"
|
||||
#include "myk_ad9528init.h"
|
||||
#include "myk_init.h"
|
||||
|
||||
#include "parameters.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* This function setups ad9528 and ad9371 via spi.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return
|
||||
* - ADIERR_FAILED if successful,
|
||||
* - ADIERR_OK if not succesful
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int HARDWARE_initialize();
|
||||
|
||||
int HARDWARE_ad9371Config(void);
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Setup up Axi Gpio, through which ad9371 can be reconfigured. Axi Gpio
|
||||
* instance and interrupt system initialization are included.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return
|
||||
* - ADIERR_FAILED if successful,
|
||||
* - ADIERR_OK if not succesful
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int HW_ad9371DynamicCfgInit(void);
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Setup up interrupt system, initialize exception handlers.
|
||||
*
|
||||
* @param DeviceId is the unique identifier for a device.
|
||||
* @param GicPtr is a pointer to the XScuGic instance.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful,
|
||||
* - XST_FAILURE if not succesful
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int HW_setupIntrSystem(u16 DeviceId, XScuGic * GicPtr);
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Make the connection between the Int_Id of the interrupt source and the
|
||||
* associated handler. Set the interrupt priority and trigger type for the
|
||||
* specified IRQ source..
|
||||
*
|
||||
* @param GicPtr is a pointer to the XScuGic instance.
|
||||
* @param Int_Id contains the ID of the interrupt source and should be
|
||||
* in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
|
||||
* @param Handler to the handler for that interrupt.
|
||||
* @param CallBackRef is the callback reference, usually the instance
|
||||
* pointer of the connecting driver.
|
||||
* @param Priority is the new priority for the IRQ source. 0 is highest
|
||||
* priority, 0xF8(248) is lowest. There are 32 priority levels
|
||||
* supported with a step of 8. Hence the supported priorities are
|
||||
* 0, 8, 16, 32, 40 ..., 248.
|
||||
* @param Trigger is the new trigger type for the IRQ source.
|
||||
* Each bit pair describes the configuration for an INT_ID.
|
||||
* SFI Read Only b10 always
|
||||
* PPI Read Only depending on how the PPIs are configured.
|
||||
* b01 Active HIGH level sensitive
|
||||
* b11 Rising edge sensitive
|
||||
* SPI LSB is read only.
|
||||
* b01 Active HIGH level sensitive
|
||||
* b11 Rising edge sensitive/
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful,
|
||||
* - XST_FAILURE if not succesful
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int HW_connectIntr(XScuGic *GicPtr,u32 IntrId,Xil_InterruptHandler Handler,
|
||||
void *CallBackRef, u8 Priority, u8 Trigger);
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Initialize Analog Device related configuration profile. This is a HARDWARE-
|
||||
* ASSOTIATED function, which may differ between different board.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return
|
||||
* - ADIERR_OK if configuration profile exists,
|
||||
* - ADIERR_FAILED if onfiguration profile does not exist
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int HW_adiCfgProfileInit(void);
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function conducts AD9528 device configuration initializing procedure.
|
||||
*
|
||||
* @param clockAD9528_device is a pointer to the data structure holding
|
||||
* AD9528 settings, which contains basic AD9528 settings such as
|
||||
* spi and gpio.
|
||||
*
|
||||
* @return
|
||||
* - ADIERR_OK if successful.
|
||||
* - ADIERR_FAILED if not successful.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
int HW_9528Config(ad9528Device_t *clockAD9528_device);
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function read AD9528 reg508 status, to check whether ad9528 is locked or
|
||||
* not.
|
||||
*
|
||||
* @param clockAD9528_device is a pointer to the data structure holding
|
||||
* AD9528 settings, which contains basic AD9528 settings.
|
||||
*
|
||||
* @return
|
||||
* - ADIERR_OK if successful.
|
||||
* - ADIERR_FAILED if not successful.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
int HW_9528GetLockStatus(ad9528Device_t *device, uint8_t *reg508);
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Conduct AD9371 device configuration initializing procedure.
|
||||
*
|
||||
* @param clockAD9528_device is a pointer to the data structure holding
|
||||
* AD9528 settings, which contains basic AD9528 settings.
|
||||
* @param mykDevice is ADI hardware layer settings pointer specific to
|
||||
* a Mykonos instance which contains basic settings such as spi,
|
||||
* gpio, tx/rx and jesd configurations.
|
||||
*
|
||||
* @return
|
||||
* - ADIERR_OK if successful.
|
||||
* - ADIERR_FAILED if not successful.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice);
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read AD9371's RX framer, ORX framer and TX deframer status, to check jesd204b
|
||||
* sync status.
|
||||
*
|
||||
* @param mykDevice is ADI hardware layer settings pointer specific to
|
||||
* a Mykonos instance which contains basic settings such as spi,
|
||||
* gpio, tx/rx and jesd configurations.
|
||||
* @param framerStatus is the RX framer status byte read
|
||||
* framerStatus | Description
|
||||
* -------------|-----------------------------------------------------------------------------
|
||||
* [7] | SYSREF phase error ? a new SYSREF had different timing than the first that set the LMFC timing.
|
||||
* [6] | Framer lane FIFO read/write pointer delta has changed. Can help debug issues with deterministic latency.
|
||||
* [5] | Framer has received the SYSREF and has retimed its LMFC
|
||||
* [4:2] | Framer ILAS state: 0=CGS, 1= 1st Multframe, 2= 2nd Multiframe, 3= 3rd Multiframe, 4= 4th multiframe, 5= Last multiframe, 6=invalid, 7= ILAS complete
|
||||
* [1:0] | Framer Tx state: 0=CGS, 1= ILAS, 2 = ADC Data
|
||||
* @param obsFramerStatus is the ORX framer status byte read
|
||||
* obsFramerStatus | Description
|
||||
* ----------------|-----------------------------------------------------------------------------
|
||||
* [7] | SYSREF phase error ? a new SYSREF had different timing than the first that set the LMFC timing.
|
||||
* [6] | Framer lane FIFO read/write pointer delta has changed. Can help debug issues with deterministic latency.
|
||||
* [5] | Framer has received the SYSREF and has retimed its LMFC
|
||||
* [4:2] | Framer ILAS state: 0=CGS, 1= 1st Multframe, 2= 2nd Multiframe, 3= 3rd Multiframe, 4= 4th multiframe, 5= Last multiframe, 6=invalid, 7= ILAS complete
|
||||
* [1:0] | Framer Tx state: 0=CGS, 1= ILAS, 2 = ADC Data
|
||||
* @param deframerStatus is the TX deframer status byte read
|
||||
* deframerStatus | Bit Name | Description
|
||||
* ----------------|--------------------------|---------------------------------------------
|
||||
* [7] | Unused | Unused
|
||||
* [6] | Deframer IRQ | This bit indicates that the IRQ interrupt was asserted.
|
||||
* [5] | Deframer SYSREF Received | When this bit is set, it indicates that the SYSREF pulse was received by the deframer IP
|
||||
* [4] | Deframer Receiver Error | This bit is set when PRBS has received an error.
|
||||
* [3] | Valid Checksum | This bit is set when the received ILAS checksum is valid.
|
||||
* [2] | EOF Event | This bit captures the internal status of the framer End of Frame event. Value =1 if framing error during ILAS
|
||||
* [1] | EOMF Event | This bit captures the internal status of the framer End of Multi-Frame event. Value =1 if framing error during ILAS
|
||||
* [0] | FS Lost | This bit captures the internal status of the framer Frame Symbol event. Value =1 if framing error during ILAS or user data (invalid replacement characters)
|
||||
*
|
||||
* @return
|
||||
* - ADIERR_OK if successful.
|
||||
* - ADIERR_FAILED if not successful.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
int HW_9371CheckJesdStatus(mykonosDevice_t *mykDevice, uint8_t *framerStatus,
|
||||
uint8_t *obsFramerStatus, uint8_t *deframerStatus);
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function conducts AD9371/9375 samll RF PLL frequcny change procedure. The
|
||||
* procedure is performed as follows:
|
||||
* 1. Move the device into the radio off state.
|
||||
* 2. Program the new local oscillator (LO) frequency.
|
||||
* 3. Reset the external channel.(ignored)
|
||||
* 4. Move the device back into the radio on state.
|
||||
* 5. Reenable tracking calibrations.(ignored)
|
||||
*
|
||||
* @param mykDevice is ADI hardware layer settings pointer specific to
|
||||
* a Mykonos instance which contains basic settings such as spi,
|
||||
* gpio, tx/rx and jesd configurations.
|
||||
* @param freq_Hz is the target frequancy in Hz.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note The procedure is used when a radio frequency (RF) phased-lock loop
|
||||
* (PLL) change is required with the following conditions:
|
||||
* - A desire to change the Rx, Tx, and ORx frequencies.
|
||||
* - The frequency step change is less than 100 MHz.
|
||||
* - The frequency step does not cross the divide by 2 boundaries outlined
|
||||
* in AD9371/9375-UG-992-Rev.B-Table 96.
|
||||
*
|
||||
*******************************************************************************/
|
||||
int HW_9371SmallFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz);
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function conducts AD9371/9375 large RF PLL frequcny change procedure. The
|
||||
* procedure is performed as follows:
|
||||
* 1. Move the device into the radio off state.
|
||||
* 2. Program the new local oscillator (LO) frequency.
|
||||
* 3. Rerun the initialization calibrations.
|
||||
* 4. Move the device back into the radio on state.
|
||||
* 5. Reenable tracking calibrations.(ignored)
|
||||
*
|
||||
* @param mykDevice is ADI hardware layer settings pointer specific to
|
||||
* a Mykonos instance which contains basic settings such as spi,
|
||||
* gpio, tx/rx and jesd configurations.
|
||||
* @param freq_Hz is the target frequancy in Hz.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note The procedure is used when a radio frequency (RF) phased-lock loop
|
||||
* (PLL) change is required with the following conditions:
|
||||
* - A desire to change the Rx, Tx, and ORx frequencies.
|
||||
* - The frequency step change is more than 100 MHz.
|
||||
* - The frequency step does cross the divide by 2 boundaries outlined
|
||||
* in AD9371/9375-UG-992-Rev.B-Table 96.
|
||||
*
|
||||
*******************************************************************************/
|
||||
int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz);
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Handles AD9371 TX & RX frequency change axi gpio interruput.
|
||||
*
|
||||
* @param CallBackRef is the callback reference, usually the instance
|
||||
* pointer of the connecting driver.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
void FreqIntrHandler(void *CallbackRef);
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Handles AD9371 Rx gain index change axi gpio interruput.
|
||||
*
|
||||
* @param CallBackRef is the callback reference, usually the instance
|
||||
* pointer of the connecting driver.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
void GainIntrHandler(void *CallbackRef);
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Handles AD9371 Tx attenuation change axi gpio interruput.
|
||||
*
|
||||
* @param CallBackRef is the callback reference, usually the instance
|
||||
* pointer of the connecting driver.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
void AttnIntrHandler(void *CallbackRef);
|
||||
|
||||
#endif /* SRC_HEADLESS_H_ */
|
||||
@@ -1,189 +0,0 @@
|
||||
///*
|
||||
// * myk_clock_init.c
|
||||
// *
|
||||
// */
|
||||
//
|
||||
///**
|
||||
//* \page Disclaimer Legal Disclaimer
|
||||
//* Copyright 2015-2017 Analog Devices Inc.
|
||||
//* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
|
||||
//*
|
||||
//*/
|
||||
//
|
||||
//#ifndef MYK_CLOCK_INIT_C_
|
||||
//#define MYK_CLOCK_INIT_C_
|
||||
//#include <stdint.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <stddef.h>
|
||||
//#include "common.h"
|
||||
//
|
||||
//#include "ad9528.h"
|
||||
//#include "t_ad9528.h"
|
||||
//#include "myk_ad9528init.h"
|
||||
//#include "parameters.h"
|
||||
//
|
||||
//static ad9528pll1Settings_t clockPll1Settings =
|
||||
//{
|
||||
// .refA_Frequency_Hz = 30720000,
|
||||
// .refA_Divider = 1,
|
||||
// .refA_bufferCtrl = DISABLED,
|
||||
// .refB_Frequency_Hz = 0,
|
||||
// .refB_Divider = 1,
|
||||
// .refB_bufferCtrl = DISABLED,
|
||||
// .vcxo_Frequency_Hz = 122880000,
|
||||
// .vcxoBufferCtrl = NEG_SINGLE_ENDED,
|
||||
// .nDivider = 4,
|
||||
// .bypassPll1 = 0
|
||||
//};
|
||||
//
|
||||
//static ad9528pll2Settings_t clockPll2Settings =
|
||||
//{
|
||||
// .rfDivider = 4,
|
||||
// .n2Divider = 10,
|
||||
// .totalNdiv = 30
|
||||
//};
|
||||
//
|
||||
//static ad9528outputSettings_t clockOutputSettings =
|
||||
//{
|
||||
// .outPowerDown = 53237, // 0xCFF5
|
||||
// .outSource = {
|
||||
// CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV, SYSREF,
|
||||
// CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV,
|
||||
// CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV,
|
||||
// SYSREF, CHANNEL_DIV},
|
||||
// .outBufferCtrl = {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
// .outAnalogDelay = {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
// .outDigitalDelay = {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
// .outChannelDiv = {10,10,10,10,10,10,10,10,10,10,10,10,10,10},
|
||||
// .outFrequency_Hz = {122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000}
|
||||
//};
|
||||
//
|
||||
//static ad9528sysrefSettings_t clockSysrefSettings =
|
||||
//{
|
||||
// .sysrefRequestMethod = PIN,
|
||||
// .sysrefSource = INTERNAL,
|
||||
// .sysrefPinEdgeMode = LEVEL_ACTIVE_HIGH,
|
||||
// .sysrefPinBufferMode = DISABLED,
|
||||
// .sysrefPatternMode = NSHOT,
|
||||
// .sysrefNshotMode = ONE_PULSE,
|
||||
// .sysrefDivide = 512
|
||||
//};
|
||||
//
|
||||
//static spiSettings_t clockSpiSettings =
|
||||
//{
|
||||
// .chipSelectIndex = AD9528_CS, //chip select Index
|
||||
// .writeBitPolarity = 0, //Write bit polarity
|
||||
// .longInstructionWord = 1, //16bit instruction word
|
||||
// .MSBFirst = 1, //MSB first
|
||||
// .CPHA = 0, //Clock phase
|
||||
// .CPOL = 0, //Clock polarity
|
||||
// .enSpiStreaming = 0, //uint8_t enSpiStreaming;
|
||||
// .autoIncAddrUp = 1, //uint8_t autoIncAddrUp;
|
||||
// .fourWireMode = 1 //uint8_t fourWireMode;
|
||||
//};
|
||||
//
|
||||
//ad9528Device_t clockAD9528_ =
|
||||
//{
|
||||
// &clockSpiSettings,
|
||||
// &clockPll1Settings,
|
||||
// &clockPll2Settings,
|
||||
// &clockOutputSettings,
|
||||
// &clockSysrefSettings
|
||||
//};
|
||||
//
|
||||
//ad9528Device_t *ad9528Init = &clockAD9528_;
|
||||
//
|
||||
//#endif /* MYK_CLOCK_INIT_C_ */
|
||||
|
||||
|
||||
/* AD9528 data structure initialization file */
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include "common.h"
|
||||
|
||||
#include "./mykonos/ad9528.h"
|
||||
#include "./mykonos/t_ad9528.h"
|
||||
#include "myk_ad9528init.h"
|
||||
#include "parameters.h"
|
||||
|
||||
static ad9528pll1Settings_t clockPll1Settings = {
|
||||
.refA_Frequency_Hz = 122880000,
|
||||
.refA_Divider = 1,
|
||||
.refA_bufferCtrl = SINGLE_ENDED,
|
||||
.refB_Frequency_Hz = 0,
|
||||
.refB_Divider = 1,
|
||||
.refB_bufferCtrl = DISABLED,
|
||||
.vcxo_Frequency_Hz = 122880000,
|
||||
.vcxoBufferCtrl = DIFFERENTIAL,
|
||||
.nDivider = 1,
|
||||
.bypassPll1 = 0
|
||||
};
|
||||
|
||||
static ad9528pll2Settings_t clockPll2Settings = {
|
||||
.rfDivider = 3,
|
||||
.n2Divider = 10,
|
||||
.totalNdiv = 30
|
||||
};
|
||||
|
||||
/*******************************************************************
|
||||
* Output Distribution Settings
|
||||
* 9369CE02A uses the following clock outputs
|
||||
* OUT 1: FPGA_REF_CLK
|
||||
* OUT 2: FPGA_AUX_CLK
|
||||
* OUT 3: FPGA_SYSREF
|
||||
* OUT 12: SYSREF_IN
|
||||
* OUT 13: DEV_CLK_IN
|
||||
*******************************************************************
|
||||
*/
|
||||
static ad9528outputSettings_t clockOutputSettings = {
|
||||
.outPowerDown = 0x0,
|
||||
.outSource = {
|
||||
SYSREF, SYSREF, CHANNEL_DIV, SYSREF,
|
||||
CHANNEL_DIV, CHANNEL_DIV, SYSREF, SYSREF,
|
||||
CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV,
|
||||
SYSREF , CHANNEL_DIV
|
||||
},
|
||||
.outBufferCtrl = {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
.outAnalogDelay = {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
.outDigitalDelay = {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
.outChannelDiv = {10,10,10,10,10,10,10,10,10,10,10,10,10,10},
|
||||
.outFrequency_Hz = {
|
||||
122880000, 122880000, 122880000, 122880000,
|
||||
122880000, 122880000, 122880000, 122880000,
|
||||
122880000, 122880000, 122880000, 122880000,
|
||||
122880000, 122880000
|
||||
}
|
||||
};
|
||||
|
||||
static ad9528sysrefSettings_t clockSysrefSettings = {
|
||||
.sysrefRequestMethod = SPI,
|
||||
.sysrefSource = INTERNAL,
|
||||
.sysrefPinEdgeMode = LEVEL_ACTIVE_HIGH,
|
||||
.sysrefPinBufferMode = DISABLED,
|
||||
.sysrefPatternMode = CONTINUOUS,
|
||||
.sysrefNshotMode = FOUR_PULSES,
|
||||
.sysrefDivide = 512
|
||||
};
|
||||
|
||||
static spiSettings_t clockSpiSettings = {
|
||||
.chipSelectIndex = 2, //chip select Index
|
||||
.writeBitPolarity = 0, //Write bit polarity
|
||||
.longInstructionWord = 1, //16bit instruction word
|
||||
.MSBFirst = 1, //MSB first
|
||||
.CPHA = 0, //Clock phase
|
||||
.CPOL = 0, //Clock polarity
|
||||
.enSpiStreaming = 0, //uint8_t enSpiStreaming;
|
||||
.autoIncAddrUp = 1, //uint8_t autoIncAddrUp;
|
||||
.fourWireMode = 1 //uint8_t fourWireMode;
|
||||
};
|
||||
|
||||
ad9528Device_t clockAD9528_ = {
|
||||
&clockSpiSettings,
|
||||
&clockPll1Settings,
|
||||
&clockPll2Settings,
|
||||
&clockOutputSettings,
|
||||
&clockSysrefSettings
|
||||
};
|
||||
|
||||
ad9528Device_t *ad9528Init = &clockAD9528_;
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* myk_clock_init.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \page Disclaimer Legal Disclaimer
|
||||
* Copyright 2015-2017 Analog Devices Inc.
|
||||
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MYK_CLOCK_INIT_H_
|
||||
#define MYK_CLOCK_INIT_H_
|
||||
|
||||
#include "./mykonos/ad9528.h"
|
||||
|
||||
extern ad9528Device_t *ad9528Init;
|
||||
|
||||
#endif /* MYK_CLOCK_INIT_H_ */
|
||||
@@ -1,558 +0,0 @@
|
||||
/**
|
||||
* \file myk_init.c
|
||||
*
|
||||
* \brief Contains init setting structure declarations for the _instance API
|
||||
*
|
||||
* The top level structure mykonosDevice_t mykDevice uses keyword
|
||||
* extern to allow the application layer main() to have visibility
|
||||
* to these settings.
|
||||
*
|
||||
* All data structures required for operation have been initialized with values which reflect
|
||||
* these settings:
|
||||
*
|
||||
* Device Clock = $122.88$ Mhz
|
||||
* Rx enabled channels = $2$
|
||||
* Tx enabled channels = $2$
|
||||
*
|
||||
* Mykonos Framer:
|
||||
* Lane Rate = $4915.2$ Mbs
|
||||
* L = $2$
|
||||
* K = $32$
|
||||
* M = $4$
|
||||
* F = $4$
|
||||
*
|
||||
* Mykonos Deframer:
|
||||
* Lane Rate = $4915.2$ Mbs
|
||||
* L = $2$
|
||||
* K = $32$
|
||||
* M = $4$
|
||||
* F = $4$
|
||||
*
|
||||
* Mykonos Observation framer:
|
||||
* Lane Rate = $4915.2$ Mbs
|
||||
* L = $2$
|
||||
* K = $32$
|
||||
* M = $4$
|
||||
* F = $4$
|
||||
*
|
||||
* Using these profiles:
|
||||
* $Rx 100Mhz, IQrate 122.88Mhz, Dec5$
|
||||
* $Tx 100/100Mhz, IQrate 122.88Mhz, Dec5$
|
||||
* $ORX 100Mhz, IQrate 122.88Mhz, Dec5$
|
||||
* $SRx 20Mhz, IQrate 30.72Mhz, Dec5$
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \page Disclaimer Legal Disclaimer
|
||||
* Copyright 2015-2017 Analog Devices Inc.
|
||||
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "./mykonos/t_mykonos.h"
|
||||
#include "myk_init.h"
|
||||
#include "parameters.h"
|
||||
#include "./mykonos/mykonos_gpio.h"
|
||||
|
||||
static int16_t txFirCoefs[] = {-94,-26,282,177,-438,-368,756,732,-1170,-1337,1758,2479,-2648,-5088,4064,16760,16759,4110,-4881,-2247,2888,1917,-1440,-1296,745,828,-358,-474,164,298,-16,-94};
|
||||
|
||||
static mykonosFir_t txFir =
|
||||
{
|
||||
6, /* Filter gain in dB*/
|
||||
32, /* Number of coefficients in the FIR filter*/
|
||||
&txFirCoefs[0] /* A pointer to an array of filter coefficients*/
|
||||
};
|
||||
|
||||
static int16_t rxFirCoefs[] = {-20,6,66,22,-128,-54,240,126,-402,-248,634,444,-956,-756,1400,1244,-2028,-2050,2978,3538,-4646,-7046,9536,30880,30880,9536,-7046,-4646,3538,2978,-2050,-2028,1244,1400,-756,-956,444,634,-248,-402,126,240,-54,-128,22,66,6,-20};
|
||||
|
||||
static mykonosFir_t rxFir =
|
||||
{
|
||||
-6, /* Filter gain in dB*/
|
||||
48, /* Number of coefficients in the FIR filter*/
|
||||
&rxFirCoefs[0] /* A pointer to an array of filter coefficients*/
|
||||
};
|
||||
|
||||
static int16_t obsrxFirCoefs[] = {-14,-19,44,41,-89,-95,175,178,-303,-317,499,527,-779,-843,1184,1317,-1781,-2059,2760,3350,-4962,-7433,9822,32154,32154,9822,-7433,-4962,3350,2760,-2059,-1781,1317,1184,-843,-779,527,499,-317,-303,178,175,-95,-89,41,44,-19,-14};
|
||||
static mykonosFir_t obsrxFir =
|
||||
{
|
||||
-6, /* Filter gain in dB*/
|
||||
48, /* Number of coefficients in the FIR filter*/
|
||||
&obsrxFirCoefs[0]/* A pointer to an array of filter coefficients*/
|
||||
};
|
||||
|
||||
static int16_t snifferFirCoefs[] = {-1,-5,-14,-23,-16,24,92,137,80,-120,-378,-471,-174,507,1174,1183,98,-1771,-3216,-2641,942,7027,13533,17738,17738,13533,7027,942,-2641,-3216,-1771,98,1183,1174,507,-174,-471,-378,-120,80,137,92,24,-16,-23,-14,-5,-1};
|
||||
static mykonosFir_t snifferRxFir=
|
||||
{
|
||||
-6, /* Filter gain in dB*/
|
||||
48, /* Number of coefficients in the FIR filter*/
|
||||
&snifferFirCoefs[0]/* A pointer to an array of filter coefficients*/
|
||||
};
|
||||
|
||||
static mykonosJesd204bFramerConfig_t rxFramer =
|
||||
{
|
||||
0, /* JESD204B Configuration Bank ID -extension to Device ID (Valid 0..15)*/
|
||||
0, /* JESD204B Configuration Device ID - link identification number. (Valid 0..255)*/
|
||||
0, /* JESD204B Configuration starting Lane ID. If more than one lane used, each lane will increment from the Lane0 ID. (Valid 0..31)*/
|
||||
4, /* number of ADCs (0, 2, or 4) - 2 ADCs per receive chain*/
|
||||
32, /* number of frames in a multiframe (default=32), F*K must be a multiple of 4. (F=2*M/numberOfLanes)*/
|
||||
0, /* scrambling off if framerScramble= 0, if framerScramble>0 scramble is enabled.*/
|
||||
1, /* 0=use internal SYSREF, 1= use external SYSREF*/
|
||||
0x03, /* serializerLanesEnabled - bit per lane, [0] = Lane0 enabled, [1] = Lane1 enabled*/
|
||||
0xE4, /* serializerLaneCrossbar*/
|
||||
22, /* serializerAmplitude - default 22 (valid (0-31)*/
|
||||
4, /* preEmphasis - < default 4 (valid 0 - 7)*/
|
||||
0, /* invertLanePolarity - default 0 ([0] will invert lane [0], bit1 will invert lane1)*/
|
||||
0, /* lmfcOffset - LMFC_Offset offset value for deterministic latency setting*/
|
||||
0, /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set*/
|
||||
0, /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/
|
||||
0, /* Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer*/
|
||||
0, /* Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/
|
||||
0, /* Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples)*/
|
||||
0 /* Flag for determining if API will calculate the appropriate settings for framer lane outputs to physical lanes. Where, if '0' = API will set automatic lane crossbar, '1' = set to manual mode and the value in serializerLaneCrossbar will be used*/
|
||||
};
|
||||
|
||||
static mykonosJesd204bFramerConfig_t obsRxFramer =
|
||||
{
|
||||
0, /* JESD204B Configuration Bank ID -extension to Device ID (Valid 0..15)*/
|
||||
0, /* JESD204B Configuration Device ID - link identification number. (Valid 0..255)*/
|
||||
0, /* JESD204B Configuration starting Lane ID. If more than one lane used, each lane will increment from the Lane0 ID. (Valid 0..31)*/
|
||||
2, /* number of ADCs (0, 2, or 4) - 2 ADCs per receive chain*/
|
||||
32, /* number of frames in a multiframe (default=32), F*K must be a multiple of 4. (F=2*M/numberOfLanes)*/
|
||||
0, /* scrambling off if framerScramble= 0, if framerScramble>0 scramble is enabled.*/
|
||||
1, /* 0=use internal SYSREF, 1= use external SYSREF*/
|
||||
0x04, /* serializerLanesEnabled - bit per lane, [0] = Lane0 enabled, [1] = Lane1 enabled*/
|
||||
0xE4, /* Lane crossbar to map framer lane outputs to physical lanes*/
|
||||
22, /* serializerAmplitude - default 22 (valid (0-31)*/
|
||||
4, /* preEmphasis - < default 4 (valid 0 - 7)*/
|
||||
0, /* invertLanePolarity - default 0 ([0] will invert lane [0], bit1 will invert lane1)*/
|
||||
0, /* lmfcOffset - LMFC_Offset offset value for deterministic latency setting*/
|
||||
0, /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set*/
|
||||
0, /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/
|
||||
1, /* Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer*/
|
||||
0, /* Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/
|
||||
0, /* Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples)*/
|
||||
0 /* Flag for determining if API will calculate the appropriate settings for framer lane outputs to physical lanes. Where, if '0' = API will set automatic lane crossbar, '1' = set to manual mode and the value in serializerLaneCrossbar will be used*/
|
||||
};
|
||||
|
||||
static mykonosJesd204bDeframerConfig_t deframer =
|
||||
{
|
||||
0, /* bankId extension to Device ID (Valid 0..15)*/
|
||||
0, /* deviceId link identification number. (Valid 0..255)*/
|
||||
0, /* lane0Id Lane0 ID. (Valid 0..31)*/
|
||||
4, /* M number of DACss (0, 2, or 4) - 2 DACs per transmit chain */
|
||||
32, /* K #frames in a multiframe (default=32), F*K=multiple of 4. (F=2*M/numberOfLanes)*/
|
||||
0, /* scramble scrambling off if scramble= 0.*/
|
||||
1, /* External SYSREF select. 0 = use internal SYSREF, 1 = external SYSREF*/
|
||||
0x03, /* Deserializer lane select bit field. Where, [0] = Lane0 enabled, [1] = Lane1 enabled, etc */
|
||||
0xE4, /* Lane crossbar to map physical lanes to deframer lane inputs [1:0] = Deframer Input 0 Lane section, [3:2] = Deframer Input 1 lane select, etc */
|
||||
1, /* Equalizer setting. Applied to all deserializer lanes. Range is 0..4*/
|
||||
0, /* PN inversion per each lane. bit[0] = 1 Invert PN of Lane 0, bit[1] = Invert PN of Lane 1, etc).*/
|
||||
0, /* LMFC_Offset offset value to adjust deterministic latency. Range is 0..31*/
|
||||
0, /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, '0' = not set*/
|
||||
0, /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/
|
||||
0, /* Flag for determining if CMOS mode for TX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/
|
||||
0 /* Flag for determining if API will calculate the appropriate settings for deframer lane in to physical lanes. Where, if '0' = API will set automatic lane crossbar, '1' = set to manual mode and the value in deserializerLaneCrossbar will be used*/
|
||||
};
|
||||
|
||||
static mykonosRxGainControl_t rxGainControl =
|
||||
{
|
||||
MGC, /* Current Rx gain control mode setting*/
|
||||
255, /* Rx1 Gain Index, can be used in different ways for manual and AGC gain control*/
|
||||
255, /* Rx2 Gain Index, can be used in different ways for manual and AGC gain control*/
|
||||
255, /* Max gain index for the currently loaded Rx1 Gain table*/
|
||||
195, /* Min gain index for the currently loaded Rx1 Gain table*/
|
||||
255, /* Max gain index for the currently loaded Rx2 Gain table*/
|
||||
195, /* Min gain index for the currently loaded Rx2 Gain table*/
|
||||
0, /* Stores Rx1 RSSI value read back from the Mykonos*/
|
||||
0 /* Stores Rx2 RSSI value read back from the Mykonos*/
|
||||
};
|
||||
|
||||
|
||||
static mykonosORxGainControl_t orxGainControl =
|
||||
{
|
||||
MGC, /* Current ORx gain control mode setting*/
|
||||
255, /* ORx1 Gain Index, can be used in different ways for manual and AGC gain control*/
|
||||
255, /* ORx2 Gain Index, can be used in different ways for manual and AGC gain control*/
|
||||
255, /* Max gain index for the currently loaded ORx Gain table*/
|
||||
237 /* Min gain index for the currently loaded ORx Gain table*/
|
||||
};
|
||||
|
||||
static mykonosSnifferGainControl_t snifferGainControl =
|
||||
{
|
||||
MGC, /* Current Sniffer gain control mode setting*/
|
||||
255, /* Current Sniffer gain index. Can be used differently for MANUAL Gain control/AGC*/
|
||||
255, /* Max gain index for the currently loaded Sniffer Gain table*/
|
||||
203 /* Min gain index for the currently loaded Sniffer Gain table*/
|
||||
};
|
||||
|
||||
static mykonosPeakDetAgcCfg_t rxPeakAgc =
|
||||
{
|
||||
0x0C, /* apdHighThresh: */
|
||||
0x08, /* apdLowThresh */
|
||||
0xB5, /* hb2HighThresh */
|
||||
0x80, /* hb2LowThresh */
|
||||
0x40, /* hb2VeryLowThresh */
|
||||
0x06, /* apdHighThreshExceededCnt */
|
||||
0x04, /* apdLowThreshExceededCnt */
|
||||
0x06, /* hb2HighThreshExceededCnt */
|
||||
0x04, /* hb2LowThreshExceededCnt */
|
||||
0x04, /* hb2VeryLowThreshExceededCnt */
|
||||
0x4, /* apdHighGainStepAttack */
|
||||
0x2, /* apdLowGainStepRecovery */
|
||||
0x4, /* hb2HighGainStepAttack */
|
||||
0x2, /* hb2LowGainStepRecovery */
|
||||
0x4, /* hb2VeryLowGainStepRecovery */
|
||||
0x1, /* apdFastAttack */
|
||||
0x1, /* hb2FastAttack */
|
||||
0x1, /* hb2OverloadDetectEnable */
|
||||
0x1, /* hb2OverloadDurationCnt */
|
||||
0x1 /* hb2OverloadThreshCnt */
|
||||
};
|
||||
|
||||
static mykonosPowerMeasAgcCfg_t rxPwrAgc =
|
||||
{
|
||||
0x01, /* pmdUpperHighThresh */
|
||||
0x03, /* pmdUpperLowThresh */
|
||||
0x0C, /* pmdLowerHighThresh */
|
||||
0x00, /* pmdLowerLowThresh */
|
||||
0x4, /* pmdUpperHighGainStepAttack */
|
||||
0x2, /* pmdUpperLowGainStepAttack */
|
||||
0x2, /* pmdLowerHighGainStepRecovery */
|
||||
0x4, /* pmdLowerLowGainStepRecovery */
|
||||
0x08, /* pmdMeasDuration */
|
||||
0x02 /* pmdMeasConfig */
|
||||
};
|
||||
|
||||
static mykonosAgcCfg_t rxAgcConfig =
|
||||
{
|
||||
255, /* agcRx1MaxGainIndex */
|
||||
195, /* agcRx1MinGainIndex */
|
||||
255, /* agcRx2MaxGainIndex */
|
||||
195, /* agcRx2MinGainIndex: */
|
||||
255, /* agcObsRxMaxGainIndex */
|
||||
203, /* agcObsRxMinGainIndex */
|
||||
1, /* agcObsRxSelect */
|
||||
1, /* agcPeakThresholdMode */
|
||||
1, /* agcLowThsPreventGainIncrease */
|
||||
30720, /* agcGainUpdateCounter */
|
||||
3, /* agcSlowLoopSettlingDelay */
|
||||
2, /* agcPeakWaitTime */
|
||||
1, /* agcResetOnRxEnable */
|
||||
0, /* agcEnableSyncPulseForGainCounter */
|
||||
&rxPeakAgc,
|
||||
&rxPwrAgc
|
||||
};
|
||||
|
||||
static mykonosPeakDetAgcCfg_t obsRxPeakAgc =
|
||||
{
|
||||
0x1F, /* apdHighThresh: */
|
||||
0x16, /* apdLowThresh */
|
||||
0xB5, /* hb2HighThresh */
|
||||
0x80, /* hb2LowThresh */
|
||||
0x40, /* hb2VeryLowThresh */
|
||||
0x06, /* apdHighThreshExceededCnt */
|
||||
0x04, /* apdLowThreshExceededCnt */
|
||||
0x06, /* hb2HighThreshExceededCnt */
|
||||
0x04, /* hb2LowThreshExceededCnt */
|
||||
0x04, /* hb2VeryLowThreshExceededCnt */
|
||||
0x4, /* apdHighGainStepAttack */
|
||||
0x2, /* apdLowGainStepRecovery */
|
||||
0x4, /* hb2HighGainStepAttack */
|
||||
0x2, /* hb2LowGainStepRecovery */
|
||||
0x4, /* hb2VeryLowGainStepRecovery */
|
||||
0x1, /* apdFastAttack */
|
||||
0x1, /* hb2FastAttack */
|
||||
0x1, /* hb2OverloadDetectEnable */
|
||||
0x1, /* hb2OverloadDurationCnt */
|
||||
0x1 /* hb2OverloadThreshCnt */
|
||||
};
|
||||
|
||||
static mykonosPowerMeasAgcCfg_t obsRxPwrAgc =
|
||||
{
|
||||
0x01, /* pmdUpperHighThresh */
|
||||
0x03, /* pmdUpperLowThresh */
|
||||
0x0C, /* pmdLowerHighThresh */
|
||||
0x00, /* pmdLowerLowThresh */
|
||||
0x4, /* pmdUpperHighGainStepAttack */
|
||||
0x2, /* pmdUpperLowGainStepAttack */
|
||||
0x2, /* pmdLowerHighGainStepRecovery */
|
||||
0x4, /* pmdLowerLowGainStepRecovery */
|
||||
0x08, /* pmdMeasDuration */
|
||||
0x02 /* pmdMeasConfig */
|
||||
};
|
||||
|
||||
static mykonosAgcCfg_t obsRxAgcConfig =
|
||||
{
|
||||
255, /* agcRx1MaxGainIndex */
|
||||
195, /* agcRx1MinGainIndex */
|
||||
255, /* agcRx2MaxGainIndex */
|
||||
195, /* agcRx2MinGainIndex: */
|
||||
255, /* agcObsRxMaxGainIndex */
|
||||
203, /* agcObsRxMinGainIndex */
|
||||
1, /* agcObsRxSelect */
|
||||
1, /* agcPeakThresholdMode */
|
||||
1, /* agcLowThsPreventGainIncrease */
|
||||
30720, /* agcGainUpdateCounter */
|
||||
3, /* agcSlowLoopSettlingDelay */
|
||||
2, /* agcPeakWaitTime */
|
||||
1, /* agcResetOnRxEnable */
|
||||
0, /* agcEnableSyncPulseForGainCounter */
|
||||
&obsRxPeakAgc,
|
||||
&obsRxPwrAgc
|
||||
};
|
||||
|
||||
|
||||
static mykonosRxProfile_t rxProfile =
|
||||
{/* Rx 100MHz, IQrate 122.88MSPS, Dec5 */
|
||||
1, /* The divider used to generate the ADC clock*/
|
||||
&rxFir, /* Pointer to Rx FIR filter structure*/
|
||||
2, /* Rx FIR decimation (1,2,4)*/
|
||||
5, /* Decimation of Dec5 or Dec4 filter (5,4)*/
|
||||
1, /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/
|
||||
1, /* RX Half band 1 decimation (1 or 2)*/
|
||||
122880, /* Rx IQ data rate in kHz*/
|
||||
100000000, /* The Rx RF passband bandwidth for the profile*/
|
||||
100000, /* Rx BBF 3dB corner in kHz*/
|
||||
NULL /* pointer to custom ADC profile*/
|
||||
};
|
||||
|
||||
static mykonosRxProfile_t orxProfile =
|
||||
{/* ORX 100MHz, IQrate 122.88MSPS, Dec5 */
|
||||
1, /* The divider used to generate the ADC clock*/
|
||||
&obsrxFir, /* Pointer to Rx FIR filter structure or NULL*/
|
||||
2, /* Rx FIR decimation (1,2,4)*/
|
||||
5, /* Decimation of Dec5 or Dec4 filter (5,4)*/
|
||||
0, /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/
|
||||
1, /* RX Half band 1 decimation (1 or 2)*/
|
||||
122880, /* Rx IQ data rate in kHz*/
|
||||
100000000, /* The Rx RF passband bandwidth for the profile*/
|
||||
100000, /* Rx BBF 3dB corner in kHz*/
|
||||
NULL /* pointer to custom ADC profile*/
|
||||
};
|
||||
|
||||
|
||||
static mykonosRxProfile_t snifferProfile =
|
||||
{ /* SRx 20MHz, IQrate 30.72MSPS, Dec5 */
|
||||
1, /* The divider used to generate the ADC clock*/
|
||||
&snifferRxFir, /* Pointer to Rx FIR filter structure or NULL*/
|
||||
4, /* Rx FIR decimation (1,2,4)*/
|
||||
5, /* Decimation of Dec5 or Dec4 filter (5,4)*/
|
||||
0, /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/
|
||||
2, /* RX Half band 1 decimation (1 or 2)*/
|
||||
30720, /* Rx IQ data rate in kHz*/
|
||||
10000000, /* The Rx RF passband bandwidth for the profile*/
|
||||
100000, /* Rx BBF 3dB corner in kHz*/
|
||||
NULL /* pointer to custom ADC profile*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
static mykonosTxProfile_t txProfile =
|
||||
{ /* Tx 20/100MHz, IQrate 122.88MSPS, Dec5 */
|
||||
DACDIV_2p5, /* The divider used to generate the DAC clock*/
|
||||
&txFir, /* Pointer to Tx FIR filter structure*/
|
||||
2, /* The Tx digital FIR filter interpolation (1,2,4)*/
|
||||
2, /* Tx Halfband1 filter interpolation (1,2)*/
|
||||
1, /* Tx Halfband2 filter interpolation (1,2)*/
|
||||
1, /* TxInputHbInterpolation (1,2)*/
|
||||
122880, /* Tx IQ data rate in kHz*/
|
||||
100000000, /* Primary Signal BW*/
|
||||
100000000, /* The Tx RF passband bandwidth for the profile*/
|
||||
710539, /* The DAC filter 3dB corner in kHz*/
|
||||
50000, /* Tx BBF 3dB corner in kHz*/
|
||||
0 /* Enable DPD, only valid for AD9373*/
|
||||
};
|
||||
|
||||
static mykonosDigClocks_t mykonosClocks =
|
||||
{
|
||||
122880, /* CLKPLL and device reference clock frequency in kHz*/
|
||||
9830400, /* CLKPLL VCO frequency in kHz*/
|
||||
VCODIV_2, /* CLKPLL VCO divider*/
|
||||
4 /* CLKPLL high speed clock divider*/
|
||||
};
|
||||
|
||||
static mykonosRxSettings_t rxSettings =
|
||||
{
|
||||
&rxProfile, /* Rx datapath profile, 3dB corner frequencies, and digital filter enables*/
|
||||
&rxFramer, /* Rx JESD204b framer configuration structure*/
|
||||
&rxGainControl, /* Rx Gain control settings structure*/
|
||||
&rxAgcConfig, /* Rx AGC control settings structure*/
|
||||
RX1_RX2, /* The desired Rx Channels to enable during initialization*/
|
||||
0, /* Internal LO = 0, external LO*2 = 1*/
|
||||
2550000000U, /* Rx PLL LO Frequency (internal or external LO)*/
|
||||
0 /* Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where, if > 0 = real IF data, '0' = zero IF (IQ) data*/
|
||||
};
|
||||
|
||||
static mykonosDpdConfig_t dpdConfig =
|
||||
{
|
||||
5, /* 1/2^(damping + 8) fraction of power `forgotten' per sample (default: `1/8192' = 5, valid 0 to 15), 0 = infinite damping*/
|
||||
1, /* number of weights to use for int8_cpx weights weights member of this structure (default = 1)*/
|
||||
2, /* DPD model version: one of four different generalized polynomial models: 0 = same as R0 silicon, 1-3 are new and the best one depends on the PA (default: 2)*/
|
||||
1, /* 1 = Update saved model whenever peak Tx digital RMS is within 1dB of historical peak Tx RMS*/
|
||||
20, /* Determines how much weight the loaded prior model has on DPD modeling (Valid 0 - 32, default 20)*/
|
||||
0, /* Default off = 0, 1=enables automatic outlier removal during DPD modeling */
|
||||
512, /* Number of samples to capture (default: 512, valid 64-32768)*/
|
||||
4096, /* threshold for sample in AM-AM plot outside of 1:1 line to be thrown out. (default: 50% = 8192/2, valid 8192 to 1)*/
|
||||
0, /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/
|
||||
255, /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range 1 to 8191)*/
|
||||
{{64,0},{0,0},{0,0}}/* DPD model error weighting (real/imag valid from -128 to 127)*/
|
||||
};
|
||||
|
||||
static mykonosClgcConfig_t clgcConfig =
|
||||
{
|
||||
-2000, /* (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx1 output to ORx1 input in (dB * 100)*/
|
||||
-2000, /* (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx2 output to ORx2 input in (dB * 100)*/
|
||||
0, /* (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx1Atten is not reduced below the limit*/
|
||||
0, /* (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx2Atten is not reduced below the limit*/
|
||||
75, /* valid range 1-100, default 75*/
|
||||
75, /* valid range 1-100, default 45*/
|
||||
0, /* 0= allow CLGC to run, but Tx1Atten will not be updated. User can still read back power measurements. 1=CLGC runs, and Tx1Atten automatically updated*/
|
||||
0, /* 0= allow CLGC to run, but Tx2Atten will not be updated. User can still read back power measurements. 1=CLGC runs, and Tx2Atten automatically updated*/
|
||||
0, /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/
|
||||
255, /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range 1 to 8191)*/
|
||||
600, /* Threshold for Tx1 in order to stop tracking, value = 100 * dB, default 6db then value = 600*/
|
||||
600, /* Threshold for Tx2 in order to stop tracking, value = 100 * dB, default 6db then value = 600*/
|
||||
0, /* Threshold feature enable for Tx1, 0 = disable, 1 = enable, default = 0*/
|
||||
0 /* Threshold feature enable for Tx1, 0 = disable, 1 = enable, default = 0*/
|
||||
};
|
||||
|
||||
static mykonosVswrConfig_t vswrConfig =
|
||||
{
|
||||
0, /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/
|
||||
255, /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range 1 to 8191)*/
|
||||
0, /* 3p3V GPIO pin to use to control VSWR switch for Tx1 (valid 0-11) (output from Mykonos)*/
|
||||
1, /* 3p3V GPIO pin to use to control VSWR switch for Tx2 (valid 0-11) (output from Mykonos)*/
|
||||
0, /* 3p3v GPIO pin polarity for forward path of Tx1, opposite used for reflection path (1 = high level, 0 = low level)*/
|
||||
0, /* 3p3v GPIO pin polarity for forward path of Tx2, opposite used for reflection path (1 = high level, 0 = low level)*/
|
||||
50, /* Delay for Tx1 after flipping the VSWR switch until measurement is made. In us resolution*/
|
||||
50 /* Delay for Tx2 after flipping the VSWR switch until measurement is made. In us resolution*/
|
||||
};
|
||||
|
||||
static mykonosTxSettings_t txSettings =
|
||||
{
|
||||
&txProfile, /* Tx datapath profile, 3dB corner frequencies, and digital filter enables*/
|
||||
&deframer, /* Mykonos JESD204b deframer config for the Tx data path*/
|
||||
TX1_TX2, /* The desired Tx channels to enable during initialization*/
|
||||
0, /* Internal LO=0, external LO*2 if =1*/
|
||||
2500000000U, /* Tx PLL LO frequency (internal or external LO)*/
|
||||
TXATTEN_0P05_DB,/* Initial and current Tx1 Attenuation*/
|
||||
10000, /* Initial and current Tx1 Attenuation mdB*/
|
||||
10000, /* Initial and current Tx2 Attenuation mdB*/
|
||||
NULL, /* DPD,CLGC,VSWR settings. Only valid for AD9373 device, set pointer to NULL otherwise*/
|
||||
NULL, /* CLGC Config Structure. Only valid for AD9373 device, set pointer to NULL otherwise*/
|
||||
NULL /* VSWR Config Structure. Only valid for AD9373 device, set pointer to NULL otherwise*/
|
||||
};
|
||||
|
||||
|
||||
static mykonosObsRxSettings_t obsRxSettings =
|
||||
{
|
||||
&orxProfile, /* ORx datapath profile, 3dB corner frequencies, and digital filter enables*/
|
||||
&orxGainControl,/* ObsRx gain control settings structure*/
|
||||
&obsRxAgcConfig,/* ORx AGC control settings structure*/
|
||||
&snifferProfile,/* Sniffer datapath profile, 3dB corner frequencies, and digital filter enables*/
|
||||
&snifferGainControl,/* SnRx gain control settings structure*/
|
||||
&obsRxFramer, /* ObsRx JESD204b framer configuration structure */
|
||||
(MYK_ORX1_ORX2 | MYK_SNRXA_B_C),/* obsRxChannel */
|
||||
OBSLO_TX_PLL, /* (obsRxLoSource) The Obs Rx mixer can use the Tx Synth(TX_PLL) or Sniffer Synth (SNIFFER_PLL) */
|
||||
2600000000U, /* SnRx PLL LO frequency in Hz */
|
||||
0, /* Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where if > 0 = real IF data, '0' = complex data*/
|
||||
NULL, /* Custom Loopback ADC profile to set the bandwidth of the ADC response */
|
||||
OBS_RXOFF /* Default ObsRx channel to enter when radioOn called */
|
||||
};
|
||||
|
||||
static mykonosArmGpioConfig_t armGpio =
|
||||
{
|
||||
1, // useRx2EnablePin; /*!< 0= RX1_ENABLE controls RX1 and RX2, 1 = separate RX1_ENABLE/RX2_ENABLE pins */
|
||||
1, // useTx2EnablePin; /*!< 0= TX1_ENABLE controls TX1 and TX2, 1 = separate TX1_ENABLE/TX2_ENABLE pins */
|
||||
1, // txRxPinMode; /*!< 0= ARM command mode, 1 = Pin mode to power up Tx/Rx chains */
|
||||
0, // orxPinMode; /*!< 0= ARM command mode, 1 = Pin mode to power up ObsRx receiver*/
|
||||
|
||||
/*Mykonos ARM input GPIO pins -- Only valid if orxPinMode = 1 */
|
||||
0, // orxTriggerPin; /*!< Select desired GPIO pin (valid 4-15) */
|
||||
0, // orxMode2Pin; /*!< Select desired GPIO pin (valid 0-18) */
|
||||
0, // orxMode1Pin; /*!< Select desired GPIO pin (valid 0-18) */
|
||||
0, // orxMode0Pin; /*!< Select desired GPIO pin (valid 0-18) */
|
||||
|
||||
/* Mykonos ARM output GPIO pins -- always available, even when pin mode not enabled*/
|
||||
0, // rx1EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
|
||||
0, // rx2EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
|
||||
0, // tx1EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
|
||||
0, // tx2EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
|
||||
0, // orx1EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
|
||||
0, // orx2EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
|
||||
0, // srxEnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
|
||||
0 // txObsSelect; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
|
||||
/* When 2Tx are used with only 1 ORx input, this GPIO tells the BBIC which Tx channel is */
|
||||
/* active for calibrations, so BBIC can route correct RF Tx path into the single ORx input*/
|
||||
};
|
||||
|
||||
static mykonosGpio3v3_t gpio3v3 =
|
||||
{
|
||||
0, /*!< Oe per pin, 1=output, 0 = input */
|
||||
GPIO3V3_BITBANG_MODE, /*!< Mode for GPIO3V3[3:0] */
|
||||
GPIO3V3_BITBANG_MODE, /*!< Mode for GPIO3V3[7:4] */
|
||||
GPIO3V3_BITBANG_MODE, /*!< Mode for GPIO3V3[11:8] */
|
||||
};
|
||||
|
||||
static mykonosGpioLowVoltage_t gpio =
|
||||
{
|
||||
0,/* Oe per pin, 1=output, 0 = input */
|
||||
GPIO_MONITOR_MODE,/* Mode for GPIO[3:0] */
|
||||
GPIO_MONITOR_MODE,/* Mode for GPIO[7:4] */
|
||||
GPIO_MONITOR_MODE,/* Mode for GPIO[11:8] */
|
||||
GPIO_MONITOR_MODE,/* Mode for GPIO[15:12] */
|
||||
GPIO_MONITOR_MODE,/* Mode for GPIO[18:16] */
|
||||
};
|
||||
|
||||
static mykonosAuxIo_t mykonosAuxIo =
|
||||
{
|
||||
0, //auxDacEnableMask uint16_t
|
||||
{0,0,0,0,0,0,0,0,0,0}, //AuxDacValue uint16[10]
|
||||
{0,0,0,0,0,0,0,0,0,0}, //AuxDacSlope uint8[10]
|
||||
{0,0,0,0,0,0,0,0,0,0}, //AuxDacVref uint8[10]
|
||||
&gpio3v3, //pointer to gpio3v3 struct
|
||||
&gpio, //pointer to gpio1v8 struct
|
||||
&armGpio
|
||||
};
|
||||
|
||||
static spiSettings_t mykSpiSettings =
|
||||
{
|
||||
1, /* chip select index - valid 1~8 */
|
||||
0, /* the level of the write bit of a SPI write instruction word, value is inverted for SPI read operation */
|
||||
1, /* 1 = 16-bit instruction word, 0 = 8-bit instruction word */
|
||||
1, /* 1 = MSBFirst, 0 = LSBFirst */
|
||||
0, /* clock phase, sets which clock edge the data updates (valid 0 or 1) */
|
||||
0, /* clock polarity 0 = clock starts low, 1 = clock starts high */
|
||||
0, /* Not implemented in ADIs platform layer. SW feature to improve SPI throughput */
|
||||
1, /* Not implemented in ADIs platform layer. For SPI Streaming, set address increment direction. 1= next addr = addr+1, 0:addr=addr-1 */
|
||||
1 /* 1: Use 4-wire SPI, 0: 3-wire SPI (SDIO pin is bidirectional). NOTE: ADI's FPGA platform always uses 4-wire mode */
|
||||
};
|
||||
|
||||
static mykonosTempSensorConfig_t tempSensor =
|
||||
{
|
||||
7, /* 3-bit value that controls the AuxADC decimation factor when used for temp sensor calculations; AuxADC_decimation = 256 * 2^tempDecimation*/
|
||||
67, /* 8-bit offset that gets added to temp sensor code internally*/
|
||||
1, /* this bit overrides the factory-calibrated fuse offset and uses the value stored in the offset member*/
|
||||
15, /* 4-bit code with a resolution of 1°C/LSB, each time a temperature measurement is performed, the device compares the current temperature against the previous value.*/
|
||||
};
|
||||
|
||||
static mykonosTempSensorStatus_t tempStatus =
|
||||
{
|
||||
0, /* 16-bit signed temperature value (in deg C) that is read back*/
|
||||
0, /* If the absolute value of the difference is greater than the value in temperature configuration tempWindow, the windowExceeded flag is set.*/
|
||||
0, /* when windowExceeded member gets set, this bit is set to 1 if current value is greater than previous value, else reset*/
|
||||
0, /* when the reading is complete and a valid temperature value stored in tempCode.*/
|
||||
};
|
||||
|
||||
mykonosDevice_t mykDevice =
|
||||
{
|
||||
&mykSpiSettings, /* SPI settings data structure pointer */
|
||||
&rxSettings, /* Rx settings data structure pointer */
|
||||
&txSettings, /* Tx settings data structure pointer */
|
||||
&obsRxSettings, /* ObsRx settings data structure pointer */
|
||||
&mykonosAuxIo, /* Auxiliary IO settings data structure pointer */
|
||||
&mykonosClocks, /* Holds settings for CLKPLL and reference clock */
|
||||
0 /* Mykonos initialize function uses this as an output to remember which profile data structure pointers are valid */
|
||||
};
|
||||
@@ -1,24 +0,0 @@
|
||||
/**
|
||||
* \file myk_init.h
|
||||
*
|
||||
* \brief Contains structure definitions for myk_init.c
|
||||
*
|
||||
* The top level structure mykonosDevice_t mykDevice uses keyword
|
||||
* extern to allow the application layer main() to have visibility
|
||||
* to these settings.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \page Disclaimer Legal Disclaimer
|
||||
* Copyright 2015-2017 Analog Devices Inc.
|
||||
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MYK_INIT_H_
|
||||
#define MYK_INIT_H_
|
||||
|
||||
|
||||
extern mykonosDevice_t mykDevice;
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,13 +0,0 @@
|
||||
/**
|
||||
SOFTWARE LICENSE AGREEMENT
|
||||
20180301-AD937X-CTSLA
|
||||
**/
|
||||
|
||||
// Version 5.2.2
|
||||
#ifndef SRC_MYKONOS_BIN_H_
|
||||
#define SRC_MYKONOS_BIN_H_
|
||||
|
||||
unsigned char firmware_Mykonos_M3_bin[];
|
||||
unsigned int firmware_Mykonos_M3_bin_len;
|
||||
|
||||
#endif
|
||||
@@ -1,740 +0,0 @@
|
||||
/**
|
||||
* \file ad9528.c
|
||||
* \brief Contains source code for configuring and initializing AD9528 clock device
|
||||
*/
|
||||
|
||||
/**
|
||||
* \page Disclaimer Legal Disclaimer
|
||||
* Copyright 2015-2017 Analog Devices Inc.
|
||||
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ad9528.h"
|
||||
|
||||
/**
|
||||
* \brief Performs a hard reset on the AD9528 DUT
|
||||
*
|
||||
* <B>Dependencies</B>
|
||||
* - device->spiSettings->chipSelectIndex
|
||||
*
|
||||
* \param device is structure pointer to the AD9528 data structure containing settings
|
||||
* \return Returns enum ADI_ERR, ADIERR_OK=pass, !ADIERR_OK=fail
|
||||
*/
|
||||
ADI_ERR AD9528_resetDevice(ad9528Device_t *device)
|
||||
{
|
||||
/* toggle RESETB on device with matching spi chip select index */
|
||||
CMB_hardReset(device->spiSettings->chipSelectIndex);
|
||||
return ADIERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets the AD9528 device SPI settings (3wire/4wire, MSBFirst, etc).
|
||||
*
|
||||
* This function will use the settings in the device->spiSettings structure
|
||||
* to set SPI stream mode, address auto increment direction, MSBFirst/LSBfirst,
|
||||
* and 3wire/4wire mode. The AD9528 device always uses SPI MODE 0 (CPHA=0, CPOL=0).
|
||||
* This function will update your device->spiSettings to set CHPA=0 and CPOL=0 and
|
||||
* longInstructionWord =1 to use a 16bit instruction word.
|
||||
*
|
||||
* <B>Dependencies</B>
|
||||
* - writes device->spiSettings->CPHA = 0
|
||||
* - writes device->spiSettings->CPOL = 0
|
||||
* - writes device->spiSettings->longInstructionWord = 1
|
||||
*
|
||||
* - device->spiSettings->MSBFirst
|
||||
* - device->spiSettings->enSpiStreaming
|
||||
* - device->spiSettings->autoIncAddrUp
|
||||
* - device->spiSettings->fourWireMode
|
||||
*
|
||||
* \param device is structure pointer to the AD9528 data structure containing settings
|
||||
*
|
||||
* \return Returns enum ADI_ERR, ADIERR_OK=pass, !ADIERR_OK=fail
|
||||
*/
|
||||
ADI_ERR AD9528_setSpiSettings(ad9528Device_t *device)
|
||||
{
|
||||
//device->spiSettings->enSpiStreaming
|
||||
uint8_t spiReg = 0;
|
||||
|
||||
device->spiSettings->CPHA = 0;
|
||||
device->spiSettings->CPOL = 0;
|
||||
device->spiSettings->longInstructionWord = 1;
|
||||
|
||||
if (device->spiSettings->MSBFirst == 0)
|
||||
{
|
||||
spiReg |= 0x42; /* SPI bit is 1=LSB first */
|
||||
}
|
||||
|
||||
if (device->spiSettings->autoIncAddrUp > 0)
|
||||
{
|
||||
spiReg |= 0x24;
|
||||
}
|
||||
|
||||
if (device->spiSettings->fourWireMode > 0)
|
||||
{
|
||||
spiReg |= 0x18;
|
||||
}
|
||||
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_ADI_SPI_CONFIG_A, spiReg);
|
||||
|
||||
if (device->spiSettings->enSpiStreaming > 0)
|
||||
{
|
||||
/* Allow SPI streaming mode: SPI message ends when chip select deasserts */
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_ADI_SPI_CONFIG_B, 0x00);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Force single instruction mode */
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_ADI_SPI_CONFIG_B, 0x80);
|
||||
}
|
||||
|
||||
return ADIERR_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Helper function for ADI transceiver eval boards to init the AD9528 data structure
|
||||
*
|
||||
* This function inits the AD9528 device data structure with defaults that
|
||||
* are known to work with the ADI AD9369 and AD9371 evaluation boards. NOTE: This function will
|
||||
* modify the contents of the AD9528 device data structure.
|
||||
*
|
||||
* <B>Dependencies</B>
|
||||
* - spi->chipSelectIndex
|
||||
* - spi
|
||||
*
|
||||
* \param device Pointer to the AD9528 device data structure to initialize
|
||||
* \param vcxoFrequency_Hz The VCXO frequency that is connected to the AD9528
|
||||
* \param refAFrequency_Hz The reference clock frequency being input into the AD9528 REFCLK A input
|
||||
* \param outputDeviceClock_Hz Desired output clock frequency to the FPGA and transceiver device
|
||||
*
|
||||
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
|
||||
*/
|
||||
ADI_ERR AD9528_initDeviceDataStruct(ad9528Device_t *device, uint32_t vcxoFrequency_Hz, uint32_t refAFrequency_Hz, uint32_t outputDeviceClock_Hz)
|
||||
{
|
||||
// uint16_t chDiv;
|
||||
// uint8_t i = 0;
|
||||
//
|
||||
// uint32_t pll1PfdFreq_Hz = 0;
|
||||
// uint8_t pll1Ndiv = 0;
|
||||
// uint8_t validPll1DivSetting = 0;
|
||||
// uint8_t refAdiv = 1;
|
||||
//
|
||||
//
|
||||
// uint8_t pll2RfDiv = 3; /* Valid values 3,4,5 */
|
||||
// uint16_t pll2Ndiv = 1; /* Valid values 1-256 */
|
||||
// uint32_t pll2InputFreq_Hz = 0;
|
||||
// uint64_t pll2VcoFreq_Hz = 0;
|
||||
// uint16_t pll2NdivStart = 0;
|
||||
// uint8_t validPll2DivSetting = 0;
|
||||
// uint64_t chDivU64 = 0;
|
||||
//
|
||||
// static const uint64_t PLL2_MIN_VCO_FREQ_HZ = 3450000000ULL;
|
||||
// static const uint64_t PLL2_MAX_VCO_FREQ_HZ = 4025000000ULL;
|
||||
// /*******************************************************************
|
||||
// * PLL1 Settings
|
||||
// *******************************************************************
|
||||
// */
|
||||
//
|
||||
// /* find valid PLL1 Ndiv and REFA div */
|
||||
// for (pll1Ndiv = 1; pll1Ndiv < 20; pll1Ndiv++)
|
||||
// {
|
||||
// pll1PfdFreq_Hz = vcxoFrequency_Hz / pll1Ndiv;
|
||||
//
|
||||
// if ((pll1PfdFreq_Hz <= 110000000) && (pll1PfdFreq_Hz >= 1000000) &&
|
||||
// (pll1PfdFreq_Hz <= refAFrequency_Hz) &&
|
||||
// (refAFrequency_Hz % pll1PfdFreq_Hz == 0)
|
||||
// )
|
||||
// {
|
||||
// validPll1DivSetting = 1;
|
||||
// refAdiv = refAFrequency_Hz / pll1PfdFreq_Hz ;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (validPll1DivSetting == 0)
|
||||
// {
|
||||
// return ADIERR_INV_PARM;
|
||||
// }
|
||||
//
|
||||
// device->pll1Settings->nDivider = pll1Ndiv; //This init function always runs PLL1 at 30.72MHz Pfd rate
|
||||
// device->pll1Settings->refA_bufferCtrl = DIFFERENTIAL; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL
|
||||
// device->pll1Settings->refA_Divider = refAdiv;
|
||||
// device->pll1Settings->refA_Frequency_Hz = refAFrequency_Hz;
|
||||
// device->pll1Settings->refB_bufferCtrl = DISABLED; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL
|
||||
// device->pll1Settings->refB_Divider = 1;
|
||||
// device->pll1Settings->refB_Frequency_Hz = 0;
|
||||
// device->pll1Settings->vcxoBufferCtrl = NEG_SINGLE_ENDED; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL
|
||||
// device->pll1Settings->vcxo_Frequency_Hz = vcxoFrequency_Hz;
|
||||
//
|
||||
// /*******************************************************************
|
||||
// * PLL2 Settings
|
||||
// *******************************************************************
|
||||
// */
|
||||
//
|
||||
// /*******************************************************************
|
||||
// * Output Distribution Settings
|
||||
// * 9369CE02A uses the following clock outputs
|
||||
// * OUT 1: FPGA REFCLK
|
||||
// * OUT 3: FPGA SYSREF
|
||||
// * OUT 12: DUT SYSREF
|
||||
// * OUT 13: DUT REFCLK
|
||||
// *******************************************************************
|
||||
// */
|
||||
//
|
||||
// /* PLL 2 input clock can be several different things. Currently hard coded by this init funciton to use
|
||||
// * PLL 1 output (VCXO Frequency) with no scaling
|
||||
// */
|
||||
// pll2InputFreq_Hz = device->pll1Settings->vcxo_Frequency_Hz;
|
||||
// validPll2DivSetting = 0;
|
||||
//
|
||||
// /* Sweep PLL2 Divider settings to find something that has a valid integer divide (3,4,5)*/
|
||||
// for (pll2RfDiv = 3; pll2RfDiv <= 5; pll2RfDiv++)
|
||||
// {
|
||||
//
|
||||
// pll2NdivStart = (PLL2_MIN_VCO_FREQ_HZ / pll2RfDiv / pll2InputFreq_Hz);
|
||||
// /* find valid PLL2 Ndiv (1-256) */
|
||||
// for (pll2Ndiv = pll2NdivStart; pll2Ndiv <= 256; pll2Ndiv++)
|
||||
// {
|
||||
// pll2VcoFreq_Hz = (pll2InputFreq_Hz * pll2RfDiv * pll2Ndiv);
|
||||
//
|
||||
// if (pll2VcoFreq_Hz < PLL2_MIN_VCO_FREQ_HZ)
|
||||
// {
|
||||
// /* Continue to next PLL2 N div */
|
||||
// continue;
|
||||
// }
|
||||
// else if (pll2VcoFreq_Hz > PLL2_MAX_VCO_FREQ_HZ)
|
||||
// {
|
||||
// /* Break to next PLL2 RF div */
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// if (((pll2VcoFreq_Hz / pll2RfDiv) % outputDeviceClock_Hz) == 0)
|
||||
// {
|
||||
//
|
||||
// device->pll2Settings->rfDivider = pll2RfDiv;
|
||||
// device->pll2Settings->n2Divider = pll2Ndiv;
|
||||
// device->pll2Settings->totalNdiv = pll2RfDiv * pll2Ndiv;
|
||||
// chDivU64 = ((pll2VcoFreq_Hz / pll2RfDiv) / outputDeviceClock_Hz);
|
||||
//
|
||||
// if ((chDivU64 < 1) || (chDivU64 > 256))
|
||||
// {
|
||||
// return ADIERR_INV_PARM;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// chDiv = (uint16_t)(chDivU64);
|
||||
// }
|
||||
//
|
||||
// validPll2DivSetting = 1;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (validPll2DivSetting == 1)
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (validPll2DivSetting == 0)
|
||||
// {
|
||||
// return ADIERR_INV_PARM;
|
||||
// }
|
||||
//
|
||||
// device->outputSettings->outPowerDown = (uint16_t)(~0x300A); //enable outputs 13,12,3 and 1
|
||||
//
|
||||
// for (i=0; i<14; i++){
|
||||
// device->outputSettings->outSource[i] = CHANNEL_DIV; //CHANNEL_DIV , PLL1_OUTPUT, SYSREF, INV_PLL1_OUTPUT
|
||||
// device->outputSettings->outBufferCtrl[i] = LVDS; //LVDS, LVDS_BOOST, HSTL
|
||||
// device->outputSettings->outChannelDiv[i] = chDiv;
|
||||
// device->outputSettings->outFrequency_Hz[i] = outputDeviceClock_Hz;
|
||||
// device->outputSettings->outAnalogDelay[i] = 0;
|
||||
// device->outputSettings->outDigitalDelay[i] = 0;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// device->outputSettings->outSource[3] = SYSREF;
|
||||
// device->outputSettings->outSource[12] = SYSREF;
|
||||
//
|
||||
//
|
||||
// device->sysrefSettings->sysrefDivide = 512; //SYSREF frequency = VCXO / 2 / sysrefDivde
|
||||
// device->sysrefSettings->sysrefNshotMode = ONE_PULSE; //ONE_PULSE=0, TWO_PULSES=2, FOUR_PULSES=3, SIX_PULSES=4, EIGHT_PULSES=5
|
||||
// device->sysrefSettings->sysrefPatternMode = NSHOT; //NSHOT=0, CONTINUOUS=1, PRBS=2, STOP=3
|
||||
// device->sysrefSettings->sysrefPinBufferMode = DISABLED; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL
|
||||
// device->sysrefSettings->sysrefPinEdgeMode = LEVEL_ACTIVE_HIGH; //LEVEL_ACTIVE_HIGH=0, LEVEL_ACTIVE_LOW=1, RISING_EDGE=2, FALLING_EDGE=3
|
||||
// device->sysrefSettings->sysrefRequestMethod = SPI; //SPI=0,PIN=1
|
||||
// device->sysrefSettings->sysrefSource = INTERNAL; //EXTERNAL=0, EXT_RESAMPLED=1, INTERNAL=2
|
||||
return ADIERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Debug function to print out summary of AD9528 setup
|
||||
*
|
||||
* \param device AD9528 Device data structure describing setup of device.
|
||||
*
|
||||
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
|
||||
***********************************************************************************/
|
||||
ADI_ERR AD9528_reportClockRates(ad9528Device_t *device)
|
||||
{
|
||||
|
||||
return ADIERR_OK;
|
||||
} //debug function to help verify data structure is setup correctly.
|
||||
|
||||
/**
|
||||
* \brief Initializes the AD9528 by writing all SPI registers
|
||||
*
|
||||
* Initializes the AD9528 for use with the AD9369 transceiver. Designed to work with
|
||||
* a reference clock of 122.88MHz. Reference clock is expected to be 30.72MHz.
|
||||
* The output clocks from the AD9528 can run at 122.88M, 153.6M, 184.32M, 245.76M, or 307.2M.
|
||||
* Typical setup: REFA frequency = 30.72, VCXO = 122.88MHz
|
||||
* SYNC(SYSREF) pulses output at rate of 120kHz
|
||||
*
|
||||
* <B>Dependencies</B>
|
||||
* - All parameters in device structure
|
||||
*
|
||||
* \param device is structure pointer to AD9528 clock device structure
|
||||
*
|
||||
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
|
||||
*/
|
||||
ADI_ERR AD9528_initialize(ad9528Device_t *device) { //writes all registers to desired values, leaves clock outputs off, SYSREF output disabled.
|
||||
uint8_t pll2_Adiv=0;
|
||||
uint8_t pll2_Bdiv=0;
|
||||
uint8_t reg108=0;
|
||||
uint8_t reg109=0;
|
||||
uint8_t i = 0;
|
||||
uint8_t j = 0;
|
||||
uint8_t reg508;
|
||||
ADI_ERR retval = ADIERR_OK;
|
||||
|
||||
CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, ADIERR_OK, "\n// AD9528_initialize\n");
|
||||
|
||||
//CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_ADI_SPI_CONFIG_A, 0x18); //[4] and [3] =1 enable 4 wire SPI
|
||||
//CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_ADI_SPI_CONFIG_B, 0x00);
|
||||
retval = AD9528_setSpiSettings(device);
|
||||
if (retval != ADIERR_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Configure PLL1
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_REF_A_DIVIDER_LSB,
|
||||
device->pll1Settings->refA_Divider & 0xFF); //REF A div[7:0]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_REF_A_DIVIDER_MSB,
|
||||
(device->pll1Settings->refA_Divider >> 8) & 0x03); //REF A div[9:8]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_REF_B_DIVIDER_LSB,
|
||||
device->pll1Settings->refB_Divider & 0xFF); //REF B div[7:0]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_REF_B_DIVIDER_MSB,
|
||||
(device->pll1Settings->refB_Divider >> 8) & 0x03); //REF B div[9:8]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL1_N_DIV_LSB,
|
||||
device->pll1Settings->nDivider & 0xFF); //PLL1 N div[7:0]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL1_N_DIV_MSB,
|
||||
(device->pll1Settings->nDivider >> 8) & 0x03); //PLL1 N div[9:8]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL1_CHARGEPUMP,
|
||||
0x0A); //PLL1 Charge Pump control 1
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL1_CP_CTRL2,
|
||||
0x03); //PLL1 Charge Pump control 2
|
||||
|
||||
switch (device->pll1Settings->refA_bufferCtrl){
|
||||
case DISABLED:
|
||||
reg108 &= ~0x28;
|
||||
reg109 &= ~0x01;
|
||||
break; //clear all REFA enable bits
|
||||
case SINGLE_ENDED:
|
||||
reg108 |= 0x08;
|
||||
reg109 &= ~0x01;
|
||||
break; //Set REFA receiver enable, clear REFA SE negative input enable
|
||||
case NEG_SINGLE_ENDED:
|
||||
reg108 |= 0x08;
|
||||
reg108 &= ~0x10;
|
||||
reg109 |= 0x01;
|
||||
break; //Disable REFA diff receiver, enable REFA receiver and use negative REFA input
|
||||
case DIFFERENTIAL:
|
||||
reg108 |= 0x28;
|
||||
reg109 &= ~0x01;
|
||||
break;
|
||||
default:
|
||||
reg108 |= 0x08;
|
||||
reg109 &= ~0x01;
|
||||
break; //default to single ended case
|
||||
}
|
||||
switch (device->pll1Settings->refB_bufferCtrl){
|
||||
case DISABLED:
|
||||
reg108 &= ~0x50;
|
||||
reg109 &= ~0x02;
|
||||
break; //clear all REFB enable bits
|
||||
case SINGLE_ENDED:
|
||||
reg108 |= 0x10;
|
||||
reg109 &= ~0x02;
|
||||
break; //Set REFB receiver enable, clear REFB SE negative input enable
|
||||
case NEG_SINGLE_ENDED:
|
||||
reg108 |= 0x10;
|
||||
reg108 &= ~0x40;
|
||||
reg109 |= 0x02;
|
||||
break; //Disable REFB diff receiver, enable REFB receiver and use negative REFB input
|
||||
case DIFFERENTIAL:
|
||||
reg108 |= 0x50;
|
||||
reg109 &= ~0x02;
|
||||
break;
|
||||
default:
|
||||
reg108 |= 0x10;
|
||||
reg109 &= ~0x02;
|
||||
break; //default to single ended case
|
||||
}
|
||||
switch (device->pll1Settings->vcxoBufferCtrl){
|
||||
case DISABLED:
|
||||
reg108 &= ~0x03;
|
||||
reg108 |= 0x04;
|
||||
break; //power down VCXO input
|
||||
case SINGLE_ENDED:
|
||||
reg108 &= ~0x07;
|
||||
break; //Clear VCXO receiver power down, defaults to Single ended mode
|
||||
case NEG_SINGLE_ENDED:
|
||||
reg108 &= ~0x07;
|
||||
reg108 |= 0x02;
|
||||
break; //Clear VCXO power down, enable Negative single ended mode[1]
|
||||
case DIFFERENTIAL:
|
||||
reg108 &= ~0x07;
|
||||
reg108 |= 0x01;
|
||||
break; //Clear VCXO power down, enable differential input buffer[0]
|
||||
default:
|
||||
reg108 &= ~0x07;
|
||||
break; //default to positive single ended case
|
||||
}
|
||||
|
||||
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_INPUT_RECEIVERS1,
|
||||
reg108); //Input receiver settings (single ended or differential clock inputs)
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_INPUT_RECEIVERS2,
|
||||
reg109); //Input receiver settings
|
||||
|
||||
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_INPUT_RECEIVERS3,
|
||||
0x0A); //Reference selection mode
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL1_FASTLOCK,
|
||||
0x00); //Disable Fast lock
|
||||
|
||||
/**********************************************************************
|
||||
* Configure PLL2
|
||||
**********************************************************************
|
||||
*/
|
||||
pll2_Bdiv = device->pll2Settings->totalNdiv / 4;
|
||||
pll2_Adiv = device->pll2Settings->totalNdiv % 4;
|
||||
|
||||
if (pll2_Adiv > 3) { //A div valid range (0 to 3)
|
||||
CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, ADIERR_INV_PARM, "\n// AD9528 PLL2 A Divider out of range (0 to 3)\n");
|
||||
return ADIERR_INV_PARM;
|
||||
}
|
||||
if (pll2_Bdiv < 3 || pll2_Bdiv > 63) {
|
||||
CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, ADIERR_INV_PARM, "\n// AD9528 PLL2 B Divider out of range (3 to 63)\n");
|
||||
return ADIERR_INV_PARM;
|
||||
}
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_CHARGEPUMP,
|
||||
0xE6); //PLL2 Charge Pump[7:0]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_N_DIV,
|
||||
((pll2_Adiv & 0x3) << 6) | (pll2_Bdiv & 0x3F)); //PLL2 A and B divider
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_CTRL, 0x03); //PLL2 control
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_VCO_CTRL, 0x01); //Manual VCO CAL
|
||||
|
||||
if (device->pll2Settings->rfDivider < 3 || device->pll2Settings->rfDivider > 5) {
|
||||
CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, ADIERR_INV_PARM, "\n// AD9528 PLL2 RF Divider out of range (3,4, or 5)\n");
|
||||
return ADIERR_INV_PARM;
|
||||
}
|
||||
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_VCO_DIV,
|
||||
device->pll2Settings->rfDivider); //VCO divider
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_LF_CTRL1,
|
||||
0x3A); //PLL2 Loop filter [7:0]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_LF_CTRL2,
|
||||
0x00); //PLL2 Loop filter [8]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_RDIV,
|
||||
0x00); //R divider
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_REPLICA_CHDIV,
|
||||
(device->pll2Settings->totalNdiv / device->pll2Settings->rfDivider)
|
||||
-1 ); //Replica channel divider: Ndivider = rfDivider * R divider
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_REPLICA_DIV_PHASE,
|
||||
0x00); //Replica Channel Divider phase
|
||||
|
||||
/**********************************************************************
|
||||
* Configure Output Distribution
|
||||
**********************************************************************
|
||||
*/
|
||||
for (i=0; i<14; i=i+1){
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_OUT0_CTRL1 + j,
|
||||
((device->outputSettings->outSource[i] & 0x7) << 5) |
|
||||
(device->outputSettings->outAnalogDelay[i] & 0x1F));
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_OUT0_CTRL2 + j,
|
||||
((device->outputSettings->outBufferCtrl[i] & 0x3) << 6) |
|
||||
(device->outputSettings->outDigitalDelay[i] & 0x3F));
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_OUT0_CHDIV + j,
|
||||
device->outputSettings->outChannelDiv[i]-1);
|
||||
j = j+3;
|
||||
}
|
||||
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_OUTPUT_SYNC, 0x00); //Sync outputs
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_MASK_SYNC1, 0x00); //Mask SYNC[7:0]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_MASK_SYNC2, 0x00); //Mask SYNC[13:8]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_EN_OUTPUT_PATH_SEL1,
|
||||
0x00); //Bypass SYSREF resample [6:0], bit0:Enable VCXO to feed output distrubution
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_EN_OUTPUT_PATH_SEL2,
|
||||
0x00); //Bypass SYSREF resample [13:7]
|
||||
|
||||
/**********************************************************************
|
||||
* Configure SYSREF operation
|
||||
**********************************************************************
|
||||
*/
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSERF_DIV_LSB,
|
||||
device->sysrefSettings->sysrefDivide & 0xFF); //SYSREF divider [7:0]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSERF_DIV_MSB,
|
||||
(device->sysrefSettings->sysrefDivide >> 8) & 0xFF); //SYSREF divider [7:0]
|
||||
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL3,
|
||||
((device->sysrefSettings->sysrefRequestMethod & 0x1) << 7) |
|
||||
((device->sysrefSettings->sysrefPinEdgeMode & 0x3) << 5) );
|
||||
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL4,
|
||||
((device->sysrefSettings->sysrefSource & 0x03) << 6) |
|
||||
((device->sysrefSettings->sysrefPatternMode & 0x3) << 4 ) |
|
||||
((device->sysrefSettings->sysrefNshotMode & 0x7) << 1) );
|
||||
|
||||
if(device->sysrefSettings->sysrefPinBufferMode == DISABLED)
|
||||
{
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL5,
|
||||
0x04); //power down input buffer for external SYSREF
|
||||
}
|
||||
else if(device->sysrefSettings->sysrefPinBufferMode == SINGLE_ENDED)
|
||||
{
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL5,
|
||||
0x00); //enable positive singled ended input
|
||||
}
|
||||
else if(device->sysrefSettings->sysrefPinBufferMode == NEG_SINGLE_ENDED)
|
||||
{
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL5,
|
||||
0x02); //enable negative singled ended input
|
||||
}
|
||||
else if(device->sysrefSettings->sysrefPinBufferMode == DIFFERENTIAL)
|
||||
{
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL5,
|
||||
0x01); //enable differential input buffer
|
||||
}
|
||||
else
|
||||
{
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL5,
|
||||
0x04); //power down input buffer for external SYSREF
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Power down control
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
if (device->pll1Settings->bypassPll1 > 0)
|
||||
{
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_POWERDOWN_CTRL,
|
||||
0x14);// power up PLL2 and output distribution, power down PLL1
|
||||
}
|
||||
else
|
||||
{
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_POWERDOWN_CTRL,
|
||||
0x10);// power up PLL1, PLL2 and output distribution
|
||||
}
|
||||
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_POWERDOWN1,
|
||||
device->outputSettings->outPowerDown & 0xFF); //power down out[7:0]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_POWERDOWN2,
|
||||
((device->outputSettings->outPowerDown >> 8) & 0x3F)); //power down out[13:8]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_LDO_ENABLES1,
|
||||
0xFF); //LDO enable per output channel [7:0]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_LDO_ENABLES2,
|
||||
0xFF); //LDO enable per output channel [15:8]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_STATUS0_CTRL,
|
||||
0x07); //STATUS 0 outputs REFA present
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_STATUS1_CTRL,
|
||||
0x01); //STATUS 1 outputs PLL1 and PLL2 locked
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_STATUS_OE,
|
||||
0x0C);// Make Status0 and Status1 outputs after reset.
|
||||
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_IO_UPDATE,
|
||||
0x01); //IO update to make all these settings valid in the 9528
|
||||
|
||||
CMB_setTimeout_ms(1000);
|
||||
do{
|
||||
CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_STATUS_READBACK0, ®508);
|
||||
if(CMB_hasTimeoutExpired() > 0)
|
||||
{
|
||||
return ADIERR_FAILED;
|
||||
}
|
||||
}while((reg508 & 0xA2) != 0xA2);
|
||||
|
||||
return ADIERR_OK;
|
||||
}
|
||||
|
||||
/// Send a SPI message to request a SYSREF pulse or continuous SYSREF from the AD9528.
|
||||
/*******************************************************************************//**
|
||||
* Requests a SYSREF from the AD9528. It will use whatever settings for SYSREF
|
||||
* that are current configured in the AD9528. This could be a single pulse,
|
||||
* multiple pulses, or continuous pulses.
|
||||
* <B>Dependencies</B>
|
||||
* - device->spiSettings
|
||||
* - device->sysrefSettings->sysrefPatternMode
|
||||
*
|
||||
* \param device is structure pointer to AD9528 clock device structure
|
||||
* \param enableSYSREF If NSHOT SYSREF mode, this parameter is ignored. If PRBS/CONTINUOUS SYSREF mode, 1= enable SYSREF, 0= disable SYSREF.
|
||||
*
|
||||
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
|
||||
***********************************************************************************/
|
||||
ADI_ERR AD9528_requestSysref(ad9528Device_t *device, uint8_t enableSYSREF){
|
||||
uint8_t _enableSYSREF=0;
|
||||
|
||||
if (device->sysrefSettings->sysrefPatternMode == NSHOT || enableSYSREF > 0)
|
||||
{
|
||||
_enableSYSREF = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_enableSYSREF = 0;
|
||||
}
|
||||
|
||||
CMB_SPIWriteField(device->spiSettings, AD9528_ADDR_SYSREF_CTRL4, _enableSYSREF, 0x01, 0x00); //Set SPI SYSREF request bit
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_IO_UPDATE, 0x01); //IO update to make all these settings valid in the 9528
|
||||
|
||||
return ADIERR_OK;
|
||||
}
|
||||
|
||||
/// Allow changing the 9528 SYSREF frequency and pattern mode(CONTINUOUS, PRBS vs NSHOT mode)
|
||||
/*******************************************************************************//**
|
||||
* NOTE: this function will update the device structure with the parameter values passed
|
||||
* into this function. The device->sysrefSettings->sysrefPatternMode, device->sysrefSettings->sysrefNshotMode,
|
||||
* and device->sysrefSettings->sysrefDivide values will be updated in the device structure.
|
||||
*
|
||||
* <B>Dependencies</B>
|
||||
* - device->spiSettings
|
||||
*
|
||||
* \param device is structure pointer to AD9528 clock device structure
|
||||
* \param divideFromPll1Out Sets the SYSREF pulse frequency. SYSREF frequency = PLL1_VCXO frequency/divideFromPll1Out
|
||||
* \param sysrefPatternMode Valid settings: NSHOT, CONTINUOUS, PRBS, STOP
|
||||
* \param nShotPulses Valid settings: ONE_PULSE=0, TWO_PULSES=2, FOUR_PULSES=3, SIX_PULSES=4, EIGHT_PULSES=5
|
||||
*
|
||||
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
|
||||
***********************************************************************************/
|
||||
ADI_ERR AD9528_setupSYSREF(ad9528Device_t *device, uint16_t divideFromPll1Out, sysrefPatternMode_t sysrefPatternMode, sysrefNshotMode_t nShotPulses)
|
||||
{
|
||||
uint8_t reg403=0;
|
||||
|
||||
device->sysrefSettings->sysrefPatternMode = sysrefPatternMode;
|
||||
device->sysrefSettings->sysrefNshotMode = nShotPulses;
|
||||
device->sysrefSettings->sysrefDivide = divideFromPll1Out >> 1; //SYSREF frequency is (PLL1)VCXO frequency / 2 / device->sysrefSettings->sysrefDivide
|
||||
|
||||
CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL4, ®403);
|
||||
|
||||
reg403 = reg403 & ~0x01; //clear bit 0 to stop a continuous sysref if it is on.
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL4, reg403);
|
||||
|
||||
reg403 = reg403 & ~0x3E; //clear bits for pattern mode and Nshot mode bitfields
|
||||
reg403 = reg403 | ((sysrefPatternMode & 0x3) << 4) | ((nShotPulses & 0x7) << 1);
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL4, reg403); //update internal sysref pattern mode and Nshot mode (number of pulses)
|
||||
|
||||
//SYSREF request bit x403[0] is left 0. The next call to AD9528_requestSysref will start the SYSREF
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_IO_UPDATE, 0x01); //IO update to make all these settings valid in the 9528
|
||||
|
||||
|
||||
return ADIERR_OK;
|
||||
}
|
||||
|
||||
/// Update the AD9528 clock outputs that are enabled.
|
||||
/*******************************************************************************//**
|
||||
* NOTE: this function will update the device structure with the parameter values passed
|
||||
* into this function. The device->sysrefSettings->sysrefPatternMode, device->sysrefSettings->sysrefNshotMode,
|
||||
* and device->sysrefSettings->sysrefDivide values will be updated in the device structure.
|
||||
*
|
||||
* <B>Dependencies</B>
|
||||
* - device->spiSettings
|
||||
*
|
||||
* \param device is structure pointer to AD9528 clock device structure
|
||||
* \param clkEnable Sets which clock outputs are enabled. Bit per clock output. bit0 = out0, etc.
|
||||
*
|
||||
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
|
||||
***********************************************************************************/
|
||||
ADI_ERR AD9528_enableClockOutputs(ad9528Device_t *device, uint16_t clkEnable)
|
||||
{ //clkEnable: bit per clock output
|
||||
|
||||
device->outputSettings->outPowerDown = ~clkEnable;
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_POWERDOWN1, device->outputSettings->outPowerDown & 0xFF); //power down out[7:0]
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_POWERDOWN2, ((device->outputSettings->outPowerDown >> 8) & 0x3F)); //power down out[13:8]
|
||||
|
||||
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_IO_UPDATE, 0x01); //IO update to make all these settings valid in the 9528
|
||||
return ADIERR_OK;
|
||||
}
|
||||
|
||||
/// Waits for PLL1 and PLL2 to lock and the REFA and VCXO clocks to be present
|
||||
/*******************************************************************************//**
|
||||
* Waits until Reference A clock and VCXO clock input to be detected (present),
|
||||
* and PLL1 and PLL2 to lock. Will timeout after 1 second and return ADIERR_FAILED.
|
||||
* If clock are detected and PLLs locked, returns ADIERR_OK.
|
||||
*
|
||||
* <B>Dependencies</B>
|
||||
* - device->spiSettings
|
||||
*
|
||||
* \param device is structure pointer to AD9528 clock device structure
|
||||
*
|
||||
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
|
||||
***********************************************************************************/
|
||||
ADI_ERR AD9528_waitForPllLock(ad9528Device_t *device)
|
||||
{
|
||||
uint8_t reg508;
|
||||
|
||||
CMB_setTimeout_ms(1000);
|
||||
do{
|
||||
CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_STATUS_READBACK0, ®508);
|
||||
if(CMB_hasTimeoutExpired() > 0)
|
||||
{
|
||||
return ADIERR_FAILED;
|
||||
}
|
||||
}while((reg508 & 0x27) != 0x27);
|
||||
|
||||
return ADIERR_OK;
|
||||
}
|
||||
|
||||
/// Reads the Lock Status of the PLLs and present detect of the reference clocks
|
||||
/*******************************************************************************//**
|
||||
* NOTE: This is a non blocking function that reads a register to see if PLL1
|
||||
* and PLL2 are locked and Reference clock A and the VCXO input clock are
|
||||
* detected (present). If the *status parameter is not NULL, the status will
|
||||
* be returned. If *status is NULL, the error return value will denote if
|
||||
* the PllStatus is locked or not with ADIERR_OK or ADIERR_FAILED.
|
||||
*
|
||||
* <B>Dependencies</B>
|
||||
* - device->spiSettings
|
||||
*
|
||||
* \param device is structure pointer to AD9528 clock device structure
|
||||
*
|
||||
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
|
||||
***********************************************************************************/
|
||||
ADI_ERR AD9528_readPllStatus(ad9528Device_t *device, uint8_t *status)
|
||||
{
|
||||
uint8_t reg508;
|
||||
|
||||
//bit5 is VCXO clock detected
|
||||
//bit2 is REFCLK A detected
|
||||
//bit1 is PLL2 lock detect
|
||||
//bit0 is PLL1 lock detect
|
||||
|
||||
/* read twice to refresh status bits */
|
||||
CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_STATUS_READBACK0, ®508);
|
||||
CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_STATUS_READBACK0, ®508);
|
||||
/* if status is a valid pointer, return the PLL status */
|
||||
if (status > 0)
|
||||
{
|
||||
*status = reg508;
|
||||
}
|
||||
|
||||
/* PLLs 1 and 2 are locked and VCXO and REFA detected if reg508 has bits 5,2,1 and 0 set */
|
||||
if((reg508 & 0x27) == 0x27)
|
||||
return ADIERR_OK;
|
||||
else
|
||||
return ADIERR_FAILED;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/**
|
||||
* \file ad9528.h
|
||||
* \brief Contains function declarations and ad9528Device_t structure typedef for ad9528.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* \page Disclaimer Legal Disclaimer
|
||||
* Copyright 2015-2017 Analog Devices Inc.
|
||||
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AD9528_LIB_H_
|
||||
#define _AD9528_LIB_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../common.h"
|
||||
#include "t_ad9528.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CLEMENTE_TDD_AD9528_CLKOUT_INDEX 13
|
||||
|
||||
//Helper function to setup the 9528 device data structure specifically for the ADI transceiver evaluation cards
|
||||
ADI_ERR AD9528_initDeviceDataStruct(ad9528Device_t *device, uint32_t vcxoFrequency_Hz, uint32_t refAFrequency_Hz, uint32_t outputDeviceClock_Hz);
|
||||
ADI_ERR AD9528_reportClockRates(ad9528Device_t *device); //debug function to help verify data structure is setup correctly.
|
||||
|
||||
//AD9528 API functions
|
||||
ADI_ERR AD9528_resetDevice(ad9528Device_t *device);
|
||||
ADI_ERR AD9528_setSpiSettings(ad9528Device_t *device);
|
||||
ADI_ERR AD9528_initialize(ad9528Device_t *device); //writes all registers to desired values, leaves clock outputs off.
|
||||
ADI_ERR AD9528_waitForPllLock(ad9528Device_t *device);
|
||||
ADI_ERR AD9528_readPllStatus(ad9528Device_t *device, uint8_t *status);
|
||||
ADI_ERR AD9528_enableClockOutputs(ad9528Device_t *device, uint16_t clkEnable); //clkEnable: bit per clock output
|
||||
ADI_ERR AD9528_setupSYSREF(ad9528Device_t *device, uint16_t divideFromPll1Out, sysrefPatternMode_t sysrefPatternMode, sysrefNshotMode_t nShotPulses);
|
||||
ADI_ERR AD9528_requestSysref(ad9528Device_t *device, uint8_t enableSYSREF);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,277 +0,0 @@
|
||||
/*!
|
||||
* \file mykonos.h
|
||||
* \brief Contains macro definitions and function prototypes for mykonos.c
|
||||
*
|
||||
* Mykonos API version: 1.5.2.3566
|
||||
*/
|
||||
|
||||
/**
|
||||
* \page Disclaimer Legal Disclaimer
|
||||
* Copyright 2015-2017 Analog Devices Inc.
|
||||
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MYKONOS_LIB_H_
|
||||
#define _MYKONOS_LIB_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "t_mykonos.h"
|
||||
#include "mykonos_version.h"
|
||||
|
||||
#define TX_PROFILE_VALID 0x01
|
||||
#define RX_PROFILE_VALID 0x02
|
||||
#define ORX_PROFILE_VALID 0x04
|
||||
#define SNIFF_PROFILE_VALID 0x08
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* General Initialization functions
|
||||
****************************************************************************
|
||||
*/
|
||||
mykonosErr_t MYKONOS_resetDevice(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_getDeviceRev(mykonosDevice_t *device, uint8_t *revision);
|
||||
mykonosErr_t MYKONOS_getProductId(mykonosDevice_t *device, uint8_t *productId);
|
||||
mykonosErr_t MYKONOS_setSpiSettings(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_verifyDeviceDataStructure(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_verifyProfiles(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_initialize(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_waitForEvent(mykonosDevice_t *device, waitEvent_t waitEvent, uint32_t timeout_us);
|
||||
mykonosErr_t MYKONOS_readEventStatus(mykonosDevice_t *device, waitEvent_t waitEvent, uint8_t *eventDone);
|
||||
mykonosErr_t MYKONOS_getApiVersion (mykonosDevice_t *device, uint32_t *siVer, uint32_t *majorVer, uint32_t *minorVer, uint32_t *buildVer);
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* PLL / Synthesizer functions
|
||||
*****************************************************************************
|
||||
*/
|
||||
mykonosErr_t MYKONOS_initDigitalClocks(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_setRfPllFrequency(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint64_t rfPllLoFrequency_Hz);
|
||||
mykonosErr_t MYKONOS_getRfPllFrequency(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint64_t *rfPllLoFrequency_Hz);
|
||||
mykonosErr_t MYKONOS_checkPllsLockStatus(mykonosDevice_t *device, uint8_t *pllLockStatus);
|
||||
mykonosErr_t MYKONOS_setRfPllLoopFilter(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint16_t loopBandwidth_kHz, uint8_t stability);
|
||||
mykonosErr_t MYKONOS_getRfPllLoopFilter(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint16_t *loopBandwidth_kHz, uint8_t *stability);
|
||||
/*
|
||||
*****************************************************************************
|
||||
* ARM Processor Control Functions
|
||||
*****************************************************************************
|
||||
*/
|
||||
mykonosErr_t MYKONOS_initArm(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_loadArmFromBinary(mykonosDevice_t *device, uint8_t *binary, uint32_t count);
|
||||
mykonosErr_t MYKONOS_loadArmConcurrent(mykonosDevice_t *device, uint8_t *binary, uint32_t count);
|
||||
mykonosErr_t MYKONOS_verifyArmChecksum(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_checkArmState(mykonosDevice_t *device, mykonosArmState_t armStateCheck);
|
||||
mykonosErr_t MYKONOS_getArmVersion(mykonosDevice_t *device, uint8_t *majorVer, uint8_t *minorVer, uint8_t *rcVer, mykonosBuild_t *buildType);
|
||||
|
||||
mykonosErr_t MYKONOS_configDpd(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_getDpdConfig(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_getDpdStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosDpdStatus_t *dpdStatus);
|
||||
mykonosErr_t MYKONOS_restoreDpdModel(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t *modelDataBuffer, uint32_t modelNumberBytes);
|
||||
mykonosErr_t MYKONOS_saveDpdModel(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t *modelDataBuffer, uint32_t modelNumberBytes);
|
||||
mykonosErr_t MYKONOS_setDpdActState(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t actState);
|
||||
mykonosErr_t MYKONOS_resetDpd(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosDpdResetMode_t reset);
|
||||
mykonosErr_t MYKONOS_setDpdBypassConfig(mykonosDevice_t *device, mykonosDpdBypassConfig_t *actConfig);
|
||||
mykonosErr_t MYKONOS_getDpdBypassConfig(mykonosDevice_t *device, mykonosDpdBypassConfig_t *actConfig);
|
||||
mykonosErr_t MYKONOS_setDpdActuatorCheck(mykonosDevice_t *device, mykonosDpdActuatorCheck_t *actCheck);
|
||||
mykonosErr_t MYKONOS_getDpdActuatorCheck(mykonosDevice_t *device, mykonosDpdActuatorCheck_t *actCheck);
|
||||
|
||||
mykonosErr_t MYKONOS_setClgcAttenTuningConfig(mykonosDevice_t *device, mykonosClgcAttenTuningConfig_t *attRangeCfg);
|
||||
mykonosErr_t MYKONOS_getClgcAttenTuningConfig(mykonosDevice_t *device, mykonosClgcAttenTuningConfig_t *attRangeCfg);
|
||||
|
||||
mykonosErr_t MYKONOS_configClgc(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_getClgcConfig(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_getClgcStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosClgcStatus_t *clgcStatus);
|
||||
mykonosErr_t MYKONOS_setClgcGain(mykonosDevice_t *device, mykonosTxChannels_t txChannel, int16_t gain);
|
||||
|
||||
mykonosErr_t MYKONOS_configVswr(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_getVswrConfig(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_getVswrStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosVswrStatus_t *vswrStatus);
|
||||
|
||||
mykonosErr_t MYKONOS_runInitCals(mykonosDevice_t *device, uint32_t calMask);
|
||||
mykonosErr_t MYKONOS_waitInitCals(mykonosDevice_t *device, uint32_t timeoutMs, uint8_t *errorFlag, uint8_t *errorCode);
|
||||
mykonosErr_t MYKONOS_abortInitCals(mykonosDevice_t *device, uint32_t *calsCompleted);
|
||||
mykonosErr_t MYKONOS_getInitCalStatus(mykonosDevice_t *device, mykonosInitCalStatus_t *initCalStatus);
|
||||
|
||||
mykonosErr_t MYKONOS_resetExtTxLolChannel(mykonosDevice_t *device, mykonosTxChannels_t channelSel);
|
||||
|
||||
mykonosErr_t MYKONOS_radioOn(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_radioOff(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_getRadioState(mykonosDevice_t *device, uint32_t *radioStatus);
|
||||
mykonosErr_t MYKONOS_enableTrackingCals(mykonosDevice_t *device, uint32_t enableMask);
|
||||
mykonosErr_t MYKONOS_rescheduleTrackingCal(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal);
|
||||
mykonosErr_t MYKONOS_setAllTrackCalState(mykonosDevice_t *device, uint32_t trackingCalMask);
|
||||
mykonosErr_t MYKONOS_getAllTrackCalState(mykonosDevice_t *device, uint32_t *trackCals);
|
||||
mykonosErr_t MYKONOS_setTrackingCalState(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal, uint8_t trackCalState);
|
||||
mykonosErr_t MYKONOS_getTrackingCalState(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal, uint8_t *trackCalState);
|
||||
mykonosErr_t MYKONOS_getEnabledTrackingCals(mykonosDevice_t *device, uint32_t *enableMask);
|
||||
mykonosErr_t MYKONOS_getPendingTrackingCals(mykonosDevice_t *device, uint32_t *pendingCalMask);
|
||||
mykonosErr_t MYKONOS_getTxLolStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosTxLolStatus_t *txLolStatus);
|
||||
mykonosErr_t MYKONOS_getTxQecStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosTxQecStatus_t *txQecStatus);
|
||||
|
||||
mykonosErr_t MYKONOS_getRxQecStatus(mykonosDevice_t *device, mykonosRxChannels_t rxChannel, mykonosRxQecStatus_t *rxQecStatus);
|
||||
mykonosErr_t MYKONOS_getOrxQecStatus(mykonosDevice_t *device, mykonosObsRxChannels_t orxChannel, mykonosOrxQecStatus_t *orxQecStatus);
|
||||
|
||||
mykonosErr_t MYKONOS_setSnifferChannel(mykonosDevice_t *device, mykonosSnifferChannel_t snifferChannel);
|
||||
mykonosErr_t MYKONOS_setRadioControlPinMode(mykonosDevice_t *device);
|
||||
|
||||
mykonosErr_t MYKONOS_setPathDelay(mykonosDevice_t *device, mykonosPathdelay_t *pathDelay);
|
||||
mykonosErr_t MYKONOS_getPathDelay(mykonosDevice_t *device, mykonosPathDelaySel_t select, mykonosPathdelay_t *pathDelay);
|
||||
|
||||
mykonosErr_t MYKONOS_getDpdErrorCounters(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosDpdErrorCounters_t *dpdErrCnt);
|
||||
|
||||
/* Low level ARM functions */
|
||||
mykonosErr_t MYKONOS_readArmMem(mykonosDevice_t *device, uint32_t address, uint8_t *returnData, uint32_t bytesToRead, uint8_t autoIncrement);
|
||||
mykonosErr_t MYKONOS_writeArmMem(mykonosDevice_t *device, uint32_t address, uint8_t *data, uint32_t byteCount);
|
||||
mykonosErr_t MYKONOS_writeArmConfig(mykonosDevice_t *device, uint8_t objectId, uint16_t offset, uint8_t *data, uint8_t byteCount);
|
||||
mykonosErr_t MYKONOS_readArmConfig(mykonosDevice_t *device, uint8_t objectId, uint16_t offset, uint8_t *data, uint8_t byteCount);
|
||||
mykonosErr_t MYKONOS_sendArmCommand(mykonosDevice_t *device, uint8_t opCode, uint8_t *extendedData, uint8_t extendedDataNumBytes);
|
||||
mykonosErr_t MYKONOS_readArmCmdStatus(mykonosDevice_t *device, uint16_t *errorWord, uint16_t *statusWord);
|
||||
mykonosErr_t MYKONOS_readArmCmdStatusByte(mykonosDevice_t *device, uint8_t opCode, uint8_t *cmdStatByte);
|
||||
mykonosErr_t MYKONOS_waitArmCmdStatus(mykonosDevice_t *device, uint8_t opCode, uint32_t timeoutMs, uint8_t *cmdStatByte);
|
||||
mykonosErr_t MYKONOS_writeArmProfile(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_loadAdcProfiles(mykonosDevice_t *device);
|
||||
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* JESD204B Datapath Functions
|
||||
*****************************************************************************
|
||||
*/
|
||||
/* Functions to setup the JESD204B IP */
|
||||
mykonosErr_t MYKONOS_resetDeframer(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_setupSerializers(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_setupDeserializers(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_setupJesd204bFramer(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_setupJesd204bObsRxFramer(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_setupJesd204bDeframer(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_enableRxFramerLink(mykonosDevice_t *device, uint8_t enable);
|
||||
mykonosErr_t MYKONOS_enableObsRxFramerLink(mykonosDevice_t *device, uint8_t enable);
|
||||
|
||||
/* Functions to initialize the JESD204B link */
|
||||
mykonosErr_t MYKONOS_enableMultichipSync(mykonosDevice_t *device, uint8_t enableMcs, uint8_t *mcsStatus);
|
||||
mykonosErr_t MYKONOS_enableSysrefToRxFramer(mykonosDevice_t *device, uint8_t enable);
|
||||
mykonosErr_t MYKONOS_enableSysrefToObsRxFramer(mykonosDevice_t *device, uint8_t enable);
|
||||
mykonosErr_t MYKONOS_enableSysrefToDeframer(mykonosDevice_t *device, uint8_t enable);
|
||||
|
||||
/* Functions to help debug the JESD204B link */
|
||||
mykonosErr_t MYKONOS_readRxFramerStatus(mykonosDevice_t *device, uint8_t *framerStatus);
|
||||
mykonosErr_t MYKONOS_readOrxFramerStatus(mykonosDevice_t *device, uint8_t *obsFramerStatus);
|
||||
mykonosErr_t MYKONOS_readDeframerStatus(mykonosDevice_t *device, uint8_t *deframerStatus);
|
||||
mykonosErr_t MYKONOS_getDeframerFifoDepth(mykonosDevice_t *device, uint8_t *fifoDepth, uint8_t *readEnLmfcCount);
|
||||
|
||||
/* PRBS debug functions */
|
||||
mykonosErr_t MYKONOS_enableRxFramerPrbs(mykonosDevice_t *device, mykonosPrbsOrder_t polyOrder, uint8_t enable);
|
||||
mykonosErr_t MYKONOS_enableObsRxFramerPrbs(mykonosDevice_t *device, mykonosPrbsOrder_t polyOrder, uint8_t enable);
|
||||
mykonosErr_t MYKONOS_rxInjectPrbsError(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_obsRxInjectPrbsError(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_enableDeframerPrbsChecker(mykonosDevice_t *device, uint8_t lanes, mykonosPrbsOrder_t polyOrder, uint8_t enable);
|
||||
mykonosErr_t MYKONOS_clearDeframerPrbsCounters(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_readDeframerPrbsCounters(mykonosDevice_t *device, uint8_t counterSelect, uint32_t *prbsErrorCount);
|
||||
|
||||
/* Miscellaneous debug functions */
|
||||
mykonosErr_t MYKONOS_jesd204bIlasCheck(mykonosDevice_t *device, uint16_t *mismatch);
|
||||
mykonosErr_t MYKONOS_setRxFramerDataSource(mykonosDevice_t *device, uint8_t dataSource);
|
||||
mykonosErr_t MYKONOS_setObsRxFramerDataSource(mykonosDevice_t *device, uint8_t dataSource);
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Shared Data path functions
|
||||
*****************************************************************************
|
||||
*/
|
||||
mykonosErr_t MYKONOS_programFir(mykonosDevice_t *device, mykonosfirName_t filterToProgram, mykonosFir_t *firFilter);
|
||||
mykonosErr_t MYKONOS_readFir(mykonosDevice_t *device, mykonosfirName_t filterToRead, mykonosFir_t *firFilter);
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Rx Data path functions
|
||||
*****************************************************************************
|
||||
*/
|
||||
mykonosErr_t MYKONOS_programRxGainTable(mykonosDevice_t *device, uint8_t *gainTablePtr, uint8_t numGainIndexesInTable, mykonosGainTable_t rxChannel);
|
||||
mykonosErr_t MYKONOS_setRx1ManualGain(mykonosDevice_t *device, uint8_t gainIndex);
|
||||
mykonosErr_t MYKONOS_setRx2ManualGain(mykonosDevice_t *device, uint8_t gainIndex);
|
||||
mykonosErr_t MYKONOS_getRx1Gain(mykonosDevice_t *device, uint8_t *rx1GainIndex);
|
||||
mykonosErr_t MYKONOS_getRx2Gain(mykonosDevice_t *device, uint8_t *rx2GainIndex);
|
||||
mykonosErr_t MYKONOS_setupRxAgc(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_resetRxAgc(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_setRxAgcMinMaxGainIndex(mykonosDevice_t *device, mykonosRxChannels_t rxChannelSelect, uint8_t maxGainIndex, uint8_t minGainIndex);
|
||||
mykonosErr_t MYKONOS_setObsRxAgcMinMaxGainIndex(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxChannelSelect, uint8_t maxGainIndex, uint8_t minGainIndex);
|
||||
mykonosErr_t MYKONOS_setRx1TempGainComp(mykonosDevice_t *device, int16_t rx1TempCompGain_mdB);
|
||||
mykonosErr_t MYKONOS_getRx1TempGainComp(mykonosDevice_t *device, int16_t *rx1TempCompGain_mdB);
|
||||
mykonosErr_t MYKONOS_setRx2TempGainComp(mykonosDevice_t *device, int16_t rx2TempCompGain_mdB);
|
||||
mykonosErr_t MYKONOS_getRx2TempGainComp(mykonosDevice_t *device, int16_t *rx2TempCompGain_mdB);
|
||||
mykonosErr_t MYKONOS_setObsRxTempGainComp(mykonosDevice_t *device, int16_t obsRxTempCompGain_mdB);
|
||||
mykonosErr_t MYKONOS_getObsRxTempGainComp(mykonosDevice_t *device, int16_t *obsRxTempCompGain_mdB);
|
||||
mykonosErr_t MYKONOS_enableRxGainCtrSyncPulse(mykonosDevice_t *device, uint8_t enable);
|
||||
mykonosErr_t MYKONOS_setRxGainControlMode(mykonosDevice_t *device, mykonosGainMode_t mode);
|
||||
mykonosErr_t MYKONOS_getRx1DecPower(mykonosDevice_t *device, uint16_t *rx1DecPower_mdBFS);
|
||||
mykonosErr_t MYKONOS_getRx2DecPower(mykonosDevice_t *device, uint16_t *rx2DecPower_mdBFS);
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Observation Rx Data path functions
|
||||
*****************************************************************************
|
||||
*/
|
||||
mykonosErr_t MYKONOS_setDefaultObsRxPath(mykonosDevice_t *device, mykonosObsRxChannels_t defaultObsRxCh);
|
||||
mykonosErr_t MYKONOS_setObsRxPathSource(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxCh);
|
||||
mykonosErr_t MYKONOS_getObsRxPathSource(mykonosDevice_t *device, mykonosObsRxChannels_t *obsRxCh);
|
||||
mykonosErr_t MYKONOS_setObsRxManualGain(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxCh, uint8_t gainIndex);
|
||||
mykonosErr_t MYKONOS_getObsRxGain(mykonosDevice_t *device, uint8_t *gainIndex);
|
||||
mykonosErr_t MYKONOS_setupObsRxAgc(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_enableObsRxGainCtrSyncPulse(mykonosDevice_t *device, uint8_t enable);
|
||||
mykonosErr_t MYKONOS_setObsRxGainControlMode(mykonosDevice_t *device, mykonosGainMode_t mode);
|
||||
mykonosErr_t MYKONOS_getObsRxDecPower(mykonosDevice_t *device, uint16_t *obsRxDecPower_mdBFS);
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Tx Data path functions
|
||||
*****************************************************************************
|
||||
*/
|
||||
mykonosErr_t MYKONOS_setTx1Attenuation(mykonosDevice_t *device, uint16_t tx1Attenuation_mdB);
|
||||
mykonosErr_t MYKONOS_setTx2Attenuation(mykonosDevice_t *device, uint16_t tx2Attenuation_mdB);
|
||||
mykonosErr_t MYKONOS_getTx1Attenuation(mykonosDevice_t *device, uint16_t *tx1Attenuation_mdB);
|
||||
mykonosErr_t MYKONOS_getTx2Attenuation(mykonosDevice_t *device, uint16_t *tx2Attenuation_mdB);
|
||||
mykonosErr_t MYKONOS_getTxFilterOverRangeStatus(mykonosDevice_t *device, uint8_t *txFilterStatus);
|
||||
mykonosErr_t MYKONOS_enableTxNco(mykonosDevice_t *device, uint8_t enable, int32_t tx1ToneFreq_kHz, int32_t tx2ToneFreq_kHz);
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* PA Protection Functions
|
||||
*****************************************************************************
|
||||
*/
|
||||
mykonosErr_t MYKONOS_setupPaProtection(mykonosDevice_t *device, uint16_t powerThreshold, uint8_t attenStepSize, uint8_t avgDuration, uint8_t stickyFlagEnable, uint8_t txAttenControlEnable);
|
||||
mykonosErr_t MYKONOS_enablePaProtection(mykonosDevice_t *device, uint8_t enable);
|
||||
mykonosErr_t MYKONOS_getDacPower(mykonosDevice_t *device, mykonosTxChannels_t channel, uint16_t *channelPower);
|
||||
mykonosErr_t MYKONOS_getPaProtectErrorFlagStatus(mykonosDevice_t *device, uint8_t *errorFlagStatus);
|
||||
mykonosErr_t MYKONOS_clearPaErrorFlag(mykonosDevice_t *device);
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Low level functions and helper functions. BBP should not need to call
|
||||
*****************************************************************************
|
||||
*/
|
||||
const char* getMykonosErrorMessage(mykonosErr_t errorCode);
|
||||
|
||||
mykonosErr_t MYKONOS_initSubRegisterTables(mykonosDevice_t *device);
|
||||
mykonosErr_t MYKONOS_setTxPfirSyncClk(mykonosDevice_t *device); /* Helper function */
|
||||
mykonosErr_t MYKONOS_setRxPfirSyncClk(mykonosDevice_t *device); /* Helper function */
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Functions to configure DC offsets
|
||||
*****************************************************************************
|
||||
*/
|
||||
mykonosErr_t MYKONOS_setRfDcOffsetCnt(mykonosDevice_t *device, mykonosDcOffsetChannels_t channel, uint16_t measureCount);
|
||||
mykonosErr_t MYKONOS_getRfDcOffsetCnt(mykonosDevice_t *device, mykonosDcOffsetChannels_t channel, uint16_t *measureCount);
|
||||
mykonosErr_t MYKONOS_setDigDcOffsetMShift(mykonosDevice_t *device, mykonosDcOffsetChannels_t channel, uint8_t mShift);
|
||||
mykonosErr_t MYKONOS_getDigDcOffsetMShift(mykonosDevice_t *device, mykonosDcOffsetChannels_t channel, uint8_t *mShift);
|
||||
mykonosErr_t MYKONOS_setDigDcOffsetEn(mykonosDevice_t *device, uint8_t enableMask);
|
||||
mykonosErr_t MYKONOS_getDigDcOffsetEn(mykonosDevice_t *device, uint8_t *enableMask);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,136 +0,0 @@
|
||||
/**
|
||||
* \file mykonosMmap.c
|
||||
* \brief Contains the Mykonos memory mapping
|
||||
*
|
||||
* Mykonos API version: 1.5.2.3566
|
||||
*/
|
||||
|
||||
/**
|
||||
* \page Disclaimer Legal Disclaimer
|
||||
* Copyright 2015-2017 Analog Devices Inc.
|
||||
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
uint8_t mykonosMmap [] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x13,0x03,0x03,0x13,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
|
||||
0x00,0xE4,0xE4,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA5,0xA5,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x01,0x00,0xE4,0xE4,0x00,0x00,0x00,0x1F,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9F,0xE0,0x20,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xF5,0x8F,0x0F,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
/*!< Mykonos memory map */
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user