Author SHA1 Message Date
josh ca75a51f75 Merge branch 'tx_qpsk_poly'
vivado version need to be updated, the developing goal is change to qam and psk multi-variate signal generator
2024-10-27 11:22:58 +08:00
josh 8a5c992b1c update zc706_cx9261a_demo
remove hop axi gpio, add hop control to ps gpio
2024-10-27 11:15:33 +08:00
josh a8ea62ab3d add zc706_cx9261a_demo vitis project, hop function needs further development 2024-10-25 15:17:18 +08:00
josh 9103a45487 add zc706_cx9261a_demo vivado project 2024-10-25 15:15:51 +08:00
josh eb40f1ba27 [WIP] polyphase qpsk transmitter 2024-01-24 11:17:05 +08:00
1767 changed files with 725838 additions and 0 deletions
@@ -0,0 +1,776 @@
; XILINX CORE Generator v1.0
; Copyright 2023 Gatsby Van <[email protected]>
; generated by MATLAB 23.2 (R2023b)
; generated at: 15-Jan-2024 11:07:53 +0800
RADIX = 10;
COEFDATA =
-46,
-30,
-13,
5,
22,
39,
56,
73,
90,
106,
123,
138,
154,
168,
183,
196,
209,
221,
233,
243,
253,
261,
269,
276,
281,
286,
289,
291,
292,
292,
291,
289,
285,
280,
274,
267,
259,
250,
240,
228,
216,
202,
188,
173,
157,
140,
122,
104,
85,
66,
46,
26,
6,
-15,
-35,
-56,
-77,
-97,
-117,
-138,
-157,
-176,
-195,
-213,
-230,
-247,
-262,
-277,
-290,
-303,
-314,
-324,
-333,
-340,
-346,
-351,
-354,
-355,
-355,
-354,
-351,
-346,
-339,
-331,
-322,
-310,
-297,
-283,
-267,
-250,
-231,
-210,
-189,
-166,
-142,
-116,
-90,
-63,
-34,
-5,
24,
55,
85,
116,
148,
179,
211,
242,
273,
304,
334,
364,
393,
421,
448,
473,
498,
521,
542,
562,
581,
597,
611,
623,
634,
641,
647,
650,
651,
649,
645,
638,
628,
616,
600,
583,
562,
539,
513,
485,
454,
420,
384,
345,
305,
261,
216,
169,
120,
69,
17,
-37,
-93,
-149,
-207,
-265,
-324,
-383,
-442,
-502,
-561,
-620,
-678,
-736,
-792,
-848,
-901,
-953,
-1003,
-1051,
-1097,
-1140,
-1180,
-1217,
-1252,
-1282,
-1309,
-1333,
-1353,
-1368,
-1379,
-1386,
-1389,
-1387,
-1380,
-1369,
-1352,
-1331,
-1305,
-1274,
-1238,
-1197,
-1151,
-1100,
-1044,
-983,
-917,
-847,
-773,
-694,
-610,
-523,
-432,
-337,
-239,
-137,
-32,
75,
185,
297,
410,
526,
642,
760,
877,
995,
1113,
1231,
1347,
1462,
1575,
1686,
1795,
1900,
2003,
2101,
2196,
2286,
2371,
2451,
2525,
2594,
2656,
2711,
2759,
2800,
2834,
2859,
2877,
2886,
2886,
2878,
2861,
2834,
2798,
2753,
2698,
2634,
2560,
2476,
2383,
2280,
2168,
2047,
1916,
1776,
1627,
1470,
1304,
1130,
949,
759,
563,
360,
151,
-64,
-284,
-509,
-738,
-971,
-1208,
-1446,
-1687,
-1929,
-2171,
-2413,
-2655,
-2895,
-3133,
-3368,
-3599,
-3826,
-4047,
-4263,
-4471,
-4673,
-4866,
-5049,
-5223,
-5387,
-5539,
-5679,
-5806,
-5920,
-6019,
-6104,
-6173,
-6226,
-6262,
-6281,
-6281,
-6264,
-6227,
-6171,
-6095,
-5999,
-5882,
-5744,
-5585,
-5404,
-5202,
-4978,
-4732,
-4463,
-4173,
-3861,
-3526,
-3170,
-2791,
-2391,
-1970,
-1528,
-1065,
-582,
-79,
444,
986,
1546,
2123,
2718,
3329,
3956,
4597,
5253,
5922,
6603,
7296,
7999,
8711,
9432,
10160,
10895,
11635,
12379,
13126,
13875,
14625,
15374,
16122,
16866,
17607,
18343,
19072,
19793,
20506,
21209,
21900,
22579,
23245,
23897,
24532,
25151,
25752,
26334,
26897,
27438,
27958,
28455,
28929,
29378,
29802,
30200,
30572,
30916,
31232,
31520,
31780,
32009,
32209,
32379,
32518,
32627,
32705,
32751,
32767,
32751,
32705,
32627,
32518,
32379,
32209,
32009,
31780,
31520,
31232,
30916,
30572,
30200,
29802,
29378,
28929,
28455,
27958,
27438,
26897,
26334,
25752,
25151,
24532,
23897,
23245,
22579,
21900,
21209,
20506,
19793,
19072,
18343,
17607,
16866,
16122,
15374,
14625,
13875,
13126,
12379,
11635,
10895,
10160,
9432,
8711,
7999,
7296,
6603,
5922,
5253,
4597,
3956,
3329,
2718,
2123,
1546,
986,
444,
-79,
-582,
-1065,
-1528,
-1970,
-2391,
-2791,
-3170,
-3526,
-3861,
-4173,
-4463,
-4732,
-4978,
-5202,
-5404,
-5585,
-5744,
-5882,
-5999,
-6095,
-6171,
-6227,
-6264,
-6281,
-6281,
-6262,
-6226,
-6173,
-6104,
-6019,
-5920,
-5806,
-5679,
-5539,
-5387,
-5223,
-5049,
-4866,
-4673,
-4471,
-4263,
-4047,
-3826,
-3599,
-3368,
-3133,
-2895,
-2655,
-2413,
-2171,
-1929,
-1687,
-1446,
-1208,
-971,
-738,
-509,
-284,
-64,
151,
360,
563,
759,
949,
1130,
1304,
1470,
1627,
1776,
1916,
2047,
2168,
2280,
2383,
2476,
2560,
2634,
2698,
2753,
2798,
2834,
2861,
2878,
2886,
2886,
2877,
2859,
2834,
2800,
2759,
2711,
2656,
2594,
2525,
2451,
2371,
2286,
2196,
2101,
2003,
1900,
1795,
1686,
1575,
1462,
1347,
1231,
1113,
995,
877,
760,
642,
526,
410,
297,
185,
75,
-32,
-137,
-239,
-337,
-432,
-523,
-610,
-694,
-773,
-847,
-917,
-983,
-1044,
-1100,
-1151,
-1197,
-1238,
-1274,
-1305,
-1331,
-1352,
-1369,
-1380,
-1387,
-1389,
-1386,
-1379,
-1368,
-1353,
-1333,
-1309,
-1282,
-1252,
-1217,
-1180,
-1140,
-1097,
-1051,
-1003,
-953,
-901,
-848,
-792,
-736,
-678,
-620,
-561,
-502,
-442,
-383,
-324,
-265,
-207,
-149,
-93,
-37,
17,
69,
120,
169,
216,
261,
305,
345,
384,
420,
454,
485,
513,
539,
562,
583,
600,
616,
628,
638,
645,
649,
651,
650,
647,
641,
634,
623,
611,
597,
581,
562,
542,
521,
498,
473,
448,
421,
393,
364,
334,
304,
273,
242,
211,
179,
148,
116,
85,
55,
24,
-5,
-34,
-63,
-90,
-116,
-142,
-166,
-189,
-210,
-231,
-250,
-267,
-283,
-297,
-310,
-322,
-331,
-339,
-346,
-351,
-354,
-355,
-355,
-354,
-351,
-346,
-340,
-333,
-324,
-314,
-303,
-290,
-277,
-262,
-247,
-230,
-213,
-195,
-176,
-157,
-138,
-117,
-97,
-77,
-56,
-35,
-15,
6,
26,
46,
66,
85,
104,
122,
140,
157,
173,
188,
202,
216,
228,
240,
250,
259,
267,
274,
280,
285,
289,
291,
292,
292,
291,
289,
286,
281,
276,
269,
261,
253,
243,
233,
221,
209,
196,
183,
168,
154,
138,
123,
106,
90,
73,
56,
39,
22,
5,
-13,
-30,
-46;
@@ -0,0 +1,349 @@
{
"schema": "xilinx.com:schema:json_instance:1.0",
"ip_inst": {
"xci_name": "hrc_256_12_025",
"component_reference": "xilinx.com:ip:fir_compiler:7.2",
"ip_revision": "20",
"gen_directory": "../../../../tx_qpsk_poly.gen/sources_1/ip/hrc_256_12_025",
"parameters": {
"component_parameters": {
"Component_Name": [ { "value": "hrc_256_12_025", "resolve_type": "user", "usage": "all" } ],
"GUI_Behaviour": [ { "value": "Coregen", "resolve_type": "user", "usage": "all" } ],
"CoefficientSource": [ { "value": "COE_File", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"CoefficientVector": [ { "value": "6,0,-4,-3,5,6,-6,-13,7,44,64,44,7,-13,-6,6,5,-3,-4,0,6", "resolve_type": "user", "usage": "all" } ],
"Coefficient_File": [ { "value": "../coe/hrc_256_12_025.coe", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Coefficient_Sets": [ { "value": "1", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Coefficient_Reload": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Filter_Type": [ { "value": "Interpolation", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Rate_Change_Type": [ { "value": "Integer", "resolve_type": "user", "usage": "all" } ],
"Interpolation_Rate": [ { "value": "256", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Decimation_Rate": [ { "value": "1", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Zero_Pack_Factor": [ { "value": "1", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Channel_Sequence": [ { "value": "Basic", "resolve_type": "user", "usage": "all" } ],
"Number_Channels": [ { "value": "1", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Select_Pattern": [ { "value": "All", "resolve_type": "user", "usage": "all" } ],
"Pattern_List": [ { "value": "P4-0,P4-1,P4-2,P4-3,P4-4", "resolve_type": "user", "usage": "all" } ],
"Number_Paths": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
"RateSpecification": [ { "value": "Input_Sample_Period", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"HardwareOversamplingRate": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
"SamplePeriod": [ { "value": "64", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Sample_Frequency": [ { "value": "0.001", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Clock_Frequency": [ { "value": "300.0", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Coefficient_Sign": [ { "value": "Signed", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Quantization": [ { "value": "Integer_Coefficients", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Coefficient_Width": [ { "value": "16", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"BestPrecision": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Coefficient_Fractional_Bits": [ { "value": "0", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Coefficient_Structure": [ { "value": "Inferred", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Data_Sign": [ { "value": "Signed", "resolve_type": "user", "usage": "all" } ],
"Data_Width": [ { "value": "2", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Data_Fractional_Bits": [ { "value": "0", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Output_Rounding_Mode": [ { "value": "Full_Precision", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Output_Width": [ { "value": "18", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Filter_Architecture": [ { "value": "Systolic_Multiply_Accumulate", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Optimization_Goal": [ { "value": "Area", "resolve_type": "user", "usage": "all" } ],
"Optimization_Selection": [ { "value": "None", "resolve_type": "user", "usage": "all" } ],
"Data_Path_Fanout": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Pre_Adder_Pipeline": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Coefficient_Fanout": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Control_Path_Fanout": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Control_Column_Fanout": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Control_Broadcast_Fanout": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Control_LUT_Pipeline": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"No_BRAM_Read_First_Mode": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Optimal_Column_Lengths": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Data_Path_Broadcast": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Disable_Half_Band_Centre_Tap": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"No_SRL_Attributes": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Other": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Optimization_List": [ { "value": "None", "resolve_type": "user", "usage": "all" } ],
"Data_Buffer_Type": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Coefficient_Buffer_Type": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Input_Buffer_Type": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Output_Buffer_Type": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Preference_For_Other_Storage": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Multi_Column_Support": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Inter_Column_Pipe_Length": [ { "value": "4", "resolve_type": "user", "format": "long", "usage": "all" } ],
"ColumnConfig": [ { "value": "13", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"DATA_Has_TLAST": [ { "value": "Not_Required", "resolve_type": "user", "usage": "all" } ],
"M_DATA_Has_TREADY": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"S_DATA_Has_FIFO": [ { "value": "false", "value_src": "user", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"S_DATA_Has_TUSER": [ { "value": "Not_Required", "resolve_type": "user", "usage": "all" } ],
"M_DATA_Has_TUSER": [ { "value": "Not_Required", "resolve_type": "user", "usage": "all" } ],
"DATA_TUSER_Width": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
"S_CONFIG_Sync_Mode": [ { "value": "On_Vector", "resolve_type": "user", "usage": "all" } ],
"S_CONFIG_Method": [ { "value": "Single", "resolve_type": "user", "usage": "all" } ],
"Num_Reload_Slots": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Has_ACLKEN": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Has_ARESETn": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Reset_Data_Vector": [ { "value": "true", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Blank_Output": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Gen_MIF_from_Spec": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Gen_MIF_from_COE": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Reload_File": [ { "value": "no_coe_file_loaded", "resolve_type": "user", "usage": "all" } ],
"Gen_MIF_Files": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"DisplayReloadOrder": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Passband_Min": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Passband_Max": [ { "value": "0.5", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Stopband_Min": [ { "value": "0.5", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Stopband_Max": [ { "value": "1.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Filter_Selection": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ]
},
"model_parameters": {
"C_XDEVICEFAMILY": [ { "value": "zynquplus", "resolve_type": "generated", "usage": "all" } ],
"C_ELABORATION_DIR": [ { "value": "./", "resolve_type": "generated", "usage": "all" } ],
"C_COMPONENT_NAME": [ { "value": "hrc_256_12_025", "resolve_type": "generated", "usage": "all" } ],
"C_COEF_FILE": [ { "value": "hrc_256_12_025.mif", "resolve_type": "generated", "usage": "all" } ],
"C_COEF_FILE_LINES": [ { "value": "3328", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_FILTER_TYPE": [ { "value": "2", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_INTERP_RATE": [ { "value": "64", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DECIM_RATE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_ZERO_PACKING_FACTOR": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_SYMMETRY": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_NUM_FILTS": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_NUM_TAPS": [ { "value": "3073", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_NUM_CHANNELS": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_CHANNEL_PATTERN": [ { "value": "fixed", "resolve_type": "generated", "usage": "all" } ],
"C_ROUND_MODE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COEF_RELOAD": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_NUM_RELOAD_SLOTS": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COL_MODE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COL_PIPE_LEN": [ { "value": "4", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COL_CONFIG": [ { "value": "13", "resolve_type": "generated", "usage": "all" } ],
"C_OPTIMIZATION": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATA_PATH_WIDTHS": [ { "value": "2,2,2,2", "resolve_type": "generated", "usage": "all" } ],
"C_DATA_IP_PATH_WIDTHS": [ { "value": "2", "resolve_type": "generated", "usage": "all" } ],
"C_DATA_PX_PATH_WIDTHS": [ { "value": "2", "resolve_type": "generated", "usage": "all" } ],
"C_DATA_WIDTH": [ { "value": "2", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COEF_PATH_WIDTHS": [ { "value": "16,16,16,16", "resolve_type": "generated", "usage": "all" } ],
"C_COEF_WIDTH": [ { "value": "16", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATA_PATH_SRC": [ { "value": "0,0,0,0", "resolve_type": "generated", "usage": "all" } ],
"C_COEF_PATH_SRC": [ { "value": "0,1,2,3", "resolve_type": "generated", "usage": "all" } ],
"C_PX_PATH_SRC": [ { "value": "0,1,2,3", "resolve_type": "generated", "usage": "all" } ],
"C_DATA_PATH_SIGN": [ { "value": "0,0,0,0", "resolve_type": "generated", "usage": "all" } ],
"C_COEF_PATH_SIGN": [ { "value": "0,0,0,0", "resolve_type": "generated", "usage": "all" } ],
"C_ACCUM_PATH_WIDTHS": [ { "value": "18,18,18,18", "resolve_type": "generated", "usage": "all" } ],
"C_OUTPUT_WIDTH": [ { "value": "18", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_OUTPUT_PATH_WIDTHS": [ { "value": "18,18,18,18", "resolve_type": "generated", "usage": "all" } ],
"C_ACCUM_OP_PATH_WIDTHS": [ { "value": "18,18,18,18", "resolve_type": "generated", "usage": "all" } ],
"C_EXT_MULT_CNFG": [ { "value": "none", "resolve_type": "generated", "usage": "all" } ],
"C_DATA_PATH_PSAMP_SRC": [ { "value": "-0;-0;-0;-0", "resolve_type": "generated", "usage": "all" } ],
"C_OP_PATH_PSAMP_SRC": [ { "value": "-0;-0;-0;-0", "resolve_type": "generated", "usage": "all" } ],
"C_NUM_MADDS": [ { "value": "13", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_OPT_MADDS": [ { "value": "none;none;none;none", "resolve_type": "generated", "usage": "all" } ],
"C_OVERSAMPLING_RATE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_INPUT_RATE": [ { "value": "64", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_OUTPUT_RATE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATA_MEMTYPE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COEF_MEMTYPE": [ { "value": "2", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_IPBUFF_MEMTYPE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_OPBUFF_MEMTYPE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATAPATH_MEMTYPE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_MEM_ARRANGEMENT": [ { "value": "2", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATA_MEM_PACKING": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COEF_MEM_PACKING": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_FILTS_PACKED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_LATENCY": [ { "value": "19", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_HAS_ARESETn": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_HAS_ACLKEN": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATA_HAS_TLAST": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_S_DATA_HAS_FIFO": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_S_DATA_HAS_TUSER": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_S_DATA_TDATA_WIDTH": [ { "value": "8", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_S_DATA_TUSER_WIDTH": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_M_DATA_HAS_TREADY": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_M_DATA_HAS_TUSER": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_M_DATA_TDATA_WIDTH": [ { "value": "96", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_M_DATA_TUSER_WIDTH": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_HAS_CONFIG_CHANNEL": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_CONFIG_SYNC_MODE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_CONFIG_PACKET_SIZE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_CONFIG_TDATA_WIDTH": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_RELOAD_TDATA_WIDTH": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ]
},
"project_parameters": {
"ARCHITECTURE": [ { "value": "zynquplusRFSOC" } ],
"BASE_BOARD_PART": [ { "value": "" } ],
"BOARD_CONNECTIONS": [ { "value": "" } ],
"DEVICE": [ { "value": "xczu48dr" } ],
"PACKAGE": [ { "value": "fsvg1517" } ],
"PREFHDL": [ { "value": "VERILOG" } ],
"SILICON_REVISION": [ { "value": "" } ],
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
"SPEEDGRADE": [ { "value": "-2" } ],
"STATIC_POWER": [ { "value": "" } ],
"TEMPERATURE_GRADE": [ { "value": "I" } ]
},
"runtime_parameters": {
"IPCONTEXT": [ { "value": "IP_Flow" } ],
"IPREVISION": [ { "value": "20" } ],
"MANAGED": [ { "value": "TRUE" } ],
"OUTPUTDIR": [ { "value": "../../../../tx_qpsk_poly.gen/sources_1/ip/hrc_256_12_025" } ],
"SELECTEDSIMMODEL": [ { "value": "" } ],
"SHAREDDIR": [ { "value": "." } ],
"SWVERSION": [ { "value": "2023.2.1" } ],
"SYNTHESISFLOW": [ { "value": "OUT_OF_CONTEXT" } ]
}
},
"boundary": {
"ports": {
"aclk": [ { "direction": "in" } ],
"s_axis_data_tvalid": [ { "direction": "in", "driver_value": "0x0" } ],
"s_axis_data_tready": [ { "direction": "out", "driver_value": "0x1" } ],
"s_axis_data_tdata": [ { "direction": "in", "size_left": "7", "size_right": "0", "driver_value": "0" } ],
"m_axis_data_tvalid": [ { "direction": "out", "driver_value": "0x0" } ],
"m_axis_data_tdata": [ { "direction": "out", "size_left": "95", "size_right": "0", "driver_value": "0" } ]
},
"interfaces": {
"event_s_data_tlast_missing_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_data_tlast_unexpected_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_data_chanid_incorrect_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_config_tlast_missing_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_config_tlast_unexpected_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_reload_tlast_missing_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_reload_tlast_unexpected_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"aclk_intf": {
"vlnv": "xilinx.com:signal:clock:1.0",
"abstraction_type": "xilinx.com:signal:clock_rtl:1.0",
"mode": "slave",
"parameters": {
"ASSOCIATED_BUSIF": [ { "value": "S_AXIS_CONFIG:M_AXIS_DATA:S_AXIS_DATA:S_AXIS_RELOAD", "value_src": "constant", "usage": "all" } ],
"ASSOCIATED_RESET": [ { "value": "aresetn", "value_src": "constant", "usage": "all" } ],
"ASSOCIATED_CLKEN": [ { "value": "aclken", "value_src": "constant", "usage": "all" } ],
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "user", "format": "long", "usage": "all" } ],
"FREQ_TOLERANCE_HZ": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"ASSOCIATED_PORT": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
},
"port_maps": {
"CLK": [ { "physical_name": "aclk" } ]
}
},
"aresetn_intf": {
"vlnv": "xilinx.com:signal:reset:1.0",
"abstraction_type": "xilinx.com:signal:reset_rtl:1.0",
"mode": "slave",
"parameters": {
"POLARITY": [ { "value": "ACTIVE_LOW", "value_src": "constant", "usage": "all" } ],
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"aclken_intf": {
"vlnv": "xilinx.com:signal:clockenable:1.0",
"abstraction_type": "xilinx.com:signal:clockenable_rtl:1.0",
"mode": "slave",
"parameters": {
"POLARITY": [ { "value": "ACTIVE_HIGH", "value_src": "constant", "usage": "all" } ]
}
},
"S_AXIS_DATA": {
"vlnv": "xilinx.com:interface:axis:1.0",
"abstraction_type": "xilinx.com:interface:axis_rtl:1.0",
"mode": "slave",
"parameters": {
"TDATA_NUM_BYTES": [ { "value": "1", "value_src": "auto", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TDEST_WIDTH": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TID_WIDTH": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TUSER_WIDTH": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TREADY": [ { "value": "1", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TSTRB": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TKEEP": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TLAST": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"LAYERED_METADATA": [ { "value": "undef", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
},
"port_maps": {
"TDATA": [ { "physical_name": "s_axis_data_tdata" } ],
"TREADY": [ { "physical_name": "s_axis_data_tready" } ],
"TVALID": [ { "physical_name": "s_axis_data_tvalid" } ]
}
},
"M_AXIS_DATA": {
"vlnv": "xilinx.com:interface:axis:1.0",
"abstraction_type": "xilinx.com:interface:axis_rtl:1.0",
"mode": "master",
"parameters": {
"TDATA_NUM_BYTES": [ { "value": "12", "value_src": "auto", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TDEST_WIDTH": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TID_WIDTH": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TUSER_WIDTH": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TREADY": [ { "value": "0", "value_src": "auto", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TSTRB": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TKEEP": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TLAST": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"LAYERED_METADATA": [ { "value": "undef", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
},
"port_maps": {
"TDATA": [ { "physical_name": "m_axis_data_tdata" } ],
"TVALID": [ { "physical_name": "m_axis_data_tvalid" } ]
}
}
}
}
}
}
@@ -0,0 +1,349 @@
{
"schema": "xilinx.com:schema:json_instance:1.0",
"ip_inst": {
"xci_name": "hrc_512_12_025",
"component_reference": "xilinx.com:ip:fir_compiler:7.2",
"ip_revision": "20",
"gen_directory": "../../../../tx_qpsk_poly.gen/sources_1/ip/hrc_512_12_025",
"parameters": {
"component_parameters": {
"Component_Name": [ { "value": "hrc_512_12_025", "resolve_type": "user", "usage": "all" } ],
"GUI_Behaviour": [ { "value": "Coregen", "resolve_type": "user", "usage": "all" } ],
"CoefficientSource": [ { "value": "COE_File", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"CoefficientVector": [ { "value": "6,0,-4,-3,5,6,-6,-13,7,44,64,44,7,-13,-6,6,5,-3,-4,0,6", "resolve_type": "user", "usage": "all" } ],
"Coefficient_File": [ { "value": "../coe/hrc_512_12_025.coe", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Coefficient_Sets": [ { "value": "1", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Coefficient_Reload": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Filter_Type": [ { "value": "Interpolation", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Rate_Change_Type": [ { "value": "Integer", "resolve_type": "user", "usage": "all" } ],
"Interpolation_Rate": [ { "value": "512", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Decimation_Rate": [ { "value": "1", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Zero_Pack_Factor": [ { "value": "1", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Channel_Sequence": [ { "value": "Basic", "resolve_type": "user", "usage": "all" } ],
"Number_Channels": [ { "value": "1", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Select_Pattern": [ { "value": "All", "resolve_type": "user", "usage": "all" } ],
"Pattern_List": [ { "value": "P4-0,P4-1,P4-2,P4-3,P4-4", "resolve_type": "user", "usage": "all" } ],
"Number_Paths": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
"RateSpecification": [ { "value": "Input_Sample_Period", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"HardwareOversamplingRate": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
"SamplePeriod": [ { "value": "64", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Sample_Frequency": [ { "value": "0.001", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Clock_Frequency": [ { "value": "300.0", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Coefficient_Sign": [ { "value": "Signed", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Quantization": [ { "value": "Integer_Coefficients", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Coefficient_Width": [ { "value": "16", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"BestPrecision": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Coefficient_Fractional_Bits": [ { "value": "0", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Coefficient_Structure": [ { "value": "Inferred", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Data_Sign": [ { "value": "Signed", "resolve_type": "user", "usage": "all" } ],
"Data_Width": [ { "value": "2", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Data_Fractional_Bits": [ { "value": "0", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Output_Rounding_Mode": [ { "value": "Full_Precision", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Output_Width": [ { "value": "18", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Filter_Architecture": [ { "value": "Systolic_Multiply_Accumulate", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Optimization_Goal": [ { "value": "Area", "resolve_type": "user", "usage": "all" } ],
"Optimization_Selection": [ { "value": "None", "resolve_type": "user", "usage": "all" } ],
"Data_Path_Fanout": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Pre_Adder_Pipeline": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Coefficient_Fanout": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Control_Path_Fanout": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Control_Column_Fanout": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Control_Broadcast_Fanout": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Control_LUT_Pipeline": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"No_BRAM_Read_First_Mode": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Optimal_Column_Lengths": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Data_Path_Broadcast": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Disable_Half_Band_Centre_Tap": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"No_SRL_Attributes": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Other": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Optimization_List": [ { "value": "None", "resolve_type": "user", "usage": "all" } ],
"Data_Buffer_Type": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Coefficient_Buffer_Type": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Input_Buffer_Type": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Output_Buffer_Type": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Preference_For_Other_Storage": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Multi_Column_Support": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Inter_Column_Pipe_Length": [ { "value": "4", "resolve_type": "user", "format": "long", "usage": "all" } ],
"ColumnConfig": [ { "value": "13", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"DATA_Has_TLAST": [ { "value": "Not_Required", "resolve_type": "user", "usage": "all" } ],
"M_DATA_Has_TREADY": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"S_DATA_Has_FIFO": [ { "value": "false", "value_src": "user", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"S_DATA_Has_TUSER": [ { "value": "Not_Required", "resolve_type": "user", "usage": "all" } ],
"M_DATA_Has_TUSER": [ { "value": "Not_Required", "resolve_type": "user", "usage": "all" } ],
"DATA_TUSER_Width": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
"S_CONFIG_Sync_Mode": [ { "value": "On_Vector", "resolve_type": "user", "usage": "all" } ],
"S_CONFIG_Method": [ { "value": "Single", "resolve_type": "user", "usage": "all" } ],
"Num_Reload_Slots": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Has_ACLKEN": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Has_ARESETn": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Reset_Data_Vector": [ { "value": "true", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Blank_Output": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Gen_MIF_from_Spec": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Gen_MIF_from_COE": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Reload_File": [ { "value": "no_coe_file_loaded", "resolve_type": "user", "usage": "all" } ],
"Gen_MIF_Files": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"DisplayReloadOrder": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Passband_Min": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Passband_Max": [ { "value": "0.5", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Stopband_Min": [ { "value": "0.5", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Stopband_Max": [ { "value": "1.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Filter_Selection": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ]
},
"model_parameters": {
"C_XDEVICEFAMILY": [ { "value": "zynquplus", "resolve_type": "generated", "usage": "all" } ],
"C_ELABORATION_DIR": [ { "value": "./", "resolve_type": "generated", "usage": "all" } ],
"C_COMPONENT_NAME": [ { "value": "hrc_512_12_025", "resolve_type": "generated", "usage": "all" } ],
"C_COEF_FILE": [ { "value": "hrc_512_12_025.mif", "resolve_type": "generated", "usage": "all" } ],
"C_COEF_FILE_LINES": [ { "value": "6656", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_FILTER_TYPE": [ { "value": "2", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_INTERP_RATE": [ { "value": "64", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DECIM_RATE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_ZERO_PACKING_FACTOR": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_SYMMETRY": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_NUM_FILTS": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_NUM_TAPS": [ { "value": "6145", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_NUM_CHANNELS": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_CHANNEL_PATTERN": [ { "value": "fixed", "resolve_type": "generated", "usage": "all" } ],
"C_ROUND_MODE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COEF_RELOAD": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_NUM_RELOAD_SLOTS": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COL_MODE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COL_PIPE_LEN": [ { "value": "4", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COL_CONFIG": [ { "value": "13", "resolve_type": "generated", "usage": "all" } ],
"C_OPTIMIZATION": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATA_PATH_WIDTHS": [ { "value": "2,2,2,2,2,2,2,2", "resolve_type": "generated", "usage": "all" } ],
"C_DATA_IP_PATH_WIDTHS": [ { "value": "2", "resolve_type": "generated", "usage": "all" } ],
"C_DATA_PX_PATH_WIDTHS": [ { "value": "2", "resolve_type": "generated", "usage": "all" } ],
"C_DATA_WIDTH": [ { "value": "2", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COEF_PATH_WIDTHS": [ { "value": "16,16,16,16,16,16,16,16", "resolve_type": "generated", "usage": "all" } ],
"C_COEF_WIDTH": [ { "value": "16", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATA_PATH_SRC": [ { "value": "0,0,0,0,0,0,0,0", "resolve_type": "generated", "usage": "all" } ],
"C_COEF_PATH_SRC": [ { "value": "0,1,2,3,4,5,6,7", "resolve_type": "generated", "usage": "all" } ],
"C_PX_PATH_SRC": [ { "value": "0,1,2,3,4,5,6,7", "resolve_type": "generated", "usage": "all" } ],
"C_DATA_PATH_SIGN": [ { "value": "0,0,0,0,0,0,0,0", "resolve_type": "generated", "usage": "all" } ],
"C_COEF_PATH_SIGN": [ { "value": "0,0,0,0,0,0,0,0", "resolve_type": "generated", "usage": "all" } ],
"C_ACCUM_PATH_WIDTHS": [ { "value": "18,18,18,18,18,18,18,18", "resolve_type": "generated", "usage": "all" } ],
"C_OUTPUT_WIDTH": [ { "value": "18", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_OUTPUT_PATH_WIDTHS": [ { "value": "18,18,18,18,18,18,18,18", "resolve_type": "generated", "usage": "all" } ],
"C_ACCUM_OP_PATH_WIDTHS": [ { "value": "18,18,18,18,18,18,18,18", "resolve_type": "generated", "usage": "all" } ],
"C_EXT_MULT_CNFG": [ { "value": "none", "resolve_type": "generated", "usage": "all" } ],
"C_DATA_PATH_PSAMP_SRC": [ { "value": "-0;-0;-0;-0;-0;-0;-0;-0", "resolve_type": "generated", "usage": "all" } ],
"C_OP_PATH_PSAMP_SRC": [ { "value": "-0;-0;-0;-0;-0;-0;-0;-0", "resolve_type": "generated", "usage": "all" } ],
"C_NUM_MADDS": [ { "value": "13", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_OPT_MADDS": [ { "value": "none;none;none;none;none;none;none;none", "resolve_type": "generated", "usage": "all" } ],
"C_OVERSAMPLING_RATE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_INPUT_RATE": [ { "value": "64", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_OUTPUT_RATE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATA_MEMTYPE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COEF_MEMTYPE": [ { "value": "2", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_IPBUFF_MEMTYPE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_OPBUFF_MEMTYPE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATAPATH_MEMTYPE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_MEM_ARRANGEMENT": [ { "value": "2", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATA_MEM_PACKING": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COEF_MEM_PACKING": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_FILTS_PACKED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_LATENCY": [ { "value": "19", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_HAS_ARESETn": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_HAS_ACLKEN": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATA_HAS_TLAST": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_S_DATA_HAS_FIFO": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_S_DATA_HAS_TUSER": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_S_DATA_TDATA_WIDTH": [ { "value": "8", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_S_DATA_TUSER_WIDTH": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_M_DATA_HAS_TREADY": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_M_DATA_HAS_TUSER": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_M_DATA_TDATA_WIDTH": [ { "value": "192", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_M_DATA_TUSER_WIDTH": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_HAS_CONFIG_CHANNEL": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_CONFIG_SYNC_MODE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_CONFIG_PACKET_SIZE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_CONFIG_TDATA_WIDTH": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_RELOAD_TDATA_WIDTH": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ]
},
"project_parameters": {
"ARCHITECTURE": [ { "value": "zynquplusRFSOC" } ],
"BASE_BOARD_PART": [ { "value": "" } ],
"BOARD_CONNECTIONS": [ { "value": "" } ],
"DEVICE": [ { "value": "xczu48dr" } ],
"PACKAGE": [ { "value": "fsvg1517" } ],
"PREFHDL": [ { "value": "VERILOG" } ],
"SILICON_REVISION": [ { "value": "" } ],
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
"SPEEDGRADE": [ { "value": "-2" } ],
"STATIC_POWER": [ { "value": "" } ],
"TEMPERATURE_GRADE": [ { "value": "I" } ]
},
"runtime_parameters": {
"IPCONTEXT": [ { "value": "IP_Flow" } ],
"IPREVISION": [ { "value": "20" } ],
"MANAGED": [ { "value": "TRUE" } ],
"OUTPUTDIR": [ { "value": "../../../../tx_qpsk_poly.gen/sources_1/ip/hrc_512_12_025" } ],
"SELECTEDSIMMODEL": [ { "value": "" } ],
"SHAREDDIR": [ { "value": "." } ],
"SWVERSION": [ { "value": "2023.2.1" } ],
"SYNTHESISFLOW": [ { "value": "OUT_OF_CONTEXT" } ]
}
},
"boundary": {
"ports": {
"aclk": [ { "direction": "in" } ],
"s_axis_data_tvalid": [ { "direction": "in", "driver_value": "0x0" } ],
"s_axis_data_tready": [ { "direction": "out", "driver_value": "0x1" } ],
"s_axis_data_tdata": [ { "direction": "in", "size_left": "7", "size_right": "0", "driver_value": "0" } ],
"m_axis_data_tvalid": [ { "direction": "out", "driver_value": "0x0" } ],
"m_axis_data_tdata": [ { "direction": "out", "size_left": "191", "size_right": "0", "driver_value": "0" } ]
},
"interfaces": {
"event_s_data_tlast_missing_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_data_tlast_unexpected_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_data_chanid_incorrect_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_config_tlast_missing_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_config_tlast_unexpected_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_reload_tlast_missing_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_reload_tlast_unexpected_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"aclk_intf": {
"vlnv": "xilinx.com:signal:clock:1.0",
"abstraction_type": "xilinx.com:signal:clock_rtl:1.0",
"mode": "slave",
"parameters": {
"ASSOCIATED_BUSIF": [ { "value": "S_AXIS_CONFIG:M_AXIS_DATA:S_AXIS_DATA:S_AXIS_RELOAD", "value_src": "constant", "usage": "all" } ],
"ASSOCIATED_RESET": [ { "value": "aresetn", "value_src": "constant", "usage": "all" } ],
"ASSOCIATED_CLKEN": [ { "value": "aclken", "value_src": "constant", "usage": "all" } ],
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "user", "format": "long", "usage": "all" } ],
"FREQ_TOLERANCE_HZ": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"ASSOCIATED_PORT": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
},
"port_maps": {
"CLK": [ { "physical_name": "aclk" } ]
}
},
"aresetn_intf": {
"vlnv": "xilinx.com:signal:reset:1.0",
"abstraction_type": "xilinx.com:signal:reset_rtl:1.0",
"mode": "slave",
"parameters": {
"POLARITY": [ { "value": "ACTIVE_LOW", "value_src": "constant", "usage": "all" } ],
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"aclken_intf": {
"vlnv": "xilinx.com:signal:clockenable:1.0",
"abstraction_type": "xilinx.com:signal:clockenable_rtl:1.0",
"mode": "slave",
"parameters": {
"POLARITY": [ { "value": "ACTIVE_HIGH", "value_src": "constant", "usage": "all" } ]
}
},
"S_AXIS_DATA": {
"vlnv": "xilinx.com:interface:axis:1.0",
"abstraction_type": "xilinx.com:interface:axis_rtl:1.0",
"mode": "slave",
"parameters": {
"TDATA_NUM_BYTES": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TDEST_WIDTH": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TID_WIDTH": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TUSER_WIDTH": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TREADY": [ { "value": "1", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TSTRB": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TKEEP": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TLAST": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"LAYERED_METADATA": [ { "value": "undef", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
},
"port_maps": {
"TDATA": [ { "physical_name": "s_axis_data_tdata" } ],
"TREADY": [ { "physical_name": "s_axis_data_tready" } ],
"TVALID": [ { "physical_name": "s_axis_data_tvalid" } ]
}
},
"M_AXIS_DATA": {
"vlnv": "xilinx.com:interface:axis:1.0",
"abstraction_type": "xilinx.com:interface:axis_rtl:1.0",
"mode": "master",
"parameters": {
"TDATA_NUM_BYTES": [ { "value": "24", "value_src": "auto", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TDEST_WIDTH": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TID_WIDTH": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TUSER_WIDTH": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TREADY": [ { "value": "0", "value_src": "auto", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TSTRB": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TKEEP": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TLAST": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"LAYERED_METADATA": [ { "value": "undef", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
},
"port_maps": {
"TDATA": [ { "physical_name": "m_axis_data_tdata" } ],
"TVALID": [ { "physical_name": "m_axis_data_tvalid" } ]
}
}
}
}
}
}
@@ -0,0 +1,349 @@
{
"schema": "xilinx.com:schema:json_instance:1.0",
"ip_inst": {
"xci_name": "hrc_64_12_025",
"component_reference": "xilinx.com:ip:fir_compiler:7.2",
"ip_revision": "20",
"gen_directory": "../../../../tx_qpsk_poly.gen/sources_1/ip/hrc_64_12_025",
"parameters": {
"component_parameters": {
"Component_Name": [ { "value": "hrc_64_12_025", "resolve_type": "user", "usage": "all" } ],
"GUI_Behaviour": [ { "value": "Coregen", "resolve_type": "user", "usage": "all" } ],
"CoefficientSource": [ { "value": "COE_File", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"CoefficientVector": [ { "value": "6,0,-4,-3,5,6,-6,-13,7,44,64,44,7,-13,-6,6,5,-3,-4,0,6", "resolve_type": "user", "usage": "all" } ],
"Coefficient_File": [ { "value": "../coe/hrc_64_12_025.coe", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Coefficient_Sets": [ { "value": "1", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Coefficient_Reload": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Filter_Type": [ { "value": "Interpolation", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Rate_Change_Type": [ { "value": "Integer", "resolve_type": "user", "usage": "all" } ],
"Interpolation_Rate": [ { "value": "64", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Decimation_Rate": [ { "value": "1", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Zero_Pack_Factor": [ { "value": "1", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Channel_Sequence": [ { "value": "Basic", "resolve_type": "user", "usage": "all" } ],
"Number_Channels": [ { "value": "1", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Select_Pattern": [ { "value": "All", "resolve_type": "user", "usage": "all" } ],
"Pattern_List": [ { "value": "P4-0,P4-1,P4-2,P4-3,P4-4", "resolve_type": "user", "usage": "all" } ],
"Number_Paths": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
"RateSpecification": [ { "value": "Input_Sample_Period", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"HardwareOversamplingRate": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
"SamplePeriod": [ { "value": "64", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Sample_Frequency": [ { "value": "0.001", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Clock_Frequency": [ { "value": "300.0", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Coefficient_Sign": [ { "value": "Signed", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Quantization": [ { "value": "Integer_Coefficients", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Coefficient_Width": [ { "value": "16", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"BestPrecision": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Coefficient_Fractional_Bits": [ { "value": "0", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Coefficient_Structure": [ { "value": "Inferred", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Data_Sign": [ { "value": "Signed", "resolve_type": "user", "usage": "all" } ],
"Data_Width": [ { "value": "2", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Data_Fractional_Bits": [ { "value": "0", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Output_Rounding_Mode": [ { "value": "Full_Precision", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Output_Width": [ { "value": "18", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Filter_Architecture": [ { "value": "Systolic_Multiply_Accumulate", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"Optimization_Goal": [ { "value": "Area", "resolve_type": "user", "usage": "all" } ],
"Optimization_Selection": [ { "value": "None", "resolve_type": "user", "usage": "all" } ],
"Data_Path_Fanout": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Pre_Adder_Pipeline": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Coefficient_Fanout": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Control_Path_Fanout": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Control_Column_Fanout": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Control_Broadcast_Fanout": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Control_LUT_Pipeline": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"No_BRAM_Read_First_Mode": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Optimal_Column_Lengths": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Data_Path_Broadcast": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Disable_Half_Band_Centre_Tap": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"No_SRL_Attributes": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Other": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Optimization_List": [ { "value": "None", "resolve_type": "user", "usage": "all" } ],
"Data_Buffer_Type": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Coefficient_Buffer_Type": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Input_Buffer_Type": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Output_Buffer_Type": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Preference_For_Other_Storage": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Multi_Column_Support": [ { "value": "Automatic", "resolve_type": "user", "usage": "all" } ],
"Inter_Column_Pipe_Length": [ { "value": "4", "resolve_type": "user", "format": "long", "usage": "all" } ],
"ColumnConfig": [ { "value": "7", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
"DATA_Has_TLAST": [ { "value": "Not_Required", "resolve_type": "user", "usage": "all" } ],
"M_DATA_Has_TREADY": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"S_DATA_Has_FIFO": [ { "value": "false", "value_src": "user", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"S_DATA_Has_TUSER": [ { "value": "Not_Required", "resolve_type": "user", "usage": "all" } ],
"M_DATA_Has_TUSER": [ { "value": "Not_Required", "resolve_type": "user", "usage": "all" } ],
"DATA_TUSER_Width": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
"S_CONFIG_Sync_Mode": [ { "value": "On_Vector", "resolve_type": "user", "usage": "all" } ],
"S_CONFIG_Method": [ { "value": "Single", "resolve_type": "user", "usage": "all" } ],
"Num_Reload_Slots": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
"Has_ACLKEN": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Has_ARESETn": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Reset_Data_Vector": [ { "value": "true", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Blank_Output": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Gen_MIF_from_Spec": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Gen_MIF_from_COE": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Reload_File": [ { "value": "no_coe_file_loaded", "resolve_type": "user", "usage": "all" } ],
"Gen_MIF_Files": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"DisplayReloadOrder": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
"Passband_Min": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Passband_Max": [ { "value": "0.5", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Stopband_Min": [ { "value": "0.5", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Stopband_Max": [ { "value": "1.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
"Filter_Selection": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ]
},
"model_parameters": {
"C_XDEVICEFAMILY": [ { "value": "zynquplus", "resolve_type": "generated", "usage": "all" } ],
"C_ELABORATION_DIR": [ { "value": "./", "resolve_type": "generated", "usage": "all" } ],
"C_COMPONENT_NAME": [ { "value": "hrc_64_12_025", "resolve_type": "generated", "usage": "all" } ],
"C_COEF_FILE": [ { "value": "hrc_64_12_025.mif", "resolve_type": "generated", "usage": "all" } ],
"C_COEF_FILE_LINES": [ { "value": "448", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_FILTER_TYPE": [ { "value": "2", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_INTERP_RATE": [ { "value": "64", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DECIM_RATE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_ZERO_PACKING_FACTOR": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_SYMMETRY": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_NUM_FILTS": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_NUM_TAPS": [ { "value": "769", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_NUM_CHANNELS": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_CHANNEL_PATTERN": [ { "value": "fixed", "resolve_type": "generated", "usage": "all" } ],
"C_ROUND_MODE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COEF_RELOAD": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_NUM_RELOAD_SLOTS": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COL_MODE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COL_PIPE_LEN": [ { "value": "4", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COL_CONFIG": [ { "value": "7", "resolve_type": "generated", "usage": "all" } ],
"C_OPTIMIZATION": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATA_PATH_WIDTHS": [ { "value": "2", "resolve_type": "generated", "usage": "all" } ],
"C_DATA_IP_PATH_WIDTHS": [ { "value": "2", "resolve_type": "generated", "usage": "all" } ],
"C_DATA_PX_PATH_WIDTHS": [ { "value": "2", "resolve_type": "generated", "usage": "all" } ],
"C_DATA_WIDTH": [ { "value": "2", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COEF_PATH_WIDTHS": [ { "value": "17", "resolve_type": "generated", "usage": "all" } ],
"C_COEF_WIDTH": [ { "value": "16", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATA_PATH_SRC": [ { "value": "0", "resolve_type": "generated", "usage": "all" } ],
"C_COEF_PATH_SRC": [ { "value": "0", "resolve_type": "generated", "usage": "all" } ],
"C_PX_PATH_SRC": [ { "value": "0", "resolve_type": "generated", "usage": "all" } ],
"C_DATA_PATH_SIGN": [ { "value": "0", "resolve_type": "generated", "usage": "all" } ],
"C_COEF_PATH_SIGN": [ { "value": "0", "resolve_type": "generated", "usage": "all" } ],
"C_ACCUM_PATH_WIDTHS": [ { "value": "19", "resolve_type": "generated", "usage": "all" } ],
"C_OUTPUT_WIDTH": [ { "value": "18", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_OUTPUT_PATH_WIDTHS": [ { "value": "18", "resolve_type": "generated", "usage": "all" } ],
"C_ACCUM_OP_PATH_WIDTHS": [ { "value": "18", "resolve_type": "generated", "usage": "all" } ],
"C_EXT_MULT_CNFG": [ { "value": "none", "resolve_type": "generated", "usage": "all" } ],
"C_DATA_PATH_PSAMP_SRC": [ { "value": "0", "resolve_type": "generated", "usage": "all" } ],
"C_OP_PATH_PSAMP_SRC": [ { "value": "0", "resolve_type": "generated", "usage": "all" } ],
"C_NUM_MADDS": [ { "value": "7", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_OPT_MADDS": [ { "value": "none", "resolve_type": "generated", "usage": "all" } ],
"C_OVERSAMPLING_RATE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_INPUT_RATE": [ { "value": "64", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_OUTPUT_RATE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATA_MEMTYPE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COEF_MEMTYPE": [ { "value": "2", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_IPBUFF_MEMTYPE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_OPBUFF_MEMTYPE": [ { "value": "2", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATAPATH_MEMTYPE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_MEM_ARRANGEMENT": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATA_MEM_PACKING": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_COEF_MEM_PACKING": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_FILTS_PACKED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_LATENCY": [ { "value": "17", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_HAS_ARESETn": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_HAS_ACLKEN": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_DATA_HAS_TLAST": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_S_DATA_HAS_FIFO": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_S_DATA_HAS_TUSER": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_S_DATA_TDATA_WIDTH": [ { "value": "8", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_S_DATA_TUSER_WIDTH": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_M_DATA_HAS_TREADY": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_M_DATA_HAS_TUSER": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_M_DATA_TDATA_WIDTH": [ { "value": "24", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_M_DATA_TUSER_WIDTH": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_HAS_CONFIG_CHANNEL": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_CONFIG_SYNC_MODE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_CONFIG_PACKET_SIZE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_CONFIG_TDATA_WIDTH": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
"C_RELOAD_TDATA_WIDTH": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ]
},
"project_parameters": {
"ARCHITECTURE": [ { "value": "zynquplusRFSOC" } ],
"BASE_BOARD_PART": [ { "value": "" } ],
"BOARD_CONNECTIONS": [ { "value": "" } ],
"DEVICE": [ { "value": "xczu48dr" } ],
"PACKAGE": [ { "value": "fsvg1517" } ],
"PREFHDL": [ { "value": "VERILOG" } ],
"SILICON_REVISION": [ { "value": "" } ],
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
"SPEEDGRADE": [ { "value": "-2" } ],
"STATIC_POWER": [ { "value": "" } ],
"TEMPERATURE_GRADE": [ { "value": "I" } ]
},
"runtime_parameters": {
"IPCONTEXT": [ { "value": "IP_Flow" } ],
"IPREVISION": [ { "value": "20" } ],
"MANAGED": [ { "value": "TRUE" } ],
"OUTPUTDIR": [ { "value": "../../../../tx_qpsk_poly.gen/sources_1/ip/hrc_64_12_025" } ],
"SELECTEDSIMMODEL": [ { "value": "" } ],
"SHAREDDIR": [ { "value": "." } ],
"SWVERSION": [ { "value": "2023.2.1" } ],
"SYNTHESISFLOW": [ { "value": "OUT_OF_CONTEXT" } ]
}
},
"boundary": {
"ports": {
"aclk": [ { "direction": "in" } ],
"s_axis_data_tvalid": [ { "direction": "in", "driver_value": "0x0" } ],
"s_axis_data_tready": [ { "direction": "out", "driver_value": "0x1" } ],
"s_axis_data_tdata": [ { "direction": "in", "size_left": "7", "size_right": "0", "driver_value": "0" } ],
"m_axis_data_tvalid": [ { "direction": "out", "driver_value": "0x0" } ],
"m_axis_data_tdata": [ { "direction": "out", "size_left": "23", "size_right": "0", "driver_value": "0" } ]
},
"interfaces": {
"event_s_data_tlast_missing_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_data_tlast_unexpected_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_data_chanid_incorrect_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_config_tlast_missing_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_config_tlast_unexpected_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_reload_tlast_missing_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"event_s_reload_tlast_unexpected_intf": {
"vlnv": "xilinx.com:signal:interrupt:1.0",
"abstraction_type": "xilinx.com:signal:interrupt_rtl:1.0",
"mode": "master",
"parameters": {
"SENSITIVITY": [ { "value": "EDGE_RISING", "value_src": "constant", "usage": "all" } ],
"PortWidth": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"aclk_intf": {
"vlnv": "xilinx.com:signal:clock:1.0",
"abstraction_type": "xilinx.com:signal:clock_rtl:1.0",
"mode": "slave",
"parameters": {
"ASSOCIATED_BUSIF": [ { "value": "S_AXIS_CONFIG:M_AXIS_DATA:S_AXIS_DATA:S_AXIS_RELOAD", "value_src": "constant", "usage": "all" } ],
"ASSOCIATED_RESET": [ { "value": "aresetn", "value_src": "constant", "usage": "all" } ],
"ASSOCIATED_CLKEN": [ { "value": "aclken", "value_src": "constant", "usage": "all" } ],
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "user", "format": "long", "usage": "all" } ],
"FREQ_TOLERANCE_HZ": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"ASSOCIATED_PORT": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
},
"port_maps": {
"CLK": [ { "physical_name": "aclk" } ]
}
},
"aresetn_intf": {
"vlnv": "xilinx.com:signal:reset:1.0",
"abstraction_type": "xilinx.com:signal:reset_rtl:1.0",
"mode": "slave",
"parameters": {
"POLARITY": [ { "value": "ACTIVE_LOW", "value_src": "constant", "usage": "all" } ],
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
}
},
"aclken_intf": {
"vlnv": "xilinx.com:signal:clockenable:1.0",
"abstraction_type": "xilinx.com:signal:clockenable_rtl:1.0",
"mode": "slave",
"parameters": {
"POLARITY": [ { "value": "ACTIVE_HIGH", "value_src": "constant", "usage": "all" } ]
}
},
"S_AXIS_DATA": {
"vlnv": "xilinx.com:interface:axis:1.0",
"abstraction_type": "xilinx.com:interface:axis_rtl:1.0",
"mode": "slave",
"parameters": {
"TDATA_NUM_BYTES": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TDEST_WIDTH": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TID_WIDTH": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TUSER_WIDTH": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TREADY": [ { "value": "1", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TSTRB": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TKEEP": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TLAST": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"LAYERED_METADATA": [ { "value": "undef", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
},
"port_maps": {
"TDATA": [ { "physical_name": "s_axis_data_tdata" } ],
"TREADY": [ { "physical_name": "s_axis_data_tready" } ],
"TVALID": [ { "physical_name": "s_axis_data_tvalid" } ]
}
},
"M_AXIS_DATA": {
"vlnv": "xilinx.com:interface:axis:1.0",
"abstraction_type": "xilinx.com:interface:axis_rtl:1.0",
"mode": "master",
"parameters": {
"TDATA_NUM_BYTES": [ { "value": "3", "value_src": "auto", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TDEST_WIDTH": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TID_WIDTH": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"TUSER_WIDTH": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TREADY": [ { "value": "0", "value_src": "auto", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TSTRB": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TKEEP": [ { "value": "0", "value_src": "constant", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"HAS_TLAST": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"LAYERED_METADATA": [ { "value": "undef", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
},
"port_maps": {
"TDATA": [ { "physical_name": "m_axis_data_tdata" } ],
"TVALID": [ { "physical_name": "m_axis_data_tvalid" } ]
}
}
}
}
}
}
@@ -0,0 +1,627 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
// _ _ ____
// | | ___ ___| |__ / ___| __ _ ___
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
// \___/ \___/|___/_| |_| \____|\__,_|\___/
//
// Create Date: 2022/03/23 20:17:56
// Last Modified Date: 2023/03/10 15:41
// Design Name:
// Module Name: tx_qpsk_poly
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// 20230228-1541 - 修改不扫频、无基带频偏时 [baseband_i/q] 的数据输出,原来从
// 乘法器引出,会导致频率为 0 时输出数据错误,现在直接从基带数据引出。
// 20230310-1542 - 增加输入参数,发送数据更改为直接由参数输入,发送方波改为 8
// 倍过采样,发送双音信号中 1MHz 信号的频率控制字可以根据参数中的时钟频率计
// 算得出。
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module tx_qpsk_poly
#(
parameter DATA_WIDTH = 12, // need to be <= 16
parameter BIT_DATA = 128'b00000011000010100011110010001011001110101001111101000011100010010011011010110111101100011010010111011100110010101011111110000001, // inverse pseudorandom bit sequence, [0,flip(PRSB7)]
parameter BIT_DATA_LEN = 128,
parameter SQUARE_INTERP = 8,
parameter CLK_FREQ = 245_760_000*8, // in Hertz
parameter PARALLEL_NUM = 8
)
(
input clk ,
input rst ,
output [DATA_WIDTH-1:0] tx_data_i ,
output [DATA_WIDTH-1:0] tx_data_q ,
// debug ports
input [ 1:0] waveform_sel ,
input sweep_on ,
input [31:0] freq_set ,
input [ 1:0] iq_sel ,
input [ 3:0] bb_rshift
);
localparam RCOS_INTERP = 64*PARALLEL_NUM;
localparam INTERP = (RCOS_INTERP > SQUARE_INTERP) ? RCOS_INTERP : SQUARE_INTERP;
localparam FREQ_WORD_1M = (64'd2)**(64'd16)*(64'd1_000_000)/CLK_FREQ;
integer i;
genvar m;
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// Data Counter /////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// symbol & interpolation counter
reg [$clog2(INTERP*BIT_DATA_LEN)-1 : 0] cnt = 'b0;
always @(posedge clk) begin
if (rst) begin
cnt <= 'b0;
end
else begin
cnt <= (cnt == INTERP*BIT_DATA_LEN - 1) ? 'b0 : cnt + 16'b1;
end
end
// address
reg [$clog2(BIT_DATA_LEN)-1 : 0] bit_data_addr_i = 'b0;
reg [$clog2(BIT_DATA_LEN)-1 : 0] bit_data_addr_q = 'b1;
always @(posedge clk) begin
if (rst) begin
bit_data_addr_i <= 'b0;
bit_data_addr_q <= 'b1;
end
else begin
bit_data_addr_i <= {cnt[$clog2(RCOS_INTERP) +: ($clog2(BIT_DATA_LEN)-1)],1'b0};
bit_data_addr_q <= {cnt[$clog2(RCOS_INTERP) +: ($clog2(BIT_DATA_LEN)-1)],1'b1};
end
end
// bit data
reg bit_data_i = 'b0;
reg bit_data_q = 'b0;
always @(posedge clk) begin
if (rst) begin
bit_data_i <= 'b0;
bit_data_q <= 'b0;
end
else begin
bit_data_i <= BIT_DATA[bit_data_addr_i];
bit_data_q <= BIT_DATA[bit_data_addr_q];
end
end
////////////////////////////////////////////////////////////////////////////////
////////////////////// Root-Rasied Cosine Shaping Filter ///////////////////////
////////////////////////////////////////////////////////////////////////////////
// polarization
wire [7:0] hrc_data_polar_i;
wire [7:0] hrc_data_polar_q;
assign hrc_data_polar_i = {{7{bit_data_i}},1'b1};
assign hrc_data_polar_q = {{7{bit_data_q}},1'b1};
// root raised cosine shaping-filter
wire [24*PARALLEL_NUM-1 : 0] hrc_wave_i;
wire [24*PARALLEL_NUM-1 : 0] hrc_wave_q;
wire [23:0] hrc_wave_i_par [0 : PARALLEL_NUM-1];
wire [23:0] hrc_wave_q_par [0 : PARALLEL_NUM-1];
generate
for (m = 0; m < PARALLEL_NUM; m = m + 1) begin
assign hrc_wave_i_par[m] = hrc_wave_i[24*m +: 24];
assign hrc_wave_q_par[m] = hrc_wave_q[24*m +: 24];
end
case (PARALLEL_NUM)
1: begin
hrc_64_12_025 u_hrc_i
(
.aclk (clk ), // input wire aclk
.s_axis_data_tvalid (~rst ), // input wire s_axis_data_tvalid
.s_axis_data_tready ( ), // output wire s_axis_data_tready
.s_axis_data_tdata (hrc_data_polar_i ), // input wire [7 : 0] s_axis_data_tdata
.m_axis_data_tvalid ( ), // output wire m_axis_data_tvalid
.m_axis_data_tdata (hrc_wave_i ) // output wire [23 : 0] m_axis_data_tdata
);
hrc_64_12_025 u_hrc_q
(
.aclk (clk ), // input wire aclk
.s_axis_data_tvalid (~rst ), // input wire s_axis_data_tvalid
.s_axis_data_tready ( ), // output wire s_axis_data_tready
.s_axis_data_tdata (hrc_data_polar_q ), // input wire [7 : 0] s_axis_data_tdata
.m_axis_data_tvalid ( ), // output wire m_axis_data_tvalid
.m_axis_data_tdata (hrc_wave_q ) // output wire [23 : 0] m_axis_data_tdata
);
end
4: begin
hrc_256_12_025 u_hrc_i
(
.aclk (clk ), // input wire aclk
.s_axis_data_tvalid (~rst ), // input wire s_axis_data_tvalid
.s_axis_data_tready ( ), // output wire s_axis_data_tready
.s_axis_data_tdata (hrc_data_polar_i ), // input wire [7 : 0] s_axis_data_tdata
.m_axis_data_tvalid ( ), // output wire m_axis_data_tvalid
.m_axis_data_tdata (hrc_wave_i ) // output wire [95 : 0] m_axis_data_tdata
);
hrc_256_12_025 u_hrc_q
(
.aclk (clk ), // input wire aclk
.s_axis_data_tvalid (~rst ), // input wire s_axis_data_tvalid
.s_axis_data_tready ( ), // output wire s_axis_data_tready
.s_axis_data_tdata (hrc_data_polar_q ), // input wire [7 : 0] s_axis_data_tdata
.m_axis_data_tvalid ( ), // output wire m_axis_data_tvalid
.m_axis_data_tdata (hrc_wave_q ) // output wire [95 : 0] m_axis_data_tdata
);
end
8: begin
hrc_512_12_025 u_hrc_i
(
.aclk (clk ), // input wire aclk
.s_axis_data_tvalid (~rst ), // input wire s_axis_data_tvalid
.s_axis_data_tready ( ), // output wire s_axis_data_tready
.s_axis_data_tdata (hrc_data_polar_i ), // input wire [7 : 0] s_axis_data_tdata
.m_axis_data_tvalid ( ), // output wire m_axis_data_tvalid
.m_axis_data_tdata (hrc_wave_i ) // output wire [191 : 0] m_axis_data_tdata
);
hrc_512_12_025 u_hrc_q
(
.aclk (clk ), // input wire aclk
.s_axis_data_tvalid (~rst ), // input wire s_axis_data_tvalid
.s_axis_data_tready ( ), // output wire s_axis_data_tready
.s_axis_data_tdata (hrc_data_polar_q ), // input wire [7 : 0] s_axis_data_tdata
.m_axis_data_tvalid ( ), // output wire m_axis_data_tvalid
.m_axis_data_tdata (hrc_wave_q ) // output wire [191 : 0] m_axis_data_tdata
);
end
default: begin
hrc_64_12_025 u_hrc_i
(
.aclk (clk ), // input wire aclk
.s_axis_data_tvalid (~rst ), // input wire s_axis_data_tvalid
.s_axis_data_tready ( ), // output wire s_axis_data_tready
.s_axis_data_tdata (hrc_data_polar_i ), // input wire [7 : 0] s_axis_data_tdata
.m_axis_data_tvalid ( ), // output wire m_axis_data_tvalid
.m_axis_data_tdata (hrc_wave_i ) // output wire [23 : 0] m_axis_data_tdata
);
hrc_64_12_025 u_hrc_q
(
.aclk (clk ), // input wire aclk
.s_axis_data_tvalid (~rst ), // input wire s_axis_data_tvalid
.s_axis_data_tready ( ), // output wire s_axis_data_tready
.s_axis_data_tdata (hrc_data_polar_q ), // input wire [7 : 0] s_axis_data_tdata
.m_axis_data_tvalid ( ), // output wire m_axis_data_tvalid
.m_axis_data_tdata (hrc_wave_q ) // output wire [23 : 0] m_axis_data_tdata
);
end
endcase
endgenerate
////////////////////////////////////////////////////////////////////////////////
//////////////////////////// Square Shaping Filter /////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// square shaping-filter
reg [17:0] hsq_wave_i ='b0;
reg [17:0] hsq_wave_q ='b0;
always @(posedge clk) begin
if (rst) begin
hsq_wave_i <= 'b0;
hsq_wave_q <= 'b0;
end
else begin
hsq_wave_i <= bit_data_i ? 18'b01_1111_1111_1111_1111 : 18'b10_0000_0000_0000_0001;
hsq_wave_q <= bit_data_q ? 18'b10_0000_0000_0000_0001 : 18'b01_1111_1111_1111_1111;
end
end
////////////////////////////////////////////////////////////////////////////////
/////////////////////////////// Two Tone Signal ////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// cosine wave with freq of 1 MHz
wire signed [16*PARALLEL_NUM-1 : 0] cos_1m;
wire signed [16*PARALLEL_NUM-1 : 0] sin_1m;
wire signed [15 : 0] cos_1m_par [0 : PARALLEL_NUM-1];
wire signed [15 : 0] sin_1m_par [0 : PARALLEL_NUM-1];
generate
for (m = 0; m < PARALLEL_NUM; m = m + 1) begin
assign cos_1m_par[m] = cos_1m[16*m +: 16];
assign sin_1m_par[m] = sin_1m[16*m +: 16];
end
endgenerate
dds_par #(
.PHASE_WIDTH (16 ),
.WAVE_WIDTH (16 ),
.PARALLEL_NUM (PARALLEL_NUM )
)
(
.clk (clk ),
.rst (rst ),
.phase_inc(FREQ_WORD_1M ),
.cos_wave (cos_1m ),
.sin_wave (sin_1m )
);
// two-tone signal
reg signed [15:0] two_tone_wave_i [0 : PARALLEL_NUM-1];
reg signed [15:0] two_tone_wave_q [0 : PARALLEL_NUM-1];
always @(posedge clk) begin
if (rst) begin
for (i = 0; i < PARALLEL_NUM; i = i + 1) begin
two_tone_wave_i[i] <= 'b0;
two_tone_wave_q[i] <= 'b0;
end
end
else begin
for (i = 0; i < PARALLEL_NUM; i = i + 1) begin
two_tone_wave_i[i] <= (cos_1m[i] >>> 1) + 16'h3fff;
two_tone_wave_q[i] <= (sin_1m[i] >>> 1) + 16'b0;
end
end
end
////////////////////////////////////////////////////////////////////////////////
///////////////////// Waveform Selection & Hopping Control /////////////////////
////////////////////////////////////////////////////////////////////////////////
// baseband signal select
reg [15:0] baseband_sel_i [0 : PARALLEL_NUM-1];
reg [15:0] baseband_sel_q [0 : PARALLEL_NUM-1];
always @(posedge clk) begin
if (rst) begin
for (i = 0; i < PARALLEL_NUM; i = i + 1) begin
baseband_sel_i[i] <= 'b0;
baseband_sel_q[i] <= 'b0;
end
end
else begin
for (i = 0; i < PARALLEL_NUM; i = i + 1) begin
case (waveform_sel[1:0])
2'd0: begin
baseband_sel_i[i] <= hrc_wave_i_par[i][0 +: 16];
baseband_sel_q[i] <= hrc_wave_q_par[i][0 +: 16];
end
2'd1: begin
baseband_sel_i[i] <= hsq_wave_i[17:0];
baseband_sel_q[i] <= hsq_wave_q[17:0];
end
2'd2: begin
baseband_sel_i[i] <= 16'h7fff;
baseband_sel_q[i] <= 16'b0;
end
2'd3: begin
baseband_sel_i[i] <= two_tone_wave_i[i];
baseband_sel_q[i] <= two_tone_wave_q[i];
end
default: begin
baseband_sel_i[i] <= hrc_wave_i_par[i][0 +: 16];
baseband_sel_q[i] <= hrc_wave_q_par[i][0 +: 16];
end
endcase
end
end
end
// hopping control, 3750hop/s
reg [23:0] sweep_rom_addr = 'b0;
wire [31:0] freq_sweep;
always @(posedge clk) begin
if (rst) begin
sweep_rom_addr <= 'b0;
end
else if (sweep_on) begin
sweep_rom_addr <= sweep_rom_addr + 24'b1;
end
else begin
sweep_rom_addr <= 'b0;
end
end
hop_rom u_sweep_rom
(
.clka (clk ), // input wire clka
.addra (sweep_rom_addr[23:16] ), // input wire [7 : 0] addra
.douta (freq_sweep ) // output wire [31 : 0] douta
);
// choose the actual frequency word
reg [31:0] freq_word = 'b0;
always @(posedge clk) begin
if (rst) begin
freq_word <= 'b0;
end
else if (sweep_on) begin
// frequency sweep
freq_word <= freq_sweep;
end
else begin
// normal operation
freq_word <= freq_set;
end
end
// baseband frequency shift carrier generation
wire [ 7:0] cos_dds;
wire [ 7:0] sin_dds;
reg [ 7:0] cos = 'b0;
reg [ 7:0] sin = 'b0;
dds_32b_8b u_dds_bb_shift (
.aclk (clk ), // input wire aclk
.s_axis_config_tvalid (~rst ), // input wire s_axis_config_tvalid
.s_axis_config_tdata (freq_word ), // input wire [31 : 0] s_axis_config_tdata
.m_axis_data_tvalid ( ), // output wire m_axis_data_tvalid
.m_axis_data_tdata ({sin_dds,cos_dds}) // output wire [31 : 0] m_axis_data_tdata
);
always @(posedge clk) begin
if (rst) begin
cos <= 'b0;
sin <= 'b0;
end
else if (freq_word == 'b0) begin
// to make sure the carriers stay at the right position when freq = 0
cos <= 8'b0111_1111;
sin <= 8'b0111_1111;
end
else begin
cos <= cos_dds;
sin <= sin_dds;
end
end
// baseband frequency shift modulation
wire [47:0] mod_cmpy_a;
wire [15:0] mod_cmpy_b;
wire [63:0] mod_cmpy_out;
wire [26:0] baseband_mult_i;
wire [26:0] baseband_mult_q;
assign mod_cmpy_a = {6'b0,baseband_sel_q,6'b0,baseband_sel_i};
assign mod_cmpy_b = {-sin,cos};
assign baseband_mult_i = mod_cmpy_out[58:32];
assign baseband_mult_q = mod_cmpy_out[26: 0];
cmpy_18x8 u_cmpy_18x8
(
.aclk (clk ), // input wire aclk
.s_axis_a_tvalid (1'b1 ), // input wire s_axis_a_tvalid
.s_axis_a_tdata (mod_cmpy_a ), // input wire [47 : 0] s_axis_a_tdata
.s_axis_b_tvalid (1'b1 ), // input wire s_axis_b_tvalid
.s_axis_b_tdata (mod_cmpy_b ), // input wire [15 : 0] s_axis_b_tdata
.m_axis_dout_tvalid ( ), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata (mod_cmpy_out ) // output wire [63 : 0] m_axis_dout_tdata
);
// truncate to 16-bit
reg signed [15:0] baseband_i = 'b0;
reg signed [15:0] baseband_q = 'b0;
always @(posedge clk) begin
if (rst) begin
baseband_i <= 'b0;
baseband_q <= 'b0;
end
else begin
case (waveform_sel[1:0])
2'd0: begin
// scale rasied-cosine-shaped bpsk signal by 1.125 or 1.625
baseband_i <= (sweep_on == 0 && freq_set == 0) ? (baseband_sel_i[17 -: 16] + {{3{baseband_sel_i[17]}},baseband_sel_i[17 -: 13]}) : (baseband_mult_i[25:10] + {baseband_mult_i[25],baseband_mult_i[25:11]} + {{3{baseband_mult_i[25]}},baseband_mult_i[25:13]});
baseband_q <= (sweep_on == 0 && freq_set == 0) ? (baseband_sel_q[17 -: 16] + {{3{baseband_sel_q[17]}},baseband_sel_q[17 -: 13]}) : (baseband_mult_q[25:10] + {baseband_mult_q[25],baseband_mult_q[25:11]} + {{3{baseband_mult_q[25]}},baseband_mult_q[25:13]});
end
2'd1: begin
baseband_i <= (sweep_on == 0 && freq_set == 0) ? baseband_sel_i[17 -: 16] : (baseband_mult_i[25:10] + {{2{baseband_mult_i[25]}},baseband_mult_i[25:12]});
baseband_q <= (sweep_on == 0 && freq_set == 0) ? baseband_sel_q[17 -: 16] : (baseband_mult_q[25:10] + {{2{baseband_mult_q[25]}},baseband_mult_q[25:12]});
end
2'd2: begin
baseband_i <= baseband_mult_i[24:9];
baseband_q <= baseband_mult_q[24:9];
end
2'd3: begin
baseband_i <= (sweep_on == 0 && freq_set == 0) ? baseband_sel_i[17 -: 16] : baseband_mult_i[24:9];
baseband_q <= (sweep_on == 0 && freq_set == 0) ? baseband_sel_q[17 -: 16] : baseband_mult_q[24:9];
end
default: begin
// scale rasied-cosine-shaped bpsk signal by 1.125
baseband_i <= baseband_mult_i[25:10] + {{3{baseband_mult_i[25]}},baseband_mult_i[25:13]};
baseband_q <= baseband_mult_q[25:10] + {{3{baseband_mult_q[25]}},baseband_mult_q[25:13]};
end
endcase
end
end
// iq selection & baseband right shift
reg signed [15:0] baseband_data_i = 'b0;
reg signed [15:0] baseband_data_q = 'b0;
always @(posedge clk) begin
if (rst) begin
baseband_data_i <= 'b0;
baseband_data_q <= 'b0;
end
else begin
// inphase selection
if (iq_sel[1]) begin
baseband_data_i <= baseband_i >>> bb_rshift;
end
else begin
baseband_data_i <= 'b0;
end
// quadrature selection
if (iq_sel[0]) begin
baseband_data_q <= baseband_q >>> bb_rshift;
end
else begin
baseband_data_q <= 'b0;
end
end
end
// output data to ports
assign tx_data_i = baseband_data_i[15 -: DATA_WIDTH];
assign tx_data_q = baseband_data_q[15 -: DATA_WIDTH];
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2020/12/08 12:43:46
// Design Name:
// Module Name: tb_tx_qpsk
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
// module tb_tx_qpsk;
// reg clk = 1'b0 ;
// reg rst = 1'b1 ;
// reg tx_on = 1'b1 ;
// reg [31:0] freq_set ;
// reg [ 1:0] waveform_sel = 2'b00;
// reg [ 1:0] iq_sel = 2'b11 ;
// wire [11:0] tx_data_i ;
// wire [11:0] tx_data_q ;
// reg [ 3:0] bb_rshift = 5'b0 ;
// tx_qpsk u_tx_qpsk
// (
// .clk (clk ),
// .rst (rst ),
// .tx_data_i (tx_data_i ),
// .tx_data_q (tx_data_q ),
// .waveform_sel (waveform_sel ),
// .sweep_on (1'b0 ),
// // .freq_set (32'd447392426 ),
// .freq_set (32'd0 ),
// .iq_sel (iq_sel ),
// .bb_rshift (bb_rshift )
// );
// initial begin
// #102
// rst = 1'b0;
// // freq_set = 32'd873813333;
// // waveform_sel = 2'b00;
// // bb_rshift = 5'd0;
// // #5000
// // bb_rshift = 5'd1;
// // #5000
// // bb_rshift = 5'd2;
// // #5000
// // bb_rshift = 5'd3;
// // #5000
// // bb_rshift = 5'd4;
// // #5000
// // bb_rshift = 5'd5;
// // #5000
// // bb_rshift = 5'd6;
// // #5000
// // bb_rshift = 5'd7;
// // #5000
// // bb_rshift = 5'd8;
// // #5000
// // bb_rshift = 5'd9;
// // #5000
// // bb_rshift = 5'd14;
// // #5000
// // bb_rshift = 5'd15;
// // #5000
// // bb_rshift = 5'd16;
// // freq_set = 32'd0;
// // func_sel = 3'b010;
// // #7777
// // freq_set = 32'd536870912;
// // func_sel = 3'b100;
// // #7777
// // freq_set = 32'd0;
// // func_sel = 3'b100;
// // #7777
// // freq_set = 32'd536870912;
// // func_sel = 3'b010;
// // #7777
// // freq_set = 32'd0;
// // func_sel = 3'b010;
// // freq_set = 32'd536870912;
// // iq_sel = 2'b00;
// // #7777
// // freq_set = 32'd536870912;
// // iq_sel = 2'b01;
// // #7777
// // freq_set = 32'd536870912;
// // iq_sel = 2'b10;
// // #7777
// // freq_set = 32'd536870912;
// // iq_sel = 2'b11;
// end
// always #5 clk = ~clk;
// // integer i;
// // integer w_file;
// // initial begin
// // w_file = $fopen("D:\\qpsk_josh.txt","w");
// // for (i = 0; i <= 35000; i = i + 1) begin
// // wait(clk);
// // #10;
// // $fdisplay(w_file,"%d %d",$signed(tx_data_i),
// // $signed(tx_data_q));
// // if (i == 35000) begin
// // $fclose(w_file);
// // $stop;
// // end
// // end
// // end
// endmodule
@@ -0,0 +1,395 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Product Version: Vivado v2023.2.1 (64-bit) -->
<!-- -->
<!-- Copyright 1986-2022 Xilinx, Inc. All Rights Reserved. -->
<!-- Copyright 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved. -->
<Project Product="Vivado" Version="7" Minor="65" Path="/home/josh/Workspace/vivado-git-new/modules/xczu48dr-fsvg1517-2-i/tx_qpsk_poly/tx_qpsk_poly.xpr">
<DefaultLaunch Dir="$PRUNDIR"/>
<Configuration>
<Option Name="Id" Val="fe1ad6990cf04f9197091f4875cffe86"/>
<Option Name="Part" Val="xczu48dr-fsvg1517-2-i"/>
<Option Name="CompiledLibDir" Val="$PCACHEDIR/compile_simlib"/>
<Option Name="CompiledLibDirXSim" Val=""/>
<Option Name="CompiledLibDirModelSim" Val="$PCACHEDIR/compile_simlib/modelsim"/>
<Option Name="CompiledLibDirQuesta" Val="$PCACHEDIR/compile_simlib/questa"/>
<Option Name="CompiledLibDirXcelium" Val="$PCACHEDIR/compile_simlib/xcelium"/>
<Option Name="CompiledLibDirVCS" Val="$PCACHEDIR/compile_simlib/vcs"/>
<Option Name="CompiledLibDirRiviera" Val="$PCACHEDIR/compile_simlib/riviera"/>
<Option Name="CompiledLibDirActivehdl" Val="$PCACHEDIR/compile_simlib/activehdl"/>
<Option Name="SimulatorInstallDirModelSim" Val=""/>
<Option Name="SimulatorInstallDirQuesta" Val=""/>
<Option Name="SimulatorInstallDirXcelium" Val=""/>
<Option Name="SimulatorInstallDirVCS" Val=""/>
<Option Name="SimulatorInstallDirRiviera" Val=""/>
<Option Name="SimulatorInstallDirActiveHdl" Val=""/>
<Option Name="SimulatorGccInstallDirModelSim" Val=""/>
<Option Name="SimulatorGccInstallDirQuesta" Val=""/>
<Option Name="SimulatorGccInstallDirXcelium" Val=""/>
<Option Name="SimulatorGccInstallDirVCS" Val=""/>
<Option Name="SimulatorGccInstallDirRiviera" Val=""/>
<Option Name="SimulatorGccInstallDirActiveHdl" Val=""/>
<Option Name="SimulatorVersionXsim" Val="2023.2"/>
<Option Name="SimulatorVersionModelSim" Val="2023.2"/>
<Option Name="SimulatorVersionQuesta" Val="2023.2"/>
<Option Name="SimulatorVersionXcelium" Val="23.03.002"/>
<Option Name="SimulatorVersionVCS" Val="U-2023.03-1"/>
<Option Name="SimulatorVersionRiviera" Val="2022.10"/>
<Option Name="SimulatorVersionActiveHdl" Val="14.1"/>
<Option Name="SimulatorGccVersionXsim" Val="9.3.0"/>
<Option Name="SimulatorGccVersionModelSim" Val="7.4.0"/>
<Option Name="SimulatorGccVersionQuesta" Val="7.4.0"/>
<Option Name="SimulatorGccVersionXcelium" Val="9.3.0"/>
<Option Name="SimulatorGccVersionVCS" Val="9.2.0"/>
<Option Name="SimulatorGccVersionRiviera" Val="9.3.0"/>
<Option Name="SimulatorGccVersionActiveHdl" Val="9.3.0"/>
<Option Name="BoardPart" Val=""/>
<Option Name="ActiveSimSet" Val="sim_1"/>
<Option Name="DefaultLib" Val="xil_defaultlib"/>
<Option Name="ProjectType" Val="Default"/>
<Option Name="IPOutputRepo" Val="$PCACHEDIR/ip"/>
<Option Name="IPDefaultOutputPath" Val="$PGENDIR/sources_1"/>
<Option Name="IPCachePermission" Val="read"/>
<Option Name="IPCachePermission" Val="write"/>
<Option Name="EnableCoreContainer" Val="FALSE"/>
<Option Name="EnableResourceEstimation" Val="FALSE"/>
<Option Name="SimCompileState" Val="TRUE"/>
<Option Name="CreateRefXciForCoreContainers" Val="FALSE"/>
<Option Name="IPUserFilesDir" Val="$PIPUSERFILESDIR"/>
<Option Name="IPStaticSourceDir" Val="$PIPUSERFILESDIR/ipstatic"/>
<Option Name="EnableBDX" Val="FALSE"/>
<Option Name="FeatureSet" Val="FeatureSet_Classic"/>
<Option Name="WTXSimLaunchSim" Val="0"/>
<Option Name="WTModelSimLaunchSim" Val="0"/>
<Option Name="WTQuestaLaunchSim" Val="0"/>
<Option Name="WTIesLaunchSim" Val="0"/>
<Option Name="WTVcsLaunchSim" Val="0"/>
<Option Name="WTRivieraLaunchSim" Val="0"/>
<Option Name="WTActivehdlLaunchSim" Val="0"/>
<Option Name="WTXSimExportSim" Val="5"/>
<Option Name="WTModelSimExportSim" Val="5"/>
<Option Name="WTQuestaExportSim" Val="5"/>
<Option Name="WTIesExportSim" Val="0"/>
<Option Name="WTVcsExportSim" Val="5"/>
<Option Name="WTRivieraExportSim" Val="5"/>
<Option Name="WTActivehdlExportSim" Val="5"/>
<Option Name="GenerateIPUpgradeLog" Val="TRUE"/>
<Option Name="XSimRadix" Val="hex"/>
<Option Name="XSimTimeUnit" Val="ns"/>
<Option Name="XSimArrayDisplayLimit" Val="1024"/>
<Option Name="XSimTraceLimit" Val="65536"/>
<Option Name="SimTypes" Val="rtl"/>
<Option Name="SimTypes" Val="bfm"/>
<Option Name="SimTypes" Val="tlm"/>
<Option Name="SimTypes" Val="tlm_dpi"/>
<Option Name="MEMEnableMemoryMapGeneration" Val="TRUE"/>
<Option Name="DcpsUptoDate" Val="TRUE"/>
<Option Name="ClassicSocBoot" Val="FALSE"/>
<Option Name="LocalIPRepoLeafDirName" Val="ip_repo"/>
</Configuration>
<FileSets Version="1" Minor="32">
<FileSet Name="sources_1" Type="DesignSrcs" RelSrcDir="$PSRCDIR/sources_1" RelGenDir="$PGENDIR/sources_1">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/../dds_par/dds_par.srcs/sources_1/ip/cos_16384_16b/cos_16384_16b.xci">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../dds_par/dds_par.srcs/sources_1/new/addr_to_wave.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../dds_par/dds_par.srcs/sources_1/new/dds_par.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/sources_1/new/tx_qpsk_poly.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/sources_1/ip/coe/hrc_64_12_025.coe">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/sources_1/ip/coe/hrc_256_12_025.coe">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/sources_1/ip/coe/hrc_512_12_025.coe">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../dds_par/dds_par.srcs/sources_1/ip/coe/cos_16384_16b.coe">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="tx_qpsk_poly"/>
<Option Name="TopAutoSet" Val="TRUE"/>
</Config>
</FileSet>
<FileSet Name="constrs_1" Type="Constrs" RelSrcDir="$PSRCDIR/constrs_1" RelGenDir="$PGENDIR/constrs_1">
<Filter Type="Constrs"/>
<Config>
<Option Name="ConstrsType" Val="XDC"/>
</Config>
</FileSet>
<FileSet Name="sim_1" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/sim_1" RelGenDir="$PGENDIR/sim_1">
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="tx_qpsk_poly"/>
<Option Name="TopLib" Val="xil_defaultlib"/>
<Option Name="TopAutoSet" Val="TRUE"/>
<Option Name="TransportPathDelay" Val="0"/>
<Option Name="TransportIntDelay" Val="0"/>
<Option Name="SelectedSimModel" Val="rtl"/>
<Option Name="PamDesignTestbench" Val=""/>
<Option Name="PamDutBypassFile" Val="xil_dut_bypass"/>
<Option Name="PamSignalDriverFile" Val="xil_bypass_driver"/>
<Option Name="PamPseudoTop" Val="pseudo_tb"/>
<Option Name="SrcSet" Val="sources_1"/>
</Config>
</FileSet>
<FileSet Name="utils_1" Type="Utils" RelSrcDir="$PSRCDIR/utils_1" RelGenDir="$PGENDIR/utils_1">
<Filter Type="Utils"/>
<Config>
<Option Name="TopAutoSet" Val="TRUE"/>
</Config>
</FileSet>
<FileSet Name="hrc_64_12_025" Type="BlockSrcs" RelSrcDir="$PSRCDIR/hrc_64_12_025" RelGenDir="$PGENDIR/hrc_64_12_025">
<File Path="$PSRCDIR/sources_1/ip/hrc_64_12_025/hrc_64_12_025.xci">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<Config>
<Option Name="TopModule" Val="hrc_64_12_025"/>
<Option Name="UseBlackboxStub" Val="1"/>
</Config>
</FileSet>
<FileSet Name="hrc_256_12_025" Type="BlockSrcs" RelSrcDir="$PSRCDIR/hrc_256_12_025" RelGenDir="$PGENDIR/hrc_256_12_025">
<File Path="$PSRCDIR/sources_1/ip/hrc_256_12_025/hrc_256_12_025.xci">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<Config>
<Option Name="TopModule" Val="hrc_256_12_025"/>
<Option Name="UseBlackboxStub" Val="1"/>
</Config>
</FileSet>
<FileSet Name="hrc_512_12_025" Type="BlockSrcs" RelSrcDir="$PSRCDIR/hrc_512_12_025" RelGenDir="$PGENDIR/hrc_512_12_025">
<File Path="$PSRCDIR/sources_1/ip/hrc_512_12_025/hrc_512_12_025.xci">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<Config>
<Option Name="TopModule" Val="hrc_512_12_025"/>
<Option Name="UseBlackboxStub" Val="1"/>
</Config>
</FileSet>
</FileSets>
<Simulators>
<Simulator Name="XSim">
<Option Name="Description" Val="Vivado Simulator"/>
<Option Name="CompiledLib" Val="0"/>
</Simulator>
<Simulator Name="ModelSim">
<Option Name="Description" Val="ModelSim Simulator"/>
</Simulator>
<Simulator Name="Questa">
<Option Name="Description" Val="Questa Advanced Simulator"/>
</Simulator>
<Simulator Name="Xcelium">
<Option Name="Description" Val="Xcelium Parallel Simulator"/>
</Simulator>
<Simulator Name="VCS">
<Option Name="Description" Val="Verilog Compiler Simulator (VCS)"/>
</Simulator>
<Simulator Name="Riviera">
<Option Name="Description" Val="Riviera-PRO Simulator"/>
</Simulator>
</Simulators>
<Runs Version="1" Minor="21">
<Run Id="synth_1" Type="Ft3:Synth" SrcSet="sources_1" Part="xczu48dr-fsvg1517-2-i" ConstrsSet="constrs_1" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="true" WriteIncrSynthDcp="false" State="current" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/synth_1">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2023">
<Desc>Vivado Synthesis Defaults</Desc>
</StratHandle>
<Step Id="synth_design"/>
</Strategy>
<ReportStrategy Name="Vivado Synthesis Default Reports" Flow="Vivado Synthesis 2023"/>
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/>
</Run>
<Run Id="hrc_64_12_025_synth_1" Type="Ft3:Synth" SrcSet="hrc_64_12_025" Part="xczu48dr-fsvg1517-2-i" ConstrsSet="hrc_64_12_025" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/hrc_64_12_025_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/hrc_64_12_025_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/hrc_64_12_025_synth_1">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2023">
<Desc>Vivado Synthesis Defaults</Desc>
</StratHandle>
<Step Id="synth_design"/>
</Strategy>
<GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/>
<ReportStrategy Name="Vivado Synthesis Default Reports" Flow="Vivado Synthesis 2023"/>
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/>
</Run>
<Run Id="hrc_256_12_025_synth_1" Type="Ft3:Synth" SrcSet="hrc_256_12_025" Part="xczu48dr-fsvg1517-2-i" ConstrsSet="hrc_256_12_025" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/hrc_256_12_025_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/hrc_256_12_025_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/hrc_256_12_025_synth_1">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2023">
<Desc>Vivado Synthesis Defaults</Desc>
</StratHandle>
<Step Id="synth_design"/>
</Strategy>
<GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/>
<ReportStrategy Name="Vivado Synthesis Default Reports" Flow="Vivado Synthesis 2023"/>
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/>
</Run>
<Run Id="hrc_512_12_025_synth_1" Type="Ft3:Synth" SrcSet="hrc_512_12_025" Part="xczu48dr-fsvg1517-2-i" ConstrsSet="hrc_512_12_025" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/hrc_512_12_025_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/hrc_512_12_025_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/hrc_512_12_025_synth_1">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2023">
<Desc>Vivado Synthesis Defaults</Desc>
</StratHandle>
<Step Id="synth_design"/>
</Strategy>
<GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/>
<ReportStrategy Name="Vivado Synthesis Default Reports" Flow="Vivado Synthesis 2023"/>
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/>
</Run>
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xczu48dr-fsvg1517-2-i" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" SynthRun="synth_1" IncludeInArchive="true" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/impl_1">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2023">
<Desc>Default settings for Implementation.</Desc>
</StratHandle>
<Step Id="init_design"/>
<Step Id="opt_design"/>
<Step Id="power_opt_design"/>
<Step Id="place_design"/>
<Step Id="post_place_power_opt_design"/>
<Step Id="phys_opt_design"/>
<Step Id="route_design"/>
<Step Id="post_route_phys_opt_design"/>
<Step Id="write_bitstream"/>
</Strategy>
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2023"/>
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/>
</Run>
<Run Id="hrc_64_12_025_impl_1" Type="Ft2:EntireDesign" Part="xczu48dr-fsvg1517-2-i" ConstrsSet="hrc_64_12_025" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="hrc_64_12_025_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/hrc_64_12_025_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/hrc_64_12_025_impl_1">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2023">
<Desc>Default settings for Implementation.</Desc>
</StratHandle>
<Step Id="init_design"/>
<Step Id="opt_design"/>
<Step Id="power_opt_design"/>
<Step Id="place_design"/>
<Step Id="post_place_power_opt_design"/>
<Step Id="phys_opt_design"/>
<Step Id="route_design"/>
<Step Id="post_route_phys_opt_design"/>
<Step Id="write_bitstream"/>
</Strategy>
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2023"/>
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/>
</Run>
<Run Id="hrc_256_12_025_impl_1" Type="Ft2:EntireDesign" Part="xczu48dr-fsvg1517-2-i" ConstrsSet="hrc_256_12_025" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="hrc_256_12_025_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/hrc_256_12_025_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/hrc_256_12_025_impl_1">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2023">
<Desc>Default settings for Implementation.</Desc>
</StratHandle>
<Step Id="init_design"/>
<Step Id="opt_design"/>
<Step Id="power_opt_design"/>
<Step Id="place_design"/>
<Step Id="post_place_power_opt_design"/>
<Step Id="phys_opt_design"/>
<Step Id="route_design"/>
<Step Id="post_route_phys_opt_design"/>
<Step Id="write_bitstream"/>
</Strategy>
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2023"/>
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/>
</Run>
<Run Id="hrc_512_12_025_impl_1" Type="Ft2:EntireDesign" Part="xczu48dr-fsvg1517-2-i" ConstrsSet="hrc_512_12_025" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="hrc_512_12_025_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/hrc_512_12_025_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/hrc_512_12_025_impl_1">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2023">
<Desc>Default settings for Implementation.</Desc>
</StratHandle>
<Step Id="init_design"/>
<Step Id="opt_design"/>
<Step Id="power_opt_design"/>
<Step Id="place_design"/>
<Step Id="post_place_power_opt_design"/>
<Step Id="phys_opt_design"/>
<Step Id="route_design"/>
<Step Id="post_route_phys_opt_design"/>
<Step Id="write_bitstream"/>
</Strategy>
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2023"/>
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/>
</Run>
</Runs>
<Board/>
<DashboardSummary Version="1" Minor="0">
<Dashboards>
<Dashboard Name="default_dashboard">
<Gadgets>
<Gadget Name="drc_1" Type="drc" Version="1" Row="2" Column="0">
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_drc_0 "/>
</Gadget>
<Gadget Name="methodology_1" Type="methodology" Version="1" Row="2" Column="1">
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_methodology_0 "/>
</Gadget>
<Gadget Name="power_1" Type="power" Version="1" Row="1" Column="0">
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_power_0 "/>
</Gadget>
<Gadget Name="timing_1" Type="timing" Version="1" Row="0" Column="1">
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_timing_summary_0 "/>
</Gadget>
<Gadget Name="utilization_1" Type="utilization" Version="1" Row="0" Column="0">
<GadgetParam Name="REPORTS" Type="string_list" Value="synth_1#synth_1_synth_report_utilization_0 "/>
<GadgetParam Name="RUN.STEP" Type="string" Value="synth_design"/>
<GadgetParam Name="RUN.TYPE" Type="string" Value="synthesis"/>
</Gadget>
<Gadget Name="utilization_2" Type="utilization" Version="1" Row="1" Column="1">
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_place_report_utilization_0 "/>
</Gadget>
</Gadgets>
</Dashboard>
<CurrentDashboard>default_dashboard</CurrentDashboard>
</Dashboards>
</DashboardSummary>
</Project>
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fb8b4c535ad8d52382fab27f69421ec5552cdc509ed9af9b661da148fe2ef6d5
size 1071933
@@ -0,0 +1,420 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="xilinx.gnu.armv7.exe.debug.1979421842">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="xilinx.gnu.armv7.exe.debug.1979421842" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/>
<extensions>
<extension id="com.xilinx.sdk.managedbuilder.XELF.arm.a53.x32" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="xilinx.gnu.armv7.exe.debug.1979421842" name="Debug" parent="xilinx.gnu.armv7.exe.debug" prebuildStep="a9-linaro-pre-build-step">
<folderInfo id="xilinx.gnu.armv7.exe.debug.1979421842." name="/" resourcePath="">
<toolChain id="xilinx.gnu.armv7.exe.debug.toolchain.100336480" name="Vitis ARM v7 GNU Toolchain" superClass="xilinx.gnu.armv7.exe.debug.toolchain">
<targetPlatform binaryParser="com.xilinx.sdk.managedbuilder.XELF.arm.a53.x32" id="xilinx.armv7.target.gnu.base.debug.93012261" isAbstract="false" name="Debug Platform" superClass="xilinx.armv7.target.gnu.base.debug"/>
<builder buildPath="${workspace_loc:/cx9261a_app}/Debug" enableAutoBuild="true" id="xilinx.gnu.armv7.toolchain.builder.debug.332900046" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="GNU make" superClass="xilinx.gnu.armv7.toolchain.builder.debug"/>
<tool command="arm-none-eabi-gcc" commandLinePattern="${COMMAND} -c ${FLAGS} ${OUTPUT_FLAG}${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="xilinx.gnu.armv7.c.toolchain.assembler.debug.457618078" name="ARM v7 gcc assembler" superClass="xilinx.gnu.armv7.c.toolchain.assembler.debug">
<inputType id="xilinx.gnu.assembler.input.2038248235" superClass="xilinx.gnu.assembler.input"/>
</tool>
<tool id="xilinx.gnu.armv7.c.toolchain.compiler.debug.931621375" name="ARM v7 gcc compiler" superClass="xilinx.gnu.armv7.c.toolchain.compiler.debug">
<option defaultValue="gnu.c.optimization.level.none" id="xilinx.gnu.compiler.option.optimization.level.1360143461" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.1499390092" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.506182700" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=cx9261a_app,fileType=bspInclude}"/>
</option>
<option id="xilinx.gnu.compiler.dircategory.includes.220346413" superClass="xilinx.gnu.compiler.dircategory.includes" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/include}&quot;"/>
</option>
<option id="xilinx.gnu.compiler.misc.other.1852092406" superClass="xilinx.gnu.compiler.misc.other" value="-c -fmessage-length=0 -MT&quot;$@&quot; -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -fpermissive -Wno-pointer-sign -Wno-write-strings -Wno-narrowing" valueType="string"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.flags.1696458580" superClass="xilinx.gnu.compiler.inferred.swplatform.flags" value="" valueType="string"/>
<inputType id="xilinx.gnu.armv7.c.compiler.input.422984503" name="C source files" superClass="xilinx.gnu.armv7.c.compiler.input"/>
</tool>
<tool id="xilinx.gnu.armv7.cxx.toolchain.compiler.debug.854175703" name="ARM v7 g++ compiler" superClass="xilinx.gnu.armv7.cxx.toolchain.compiler.debug">
<option defaultValue="gnu.c.optimization.level.none" id="xilinx.gnu.compiler.option.optimization.level.335662221" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.1531424834" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.632409405" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=cx9261a_app,fileType=bspInclude}"/>
</option>
<option id="xilinx.gnu.compiler.misc.other.1223544719" name="Other flags" superClass="xilinx.gnu.compiler.misc.other" useByScannerDiscovery="false" value="-c -fmessage-length=0 -MT&quot;$@&quot; -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -fpermissive -Wno-pointer-sign -Wno-write-strings -Wno-narrowing" valueType="string"/>
<option id="xilinx.gnu.compiler.dircategory.includes.1629268503" superClass="xilinx.gnu.compiler.dircategory.includes" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/include}&quot;"/>
</option>
<option id="xilinx.gnu.compiler.inferred.swplatform.flags.1301740818" superClass="xilinx.gnu.compiler.inferred.swplatform.flags" value="" valueType="string"/>
<inputType id="xilinx.gnu.armv7.cxx.compiler.input.1892739078" name="C++ source files" superClass="xilinx.gnu.armv7.cxx.compiler.input"/>
</tool>
<tool id="xilinx.gnu.armv7.toolchain.archiver.1120439520" name="ARM v7 archiver" superClass="xilinx.gnu.armv7.toolchain.archiver"/>
<tool id="xilinx.gnu.armv7.c.toolchain.linker.debug.1821868307" name="ARM v7 gcc linker" superClass="xilinx.gnu.armv7.c.toolchain.linker.debug">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.504712081" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=cx9261a_app,fileType=bspLib}"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.1998733015" name="Software Platform Inferred Flags" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,-lstdc++,--end-group"/>
</option>
<option id="xilinx.gnu.c.linker.option.lscript.1398313849" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
<option id="xilinx.gnu.c.link.option.libs.528804235" superClass="xilinx.gnu.c.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" value="m"/>
</option>
<inputType id="xilinx.gnu.linker.input.1985286695" superClass="xilinx.gnu.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<inputType id="xilinx.gnu.linker.input.lscript.1368917167" name="Linker Script" superClass="xilinx.gnu.linker.input.lscript"/>
</tool>
<tool id="xilinx.gnu.armv7.cxx.toolchain.linker.debug.517258282" name="ARM v7 g++ linker" superClass="xilinx.gnu.armv7.cxx.toolchain.linker.debug">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.590125991" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=cx9261a_app,fileType=bspLib}"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.1601353927" name="Software Platform Inferred Flags" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,-lstdc++,--end-group"/>
</option>
<option id="xilinx.gnu.c.linker.option.lscript.445430658" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
<option id="xilinx.gnu.c.link.option.ldflags.738989774" name="Linker Flags" superClass="xilinx.gnu.c.link.option.ldflags" value=" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -Wl,-build-id=none -specs=Xilinx.spec" valueType="string"/>
<option id="xilinx.gnu.c.link.option.libs.992607376" superClass="xilinx.gnu.c.link.option.libs" useByScannerDiscovery="false" valueType="libs">
<listOptionValue builtIn="false" value="m"/>
</option>
<inputType id="xilinx.gnu.linker.input.2018726619" superClass="xilinx.gnu.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<inputType id="xilinx.gnu.linker.input.lscript.155429687" name="Linker Script" superClass="xilinx.gnu.linker.input.lscript"/>
</tool>
<tool id="xilinx.gnu.armv7.size.debug.365229255" name="ARM v7 Print Size" superClass="xilinx.gnu.armv7.size.debug"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="_ide" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="xilinx.gnu.armv7.exe.release.1480550519">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="xilinx.gnu.armv7.exe.release.1480550519" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings/>
<extensions>
<extension id="com.xilinx.sdk.managedbuilder.XELF.arm.a53.x32" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="xilinx.gnu.armv7.exe.release.1480550519" name="Release" parent="xilinx.gnu.armv7.exe.release" prebuildStep="a9-linaro-pre-build-step">
<folderInfo id="xilinx.gnu.armv7.exe.release.1480550519." name="/" resourcePath="">
<toolChain id="xilinx.gnu.armv7.exe.release.toolchain.235955300" name="Vitis ARM v7 GNU Toolchain" superClass="xilinx.gnu.armv7.exe.release.toolchain">
<targetPlatform binaryParser="com.xilinx.sdk.managedbuilder.XELF.arm.a53.x32" id="xilinx.armv7.target.gnu.base.release.943402706" isAbstract="false" name="Release Platform" superClass="xilinx.armv7.target.gnu.base.release"/>
<builder buildPath="${workspace_loc:/cx9261a_app}/Release" enableAutoBuild="true" id="xilinx.gnu.armv7.toolchain.builder.release.450540806" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="GNU make" superClass="xilinx.gnu.armv7.toolchain.builder.release"/>
<tool id="xilinx.gnu.armv7.c.toolchain.assembler.release.647772233" name="ARM v7 gcc assembler" superClass="xilinx.gnu.armv7.c.toolchain.assembler.release">
<inputType id="xilinx.gnu.assembler.input.759195644" superClass="xilinx.gnu.assembler.input"/>
</tool>
<tool id="xilinx.gnu.armv7.c.toolchain.compiler.release.1520602224" name="ARM v7 gcc compiler" superClass="xilinx.gnu.armv7.c.toolchain.compiler.release">
<option defaultValue="gnu.c.optimization.level.more" id="xilinx.gnu.compiler.option.optimization.level.347411708" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.2075778540" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.270524388" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=cx9261a_app,fileType=bspInclude}"/>
</option>
<option id="xilinx.gnu.compiler.dircategory.includes.1419698669" superClass="xilinx.gnu.compiler.dircategory.includes" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/include}&quot;"/>
</option>
<option id="xilinx.gnu.compiler.misc.other.182431578" superClass="xilinx.gnu.compiler.misc.other" value="-c -fmessage-length=0 -MT&quot;$@&quot; -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -fpermissive -Wno-pointer-sign -Wno-write-strings -Wno-narrowing" valueType="string"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.flags.897762032" superClass="xilinx.gnu.compiler.inferred.swplatform.flags" value="" valueType="string"/>
<inputType id="xilinx.gnu.armv7.c.compiler.input.1755253841" name="C source files" superClass="xilinx.gnu.armv7.c.compiler.input"/>
</tool>
<tool id="xilinx.gnu.armv7.cxx.toolchain.compiler.release.1493802490" name="ARM v7 g++ compiler" superClass="xilinx.gnu.armv7.cxx.toolchain.compiler.release">
<option defaultValue="gnu.c.optimization.level.more" id="xilinx.gnu.compiler.option.optimization.level.1645654485" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.1410083352" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.146649814" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=cx9261a_app,fileType=bspInclude}"/>
</option>
<option id="xilinx.gnu.compiler.misc.other.275002810" name="Other flags" superClass="xilinx.gnu.compiler.misc.other" value="-c -fmessage-length=0 -MT&quot;$@&quot; -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -fpermissive -Wno-pointer-sign -Wno-write-strings -Wno-narrowing" valueType="string"/>
<option id="xilinx.gnu.compiler.dircategory.includes.2130713489" superClass="xilinx.gnu.compiler.dircategory.includes" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/include}&quot;"/>
</option>
<option id="xilinx.gnu.compiler.inferred.swplatform.flags.1229759994" superClass="xilinx.gnu.compiler.inferred.swplatform.flags" value="" valueType="string"/>
<inputType id="xilinx.gnu.armv7.cxx.compiler.input.177094692" name="C++ source files" superClass="xilinx.gnu.armv7.cxx.compiler.input"/>
</tool>
<tool id="xilinx.gnu.armv7.toolchain.archiver.909706957" name="ARM v7 archiver" superClass="xilinx.gnu.armv7.toolchain.archiver"/>
<tool id="xilinx.gnu.armv7.c.toolchain.linker.release.765816324" name="ARM v7 gcc linker" superClass="xilinx.gnu.armv7.c.toolchain.linker.release">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.1828409907" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=cx9261a_app,fileType=bspLib}"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.732612107" name="Software Platform Inferred Flags" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,-lstdc++,--end-group"/>
</option>
<option id="xilinx.gnu.c.linker.option.lscript.136173749" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
<option id="xilinx.gnu.c.link.option.libs.1597161826" superClass="xilinx.gnu.c.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" value="m"/>
</option>
<inputType id="xilinx.gnu.linker.input.1736949766" superClass="xilinx.gnu.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<inputType id="xilinx.gnu.linker.input.lscript.1097542079" name="Linker Script" superClass="xilinx.gnu.linker.input.lscript"/>
</tool>
<tool id="xilinx.gnu.armv7.cxx.toolchain.linker.release.1772432830" name="ARM v7 g++ linker" superClass="xilinx.gnu.armv7.cxx.toolchain.linker.release">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.1104557014" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=cx9261a_app,fileType=bspLib}"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.1087328004" name="Software Platform Inferred Flags" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,-lstdc++,--end-group"/>
</option>
<option id="xilinx.gnu.c.linker.option.lscript.403130179" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
<option id="xilinx.gnu.c.link.option.ldflags.1823588259" name="Linker Flags" superClass="xilinx.gnu.c.link.option.ldflags" value=" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -Wl,-build-id=none -specs=Xilinx.spec" valueType="string"/>
<option id="xilinx.gnu.c.link.option.libs.285503822" superClass="xilinx.gnu.c.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" value="m"/>
</option>
<inputType id="xilinx.gnu.linker.input.512730756" superClass="xilinx.gnu.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<inputType id="xilinx.gnu.linker.input.lscript.728433388" name="Linker Script" superClass="xilinx.gnu.linker.input.lscript"/>
</tool>
<tool id="xilinx.gnu.armv7.size.release.1894354961" name="ARM v7 Print Size" superClass="xilinx.gnu.armv7.size.release"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="_ide" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="cx9261a_app.xilinx.gnu.armv7.exe.81578981" name="Vitis ARM v7 Executable" projectType="xilinx.gnu.armv7.exe"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="xilinx.gnu.armv7.exe.debug.1979421842;xilinx.gnu.armv7.exe.debug.1979421842.">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53X32GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.armv7.exe.release.1480550519;xilinx.gnu.armv7.exe.release.1480550519.;xilinx.gnu.armv7.c.toolchain.compiler.release.1520602224;xilinx.gnu.armv7.c.compiler.input.1755253841">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53X32GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.armv7.exe.release.1480550519;xilinx.gnu.armv7.exe.release.1480550519.">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53X32GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.armv7.exe.debug.1979421842;xilinx.gnu.armv7.exe.debug.1979421842.;xilinx.gnu.armv7.c.toolchain.compiler.debug.931621375;xilinx.gnu.armv7.c.compiler.input.422984503">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53X32GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="refreshScope"/>
</cproject>
@@ -0,0 +1,2 @@
/Debug/
/Release/
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>cx9261a_app</name>
<comment>Created by Vitis v2024.1</comment>
<projects>
<project>cx9261a_platform</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.xilinx.sdx.sdk.core.SdkProjectNature</nature>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a90a219463fc6463674d91246b22f422d23c3bdcef4f6dd37a75f2d261b3d5ca
size 13321510
@@ -0,0 +1,874 @@
proc ps7_pll_init_data_3_0 {} {
mwr -force 0XF8000008 0x0000DF0D
mask_write 0XF8000110 0x003FFFF0 0x000FA220
mask_write 0XF8000100 0x0007F000 0x00028000
mask_write 0XF8000100 0x00000010 0x00000010
mask_write 0XF8000100 0x00000001 0x00000001
mask_write 0XF8000100 0x00000001 0x00000000
mask_poll 0XF800010C 0x00000001
mask_write 0XF8000100 0x00000010 0x00000000
mask_write 0XF8000120 0x1F003F30 0x1F000200
mask_write 0XF8000114 0x003FFFF0 0x0012C220
mask_write 0XF8000104 0x0007F000 0x00020000
mask_write 0XF8000104 0x00000010 0x00000010
mask_write 0XF8000104 0x00000001 0x00000001
mask_write 0XF8000104 0x00000001 0x00000000
mask_poll 0XF800010C 0x00000002
mask_write 0XF8000104 0x00000010 0x00000000
mask_write 0XF8000124 0xFFF00003 0x0C200003
mask_write 0XF8000118 0x003FFFF0 0x001452C0
mask_write 0XF8000108 0x0007F000 0x0001E000
mask_write 0XF8000108 0x00000010 0x00000010
mask_write 0XF8000108 0x00000001 0x00000001
mask_write 0XF8000108 0x00000001 0x00000000
mask_poll 0XF800010C 0x00000004
mask_write 0XF8000108 0x00000010 0x00000000
mwr -force 0XF8000004 0x0000767B
}
proc ps7_clock_init_data_3_0 {} {
mwr -force 0XF8000008 0x0000DF0D
mask_write 0XF8000128 0x03F03F01 0x00700F01
mask_write 0XF8000138 0x00000011 0x00000001
mask_write 0XF8000140 0x03F03F71 0x00500801
mask_write 0XF800014C 0x00003F31 0x00000501
mask_write 0XF8000150 0x00003F33 0x00001401
mask_write 0XF8000154 0x00003F33 0x00001402
mask_write 0XF8000168 0x00003F31 0x00000501
mask_write 0XF8000170 0x03F03F30 0x00400500
mask_write 0XF8000180 0x03F03F30 0x00100500
mask_write 0XF80001C4 0x00000001 0x00000001
mask_write 0XF800012C 0x01FFCCCD 0x01EC044D
mwr -force 0XF8000004 0x0000767B
}
proc ps7_ddr_init_data_3_0 {} {
mask_write 0XF8006000 0x0001FFFF 0x00000080
mask_write 0XF8006004 0x0007FFFF 0x00001082
mask_write 0XF8006008 0x03FFFFFF 0x03C0780F
mask_write 0XF800600C 0x03FFFFFF 0x02001001
mask_write 0XF8006010 0x03FFFFFF 0x00014001
mask_write 0XF8006014 0x001FFFFF 0x0004159B
mask_write 0XF8006018 0xF7FFFFFF 0x452444D3
mask_write 0XF800601C 0xFFFFFFFF 0x7282BCE5
mask_write 0XF8006020 0x7FDFFFFC 0x270872B0
mask_write 0XF8006024 0x0FFFFFC3 0x00000000
mask_write 0XF8006028 0x00003FFF 0x00002007
mask_write 0XF800602C 0xFFFFFFFF 0x00000008
mask_write 0XF8006030 0xFFFFFFFF 0x00040B30
mask_write 0XF8006034 0x13FF3FFF 0x000116D4
mask_write 0XF8006038 0x00000003 0x00000000
mask_write 0XF800603C 0x000FFFFF 0x00000777
mask_write 0XF8006040 0xFFFFFFFF 0xFFF00000
mask_write 0XF8006044 0x0FFFFFFF 0x0F666666
mask_write 0XF8006048 0x0003F03F 0x0003C008
mask_write 0XF8006050 0xFF0F8FFF 0x77010800
mask_write 0XF8006058 0x00010000 0x00000000
mask_write 0XF800605C 0x0000FFFF 0x00005003
mask_write 0XF8006060 0x000017FF 0x0000003E
mask_write 0XF8006064 0x00021FE0 0x00020000
mask_write 0XF8006068 0x03FFFFFF 0x00284141
mask_write 0XF800606C 0x0000FFFF 0x00001610
mask_write 0XF8006078 0x03FFFFFF 0x00466111
mask_write 0XF800607C 0x000FFFFF 0x00032222
mask_write 0XF80060A4 0xFFFFFFFF 0x10200802
mask_write 0XF80060A8 0x0FFFFFFF 0x0690CB73
mask_write 0XF80060AC 0x000001FF 0x000001FE
mask_write 0XF80060B0 0x1FFFFFFF 0x1CFFFFFF
mask_write 0XF80060B4 0x00000200 0x00000200
mask_write 0XF80060B8 0x01FFFFFF 0x00200066
mask_write 0XF80060C4 0x00000003 0x00000000
mask_write 0XF80060C8 0x000000FF 0x00000000
mask_write 0XF80060DC 0x00000001 0x00000000
mask_write 0XF80060F0 0x0000FFFF 0x00000000
mask_write 0XF80060F4 0x0000000F 0x00000008
mask_write 0XF8006114 0x000000FF 0x00000000
mask_write 0XF8006118 0x7FFFFFCF 0x40000001
mask_write 0XF800611C 0x7FFFFFCF 0x40000001
mask_write 0XF8006120 0x7FFFFFCF 0x40000001
mask_write 0XF8006124 0x7FFFFFCF 0x40000001
mask_write 0XF800612C 0x000FFFFF 0x0003B81E
mask_write 0XF8006130 0x000FFFFF 0x00043425
mask_write 0XF8006134 0x000FFFFF 0x0003CC19
mask_write 0XF8006138 0x000FFFFF 0x0004242A
mask_write 0XF8006140 0x000FFFFF 0x00000035
mask_write 0XF8006144 0x000FFFFF 0x00000035
mask_write 0XF8006148 0x000FFFFF 0x00000035
mask_write 0XF800614C 0x000FFFFF 0x00000035
mask_write 0XF8006154 0x000FFFFF 0x0000009E
mask_write 0XF8006158 0x000FFFFF 0x000000A5
mask_write 0XF800615C 0x000FFFFF 0x00000099
mask_write 0XF8006160 0x000FFFFF 0x000000AA
mask_write 0XF8006168 0x001FFFFF 0x00000143
mask_write 0XF800616C 0x001FFFFF 0x00000162
mask_write 0XF8006170 0x001FFFFF 0x00000148
mask_write 0XF8006174 0x001FFFFF 0x0000015E
mask_write 0XF800617C 0x000FFFFF 0x000000DE
mask_write 0XF8006180 0x000FFFFF 0x000000E5
mask_write 0XF8006184 0x000FFFFF 0x000000D9
mask_write 0XF8006188 0x000FFFFF 0x000000EA
mask_write 0XF8006190 0x6FFFFEFE 0x00040080
mask_write 0XF8006194 0x000FFFFF 0x0001FC82
mask_write 0XF8006204 0xFFFFFFFF 0x00000000
mask_write 0XF8006208 0x000703FF 0x000003FF
mask_write 0XF800620C 0x000703FF 0x000003FF
mask_write 0XF8006210 0x000703FF 0x000003FF
mask_write 0XF8006214 0x000703FF 0x000003FF
mask_write 0XF8006218 0x000F03FF 0x000003FF
mask_write 0XF800621C 0x000F03FF 0x000003FF
mask_write 0XF8006220 0x000F03FF 0x000003FF
mask_write 0XF8006224 0x000F03FF 0x000003FF
mask_write 0XF80062A8 0x00000FF5 0x00000000
mask_write 0XF80062AC 0xFFFFFFFF 0x00000000
mask_write 0XF80062B0 0x003FFFFF 0x00005125
mask_write 0XF80062B4 0x0003FFFF 0x000012A8
mask_poll 0XF8000B74 0x00002000
mask_write 0XF8006000 0x0001FFFF 0x00000081
mask_poll 0XF8006054 0x00000007
}
proc ps7_mio_init_data_3_0 {} {
mwr -force 0XF8000008 0x0000DF0D
mask_write 0XF8000B00 0x00000071 0x00000001
mask_write 0XF8000B40 0x00000FFF 0x00000600
mask_write 0XF8000B44 0x00000FFF 0x00000600
mask_write 0XF8000B48 0x00000FFF 0x00000672
mask_write 0XF8000B4C 0x00000FFF 0x00000672
mask_write 0XF8000B50 0x00000FFF 0x00000674
mask_write 0XF8000B54 0x00000FFF 0x00000674
mask_write 0XF8000B58 0x00000FFF 0x00000600
mask_write 0XF8000B5C 0xFFFFFFFF 0x0018C61C
mask_write 0XF8000B60 0xFFFFFFFF 0x00F9861C
mask_write 0XF8000B64 0xFFFFFFFF 0x00F9861C
mask_write 0XF8000B68 0xFFFFFFFF 0x00F9861C
mask_write 0XF8000B6C 0x00007FFF 0x00000209
mask_write 0XF8000B70 0x00000001 0x00000001
mask_write 0XF8000B70 0x00000021 0x00000020
mask_write 0XF8000B70 0x07FEFFFF 0x00000823
mask_write 0XF8000700 0x00003FFF 0x00001202
mask_write 0XF8000704 0x00003FFF 0x00001202
mask_write 0XF8000708 0x00003FFF 0x00000202
mask_write 0XF800070C 0x00003FFF 0x00000202
mask_write 0XF8000710 0x00003FFF 0x00000202
mask_write 0XF8000714 0x00003FFF 0x00000202
mask_write 0XF8000718 0x00003FFF 0x00000202
mask_write 0XF800071C 0x00003FFF 0x00000200
mask_write 0XF8000720 0x00003FFF 0x00000202
mask_write 0XF8000724 0x00003FFF 0x00001202
mask_write 0XF8000728 0x00003FFF 0x00001202
mask_write 0XF800072C 0x00003FFF 0x00001202
mask_write 0XF8000730 0x00003FFF 0x00001202
mask_write 0XF8000734 0x00003FFF 0x00001202
mask_write 0XF8000738 0x00003F01 0x00001201
mask_write 0XF800073C 0x00003F01 0x00001201
mask_write 0XF8000740 0x00003FFF 0x00002802
mask_write 0XF8000744 0x00003FFF 0x00002802
mask_write 0XF8000748 0x00003FFF 0x00002802
mask_write 0XF800074C 0x00003FFF 0x00002802
mask_write 0XF8000750 0x00003FFF 0x00002802
mask_write 0XF8000754 0x00003FFF 0x00002802
mask_write 0XF8000758 0x00003FFF 0x00000803
mask_write 0XF800075C 0x00003FFF 0x00000803
mask_write 0XF8000760 0x00003FFF 0x00000803
mask_write 0XF8000764 0x00003FFF 0x00000803
mask_write 0XF8000768 0x00003FFF 0x00000803
mask_write 0XF800076C 0x00003FFF 0x00000803
mask_write 0XF8000770 0x00003FFF 0x00000204
mask_write 0XF8000774 0x00003FFF 0x00000205
mask_write 0XF8000778 0x00003FFF 0x00000204
mask_write 0XF800077C 0x00003FFF 0x00000205
mask_write 0XF8000780 0x00003FFF 0x00000204
mask_write 0XF8000784 0x00003FFF 0x00000204
mask_write 0XF8000788 0x00003FFF 0x00000204
mask_write 0XF800078C 0x00003FFF 0x00000204
mask_write 0XF8000790 0x00003FFF 0x00000205
mask_write 0XF8000794 0x00003FFF 0x00000204
mask_write 0XF8000798 0x00003FFF 0x00000204
mask_write 0XF800079C 0x00003FFF 0x00000204
mask_write 0XF80007A0 0x00003FFF 0x00000280
mask_write 0XF80007A4 0x00003FFF 0x00000280
mask_write 0XF80007A8 0x00003FFF 0x00000280
mask_write 0XF80007AC 0x00003FFF 0x00000280
mask_write 0XF80007B0 0x00003FFF 0x00000280
mask_write 0XF80007B4 0x00003FFF 0x00000280
mask_write 0XF80007B8 0x00003FFF 0x00001200
mask_write 0XF80007BC 0x00003FFF 0x00001200
mask_write 0XF80007C0 0x00003FFF 0x000002E0
mask_write 0XF80007C4 0x00003FFF 0x000002E1
mask_write 0XF80007C8 0x00003FFF 0x00001240
mask_write 0XF80007CC 0x00003FFF 0x00001240
mask_write 0XF80007D0 0x00003FFF 0x00000280
mask_write 0XF80007D4 0x00003FFF 0x00000280
mask_write 0XF8000830 0x003F003F 0x000E000F
mwr -force 0XF8000004 0x0000767B
}
proc ps7_peripherals_init_data_3_0 {} {
mwr -force 0XF8000008 0x0000DF0D
mask_write 0XF8000B48 0x00000180 0x00000180
mask_write 0XF8000B4C 0x00000180 0x00000180
mask_write 0XF8000B50 0x00000180 0x00000180
mask_write 0XF8000B54 0x00000180 0x00000180
mwr -force 0XF8000004 0x0000767B
mask_write 0XE0001034 0x000000FF 0x00000006
mask_write 0XE0001018 0x0000FFFF 0x0000003E
mask_write 0XE0001000 0x000001FF 0x00000017
mask_write 0XE0001004 0x000003FF 0x00000020
mask_write 0XE000D000 0x00080000 0x00080000
mask_write 0XF8007000 0x20000000 0x00000000
mask_write 0XE000A204 0xFFFFFFFF 0x00000080
mask_write 0XE000A000 0xFFFFFFFF 0xFF7F0080
mask_write 0XE000A208 0xFFFFFFFF 0x00000080
mask_write 0XE000A000 0xFFFFFFFF 0xFF7F0000
mask_delay 0XF8F00200 1
mask_write 0XE000A000 0xFFFFFFFF 0xFF7F0080
mask_write 0XE000A244 0x003FFFFF 0x0000C000
mask_write 0XE000A008 0xFFFFFFFF 0x7FFF8000
mask_write 0XE000A248 0x003FFFFF 0x0000C000
mask_write 0XE000A008 0xFFFFFFFF 0x7FFF0000
mask_delay 0XF8F00200 1
mask_write 0XE000A008 0xFFFFFFFF 0x7FFF8000
mask_write 0XE000A244 0x003FFFFF 0x0000C000
mask_write 0XE000A008 0xFFFFFFFF 0xBFFF4000
mask_write 0XE000A248 0x003FFFFF 0x0000C000
mask_write 0XE000A008 0xFFFFFFFF 0xBFFF0000
mask_delay 0XF8F00200 1
mask_write 0XE000A008 0xFFFFFFFF 0xBFFF4000
}
proc ps7_post_config_3_0 {} {
mwr -force 0XF8000008 0x0000DF0D
mask_write 0XF8000900 0x0000000F 0x0000000F
mask_write 0XF8000240 0xFFFFFFFF 0x00000000
mwr -force 0XF8000004 0x0000767B
}
proc ps7_debug_3_0 {} {
mwr -force 0XF8898FB0 0xC5ACCE55
mwr -force 0XF8899FB0 0xC5ACCE55
mwr -force 0XF8809FB0 0xC5ACCE55
}
proc ps7_pll_init_data_2_0 {} {
mwr -force 0XF8000008 0x0000DF0D
mask_write 0XF8000110 0x003FFFF0 0x000FA220
mask_write 0XF8000100 0x0007F000 0x00028000
mask_write 0XF8000100 0x00000010 0x00000010
mask_write 0XF8000100 0x00000001 0x00000001
mask_write 0XF8000100 0x00000001 0x00000000
mask_poll 0XF800010C 0x00000001
mask_write 0XF8000100 0x00000010 0x00000000
mask_write 0XF8000120 0x1F003F30 0x1F000200
mask_write 0XF8000114 0x003FFFF0 0x0012C220
mask_write 0XF8000104 0x0007F000 0x00020000
mask_write 0XF8000104 0x00000010 0x00000010
mask_write 0XF8000104 0x00000001 0x00000001
mask_write 0XF8000104 0x00000001 0x00000000
mask_poll 0XF800010C 0x00000002
mask_write 0XF8000104 0x00000010 0x00000000
mask_write 0XF8000124 0xFFF00003 0x0C200003
mask_write 0XF8000118 0x003FFFF0 0x001452C0
mask_write 0XF8000108 0x0007F000 0x0001E000
mask_write 0XF8000108 0x00000010 0x00000010
mask_write 0XF8000108 0x00000001 0x00000001
mask_write 0XF8000108 0x00000001 0x00000000
mask_poll 0XF800010C 0x00000004
mask_write 0XF8000108 0x00000010 0x00000000
mwr -force 0XF8000004 0x0000767B
}
proc ps7_clock_init_data_2_0 {} {
mwr -force 0XF8000008 0x0000DF0D
mask_write 0XF8000128 0x03F03F01 0x00700F01
mask_write 0XF8000138 0x00000011 0x00000001
mask_write 0XF8000140 0x03F03F71 0x00500801
mask_write 0XF800014C 0x00003F31 0x00000501
mask_write 0XF8000150 0x00003F33 0x00001401
mask_write 0XF8000154 0x00003F33 0x00001402
mask_write 0XF8000168 0x00003F31 0x00000501
mask_write 0XF8000170 0x03F03F30 0x00400500
mask_write 0XF8000180 0x03F03F30 0x00100500
mask_write 0XF80001C4 0x00000001 0x00000001
mask_write 0XF800012C 0x01FFCCCD 0x01EC044D
mwr -force 0XF8000004 0x0000767B
}
proc ps7_ddr_init_data_2_0 {} {
mask_write 0XF8006000 0x0001FFFF 0x00000080
mask_write 0XF8006004 0x1FFFFFFF 0x00081082
mask_write 0XF8006008 0x03FFFFFF 0x03C0780F
mask_write 0XF800600C 0x03FFFFFF 0x02001001
mask_write 0XF8006010 0x03FFFFFF 0x00014001
mask_write 0XF8006014 0x001FFFFF 0x0004159B
mask_write 0XF8006018 0xF7FFFFFF 0x452444D3
mask_write 0XF800601C 0xFFFFFFFF 0x7282BCE5
mask_write 0XF8006020 0xFFFFFFFC 0x272872B0
mask_write 0XF8006024 0x0FFFFFFF 0x0000003C
mask_write 0XF8006028 0x00003FFF 0x00002007
mask_write 0XF800602C 0xFFFFFFFF 0x00000008
mask_write 0XF8006030 0xFFFFFFFF 0x00040B30
mask_write 0XF8006034 0x13FF3FFF 0x000116D4
mask_write 0XF8006038 0x00001FC3 0x00000000
mask_write 0XF800603C 0x000FFFFF 0x00000777
mask_write 0XF8006040 0xFFFFFFFF 0xFFF00000
mask_write 0XF8006044 0x0FFFFFFF 0x0F666666
mask_write 0XF8006048 0x3FFFFFFF 0x0003C248
mask_write 0XF8006050 0xFF0F8FFF 0x77010800
mask_write 0XF8006058 0x0001FFFF 0x00000101
mask_write 0XF800605C 0x0000FFFF 0x00005003
mask_write 0XF8006060 0x000017FF 0x0000003E
mask_write 0XF8006064 0x00021FE0 0x00020000
mask_write 0XF8006068 0x03FFFFFF 0x00284141
mask_write 0XF800606C 0x0000FFFF 0x00001610
mask_write 0XF8006078 0x03FFFFFF 0x00466111
mask_write 0XF800607C 0x000FFFFF 0x00032222
mask_write 0XF80060A0 0x00FFFFFF 0x00008000
mask_write 0XF80060A4 0xFFFFFFFF 0x10200802
mask_write 0XF80060A8 0x0FFFFFFF 0x0690CB73
mask_write 0XF80060AC 0x000001FF 0x000001FE
mask_write 0XF80060B0 0x1FFFFFFF 0x1CFFFFFF
mask_write 0XF80060B4 0x000007FF 0x00000200
mask_write 0XF80060B8 0x01FFFFFF 0x00200066
mask_write 0XF80060C4 0x00000003 0x00000000
mask_write 0XF80060C8 0x000000FF 0x00000000
mask_write 0XF80060DC 0x00000001 0x00000000
mask_write 0XF80060F0 0x0000FFFF 0x00000000
mask_write 0XF80060F4 0x0000000F 0x00000008
mask_write 0XF8006114 0x000000FF 0x00000000
mask_write 0XF8006118 0x7FFFFFFF 0x40000001
mask_write 0XF800611C 0x7FFFFFFF 0x40000001
mask_write 0XF8006120 0x7FFFFFFF 0x40000001
mask_write 0XF8006124 0x7FFFFFFF 0x40000001
mask_write 0XF800612C 0x000FFFFF 0x0003B81E
mask_write 0XF8006130 0x000FFFFF 0x00043425
mask_write 0XF8006134 0x000FFFFF 0x0003CC19
mask_write 0XF8006138 0x000FFFFF 0x0004242A
mask_write 0XF8006140 0x000FFFFF 0x00000035
mask_write 0XF8006144 0x000FFFFF 0x00000035
mask_write 0XF8006148 0x000FFFFF 0x00000035
mask_write 0XF800614C 0x000FFFFF 0x00000035
mask_write 0XF8006154 0x000FFFFF 0x0000009E
mask_write 0XF8006158 0x000FFFFF 0x000000A5
mask_write 0XF800615C 0x000FFFFF 0x00000099
mask_write 0XF8006160 0x000FFFFF 0x000000AA
mask_write 0XF8006168 0x001FFFFF 0x00000143
mask_write 0XF800616C 0x001FFFFF 0x00000162
mask_write 0XF8006170 0x001FFFFF 0x00000148
mask_write 0XF8006174 0x001FFFFF 0x0000015E
mask_write 0XF800617C 0x000FFFFF 0x000000DE
mask_write 0XF8006180 0x000FFFFF 0x000000E5
mask_write 0XF8006184 0x000FFFFF 0x000000D9
mask_write 0XF8006188 0x000FFFFF 0x000000EA
mask_write 0XF8006190 0xFFFFFFFF 0x10040080
mask_write 0XF8006194 0x000FFFFF 0x0001FC82
mask_write 0XF8006204 0xFFFFFFFF 0x00000000
mask_write 0XF8006208 0x000F03FF 0x000803FF
mask_write 0XF800620C 0x000F03FF 0x000803FF
mask_write 0XF8006210 0x000F03FF 0x000803FF
mask_write 0XF8006214 0x000F03FF 0x000803FF
mask_write 0XF8006218 0x000F03FF 0x000003FF
mask_write 0XF800621C 0x000F03FF 0x000003FF
mask_write 0XF8006220 0x000F03FF 0x000003FF
mask_write 0XF8006224 0x000F03FF 0x000003FF
mask_write 0XF80062A8 0x00000FF7 0x00000000
mask_write 0XF80062AC 0xFFFFFFFF 0x00000000
mask_write 0XF80062B0 0x003FFFFF 0x00005125
mask_write 0XF80062B4 0x0003FFFF 0x000012A8
mask_poll 0XF8000B74 0x00002000
mask_write 0XF8006000 0x0001FFFF 0x00000081
mask_poll 0XF8006054 0x00000007
}
proc ps7_mio_init_data_2_0 {} {
mwr -force 0XF8000008 0x0000DF0D
mask_write 0XF8000B00 0x00000303 0x00000001
mask_write 0XF8000B40 0x00000FFF 0x00000600
mask_write 0XF8000B44 0x00000FFF 0x00000600
mask_write 0XF8000B48 0x00000FFF 0x00000672
mask_write 0XF8000B4C 0x00000FFF 0x00000672
mask_write 0XF8000B50 0x00000FFF 0x00000674
mask_write 0XF8000B54 0x00000FFF 0x00000674
mask_write 0XF8000B58 0x00000FFF 0x00000600
mask_write 0XF8000B5C 0xFFFFFFFF 0x0018C61C
mask_write 0XF8000B60 0xFFFFFFFF 0x00F9861C
mask_write 0XF8000B64 0xFFFFFFFF 0x00F9861C
mask_write 0XF8000B68 0xFFFFFFFF 0x00F9861C
mask_write 0XF8000B6C 0x00007FFF 0x00000209
mask_write 0XF8000B70 0x00000021 0x00000021
mask_write 0XF8000B70 0x00000021 0x00000020
mask_write 0XF8000B70 0x07FFFFFF 0x00000823
mask_write 0XF8000700 0x00003FFF 0x00001202
mask_write 0XF8000704 0x00003FFF 0x00001202
mask_write 0XF8000708 0x00003FFF 0x00000202
mask_write 0XF800070C 0x00003FFF 0x00000202
mask_write 0XF8000710 0x00003FFF 0x00000202
mask_write 0XF8000714 0x00003FFF 0x00000202
mask_write 0XF8000718 0x00003FFF 0x00000202
mask_write 0XF800071C 0x00003FFF 0x00000200
mask_write 0XF8000720 0x00003FFF 0x00000202
mask_write 0XF8000724 0x00003FFF 0x00001202
mask_write 0XF8000728 0x00003FFF 0x00001202
mask_write 0XF800072C 0x00003FFF 0x00001202
mask_write 0XF8000730 0x00003FFF 0x00001202
mask_write 0XF8000734 0x00003FFF 0x00001202
mask_write 0XF8000738 0x00003F01 0x00001201
mask_write 0XF800073C 0x00003F01 0x00001201
mask_write 0XF8000740 0x00003FFF 0x00002802
mask_write 0XF8000744 0x00003FFF 0x00002802
mask_write 0XF8000748 0x00003FFF 0x00002802
mask_write 0XF800074C 0x00003FFF 0x00002802
mask_write 0XF8000750 0x00003FFF 0x00002802
mask_write 0XF8000754 0x00003FFF 0x00002802
mask_write 0XF8000758 0x00003FFF 0x00000803
mask_write 0XF800075C 0x00003FFF 0x00000803
mask_write 0XF8000760 0x00003FFF 0x00000803
mask_write 0XF8000764 0x00003FFF 0x00000803
mask_write 0XF8000768 0x00003FFF 0x00000803
mask_write 0XF800076C 0x00003FFF 0x00000803
mask_write 0XF8000770 0x00003FFF 0x00000204
mask_write 0XF8000774 0x00003FFF 0x00000205
mask_write 0XF8000778 0x00003FFF 0x00000204
mask_write 0XF800077C 0x00003FFF 0x00000205
mask_write 0XF8000780 0x00003FFF 0x00000204
mask_write 0XF8000784 0x00003FFF 0x00000204
mask_write 0XF8000788 0x00003FFF 0x00000204
mask_write 0XF800078C 0x00003FFF 0x00000204
mask_write 0XF8000790 0x00003FFF 0x00000205
mask_write 0XF8000794 0x00003FFF 0x00000204
mask_write 0XF8000798 0x00003FFF 0x00000204
mask_write 0XF800079C 0x00003FFF 0x00000204
mask_write 0XF80007A0 0x00003FFF 0x00000280
mask_write 0XF80007A4 0x00003FFF 0x00000280
mask_write 0XF80007A8 0x00003FFF 0x00000280
mask_write 0XF80007AC 0x00003FFF 0x00000280
mask_write 0XF80007B0 0x00003FFF 0x00000280
mask_write 0XF80007B4 0x00003FFF 0x00000280
mask_write 0XF80007B8 0x00003FFF 0x00001200
mask_write 0XF80007BC 0x00003FFF 0x00001200
mask_write 0XF80007C0 0x00003FFF 0x000002E0
mask_write 0XF80007C4 0x00003FFF 0x000002E1
mask_write 0XF80007C8 0x00003FFF 0x00001240
mask_write 0XF80007CC 0x00003FFF 0x00001240
mask_write 0XF80007D0 0x00003FFF 0x00000280
mask_write 0XF80007D4 0x00003FFF 0x00000280
mask_write 0XF8000830 0x003F003F 0x000E000F
mwr -force 0XF8000004 0x0000767B
}
proc ps7_peripherals_init_data_2_0 {} {
mwr -force 0XF8000008 0x0000DF0D
mask_write 0XF8000B48 0x00000180 0x00000180
mask_write 0XF8000B4C 0x00000180 0x00000180
mask_write 0XF8000B50 0x00000180 0x00000180
mask_write 0XF8000B54 0x00000180 0x00000180
mwr -force 0XF8000004 0x0000767B
mask_write 0XE0001034 0x000000FF 0x00000006
mask_write 0XE0001018 0x0000FFFF 0x0000003E
mask_write 0XE0001000 0x000001FF 0x00000017
mask_write 0XE0001004 0x00000FFF 0x00000020
mask_write 0XE000D000 0x00080000 0x00080000
mask_write 0XF8007000 0x20000000 0x00000000
mask_write 0XE000A204 0xFFFFFFFF 0x00000080
mask_write 0XE000A000 0xFFFFFFFF 0xFF7F0080
mask_write 0XE000A208 0xFFFFFFFF 0x00000080
mask_write 0XE000A000 0xFFFFFFFF 0xFF7F0000
mask_delay 0XF8F00200 1
mask_write 0XE000A000 0xFFFFFFFF 0xFF7F0080
mask_write 0XE000A244 0x003FFFFF 0x0000C000
mask_write 0XE000A008 0xFFFFFFFF 0x7FFF8000
mask_write 0XE000A248 0x003FFFFF 0x0000C000
mask_write 0XE000A008 0xFFFFFFFF 0x7FFF0000
mask_delay 0XF8F00200 1
mask_write 0XE000A008 0xFFFFFFFF 0x7FFF8000
mask_write 0XE000A244 0x003FFFFF 0x0000C000
mask_write 0XE000A008 0xFFFFFFFF 0xBFFF4000
mask_write 0XE000A248 0x003FFFFF 0x0000C000
mask_write 0XE000A008 0xFFFFFFFF 0xBFFF0000
mask_delay 0XF8F00200 1
mask_write 0XE000A008 0xFFFFFFFF 0xBFFF4000
}
proc ps7_post_config_2_0 {} {
mwr -force 0XF8000008 0x0000DF0D
mask_write 0XF8000900 0x0000000F 0x0000000F
mask_write 0XF8000240 0xFFFFFFFF 0x00000000
mwr -force 0XF8000004 0x0000767B
}
proc ps7_debug_2_0 {} {
mwr -force 0XF8898FB0 0xC5ACCE55
mwr -force 0XF8899FB0 0xC5ACCE55
mwr -force 0XF8809FB0 0xC5ACCE55
}
proc ps7_pll_init_data_1_0 {} {
mwr -force 0XF8000008 0x0000DF0D
mask_write 0XF8000110 0x003FFFF0 0x000FA220
mask_write 0XF8000100 0x0007F000 0x00028000
mask_write 0XF8000100 0x00000010 0x00000010
mask_write 0XF8000100 0x00000001 0x00000001
mask_write 0XF8000100 0x00000001 0x00000000
mask_poll 0XF800010C 0x00000001
mask_write 0XF8000100 0x00000010 0x00000000
mask_write 0XF8000120 0x1F003F30 0x1F000200
mask_write 0XF8000114 0x003FFFF0 0x0012C220
mask_write 0XF8000104 0x0007F000 0x00020000
mask_write 0XF8000104 0x00000010 0x00000010
mask_write 0XF8000104 0x00000001 0x00000001
mask_write 0XF8000104 0x00000001 0x00000000
mask_poll 0XF800010C 0x00000002
mask_write 0XF8000104 0x00000010 0x00000000
mask_write 0XF8000124 0xFFF00003 0x0C200003
mask_write 0XF8000118 0x003FFFF0 0x001452C0
mask_write 0XF8000108 0x0007F000 0x0001E000
mask_write 0XF8000108 0x00000010 0x00000010
mask_write 0XF8000108 0x00000001 0x00000001
mask_write 0XF8000108 0x00000001 0x00000000
mask_poll 0XF800010C 0x00000004
mask_write 0XF8000108 0x00000010 0x00000000
mwr -force 0XF8000004 0x0000767B
}
proc ps7_clock_init_data_1_0 {} {
mwr -force 0XF8000008 0x0000DF0D
mask_write 0XF8000128 0x03F03F01 0x00700F01
mask_write 0XF8000138 0x00000011 0x00000001
mask_write 0XF8000140 0x03F03F71 0x00500801
mask_write 0XF800014C 0x00003F31 0x00000501
mask_write 0XF8000150 0x00003F33 0x00001401
mask_write 0XF8000154 0x00003F33 0x00001402
mask_write 0XF8000168 0x00003F31 0x00000501
mask_write 0XF8000170 0x03F03F30 0x00400500
mask_write 0XF8000180 0x03F03F30 0x00100500
mask_write 0XF80001C4 0x00000001 0x00000001
mask_write 0XF800012C 0x01FFCCCD 0x01EC044D
mwr -force 0XF8000004 0x0000767B
}
proc ps7_ddr_init_data_1_0 {} {
mask_write 0XF8006000 0x0001FFFF 0x00000080
mask_write 0XF8006004 0x1FFFFFFF 0x00081082
mask_write 0XF8006008 0x03FFFFFF 0x03C0780F
mask_write 0XF800600C 0x03FFFFFF 0x02001001
mask_write 0XF8006010 0x03FFFFFF 0x00014001
mask_write 0XF8006014 0x001FFFFF 0x0004159B
mask_write 0XF8006018 0xF7FFFFFF 0x452444D3
mask_write 0XF800601C 0xFFFFFFFF 0x7282BCE5
mask_write 0XF8006020 0xFFFFFFFC 0x272872B0
mask_write 0XF8006024 0x0FFFFFFF 0x0000003C
mask_write 0XF8006028 0x00003FFF 0x00002007
mask_write 0XF800602C 0xFFFFFFFF 0x00000008
mask_write 0XF8006030 0xFFFFFFFF 0x00040B30
mask_write 0XF8006034 0x13FF3FFF 0x000116D4
mask_write 0XF8006038 0x00001FC3 0x00000000
mask_write 0XF800603C 0x000FFFFF 0x00000777
mask_write 0XF8006040 0xFFFFFFFF 0xFFF00000
mask_write 0XF8006044 0x0FFFFFFF 0x0F666666
mask_write 0XF8006048 0x3FFFFFFF 0x0003C248
mask_write 0XF8006050 0xFF0F8FFF 0x77010800
mask_write 0XF8006058 0x0001FFFF 0x00000101
mask_write 0XF800605C 0x0000FFFF 0x00005003
mask_write 0XF8006060 0x000017FF 0x0000003E
mask_write 0XF8006064 0x00021FE0 0x00020000
mask_write 0XF8006068 0x03FFFFFF 0x00284141
mask_write 0XF800606C 0x0000FFFF 0x00001610
mask_write 0XF80060A0 0x00FFFFFF 0x00008000
mask_write 0XF80060A4 0xFFFFFFFF 0x10200802
mask_write 0XF80060A8 0x0FFFFFFF 0x0690CB73
mask_write 0XF80060AC 0x000001FF 0x000001FE
mask_write 0XF80060B0 0x1FFFFFFF 0x1CFFFFFF
mask_write 0XF80060B4 0x000007FF 0x00000200
mask_write 0XF80060B8 0x01FFFFFF 0x00200066
mask_write 0XF80060C4 0x00000003 0x00000000
mask_write 0XF80060C8 0x000000FF 0x00000000
mask_write 0XF80060DC 0x00000001 0x00000000
mask_write 0XF80060F0 0x0000FFFF 0x00000000
mask_write 0XF80060F4 0x0000000F 0x00000008
mask_write 0XF8006114 0x000000FF 0x00000000
mask_write 0XF8006118 0x7FFFFFFF 0x40000001
mask_write 0XF800611C 0x7FFFFFFF 0x40000001
mask_write 0XF8006120 0x7FFFFFFF 0x40000001
mask_write 0XF8006124 0x7FFFFFFF 0x40000001
mask_write 0XF800612C 0x000FFFFF 0x0003B81E
mask_write 0XF8006130 0x000FFFFF 0x00043425
mask_write 0XF8006134 0x000FFFFF 0x0003CC19
mask_write 0XF8006138 0x000FFFFF 0x0004242A
mask_write 0XF8006140 0x000FFFFF 0x00000035
mask_write 0XF8006144 0x000FFFFF 0x00000035
mask_write 0XF8006148 0x000FFFFF 0x00000035
mask_write 0XF800614C 0x000FFFFF 0x00000035
mask_write 0XF8006154 0x000FFFFF 0x0000009E
mask_write 0XF8006158 0x000FFFFF 0x000000A5
mask_write 0XF800615C 0x000FFFFF 0x00000099
mask_write 0XF8006160 0x000FFFFF 0x000000AA
mask_write 0XF8006168 0x001FFFFF 0x00000143
mask_write 0XF800616C 0x001FFFFF 0x00000162
mask_write 0XF8006170 0x001FFFFF 0x00000148
mask_write 0XF8006174 0x001FFFFF 0x0000015E
mask_write 0XF800617C 0x000FFFFF 0x000000DE
mask_write 0XF8006180 0x000FFFFF 0x000000E5
mask_write 0XF8006184 0x000FFFFF 0x000000D9
mask_write 0XF8006188 0x000FFFFF 0x000000EA
mask_write 0XF8006190 0xFFFFFFFF 0x10040080
mask_write 0XF8006194 0x000FFFFF 0x0001FC82
mask_write 0XF8006204 0xFFFFFFFF 0x00000000
mask_write 0XF8006208 0x000F03FF 0x000803FF
mask_write 0XF800620C 0x000F03FF 0x000803FF
mask_write 0XF8006210 0x000F03FF 0x000803FF
mask_write 0XF8006214 0x000F03FF 0x000803FF
mask_write 0XF8006218 0x000F03FF 0x000003FF
mask_write 0XF800621C 0x000F03FF 0x000003FF
mask_write 0XF8006220 0x000F03FF 0x000003FF
mask_write 0XF8006224 0x000F03FF 0x000003FF
mask_write 0XF80062A8 0x00000FF7 0x00000000
mask_write 0XF80062AC 0xFFFFFFFF 0x00000000
mask_write 0XF80062B0 0x003FFFFF 0x00005125
mask_write 0XF80062B4 0x0003FFFF 0x000012A8
mask_poll 0XF8000B74 0x00002000
mask_write 0XF8006000 0x0001FFFF 0x00000081
mask_poll 0XF8006054 0x00000007
}
proc ps7_mio_init_data_1_0 {} {
mwr -force 0XF8000008 0x0000DF0D
mask_write 0XF8000B00 0x00000303 0x00000001
mask_write 0XF8000B40 0x00000FFF 0x00000600
mask_write 0XF8000B44 0x00000FFF 0x00000600
mask_write 0XF8000B48 0x00000FFF 0x00000672
mask_write 0XF8000B4C 0x00000FFF 0x00000672
mask_write 0XF8000B50 0x00000FFF 0x00000674
mask_write 0XF8000B54 0x00000FFF 0x00000674
mask_write 0XF8000B58 0x00000FFF 0x00000600
mask_write 0XF8000B5C 0xFFFFFFFF 0x0018C61C
mask_write 0XF8000B60 0xFFFFFFFF 0x00F9861C
mask_write 0XF8000B64 0xFFFFFFFF 0x00F9861C
mask_write 0XF8000B68 0xFFFFFFFF 0x00F9861C
mask_write 0XF8000B6C 0x000073FF 0x00000209
mask_write 0XF8000B70 0x00000021 0x00000021
mask_write 0XF8000B70 0x00000021 0x00000020
mask_write 0XF8000B70 0x07FFFFFF 0x00000823
mask_write 0XF8000700 0x00003FFF 0x00001202
mask_write 0XF8000704 0x00003FFF 0x00001202
mask_write 0XF8000708 0x00003FFF 0x00000202
mask_write 0XF800070C 0x00003FFF 0x00000202
mask_write 0XF8000710 0x00003FFF 0x00000202
mask_write 0XF8000714 0x00003FFF 0x00000202
mask_write 0XF8000718 0x00003FFF 0x00000202
mask_write 0XF800071C 0x00003FFF 0x00000200
mask_write 0XF8000720 0x00003FFF 0x00000202
mask_write 0XF8000724 0x00003FFF 0x00001202
mask_write 0XF8000728 0x00003FFF 0x00001202
mask_write 0XF800072C 0x00003FFF 0x00001202
mask_write 0XF8000730 0x00003FFF 0x00001202
mask_write 0XF8000734 0x00003FFF 0x00001202
mask_write 0XF8000738 0x00003F01 0x00001201
mask_write 0XF800073C 0x00003F01 0x00001201
mask_write 0XF8000740 0x00003FFF 0x00002802
mask_write 0XF8000744 0x00003FFF 0x00002802
mask_write 0XF8000748 0x00003FFF 0x00002802
mask_write 0XF800074C 0x00003FFF 0x00002802
mask_write 0XF8000750 0x00003FFF 0x00002802
mask_write 0XF8000754 0x00003FFF 0x00002802
mask_write 0XF8000758 0x00003FFF 0x00000803
mask_write 0XF800075C 0x00003FFF 0x00000803
mask_write 0XF8000760 0x00003FFF 0x00000803
mask_write 0XF8000764 0x00003FFF 0x00000803
mask_write 0XF8000768 0x00003FFF 0x00000803
mask_write 0XF800076C 0x00003FFF 0x00000803
mask_write 0XF8000770 0x00003FFF 0x00000204
mask_write 0XF8000774 0x00003FFF 0x00000205
mask_write 0XF8000778 0x00003FFF 0x00000204
mask_write 0XF800077C 0x00003FFF 0x00000205
mask_write 0XF8000780 0x00003FFF 0x00000204
mask_write 0XF8000784 0x00003FFF 0x00000204
mask_write 0XF8000788 0x00003FFF 0x00000204
mask_write 0XF800078C 0x00003FFF 0x00000204
mask_write 0XF8000790 0x00003FFF 0x00000205
mask_write 0XF8000794 0x00003FFF 0x00000204
mask_write 0XF8000798 0x00003FFF 0x00000204
mask_write 0XF800079C 0x00003FFF 0x00000204
mask_write 0XF80007A0 0x00003FFF 0x00000280
mask_write 0XF80007A4 0x00003FFF 0x00000280
mask_write 0XF80007A8 0x00003FFF 0x00000280
mask_write 0XF80007AC 0x00003FFF 0x00000280
mask_write 0XF80007B0 0x00003FFF 0x00000280
mask_write 0XF80007B4 0x00003FFF 0x00000280
mask_write 0XF80007B8 0x00003FFF 0x00001200
mask_write 0XF80007BC 0x00003FFF 0x00001200
mask_write 0XF80007C0 0x00003FFF 0x000002E0
mask_write 0XF80007C4 0x00003FFF 0x000002E1
mask_write 0XF80007C8 0x00003FFF 0x00001240
mask_write 0XF80007CC 0x00003FFF 0x00001240
mask_write 0XF80007D0 0x00003FFF 0x00000280
mask_write 0XF80007D4 0x00003FFF 0x00000280
mask_write 0XF8000830 0x003F003F 0x000E000F
mwr -force 0XF8000004 0x0000767B
}
proc ps7_peripherals_init_data_1_0 {} {
mwr -force 0XF8000008 0x0000DF0D
mask_write 0XF8000B48 0x00000180 0x00000180
mask_write 0XF8000B4C 0x00000180 0x00000180
mask_write 0XF8000B50 0x00000180 0x00000180
mask_write 0XF8000B54 0x00000180 0x00000180
mwr -force 0XF8000004 0x0000767B
mask_write 0XE0001034 0x000000FF 0x00000006
mask_write 0XE0001018 0x0000FFFF 0x0000003E
mask_write 0XE0001000 0x000001FF 0x00000017
mask_write 0XE0001004 0x00000FFF 0x00000020
mask_write 0XE000D000 0x00080000 0x00080000
mask_write 0XF8007000 0x20000000 0x00000000
mask_write 0XE000A204 0xFFFFFFFF 0x00000080
mask_write 0XE000A000 0xFFFFFFFF 0xFF7F0080
mask_write 0XE000A208 0xFFFFFFFF 0x00000080
mask_write 0XE000A000 0xFFFFFFFF 0xFF7F0000
mask_delay 0XF8F00200 1
mask_write 0XE000A000 0xFFFFFFFF 0xFF7F0080
mask_write 0XE000A244 0x003FFFFF 0x0000C000
mask_write 0XE000A008 0xFFFFFFFF 0x7FFF8000
mask_write 0XE000A248 0x003FFFFF 0x0000C000
mask_write 0XE000A008 0xFFFFFFFF 0x7FFF0000
mask_delay 0XF8F00200 1
mask_write 0XE000A008 0xFFFFFFFF 0x7FFF8000
mask_write 0XE000A244 0x003FFFFF 0x0000C000
mask_write 0XE000A008 0xFFFFFFFF 0xBFFF4000
mask_write 0XE000A248 0x003FFFFF 0x0000C000
mask_write 0XE000A008 0xFFFFFFFF 0xBFFF0000
mask_delay 0XF8F00200 1
mask_write 0XE000A008 0xFFFFFFFF 0xBFFF4000
}
proc ps7_post_config_1_0 {} {
mwr -force 0XF8000008 0x0000DF0D
mask_write 0XF8000900 0x0000000F 0x0000000F
mask_write 0XF8000240 0xFFFFFFFF 0x00000000
mwr -force 0XF8000004 0x0000767B
}
proc ps7_debug_1_0 {} {
mwr -force 0XF8898FB0 0xC5ACCE55
mwr -force 0XF8899FB0 0xC5ACCE55
mwr -force 0XF8809FB0 0xC5ACCE55
}
set PCW_SILICON_VER_1_0 "0x0"
set PCW_SILICON_VER_2_0 "0x1"
set PCW_SILICON_VER_3_0 "0x2"
set APU_FREQ 667000000
proc mask_poll { addr mask } {
set count 1
set curval "0x[string range [mrd $addr] end-8 end]"
set maskedval [expr {$curval & $mask}]
while { $maskedval == 0 } {
set curval "0x[string range [mrd $addr] end-8 end]"
set maskedval [expr {$curval & $mask}]
set count [ expr { $count + 1 } ]
if { $count == 100000000 } {
puts "Timeout Reached. Mask poll failed at ADDRESS: $addr MASK: $mask"
break
}
}
}
proc mask_delay { addr val } {
set delay [ get_number_of_cycles_for_delay $val ]
perf_reset_and_start_timer
set curval "0x[string range [mrd $addr] end-8 end]"
set maskedval [expr {$curval < $delay}]
while { $maskedval == 1 } {
set curval "0x[string range [mrd $addr] end-8 end]"
set maskedval [expr {$curval < $delay}]
}
perf_reset_clock
}
proc ps_version { } {
set si_ver "0x[string range [mrd 0xF8007080] end-8 end]"
set mask_sil_ver "0x[expr {$si_ver >> 28}]"
return $mask_sil_ver;
}
proc ps7_post_config {} {
set saved_mode [configparams force-mem-accesses]
configparams force-mem-accesses 1
variable PCW_SILICON_VER_1_0
variable PCW_SILICON_VER_2_0
variable PCW_SILICON_VER_3_0
set sil_ver [ps_version]
if { $sil_ver == $PCW_SILICON_VER_1_0} {
ps7_post_config_1_0
} elseif { $sil_ver == $PCW_SILICON_VER_2_0 } {
ps7_post_config_2_0
} else {
ps7_post_config_3_0
}
configparams force-mem-accesses $saved_mode
}
proc ps7_debug {} {
variable PCW_SILICON_VER_1_0
variable PCW_SILICON_VER_2_0
variable PCW_SILICON_VER_3_0
set sil_ver [ps_version]
if { $sil_ver == $PCW_SILICON_VER_1_0} {
ps7_debug_1_0
} elseif { $sil_ver == $PCW_SILICON_VER_2_0 } {
ps7_debug_2_0
} else {
ps7_debug_3_0
}
}
proc ps7_init {} {
variable PCW_SILICON_VER_1_0
variable PCW_SILICON_VER_2_0
variable PCW_SILICON_VER_3_0
set sil_ver [ps_version]
if { $sil_ver == $PCW_SILICON_VER_1_0} {
ps7_mio_init_data_1_0
ps7_pll_init_data_1_0
ps7_clock_init_data_1_0
ps7_ddr_init_data_1_0
ps7_peripherals_init_data_1_0
#puts "PCW Silicon Version : 1.0"
} elseif { $sil_ver == $PCW_SILICON_VER_2_0 } {
ps7_mio_init_data_2_0
ps7_pll_init_data_2_0
ps7_clock_init_data_2_0
ps7_ddr_init_data_2_0
ps7_peripherals_init_data_2_0
#puts "PCW Silicon Version : 2.0"
} else {
ps7_mio_init_data_3_0
ps7_pll_init_data_3_0
ps7_clock_init_data_3_0
ps7_ddr_init_data_3_0
ps7_peripherals_init_data_3_0
#puts "PCW Silicon Version : 3.0"
}
}
# For delay calculation using global timer
# start timer
proc perf_start_clock { } {
#writing SCU_GLOBAL_TIMER_CONTROL register
mask_write 0xF8F00208 0x00000109 0x00000009
}
# stop timer and reset timer count regs
proc perf_reset_clock { } {
perf_disable_clock
mask_write 0xF8F00200 0xFFFFFFFF 0x00000000
mask_write 0xF8F00204 0xFFFFFFFF 0x00000000
}
# Compute mask for given delay in miliseconds
proc get_number_of_cycles_for_delay { delay } {
# GTC is always clocked at 1/2 of the CPU frequency (CPU_3x2x)
variable APU_FREQ
return [ expr ($delay * $APU_FREQ /(2 * 1000))]
}
# stop timer
proc perf_disable_clock {} {
mask_write 0xF8F00208 0xFFFFFFFF 0x00000000
}
proc perf_reset_and_start_timer {} {
perf_reset_clock
perf_start_clock
}
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="ASCII"?>
<sdkproject:SdkProject xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sdkproject="http://www.xilinx.com/sdkproject" name="cx9261a_app" location="/home/josh/Workspace/vivado/vivado_pub/projects/cx9261a/zc706_cx9261a_demo/vitis_classic/cx9261a_app" platform="/home/josh/Workspace/vivado/vivado_pub/projects/cx9261a/zc706_cx9261a_demo/vitis_classic/cx9261a_platform/export/cx9261a_platform/cx9261a_platform.xpfm" platformUID="xilinx:zc706::0.0(custom)" systemProject="cx9261a_app_system" sysConfig="cx9261a_platform" runtime="C/C++" cpu="standalone_domain" cpuInstance="ps7_cortexa9_0" os="standalone" language="CPP" mssSignature="bc17e5d70c87e6a7f92b2333eecd1dbf">
<configuration name="Debug" id="xilinx.gnu.armv7.exe.debug.1979421842">
<configBuildOptions xsi:type="sdkproject:SdkOptions"/>
<lastBuildOptions xsi:type="sdkproject:SdkOptions"/>
</configuration>
<configuration name="Release" id="xilinx.gnu.armv7.exe.release.1480550519" dirty="true">
<configBuildOptions xsi:type="sdkproject:SdkOptions"/>
</configuration>
<template appTemplateName="empty_application"/>
</sdkproject:SdkProject>
@@ -0,0 +1 @@
Empty application. Add your own sources.
@@ -0,0 +1,2 @@
*startfile:
crti%O%s crtbegin%O%s
@@ -0,0 +1,228 @@
/*****************************************************************************/
/**
* Description: Global configurations.
*
* Date: 2021-04-28 13:19
* Last Editors: Fan Hao
* Last Edit Time: [2022-05-23 20:32]
*
* Revisions: Rev 0.0
* History:
* [2021-04-28]: Initial edition.
*
* Copyright(c) 2024 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#ifndef __APP_CONFIG_H_
#define __APP_CONFIG_H_
#define XILINX_PLATFORM
#include "xparameters.h"
/******** Software Version ********/
#define _APP_VER 0x00010000
#define _APP_VER_MAIN ((_APP_VER & 0xFF000000) >> 24)
#define _APP_VER_MINOR ((_APP_VER & 0x00FF0000) >> 16)
#define _APP_VER_PATCH (_APP_VER & 0x0000FFFF)
/*********** Debug Info Level ************/
// #define _DEBUG_LEVEL 1
// 3 - print all debug info
// 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)
#define FCLK_CLK0_HZ 100000000
/********* Zynq Platform Configs **********/
// SCU Timer (for logging)
#define SCUTIMER_DEVICE_ID XPAR_PS7_SCUTIMER_0_DEVICE_ID
#define SCUTIMER_INTR_ID XPAR_SCUTIMER_INTR
// Physical Layer Configs
#define PHY_DEVICE_ID (0x01 | 0x00)
#define PHY_BASEADDR XPAR_PHYC_BASEADDR
#define PHY_BEAM_FORMING_ENABLE
// -- Antenna Bram Configs
#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
// -- Interrupt id
#define PHY_INTR_ID XPAR_FABRIC_PHY_IRQ_INTR
#define PERIODIC_5MS_INTR_ID XPAR_FABRIC_PHY_5MS_DELAY_2MS_INTR
// Time Controller Configs
#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
// INTC configis
#define INTC_DEVICE_ID XPAR_SCUGIC_0_DEVICE_ID
// AD9361 Configuration
#define AD9361
#ifdef AD9361
#define AD9361_REG
//#define AD9361_API
#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 + 4)
#define AD9361_1_ENABLE (AD9361_GPIO_OFFSET + 5)
#define AD9361_1_EN_AGC (AD9361_GPIO_OFFSET + 6)
#define AD9361_1_RESET_B (AD9361_GPIO_OFFSET + 7)
#define AD9361_1_CTRL_OUT0 (AD9361_GPIO_OFFSET + 8)
#define AD9361_1_CTRL_OUT1 (AD9361_GPIO_OFFSET + 9)
#define AD9361_1_CTRL_OUT2 (AD9361_GPIO_OFFSET + 10)
#define AD9361_1_CTRL_OUT3 (AD9361_GPIO_OFFSET + 11)
#define AD9361_1_CTRL_OUT4 (AD9361_GPIO_OFFSET + 12)
#define AD9361_1_CTRL_OUT5 (AD9361_GPIO_OFFSET + 13)
#define AD9361_1_CTRL_OUT6 (AD9361_GPIO_OFFSET + 14)
#define AD9361_1_CTRL_OUT7 (AD9361_GPIO_OFFSET + 15)
#define AD9361_1_CTRL_IN0 (AD9361_GPIO_OFFSET + 16)
#define AD9361_1_CTRL_IN1 (AD9361_GPIO_OFFSET + 17)
#define AD9361_1_CTRL_IN2 (AD9361_GPIO_OFFSET + 18)
#define AD9361_1_CTRL_IN3 (AD9361_GPIO_OFFSET + 19)
// -- AD9361-2 GPIO
#define AD9361_2_TXNRX (AD9361_GPIO_OFFSET + 20)
#define AD9361_2_ENABLE (AD9361_GPIO_OFFSET + 21)
#define AD9361_2_EN_AGC (AD9361_GPIO_OFFSET + 22)
#define AD9361_2_RESET_B (AD9361_GPIO_OFFSET + 23)
#define AD9361_2_CTRL_OUT0 (AD9361_GPIO_OFFSET + 24)
#define AD9361_2_CTRL_OUT1 (AD9361_GPIO_OFFSET + 25)
#define AD9361_2_CTRL_OUT2 (AD9361_GPIO_OFFSET + 26)
#define AD9361_2_CTRL_OUT3 (AD9361_GPIO_OFFSET + 27)
#define AD9361_2_CTRL_OUT4 (AD9361_GPIO_OFFSET + 28)
#define AD9361_2_CTRL_OUT5 (AD9361_GPIO_OFFSET + 29)
#define AD9361_2_CTRL_OUT6 (AD9361_GPIO_OFFSET + 30)
#define AD9361_2_CTRL_OUT7 (AD9361_GPIO_OFFSET + 31)
#define AD9361_2_CTRL_IN0 (AD9361_GPIO_OFFSET + 32)
#define AD9361_2_CTRL_IN1 (AD9361_GPIO_OFFSET + 33)
#define AD9361_2_CTRL_IN2 (AD9361_GPIO_OFFSET + 34)
#define AD9361_2_CTRL_IN3 (AD9361_GPIO_OFFSET + 35)
typedef enum
{
TX_FREQ_125,
TX_FREQ_126,
TX_FREQ_4125
} ad9361TxFreq;
#endif
// HMC7044 Configurations
//#define HMC7044
#ifdef HMC7044
#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 0x00
#endif
// AD9528 Configurations
#define AD9528
#ifdef AD9528
#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
#endif
// AD9653 Configurations
#define AD9653
#ifdef AD9653
#define AD9653_GPIO_DEVICE_ID 0
#define AD9653_GPIO_OFFSET 54
#define AD9653_POWR_DOWN (AD9653_GPIO_OFFSET+0)
// -- AD9528 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
#endif
// Configuration Check
#if defined(PHY_BEAM_SET_PRESET) && !defined(PHY_BEAM_FORMING_ENABLE)
#define PHY_BEAM_FORMING_ENABLE
#warning To impliment beam scan must enable beam forming...
#endif
#if defined(DATALINK_ENABLE_BERTEST)
#if !defined(DATALINK_ENABLE_AUTOTIMESYNC)
#warning To enbale bit error rate test, auto time-sync should be enabled...
#endif
#endif
#endif //__APP_CONFIG_H_
@@ -0,0 +1,343 @@
#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"
#ifdef AD9361_API
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,
.chip_select = AD9361_1_SPI_CS,
.mode = SPI_MODE_1,
.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
};
#endif
@@ -0,0 +1,138 @@
#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"
#ifdef AD9528
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,
.chip_select = AD9528_SPI_CS,
.mode = SPI_MODE_0,
.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 */
.gpio_init_resetb = &ad9528_gpio_resetb_init,
.gpio_init_sysref_req = &ad9528_gpio_sysref_req_init,
.spi_init = &ad9528_spi_init,
.spiSettings = &clockSpiSettings,
.pll1Settings = &clockPll1Settings,
.pll2Settings = &clockPll2Settings,
.outputSettings = &clockOutputSettings,
.sysrefSettings = &clockSysrefSettings
};
#endif
@@ -0,0 +1,50 @@
#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"
#ifdef AD9653
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,
.chip_select = AD9653_SPI_CS,
.mode = SPI_MODE_4,
.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
};
#endif
@@ -0,0 +1,284 @@
#include "dev_profile.h"
#include "spi.h"
#include "../config/app_config.h"
#include "../drivers/rf-transceiver/cx9261a/cx9261a_driver.h"
#include "../drivers/axi_core/spi_engine/spi_engine.h"
#include "../drivers/platform/xilinx_gpio.h"
#include "common.h"
#include "xtime_l.h"
#undef max
CX9261A::Clock* ref_clock;
extern struct cx9261a_dev *cx9261a_inst;
void trx_ch_pll_config(uint8_t pll_index)
{
uint8_t rx_data;
uint8_t recv_buf[3]={0};
uint32_t trx_ch_pll_data;
if(pll_index==1){
trx_ch_pll_data = 0x00077DCF;
}else if(pll_index==2){
trx_ch_pll_data = 0x00077D0C;
}
// recv_buf[0] =(trx_ch_pll_data>>16 & 0xff)|0x80 ;
// recv_buf[1] = trx_ch_pll_data>>8 & 0xff;
// recv_buf[2] = trx_ch_pll_data & 0xff;
// SpiPs_write_read(recv_buf,&rx_data);
cx9261a_write(cx9261a_inst, trx_ch_pll_data>>16 & 0xff, trx_ch_pll_data & 0xff);
}
//void frqhop_config(int hop_flag,CX9261A::Clock& clock){
void frqhop_config(int hop_flag){
static XTime tCur;
XTime_GetTime(&tCur);
srand(tCur);
static double hop_freq ;
hop_freq = (rand()%(800-30))+30+(rand()%(101))/(double)100;//随机产生[30,800)double类型的数
// double hop_freq = 400.52;
static double hop_freq1 = 800.25;
static int pll_index=1;
static int unlock_pll1_cnt=0,unlock_pll2_cnt=0;
if(hop_freq == hop_freq1){
if(pll_index == 2){
pll_index = 4;
}
else if(pll_index == 1){
pll_index = 3;
}
}
if(hop_flag == 1){
if(pll_index == 1 || pll_index == 3){
//切换至pll2来源
trx_ch_pll_config(2);
//配置pll1参数
CX9261A::configPll1(hop_freq,*ref_clock);
// unlock_pll1_cnt=PLL_config(1,hop_freq,ref)-1;
while (!CX9261A::afcPll1()) {
unlock_pll1_cnt++;
}
pll_index = 2;
}
else if(pll_index == 2 || pll_index == 4){
//切换至pll1来源
trx_ch_pll_config(1);
//配置pll2参数
CX9261A::configPll2(hop_freq,*ref_clock);
// unlock_pll2_cnt=PLL_config(2,hop_freq,ref)-1;
while (!CX9261A::afcPll2()) {
unlock_pll2_cnt++;
}
pll_index = 1;
}
}
hop_freq1 = hop_freq;
if(unlock_pll2_cnt!=0 || unlock_pll1_cnt !=0){
// DBG_PRINT("pll1 unlock num: %d; pll2 unlock num: %d;.\n", unlock_pll1_cnt, unlock_pll2_cnt);
}
}
int cx9261a_config() {
/***********************配置参数定义*****************************/
// 芯片配置结构体
CX9261A::CX9261AConfiguration configuration;
// 电源管理 (与评估软件电源管理自定义电源里面勾选项相对应,先左再右,从上往下)
// 断电模式电源管理
configuration.powerManagement.shutdownPower = {
0, 0, 0, 0, 0, // digital trx
0, 0, 0, 0, 0, 0, 0, // aux
0, 0, 0, 0, 0, // analog trx
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // plls
};
// 接收模式电源管理
configuration.powerManagement.rxPower = {
0, 0, 0, 1, 1, // digital trx
1, 0, 0, 0, 0, 1, 0, // aux
0, 0, 0, 1, 1, // analog trx
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 // plls
};
// 发射模式电源管理
configuration.powerManagement.txPower = {
1, 1, 0, 0, 0, // digital trx
1, 0, 0, 0, 0, 1, 0, // aux
1, 1, 0, 0, 0, // analog trx
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 // plls
};
// FDD模式电源管理
configuration.powerManagement.fddPower = {
1, 1, 0, 1, 1, // digital trx
1, 0, 0, 0, 0, 1, 0, // aux
1, 1, 0, 1, 1, // analog trx
0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1 // plls
};
// 电源模式 即初始化配置结束后的电源模式
configuration.powerManagement.powerMode = CX9261A::PowerMode::Duplex;
// 接口模式
configuration.interface = {
.workMode = CX9261A::WorkMode::Tx,
.trMode = CX9261A::TrMode::R1T1,
.portMode = CX9261A::PortMode::Single,
.ioMode = CX9261A::IOMode::CMOS
};
// 时钟相关 (与评估软件参考配置和基带配置相对应)
configuration.clock = {
.ref = 200, .adc = 25.6, .refDiv = 2, .bbUseIntDiv = false, .refDoubler = false
};
// 本振相关
using LoSource = CX9261A::LoSource;
// 本振来源
configuration.pllSource = {
.rxUseExt = false,
.txUseExt = false,
.rx2Source = LoSource::Pll2,
.rx3Source = LoSource::Off,
.tx1Source = LoSource::Pll1,
.tx2Source = LoSource::Pll2
};
// 本振频率 注意:使用的所有PLL,频率必须设为正数
configuration.pllFreq = {
.pll1Freq = 200,
.pll2Freq = 500,
.pll3Freq = 800,
.pll4Freq = 900,
.pll5Freq = 1000
};
// Rx通道 注意:tia推荐配置为6 Mixer为三个通道共用同一个寄存器
configuration.rx1Config = {.bandwidth = 32, .tia = 6, .mixer = 31};
configuration.rx2Config = {.bandwidth = 32, .tia = 6, .mixer = 31};
configuration.rx3Config = {.bandwidth = 32, .tia = 6, .mixer = 31};
// Tx通道
configuration.tx1Config = {.bandwidth = 20, .mixer = 63};
configuration.tx2Config = {.bandwidth = 20, .mixer = 63};
// 接收滤波器
configuration.rxFilters = {.fir = 0, .hbf1 = 0, .hbf2 = 0, .hbf3 = 0, .cic = 0};
// 发射滤波器
configuration.txFilters = {.fir = 0, .hbf1 = 2, .hbf2 = 2, .hbf3 = 0, .cic = 0};
// Rx NCO
configuration.rxNco = {
.rxUseBist = false, .rxNCOBypass = true, .rxNCOUpward = true, .rxNCOMaster = true, .rxNCOFreq = 0};
// Tx NCO
configuration.txNco = {.txUseBist = true, .txNCOFreq = 1};
// AGC 注意:mode = 0表示关闭AGC,此时其他的参数可以不配置
configuration.agc = {.mode = 0};
configuration.agc.pdt = {.pdtN = 0,.pdtM = 2};
configuration.agc.lmt = {.count = 15,.threshold1 = 2,.threshold2 = 2,.threshold3 = 2,.threshold4 = 2};
configuration.agc.dig = {.count = 15,.threshold1 =-10,.threshold2 =-14,.threshold3 =-30,.threshold4 =-40};
// 校准
configuration.calib = {.calibRx1 = true,
.calibRx2 = true,
.calibRx3 = false,
.calibTx1 = true,
.calibTx2 = true,
.calibDC = true,
.dcCalibLength = 16384,
.f0 = 1.6};
ref_clock = &configuration.clock;
/***********************配置参数执行*****************************/
// 开始配置芯片
CX9261A::initialChip(); // 最开始需要调用此函数
CX9261A::initialPowerConfig(configuration);
using PowerMode = CX9261A::PowerMode;
// 不需要自定义电源管理时,这部分代码可以省略
CX9261A::configPowerPins(configuration.powerManagement.shutdownPower, PowerMode::Shutdown);
CX9261A::configPowerPins(configuration.powerManagement.rxPower, PowerMode::Receive);
CX9261A::configPowerPins(configuration.powerManagement.txPower, PowerMode::Transmit);
CX9261A::configPowerPins(configuration.powerManagement.fddPower, PowerMode::Duplex);
// 配置pll
CX9261A::configBBPLL(configuration);
CX9261A::configPllSource(configuration.pllSource);
CX9261A::configPll1(configuration.pllFreq.pll1Freq, configuration.clock);
CX9261A::configPll2(configuration.pllFreq.pll2Freq, configuration.clock);
// 配置Rx通道
CX9261A::configRxChannel(configuration.rx1Config, CX9261A::RxChannel::Rx1);
CX9261A::configRxChannel(configuration.rx2Config, CX9261A::RxChannel::Rx2);
CX9261A::configRxChannel(configuration.rx3Config, CX9261A::RxChannel::Rx3);
// 配置Tx通道
using TxChannel = CX9261A::TxChannel;
CX9261A::configTxChannelFrequency(configuration.pllFreq.pll1Freq, TxChannel::Tx1);
CX9261A::configTxChannelFrequency(configuration.pllFreq.pll2Freq, TxChannel::Tx2);
CX9261A::configTxChannel(configuration.tx1Config, TxChannel::Tx1);
CX9261A::configTxChannel(configuration.tx2Config, TxChannel::Tx2);
// 配置滤波器
CX9261A::configRxFilters(configuration.rxFilters);
CX9261A::configTxFilters(configuration.txFilters);
// 配置NCO
CX9261A::configRxNco(configuration.rxNco, configuration.clock.adc);
const int filters = std::max(configuration.rxFilters.fir, 1) * std::max(configuration.rxFilters.hbf3, 1) *
std::max(configuration.rxFilters.hbf2, 1) *
std::max(configuration.rxFilters.hbf1, 1) * std::max(configuration.rxFilters.cic, 1);
CX9261A::configTxNco(configuration.txNco, configuration.clock.adc / filters);
// 配置AGC
CX9261A::configAGC(configuration.agc);
// 切换到休眠模式
CX9261A::configPowerMode(PowerMode::Sleep);
CX9261A::pause(1000);
// 切换到校准模式
CX9261A::configPowerMode(PowerMode::Calib);
CX9261A::pause(100);
// // 锁定BBPLL
// while (!CX9261A::afcBBPll()) {
// }
// // 锁定PLL1 根据本振来源确定是否需要AFC
// while (!CX9261A::afcPll1()) {
// }
// // 锁定PLL2 根据本振来源确定是否需要AFC
// while (!CX9261A::afcPll2()) {
// }
// // 配置接口
// CX9261A::configInterface(configuration.interface);
// // 配置FPGA接口相关 此为示例,仅适用于Demo工程,用户应根据实际情况进行配置
// CX9261A::configFPGA(configuration.interface);
// // 配置校准
// CX9261A::configDcCalib(configuration.calib);
// CX9261A::configADCCalib(configuration.clock.adc);
// CX9261A::configFlashCalib();
// CX9261A::configQecCalib(configuration);
// // 切换到工作模式
// CX9261A::configPowerMode(configuration.powerManagement.powerMode);
//消除杂散信号
// CX9261A::writeSpi(0x75C, 0x83);
// CX9261A::writeSpi(0x766, 0x83);
/***********************多点校准*****************************/
/*
//跳频qec校准频点预设,最多256个频点。其中包含初始频点则加载初始频点校准值给三个通道
const std::vector<double> points = {200,300,400,500,600,700};
CX9261A::configRxMultiPointsQec(configuration, points);
CX9261A::setPin(43, 0);
CX9261A::setPin(43, 1);
// 加载第1组校准系数(300MHz)
configuration.pllFreq.pll1Freq = 300;
CX9261A::configPll1(configuration.pllFreq.pll1Freq, configuration.clock.ref);
CX9261A::afcPll1();
CX9261A::pause(10);
CX9261A::loadRxCalibPredis(1);
// 加载第2组校准系数(400MHz)
configuration.pllFreq.pll1Freq = 400;
CX9261A::configPll1(configuration.pllFreq.pll1Freq, configuration.clock.ref);
CX9261A::afcPll1();
CX9261A::pause(10);
CX9261A::loadRxCalibPredis(2);
// 加载第5组校准系数(700MHz)
configuration.pllFreq.pll1Freq = 700;
CX9261A::configPll1(configuration.pllFreq.pll1Freq, configuration.clock.ref);
CX9261A::afcPll1();
CX9261A::pause(10);
CX9261A::loadRxCalibPredis(5);
*/
/***********************PLL锁定和跳频测试*****************************/
// for(int i=0;i<20000;i++){
// PLL_scan(0);
// PLL_scan(1);
// }
// frqhop_flag(1);
// while(1);
return 0;
}
@@ -0,0 +1,42 @@
#ifndef _DEV_PROFILE_H_
#define _DEV_PROFILE_H_
#include "irq.h"
#include "error.h"
#include "../drivers/rf-transceiver/ad9361/ad9361_api.h"
#include "../drivers/rf-transceiver/ad9361_reg/ad9361_reg.h"
#include "../drivers/frequency/hmc7044/hmc7044.h"
#include "../drivers/frequency/ad9528/ad9528.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;
// HMC7044
extern struct hmc7044_init_param hmc7044_default_init_param;
// AD9528
extern ad9528Init_t ad9528_default_init_param;
// 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);
// CX9261A
int cx9261a_config();
// 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;
#endif /* SRC_DEV_PROFILE_H_ */
@@ -0,0 +1,11 @@
//#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,135 @@
#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"
#ifdef HMC7044
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,
.chip_select = HMC7044_SPI_CS,
.mode = SPI_MODE_4,
.platform_ops = &spi_eng_platform_ops,
.extra = &spi_engine_param
};
// hmc7044 channel specifications
struct hmc7044_chan_spec hmc7044_chan_spec[4] = {
/* AD9361_XTAL */
{
.num = 3,
.disable = 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,
.divider = 100,
.coarse_delay = 0,
.fine_delay = 0,
.driver_mode = HMC7044_CML,
.driver_impedance = INTERNAL_100OHM_PER_PIN,
.out_mux_mode = HMC7044_CHANNEL_DIV
},
/* FPGA_DAC_LOGIC_CLK */
{
.num = 4,
.disable = 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,
.divider = 10,
.coarse_delay = 0,
.fine_delay = 0,
.driver_mode = HMC7044_CML,
.driver_impedance = INTERNAL_100OHM_PER_PIN,
.out_mux_mode = HMC7044_CHANNEL_DIV
},
/* B_AD9361_XTAL */
{
.num = 12,
.disable = 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,
.divider = 100,
.coarse_delay = 0,
.fine_delay = 0,
.driver_mode = HMC7044_CML,
.driver_impedance = INTERNAL_100OHM_PER_PIN,
.out_mux_mode = HMC7044_CHANNEL_DIV
},
/* AD9361_RX_EXT_LO */
{
.num = 13,
.disable = 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,
.divider = 10,
.coarse_delay = 0,
.fine_delay = 0,
.driver_mode = HMC7044_CML,
.driver_impedance = INTERNAL_100OHM_PER_PIN,
.out_mux_mode = HMC7044_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,
.pll1_ref_prio_ctrl = 0xE4,
.high_performance_mode_clock_dist_en = false,
.sync_pin_mode = SYNC_MULTICHIP,
.pulse_gen_mode = PULSE_ONE,
.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,
.channels = hmc7044_chan_spec
};
#endif
@@ -0,0 +1,14 @@
//#include "dev_profile.h"
//#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
//};
//
//struct irq_init_param intc_init_param = {
// .irq_ctrl_id = INTC_DEVICE_ID,
// .platform_ops = &xil_irq_ops,
// .extra = &xil_intc_init_param
//};
@@ -0,0 +1,17 @@
#include "dev_profile.h"
#include "timer.h"
#include "../config/app_config.h"
#include "../drivers/platform/xilinx_timer.h"
struct xil_timer_init_param xil_scutimer_init_param = {
.active_tmr = 0,
.type = TIMER_PS
};
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
.platform_ops = &xil_timer_ops,
.extra = &xil_scutimer_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,229 @@
/***************************************************************************//**
* @file irq.c
* @brief Implementation of the IRQ Interface
* @author Andrei Porumb ([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 <inttypes.h>
#include <stdlib.h>
#include "irq.h"
#include "error.h"
/**
* @brief Initialize the IRQ interrupts.
* @param desc - The IRQ descriptor.
* @param param - The structure that contains the IRQ parameters.
* @return 0 in case of success, -1 otherwise.
*/
int32_t irq_ctrl_init(struct irq_ctrl_desc **desc,
const struct irq_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;
return 0;
}
/**
* @brief Free the resources allocated by irq_ctrl_init().
* @param desc - The SPI descriptor.
* @return 0 in case of success, -1 otherwise.
*/
int32_t irq_ctrl_remove(struct irq_ctrl_desc *desc)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->remove)
return -ENOSYS;
return desc->platform_ops->remove(desc);
}
/**
* @brief Register a callback to handle the irq events.
* @param desc - The IRQ controller descriptor.
* @param irq_id - Interrupt identifier.
* @param callback - Callback descriptor - platform specific type.
* @return SUCCESS in case of success, FAILURE otherwise.
*/
int32_t irq_register_callback(struct irq_ctrl_desc *desc,
uint32_t irq_id,
struct callback_desc *callback)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->register_callback)
return -ENOSYS;
return desc->platform_ops->register_callback(desc, irq_id, callback);
}
/**
* @brief Unregisters a generic IRQ handling function.
* @param desc - The IRQ controller descriptor.
* @param irq_id - Interrupt identifier.
* @param callback - Callback descriptor - platform specific type.
* @return SUCCESS in case of success, FAILURE otherwise.
*/
int32_t irq_unregister_callback(struct irq_ctrl_desc *desc,
uint32_t irq_id,
struct callback_desc *callback)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->unregister_callback)
return -ENOSYS;
return desc->platform_ops->unregister_callback(desc, irq_id, callback);
}
/**
* @brief Enable global interrupts.
* @return 0 in case of success, -1 otherwise.
*/
int32_t irq_global_enable(struct irq_ctrl_desc *desc)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->global_enable)
return -ENOSYS;
return desc->platform_ops->global_enable(desc);
}
/**
* @brief Disable global interrupts.
* @return 0 in case of success, -1 otherwise.
*/
int32_t irq_global_disable(struct irq_ctrl_desc *desc)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->global_disable)
return -ENOSYS;
return desc->platform_ops->global_disable(desc);
}
/**
* @brief Set interrupt trigger level.
* @param desc - The IRQ controller descriptor.
* @param irq_id - Interrupt identifier.
* @param trig - New trigger level for the interrupt.
* @return 0 in case of success, -1 otherwise.
*/
int32_t irq_trigger_level_set(struct irq_ctrl_desc *desc,
uint32_t irq_id,
enum irq_trig_level trig)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if(!desc->platform_ops->trigger_level_set)
return -ENOSYS;
return desc->platform_ops->trigger_level_set(desc, irq_id, trig);
}
/**
* @brief Enable specific interrupt.
* @param desc - The IRQ controller descriptor.
* @param irq_id - Interrupt identifier.
* @return 0 in case of success, -1 otherwise.
*/
int32_t irq_enable(struct irq_ctrl_desc *desc, uint32_t irq_id)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->enable)
return -ENOSYS;
return desc->platform_ops->enable(desc, irq_id);
}
/**
* @brief Disable specific interrupt.
* @param desc - The IRQ controller descriptor.
* @param irq_id - Interrupt identifier.
* @return 0 in case of success, -1 otherwise.
*/
int32_t irq_disable(struct irq_ctrl_desc *desc, uint32_t irq_id)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->disable)
return -ENOSYS;
return desc->platform_ops->disable(desc, irq_id);
}
/**
* @brief Set the priority for an interrupt.
* @param desc - The IRQ controller descriptor.
* @param irq_id - Interrupt identifier.
* @param priority_level - The priority level of the interrupt.
* @return 0 in case of success, negative errno error codes.
*/
int32_t irq_set_priority(struct irq_ctrl_desc *desc,
uint32_t irq_id,
uint32_t priority_level)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->set_priority)
return -ENOSYS;
return desc->platform_ops->set_priority(desc, irq_id, priority_level);
}
@@ -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,211 @@
/***************************************************************************//**
* @file timer.c
* @brief Implementation of the timer Interface
* @author RBolboac ([email protected])
********************************************************************************
* Copyright 2022(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 "error.h"
#include "timer.h"
/******************************************************************************/
/************************ Functions Definitions *******************************/
/******************************************************************************/
/**
* @brief Initialize hardware timer and the handler structure associated with
* it.
* @param [out] desc - Pointer to the reference of the device handler.
* @param [in] param - Initialization structure.
* @return 0 in case of success, negative error code otherwise
*/
int32_t timer_init(struct timer_desc **desc,
struct timer_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;
return 0;
}
/**
* @brief Free the memory allocated by timer_init().
* @param [in] desc - Pointer to the device handler.
* @return 0 in case of success, negative error code otherwise
*/
int32_t timer_remove(struct timer_desc *desc)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->remove)
return -ENOSYS;
return desc->platform_ops->remove(desc);
}
/**
* @brief Start a timer.
* @param [in] desc - Pointer to the device handler.
* @return 0 in case of success, negative error code otherwise
*/
int32_t timer_start(struct timer_desc *desc)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->start)
return -ENOSYS;
return desc->platform_ops->start(desc);
}
/**
* @brief Stop a timer from counting.
* @param [in] desc - Pointer to the device handler.
* @return 0 in case of success, negative error code otherwise
*/
int32_t timer_stop(struct timer_desc *desc)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->stop)
return -ENOSYS;
return desc->platform_ops->stop(desc);
}
/**
* @brief Get the value of the counter register for the timer.
* @param [in] desc - Pointer to the device handler.
* @param [out] counter - Pointer to the counter value.
* @return 0 in case of success, error code otherwise.
*/
int32_t timer_counter_get(struct timer_desc *desc,
uint32_t *counter)
{
if (!desc || !desc->platform_ops || !counter)
return -EINVAL;
if (!desc->platform_ops->counter_get)
return -ENOSYS;
return desc->platform_ops->counter_get(desc, counter);
}
/**
* @brief Set the timer counter register value.
* @param [in] desc - Pointer to the device handler.
* @param [in] new_val - The new value of the counter register.
* @return 0 in case of success, error code otherwise.
*/
int32_t timer_counter_set(struct timer_desc *desc, uint32_t new_val)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->counter_set)
return -ENOSYS;
return desc->platform_ops->counter_set(desc, new_val);
}
/**
* @brief Get the timer clock frequency.
* @param [in] desc - Pointer to the device handler.
* @param [out] freq_hz - The value in Hz of the timer clock.
* @return 0 in case of success, error code otherwise.
*/
int32_t timer_count_clk_get(struct timer_desc *desc,
uint32_t *freq_hz)
{
if (!desc || !desc->platform_ops || !freq_hz)
return -EINVAL;
if (!desc->platform_ops->count_clk_get)
return -ENOSYS;
return desc->platform_ops->count_clk_get(desc, freq_hz);
}
/**
* @brief Set the timer clock frequency.
* @param [in] desc - Pointer to the device handler.
* @param [in] freq_hz - The value in Hz of the new timer clock.
* @return 0 in case of success, error code otherwise.
*/
int32_t timer_count_clk_set(struct timer_desc *desc,
uint32_t freq_hz)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->count_clk_set)
return -ENOSYS;
return desc->platform_ops->count_clk_set(desc, freq_hz);
}
/**
* @brief Get the elapsed time in nsec for the timer.
* @param [in] desc - Pointer to the device handler.
* @param [in] elapsed_time - The elapsed time in nsec.
* @return 0 in case of success, error code otherwise.
*/
int32_t timer_get_elapsed_time_nsec(struct timer_desc *desc,
uint64_t *elapsed_time)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->get_elapsed_time_nsec)
return -ENOSYS;
return desc->platform_ops->get_elapsed_time_nsec(desc, elapsed_time);
}
@@ -0,0 +1,111 @@
/***************************************************************************//**
* @file trng.c
* @brief Implementation of the TRNG Interface
* @author Antoniu Miclaus ([email protected])
********************************************************************************
* Copyright 2023(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 "trng.h"
#include <stdlib.h>
#include "error.h"
/******************************************************************************/
/************************ Functions Definitions *******************************/
/******************************************************************************/
/**
* @brief Initialize the TRNG.
* @param desc - The TRNG descriptor.
* @param param - The structure that contains the TRNG parameters.
* @return 0 in case of success, -1 otherwise.
*/
int trng_init(struct trng_desc **desc,
const struct trng_init_param *param)
{
int 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;
return 0;
}
/**
* @brief Free the resources allocated by trng_init().
* @param desc - The TRNG descriptor.
* @return 0 in case of success, -1 otherwise.
*/
int trng_remove(struct trng_desc *desc)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->remove)
return -ENOSYS;
return desc->platform_ops->remove(desc);
}
/**
* @brief Fill buffer with rng data.
* @param desc - The TRNG descriptor.
* @param buff - Buffer to be filled
* @param len - Size of the buffer
* @return 0 in case of success, -1 otherwise.
*/
int trng_fill_buffer(struct trng_desc *desc, uint8_t *buff,
uint32_t len)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->fill_buffer)
return -ENOSYS;
return desc->platform_ops->fill_buffer(desc, buff, len);
}
@@ -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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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 (sergiu.cuciurean@analog.com)
********************************************************************************
* 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 (sergiu.cuciurean@analog.com)
********************************************************************************
* 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, &reg508);
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, &reg403);
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 (dragos.bogdan@analog.com)
********************************************************************************
* 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 (dragos.bogdan@analog.com)
********************************************************************************
* 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
{
HMC7044_CML = 0,
HMC7044_LVPECL = 1,
HMC7044_LVDS = 2,
HMC7044_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
{
HMC7044_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,79 @@
/***************************************************************************//**
* @file xilinx/xilinx_axi_io.c
* @brief Implementation of Xilinx AXI IO.
* @author Antoniu Miclaus (antoniu.miclaus@analog.com)
********************************************************************************
* 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 <xil_io.h>
#include "error.h"
#include "axi_io.h"
/******************************************************************************/
/************************ Functions Definitions *******************************/
/******************************************************************************/
/**
* @brief AXI IO Xilinx specific read function.
* @param base - Base address
* @param offset - Address offset
* @param data - variable where returned data is stored
* @return 0 in case of success, -1 otherwise.
*/
int32_t axi_io_read(uint32_t base, uint32_t offset, uint32_t *data)
{
*data = Xil_In32(base + offset);
return 0;
}
/**
* @brief AXI IO Xilinx specific write function.
* @param base - Base address
* @param offset - Address offset
* @param data - data to be written.
* @return 0 in case of success, -1 otherwise.
*/
int32_t axi_io_write(uint32_t base, uint32_t offset, uint32_t data)
{
Xil_Out32(base + offset, data);
return 0;
}
@@ -0,0 +1,100 @@
/***************************************************************************//**
* @file xilinx/xilinx_delay.c
* @brief Implementation of Xilinx Delay Functions.
* @author Antoniu Miclaus (antoniu.miclaus@analog.com)
********************************************************************************
* 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 (antoniu.miclaus@analog.com)
********************************************************************************
* 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 (sergiu.cuciurean@analog.com)
********************************************************************************
* 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 (andrei.porumb@analog.com)
********************************************************************************
* 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(&param->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(&param->my_Gpio, callback_desc->pin_nb);
XGpioPs_IntrClearPin(&param->my_Gpio, callback_desc->pin_nb);
callback_desc->callback.legacy_callback(callback_desc->callback.ctx, 0U, NULL);
if(callback_desc->enabled)
XGpioPs_IntrEnablePin(&param->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,
.register_callback = &xil_gpio_irq_register_callback,
.unregister_callback = xil_gpio_irq_unregister_callback,
.trigger_level_set = &xil_gpio_irq_trigger_level_set,
.enable = &xil_gpio_irq_enable,
.disable = &xil_gpio_irq_disable,
.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 (andrei.porumb@analog.com)
********************************************************************************
* 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 (antoniu.miclaus@analog.com)
********************************************************************************
* 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 (sergiu.cuciurean@analog.com)
********************************************************************************
* 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,433 @@
/***************************************************************************//**
* @file xilinx/xilinx_irq.c
* @brief Implementation of Xilinx IRQ Generic Driver.
* @author Cristian Pop (cristian.pop@analog.com)
********************************************************************************
* 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 <xparameters.h>
#include <stdlib.h>
#include "error.h"
#include "irq.h"
#include "xilinx_irq.h"
#ifdef XPAR_XSCUGIC_NUM_INSTANCES
#include <xscugic.h>
#endif
#ifdef XPAR_XINTC_NUM_INSTANCES
#include <xintc.h>
#endif
#ifdef XPAR_XTMRCTR_NUM_INSTANCES
#include <xtmrctr.h>
#endif
/******************************************************************************/
/************************ Functions Definitions *******************************/
/******************************************************************************/
/**
* @brief Initialize the IRQ interrupts.
* @param desc - The IRQ controller descriptor.
* @param param - The structure that contains the IRQ parameters.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_irq_ctrl_init(struct irq_ctrl_desc **desc,
const struct irq_init_param *param)
{
int32_t status;
struct irq_ctrl_desc *descriptor;
struct xil_irq_desc *xil_dev;
#ifdef XSCUGIC_H
void *config;
#endif
descriptor = (struct irq_ctrl_desc *)calloc(1, sizeof *descriptor);
if(!descriptor)
return -1;
xil_dev = (struct xil_irq_desc *)calloc(1, sizeof *xil_dev);
if(!xil_dev) {
free(descriptor);
return -1;
}
Xil_ExceptionInit();
descriptor->irq_ctrl_id = param->irq_ctrl_id;
descriptor->extra = xil_dev;
xil_dev->type = ((struct xil_irq_init_param *)param->extra)->type;
switch(xil_dev->type) {
case IRQ_PS:
#ifdef XSCUGIC_H
xil_dev->instance = calloc(1, sizeof(XScuGic));
if(!xil_dev->instance)
goto error;
config = XScuGic_LookupConfig(descriptor->irq_ctrl_id);
if(!config)
goto ps_error;
status = XScuGic_CfgInitialize(xil_dev->instance, config,
((XScuGic_Config *)config)->CpuBaseAddress);
if (status != 0)
goto ps_error;
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
xil_dev->instance);
break;
ps_error:
free(xil_dev->instance);
#endif
goto error;
case IRQ_PL:
#ifdef XINTC_H
xil_dev->instance = calloc(1, sizeof(XIntc));
if(!xil_dev->instance)
goto error;
status = XIntc_Initialize(xil_dev->instance, descriptor->irq_ctrl_id);
if(status != 0)
goto pl_error;
status = XIntc_Start(xil_dev->instance, XIN_REAL_MODE);
if(status != 0)
goto pl_error;
break;
pl_error:
free(xil_dev->instance);
#endif
goto error;
default:
goto error;
break;
}
*desc = descriptor;
return 0;
error:
free(xil_dev);
free(descriptor);
return -1;
}
/**
* @brief Enable global interrupts.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_irq_global_enable(struct irq_ctrl_desc *desc)
{
/* Enable interrupts */
Xil_ExceptionEnable();
return 0;
}
/**
* @brief Disable global interrupts.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_irq_global_disable(struct irq_ctrl_desc *desc)
{
/* Disable interrupts */
Xil_ExceptionDisable();
return 0;
}
/**
* @brief Enable specific interrupt.
* @param desc - The IRQ controller descriptor.
* @param irq_id - Interrupt identifier.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_irq_enable(struct irq_ctrl_desc *desc, uint32_t irq_id)
{
struct xil_irq_desc *xil_dev = desc->extra;
switch(xil_dev->type) {
case IRQ_PS:
#ifdef XSCUGIC_H
XScuGic_Enable(xil_dev->instance, irq_id);
#endif
break;
case IRQ_PL:
#ifdef XINTC_H
XIntc_Enable(xil_dev->instance, irq_id);
#endif
break;
default:
return -1;
}
return 0;
}
/**
* @brief Disable specific interrupt.
* @param desc - The IRQ controller descriptor.
* @param irq_id - Interrupt identifier.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_irq_disable(struct irq_ctrl_desc *desc, uint32_t irq_id)
{
struct xil_irq_desc *xil_dev = desc->extra;
switch(xil_dev->type) {
case IRQ_PS:
#ifdef XSCUGIC_H
XScuGic_Disable(xil_dev->instance, irq_id);
#endif
break;
case IRQ_PL:
#ifdef XINTC_H
XIntc_Disable(xil_dev->instance, irq_id);
#endif
break;
default:
return -1;
}
return 0;
}
/**
* @brief Register a callback to handle the irq events.
* @param desc - The IRQ controller descriptor.
* @param irq_id - Interrupt identifier.
* @param callback_desc - Callback descriptor
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_irq_register_callback(struct irq_ctrl_desc *desc,
uint32_t irq_id,
struct callback_desc *callback_desc)
{
struct xil_irq_desc *xil_dev = desc->extra;
switch(xil_dev->type) {
case IRQ_PS:
#ifdef XSCUGIC_H
return XScuGic_Connect(xil_dev->instance, irq_id,
(Xil_InterruptHandler) callback_desc->callback,
callback_desc->ctx);
#endif
break;
case IRQ_PL:
#ifdef XINTC_H
if (irq_id == XPAR_AXI_INTC_AXI_TIMER_INTERRUPT_INTR) {
int32_t ret;
ret = XIntc_Connect(xil_dev->instance, irq_id,
XTmrCtr_InterruptHandler, callback_desc->legacy_config);
if (IS_ERR_VALUE(ret))
return -1;
XTmrCtr_SetHandler(callback_desc->legacy_config,
(XTmrCtr_Handler)callback_desc->callback,
callback_desc->ctx);
return 0;
}
return XIntc_Connect(xil_dev->instance, irq_id,
(XInterruptHandler) callback_desc->callback,
callback_desc->ctx);
#endif
break;
default:
break;
}
return -1;
}
/**
* @brief Set interrupt trigger level.
* @param desc - The IRQ controller descriptor.
* @param irq_id - Interrupt identifier.
* @param trig - New trigger level for the interrupt.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_irq_trigger_level_set(struct irq_ctrl_desc *desc,
uint32_t irq_id,
enum irq_trig_level trig)
{
struct xil_irq_desc *xil_dev = desc->extra;
if(trig == IRQ_EDGE_BOTH)
return -EINVAL;
switch(xil_dev->type) {
case IRQ_PS:
#ifdef XSCUGIC_H
;
uint8_t priority, trigger;
XScuGic_GetPriorityTriggerType(xil_dev->instance, irq_id, &priority,
&trigger);
trigger = trig;
XScuGic_SetPriorityTriggerType(xil_dev->instance, irq_id, priority,
trigger);
return 0;
#endif
break;
case IRQ_PL:
#ifdef XINTC_H
/* Interrupt trigger determined in hardware. TODO: verify */
return 0;
#endif
break;
default:
break;
}
return -1;
}
/**
* @brief Set interrupt trigger level.
* @param desc - The IRQ controller descriptor.
* @param irq_id - Interrupt identifier.
* @param priority_level - New priority level for the interrupt.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_irq_set_priority(struct irq_ctrl_desc *desc,
uint32_t irq_id,
uint32_t priority_level)
{
struct xil_irq_desc *xil_dev = desc->extra;
if(priority_level % 8 != 0)
return -EINVAL;
switch(xil_dev->type) {
case IRQ_PS:
#ifdef XSCUGIC_H
;
uint8_t priority, trigger;
XScuGic_GetPriorityTriggerType(xil_dev->instance, irq_id, &priority,
&trigger);
priority = priority_level;
XScuGic_SetPriorityTriggerType(xil_dev->instance, irq_id, priority,
trigger);
return 0;
#endif
break;
case IRQ_PL:
#ifdef XINTC_H
/* Interrupt priority level determined in hardware. TODO: verify */
return 0;
#endif
break;
default:
break;
}
return -1;
}
/**
* @brief Unregisters a generic IRQ handling function.
* @param desc - The IRQ controller descriptor.
* @param irq_id - Interrupt identifier.
* @param cb - Callback descriptor.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_irq_unregister_callback(struct irq_ctrl_desc *desc,
uint32_t irq_id, struct callback_desc *cb)
{
struct xil_irq_desc *xil_dev = desc->extra;
switch(xil_dev->type) {
case IRQ_PS:
#ifdef XSCUGIC_H
XScuGic_Disconnect(xil_dev->instance, irq_id);
#endif
break;
case IRQ_PL:
#ifdef XINTC_H
XIntc_Disconnect(xil_dev->instance, irq_id);
#endif
break;
default:
return -1;
}
return 0;
}
/**
* @brief Free the resources allocated by irq_ctrl_init().
* @param desc - The IRQ control descriptor.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_irq_ctrl_remove(struct irq_ctrl_desc *desc)
{
struct xil_irq_desc *xil_dev = desc->extra;
free(xil_dev->instance);
free(desc->extra);
free(desc);
return 0;
}
/**
* @brief Xilinx platform specific IRQ platform ops structure
*/
const struct irq_platform_ops xil_irq_ops = {
.init = &xil_irq_ctrl_init,
.register_callback = &xil_irq_register_callback,
.unregister_callback = &xil_irq_unregister_callback,
.global_enable = &xil_irq_global_enable,
.global_disable = &xil_irq_global_disable,
.trigger_level_set = &xil_irq_trigger_level_set,
.enable = &xil_irq_enable,
.disable = &xil_irq_disable,
.set_priority = &xil_irq_set_priority,
.remove = &xil_irq_ctrl_remove
};
@@ -0,0 +1,91 @@
/*******************************************************************************
* @file xilinx_irq.h
* @brief Header containing types used in the irq driver.
* @author Cristian Pop (cristian.pop@analog.com)
********************************************************************************
* 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_IRQ_H_
#define XILINX_IRQ_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
#include "irq.h"
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
/**
* @enum xil_irq_type
* @brief Xilinx platform architecture sections
*/
enum xil_irq_type {
/** Programmable Logic */
IRQ_PL,
/** Processing System */
IRQ_PS
};
/**
* @struct xil_irq_init_param
* @brief Structure holding the initialization parameters for Xilinx platform
* specific IRQ parameters.
*/
struct xil_irq_init_param {
/** Xilinx architecture */
enum xil_irq_type type;
};
/**
* @struct xil_irq_desc
* @brief Xilinx platform specific IRQ descriptor
*/
struct xil_irq_desc {
/** Xilinx architecture */
enum xil_irq_type type;
/** Xilinx IRQ Instance */
void *instance;
};
/**
* @brief Xilinx specific IRQ platform ops structure
*/
extern const struct irq_platform_ops xil_irq_ops;
#endif
@@ -0,0 +1,462 @@
/***************************************************************************//**
* @file xilinx/xilinx_spi.c
* @brief Implementation of Xilinx SPI Generic Driver.
* @author Antoniu Miclaus (antoniu.miclaus@analog.com)
********************************************************************************
* 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 (sergiu.cuciurean@analog.com)
********************************************************************************
* 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 (mihail.chindris@analog.com)
********************************************************************************
* 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
@@ -0,0 +1,457 @@
/***************************************************************************//**
* @file xilinx/xilinx_timer.c
* @brief Timer and GIC control module source.
* @author Andrei Drimbarean (andrei.drimbarean@analog.com)
********************************************************************************
* 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 Files **********************************/
/******************************************************************************/
#include <stdlib.h>
#include <xparameters.h>
#include "timer.h"
#include "xilinx_timer.h"
#include "error.h"
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
#if defined(_XPARAMETERS_PS_H_)
#define CORE_PRIVATE_TIMER_CLOCK (XPAR_CPU_CORTEXA9_CORE_CLOCK_FREQ_HZ / 2)
#endif
/******************************************************************************/
/************************ Functions Definitions *******************************/
/******************************************************************************/
/**
* @brief Set the current counter value of the timer.
* @param [in] desc - Pointer to the device handler.
* @param [in] new_val - New value for the timer counter.
* @return 0 in case of success, -1 otherwise
*/
int32_t xilinx_timer_counter_set(struct timer_desc *desc,
uint32_t new_val)
{
struct xil_timer_desc *xdesc;
if (!desc)
return -1;
xdesc = desc->extra;
switch (xdesc->type) {
case TIMER_PS:
#ifdef XSCUTIMER_H
XScuTimer_LoadTimer((XScuTimer *)xdesc->instance, new_val - 1);
break;
#endif
return -1;
case TIMER_PL:
#ifdef XTMRCTR_H
XTmrCtr_SetResetValue(xdesc->instance, xdesc->active_tmr, new_val);
XTmrCtr_Reset(xdesc->instance, xdesc->active_tmr);
break;
#endif
return -1;
default:
return -1;
}
return 0;
}
/**
* @brief Set the timer clock frequency.
* @param [in] desc - Pointer to the device handler.
* @param [in] freq_hz - New timer frequency in hertz.
* @return 0 in case of success, -1 otherwise
*/
int32_t xilinx_timer_count_clk_set(struct timer_desc *desc,
uint32_t freq_hz)
{
struct xil_timer_desc *xdesc;
if (!desc || !freq_hz)
return -1;
xdesc = desc->extra;
switch (xdesc->type) {
case TIMER_PS:{
#ifdef XSCUTIMER_H
;
uint32_t prescaler = CORE_PRIVATE_TIMER_CLOCK / freq_hz;
if (prescaler == 0 || prescaler >= 256)
return -1;
XScuTimer_SetPrescaler(xdesc->instance, prescaler - 1);
desc->freq_hz = CORE_PRIVATE_TIMER_CLOCK / prescaler;
break;
#endif
return -1;
}
case TIMER_PL:
#ifdef XTMRCTR_H
(void *)xdesc;
/** Cannot be done. */
#endif
return -1;
default:
return -1;
}
return 0;
}
/**
* @brief Initialize hardware timer and the handler structure associated with
* it.
* @param [out] desc - Pointer to the reference of the device handler.
* @param [in] param - Initialization structure.
* @return 0 in case of success, -1 otherwise
*/
int32_t xilinx_timer_init(struct timer_desc **desc,
const struct timer_init_param *param)
{
int32_t ret;
struct timer_desc *dev;
struct xil_timer_desc *xdesc;
struct xil_timer_init_param *xinit;
if (!desc || !param)
return -1;
xinit = param->extra;
dev = (struct timer_desc *)calloc(1, sizeof(*dev));
if(!dev)
return -1;
xdesc = (struct xil_timer_desc *)calloc(1, sizeof(*xdesc));
if(!xdesc)
goto error_desc;
dev->id = param->id;
dev->freq_hz = param->freq_hz;
dev->ticks_count = param->ticks_count;
dev->extra = xdesc;
xdesc->active_tmr = xinit->active_tmr;
xdesc->type = xinit->type;
switch (xdesc->type) {
case TIMER_PS:
#ifdef XSCUTIMER_H
xdesc->config = XScuTimer_LookupConfig(dev->id);
xdesc->instance = calloc(1, sizeof(XScuTimer));
if (!xdesc->instance)
goto error_xdesc;
ret = XScuTimer_CfgInitialize(xdesc->instance, xdesc->config,
((XScuTimer_Config *)xdesc->config)->BaseAddr);
if (ret != XST_SUCCESS) {
free(xdesc->instance);
goto error_xdesc;
}
ret = xilinx_timer_count_clk_set(dev, param->freq_hz);
if (IS_ERR_VALUE(ret))
goto error_xdesc;
ret = xilinx_timer_counter_set(dev, dev->ticks_count);
if (IS_ERR_VALUE(ret))
goto error_xdesc;
XScuTimer_EnableAutoReload((XScuTimer *)xdesc->instance);
XScuTimer_EnableInterrupt((XScuTimer *)xdesc->instance);
break;
#endif
goto error_xdesc;
case TIMER_PL:
#ifdef XTMRCTR_H
xdesc->instance = (XTmrCtr *)calloc(1, sizeof(XTmrCtr));
if (!xdesc->instance)
return -1;
xdesc->config = XTmrCtr_LookupConfig(dev->id);
if (!xdesc->config) {
free(xdesc->instance);
goto error_desc;
}
XTmrCtr_CfgInitialize(xdesc->instance, xdesc->config,
((XTmrCtr_Config *)xdesc->config)->BaseAddress);
ret = XTmrCtr_InitHw(xdesc->instance);
if (ret != 0) {
free(xdesc->instance);
goto error_desc;
}
dev->freq_hz = ((XTmrCtr_Config *)xdesc->config)->SysClockFreqHz;
ret = XTmrCtr_SelfTest(xdesc->instance, dev->id);
if(ret != 0)
goto error_desc;
XTmrCtr_SetOptions(xdesc->instance, xdesc->active_tmr,
XTC_DOWN_COUNT_OPTION | XTC_INT_MODE_OPTION |
XTC_AUTO_RELOAD_OPTION);
XTmrCtr_SetResetValue(xdesc->instance, xdesc->active_tmr,
dev->ticks_count);
break;
#endif
goto error_xdesc;
default:
goto error_xdesc;
}
*desc = dev;
return 0;
error_xdesc:
free(xdesc);
error_desc:
free(dev);
return -1;
}
/**
* @brief Free the memory allocated by timer_setup().
* @param [in] desc - Pointer to the device handler.
* @return 0 in case of success, -1 otherwise
*/
int32_t xilinx_timer_remove(struct timer_desc *desc)
{
struct xil_timer_desc *xdesc;
if(!desc)
return -1;
xdesc = desc->extra;
switch (xdesc->type) {
case TIMER_PS:
#ifdef XSCUTIMER_H
XScuTimer_Stop(xdesc->instance);
free(xdesc->instance);
break;
#endif
return -1;
case TIMER_PL:
#ifdef XTMRCTR_H
XTmrCtr_Stop(xdesc->instance, xdesc->active_tmr);
break;
#endif
return -1;
default:
return -1;
}
free(xdesc);
free(desc);
return 0;
}
/**
* @brief Start a timer.
* @param [in] desc - Pointer to the device handler.
* @return 0 in case of success, -1 otherwise
*/
int32_t xilinx_timer_start(struct timer_desc *desc)
{
struct xil_timer_desc *xdesc;
if (!desc)
return -1;
xdesc = desc->extra;
switch (xdesc->type) {
case TIMER_PS:
#ifdef XSCUTIMER_H
XScuTimer_Start(xdesc->instance);
break;
#endif
return -1;
case TIMER_PL:
#ifdef XTMRCTR_H
XTmrCtr_Start(xdesc->instance, xdesc->active_tmr);
break;
#endif
return -1;
}
return 0;
}
/**
* @brief Stop a timer from counting.
* @param [in] desc - Pointer to the device handler.
* @return 0 in case of success, -1 otherwise
*/
int32_t xilinx_timer_stop(struct timer_desc *desc)
{
struct xil_timer_desc *xdesc;
if (!desc)
return -1;
xdesc = desc->extra;
switch (xdesc->type) {
case TIMER_PS:
#ifdef XSCUTIMER_H
XScuTimer_Stop(xdesc->instance);
break;
#endif
return -1;
case TIMER_PL:
#ifdef XTMRCTR_H
XTmrCtr_Stop(xdesc->instance, xdesc->active_tmr);
break;
#endif
return -1;
default:
return -1;
}
return 0;
}
/**
* @brief Get the current counter value of the timer.
* @param [in] desc - Pointer to the device handler.
* @param [out] counter - Pointer to the current counter value.
* @return 0 in case of success, -1 otherwise
*/
int32_t xilinx_timer_counter_get(struct timer_desc *desc,
uint32_t *counter)
{
struct xil_timer_desc *xdesc;
if (!desc || !counter)
return -1;
xdesc = desc->extra;
switch (xdesc->type) {
case TIMER_PS:
#ifdef XSCUTIMER_H
*counter = XScuTimer_GetCounterValue((XScuTimer *)xdesc->instance);
++(*counter);
break;
#endif
return -1;
case TIMER_PL:
#ifdef XTMRCTR_H
*counter = XTmrCtr_GetValue(xdesc->instance, xdesc->active_tmr);
break;
#endif
return -1;
default:
*counter = 0;
return -1;
}
return 0;
}
/**
* @brief Get the timer clock frequency.
* @param [in] desc - Pointer to the device handler.
* @param [out] freq_hz - Pointer to the returned frequency.
* @return 0 in case of success, -1 otherwise
*/
int32_t xilinx_timer_count_clk_get(struct timer_desc *desc,
uint32_t *freq_hz)
{
struct xil_timer_desc *xdesc;
if (!desc || !freq_hz)
return -1;
xdesc = desc->extra;
switch (xdesc->type) {
case TIMER_PS:
#ifdef XSCUTIMER_H
*freq_hz = desc->freq_hz;
break;
#endif
return -1;
case TIMER_PL:
#ifdef XTMRCTR_H
*freq_hz = ((XTmrCtr_Config *)xdesc->config)->SysClockFreqHz;
break;
#endif
return -1;
default:
*freq_hz = 0;
return -1;
}
return 0;
}
/**
* @brief Get the elapsed time in nsec for the timer.
* @param [in] desc - Pointer to the device handler.
* @param [in] elapsed_time - The elapsed time in nsec.
* @return -ENOSYS.
*/
int32_t xilinx_timer_get_elapsed_time_nsec(struct timer_desc *desc,
uint64_t *elapsed_time)
{
/* Function not implemented */
return -ENOSYS;
}
/**
* @brief Xilinx platform specific timer platform ops structure
*/
const struct timer_platform_ops xil_timer_ops = {
.init = &xilinx_timer_init,
.start = &xilinx_timer_start,
.stop = &xilinx_timer_stop,
.counter_get = &xilinx_timer_counter_get,
.counter_set = &xilinx_timer_counter_set,
.count_clk_get = &xilinx_timer_count_clk_get,
.count_clk_set = &xilinx_timer_count_clk_set,
.get_elapsed_time_nsec = &xilinx_timer_get_elapsed_time_nsec,
.remove = &xilinx_timer_remove
};
@@ -0,0 +1,101 @@
/***************************************************************************//**
* @file xilinx_timer.h
* @brief Timer control module header.
* @author Andrei Drimbarean (andrei.drimbarean@analog.com)
********************************************************************************
* 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.
*******************************************************************************/
#ifndef XILINX_TIMER_H_
#define XILINX_TIMER_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <xparameters.h>
#ifdef XPAR_XSCUTIMER_NUM_INSTANCES
#include <xscutimer.h>
#endif
#ifdef XPAR_XTMRCTR_NUM_INSTANCES
#include <xtmrctr.h>
#endif
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
/**
* @enum xil_timer_type
* @brief Xilinx platform architecture sections
*/
enum xil_timer_type {
/** Programmable Logic */
TIMER_PL,
/** Processing System */
TIMER_PS
};
/**
* @struct xil_timer_desc
* @brief Xilinx specific timer descriptor
*/
struct xil_timer_desc {
/** Pointer to the BSP driver handler */
void *instance;
/** Pointer to the BSP driver configuration handler */
void *config;
/** Timer used from the PL 3-timer core */
uint8_t active_tmr;
/** Platform selection parameter */
enum xil_timer_type type;
};
/**
* @struct xil_timer_init_param
* @brief Xilinx specific timer initialization structure
*/
struct xil_timer_init_param {
/** Timer used from the PL 3-timer core */
uint8_t active_tmr;
/** Platform selection parameter */
enum xil_timer_type type;
};
/**
* @brief Xilinx platform specific timer platform ops structure
*/
extern const struct timer_platform_ops xil_timer_ops;
#endif /* XILINX_TIMER_H_ */
@@ -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,70 @@
/***************************************************************************//**
* @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(__cplusplus)
#else
#if defined (__STDC__) && (__STDC_VERSION__ >= 199901L)
#include <stdbool.h>
#else
typedef enum { false, true } bool;
#endif
#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,102 @@
/***************************************************************************//**
* @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
@@ -0,0 +1,352 @@
/**
* @file defs.h
*/
#ifndef CX9261A_DEFS_H
#define CX9261A_DEFS_H
#include <bitset>
#include <map>
#include <vector>
namespace CX9261A {
/**
* @brief 芯片工作模式
*/
enum class WorkMode { Rx, Tx, FDD };
/**
* @brief 收发数据通道数量
* @note 此模式并不代表使用几个通道进行收发
*/
enum class TrMode { R1T1, R2T2 };
/**
* @brief 收发接口通道数量
*/
enum class PortMode { Single, Dual };
/**
* @brief 接口模式:
* CMOS CMOS接口模式,
* LVDS_S LVDS顺序模式,
* LVDS_E LVDS奇偶模式
*/
enum class IOMode { CMOS, LVDS_S, LVDS_E };
/**
* @brief 本振来源
*/
enum class LoSource { Pll1, Pll2, Pll3, Pll4, Pll5, Off };
/**
* @brief 接收通道
*/
enum class RxChannel { Rx1 = 1, Rx2, Rx3 };
/**
* @brief 发射通道
*/
enum class TxChannel { Tx1 = 1, Tx2 };
/**
* @brief 电源模式
*/
enum class PowerMode { Shutdown = 0, Sleep, Alert, Calib, Receive, Transmit, Duplex, Obs };
/**
* @brief NCO模式
*/
enum class NCOMode { Bypass = 0, Up, Down, BIST, Master, Slaver };
/**
* @brief AFC等待延时,单位ms
*/
constexpr double delay = 100;
constexpr double delay_afc = 0.020;
/**
* @brief QEC等待延时,单位ms
*/
constexpr double qecDelay = 100;
/**
* @brief 接收通道本振来源映射表
*/
static const std::map<std::pair<LoSource, LoSource>, std::bitset<7>> rxSrcMap = {
{ { LoSource::Pll2, LoSource::Pll2 }, 0b0010000 }, { { LoSource::Pll1, LoSource::Pll1 }, 0b1101000 },
{ { LoSource::Pll2, LoSource::Pll1 }, 0b0100000 }, { { LoSource::Pll1, LoSource::Pll2 }, 0b1000000 },
{ { LoSource::Off, LoSource::Pll1 }, 0b0101010 }, { { LoSource::Off, LoSource::Pll2 }, 0b1010010 },
{ { LoSource::Pll1, LoSource::Off }, 0b1001001 }, { { LoSource::Pll2, LoSource::Off }, 0b0110001 },
{ { LoSource::Off, LoSource::Off }, 0b0011011 }
};
/**
* @brief 发射通道本振来源映射表
*/
static const std::map<std::pair<LoSource, LoSource>, std::bitset<11>> txSrcMap = {
{ { LoSource::Pll4, LoSource::Pll4 }, 16 }, { { LoSource::Pll3, LoSource::Pll3 }, 104 },
{ { LoSource::Pll4, LoSource::Pll3 }, 32 }, { { LoSource::Pll3, LoSource::Pll4 }, 64 },
{ { LoSource::Pll2, LoSource::Pll2 }, 1560 }, { { LoSource::Pll1, LoSource::Pll1 }, 1944 },
{ { LoSource::Pll2, LoSource::Pll1 }, 1688 }, { { LoSource::Pll1, LoSource::Pll2 }, 1816 },
{ { LoSource::Off, LoSource::Pll3 }, 42 }, { { LoSource::Off, LoSource::Pll4 }, 82 },
{ { LoSource::Off, LoSource::Pll2 }, 794 }, { { LoSource::Off, LoSource::Pll1 }, 666 },
{ { LoSource::Pll3, LoSource::Off }, 73 }, { { LoSource::Pll4, LoSource::Off }, 49 },
{ { LoSource::Pll2, LoSource::Off }, 1177 }, { { LoSource::Pll1, LoSource::Off }, 1305 },
{ { LoSource::Off, LoSource::Off }, 27 }, { { LoSource::Pll1, LoSource::Pll3 }, 1320 },
{ { LoSource::Pll1, LoSource::Pll4 }, 1360 }, { { LoSource::Pll2, LoSource::Pll3 }, 1064 },
{ { LoSource::Pll2, LoSource::Pll4 }, 1104 }, { { LoSource::Pll3, LoSource::Pll1 }, 712 },
{ { LoSource::Pll4, LoSource::Pll1 }, 688 }, { { LoSource::Pll3, LoSource::Pll2 }, 584 },
{ { LoSource::Pll4, LoSource::Pll2 }, 560 }
};
/**
* @brief 环路参数选择表
*/
static const std::vector<std::vector<std::vector<int>>> coreTable = {
{ { 0x0C, 0x30, 0x08 }, { 0x0B, 0x30, 0x09 }, { 0x0C, 0x30, 0x05 }, { 0x0D, 0x30, 0x08 } },
{ { 0x0C, 0x30, 0x0C }, { 0x0B, 0x30, 0x0E }, { 0x0C, 0x30, 0x08 }, { 0x0D, 0x30, 0x0B } },
{ { 0x0C, 0x20, 0x10 }, { 0x0B, 0x20, 0x10 }, { 0x0C, 0x20, 0x0A }, { 0x0D, 0x20, 0x0D } },
{ { 0x0C, 0x20, 0x11 }, { 0x0B, 0x20, 0x13 }, { 0x0C, 0x20, 0x0C }, { 0x0D, 0x20, 0x0F } },
{ { 0x0D, 0x30, 0x14 }, { 0x0D, 0x22, 0x14 }, { 0x0D, 0x20, 0x0D }, { 0x0D, 0x15, 0x0C } },
{ { 0x0E, 0x30, 0x18 }, { 0x0E, 0x25, 0x16 }, { 0x0E, 0x25, 0x0F }, { 0x0E, 0x18, 0x0F } },
{ { 0x0F, 0x38, 0x1A }, { 0x0F, 0x32, 0x1C }, { 0x0F, 0x18, 0x12 }, { 0x0F, 0x18, 0x12 } }
};
/**
* @brief AGC PDT模式的结构体
*/
struct AGCPDT
{
int pdtN;
int pdtM;
};
/**
* @brief AGC LMT模式的结构体
*/
struct AGCLMT
{
int count; /**< LMT统计次数阈值*/
int threshold1; /**< LMT阈值第一档*/
int threshold2; /**< LMT阈值第二档*/
int threshold3; /**< LMT阈值第三档*/
int threshold4; /**< LMT阈值第四档*/
};
/**
* @brief AGC DIG模式的结构体
*/
struct AGCDIG
{
int count; /**< DIG统计次数阈值*/
int threshold1; /**< DIG阈值第一档*/
int threshold2; /**< DIG阈值第二档*/
int threshold3; /**< DIG阈值第三档*/
int threshold4; /**< DIG阈值第四档*/
};
/**
* @brief AGC模式的结构体
*/
struct AGC
{
int mode; /**< AGC模式选择*/
AGCPDT pdt; /**< AGC PDT模式的结构体*/
AGCLMT lmt; /**< AGC LMT模式的结构体*/
AGCDIG dig; /**< AGC DIG模式的结构体*/
};
/**
* @brief 时钟相关参数结构体
*/
struct Clock
{
double ref; /**< 参考时钟频率,单位MHz*/
double adc; /**< ADC频率,单位MHz*/
int refDiv; /**< 参考时钟分频比*/
bool bbUseIntDiv; /**< 是否使用整数分频模式*/
bool refDoubler; /**< 是否使用参考时钟倍频器*/
};
/**
* @brief 校准相关参数结构体
*/
struct Calib
{
bool calibRx1; /**< 是否校准Rx1*/
bool calibRx2; /**< 是否校准Rx2*/
bool calibRx3; /**< 是否校准Rx3*/
bool calibTx1; /**< 是否校准Tx1*/
bool calibTx2; /**< 是否校准Tx1*/
bool calibDC; /**< 是否开启DC Tracking*/
int dcCalibLength; /**< DC Tracking长度*/
double f0; /**< 校准音频率*/
};
/**
* @brief 配置PLL来源相关参数结构体
*/
struct PllSource
{
bool rxUseExt; /**< 接收通道是否使用外本振*/
bool txUseExt; /**< 发射通道是否使用外本振*/
LoSource rx1Source; /**< Rx1通道本振来源*/
LoSource rx2Source; /**< Rx2通道本振来源*/
LoSource rx3Source; /**< Rx3通道本振来源*/
LoSource tx1Source; /**< Tx1通道本振来源*/
LoSource tx2Source; /**< Tx2通道本振来源*/
};
/**
* @brief 配置PLL频率相关参数结构体
*/
struct PllFreq
{
double pll1Freq; /**< PLL1本振时钟,单位MHz*/
double pll2Freq; /**< PLL2本振时钟,单位MHz*/
double pll3Freq; /**< PLL3本振时钟,单位MHz*/
double pll4Freq; /**< PLL4本振时钟,单位MHz*/
double pll5Freq; /**< PLL5本振时钟,单位MHz*/
double rxExtFreq; /**< 接收通道使用外本振时,外本振频率,单位MHz*/
double txExtFreq; /**< 发射通道使用外本振时,外本振频率,单位MHz*/
};
/**
* @brief 配置接口相关参数结构体
*/
struct Interface
{
WorkMode workMode; /**< 芯片工作模式*/
TrMode trMode; /**< 收发数据通道模式*/
PortMode portMode; /**< 收发接口通道模式*/
IOMode ioMode; /**< 接口电平模式*/
};
/**
* @brief 配置TX NCO相关参数结构体
*/
struct TxNCO
{
bool txUseBist; /**< 是否开启BIST模式*/
double txNCOFreq; /**< NCO频率*/
};
/**
* @brief 配置RX NCO相关参数结构体
*/
struct RxNCO
{
bool rxUseBist; /**< 是否开启BIST模式*/
bool rxNCOBypass; /**< 是否Bypass NCO*/
bool rxNCOUpward; /**< 开启上/下混频模式*/
bool rxNCOMaster; /**< 使用Master/Slaver模式*/
double rxNCOFreq; /**< NCO频率*/
};
/**
* @brief 配置接收通道相关参数结构体
*/
struct RxConfig
{
double bandwidth; /**< 接收通道1dB带宽,单位MHz*/
int tia; /**< 接收通道TIA增益配置,推荐配置6*/
int mixer; /**< 接收通道Mixer增益配置*/
};
/**
* @brief 配置发射通道相关参数结构体
*/
struct TxConfig
{
double bandwidth; /**< 发射通道1dB带宽,单位MHz*/
int mixer; /**< 发射通道Mixer增益配置*/
};
/**
* @brief 配置滤波器相关参数结构体,0代表bypass
*/
struct Filters
{
int fir; /**< FIR滤波器抽取/插值倍数*/
int hbf1; /**< HBF1滤波器抽取/插值倍数*/
int hbf2; /**< HBF2滤波器抽取/插值倍数*/
int hbf3; /**< HBF3滤波器抽取/插值倍数*/
int cic; /**< CIC滤波器抽取/插值倍数*/
};
/**
* @brief 配置电源模式结构体,1代表该模块上电
*/
struct Power
{
bool dig_tx2;
bool dig_tx1;
bool dig_rx3;
bool dig_rx2;
bool dig_rx1;
bool fref1_rx;
bool auxadc2;
bool auxadc1;
bool auxdac;
bool temp_sensor;
bool bgr;
bool exlo;
bool tx2;
bool tx1;
bool rx3;
bool rx2;
bool rx1;
bool pll5_ldo;
bool pll5;
bool pll4_ldo;
bool pll4;
bool pll3_ldo;
bool pll3;
bool pll2_ldo;
bool pll2;
bool pll1_ldo;
bool pll1;
bool bbpll;
};
/**
* @brief 配置电源模式管理,包含模式选择,断电模式,接收模式,发射模式,FDD模式
*/
struct PowerManagement
{
PowerMode powerMode;
Power shutdownPower;
Power rxPower;
Power txPower;
Power fddPower;
};
/**
* @brief 储存窄带校准结果的结构体
*/
struct CalibPredis {
int bHigh;
int bLow;
int cHigh;
int cLow;
int dciHigh;
int dciLow;
int dcqHigh;
int dcqLow;
};
/**
* @brief CX9261A结构体
*/
struct CX9261AConfiguration
{
AGC agc; /**< AGC结构体*/
Interface interface; /**< Interface结构体*/
Clock clock; /**< Clock结构体*/
PllSource pllSource; /**< PllSource结构体*/
Calib calib; /**< Calib结构体*/
PllFreq pllFreq; /**< PllFreq结构体*/
TxNCO txNco; /**< TxNCO结构体*/
RxNCO rxNco; /**< RxNCO结构体*/
RxConfig rx1Config; /**< RxConfig结构体*/
RxConfig rx2Config; /**< RxConfig结构体*/
RxConfig rx3Config; /**< RxConfig结构体*/
TxConfig tx1Config; /**< TxConfig结构体*/
TxConfig tx2Config; /**< TxConfig结构体*/
Filters rxFilters; /**< Filters结构体*/
Filters txFilters; /**< Filters结构体*/
PowerManagement powerManagement; /**< PowerManagement结构体*/
std::vector<double> rxFIRCoe; /**< Rx FIR滤波器系数*/
std::vector<double> txFIRCoe; /**< Tx FIR滤波器系数*/
};
} // namespace CX9261A
#endif // CX9261ADRIVER_DEFS_H
@@ -0,0 +1,505 @@
/**
* @file cx9261adriver.h
*/
#ifndef CX9261A_DRIVER_H
#define CX9261A_DRIVER_H
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
#include "delay.h"
#include "spi.h"
#include "gpio.h"
#include "cx9261a_defs.h"
#include "cx9261a_utils.h"
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
struct cx9261a_dev {
/* SPI */
struct spi_desc *spi_desc;
struct gpio_desc *gpio_desc_nrst;
struct gpio_desc *gpio_desc_txnrx_trx1;
struct gpio_desc *gpio_desc_txnrx_trx2;
struct gpio_desc *gpio_desc_txnrx_rxfb;
struct gpio_desc *gpio_desc_enable_trx1;
struct gpio_desc *gpio_desc_enable_trx2;
struct gpio_desc *gpio_desc_enable_rxfb;
struct gpio_desc *gpio_desc_pl_rst;
struct gpio_desc *gpio_desc_tr_sel;
struct gpio_desc *gpio_desc_tdd_fdd_sel;
struct gpio_desc *gpio_desc_r1t1_r2t2_sel;
struct gpio_desc *gpio_desc_sp_dp_sel;
};
struct cx9261a_init_param {
/* SPI */
struct spi_init_param *spi_init;
struct gpio_init_param *gpio_nrst;
struct gpio_init_param *gpio_txnrx_trx1;
struct gpio_init_param *gpio_txnrx_trx2;
struct gpio_init_param *gpio_txnrx_rxfb;
struct gpio_init_param *gpio_enable_trx1;
struct gpio_init_param *gpio_enable_trx2;
struct gpio_init_param *gpio_enable_rxfb;
struct gpio_init_param *gpio_pl_rst;
struct gpio_init_param *gpio_tr_sel;
struct gpio_init_param *gpio_tdd_fdd_sel;
struct gpio_init_param *gpio_r1t1_r2t2_sel;
struct gpio_init_param *gpio_sp_dp_sel;
};
int32_t cx9261a_read(struct cx9261a_dev *dev,
uint16_t reg_addr,
uint8_t *reg_data);
int32_t cx9261a_write(struct cx9261a_dev *dev,
uint16_t reg_addr,
uint8_t reg_data);
int32_t cx9261a_reset(struct cx9261a_dev *dev);
namespace CX9261A {
/**
* @brief 需要实现的函数,实现SPI写入寄存器功能
* @param address 要写入的寄存器地址
* @param value 要写入的寄存器值
*/
void writeSpi(int address, int value);
/**
* @brief 需要实现的函数,实现SPI读取寄存器功能
* @param address 要读取的寄存器地址
* @return 返回的寄存器值
*/
int readSpi(int address);
/**
* @brief 需要实现的函数,实现等待功能
* @param ms 等待时间,单位毫秒
*/
void pause(double ms);
/**
* @brief 需要实现的函数,实现配置FPGA对应寄存器功能
* @param pin 寄存器地址
* @param value 寄存器值
*/
void setPin(int pin, int value);
/**
* @brief 初始化电源配置,如果只自定义配置部分模式下的电源管理,在自定义配置之前需要先调用此函数
*/
void initialPowerConfig(const CX9261AConfiguration& config);
/**
* @brief 初始化芯片状态,写入与具体配置无关的寄存器值
*/
void initialChip();
/**
* @brief 初始化BBPLL相关寄存器,如果调用了initialChip,则无需单独调用此函数
*/
void initialBBPLL();
/**
* @brief 初始化PLL1相关寄存器,如果调用了initialChip,则无需单独调用此函数
*/
void initialPLL1();
/**
* @brief 初始化PLL2相关寄存器,如果调用了initialChip,则无需单独调用此函数
*/
void initialPLL2();
/**
* @brief 初始化PLL3相关寄存器,如果调用了initialChip,则无需单独调用此函数
*/
void initialPLL3();
/**
* @brief 初始化PLL4相关寄存器,如果调用了initialChip,则无需单独调用此函数
*/
void initialPLL4();
/**
* @brief 初始化PLL5相关寄存器,如果调用了initialChip,则无需单独调用此函数
*/
void initialPLL5();
/**
* @brief 配置AGC模式
* @param mode 模式0~13
*/
void configAGCMode(int mode);
/**
* @brief 配置AGC PDT
* @param pdt AGCPDT结构体
*/
void configAGCPDT(const AGCPDT& pdt);
/**
* @brief 配置AGC LMT
* @param lmt AGCLMT结构体
*/
void configAGCLMT(const AGCLMT& lmt);
/**
* @brief 配置AGC DIG
* @param dig AGCDIG结构体
*/
void configAGCDIG(const AGCDIG& dig);
/**
* @brief 配置AGC
* @param agc AGC结构体
*/
void configAGC(const AGC& agc);
/**
* @brief 配置时钟相关寄存器,包括ADC和BBPLL
* @param config CX9261A参数结构体
*/
void configBBPLL(const CX9261AConfiguration& config);
/**
* @brief BBPLL AFC
* @return 是否锁定
*/
bool afcBBPll();
/**
* @brief 配置PLL1频率
* @param lo 目标频率
* @param clock 时钟结构体,使用其中的ref和refDoubler属性
*/
void configPll1(double lo, const Clock& clock);
/**
* @brief Pll1 AFC
* @return 是否锁定
*/
bool afcPll1();
/**
* @brief 配置PLL2频率
* @param lo 目标频率
* @param clock 时钟结构体,使用其中的ref和refDoubler属性
*/
void configPll2(double lo, const Clock& clock);
/**
* @brief Pll2 AFC
* @return 是否锁定
*/
bool afcPll2();
/**
* @brief 配置PLL3频率
* @param lo 目标频率
* @param clock 时钟结构体,使用其中的ref和refDoubler属性
*/
void configPll3(double lo, const Clock& clock);
/**
* @brief Pll3 AFC
* @return 是否锁定
*/
bool afcPll3();
/**
* @brief 配置PLL4频率
* @param lo 目标频率
* @param clock 时钟结构体,使用其中的ref和refDoubler属性
*/
void configPll4(double lo, const Clock& clock);
/**
* @brief Pll4 AFC
* @return 是否锁定
*/
bool afcPll4();
/**
* @brief 配置PLL5频率
* @param lo 目标频率
* @param clock 时钟结构体,使用其中的ref和refDoubler属性
*/
void configPll5(double lo, const Clock& clock);
/**
* @brief Pll5 AFC
* @return 是否锁定
*/
bool afcPll5();
/**
* @brief ADC校准
* @param adc ADC速率
*/
void configADCCalib(double adc);
/**
* @brief Flash校准
*/
void configFlashCalib();
/**
* @brief 配置片内处理器,仅在使用需要处理器辅助的校准方法时需要开启处理器
* @param on 开启/关闭
*/
void configRISCV(bool on);
/**
* @brief QEC校准会改变部分寄存器配置,在进行校准之前需要保存这部分寄存器,校准后恢复
* @return 包含寄存器地址和值的map
*/
std::map<int, int> beforeQecState();
/**
* @brief 恢复QEC校准过程中改变的寄存器
* @param state beforeQecState函数返回的map
*/
void restoreQecState(const std::map<int, int>& state);
/**
* @brief Rx窄带多点校准
* @param config CX9261A配置结构体
* @param points 校准点
*/
void configRxMultiPointsQec(const CX9261AConfiguration& config, const std::vector<double>& points);
/**
* @brief Qec校准顶层函数,内部根据配置选择使用RX TST窄带方法对接收通道校准,使用二分法对发射通道校准
* @param config CX9261A配置结构体
*/
void configQecCalib(const CX9261AConfiguration& config);
/**
* @brief Rx TST窄带校准
* @param config CX9261A配置结构体
* @param chan 要进行校准的通道
*/
void rxTSTCalib(const CX9261AConfiguration& config, RxChannel chan);
/**
* @brief 等待RxTST窄带校准结束,可重写
* @return 校准是否结束
*/
bool waitRxTSTFinished();
/**
* @brief Tx通道校准
* @param config CX9261A配置结构体
*/
void txCalib(const CX9261AConfiguration& config);
/**
* @brief TX二分法QEC校准
* @param f0 校准音频率
* @param fs adc频率
*/
void txBisectionQecCalib(double f0, double fs);
/**
* @brief TX二分法DC校准
* @param f0 校准音频率
* @param fs adc频率
*/
void txBisectionDcCalib(double f0, double fs);
/**
* @brief DC Tracking
* @param config CX9261A配置结构体
*/
void configDcCalib(const Calib& config);
/**
* @brief 配置TX NCO相关寄存器
* @param nco TX NCO配置结构体
* @param fs adc速率
*/
void configTxNco(const TxNCO& nco, double fs);
/**
* @brief 配置TX NCO BIST模式
* @param bist 开启/关闭BIST
*/
void configTxBIST(bool bist);
/**
* @brief 配置TX NCO频率
* @param freq 混频频率
* @param fs adc抽取后速率
*/
void configTxNcoFreq(double freq, double fs);
/**
* @brief 配置RX NCO相关寄存器
* @param nco RX NCO配置结构体
* @param fs adc速率
*/
void configRxNco(const RxNCO& nco, double fs);
/**
* @brief 配置Rx NCO模式
* @param mode NCO模式:Bypass/BIST/Up/Down
*/
void configRxNcoMode(NCOMode mode);
/**
* @brief 配置Rx NCO模式
* @param mode NCO模式:Master/Slaver
*/
void configRxNcoMS(NCOMode mode);
/**
* @brief 配置Rx NCO频率
* @param freq 混频频率
* @param fs adc速率
*/
void configRxNcoFreq(double freq, double fs);
/**
* @brief 配置接口相关寄存器
* @param interface Interface配置结构体
*/
void configInterface(const Interface& interface);
/**
* @brief 配置PLL来源
* @param pllSource PLlSource结构体
*/
void configPllSource(const PllSource& pllSource);
/**
* @brief 切换电源模式
* @param pm 电源模式
*/
void configPowerMode(PowerMode pm);
/**
* @brief 配置电源管理
* @param power 电源配置结构体
* @param pm 电源模式
*/
void configPowerPins(const Power& power, PowerMode pm);
/**
* @brief 配置参考倍频器
* @param doubler 倍频器开关
* @param ref 参考时钟频率,单位MHz
*/
void configRefDoubler(bool doubler, double ref);
/**
* @brief 初始化通道,调用initialChip函数会初始化RX1,RX2,RX3三个通道
* @param chan 通道 RX1/RX2/RX3
*/
void initialRxChannel(RxChannel chan);
/**
* @brief 配置Rx带宽
* @note 只改变Rx带宽会导致通道增益改变,建议使用configRxChannel函数进行带宽调整
* @param bandwidth 带宽,单位(MHz)
* @param chan 通道 Rx1/Rx2/Rx3
*/
void configRxBandwidth(double bandwidth, RxChannel chan);
/**
* @brief 配置Rx TIA
* @note 只改变TIA会导致通道带宽改变,建议使用configRxChannel函数进行TIA调整
* @param tia tia档位
* @param chan 通道 Rx1/Rx2/Rx3
*/
void configRxTIA(int tia, RxChannel chan);
/**
* @brief 配置Rx Mixer
* @param mixer mixer档位
*/
void configRxMixer(int mixer);
/**
* @brief 配置Rx通道,包含TIA,Mixer以及Bandwidth
* @param config RxConfig结构体
* @param chan Rx1/Rx2/Rx3
*/
void configRxChannel(const RxConfig& config, RxChannel chan);
/**
* @brief 配置Rx FIR滤波器抽取倍数
* @param fir 抽取倍数 0(Bypass)/1/2/3/4/8
*/
void configRxFIR(int fir);
/**
* @brief 配置Rx FIR滤波器系数
* @param coe 滤波器系数,长度为16的整倍数,最大128
*/
void configRxFIRCoe(const std::vector<double>& coe);
/**
* @brief 配置Rx HBF1滤波器抽取倍数
* @param hbf 抽取倍数 0(Bypass)/2
*/
void configRxHBF1(int hbf);
/**
* @brief 配置Rx HBF2滤波器抽取倍数
* @param hbf 抽取倍数 0(Bypass)/2
*/
void configRxHBF2(int hbf);
/**
* @brief 配置Rx HBF3滤波器抽取倍数
* @param hbf 抽取倍数 0(Bypass)/2/3
*/
void configRxHBF3(int hbf);
/**
* @brief 配置Rx CIC滤波器
* @param cic 抽取倍数 0(Bypass)/20
*/
void configRxCIC(int cic);
/**
* @brief 配置Rx滤波器
* @param filters Filters结构体
*/
void configRxFilters(const Filters& filters);
/**
* @brief 配置Tx带宽
* @param bandwidth 带宽,单位(MHz)
* @param chan 通道 TX1/TX2
*/
void configTxBandwidth(double bandwidth, TxChannel chan);
/**
* @brief 配置Tx Mixer
* @param mixer 混频器值
* @param chan TX1/TX2
*/
void configTxMixer(int mixer, TxChannel chan);
/**
* @brief 初始化Tx通道
* @param chan 通道 TX1/TX2
*/
void initialTxChannel(TxChannel chan);
/**
* @brief 根据Tx通道的本振频率,配置对应的参数
* @param lo 本振频率,单位(MHz)
* @param chan 通道(Tx1/Tx2)
*/
void configTxChannelFrequency(double lo, TxChannel chan);
/**
* @brief 配置Tx通道,Mixer以及Bandwidth
* @param config TxConfig结构体
* @param chan Tx1/Tx2
*/
void configTxChannel(const TxConfig& config, TxChannel chan);
/**
* @brief 配置Tx FIR滤波器插值倍数
* @param fir 插值倍数 0(Bypass)/1/2/3/4/8
*/
void configTxFIR(int fir);
/**
* @brief 配置Tx FIR滤波器系数
* @param coe 滤波器系数,长度为16的整倍数,最大128
*/
void configTxFIRCoe(const std::vector<double>& coe);
/**
* @brief 配置Tx HBF1滤波器插值倍数
* @param hbf 插值倍数 0(Bypass)/2
*/
void configTxHBF1(int hbf);
/**
* @brief 配置Tx HBF2滤波器插值倍数
* @param hbf 插值倍数 0(Bypass)/2
*/
void configTxHBF2(int hbf);
/**
* @brief 配置Tx HBF3滤波器插值倍数
* @param hbf 插值倍数 0(Bypass)/2/3
*/
void configTxHBF3(int hbf);
/**
* @brief 配置Tx CIC滤波器
* @param cic 插值倍数 0(Bypass)/8/20/32/80
*/
void configTxCIC(int cic);
/**
* @brief 配置Tx滤波器
* @param filters Filters结构体
*/
void configTxFilters(const Filters& filters);
/**
* @brief 读取当前Rx chan通道的校准值
* @param chan Rx通道
* @return Rx校准值结构体
*/
CalibPredis readRxCalibPredis(RxChannel chan);
/**
* @brief 储存校准值
* @param index 第index组校准值
* @param chan 接收通道
* @param predis 校准值
*/
void saveRxCalibPredis(unsigned char index, RxChannel chan, const CalibPredis& predis);
/**
* @brief 加载保存的校准值
* @param index 第index组校准值
*/
void loadRxCalibPredis(unsigned char index);
/**
* @brief 此函数为Demo板配套配置函数,用于配置FPGA接口,用户开发自己的程序时应重写对应功能
* @param interface Interface结构体
*/
void configFPGA(const Interface& interface);
} // namespace CX9261A
#endif // CX9261ADRIVER_CX9261ADRIVER_H
@@ -0,0 +1,99 @@
/**
* @file utils.h
*/
#ifndef CX9261ADRIVER_UTILS_H
#define CX9261ADRIVER_UTILS_H
#include <algorithm>
#include <bitset>
#include <cmath>
#include <string>
namespace CX9261A {
#if __cplusplus >= 201703L
template <typename T>
constexpr const T& clamp(const T& v, const T& lo, const T& hi) {
return std::clamp(v, lo, hi);
}
#else
template <typename T>
constexpr const T& clamp(const T& v, const T& lo, const T& hi) {
return std::max(std::min(hi, v), lo);
}
#endif
template <typename Float>
int round(Float f) {
return static_cast<int>(std::round(f));
}
template <typename Float>
long long round64(Float f) {
return static_cast<long long>(std::round(f));
}
template <typename Float>
int floor(Float f) {
return static_cast<int>(std::floor(f));
}
template <typename Float>
long long floor64(Float f) {
return static_cast<long long>(std::floor(f));
}
template <typename Float>
int ceil(Float f) {
return static_cast<int>(std::ceil(f));
}
template <typename Float>
long long ceil64(Float f) {
return static_cast<long long>(std::ceil(f));
}
/**
* @brief Register类,提供方便的位操作函数
*/
class Register {
public:
template <typename T = int>
constexpr Register(const T value = 0) {
// static_assert(std::is_integral_v<T>, "Register value must be integral!");
m_value = static_cast<unsigned long long>(value);
}
/**
* 以十进制返回寄存器值
*/
unsigned char value() const { return static_cast<unsigned char>(m_value.to_ulong()); }
/**
* 对寄存器值进行部分值的替换操作
* 例:replace(7, 4, 0b1111); 使寄存器的高四位为1
* @param start 起始位
* @param end 中止位
* @param after 要替换的值
*/
void replace(const unsigned int start, const unsigned int end, unsigned char after) {
for (auto i = end; i <= start; ++i) {
m_value[i] = (after >> (i - end)) & 0b1;
}
}
auto operator[](const size_t position) { return m_value[position]; }
template <typename Type>
operator Type() const {
// static_assert(std::is_integral_v<Type>, "Type must be an integral");
return static_cast<Type>(m_value.to_ulong());
}
private:
std::bitset<8> m_value{};
};
template <int N>
std::string frac2bin(const double frac) {
const long double num = frac * (pow(2.0, N));
std::string ret = std::bitset<N>(std::floor(num)).to_string();
return ret;
}
} // namespace CX9261A
#endif // CX9261ADRIVER_UTILS_H
@@ -0,0 +1,222 @@
/*****************************************************************************/
/**
* Description: hwconfig.h
*
* Date: 2024-02-20 13:19
* Last Edit Time: [2024-02-20 13:19]
*
* Revisions: Rev 0.0
* History:
* [2023-05-07]: Initial edition.
*
* Copyright(c) 2024 Beijing Institute of Technology.
*
******************************************************************************/
/***************************** Include Files *********************************/
// Standard
#include <stdint.h>
#include <stdbool.h>
// Xilinx
#include "xgpiops.h"
#include "drivers/rf-transceiver/ad9361_reg/ad9361_reg.h"
#include "drivers/rf-transceiver/ad9361/ad9361_api.h"
#include "drivers/axi_core/spi_engine/spi_engine.h"
// App
#include "common.h"
#include "error.h"
#include "delay.h"
#include "system_monitor.h"
#include "hwconfig.h"
#include "config/app_config.h"
#include "dev_profile/dev_profile.h"
/************************** Function Prototypes ******************************/
/*********************** Driver Instance Definitions **************************/
ad9528Device_t *ad9528_inst;
static struct ad9361_reg_dev *ad9361_1_reg_inst;
static struct ad9361_reg_dev *ad9361_2_reg_inst;
static struct ad9653_dev *ad9653_inst;
struct cx9261a_dev *cx9261a_inst;
// static struct ad9361_rf_phy *ad9361_phy;
// static struct ad9361_rf_phy *ad9361_2_phy;
/*****************************************************************************/
/**
* @brief Hardware_Init
*
* @param none.
*
* @return None.
*
******************************************************************************/
int32_t Hardware_Init(void)
{
int32_t Status;
XGpioPs Gpio;
XGpioPs_Config *ConfigPtr;
ConfigPtr = XGpioPs_LookupConfig(AD9528_GPIO_DEVICE_ID);
Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
if (Status != SUCCESS)
{
return FAILURE;
}
/**********************************************************/
/****************** AD9528 Configuration ******************/
/**********************************************************/
Status = AD9528_init(&ad9528_inst, &ad9528_default_init_param);
if (Status != SUCCESS) {
DBG_ERROR("AD9528_init() error: %" PRId32 "\n", Status);
return FAILURE;
}
Status = AD9528_config(ad9528_inst);
if (Status != SUCCESS) {
return FAILURE;
DBG_ERROR("AD9528_config() error: %" PRId32 "\n", Status);
}
/**********************************************************/
/***************** AD9361-1 Configuration *****************/
/**********************************************************/
XGpioPs_SetDirectionPin(&Gpio, AD9361_1_TXNRX, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_1_ENABLE, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_1_EN_AGC, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_1_RESET_B, AD9361_GPIO_OUTPUT);
ad9361_reg_init(&ad9361_1_reg_inst, &ad9361_1_reg_default_init_param);
XGpioPs_WritePin(&Gpio, AD9361_1_ENABLE, 0);
ad9361_1_reg_config(ad9361_1_reg_inst);
XGpioPs_WritePin(&Gpio, AD9361_1_ENABLE, 1);
// Status = ad9361_init(&ad9361_phy, &ad9361_default_init_param);
// if (Status != XST_SUCCESS){
// return XST_FAILURE;
// }else{
// printf("Configurate AD9361 Completely!\n");
// }
// ad9361_set_tx_fir_config(ad9361_phy, tx_fir_config);
// ad9361_set_rx_fir_config(ad9361_phy, rx_fir_config);
/**********************************************************/
/***************** AD9361-2 Configuration *****************/
/**********************************************************/
XGpioPs_SetDirectionPin(&Gpio, AD9361_2_TXNRX, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_2_ENABLE, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_2_EN_AGC, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_2_RESET_B, AD9361_GPIO_OUTPUT);
ad9361_reg_init(&ad9361_2_reg_inst, &ad9361_2_reg_default_init_param);
XGpioPs_WritePin(&Gpio, AD9361_2_ENABLE, 0);
ad9361_2_reg_config(ad9361_2_reg_inst);
XGpioPs_WritePin(&Gpio, AD9361_2_ENABLE, 1);
// uint8_t rd_back;
// Status = ad9361_reg_read(ad9361_1_reg_inst, 0x0002, &rd_back);
// Status = ad9361_reg_read(ad9361_2_reg_inst, 0x0002, &rd_back);
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0109, 0x00); // Rx Gain
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x010C, 0x00); // Rx Gain
Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0109, 0x00); // Rx Gain
Status = ad9361_reg_write(ad9361_2_reg_inst, 0x010C, 0x00); // Rx Gain
// Status = ad9361_reg_write(ad9361_1_reg_inst, 0x03F5, 0x01); // BIST Data Port Loop
// Status = ad9361_reg_write(ad9361_2_reg_inst, 0x03F5, 0x01); // BIST Data Port Loop
/**********************************************************/
/****************** AD9653 Configuration ******************/
/**********************************************************/
Status = ad9653_init(&ad9653_inst, &ad9653_default_init_param);
for(int i = 0; i < ad9653_default_config_len; i++){
Status = ad9653_write(ad9653_inst, ad9653_default_config[i].addr,
ad9653_default_config[i].value);
if (ad9653_default_config[i].addr == 0x0000){
mdelay(500);
}
}
DBG_PRINT("Done.\n");
return SUCCESS;
}
// @ Get AD9361 - 1 temperature (Celsius Degree)
/**
* Read corresponding register to get AD9361 - 1 current temperature.
*/
int8_t Hardware_GetAD9361Temp_1(void)
{
int8_t scaleTemp;
double temp;
ad9361_reg_write(ad9361_1_reg_inst, 0x000B, -64);
ad9361_reg_write(ad9361_1_reg_inst, 0x001D, 0x01); // disable aux adc
ad9361_reg_read(ad9361_1_reg_inst, 0x000E, (uint8_t*)&scaleTemp);
ad9361_reg_write(ad9361_1_reg_inst, 0x001D, 0x00); // enable aux adc
temp = ((double)scaleTemp + 64)/1.16;
return ((temp > INT8_MAX) ? INT8_MAX : (int8_t)temp);
}
// @ Get AD9361 - 2 temperature (Celsius Degree)
/**
* Read corresponding register to get AD9361 - 2 current temperature.
*/
int8_t Hardware_GetAD9361Temp_2(void)
{
int8_t scaleTemp;
double temp;
ad9361_reg_write(ad9361_2_reg_inst, 0x000B, -64);
ad9361_reg_write(ad9361_2_reg_inst, 0x001D, 0x01); // disable aux adc
ad9361_reg_read(ad9361_2_reg_inst, 0x000E, (uint8_t*)&scaleTemp);
ad9361_reg_write(ad9361_2_reg_inst, 0x001D, 0x00); // enable aux adc
temp = ((double)scaleTemp + 64)/1.16;
return ((temp > INT8_MAX) ? INT8_MAX : (int8_t)temp);
}
// @ Determine AD9361 lock state
/**
* Read corresponding register to determine AD9361(both) lock state.
*/
uint8_t Hardware_GetAD9361LockStatus(void)
{
uint8_t ret = 0;
uint8_t regVal;
// bbpll
ad9361_reg_read(ad9361_1_reg_inst, 0x005E, &regVal); // [D7] is lock indicator
ret |= ((regVal & 0x80) == 0x80) ? CLK_AD0_BBPLL_LOCK : 0;
ad9361_reg_read(ad9361_2_reg_inst, 0x005E, &regVal); // [D7] is lock indicator
ret |= ((regVal & 0x80) == 0x80) ? CLK_AD1_BBPLL_LOCK : 0;
// rfpll
ad9361_reg_read(ad9361_1_reg_inst, 0x0287, &regVal); // [D1] is lock indicator
ret |= ((regVal & 0x02) == 0x02) ? CLK_AD0_RFPLL_LOCK : 0;
ad9361_reg_read(ad9361_2_reg_inst, 0x0287, &regVal); // [D1] is lock indicator
ret |= ((regVal & 0x02) == 0x02) ? CLK_AD1_RFPLL_LOCK : 0;
return ret;
}
// @ Determine AD9528 lock state
/**
* Read corresponding register to determine clock lock state.
*/
uint8_t Hardware_GetAD9528LockStatus(void)
{
uint8_t ret = 0;
uint8_t regVal;
// pll1
AD9528_spiReadByte(ad9528_inst, AD9528_ADDR_STATUS_READBACK0, &regVal); // [D0] is lock indicator
ret |= ((regVal & 0x01) == 0x01) ? CLK_SP_PLL1_LOCK : 0;
// pll2
AD9528_spiReadByte(ad9528_inst, AD9528_ADDR_STATUS_READBACK0, &regVal); // [D1] is lock indicator
ret |= ((regVal & 0x02) == 0x02) ? CLK_SP_PLL2_LOCK : 0;
return ret;
}
@@ -0,0 +1,32 @@
/*****************************************************************************/
/**
* Description: hwconfig.h
*
* Date: 2024-02-20 13:19
* Last Edit Time: [2024-02-20 13:19]
*
* Revisions: Rev 0.0
* History:
* [2023-05-07]: Initial edition.
*
* Copyright(c) 2024 Beijing Institute of Technology.
*
******************************************************************************/
/***************************** Include Files *********************************/
// Standard
#include <stdint.h>
#include "config/app_config.h"
#include "drivers/rf-transceiver/ad9361_reg/ad9361_reg.h"
#include "drivers/rf-transceiver/ad9361/ad9361_api.h"
/************************** Function Prototypes ******************************/
int32_t Hardware_Init(void);
int32_t Hardware_SwitchFreq(struct ad9361_reg_dev *dev, ad9361TxFreq freq);
int8_t Hardware_GetAD9361Temp_1(void);
int8_t Hardware_GetAD9361Temp_2(void);
uint8_t Hardware_GetAD9361LockStatus(void);
uint8_t Hardware_GetAD9528LockStatus(void);
@@ -0,0 +1,59 @@
/***************************************************************************//**
* @file axi_io.h
* @brief Header file of AXI IO.
* @author Antoniu Miclaus (antoniu.miclaus@analog.com)
********************************************************************************
* 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 _AXI_IO_H_
#define _AXI_IO_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
/* AXI IO Read data */
int32_t axi_io_read(uint32_t base, uint32_t offset, uint32_t *data);
/* AXI IO Write data */
int32_t axi_io_write(uint32_t base, uint32_t offset, uint32_t data);
#endif // _AXI_IO_H_
@@ -0,0 +1,100 @@
/*****************************************************************************/
/**
* @file circ_queue.h
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief A simple circular FIFO bounded queue
* @version 0.1
* @date 2023-02-23
* @note Forked from https://github.com/chrismerck/rpa_queue.git
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup Utility
* @{
*/
/**
* @defgroup CircularQueue
* @{
*/
#ifndef CIRC_QUEUE_H
#define CIRC_QUEUE_H
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
/**
* @struct CIRC_QUEUE
* @brief Circular queue Instance
*/
typedef struct
{
void **data;
volatile uint32_t nelts; ///< number of elements
uint32_t in; ///< next empty location
uint32_t out; ///< next filled location
uint32_t bounds; ///< max size of queue
} CIRC_QUEUE;
/**
* @brief create a FIFO queue
* @param queue The new queue
* @param queue_capacity maximum size of the queue
*/
bool CircQueueCreate(CIRC_QUEUE **queue, uint32_t queue_capacity);
/**
* @brief free queue memory -- call after destroy
*/
void CircQueueFree(CIRC_QUEUE *queue);
/**
* @brief Detects when the CIRC_QUEUE is full. This utility function is expected
* to be called from within critical sections, and is not threadsafe.
*/
bool isCircQueueFull(CIRC_QUEUE *queue);
/**
* @brief Detects when the CIRC_QUEUE is empty. This utility function is expected
* to be called from within critical sections, and is not threadsafe.
*/
bool isCircQueueEmpty(CIRC_QUEUE *queue);
/**
* @brief push/add an object to the queue, blocking if the queue is already full
*
* @param queue the queue
* @param data the data
* @return True on a successful push
* @return False push failed
*/
bool CircQueuePush(CIRC_QUEUE *queue, void *data);
/**
* @brief pop/get an object from the queue, blocking if the queue is already empty
*
* @param queue the queue
* @param data the data
* @return false pop failed
* @return true on a successful pop
*/
bool CircQueuePop(CIRC_QUEUE *queue, void **data);
/**
* @brief returns the size of the queue.
*
* @param queue the queue
* @return the size of the queue
*/
uint32_t CircQueueSize(CIRC_QUEUE *queue);
#endif /* CIRC_QUEUE_H */
/** @} CircularQueue*/
/** @} Utility*/
@@ -0,0 +1,138 @@
/*****************************************************************************/
/**
* @file clist.h
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief A basic list data structure
* @version 0.1
* @date 2023-02-23
* @note Forked from https://github.com/clibs/list
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup Utility
* @{
*/
/**
* @defgroup cList
* @{
*/
#ifndef __CLIST_H__
#define __CLIST_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdlib.h>
#include <stdint.h>
/**
* @enum clist_direction_t
* @brief clist_t iterator direction.
*/
typedef enum
{
LIST_HEAD,
LIST_TAIL
} clist_direction_t;
/**
* @struct clist_node_t
* @brief clist_t node struct.
*/
typedef struct clist_node
{
struct clist_node *prev; ///< previous node
struct clist_node *next; ///< next node
void *val;
} clist_node_t;
/**
* @struct clist_t
* @brief clist_t struct.
*/
typedef struct
{
clist_node_t *head; ///< first node
clist_node_t *tail; ///< last node
uint32_t len; ///< list length
void (*free)(void *val); ///< node free function handle
int8_t (*compare)(void *a, void *b); ///< node compare function handle
} clist_t;
/**
* @struct clist_iterator_t
* @brief clist_t iterator struct.
*/
typedef struct
{
clist_node_t *next; ///< next element
clist_direction_t direction; ///< iter direction
} clist_iterator_t;
// Node prototypes.
clist_node_t *
clist_node_new(void *val);
// clist_t prototypes.
clist_t *
clist_new(void);
clist_node_t *
clist_rpush(clist_t *self, clist_node_t *node);
clist_node_t *
clist_lpush(clist_t *self, clist_node_t *node);
clist_node_t *
clist_find(clist_t *self, void *val);
clist_node_t *
clist_at(clist_t *self, int index);
clist_node_t *
clist_rpop(clist_t *self);
clist_node_t *
clist_lpop(clist_t *self);
void
clist_remove(clist_t *self, clist_node_t *node);
void
clist_clear(clist_t *self);
void
clist_destroy(clist_t *self);
// clist_t iterator prototypes.
clist_iterator_t *
clist_iterator_new(clist_t *list, clist_direction_t direction);
clist_iterator_t *
clist_iterator_new_from_node(clist_node_t *node, clist_direction_t direction);
clist_node_t *
clist_iterator_next(clist_iterator_t *self);
void
clist_iterator_destroy(clist_iterator_t *self);
#ifdef __cplusplus
}
#endif
#endif /* __CLIBS_LIST_H__ */
/** @} cList*/
/** @} Utility*/
@@ -0,0 +1,93 @@
/*****************************************************************************/
/**
* @file common.h
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief Common macros
* @version 0.0
* @date 2022-07-16
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @defgroup COMMON_MACRO
* @{
*/
/***************************** Include Files *********************************/
#ifndef __COMMON_H_
#define __COMMON_H_
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <inttypes.h>
#include <assert.h>
#include "util.h"
#include "error.h"
/************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
#define __PRINT_BLOCK(block) \
do \
{ \
block \
} while (0)
#define ASSERT(exp) ((exp) ? (void)0 : AppAssert(__FILE__, __LINE__))
#define _nop_() __asm__("nop")
/* Stringify */
#define STR(x) #x
// #define _DEBUG_LEVEL 3
#if _DEBUG_LEVEL > 0
#define DBG_PRINT(...) printf(__VA_ARGS__)
#endif
#if _DEBUG_LEVEL >= 1
#define DBG_ERROR(...) __PRINT_BLOCK( \
printf("in "__FILE__ \
":%d [error]\t", \
__LINE__); \
printf(__VA_ARGS__);)
#endif
#if _DEBUG_LEVEL >= 2
#define DBG_WARNING(...) __PRINT_BLOCK( \
printf("[warning]\t"); \
printf(__VA_ARGS__);)
#endif
#if _DEBUG_LEVEL >= 3
#define DBG_INFO(...) __PRINT_BLOCK( \
printf("[Info]\t"); \
printf(__VA_ARGS__);)
#endif
#ifndef DBG_ERROR
#define DBG_ERROR(...) \
{ \
}
#endif
#ifndef DBG_WARNING
#define DBG_WARNING(...) \
{ \
}
#endif
#ifndef DBG_INFO
#define DBG_INFO(...) \
{ \
}
#endif
#ifndef DBG_PRINT
#define DBG_PRINT(...) \
{ \
}
#endif
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
void AppAssert(const char *file, int line);
#endif /* __COMMON_H_ */
/** @} */
@@ -0,0 +1,70 @@
/***************************************************************************//**
* @file delay.h
* @brief Header file of Delay functions
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* 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 _DELAY_H_
#define _DELAY_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
/**
* @struct time
* @brief Structure holding time data (seconds, microseconds).
*/
struct time {
unsigned int s, us;
};
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
/* Generate microseconds delay. */
void udelay(uint32_t usecs);
/* Generate miliseconds delay. */
void mdelay(uint32_t msecs);
/* Get current time */
struct time get_time(void);
#endif // _DELAY_H_
@@ -0,0 +1,56 @@
/*****************************************************************************/
/**
* @file common.h
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief Common error numbers
* @version 0.0
* @date 2022-06-18
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup COMMON_MACRO
* @{
*/
#ifndef SRC_ERROR_H_
#define SRC_ERROR_H_
#include <errno.h>
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
/**
* @name ERRORNO
* @{
*/
#ifdef SUCCESS
#undef SUCCESS
#endif
#define SUCCESS 0
#ifdef FAILURE
#undef FAILURE
#endif
#define FAILURE -1
#define EPARAM -2 /*!< Data crc check failed */
#define ECRC -3 /*!< Data crc check failed */
#define EDINVAL -4 /*!< Device is invalid (sleep or power off) */
#define EDCONF -5 /*!< Device confugure error */
#define ETIMEOUT -6 /*!< Timeout error */
#define EIGNORE -7 /*!< Received an unsupported command, and ignore it */
#define EQUEUE -8 /*!< Queue overflow */
#define EUNEXP -9 /*!< Encounter an unexpected error */
#define IS_ERR_VALUE(x) ((x) != SUCCESS)
#endif // ERROR_H_
/** @} ERRORNO*/
/** @} COMMON_MACRO*/
@@ -0,0 +1,95 @@
#ifndef SRC_GLOBAL_TIMER_H_
#define SRC_GLOBAL_TIMER_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <inttypes.h>
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
/**
* @struct timer_init_param
* @brief Structure holding the parameters for timer initialization
*/
struct global_timer_init_param {
/** timer ID */
uintptr_t base_addr;
/** timer ID */
uint16_t id;
/** timer count frequency (Hz) */
uint32_t freq_hz;
/** counter start value */
uint64_t load_value;
};
/**
* @struct timer_desc
* @brief Structure holding timer descriptor
*/
struct global_timer_desc {
/** timer ID */
uintptr_t base_addr;
/** timer ID */
uint16_t id;
/** timer count frequency (Hz) */
uint32_t freq_hz;
/** counter start value */
uint64_t load_value;
};
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
/* Initialize hardware timer and the handler structure associated with it. */
int32_t global_timer_init(struct global_timer_desc **desc,
struct global_timer_init_param *param);
/* Free the memory allocated by timer_setup(). */
int32_t global_timer_remove(struct global_timer_desc *desc);
/* Start a timer. */
int32_t global_timer_start(struct global_timer_desc *desc);
/* Stop a timer from counting. */
int32_t global_timer_stop(struct global_timer_desc *desc);
/* Get the value of the counter register for the timer. */
int32_t global_timer_counter_get(struct global_timer_desc *desc, uint64_t *counter);
/* Set the timer counter register value. */
int32_t global_timer_counter_set(struct global_timer_desc *desc, uint64_t new_val);
/* Get the timer clock frequency. */
int32_t global_timer_count_clk_get(struct global_timer_desc *desc, uint32_t *freq_hz);
/* Set the timer clock frequency. */
int32_t global_timer_count_clk_set(struct global_timer_desc *desc, uint32_t freq_hz);
/* Enable global timer interrupt. */
int32_t global_timer_irq_enable(struct global_timer_desc *desc);
/* Disable global timer interrupt. */
int32_t global_timer_irq_disable(struct global_timer_desc *desc);
/* Implement a acknowledgment global timer interrupt. */
int32_t global_timer_irq_ack(struct global_timer_desc *desc);
/* Set comparator register. */
int32_t global_timer_compara_set(struct global_timer_desc *desc, uint64_t com_val);
/* Set auto increment register . */
int32_t global_timer_auto_inc_set(struct global_timer_desc *desc, uint32_t inc_val);
/* Enable global timer auto increment mode. */
int32_t global_timer_auto_inc_enable(struct global_timer_desc *desc);
/* Disable global timer auto increment mode. */
int32_t global_timer_auto_inc_disable(struct global_timer_desc *desc);
#endif /* SRC_TIMER_H_ */
@@ -0,0 +1,188 @@
/***************************************************************************//**
* @file gpio.h
* @brief Header file of GPIO Interface
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* 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 _GPIO_H_
#define _GPIO_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
#define GPIO_OUT 0x01
#define GPIO_IN 0x00
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
/**
* @struct gpio_platform_ops
* @brief Structure holding gpio function pointers that point to the platform
* specific function
*/
struct gpio_platform_ops ;
/**
* @enum gpio_pull_up
* @brief Enum that holds the possible pull up/ pull down resistor configuration.
*/
enum gpio_pull_up {
PULL_NONE,
/** Strong pull up */
PULL_UP,
/** Strong pull down */
PULL_DOWN,
PULL_UP_WEAK,
PULL_DOWN_WEAK
};
/**
* @struct gpio_init_param
* @brief Structure holding the parameters for GPIO initialization.
*/
struct gpio_init_param {
/** Port number */
int32_t port;
/** GPIO number */
int32_t number;
/** Pull up/down resistor configuration */
enum gpio_pull_up pull;
/** GPIO platform specific functions */
const struct gpio_platform_ops *platform_ops;
/** GPIO extra parameters (device specific) */
void *extra;
};
/**
* @struct gpio_desc
* @brief Structure holding the GPIO descriptor.
*/
struct gpio_desc {
/** Port number */
int32_t port;
/** GPIO number */
int32_t number;
/** Pull up/down resistor configuration */
enum gpio_pull_up pull;
/** GPIO platform specific functions */
const struct gpio_platform_ops *platform_ops;
/** GPIO extra parameters (device specific) */
void *extra;
};
/**
* @enum gpio_values
* @brief Enum that holds the possible output states of a GPIO.
*/
enum gpio_values {
/** GPIO logic low */
GPIO_LOW,
/** GPIO logic high */
GPIO_HIGH,
/** GPIO high impedance */
GPIO_HIGH_Z
};
/**
* @struct gpio_platform_ops
* @brief Structure holding gpio function pointers that point to the platform
* specific function
*/
struct gpio_platform_ops {
/** gpio initialization function pointer */
int32_t (*gpio_ops_get)(struct gpio_desc **,
const struct gpio_init_param *);
/** gpio optional descriptor function pointer */
int32_t (*gpio_ops_get_optional)(struct gpio_desc **,
const struct gpio_init_param *);
/** gpio remove function pointer */
int32_t (*gpio_ops_remove)(struct gpio_desc *);
/** gpio direction input function pointer */
int32_t (*gpio_ops_direction_input)(struct gpio_desc *);
/** gpio direction output function pointer */
int32_t (*gpio_ops_direction_output)(struct gpio_desc *, uint8_t);
/** gpio get direction function pointer */
int32_t (*gpio_ops_get_direction)(struct gpio_desc *, uint8_t *);
/** gpio set value function pointer */
int32_t (*gpio_ops_set_value)(struct gpio_desc *, uint8_t);
/** gpio get value function pointer */
int32_t (*gpio_ops_get_value)(struct gpio_desc *, uint8_t *);
};
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
/* Obtain the GPIO decriptor. */
int32_t gpio_get(struct gpio_desc **desc,
const struct gpio_init_param *param);
/* Obtain optional GPIO descriptor. */
int32_t gpio_get_optional(struct gpio_desc **desc,
const struct gpio_init_param *param);
/* Free the resources allocated by gpio_get(). */
int32_t gpio_remove(struct gpio_desc *desc);
/* Enable the input direction of the specified GPIO. */
int32_t gpio_direction_input(struct gpio_desc *desc);
/* Enable the output direction of the specified GPIO. */
int32_t gpio_direction_output(struct gpio_desc *desc,
uint8_t value);
/* Get the direction of the specified GPIO. */
int32_t gpio_get_direction(struct gpio_desc *desc,
uint8_t *direction);
/* Set the value of the specified GPIO. */
int32_t gpio_set_value(struct gpio_desc *desc,
uint8_t value);
/* Get the value of the specified GPIO. */
int32_t gpio_get_value(struct gpio_desc *desc,
uint8_t *value);
#endif // _GPIO_H_
@@ -0,0 +1,134 @@
/***************************************************************************//**
* @file i2c.h
* @brief Header file of I2C Interface
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* 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 _I2C_H_
#define _I2C_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
/**
* @struct i2c_platform_ops
* @brief Structure holding I2C function pointers that point to the platform
* specific function
*/
struct i2c_platform_ops ;
/**
* @struct i2c_init_param
* @brief Structure holding the parameters for I2C initialization.
*/
struct i2c_init_param {
/** Device ID */
uint32_t device_id;
/** I2C maximum transfer speed supported */
uint32_t max_speed_hz;
/** Slave address */
uint8_t slave_address;
/** I2C platform specific functions */
const struct i2c_platform_ops *platform_ops;
/** I2C extra parameters (device specific parameters) */
void *extra;
};
/**
* @struct i2c_desc
* @brief Structure holding I2C descriptor
*/
struct i2c_desc {
/** Device ID */
uint32_t device_id;
/** I2C maximum transfer speed supported */
uint32_t max_speed_hz;
/** Slave address */
uint8_t slave_address;
/** I2C platform specific functions */
const struct i2c_platform_ops *platform_ops;
/** I2C extra parameters (device specific parameters) */
void *extra;
};
/**
* @struct i2c_platform_ops
* @brief Structure holding i2c function pointers that point to the platform
* specific function
*/
struct i2c_platform_ops {
/** i2c initialization function pointer */
int32_t (*i2c_ops_init)(struct i2c_desc **,
const struct i2c_init_param *);
/** i2c write function pointer */
int32_t (*i2c_ops_write)(struct i2c_desc *, uint8_t *, uint8_t, uint8_t);
/** i2c write function pointer */
int32_t (*i2c_ops_read)(struct i2c_desc *, uint8_t *, uint8_t, uint8_t);
/** i2c remove function pointer */
int32_t (*i2c_ops_remove)(struct i2c_desc *);
};
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
/* Initialize the I2C communication peripheral. */
int32_t i2c_init(struct i2c_desc **desc,
const struct i2c_init_param *param);
/* Free the resources allocated by i2c_init(). */
int32_t i2c_remove(struct i2c_desc *desc);
/* Write data to a slave device. */
int32_t i2c_write(struct i2c_desc *desc,
uint8_t *data,
uint8_t bytes_number,
uint8_t stop_bit);
/* Read data from a slave device. */
int32_t i2c_read(struct i2c_desc *desc,
uint8_t *data,
uint8_t bytes_number,
uint8_t stop_bit);
#endif // _I2C_H_
@@ -0,0 +1,235 @@
/***************************************************************************//**
* @file irq.h
* @brief Header file of IRQ interface.
* @author Cristian Pop (cristian.pop@analog.com)
********************************************************************************
* 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 _IRQ_H_
#define _IRQ_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
/**
* @enum irq_uart_event_e
* @brief Possible events for uart interrupt
* @todo replace this with enum irq_event
*/
enum irq_uart_event_e {
/** Write operation finalized */
IRQ_WRITE_DONE,
/** Read operation finalized */
IRQ_READ_DONE,
/** An error occurred */
IRQ_ERROR
};
enum irq_event {
EVT_GPIO,
EVT_UART_TX_COMPLETE,
EVT_UART_RX_COMPLETE,
EVT_UART_ERROR,
EVT_RTC,
EVT_XINT,
EVT_TIM_ELAPSED
};
enum irq_trig_level {
IRQ_LEVEL_LOW,
IRQ_LEVEL_HIGH,
IRQ_EDGE_FALLING,
IRQ_EDGE_RISING,
IRQ_EDGE_BOTH
};
enum irq_peripheral {
GPIO_IRQ,
UART_IRQ,
RTC_IRQ,
TIM_IRQ
};
/**
* @struct irq_platform_ops
* @brief Structure holding IRQ function pointers that point to the platform
* specific function
*/
struct irq_platform_ops ;
/**
* @struct irq_init_param
* @brief Structure holding the initial parameters for Interrupt Request.
*/
struct irq_init_param {
/** Interrupt request controller ID. */
uint32_t irq_ctrl_id;
/** Platform specific IRQ platform ops structure. */
const struct irq_platform_ops *platform_ops;
/**
* This is intended to store irq controller specific configurations,
* it should not be a reference to any peripheral descriptor.
*/
void *extra;
};
/**
* @struct irq_desc
* @brief Structure for Interrupt Request descriptor.
*/
struct irq_ctrl_desc {
/** Interrupt request controller ID. */
uint32_t irq_ctrl_id;
/** Platform specific IRQ platform ops structure. */
const struct irq_platform_ops *platform_ops;
/**
* This is intended to store irq controller specific configurations,
* it should not be a reference to any peripheral descriptor.
*/
void *extra;
};
/**
* @struct callback_desc
* @brief Structure describing a callback to be registered
* @todo: remove this, use struct irq_callback instead.
*/
struct callback_desc {
/** Callback to be called when the event an event occurs. */
void (*callback)(void *context);
/**
* Callback to be called when the event an event occurs
* @param ctx - Same as \ref callback_desc.ctx
* @param event - Event that generated the callback
* @param extra - Platform specific data
*/
void (*legacy_callback)(void *ctx, uint32_t event,
void *extra); /* TODO: remove this. */
/** Parameter to be passed when the callback is called */
void *ctx;
/** Platform specific configuration for a callback */
void *legacy_config; /* TODO: remove this. */
/** Platform specific event that triggers the calling of the callback. */
enum irq_event event;
/** Interrupt source peripheral specifier. */
enum irq_peripheral peripheral;
/** This will be used to store HAL specific descriptors */
void *handle;
};
/**
* @struct irq_platform_ops
* @brief Structure holding IRQ function pointers that point to the platform
* specific function
*/
struct irq_platform_ops {
/** Initialize a interrupt controller peripheral. */
int32_t (*init)(struct irq_ctrl_desc **desc,
const struct irq_init_param *param);
/** Register a legacy_callback to handle the irq events */
int32_t (*register_callback)(struct irq_ctrl_desc *desc, uint32_t irq_id,
struct callback_desc *callback);
/** Unregisters a generic IRQ handling function */
int32_t (*unregister_callback)(struct irq_ctrl_desc *desc,
uint32_t irq_id,
struct callback_desc *callback);
/** Global interrupt enable */
int32_t (*global_enable)(struct irq_ctrl_desc *desc);
/** Global interrupt disable */
int32_t (*global_disable)(struct irq_ctrl_desc *desc);
/** Set interrupt trigger level. */
int32_t (*trigger_level_set)(struct irq_ctrl_desc *desc, uint32_t irq_id,
enum irq_trig_level trig);
/** Enable specific interrupt */
int32_t (*enable)(struct irq_ctrl_desc *desc, uint32_t irq_id);
/** Disable specific interrupt */
int32_t (*disable)(struct irq_ctrl_desc *desc, uint32_t irq_id);
/** Set the priority level for a specific interrupt */
int32_t (*set_priority)(struct irq_ctrl_desc *desc, uint32_t irq_id,
uint32_t priority_level);
/** IRQ remove function pointer */
int32_t (*remove)(struct irq_ctrl_desc *desc);
};
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
/* Initialize a interrupt controller peripheral. */
int32_t irq_ctrl_init(struct irq_ctrl_desc **desc,
const struct irq_init_param *param);
/* Free the resources allocated by irq_ctrl_init(). */
int32_t irq_ctrl_remove(struct irq_ctrl_desc *desc);
/* Register a callback to handle the irq events */
int32_t irq_register_callback(struct irq_ctrl_desc *desc,
uint32_t irq_id,
struct callback_desc *callback_desc);
/* Unregisters a generic IRQ handling function */
int32_t irq_unregister_callback(struct irq_ctrl_desc *desc,
uint32_t irq_id,
struct callback_desc *callback_desc);
/* Global interrupt enable */
int32_t irq_global_enable(struct irq_ctrl_desc *desc);
/* Global interrupt disable */
int32_t irq_global_disable(struct irq_ctrl_desc *desc);
/* Set interrupt trigger level. */
int32_t irq_trigger_level_set(struct irq_ctrl_desc *desc,
uint32_t irq_id,
enum irq_trig_level trig);
/* Enable specific interrupt */
int32_t irq_enable(struct irq_ctrl_desc *desc, uint32_t irq_id);
/* Disable specific interrupt */
int32_t irq_disable(struct irq_ctrl_desc *desc, uint32_t irq_id);
/** Set the priority level for a specific interrupt */
int32_t irq_set_priority(struct irq_ctrl_desc *desc,
uint32_t irq_id,
uint32_t priority_level);
#endif // _IRQ_H_
@@ -0,0 +1,327 @@
/***************************************************************************//**
* @file list.h
* @brief List library header
* @author Mihail Chindris (mihail.chindris@analog.com)
********************************************************************************
* @copyright
* 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.
********************************************************************************
*
* @section list_details Library description
* This library handles double linked lists and it expose inseart,
* read, get and delete functions. \n
* It also can be accesed using it member functions which wrapp function for
* usual list types.\n
* @subsection example Sample code
* @code{.c}
* // -- Use a generic list
* struct list_desc *list1;
* struct iterator *it;
* uint32_t a;
* // Create list list1
* list_init(&list1, LIST_DEFAULT, NULL);
* // Add items to the list
* list_add_last(list1, 1);
* list_add_last(list1, 2);
* list_add_last(list1, 3);
* // Here the list will be: 1 -> 2 - > 3
*
* list_read_last(list1, &a);
* printf("Last: %d\n", a);
* // 3 will be printed
* // Create an iterator on the end of the list
* iterator_init(&it, list1, 0);
* // Move the iterator backword with one position
* iterator_move(it, -1);
* // Read the data at the current position
* iterator_read(it, &a);
* printf("Current: %d\n", a);
* // 2 will be printed
* iterator_remove(it);
* list_remove(list1);
*
* // -- Use a popular list
* struct list_desc *stack;
* // Create a FIFO list
* list_init(&stack, LIST_STACK, NULL);
* // Put elements in the list
* stack->push(stack, 1);
* stack->push(stack, 2);
* stack->push(stack, 3);
* // Read from the stack
* stack->pop(stack, &a);
* printf("Last: %d\n", a);
* // 3 will be printed
* list_remove(stack);
* @endcode
*******************************************************************************/
#ifndef _LIST_H_
#define _LIST_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
#include <stdbool.h>
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
/**
* @struct list_desc
* @brief Structure storing the list and function wrapper for usual list types
*
* With this structure the funtionalities of usual list types
* ( \ref adapter_type ) can be accesed with the functions referenced in this
* structure.
* For example:
* @code{.c}
* my_queue->push(my_queue, my_data);
* @endcode
*/
struct list_desc;
/**
* @struct list_iterator
* @brief Structure used to iterate through the list using Iterator functions.
*/
struct iterator;
/**
* @brief Prototype of the compare function.
*
* The function used to compare the elements of the liste when doing
* operations on an ordered list.
* @param data1 - First element to be compared
* @param data2 - Second element to be compared
* @return
* - -1 - If data1 < data2
* - 0 - If data1 == data2
* - 1 - If data1 > data2
*/
typedef int32_t (*f_cmp)(void *data1, void *data2);
/**
* @name Generic functions
* Each function interacting with the list have one of the following formats.\n
* Aditionaly they may have one more parametere for specific functionalities.\n
* In the Iterator functions, the list reference is replaced by the iterator's
* one.
* @{
*/
/**
* @brief Add an element in the list.
*
* The element of the list is created and the data field is stored in it.
* @param list_desc - Reference to the list. Created by \ref list_init.
* @param data - Data to store in a list element
* @return
* - 0 : On success
* - -1 : Otherwise
*/
typedef int32_t (*f_add)(struct list_desc *list_desc, void *data);
/**
* @brief Edit an element in the list. The content is replaced by new_data.
* @param list_desc - Reference to the list. Created by \ref list_init.
* @param new_data - New data to replace the old one
* @return
* - 0 : On success
* - -1 : Otherwise
*/
typedef int32_t (*f_edit)(struct list_desc *list_desc, void *new_data);
/**
* @brief Read an element from the list.
* @param list_desc - Reference to the list. Created by \ref list_init.
* @param result - If not null, result is filled with:
* @param data - Content of the list element, NULL if some error occur.
* @return \n
* - 0 : On success
* - -1 : Otherwise
* @note If the content of an element can be 0 then the result must be checked
* to see if the functions has succeded
*/
typedef int32_t (*f_read)(struct list_desc *list_desc, void **data);
/**
* @brief Read and remove an element from the list.
* @param list_desc - Reference to the list. Created by \ref list_init.
* @param result - If not null, result is filled with:
* @param data - Content of the list element, NULL if some error occur.
* @return
* - 0 : On success
* - -1 : Otherwise
*/
typedef int32_t (*f_get)(struct list_desc *list_desc, void **data);
/** @} */
/**
* @enum adapter_type
* @brief Selects functionalities for functions in \ref list_desc
*/
enum adapter_type {
/** Default type is LIST_STACK */
LIST_DEFAULT,
/**
* Functions for a FIFO list (First-in first-out). Elements are inserted
* in one end and extracted from the other end.
* - \e Push: Insert element
* - \e Pop: Get next element (Read and remove)
* - \e Top_next: Read next element
* - \e Back: Read first element
* - \e Swap: Edit the content of the next element
*/
LIST_QUEUE,
/**
* Functions for a LIFO list (Last-in first-out). Elements are inserted
* and extracted only from the same end.
* - \e Push: Insert element
* - \e Pop: Get top element (Read and remove)
* - \e Top_next: Read top element
* - \e Back: Read bottom element
* - \e Swap: Edit the content of the top element
*/
LIST_STACK,
/**
* Functions for ordered list. The order of element is determinated
* usinge the \ref f_cmp.
* - \e Push: Insert element
* - \e Pop: Get lowest element (Read and remove)
* - \e Top_next: Read lowest element
* - \e Back: Read the biggest element
* - \e Swap: Edit the lowest element
*/
LIST_PRIORITY_LIST
};
struct list_desc {
/** Refer to \ref adapter_type */
f_add push;
/** Refer to \ref adapter_type */
f_get pop;
/** Refer to \ref adapter_type */
f_read top_next;
/** Refer to \ref adapter_type */
f_read back;
/** Refer to \ref adapter_type */
f_edit swap;
/** Structure storing the list internal parameters */
void *priv_desc;
};
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
int32_t list_init(struct list_desc **list_desc,
enum adapter_type type,
f_cmp comparator);
int32_t list_remove(struct list_desc *list_desc);
int32_t list_get_size(struct list_desc *list_desc,
uint32_t *out_size);
/**
* @name Iterator functions
* An iterator is used to iterate through the list. For a list, any number of
* iterators can be created. All must be removed before removing a list.
* @{
*/
int32_t iterator_init(struct iterator **iter,
struct list_desc *list_desc,
bool start);
int32_t iterator_remove(struct iterator *iter);
int32_t iterator_move(struct iterator *iter, int32_t steps);
int32_t iterator_move_to_idx(struct iterator *iter, int32_t idx);
int32_t iterator_find(struct iterator *iter, void *cmp_data);
int32_t iterator_insert(struct iterator *iter, void *data,
bool after);
int32_t iterator_edit(struct iterator *iter, void *new_data);
int32_t iterator_read(struct iterator *iter, void **data);
int32_t iterator_get(struct iterator *iter, void **data);
/** @}*/
/**
* @name Operations on the ends of the list
* These functions will operate on the first or last element of the list
* @{
*/
int32_t list_add_first(struct list_desc *list_desc, void *data);
int32_t list_edit_first(struct list_desc *list_desc,
void *new_data);
int32_t list_read_first(struct list_desc *list_desc, void **data);
int32_t list_get_first(struct list_desc *list_desc, void **data);
int32_t list_add_last(struct list_desc *list_desc, void *data);
int32_t list_edit_last(struct list_desc *list_desc, void *new_data);
int32_t list_read_last(struct list_desc *list_desc, void **data);
int32_t list_get_last(struct list_desc *list_desc, void **data);
/** @}*/
/**
* @name Operations by index
* These functions use an index to identify the element in the list.
* @{
*/
int32_t list_add_idx(struct list_desc *list_desc, void *data,
uint32_t idx);
int32_t list_edit_idx(struct list_desc *list_desc, void *new_data,
uint32_t idx);
int32_t list_read_idx(struct list_desc *list_desc, void **data,
uint32_t idx);
int32_t list_get_idx(struct list_desc *list_desc, void **data,
uint32_t idx);
/** @}*/
/**
* @name Operations by comparation
* These functions use the specified \ref f_cmp at \ref list_init to identify
* the element this will operate on.
* @{
*/
int32_t list_add_find(struct list_desc *list_desc, void *data);
int32_t list_edit_find(struct list_desc *list_desc, void *new_data,
void *cmp_data);
int32_t list_read_find(struct list_desc *list_desc, void **data,
void *cmp_data);
int32_t list_get_find(struct list_desc *list_desc, void **data,
void *cmp_data);
/** @}*/
#endif // _LIST_H_
@@ -0,0 +1,209 @@
/***************************************************************************//**
* @file spi.h
* @brief Header file of SPI Interface
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* 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_H_
#define _SPI_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
#define SPI_CPHA 0x01
#define SPI_CPOL 0x02
#define SPI_3WIRE 0x04
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
/**
* @enum spi_mode
* @brief SPI configuration for clock phase and polarity.
*/
enum spi_mode {
/** Data on rising, shift out on falling */
SPI_MODE_0 = (0 | 0),
/** Data on falling, shift out on rising */
SPI_MODE_1 = (0 | SPI_CPHA),
/** Data on rising, shift out on falling */
SPI_MODE_2 = (SPI_CPOL | 0),
/** Data on falling, shift out on rising */
SPI_MODE_3 = (SPI_CPOL | SPI_CPHA),
/** Data on rising, shift out on falling */
SPI_MODE_4 = SPI_3WIRE
};
/**
* @enum spi_bit_order
* @brief SPI configuration for bit order (MSB/LSB).
*/
enum spi_bit_order {
/** Most-significant bit (MSB) first */
SPI_BIT_ORDER_MSB_FIRST = 0,
/** Least-significant bit (LSB) first */
SPI_BIT_ORDER_LSB_FIRST = 1,
};
/**
* @struct spi_msg_list
* @brief List item describing a SPI transfer
*/
struct spi_msg {
/** Buffer with data to send. If NULL, 0x00 will be sent */
uint8_t *tx_buff;
/** Buffer where to store data. If NULL, incoming data won't be saved */
uint8_t *rx_buff;
/** Length of buffers. Must have equal size. */
uint32_t bytes_number;
/** If set, CS will be deasserted after the transfer */
uint8_t cs_change;
/**
* Minimum delay (in us) between the CS de-assert event of the current message
* and the assert of the next one.
*/
uint32_t cs_change_delay;
/** Delay (in us) between the CS assert and the first SCLK edge. */
uint32_t cs_delay_first;
/** Delay (in us) between the last SCLK edge and the CS deassert */
uint32_t cs_delay_last;
};
/**
* @struct spi_platform_ops
* @brief Structure holding SPI function pointers that point to the platform
* specific function
*/
struct spi_platform_ops ;
/**
* @struct spi_init_param
* @brief Structure holding the parameters for SPI initialization
*/
struct spi_init_param {
/** Device ID */
uint32_t device_id;
/** maximum transfer speed */
uint32_t max_speed_hz;
/** SPI chip select */
uint8_t chip_select;
/** SPI mode */
enum spi_mode mode;
/** SPI bit order */
enum spi_bit_order bit_order;
const struct spi_platform_ops *platform_ops;
/** SPI extra parameters (device specific) */
void *extra;
/** Parent of the device */
struct spi_desc *parent;
};
/**
* @struct spi_desc
* @brief Structure holding SPI descriptor.
*/
struct spi_desc {
/** Device ID */
uint32_t device_id;
/** maximum transfer speed */
uint32_t max_speed_hz;
/** SPI chip select */
uint8_t chip_select;
/** SPI mode */
enum spi_mode mode;
/** SPI bit order */
enum spi_bit_order bit_order;
const struct spi_platform_ops *platform_ops;
/** SPI extra parameters (device specific) */
void *extra;
/** Parent of the device */
struct spi_desc *parent;
};
/**
* @struct spi_platform_ops
* @brief Structure holding SPI function pointers that point to the platform
* specific function
*/
struct spi_platform_ops {
/** SPI initialization function pointer */
int32_t (*init)(struct spi_desc **, const struct spi_init_param *);
/** SPI write/read function pointer */
int32_t (*write_and_read)(struct spi_desc *, uint8_t *, uint16_t);
/** SPI write function pointer */
int32_t (*write_and_read_3wire)(struct spi_desc *, uint8_t *,uint8_t *,uint16_t, uint16_t);
/** Iterate over the spi_msg array and send all messages at once */
int32_t (*transfer)(struct spi_desc *, struct spi_msg *, uint32_t);
/** SPI remove function pointer */
int32_t (*remove)(struct spi_desc *);
};
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
/* Initialize the SPI communication peripheral. */
int32_t spi_init(struct spi_desc **desc,
const struct spi_init_param *param);
/* Free the resources allocated by spi_init(). */
int32_t spi_remove(struct spi_desc *desc);
/* Write and read data to/from SPI. */
int32_t spi_write_and_read(struct spi_desc *desc,
uint8_t *data,
uint16_t bytes_number);
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);
/* Iterate over the spi_msg array and send all messages at once */
int32_t spi_transfer(struct spi_desc *desc,
struct spi_msg *msgs,
uint32_t len);
#endif // _SPI_H_
@@ -0,0 +1,159 @@
/***************************************************************************//**
* @file timer.h
* @brief Timer control module header.
* @author Andrei Drimbarean (andrei.drimbarean@analog.com)
********************************************************************************
* 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 _SRC_TIMER_H_
#define _SRC_TIMER_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
/**
* @struct timer_desc
* @brief Structure holding timer descriptor
*/
struct timer_desc {
/** timer ID */
uint16_t id;
/** timer count frequency (Hz) */
uint32_t freq_hz;
/** the number of ticks the timer counts until it resets */
uint32_t ticks_count;
/** Timer platform operations */
const struct timer_platform_ops *platform_ops;
/** timer extra parameters (device specific) */
void *extra;
};
/**
* @struct timer_platform_ops
* @brief Structure holding timer function pointers that point to the platform
* specific function
*/
struct timer_platform_ops ;
/**
* @struct timer_init_param
* @brief Structure holding the parameters for timer initialization
*/
struct timer_init_param {
/** timer ID */
uint16_t id;
/** timer count frequency (Hz) */
uint32_t freq_hz;
/** the number of ticks the timer counts until it resets */
uint32_t ticks_count;
/** Timer platform operations */
const struct timer_platform_ops *platform_ops;
/** timer extra parameters (device specific) */
void *extra;
};
/**
* @struct timer_platform_ops
* @brief Structure holding timer function pointers that point to the platform
* specific function
*/
struct timer_platform_ops {
/** timer initialization function pointer */
int32_t (*init)(struct timer_desc **,
const struct timer_init_param *);
/** timer start function pointer */
int32_t (*start)(struct timer_desc *);
/** timer stop function pointer */
int32_t (*stop)(struct timer_desc *);
/** timer get counter function pointer */
int32_t (*counter_get)(struct timer_desc *, uint32_t *counter);
/** timer set counter function pointer */
int32_t (*counter_set)(struct timer_desc *, uint32_t new_val);
/** timer get clock frequency function pointer */
int32_t (*count_clk_get)(struct timer_desc *, uint32_t *freq_hz);
/** timer set clock frequency function pointer */
int32_t (*count_clk_set)(struct timer_desc *, uint32_t freq_hz);
/** timer get elapsed time in nsec */
int32_t (*get_elapsed_time_nsec)(struct timer_desc *,
uint64_t *elapsed_time);
/** timer remove function pointer */
int32_t (*remove)(struct timer_desc *);
};
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
/* Initialize hardware timer and the handler structure associated with it. */
int32_t timer_init(struct timer_desc **desc,
struct timer_init_param *param);
/* Free the memory allocated by timer_setup(). */
int32_t timer_remove(struct timer_desc *desc);
/* Start a timer. */
int32_t timer_start(struct timer_desc *desc);
/* Stop a timer from counting. */
int32_t timer_stop(struct timer_desc *desc);
/* Get the value of the counter register for the timer. */
int32_t timer_counter_get(struct timer_desc *desc,
uint32_t *counter);
/* Set the timer counter register value. */
int32_t timer_counter_set(struct timer_desc *desc,
uint32_t new_val);
/* Get the timer clock frequency. */
int32_t timer_count_clk_get(struct timer_desc *desc,
uint32_t *freq_hz);
/* Set the timer clock frequency. */
int32_t timer_count_clk_set(struct timer_desc *desc,
uint32_t freq_hz);
/* Get the elapsed time in nsec for the timer. */
int32_t timer_get_elapsed_time_nsec(struct timer_desc *desc,
uint64_t *elapsed_time);
#endif // _SRC_TIMER_H_
@@ -0,0 +1,115 @@
/***************************************************************************//**
* @file trng.h
* @brief Header file of true random number generator
* @author Mihail Chindris (mihail.chindris@analog.com)
********************************************************************************
* @copyright
* 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.
*******************************************************************************/
#ifndef _TRNG_H_
#define _TRNG_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
/**
* @struct trng_platform_ops
* @brief Structure holding TRNG function pointers that point to the platform
* specific function
*/
struct trng_platform_ops;
/**
* @struct trng_desc
* @brief TRNG Descriptor
*/
struct trng_desc {
/** Platform ops */
const struct trng_platform_ops *platform_ops;
/** Platform specific parameters */
void *extra;
};
/**
* @struct trng_init_param
* @brief Init parameter for TRNG
*/
struct trng_init_param {
/** Device id */
uint32_t dev_id;
/** Platform specific parameter */
void *extra;
/** Platform ops */
const struct trng_platform_ops *platform_ops;
};
/**
* @struct trng_platform_ops
* @brief Structure holding TRNG function pointers that point to the platform
* specific function
*/
struct trng_platform_ops {
/** TRNG initialization function pointer */
int (*init)(struct trng_desc **,
const struct trng_init_param *);
/** Fill buffer with random numbers */
int (*fill_buffer)(struct trng_desc *, uint8_t *, uint32_t);
/** TRNG remove function pointer */
int (*remove)(struct trng_desc *);
};
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
/* Initialize descriptor */
int trng_init(struct trng_desc **desc,
const struct trng_init_param *param);
/* Free resources allocated in descriptor */
int trng_remove(struct trng_desc *desc);
/* Fill buffer with random numbers */
int trng_fill_buffer(struct trng_desc *desc, uint8_t *buff,
uint32_t len);
#endif // _TRNG_H_
@@ -0,0 +1,177 @@
/*****************************************************************************/
/**
* @file util.h
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief Utility functions header file
* @version 0.0
* @date 2023-05-06
*
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @defgroup Utility
* @{
*/
#ifndef __UTIL_H_
#define __UTIL_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
// #define __CRC_LSB
#define __BITSWAP_TABLE
#define __CRC_LSB
#define CRC16_INIT 0x0000
#define CRC8_INIT 0x00
#define BIT(x) (1 << (x))
#define ARRAY_SIZE(x) \
(sizeof(x) / sizeof((x)[0]))
#define DIV_ROUND_UP(x, y) \
(((x) + (y)-1) / (y))
#define DIV_ROUND_CLOSEST(x, y) \
(((x) + (y) / 2) / (y))
#define DIV_ROUND_CLOSEST_ULL(x, y) \
DIV_ROUND_CLOSEST(x, y)
#define min(x, y) \
(((x) < (y)) ? (x) : (y))
#define min_t(type, x, y) \
(type) min((type)(x), (type)(y))
#define max(x, y) \
(((x) > (y)) ? (x) : (y))
#define max_t(type, x, y) \
(type) max((type)(x), (type)(y))
#define clamp(val, min_val, max_val) \
(max(min((val), (max_val)), (min_val)))
#define clamp_t(type, val, min_val, max_val) \
(type) clamp((type)(val), (type)(min_val), (type)(max_val))
#define swap(x, y) \
{ \
typeof(x) _tmp_ = (x); \
(x) = (y); \
(y) = _tmp_; \
}
#define round_up(x, y) \
(((x) + (y)-1) / (y))
#define BITS_PER_LONG 32
#define GENMASK(h, l) ({ \
uint32_t t = (uint32_t)(~0UL); \
t = t << (BITS_PER_LONG - (h - l + 1)); \
t = t >> (BITS_PER_LONG - (h + 1)); \
t; \
})
#define bswap_constant_32(x) \
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
#define bswap_constant_16(x) ((((x) & (uint16_t)0xff00) >> 8) | \
(((x) & (uint16_t)0x00ff) << 8))
#define bit_swap_constant_8(x) \
((((x) & 0x80) >> 7) | \
(((x) & 0x40) >> 5) | \
(((x) & 0x20) >> 3) | \
(((x) & 0x10) >> 1) | \
(((x) & 0x08) << 1) | \
(((x) & 0x04) << 3) | \
(((x) & 0x02) << 5) | \
(((x) & 0x01) << 7))
#define U16_MAX ((uint16_t)~0U)
#define S16_MAX ((int16_t)(U16_MAX >> 1))
#define DIV_U64(x, y) (x / y)
#define UNUSED_PARAM(x) ((void)x)
#define shift_right(x, s) ((x) < 0 ? -(-(x) >> (s)) : (x) >> (s))
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
void IO_Out32(uintptr_t addr, uint32_t value);
uint32_t IO_In32(uintptr_t addr);
/* flip a byte left to right*/
uint8_t byte_bit_swap(uint8_t byte);
/* flip a 32bit word left to right */
uint32_t word_bit_swap(uint32_t word);
/* Returns the number of 1-bits in digit. */
uint32_t count_ones(uint32_t word);
/* convert a fixed number to a double. */
double fix2double(int32_t val, uint8_t frac_bits);
/* Find first set bit in word. */
uint32_t find_first_set_bit(uint32_t word);
/* Find last set bit in word. */
uint32_t find_last_set_bit(uint32_t word);
/* Locate the closest element in an array. */
uint32_t find_closest(int32_t val,
const int32_t *array,
uint32_t size);
/* Shift the value and apply the specified mask. */
uint32_t field_prep(uint32_t mask, uint32_t val);
/* Get a field specified by a mask from a word. */
uint32_t field_get(uint32_t mask, uint32_t word);
/* Log base 2 of the given number. */
int32_t log_base_2(uint32_t x);
/* Find greatest common divisor of the given two numbers. */
uint32_t greatest_common_divisor(uint32_t a,
uint32_t b);
/* Calculate best rational approximation for a given fraction. */
void rational_best_approximation(uint32_t given_numerator,
uint32_t given_denominator,
uint32_t max_numerator,
uint32_t max_denominator,
uint32_t *best_numerator,
uint32_t *best_denominator);
/* Calculate the number of set bits. */
uint32_t hweight8(uint32_t word);
/* Calculate the quotient and the remainder of an integer division. */
uint64_t do_div(uint64_t *n,
uint64_t base);
/* Unsigned 64bit divide with 64bit divisor and remainder */
uint64_t div64_u64_rem(uint64_t dividend, uint64_t divisor,
uint64_t *remainder);
/* Unsigned 64bit divide with 32bit divisor with remainder */
uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder);
int64_t div_s64_rem(int64_t dividend, int32_t divisor, int32_t *remainder);
/* Unsigned 64bit divide with 32bit divisor */
uint64_t div_u64(uint64_t dividend, uint32_t divisor);
int64_t div_s64(int64_t dividend, int32_t divisor);
/* Converts from string to int32_t */
int32_t str_to_int32(const char *str);
/* Converts from string to uint32_t */
uint32_t srt_to_uint32(const char *str);
int crc16_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint16_t *crcVal);
bool crc16_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly);
int crc8_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint8_t *crcVal);
bool crc8_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly);
#endif // __UTIL_H_
/** @} */
@@ -0,0 +1,293 @@
/*******************************************************************/
/* */
/* This file is automatically generated by linker script generator.*/
/* */
/* Version: 2018.3 */
/* */
/* Copyright (c) 2010-2019 Xilinx, Inc. All rights reserved. */
/* */
/* Description : Cortex-A9 Linker Script */
/* */
/*******************************************************************/
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x2000;
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x2000;
_ABORT_STACK_SIZE = DEFINED(_ABORT_STACK_SIZE) ? _ABORT_STACK_SIZE : 1024;
_SUPERVISOR_STACK_SIZE = DEFINED(_SUPERVISOR_STACK_SIZE) ? _SUPERVISOR_STACK_SIZE : 2048;
_IRQ_STACK_SIZE = DEFINED(_IRQ_STACK_SIZE) ? _IRQ_STACK_SIZE : 1024;
_FIQ_STACK_SIZE = DEFINED(_FIQ_STACK_SIZE) ? _FIQ_STACK_SIZE : 1024;
_UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024;
/* Define Memories in the system */
MEMORY
{
ps7_ddr_0 : ORIGIN = 0x100000, LENGTH = 0x3FF00000
ps7_qspi_linear_0 : ORIGIN = 0xFC000000, LENGTH = 0x2000000
ps7_ram_0 : ORIGIN = 0x0, LENGTH = 0x30000
ps7_ram_1 : ORIGIN = 0xFFFF0000, LENGTH = 0xFE00
}
/* Specify the default entry point to the program */
ENTRY(_vector_table)
/* Define the sections, and where they are mapped in memory */
SECTIONS
{
.text : {
. = ALIGN(2048);
KEEP (*(.vectors))
*(.boot)
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
*(.plt)
*(.gnu_warning)
*(.gcc_execpt_table)
*(.glue_7)
*(.glue_7t)
*(.vfp11_veneer)
*(.ARM.extab)
*(.gnu.linkonce.armextab.*)
} > ps7_ddr_0
.init : {
KEEP (*(.init))
} > ps7_ddr_0
.fini : {
KEEP (*(.fini))
} > ps7_ddr_0
.rodata : {
__rodata_start = .;
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
__rodata_end = .;
} > ps7_ddr_0
.rodata1 : {
__rodata1_start = .;
*(.rodata1)
*(.rodata1.*)
__rodata1_end = .;
} > ps7_ddr_0
.sdata2 : {
__sdata2_start = .;
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
__sdata2_end = .;
} > ps7_ddr_0
.sbss2 : {
__sbss2_start = .;
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
__sbss2_end = .;
} > ps7_ddr_0
.data : {
__data_start = .;
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.jcr)
*(.got)
*(.got.plt)
__data_end = .;
} > ps7_ddr_0
.data1 : {
__data1_start = .;
*(.data1)
*(.data1.*)
__data1_end = .;
} > ps7_ddr_0
.got : {
*(.got)
} > ps7_ddr_0
.note.gnu.build-id : {
KEEP (*(.note.gnu.build-id))
} > ps7_ddr_0
.ctors : {
__CTOR_LIST__ = .;
___CTORS_LIST___ = .;
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
___CTORS_END___ = .;
} > ps7_ddr_0
.dtors : {
__DTOR_LIST__ = .;
___DTORS_LIST___ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
___DTORS_END___ = .;
} > ps7_ddr_0
.fixup : {
__fixup_start = .;
*(.fixup)
__fixup_end = .;
} > ps7_ddr_0
.eh_frame : {
*(.eh_frame)
} > ps7_ddr_0
.eh_framehdr : {
__eh_framehdr_start = .;
*(.eh_framehdr)
__eh_framehdr_end = .;
} > ps7_ddr_0
.gcc_except_table : {
*(.gcc_except_table)
} > ps7_ddr_0
.mmu_tbl (ALIGN(16384)) : {
__mmu_tbl_start = .;
*(.mmu_tbl)
__mmu_tbl_end = .;
} > ps7_ddr_0
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
*(.gnu.linkonce.armexidix.*.*)
__exidx_end = .;
} > ps7_ddr_0
.preinit_array : {
__preinit_array_start = .;
KEEP (*(SORT(.preinit_array.*)))
KEEP (*(.preinit_array))
__preinit_array_end = .;
} > ps7_ddr_0
.init_array : {
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} > ps7_ddr_0
.fini_array : {
__fini_array_start = .;
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array))
__fini_array_end = .;
} > ps7_ddr_0
.ARM.attributes : {
__ARM.attributes_start = .;
*(.ARM.attributes)
__ARM.attributes_end = .;
} > ps7_ddr_0
.sdata : {
__sdata_start = .;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
__sdata_end = .;
} > ps7_ddr_0
.sbss (NOLOAD) : {
__sbss_start = .;
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
__sbss_end = .;
} > ps7_ddr_0
.tdata : {
__tdata_start = .;
*(.tdata)
*(.tdata.*)
*(.gnu.linkonce.td.*)
__tdata_end = .;
} > ps7_ddr_0
.tbss : {
__tbss_start = .;
*(.tbss)
*(.tbss.*)
*(.gnu.linkonce.tb.*)
__tbss_end = .;
} > ps7_ddr_0
.bss (NOLOAD) : {
__bss_start = .;
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
__bss_end = .;
} > ps7_ddr_0
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
/* Generate Stack and Heap definitions */
.heap (NOLOAD) : {
. = ALIGN(16);
_heap = .;
HeapBase = .;
_heap_start = .;
. += _HEAP_SIZE;
_heap_end = .;
HeapLimit = .;
} > ps7_ddr_0
.stack (NOLOAD) : {
. = ALIGN(16);
_stack_end = .;
. += _STACK_SIZE;
. = ALIGN(16);
_stack = .;
__stack = _stack;
. = ALIGN(16);
_irq_stack_end = .;
. += _IRQ_STACK_SIZE;
. = ALIGN(16);
__irq_stack = .;
_supervisor_stack_end = .;
. += _SUPERVISOR_STACK_SIZE;
. = ALIGN(16);
__supervisor_stack = .;
_abort_stack_end = .;
. += _ABORT_STACK_SIZE;
. = ALIGN(16);
__abort_stack = .;
_fiq_stack_end = .;
. += _FIQ_STACK_SIZE;
. = ALIGN(16);
__fiq_stack = .;
_undef_stack_end = .;
. += _UNDEF_STACK_SIZE;
. = ALIGN(16);
__undef_stack = .;
} > ps7_ddr_0
_end = .;
}
@@ -0,0 +1,88 @@
/*****************************************************************************/
/**
* Description: main.c
*
* Date: 2023-05-07 13:19
* Last Edit Time: [2023-05-07 20:32]
*
* Revisions: Rev 0.0
* History:
* [2023-05-07]: Initial edition.
*
* Copyright(c) 2024 Beijing Institute of Technology.
*
******************************************************************************/
/***************************** Include Files *********************************/
// Standard
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
// Xilinx
#include "xscugic.h"
#include "drivers/platform/xilinx_irq.h"
#include "drivers/platform/xilinx_timer.h"
// App
#include "common.h"
#include "error.h"
#include "timer.h"
#include "hwconfig.h"
#include "system_monitor.h"
#include "config/app_config.h"
#include "dev_profile/dev_profile.h"
/************************** Function Prototypes ******************************/
int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr);
void Phy_IntrHandler(void *context);
void PeriodicPull_Handler(void *callBackRef);
void ScuTimer_IntrHandler(void *context);
void Systembus_RxIntrHandler(void *context);
void Systembus_TxIntrHandler(void *context);
/************************** Constant Definitions *****************************/
/*********************** Driver Instance Definitions **************************/
static struct timer_desc *logTmPtr;
/*****************************************************************************/
/**
* @brief Main function, initialize all the device needed, initialize
* interrupt system, halt in while(1) wait for event interrupt.
*
* @param none.
*
* @return
*
******************************************************************************/
int main(void)
{
int32_t Status;
DBG_PRINT("Application Version: %2d.%2d.%4d.\n", _APP_VER_MAIN, _APP_VER_MINOR, _APP_VER_PATCH);
/* System Monitor Initialize */
Status = SysMonitor_Init();
if (Status == SUCCESS)
{
DBG_PRINT("System monitor Init SUCCESS. \n");
}
else
{
DBG_PRINT("System monitor Init FAILED. \n");
return Status;
}
/* Hardware Initialize */
Status = Hardware_Init();
if (Status == SUCCESS)
{
DBG_PRINT("Hardware Init SUCCESS. \n");
}
else
{
DBG_PRINT("Hardware Init FAILED. \n");
return Status;
}
DBG_PRINT("Done. \n");
}
@@ -0,0 +1,402 @@
/**
* @addtogroup SystemMonitor
* @{
*/
/***************************** Include Files *********************************/
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include "common.h"
#include "system_monitor.h"
/************************** Constant Definitions *****************************/
/**
* @name SystemMonitor_Private_Constants
* @{
*/
#define BUFF_A 0x00
#define BUFF_B 0x01
#define BUFF_NONE 0xFF
#define SYSINFO_PACK_LEN 54 // bytes
#define PAYLOAD_PACK_LEN 46 // bytes
#define SLOTLOG_PACK_LEN 88 // bytes
#define PRTCLLOG_PACK_ELN 24 // bytes
#define HWSTATE_PACK_ELN 12 // bytes
/** @} SystemMonitor_Private_Constants*/
/************************** Data Type Definitions ****************************/
/**
* @struct PINGPONG
* @brief PingPing Control
*/
typedef struct
{
uint8_t latest; ///< latest available index
uint8_t rBusy; ///< current read busy index
uint8_t wBusy; ///< current write busy index
} PINGPONG;
/**
* @struct SYSMONITOR
* @brief System Monitor struct holds all the system log info
*/
typedef struct
{
PINGPONG recvCtrl;
PAYLOAD recv[2];
PINGPONG sendCtrl;
PAYLOAD send[2];
PINGPONG sysInfoCtrl;
SYSINFO sysInfo[2];
PINGPONG linkLogCtrl;
LINKLOG linkLog[2];
PINGPONG phyLogCtrl;
PHYLOG phyLog[2];
PINGPONG hwStateCtrl;
HWSTATE hwState[2];
} SYSMONITOR;
/************************** Function Prototypes ******************************/
static uint8_t GetWritable(PINGPONG ctrllor);
static uint8_t GetReadable(PINGPONG ctrllor);
/************************** Variable Definitions *****************************/
static SYSMONITOR *sysMonitorInst;
/*********************** Function Implementations ***************************/
inline static uint8_t GetWritable(PINGPONG ctrllor)
{
// Allow only one write.
ASSERT(ctrllor.wBusy == BUFF_NONE);
if (ctrllor.rBusy == BUFF_NONE)
return ((ctrllor.latest == BUFF_B) ? BUFF_A : BUFF_B);
else
return ((ctrllor.rBusy == BUFF_B) ? BUFF_A : BUFF_B);
}
inline static uint8_t GetReadable(PINGPONG ctrllor)
{
if (ctrllor.wBusy == BUFF_NONE || ctrllor.wBusy != ctrllor.latest)
return ((ctrllor.latest == BUFF_NONE) ? BUFF_A : BUFF_B);
else
return ((ctrllor.wBusy == BUFF_B) ? BUFF_A : BUFF_B);
}
/**
* @brief Initialize System monitor
*
* @return SUCCESS
*/
int32_t SysMonitor_Init(void)
{
sysMonitorInst = calloc(1, sizeof(SYSMONITOR));
if (sysMonitorInst == NULL)
{
return ENOMEM;
}
memset(&(sysMonitorInst->recvCtrl), BUFF_NONE, sizeof(PINGPONG));
memset(&(sysMonitorInst->sendCtrl), BUFF_NONE, sizeof(PINGPONG));
memset(&(sysMonitorInst->sysInfoCtrl), BUFF_NONE, sizeof(PINGPONG));
memset(&(sysMonitorInst->linkLogCtrl), BUFF_NONE, sizeof(PINGPONG));
memset(&(sysMonitorInst->phyLogCtrl), BUFF_NONE, sizeof(PINGPONG));
memset(&(sysMonitorInst->hwStateCtrl), BUFF_NONE, sizeof(PINGPONG));
sysMonitorInst->recv[0].dataId = DATA_ID_NONE;
sysMonitorInst->recv[1].dataId = DATA_ID_NONE;
sysMonitorInst->send[0].dataId = DATA_ID_NONE;
sysMonitorInst->send[1].dataId = DATA_ID_NONE;
return SUCCESS;
}
/**
* @brief Destroy system monitor release all allocated memory
*/
void SysMonitor_Destroy(void)
{
free(sysMonitorInst);
}
/**
* @name SystemInfo_API
* @{
*/
/**
* @brief Update system info.
*
* @param info
*/
void SysMonitor_UpdateSysinfo(const SYSINFO *info)
{
uint8_t buffIndx;
buffIndx = GetWritable(sysMonitorInst->sysInfoCtrl);
sysMonitorInst->sysInfoCtrl.wBusy = buffIndx;
memcpy(&(sysMonitorInst->sysInfo[buffIndx]), info, sizeof(SYSINFO));
sysMonitorInst->sysInfoCtrl.latest = buffIndx;
sysMonitorInst->sysInfoCtrl.wBusy = BUFF_NONE;
}
/**
* @brief Get system info.
*
* @param info
*/
void SysMonitor_GetSysinfo(SYSINFO *info)
{
ASSERT(sysMonitorInst != NULL);
uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->sysInfoCtrl.rBusy;
if (buffIndex_old != BUFF_NONE)
buffIndx = buffIndex_old; // Keep it busy
else
buffIndx = GetReadable(sysMonitorInst->sysInfoCtrl);
sysMonitorInst->sysInfoCtrl.rBusy = buffIndx;
memcpy(info, &(sysMonitorInst->sysInfo[buffIndx]), sizeof(SYSINFO));
sysMonitorInst->sysInfoCtrl.rBusy = buffIndex_old;
}
/** @} SystemInfo_API*/
/**
* @name ServicePayload_API
* @{
*/
/**
* @brief Update send payload by
*
* @param buff
* @param len
*/
void SysMonitor_UpdateSendPayload(const uint8_t *buff, size_t len)
{
ASSERT(sysMonitorInst != NULL);
if (len > PAYLOAD_LEN_MAX)
{
return;
}
uint8_t buffIndx;
buffIndx = GetWritable(sysMonitorInst->sendCtrl);
sysMonitorInst->sendCtrl.wBusy = buffIndx;
memcpy(sysMonitorInst->send[buffIndx].data, buff, len);
sysMonitorInst->send[buffIndx].dataId++;
sysMonitorInst->sendCtrl.latest = buffIndx;
sysMonitorInst->sendCtrl.wBusy = BUFF_NONE;
}
/**
* @brief Get the latest send payload.
*
* @param buff
* @param id
* @param len
*/
void SysMonitor_GetSendPayload(uint8_t *buff, uint32_t *id, size_t len)
{
ASSERT(sysMonitorInst != NULL);
ASSERT(buff != NULL);
ASSERT(id != NULL);
if (len > PAYLOAD_LEN_MAX)
{
return;
}
uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->sendCtrl.rBusy;
if (buffIndex_old != BUFF_NONE)
buffIndx = buffIndex_old; // Keep it busy
else
buffIndx = GetReadable(sysMonitorInst->sendCtrl);
sysMonitorInst->sendCtrl.rBusy = buffIndx;
if (sysMonitorInst->send[buffIndx].dataId != DATA_ID_NONE)
{
memcpy(buff, sysMonitorInst->send[buffIndx].data, len);
}
*id = sysMonitorInst->send[buffIndx].dataId;
sysMonitorInst->sendCtrl.rBusy = buffIndex_old;
}
/**
* @brief Update receive payload.
*
* @param buff
* @param id
* @param len
*/
void SysMonitor_UpdateRecvPayload(const uint8_t *buff, uint32_t id, size_t len)
{
ASSERT(sysMonitorInst != NULL);
ASSERT(buff != NULL);
if (id == DATA_ID_NONE || len > PAYLOAD_LEN_MAX)
{
return;
}
uint8_t buffIndx;
buffIndx = GetWritable(sysMonitorInst->recvCtrl);
sysMonitorInst->recvCtrl.wBusy = buffIndx;
memcpy(sysMonitorInst->recv[buffIndx].data, buff, len);
sysMonitorInst->recv[buffIndx].dataId = id;
sysMonitorInst->recvCtrl.latest = buffIndx;
sysMonitorInst->recvCtrl.wBusy = BUFF_NONE;
}
/**
* @brief Get the latest receive payload.
*
* @param buff
* @param id
* @param len
*/
void SysMonitor_GetRecvPayload(uint8_t *buff, uint32_t *id, size_t len)
{
ASSERT(sysMonitorInst != NULL);
ASSERT(buff != NULL);
ASSERT(id != NULL);
if (len > PAYLOAD_LEN_MAX)
{
return;
}
uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->recvCtrl.rBusy;
if (buffIndex_old != BUFF_NONE)
buffIndx = buffIndex_old; // Keep it busy
else
buffIndx = GetReadable(sysMonitorInst->recvCtrl);
sysMonitorInst->recvCtrl.rBusy = buffIndx;
if (sysMonitorInst->recv[buffIndx].dataId != DATA_ID_NONE)
{
memcpy(buff, sysMonitorInst->recv[buffIndx].data, len);
}
*id = sysMonitorInst->recv[buffIndx].dataId;
sysMonitorInst->recvCtrl.rBusy = buffIndex_old;
}
/** @} ServicePayload_API*/
/**
* @name Linklayer_Log_API
* @{
*/
/**
* @brief Update link layer log
*
* @param log
*/
void SysMonitor_UpdateLinklayerLog(const LINKLOG *log)
{
ASSERT(sysMonitorInst != NULL);
ASSERT(log != NULL);
uint8_t buffIndx;
buffIndx = GetWritable(sysMonitorInst->linkLogCtrl);
sysMonitorInst->linkLogCtrl.wBusy = buffIndx;
memcpy(&(sysMonitorInst->linkLog[buffIndx]), log, sizeof(LINKLOG));
sysMonitorInst->linkLogCtrl.latest = buffIndx;
sysMonitorInst->linkLogCtrl.wBusy = BUFF_NONE;
}
/**
* @brief Get the latest link layer log
*
* @param log
*/
void SysMonitor_GetLinklayerLog(LINKLOG *log)
{
ASSERT(sysMonitorInst != NULL);
ASSERT(log != NULL);
uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->linkLogCtrl.rBusy;
if (buffIndex_old != BUFF_NONE)
buffIndx = buffIndex_old; // Keep it busy
else
buffIndx = GetReadable(sysMonitorInst->linkLogCtrl);
sysMonitorInst->linkLogCtrl.rBusy = buffIndx;
memcpy(log, &(sysMonitorInst->linkLog[buffIndx]), sizeof(LINKLOG));
sysMonitorInst->linkLogCtrl.rBusy = buffIndex_old;
}
/** @} Linklayer_Log_API*/
/**
* @name PhysicalLayer_Log_API
* @{
*/
/**
* @brief Update physical layer log
*
* @param log
*/
void SysMonitor_UpdatePhysicalLayerLog(const PHYLOG *log)
{
ASSERT(sysMonitorInst != NULL);
ASSERT(log != NULL);
uint8_t buffIndx;
buffIndx = GetWritable(sysMonitorInst->phyLogCtrl);
sysMonitorInst->phyLogCtrl.wBusy = buffIndx;
memcpy(&(sysMonitorInst->phyLog[buffIndx]), log, sizeof(PHYLOG));
sysMonitorInst->phyLogCtrl.latest = buffIndx;
sysMonitorInst->phyLogCtrl.wBusy = BUFF_NONE;
}
/**
* @brief Get the latest physical layer log
*
* @param log
*/
void SysMonitor_GetPhysicalLayerLog(PHYLOG *log)
{
ASSERT(sysMonitorInst != NULL);
ASSERT(log != NULL);
uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->phyLogCtrl.rBusy;
if (buffIndex_old != BUFF_NONE)
buffIndx = buffIndex_old; // Keep it busy
else
buffIndx = GetReadable(sysMonitorInst->phyLogCtrl);
sysMonitorInst->phyLogCtrl.rBusy = buffIndx;
memcpy(log, &(sysMonitorInst->phyLog[buffIndx]), sizeof(PHYLOG));
sysMonitorInst->phyLogCtrl.rBusy = buffIndex_old;
}
/** @} */
/**
* @name HardwareState_Log_API
* @{
*/
/**
* @brief Log hardware running status.
*
* @param state
*/
void SysMonitor_UpdateHardwareStatus(const HWSTATE *state)
{
ASSERT(sysMonitorInst != NULL);
ASSERT(state != NULL);
uint8_t buffIndx;
buffIndx = GetWritable(sysMonitorInst->hwStateCtrl);
sysMonitorInst->hwStateCtrl.wBusy = buffIndx;
memcpy(&(sysMonitorInst->hwState[buffIndx]), state, sizeof(HWSTATE));
sysMonitorInst->hwStateCtrl.latest = buffIndx;
sysMonitorInst->hwStateCtrl.wBusy = BUFF_NONE;
}
/**
* @brief Get the latest hardware running status.
*
* @param state
*/
void SysMonitor_GetHardwareStatus(HWSTATE *state)
{
ASSERT(sysMonitorInst != NULL);
ASSERT(state != NULL);
uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->hwStateCtrl.rBusy;
if (buffIndex_old != BUFF_NONE)
buffIndx = buffIndex_old; // Keep it busy
else
buffIndx = GetReadable(sysMonitorInst->hwStateCtrl);
sysMonitorInst->hwStateCtrl.rBusy = buffIndx;
memcpy(state, &(sysMonitorInst->hwState[buffIndx]), sizeof(HWSTATE));
sysMonitorInst->hwStateCtrl.rBusy = buffIndex_old;
}
/** @} HardwareState_Log_API */
/** @} SystemMonitor*/
@@ -0,0 +1,241 @@
/**
* @defgroup SystemMonitor
* @{
*/
#ifndef __SYSTEM_MONITOR_H_
#define __SYSTEM_MONITOR_H_
/***************************** Include Files *********************************/
#include <stdint.h>
#include <stdbool.h>
#include "util.h"
/************************* Constant Definitions ******************************/
/**
* @name SystemMonitor_Constants
* @{
*/
#define PAYLOAD_LEN_MAX 256
#define PAYLOAD_LEN_FLJ_RX 168
#define PAYLOAD_LEN_FLJ_TX 66
#define PAYLOAD_LEN_LJ_RX 66
#define PAYLOAD_LEN_LJ_TX 168
#define DATA_ID_NONE UINT32_MAX
#define DATA_ID_TEST 0x02030203
#define VOLTAGE_LSB 0.01 // volt
#define VOLTAGE_MAX 2.55 // volt
#define VOLT_PS_STD 1.0
#define VOLT_PSAUX_STD 1.8
#define VOLT_DDR_STD 1.5
#define VOLT_PL_STD 1.0
#define VOLT_PLAUX_STD 1.8
#define VOLT_BRAM_STD 1.0
#define VOLT_PS_OK BIT(0)
#define VOLT_PSAUX_OK BIT(1)
#define VOLT_DDR_OK BIT(2)
#define VOLT_PL_OK BIT(3)
#define VOLT_PLAUX_OK BIT(4)
#define VOLT_BRAM_OK BIT(5)
#define VOLT_ANT_PROC_OK BIT(0)
#define VOLT_ANT_RF_OK BIT(2)
#define VOLT_ANT_NIL_OK BIT(4)
#define ANT_STATE_OK BIT(6)
// Xilinx Recommended
// #define IS_PS_VALID(x) (x <= 1.05 && x >= 0.95)
// #define IS_PSAUX_VALID(x) (x <= 1.89 && x >= 1.71)
// #define IS_DDR_VALID(x) (x <= 1.89 && x >= 1.14)
// #define IS_PL_VALID(x) (x <= 1.03 && x >= 0.97)
// #define IS_PLAUX_VALID(x) (x <= 1.89 && x >= 1.71)
// #define IS_BRAM_VALID(x) (x <= 1.03 && x >= 0.97)
#define IS_PS_VALID(x) (x <= 1.1 && x >= 0.9)
#define IS_PSAUX_VALID(x) (x <= 2.0 && x >= 1.6)
#define IS_DDR_VALID(x) (x <= 1.7 && x >= 1.3)
#define IS_PL_VALID(x) (x <= 1.1 && x >= 0.9)
#define IS_PLAUX_VALID(x) (x <= 2.0 && x >= 1.6)
#define IS_BRAM_VALID(x) (x <= 1.1 && x >= 0.9)
#define CLK_SP_PLL1_LOCK BIT(0)
#define CLK_SP_PLL2_LOCK BIT(2)
#define CLK_AD0_BBPLL_LOCK BIT(0)
#define CLK_AD0_RFPLL_LOCK BIT(2)
#define CLK_AD1_BBPLL_LOCK BIT(4)
#define CLK_AD1_RFPLL_LOCK BIT(6)
#define CLK_ANT_BBPLL_LOCK BIT(0)
#define CLK_ANT_RFPLL0_LOCK BIT(2)
#define CLK_ANT_RFPLL1_LOCK BIT(4)
#define TEMPERATURE_LSB 1.0 // Celsius degree
#define TEMPERATURE_MAX 127.0 // Celsius degree
#define TEMPERATURE_MIN -128.0 // Celsius degree
/** @} SystemMonitor_Constants */
/************************* Data Type Definitions ****************************/
/**
* @struct SYSINFO
* @brief System Infomation log
*/
typedef struct __attribute__((packed))
{
uint32_t psBDS; ///< -- unit: ms, 0~604799999
uint16_t pBDS; ///< -- unit: week, 0~0~8191
uint32_t psGPS; ///< -- unit: ms, 0~604799999
uint16_t pGPS; ///< -- unit: week, 0~0~8191
uint8_t tmInd; ///< Time validation indicator \n
// -- [0] GPS\n
// -- [1] reserve.\n
// -- [2] UTC\n
// -- [3] BDS\n
float tmFly; ///< Time of flying uint: s
uint8_t stFly; ///< Status of flying \n
// [7:6] departure status 11 - departed/00 - not departed \n
// [5:4] ready status 11 - ready/00 - not ready \n
// [3:2] attitude status 11 - attitude ok/00 - attitude not ok \n
// [1:0] attitude adjust status 11 - adjusted/00 - not adjusted
float posX; ///< coord X Position in launch coordinate system
float posY; ///< coord Y Position in launch coordinate system
float posZ; ///< coord Z Position in launch coordinate system
float vX; ///< Speed X in launch coordinate system
float vY; ///< Speed Y in launch coordinate system
float vZ; ///< Speed Z in launch coordinate system
float pitch; ///< Pitch Attitude in launch inertia coordinate system
float yaw; ///< Yaw Attitude in launch inertia coordinate system
float roll; ///< Roll Attitude in launch inertia coordinate system
} SYSINFO;
/**
* @struct SYSBUSLOG
* @brief System Info holds the system bus log
*/
typedef struct __attribute__((packed))
{
// SystemBus log
uint8_t lastConfig[2]; ///< Last valid config \n
// byte 0: 0x11 FLJ, 0x00 LJ \n
// byte 1: 0x66 Full Power, 0x88 Low Power
uint32_t pollCnt; ///< number of poll commands
uint32_t svcCnt; ///< number of service commands
uint32_t remoteCnt; ///< number of remote check commands
} SYSBUSLOG;
/**
* @struct LINKLOG
* @brief Linklayer Log struct holds the Linklayer log
*/
typedef struct __attribute__((packed))
{
// Network log
uint32_t tuNum; ///< current time unite number
uint8_t slotNum; ///< current slot number
uint8_t nodeType; ///< current node type
uint8_t cxnStatus; ///< current connection status
uint8_t linkStage; ///< current linklayer working stage
uint32_t recxnCnt; ///< reconnect trial count
uint8_t beamNo; ///< current working beam number
uint8_t beamWidth; ///< current working beam width
uint16_t beamAz; ///< current working beam angle Az
uint16_t beamEl; ///< current working beam angle Ez
uint16_t advTxCnt; ///< adv frame send count
uint16_t advRecvCnt; ///< adv frame received count
uint16_t advCorrectCnt; ///< adv frame received correctly count
uint32_t cfmTxCnt; ///< cfm frame send count
uint32_t cfmRecvCnt; ///< cfm frame received count
uint32_t cfmCorrectCnt; ///< adv frame received correctly count
uint32_t svcTxCnt; ///< svc frame send count
uint32_t svcRecvCnt; ///< svc frame received count
uint32_t svcCorrectCnt; ///< svc frame received correctly count
int32_t timeDev; ///< last time deviation result
uint32_t sendId; ///< last send data id
uint32_t recvId; ///< last received data id
uint8_t reserve[4]; ///< reserved data
} LINKLOG;
/**
* @struct PHYLOG
* @brief Physical Layer Log struct holds the Linklayer log
*/
typedef struct __attribute__((packed))
{
uint32_t acqCnt; ///< aquisition count
uint32_t fsyncCnt; ///< frame sync count
uint32_t decodeCnt; ///< decode count
uint32_t crcCnt; ///< crc valid count
double doppler; ///< last doppler estimation result
uint64_t recvStamp; ///< last frame arrival time
double acqPAPR; ///< last acquisition peak-average ration
uint8_t acqPhase; ///< last acquisition phase estimation
uint8_t acqFreqCh; ///< last acquisition frequency deviation estimation
double fsyncPAPR; ///< last frame sync peak-average ration
uint8_t fsyncFreqCh; ///< last frame sync frequency estimation
uint16_t deintlvAmpEst; ///< de-interleave amplitude estimation
uint8_t antMode; ///< current antenna working mode
uint8_t reserve[3]; ///< reserved data
} PHYLOG;
/**
* @struct HWSTATE
* @brief Hardware Status Log struct holds all hardware status
*/
typedef struct __attribute__((packed))
{
bool isSpOk; ///< signal processor state
bool isAntOk; ///< antenna state
// -- Signal processor status
uint8_t spFpgaVolt; ///< Signal processor voltage state indicator
uint8_t spClkState; ///< Signal processor clock state indicator
uint8_t spAdLockState; ///< Signal processor adc lock state indicator
uint8_t spAdTemp_0; ///< Signal processor adc0 temperature
uint8_t spAdTemp_1; ///< Signal processor adc1 temperature
uint8_t spFpgaTemp; ///< Signal processor FPGA temperature
// -- Antenna status
uint8_t antVolt; ///< Antenna voltage state indicator
uint8_t antTemp; ///< Antenna rf temperature
uint8_t antPll; ///< Antenna rf lock state indicator
uint8_t antMgc0; ///< Antenna rf mgc0~1 indicator
uint8_t antMgc1; ///< Antenna rf mgc2~3 indicator
uint8_t phyId;
uint8_t reserve[1];
} HWSTATE;
/**
* @struct PAYLOAD
* @brief Payload struct holds the service payload
*/
typedef struct
{
uint32_t dataId;
uint8_t data[PAYLOAD_LEN_MAX];
} PAYLOAD;
/************************** Function Prototypes ******************************/
int32_t SysMonitor_Init(void);
void SysMonitor_Destroy(void);
void SysMonitor_UpdateSysinfo(const SYSINFO *info);
void SysMonitor_GetSysinfo(SYSINFO *info);
void SysMonitor_UpdateSendPayload(const uint8_t *buff, size_t len);
void SysMonitor_UpdateRecvPayload(const uint8_t *buff, uint32_t id, size_t len);
void SysMonitor_GetSendPayload(uint8_t *buff, uint32_t *id, size_t len);
void SysMonitor_GetRecvPayload(uint8_t *buff, uint32_t *id, size_t len);
void SysMonitor_UpdateLinklayerLog(const LINKLOG *log);
void SysMonitor_UpdatePhysicalLayerLog(const PHYLOG *log);
void SysMonitor_UpdateHardwareStatus(const HWSTATE *state);
void SysMonitor_GetLinklayerLog(LINKLOG *log);
void SysMonitor_GetPhysicalLayerLog(PHYLOG *log);
void SysMonitor_GetHardwareStatus(HWSTATE *state);
#endif //__SYSTEM_MONITOR_H_
/** @} */
@@ -0,0 +1,134 @@
/*****************************************************************************/
/**
* @file circ_queue.c
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief A simple circular FIFO bounded queue
* @version 0.1
* @date 2023-02-23
* @note Forked from https://github.com/chrismerck/rpa_queue.git
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup Utility
* @{
*/
/**
* @addtogroup CircularQueue
* @{
*/
#include "circ_queue.h"
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
inline bool isCircQueueFull(CIRC_QUEUE *queue)
{
ASSERT(queue != NULL);
return ((queue)->nelts == (queue)->bounds);
}
inline bool isCircQueueEmpty(CIRC_QUEUE *queue)
{
ASSERT(queue != NULL);
return ((queue)->nelts == 0);
}
void CircQueueFree(CIRC_QUEUE *queue)
{
ASSERT(queue != NULL);
if (queue->data)
free(queue->data);
free(queue);
}
/**
* @brief Initialize the CIRC_QUEUE.
*/
bool CircQueueCreate(CIRC_QUEUE **q, uint32_t queueCapacity)
{
ASSERT(q != NULL);
CIRC_QUEUE *queue;
queue = malloc(sizeof(CIRC_QUEUE));
if (!queue)
{
return false;
}
*q = queue;
memset(queue, 0, sizeof(CIRC_QUEUE));
/* Set all the data in the queue to NULL */
queue->data = malloc(queueCapacity * sizeof(void *));
if (queue->data == NULL)
{
goto error;
}
queue->bounds = queueCapacity;
queue->nelts = 0;
queue->in = 0;
queue->out = 0;
return true;
error:
free(queue);
return false;
}
/**
* @brief Push new data onto the queue.
*/
bool CircQueuePush(CIRC_QUEUE *queue, void *data)
{
ASSERT(queue != NULL);
if (isCircQueueFull(queue))
{
return false;
}
queue->data[queue->in] = data;
queue->in++;
if (queue->in >= queue->bounds)
{
queue->in -= queue->bounds;
}
queue->nelts++;
return true;
}
/**
* @brief Return current number of element in queue.
*/
inline uint32_t CircQueueSize(CIRC_QUEUE *queue)
{
return queue->nelts;
}
/**
* @brief Retrieves the next item from the queue.
*/
bool CircQueuePop(CIRC_QUEUE *queue, void **data)
{
ASSERT(queue != NULL);
if (isCircQueueEmpty(queue))
{
return false;
}
*data = queue->data[queue->out];
queue->nelts--;
queue->out++;
if (queue->out >= queue->bounds)
{
queue->out -= queue->bounds;
}
return true;
}
/** @} CircularQueue*/
/** @} Utility*/

Some files were not shown because too many files have changed in this diff Show More